RewriteRule question - .htaccess

RewriteRule ^foo-bar-([0-9]+)-([a-z]+)-([a-z-+]+)/$ index.php?a[]=&b=$1&c=$2&d=$3&e=$4&f=$5 [L,NC]
how could i put the last parameter from rule to not be required without to add two lines and in first one to remove it, then in second to remain..?
so, rule to be in one line but to have two option to acees url like:
/foo-bar-2-steps/
/foo-bar-2-steps-eq/

One of the following:
Use two rewrite rules, one for each case
Put a question mark after the optional part, like this:
foo-bar-([a-z]+)(-([a-z]+))?
Here, the second parameter is optional. Note that this changes your numerical indexes, since you use extra parenthesis.

Related

Rewrite rules for making multiple paths work

I have a requirement to make the following paths work.
Depending on what the url consists of, they are mapped to go to different java classes.
/books/
/books/science/
/books/science/fiction/
/books/science/fiction/kids/
So, I have given the rewrite rules in my configuration file as:
^/books$
^/books/(.*)$
^/books/(.*)/(.*)$
^/books/(.*)/(.*)/(.*)$
but the moment I give a url something like this
http://localhost/books/science/fiction/kids/12345
instead of getting captured by the fourth rewrite rule, it is captured by the second one which is not what I want.
Can someone please tell me how to achieve this? Thanks in advance
^/books$ /webapp/wcs/stores/servlet/ABCController?resultsFor=allCategories [PT,QSA]
^/books/(.*)$ /webapp/wcs/stores/servlet/XYZController?make=$1&resultsFor=category [PT,QSA]
^/books/(.*)/(.*)$ /webapp/wcs/stores/servlet/ABCDController?format=$1-$2&resultsFor=subCategory [PT,QSA]
^/books/(.*)/(.*)/(.*)$ /webapp/wcs/stores/servlet/ASDFController?resultsFor=product [PT,QSA]
instead of getting captured by the fourth rewrite rule, it is captured by the second one
That’s because the dot matches any character, so slashes as well.
Replacing it by a character class allowing anything but a slash (and demanding at least one character out of that class, so + instead of *) should fix that: ([^/]+)
Another way would be to reverse the order of your rules … You should always try and write them in order from most to least specific anyway.

Forward slashes in part numbers are breaking mod_rewrite rule

I've a simple mod_rewrite rule
RewriteRule ^product/([^/.]+)/([^/.]+)/?$ product.php?partNumber=$1&partName=$2 [L]
It works great for 99.99% of products but there are 3 or 4 products which have a forward slash in their part number (eg PART001/1)
which rewrites to something like:
/product/PART001/1/part-name-here-for-nice-seo
Obviously this doesn't work as it's looking in an extra directory. I need the part number passed correctly as it's used to look up the index in the database and fetch all the product's information.
Is there any way round this?
Looks like you just need to change the ([^/.]+) grouping in your regex to also match slashes. Try:
RewriteRule ^product/(.+)/([^/.]+)/?$ product.php?partNumber=$1&partName=$2 [L]

Mod Rewrite Rule for Dynamic URL - Is this possible?

I've given myself a headache trying to figure out if this can be done. I have a forum that was recently migrated, leaving thousands of broken dynamic links.
A typical URL looks like this:
http://domain.com/Forum_Name/b10001/25/
('b10001' refers to the forum ID number and the last number refers to the page number.)
The new URL is formatted like this:
http://domain.com/forums/Forum_Name.10001/
(No page number. Also, notice the 'b' is no longer in front of the ID number.)
Is there a rewrite rule that can achieve this?
I'm not a rewriter, but following what I've read here, something like this should work:
RewriteRule ^([A-Za-z0-9-]+)/b([0-9])+(/[0-9]+)?/?.*$ forums/$1.$2/ [NC,L]
^([A-Za-z0-9-]+) says "begins with an alphanumeric string", then there's the /b constant, followed by [0-9]+ (one or more digits), and then an optional / with one or more digit (the page number, (/[0-9]+)?), and lastly, it ends with an optional slash (/?$).
If the URL matches that pattern, then it's rewritten to forums/$1\.$2/. \. escapes the dot (it's a wildcard), $1 is the first match of the pattern (that first alphanumeric string which is the forum name), and $2 is the second match, namely, the number after the b.
Finally, NC means pattern is case-insensitive, and L is "last" - so you don't process any other rule. I think that is most up to you, just read the linked article and pick the flags you need :)
Edit: corrected pattern checking with http://htaccess.madewithlove.be/
I think what you're looking for is
RewriteRule ^([a-zA-Z0-9_]+)/b([0-9]+)/.*$ forums/$1/$2/
Make sure the contents of the [] parts match the format you're using for forum names and ids.
For parameters, you probably want R=301 to force a permanent redirect.

remove part of url via mod_rewrite

Is there any way to hide part of a Url via mod_rewrite. I am currently using part of the url, .htm, to split the page that is being requested and the query string.
Example
http://www.example.com/page/article/single.htm/articleid=8
This would let me know that the page requested is:
http://www.example.com/page/article/single
And the quest string is:
article=8
Ideally i would like the have this to work the same url without the .htm visible
http://www.example.com/page/article/single/articleid=8
The number of variables in the query sting varies as does the number of levels before the .htm so the rule would need to be dynamic
Thanks
To also do multiple querystring parameters, how do you want it to look? I started with this, which keeps this simple, then got trickier below.
http://www.example.com/page/article/single/articleid=8&anothervar=abc
Try this rule:
RewriteRule ^([^=]+)/(.+)$ $1.htm?$2 [NC,L]
This handles one or more querystring parameters, but does require at least one. This looks for anything without an = up to a slash, then everything else. Basically, it uses the = as the indicator of the path vs. the querystring portions; but actually splits it on the slash. (The NC is a habit of mine; not needed in this case, but when I leave it out I forget it when it's needed.)
To let querystrings be optional, so it could handle just
http://www.example.com/page/article/single
I found it easiest with two rules, instead of trying to mingle this into one rule:
RewriteRule ^([^=]+)$ $1.htm [NC,L]
RewriteRule ^([^=]+)/(.+)$ $1.htm?$2 [NC,L]
You can do something even prettier, using slashes for everything including multiple querystring parameters, like this:
http://www.example.com/page/article/single/articleid=8/anothervar=abc
It's a little hairy, but I think this works (couldn't let it go...)
Another rule handles replacing the slashes with ampersands, then doing the rewrite as above. This was easier to keep straight - maybe there's a way to do it all at once, but this was tricky enough for me:
RewriteRule ^([^=]+)$ $1.htm [NC,L]
RewriteRule ^([^=]+)/([^=]+=[^/]+)/([^=]+=.+)$ $1/$2&$3 [NC,LP]
RewriteRule ^/([^=]+)/(.+)$ /$1.htm?$2 [NC,L]
The first rule is as above, handling no querystrings at all. That just gets it out of the way.
The second rule is a loop LP, which is what I tend to find in examples whenever you have an unknown number of replacements. In this case, it's replacing the last querystring-slash with an ampersand, and looping until there's only one left (leaving that for the question mark in the third rule).
It's looking for the last one of these articleid=8/anothervar=abc where there are two parameters left. It replaces the slash with an ampersand like articleid=8&anothervar=abc
In words, it's looking for (and capturing in parentheses):
(not-equalsign) slash (not-equalsign equalsign not-slash) slash (not-equalsign equalsign anything)
This lines up as:
(not-equalsign) /page/article/single
slash /
(not-equalsign equalsign not-slash) articleid = 8
slash /
(not-equalsign equalsign anything) anothervar = abc
It replaces the last slash with an ampersand, and after looping, turns it into the first draft above: http://www.example.com/page/article/single/articleid=8&anothervar=abc . The third rule handles this as described above.
A note: These also assume all your urls will look like this, since they're going to tack on .htm to everything. If you want still allow explicit /something/page.htm then these rules would need to not-match on .htm if it's already there - something like that. Or maybe an initial rule up front that looks for .htm and just stops rewriting there. Or maybe only do this for the /page paths.

mod_rewrite Redirect Rule Variables question

I'm a bit of an .htaccess n00b, and can't for the life of me get a handle of regular expressions.
I have the following piece of RewriteRule code that works just fine:
RewriteRule ^logo/?$ /pages/logo.html
Basically, it takes /pages/logo.html and makes it /logo.
Is there a way for me to generalize that code with variables, so that it works automatically without having to have an independent line for each page?
I know $1 can work as a variable, but thats usually for queries, and I can't get it to work in this instance.
First you need to know that mod_rewrite can only handle requests to the server. So you would need to request /logo to have it rewritten to /pages/logo.html. And that’s what the rule does, it rewrites requests with the URL path /logo internally to /pages/logo.html and not vice versa.
If you now want to use portions of the matched string, you need to use groups to group them ( (expr)) that you then can reference to with $n. In your case the pattern [^/] will be suitable that describes any character other than the slash /:
RewriteRule ^([^/]+)$ /pages/$1.html
Try this:
RewriteRule ^/pages/(.*)\.html$ /$1
The (.*) matches anything between pages/ and .html. Whatever it matches is used in $1. So, /pages/logo.html becomes /logo, and /pages/subdir/other_page.html would become /subdir/other_page

Resources