.htaccess: Problem with URL rewriting - .htaccess

I'm new to url rewriting and having a problem i can't figure out.
I got this 2 conditions:
RewriteRule ([^/]+).php index.php?com=cat&catname=$1 [L]
RewriteRule ([^/]+)/([^/]+).php index.php?com=detail&catname=$1prodname=$2 [L]
and need 2 urls like this:
website.com/category-name.php
website.com/category-name/product-name.php
It seems that the first condition rules upon the second... i mean: if i call the first url everything works fine, but when i call the second url i can't get variables as i want ("com" is always "cat" and "catname" get the value of $2)
Thanks in advance!

URLs that match the second rule will also match the first rule. As the first rule is marked "L", the second rule will never be applied.
Maybe you should match absolute URLs - begin the regex with ^/ to match the beginning of a URL, and end it with $ to match the end of the URL. Remember that rewrite rules are applied to the URL path (everything that follows website.com, including the slash).
For example (didn't test this of course):
# Example: website.com/books.php -> website.com/index.php?com=cat&catname=books
RewriteRule ^/([^/]+).php$ /index.php?com=cat&catname=$1 [L]
# Example: website.com/books/java.php -> website.com/index.php?com=detail&catname=books&prodname=java
RewriteRule ^/([^/]+)/([^/]+).php$ /index.php?com=detail&catname=$1prodname=$2 [L]

Related

How to get only first part of string before slash in URL (HTACCESS)

To achieve this URL pattern www.example.com/abc-xyz/mno-pqr/123.html
I am using following in htaccess:
rewriterule ^(.*)/(.*)/(.*).html$ index.php?lyrics_id=$3&singer=$1&song=$2 [L]
Below are example URL which are causing duplicate title error for my site.
www.example.com/abc-xyz/WHATEVER/ANOTHER_WHATEVER/mno-pqr/283.html
www.example.com/abc-xyz/I_DONT_WANT_THIS_PART/mno-pqr/283.html
www.example.com/abc-xyz/HELP_ME/REMOVE/mno-pqr/283.html
www.example.com/abc-xyz/HELP/REMOVE/THIS/PART/mno-pqr/283.html
I want to get only first part before slash in singer part.
I want exactly this,
www.example.com/abc-xyz/mno-pqr/123.html
but not other letters or between abc-xyz and mno-pqr.
Help me writing htaccess.
It seems that you only want to match the url if it consists of exactly 3 parts. You can do this, by matching everything but the delimiter in each part. The delimiter here is /.
Also please note that . matches EVERY CHARACTER. If you want to match the period character instead, you have to escape it (\.).
RewriteRule ^([^/]*)/([^/]*)/([^/]*)\.html$ /index.php?lyrics_id=$3&singer=$1&song=$2 [L]
That works for my 3 parameters rule but how to add 301 redirect to all
those URL which have more than 3 parts?
If the extra parts are always between the first part and the 2nd part of the url, like you showed above, you have to redirect the user with a 301 header:
RewriteRule ^([^/]*)/.*/([^/]*)/([^/]*)\.html$ /$1/$2/$3.html [R=301,L]

Redirecting with htaccess using similar rules

I'm using .htaccess to rewrite my URLs and so far it's almost working as it should...
The problem I'm having is that mysite.com/author and mysite.com/author/submit/1 are both redirecting to the same page (mysite.com/author.)
These are the rewrite rules that I'm currently using:
RewriteRule ^author /zabjournal/pages/author/active_submissions.php [L]
RewriteRule ^author/submit/1 /zabjournal/pages/author/submit_step1.php [L]
How do I get the second rule to work?
This is because you have put the rules in the wrong order.
The first rule validates and executes because author is the first string in both URLs.
/author
/author/submit/1
/author/blah
/author/blah/blah/blah/blah/blah
The URLs above will all match the first rule, so, therefore, it will be executed.
The [L] (which stands for last) at the end of a rule means that it won't process other rules if that rule is executed.
But, if you change the order of your rewrite rules it will first check to see if the URL matches /author/submit/1 and, if it does, it will execute that rewrite and then stop; but if it doesn't, it will continue to the next rule, which, in your example, would be /author.

.htaccess file url rewrite keeps going to the wrong page

I am trying to get the follow urls to work
www.urlname.com/team/1-Test
www.urlname.com/team/1-Test/members
RewriteRule ^team/([^-]+)-([^&]+)$ index.php?p=teamprofile&team_name=$2&team_id=$1
RewriteRule ^team/([^-]+)-([^&]+)/members$ index.php?p=teammembers&team_name=$1&team_id=$2
but when i try the link with /members init it goes to the other page?
can someone help me please
Thanks
[^-] and [^&] includes the / so /members is included with that. you could either add / to your negation character groups like [^-/] and [^&/] so it doesn't match / or move the bottom one up and add [L] after it to tell apache this is the [L]ast rule to check if it matches.
The trouble is, your second rule is being satisfied by the first rule. You could simply switch them around and it will work:
RewriteEngine On
RewriteRule ^team/([^-]+)-([^&]+)/members$ index.php?p=teammembers&team_name=$1&team_id=$2
RewriteRule ^team/([^-]+)-([^&]+)$ index.php?p=teamprofile&team_name=$2&team_id=$1
Although, a slight change in the first rule will also address the problem:
RewriteEngine On
RewriteRule ^team/([^-]+)-([^/]+)[/]?$ index.php?p=teamprofile&team_name=$1&team_id=$2 [L]
RewriteRule ^team/([^-]+)-([^/]+)/members[/]?$ index.php?p=teammembers&team_name=$1&team_id=$2 [L]
Note, I changed the match string in the first rule from ([^&]+) to ([^/]+) - that way the forward slash isn't included in the match in cases like mydomain.com/team/1-2/. The [/]? rule at the end is an optional match for that trailing forward slash. I've likewise added one to the end of the members rule as well, now it works like this:
mydomain.com/team/1-2/ - goes to index.php?p=teamprofile&team_name=1&team_id=2
mydomain.com/team/1-2 - goes to index.php?p=teamprofile&team_name=1&team_id=2
mydomain.com/team/1-2/members - goes to index.php?p=teammembers&team_name=1&team_id=2
mydomain.com/team/1-2/members/ - goes to index.php?p=teammembers&team_name=1&team_id=2

Ampersands in URL problems

I have a php page which creates URL like:
vendors/London City/cat-DJ & Entertainment/keywords
which my .htaccess redirects as shown below
RewriteRule vendors/(.+)/cat-(.+)/(.+)$ vendors.php?location=$1&category=$2&freetext=$3 [L]
RewriteRule vendors/(.+)/cat-(.+)/(.+)/$ vendors.php?location=$1&category=$2&freetext=$3 [L]
problem 1 is : in the vendors.php file, I am getting only "DJ ; Entertainment" as category. The ampersand is missing.
Problem 2 is : My complete .htaccess file is shown below... 6 rules are defined.
RewriteRule vendors/(.+)/(.+)/$ vendors.php?location=$1&freetext=$2 [L]
RewriteRule vendors/(.+)/(.+)$ vendors.php?location=$1&freetext=$2 [L]
RewriteRule vendors/(.+)/cat-(.+)/$ vendors.php?location=$1&category=$2 [L]
RewriteRule vendors/(.+)/cat-(.+)$ vendors.php?location=$1&category=$2 [L]
RewriteRule vendors/(.+)/cat-(.+)/(.+)$ vendors.php?location=$1&category=$2&freetext=$3[L]
RewriteRule vendors/(.+)/cat-(.+)/(.+)/$ vendors.php?location=$1&category=$2&freetext=$3[L]
Why the URL vendors/London City/cat-DJ & Entertainment/keywords is matching with rule 3 or 4 and redirecting to vendors.php?location=$1&category=$2 ?
Does .htaccess Process the rules from top to beginning one by one?
I had solved the problem by putting the rules 5 and 6 at the top of other rules. Did I make the correct fix?
1. I don't really like the idea of having spaces and other special characters in the URLs. I don't know if it's possible with your site, but instead of this kind of URL
vendors/London City/cat-DJ & Entertainment/keywords
you should have this one:
vendors/london-city/cat-dj-and-entertainment/keywords
For that, of course, you will have to perform some additional transformations / lookups in your database to convert london-city back to London City and dj-and-entertainment back to DJ & Entertainment. This can be done by storing these "from-to" pairs in database.
2. In any case -- order of rules matters. Therefore you should start with more specific rules and end up with more generic rules.
Also -- the (.+) pattern is a way too broad as it can match hello as well as hello/pink/kitten. To ensure that you always grab only one section (part of URL between /) use ([^/]+) pattern instead -- this will address one of the aspects of your "prob #2".
Therefore, try these optimized rules (each rule will match the URL with and without trailing slash):
RewriteRule ^vendors/([^/]+)/cat-([^/]+)/([^/]+)/?$ vendors.php?location=$1&category=$2&freetext=$3 [L]
RewriteRule ^vendors/([^/]+)/cat-([^/]+)/?$ vendors.php?location=$1&category=$2 [L]
RewriteRule ^vendors/([^/]+)/([^/]+)/?$ vendors.php?location=$1&freetext=$2 [L]
Also I'm not getting the value of 'category' with the Ampersand as
given in the url. I am getting only semi-colon. What can be the
reason?
I do not have Apache box currently running next to me, so cannot check it right now, but try adding B or NE flag next to the L flag (e.g. [L,B]) -- one of them should help:
http://httpd.apache.org/docs/current/rewrite/flags.html#flag_b
http://httpd.apache.org/docs/current/rewrite/flags.html#flag_ne
From the docs:
The order in which these rules are defined is important - this is the order in which they will be applied at run-time.

.htaccess passing domain name

I am trying to Rewrite path in .htaccess
=-=-=-=-=-EDIT=-=-=
Hi I may not have expressed my problem clearly.
So here's a live example of my problem.
"http://fames.in/site/bollywoodhungama.com" - works fine
"http://fames.in/site/bollywoodhungama.com/2" - error
The format of the url is:
http://fames.in/site/(site name)/(page number)
I use the following codes in .htaccess
RewriteRule ^site/(.*)$ sitelist.php?q=$1&page=1
RewriteRule ^site/(.*)/([0-9]+)$ sitelist.php?q=$1&page=$2
the first line works fine.
In the second line of the code htaccess passess the whole parameters to 'q'. taking above url it is passed as "/sitelist.php?q=bollywoodhungama.com/2" . I need it to pass the 'q' and 'page' separately. Like "/sitelist.php?q=bollywoodhungama.com&page=2"
The problem is that the first rule is always matching. The .* is greedy so the /2 is part of the match. What you need is the change the match to 'anything but slash' like so:
RewriteRule ^site/([^/]*)$ sitelist.php?q=$1&page=1
So the second domain will fail to match, and then the second rule will match.
Not sue if you need more rules applied after this rule of not, but you may want to add 'last rule flag' [L] to the end of you rule.

Resources