Forum Moderators: phranque

Message Too Old, No Replies

That trailing slash.

         

el_roboto

8:36 am on Apr 16, 2007 (gmt 0)

10+ Year Member



This is my first crack at .htaccess, seemed to be doing ok until trailing slashes (or lack of) came into it.

rewriteEngine on
RewriteRule ^(.*)/$ index.php?id=$1 [NC]
ErrorDocument 404 /devname/version/index.php?id=404

Requests to
www.sitename.co.uk/devname/version/home/
www.sitename.co.uk/devname/version/contact/

work a treat

Requests to
www.sitename.co.uk/devname/version/home
www.sitename.co.uk/devname/version/contact

load up page content but my css and images don't link correctly so I get a plain text page.

I'm a little stuck so hoped someone could advise, I spent the weekend reading through the existing trailing slash posts and lots of jdmorgans stuff but nothing I tried did the trick.

jdMorgan

1:42 pm on Apr 16, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The likely problem is that you've used page-relative links in your pages.

Remember that it is the client (browser) that resolves relative links, so, for example, let's say you declare your external CSS file like this:


<link rel="stylesheet" type="text/css" href="style.css">

If this stylesheet is loaded when the browser is rendering the page at example.com/foo, then the stylesheet URL will be resolved as example.com/style.css

But, if it is loaded while the browser is at example.com/foo/, the the stylesheet URL will be resolved as example.com/foo/style.css

Several possible fixes are possible. The first is to use absolute or server-relative links, such as

 <link rel="stylesheet" type="text/css" href=[b]"http://example.com/[/b]style.css"> 

- or -
 <link rel="stylesheet" type="text/css" href=[b]"/s[/b]tyle.css"> 

A second possible fix is to rewrite the stylesheet URLS so that they always point to the same directory, no matter what URL is requested -- in other words, just for example, always remove the directory path from the stylesheet request, and then add a fixed path, such as "styles" to them, resulting in an actual file location of example.com/styles/style.css

Finally, you can add a 'tag' to the URLs that need to be rewritten, so that mod_rewrite can identify them unambiguously, and then redirect them if they are incorrect -- that is, missing the trailing slash. This is easily done by giving all of these URLs a sensible prefix, such as "/pages", "/products", or "/forum" -- whatever makes sense on your site:


# If URL starts with 'pages' but does not have a trailing slash, then redirect to add the slash
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^pages/ http://example.com/pages/$1/ [R=301,L]
# Rewrite 'pages' to the script
RewriteRule ^(([^/]+/)*)/$ /index.php?id=$1 [L]

Or perhaps, on your site, it would be safe to assume that any URL that does not have a filetype can be rewritten to your script. In that case, just look for URLs with no periods in the last part, and redirect them to add a trailing slash if there isn't one:

# If final URL-path-part does not contain a slash or a period
RewriteCond $1 !^([^/]+/)*[^/.]+$
# Redirect to add a trailing slash
RewriteRule (.*) http://example.com/$1/ [R=301,L]

With knowledge of your site's URLs, and your future plans, you may find one of these fixes useful.

For more information, see the documents cited in our forum charter [webmasterworld.com] and the tutorials in the Apache forum section of the WebmasterWorld library [webmasterworld.com].

Jim

el_roboto

1:54 pm on Apr 16, 2007 (gmt 0)

10+ Year Member



I'll do some testing with that later.

You were right on the targeting, managed to get that sorted so now just need to see which is the best solution for missing trailing slashes

Thanks for your help Jim, not just on this one, but the numerous .htaccess posts - it's all good!

el_roboto

11:31 am on Apr 17, 2007 (gmt 0)

10+ Year Member



sorry jim not having much luck with either :(

I think the second option would be the best choice

# Setup: Enable mod_rewrite, disable MultiViews
Options +FollowSymLinks -MultiViews
RewriteEngine on

RewriteRule ^(.*)/$ index.php?id=$1 [NC]

ErrorDocument 404 /username/web/index.php?id=404 [NC]

# If final URL-path-part does not contain a slash or a period
RewriteCond $1!^([^/]+/)*[^/.]+$
# Redirect to add a trailing slash
RewriteRule (.*) http://www.example.co.uk/username/web/$1/ [R,L]

for web/support rather than web/support/ i'm still getting my 404

[edited by: jdMorgan at 1:51 pm (utc) on April 17, 2007]
[edit reason] Example.co.uk [/edit]

jdMorgan

1:01 pm on Apr 17, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Look at your server error log to see what filepath the server tried to access when the 404 was generated.

Also, where did you put this code, relative to your document root? The code must account for the URL-path to its own location.

Jim

el_roboto

1:26 pm on Apr 17, 2007 (gmt 0)

10+ Year Member



Hi Jim

Server log:
File does not exist: /home/vcnytwud/public_html/username/web/procurement

I've got the htaccess file in www.sitename/username/web/
as this is just a development site I don't want to mess with the site root.

jdMorgan

1:57 pm on Apr 17, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



OK, I don't like that first version of the code I banged out. Let's try this instead:

# If final URL-path-part does not contain a period or end with a slash
RewriteCond %{REQUEST_URI} !(\.[^/]*¦/)$
# Redirect to add a trailing slash
RewriteRule (.*) http://www.example.co.uk/username/web/$1/ [R,L]

Replace the broken pipe "¦" character with a solid pipe before use; Posting on this board modifies the pipe characters.

Jim

jd01

4:10 pm on Apr 17, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Not to second guess jdMorgan, but:

#This one has been tested and might be a little more efficient:
RewriteCond %{REQUEST_URI} !(\.¦/$)
# Redirect to add a trailing slash --- Only compare URLs without a dot to the condition.
RewriteRule ([^.]+)$ http://www.example.co.uk/username/web/$1/ [R=301,L]

#This one has not been tested and might be more efficient still:
RewriteCond %{REQUEST_URI} !/$
# Redirect to add a trailing slash --- Only compare URLs without a dot to the condition.
RewriteRule ([^.]+)$ http://www.example.co.uk/username/web/$1/ [R=301,L]

Justin

jd01

7:06 pm on Apr 17, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



...and if I was to second guess myself, I might think this one would be best because you can avoid 'storing' an extra back-reference (but will defer to jdMorgan for clarification if possible, in case there is more loss by adding characters to the file, than by 'storing' the URI, which I believe is an interesting question):

#This one has not been tested and might be more efficient still:
RewriteCond %{REQUEST_URI}!/$
# Redirect to add a trailing slash --- Only compare URLs without a dot to the condition.
RewriteRule [^.]+$ http://www.example.co.uk/username/web/%{REQUEST_URI}/ [R=301,L]

Justin

[edited by: jdMorgan at 9:44 pm (utc) on April 17, 2007]
[edit reason] Double-post cleanup only [/edit]

el_roboto

8:32 am on Apr 18, 2007 (gmt 0)

10+ Year Member



hi guys

I wasn't noticing anything happening with any of the suggestions, until I stripped the comments and now things seem to be happening but I'm getting server errors (500)

ERROR LOG
/home/vcnytwud/public_html/username/web/.htaccess: RewriteCond: bad flag delimiters

Options +FollowSymLinks -MultiViews
RewriteEngine on

RewriteRule ^(.*)/$ index.php?id=$1 [NC]
ErrorDocument 404 /username/web/index.php?id=404 [NC]
RewriteCond %{REQUEST_URI}!/$
RewriteRule [^.]+$ http://www.example.co.uk/username/web/%{REQUEST_URI}/ [R,L]

jdMorgan

2:02 pm on Apr 18, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You need a space between "}" and "!"

RewriteCond %{REQUEST_URI} !/$

Jim

el_roboto

2:27 pm on Apr 18, 2007 (gmt 0)

10+ Year Member



Space added, same error, is my server a complete pain in the butt?

I've seen people achieving similar things with

RewriteRule ^([^/]*)(/)?$ index.php?id=$1 [NC]

What do you make of this?

jdMorgan

3:29 pm on Apr 18, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I make it as poorly-written, and likely to cause a loop.

It has an unnecessary pair or parentheses, and no provision to stop index.php from being rewritten to itself recursively, causing an 'infinite loop' and leading to either a server or browser error, depending on which end gives up first.

Your server is not a pain. But mod_rewrite code requires precision, and it will do exactly what you tell it to do -- Which may not be what you really want if your code isn't exactly right.

Did you ever try the last code change I posted above?

If not, here's my last suggestion:


ErrorDocument 404 /username/web/index.php?id=404 [NC]
#
RewriteRule ^(.*)/$ /index.php?id=$1 [NC]
#
# If final URL-path-part does not contain a period or end with a slash
RewriteCond %{REQUEST_URI} !(\.[^/]*¦/)$
# Redirect to add a trailing slash
RewriteRule (.*) http://www.example.co.uk/username/web/$1/ [R=301,L]
#
RewriteRule ^(.*)/$ index.php?id=$1 [NC]

As before, replace the broken pipe "¦" character with a solid pipe before use; Posting on this board modifies the pipe characters.

Jim

el_roboto

10:30 am on Apr 20, 2007 (gmt 0)

10+ Year Member



WOOHOOOOOOOOOOOOOO

Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteRule ^(.*)/$ index.php?id=$1 [NC]
RewriteCond %{REQUEST_URI}!(\.[^/]*¦/)$
RewriteRule (.*) http://www.example.co.uk/username/web/$1/ [R,L]
ErrorDocument 404 /username/web/index.php?id=404 [NC]

Thanks so much for your help, it took a lot of fiddling but finally sorted it, you know, if I have any line breaks between the lines it stops working!?1!

jdMorgan

12:47 pm on Apr 20, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> ...line breaks...

Make sure that you are using a plain-text ASCII editor, such as NotePad to edit this file.

Ideally, you should use the line-enders convention that matches the server operating system: CR-LF for Windows, and LF-only for *nix. You can use a text editor that handles this, or even use MS Word, and select the correct line-ender format when doing a "Save As".

Jim

dwikristianto

2:47 am on Apr 30, 2007 (gmt 0)

10+ Year Member



if you are on windo$$ use wordpad, better than notepad to handle linebreaks.