Forum Moderators: phranque

Message Too Old, No Replies

ModRewrite for specific URLs

         

petervullings

3:14 am on Apr 8, 2005 (gmt 0)

10+ Year Member



Hi all,

Being quite new to regular expressions, I am hoping that someone is able to validate my rewrite rule.

What it should do is ignore any URLs except those that have a /cv/ in them.
e.g. IGNORE: www.example.com/something/somepage.html
e.g. IGNORE: www.example.com/cv.php
e.g. PARSE: www.example.com/cv/company/user

It should parse the following:
www.example.com/cv/company/user
to:
www.example.com/index.php?cv=1&cp=company&cd=user

Here is my .htacess:


RewriteEngine on

#RewriteRule^[^/cv/]+/cv/([^/]+)/(.+)$ /index\.php?cv=1&cp=$1&cd=$2

In plain text my rule is (correct me if I am wrong):
^ from the start
[^/cv/]+ find one or more characters that AREN'T '/cv/'
/cv/ followed by '/cv/'
([^/]+) followed by one or more characters that arent a slash
/ followed by a slash
(.+) followed by everything else (must be at least one)

[edited by: jdMorgan at 3:47 pm (utc) on April 8, 2005]
[edit reason] Examplified. [/edit]

sitz

3:39 am on Apr 8, 2005 (gmt 0)

10+ Year Member



(correct me if I am wrong)

Ok. =)

You've got the right idea, but you're missing a couple of tidbits on how regexes work, and you're making it harder than it actually is (something I'm famous for. In *my* head, anyway).

So, four things to know:

  • [^foo] doesn't say "match if the string doesn't contain 'foo'"; it says "match if the string doesn't contain the letters 'f', 'o', or 'o'. Brackets like this:

    []

    Denote a character class; a string of characters within brackets will not do what you want.

  • You don't need to escape the '.' character on the RHS (right-hand-side) of the RewriteRule

  • You should ALWAYS use the 'L' flag at tne end of a RewriteRule unless you KNOW you don't.

  • You don't need to create a RewriteRule which deals with both the positive *and* negative cases; since all you want to do is Rewrite everything in /cv/, then this is sufficient:

    RewriteEngine on
    RewriteRule ^/cv/([^/]+)/(.+)$ /index.php?cv=1&cp=$1&cd=$2 [L]

    Make sense?

  • petervullings

    4:00 am on Apr 8, 2005 (gmt 0)

    10+ Year Member



    Perfectly. thanks! Maybe I am missing something else basic. The .htaccess goes in the root directory?

    My latest errors (after trying http://www.example.co.nz/cv/a/b) are:

    [Fri Apr 8 15:57:16 2005] [error] [client 222.***.211.187] File does not exist: /home/example/public_html/cv/a/b

    This seems to me like either non of the rules are working (i.e. rewrite is not enabled) or this rule isn't. What is an easy way to check?

    [edited by: jdMorgan at 3:46 pm (utc) on April 8, 2005]
    [edit reason] Obscured specifics per TOS. [/edit]

    sitz

    4:32 am on Apr 8, 2005 (gmt 0)

    10+ Year Member



    You have two options; either in a .htaccess file or in httpd.conf; the latter is generally preferred if possible, as the performance hit for using RewriteRules in a .htaccess file are...non-zero. =)

    (see the first couple of paragraphs at [httpd.apache.org ] for a rather detailed explanation on this)

    If the .htaccess file is your only option, the syntax changes ever-so-slightly, and some prerequisites must by fulfilled by the server administrator:

  • The LoadModule (and AddModule, for Apache 1.3.x) lines for mod_rewrite must not be commented out (IOW, mod_rewrite must be active)
  • The 'FileInfo' option to the AllowOverride directive must be in force for the directory containing the .htaccess file
  • The leading '/' must be removed from LHS of the RewriteRule, leaving:

    RewriteEngine on
    RewriteRule ^cv/([^/]+)/(.+)$ /index.php?cv=1&cp=$1&cd=$2 [L]

    To test whether the prerequisites have been met, the easy solution is to create a simple RewriteRule:


    RewriteEngine on
    RewriteRule ^.* http://www.google.com/ [L,R]

    If you get redirected to google, mod_rewrite works. =)
  • petervullings

    5:18 am on Apr 8, 2005 (gmt 0)

    10+ Year Member



    Thanks very much for supplying all this info. I appreciate it. Its great being able to understand it.

    Its definatly getting there (leaving off the first slash), however, images are treating the base URL as the url was BEFORE the rewrite rule. Is there any way to force apache to cause a proper 'redirect' so to speak?

    For example,
    www.example.com/index.php
    The root is : www.example.com/

    However, with this rewrite rule:
    www.example.com/cv/one/two -> www.example.com/index.php?cv=1&cp=one&cn=two
    The root is : www.example.com/cv/one/

    So images are attempting to be loaded from:
    www.example.com/cv/one/images/picture.jpg
    Rather than:
    www.example.com/images/picture.jpg

    Cheers,
    Peter

    [edited by: jdMorgan at 3:50 pm (utc) on April 8, 2005]
    [edit reason] Examplified. [/edit]

    anshul

    6:28 am on Apr 8, 2005 (gmt 0)

    10+ Year Member



    I am also struggling with mod_rewrite:
    [webmasterworld.com...]

    Also, read this thread; wrote:
    RewriteEngine on
    RewriteRule ^/cv/([^/]+)/(.+)$ /index.php?cv=1&cp=$1&cd=$2 [L]
    in .htaccess file

    and, this in 'index.php' file:
    <a href="http://www.example.com/index.php?cv=1&cp=company&cd=user">Hover here</a>
    <br />
    <a href="index.php?cv=1&cp=company&cd=user">Hover here again</a>

    But, when I called http://localhost/index.php in url; there is NO! again :¦

    [edited by: jdMorgan at 4:00 pm (utc) on April 8, 2005]
    [edit reason] Examplified. [/edit]

    petervullings

    9:33 am on Apr 8, 2005 (gmt 0)

    10+ Year Member



    I'm sorry anshul, I have no idea what you are trying to say :(

    sitz

    1:57 am on Apr 9, 2005 (gmt 0)

    10+ Year Member



    Its definatly getting there (leaving off the first slash), however, images are treating the base URL as the url was BEFORE the rewrite rule. Is there any way to force apache to cause a proper 'redirect' so to speak?

    You've got at least three options, although I suspect one of them is unworkable for you (substitute your server's documentroot where you see $DOCROOT):

  • Move the images/ directory to the 'correct' place (I'm guessing this won't work for you)
  • symlink $DOCROOT/cv/one/images $DOCROOT/images (certainly the easiest solution, with the least overhead)
  • Play with mod_rewrite some more; you could add something like:

    RewriteRule ^cv/[^/]+/images/(.*) /images/$1 [L]

    ...to your ruleset. If you go this route; note that you'll need to add it *above* the RewriteRule I posted earlier; order of the rules *does* matter. =)

    Alternatively, you could use:


    Alias /cv/one/images $DOCROOT/images

    ...however, that would need to get added to httpd.conf, since Alias is not valid in a .htaccess file; so, if you don't have write access to httpd.conf, that's right out. =)

    Personally, I'd go with the symlink; it's easy and there's zero additional server overhead involved. If you want to document the reason for the symlink someplace, you could drop a comment in the .htaccess file so you have it written down in case you (or someone else, if more than one of you work on this site) wonder what the heck it's doing there in a year or two. You could even create a file called something like REASON_FOR_SYMLINK, put docs in there, and then chmod the file mode 600 so that the webserver can't read it (or, you could just maintain documentation somewhere else. Options galore!)

  •