Forum Moderators: phranque
I'm having trouble with url rewrite. I'm using WordPress with pretty permalink turned on and I'm trying to rewrite /category/xyz/ to /blog/category/xyz/.
I've tried using either one of the following rules but neither works. And somehow it works when I tried R=301 redirect.
RewriteRule ^blog/category/([^/]+)/$ /index.php?category_name=$1 [L]
RewriteRule ^blog/category/([^/]+)/$ /category/$1/ [L]
What is it that I'm doing wrong? And how come it works when I do R=301?
Thanks in advance.
The most common problem when rewriting from a "virtual directory" URL to a different directory-level path is that on-page links to images, CSS, and JavaScript files will not work if those links are given in page-relative format. This is because it is the client (e.g browser) which resolves relative links, and the browser thinks that those objects will be located relative to the directory (in this example "/blog/category/<something>/" in its address bar. So those page-relative links won't be resolved correctly.
The simplest way to fix this problem is to use server-relative or canonical links; That is, use <img src="/images/logo-gif"> or <img src="http://www.example.com/images/logo-gif"> instead of <img src="images/logo-gif">
Jim
I wanted to modify the wordpress permalink structure and I've tried it with 2 different rules:
1. Rewrite to wordpress permalink, /blog/category/xyz/ to /category/xyz/
RewriteRule ^blog/category/([^/]+)/$ /category/$1/ [L]
2. Rewrite to query string, /blog/category/xyz/ to /index.php?=category_name=xyz
RewriteRule ^blog/category/([^/]+)/$ /index.php?category_name=$1 [L]
I've tried typing the url (http://mydomain.com/blog/category/xyz/) in the address bar as well as linking it in html (both href="/blog/category/xyz/" and href="mydomain.com/blog/category/xyz/"), but all I get is 404 Not Found.
I then tried redirecting by adding R=301 to both rules to double check if there was anything wrong and somehow both worked, meaning it redirected to the page that I wanted it to display.
So my questions are:
1. What am I doing wrong?
2. How come it works when redirecting but not rewriting?
Thanks!
I'm not sure why some servers are set up this way, but some are. I see it as an error in the DocumentRoot specification, but there must be some plausible reason why hosts do this.
Jim
RewriteRule ^blog/category/([^/]+)/$ /category/$1/ [L] I would assume that rule is back to front (as coded it only works if user requests "example.com/blog/category/foo and server tries to get the content from /category/foo inside the server), but as jd notes you need to be very clear as to which bit represents an external URL and which is the server filepath. Infact, if you are wanting to use a new URL for the content, shouldn't the target of your rewrite be a dynamic internal filepath like /index.php?category_name=$1 or something.
A rewrite works like this:
RewriteRule "what-the-user-requested" "where-it-is-inside-the-server" [L]
@g1smd
The /category/$1/ is the permalink structure from wordpress and I was just trying to see if it would work that way instead of a query string. I also had a rule that rewrite to query string in case it didn't work.
Anyway, I got it working on another host so its all good now. Thanks for the replies.
[edited by: Murasaki at 7:19 pm (utc) on Feb. 7, 2009]
I've fixed the wordpress settings and now I'm getting the same result as before (Page not found).
I'm a little curious though. If it's extra path injected by the server that is causing the problem, then how come it works for R=301 but not rewrite?
[edited by: Murasaki at 8:01 pm (utc) on Feb. 7, 2009]
If you cannot get the server error logs, then to be blunt, you need a new Web host. If you are going to be getting into technical things like mod_rewrite, you need a host that supports basic debugging resources like error logging. Otherwise, you will spend far more time than the savings of a "cheap host" will compensate for.
Go back to your external redirect rule temporarily, and modify it like this:
RewriteRule ^blog/category/([^/]+)/$ http://www.example.com/test?DocumentRoot_plus_URL-path=%{DOCUMENT_ROOT}%{REQUEST_URI}&Request_Filename=%{REQUEST_FILENAME} [R=302,L]
Request your /blog/category/xyz/ URL, ignore the resulting 404 error, and report back here with the test query string values that you see in the browser address bar.
We are simply using a bogus URL-path ("test") and some temporary query string name/value pairs to get the server to tell us where in the filesystem it is trying to find files.
I specified a 302 redirect so that if search engine spiders come around while this rule is in place, they will recognize it as a temporary redirect, and not screw up your search listings by listing this test URL in search results... (!)
Jim
I took your advice and got a new host. I had a look inside the error log and these are all I found that has /blog/category/.../ in them. I don't think these errors are from the rewrite rule though. It doesn't seem like the error log records it when I get a page not found. I don't know what the reason is but I could only guess that it's because of wordpress. It goes to the custom 404 page, and if I delete that custom 404 page it goes to index.
[Mon Feb 09 05:07:24 2009] [error] [client 124.171.xx.xx] File does not exist: /home/yoakenij/public_html/404.shtml, referer: http://example.com/blog/category/uncategorized/
[Mon Feb 09 05:07:24 2009] [error] [client 124.171.xx.xx] File does not exist: /home/yoakenij/public_html/2009, referer: http://example.com/blog/category/uncategorized/
I've tried that rule you suggested in your previous reply and this is what I got:
http://example.com/test?DocumentRoot_plus_URL-path=/home/yoakenij/public_html/blog/category/uncategorized/&Request_Filename=/home/yoakenij/public_html/blog/category
I've also tried adding the rewrite rule through wordpress according to their documentation but that didn't work out either.
I don't know if this helps but when I turned off permalink in wordpress and used the original rule (RewriteRule ^blog/category/([^/]+)/$ /?category_name=$1 [L]), the rewrite worked.
Thanks
Joe
[edited by: eelixduppy at 12:56 am (utc) on Feb. 10, 2009]
[edit reason] exemplified [/edit]
Please post all of your rules (after changing your domain name to "example.com"), and tell us what version of Apache you are using.
Jim
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
### SEARCH ###
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(index\.php)?\?s=(.+)?\ HTTP/
RewriteRule ^(index\.php)?$ /search/%2/? [R=301,L]
# Add a trailing slash
RewriteRule ^search/([^/]+)$ /search/$1/ [R=301,L]
#RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(index\.php)?\?category_name=([^/]+)\ HTTP/
#RewriteRule ^(index\.php)?$ /blog/category/%2/? [R=301,L]
#RewriteRule ^blog/category/([^/]+)/$ /?category_name=$1 [L]
RewriteRule ^blog/category/([^/]+)/$ http://example.com/test?DocumentRoot_plus_URL-path=%{DOCUMENT_ROOT}%{REQUEST_URI}&Request_Filename=%{REQUEST_FILENAME} [R=302,L]
# BEGIN WordPress
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
</IfModule>
Thanks
Joe
[edited by: jdMorgan at 2:47 pm (utc) on Feb. 10, 2009]
[edit reason] example.com [/edit]
I'm having trouble with url rewrite. I'm using WordPress with pretty permalink turned on and I'm trying to rewrite /category/xyz/ to /blog/category/xyz/.
This rule
RewriteRule ^blog/category/([^/]+)/$ /?category_name=$1 [L] When discussing mod_rewrite, it is critical to identify and state the requested URL (the linked URL that the browser requests) and the internal filepath that you want the server to associate with that URL. That is not clear here, and it's impossible to work with this stuff if both of those paths are not clearly identified.
So, please re-read what I wrote about what that rule does, and note the use of the terms "URL-path" and "file." Is that what you wanted?
Also, be aware that your 404 page won't be used at all; Any request for any URL that does not resolve to an existing file will be passed to your WordPress script, and wordpress must be configured to properly identify URLs for which it can or cannot return the correct content. If it cannot return correct content for the requested URL, then WordPress itself must issue a 404 response code and the contents of a "404 page" for the user to read.
Jim
[edited by: jdMorgan at 2:47 pm (utc) on Feb. 10, 2009]
I'm having trouble with url rewrite. I'm using WordPress with pretty permalink turned on and I'm trying to rewrite /category/xyz/ to /blog/category/xyz/.
My original goal when I started this topic was to use either
RewriteRule ^blog/category/([^/]+)/$ /?category_name=$1 [L]
to rewrite /blog/category/xyz/ to /?category_name=xyz
or,
RewriteRule ^blog/category/([^/]+)/$ /category/$1/ [L]
to rewrite /blog/category/xyz/ to /category/xyz/
I included that second rule because with permalink turned on, wordpress already do the rewrite from /category/xyz/ to /?category_name=xyz and so I wanted to try if it would work the same as my first rule. But then I decided later to just use the first rule.
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(index\.php)?\?category_name=([^/]+)\ HTTP/
RewriteRule ^(index\.php)?$ /blog/category/%2/? [R=301,L]
RewriteRule ^blog/category/([^/]+)/$ /?category_name=$1 [L]
You mentioned in your previous reply that something is stripping the /xyz/ part off /blog/category/xyz/. I have no idea why it is doing this, could you please give me some suggestions?
http://example.com/test?DocumentRoot_plus_URL-path=/home/yoakenij/public_html/blog/category/uncategorized/&Request_Filename=/home/yoakenij/public_html/blog/category
Thanks
Joe
[edited by: Murasaki at 3:59 pm (utc) on Feb. 10, 2009]
An external 301 redirect tells the client (browser or robot) that the content has moved to a new URL, asks it (not tells it) to re-request the content from a new URL, and terminates the current HTTP request. The syntax is
RewriteRule ^old-URL-path$ http://www.example.com/new-URL-path [R=301,L] An internal rewrite does not inform the client, and takes place entirely within the context of the current HTTP request -- instead simply telling the server where to find the file associated with the requested URL. The syntax is
RewriteRule ^requested-URL-path$ /non-default-server-filepath [L] So, we need to see clear statements like "I want to redirect client requests for URL-path /xyz to URL http://www.example.com/abc" or "When I get a request for URL-path xyz, I want to serve content from filepath /abc".
Think in terms of what URL the server receives in a request from the client, because this is where the redirect or rewrite process starts.
Otherwise, we can go around and around, and members will run out of time or simply lose interest in this thread...
Also, WordPress doesn't technically rewrite *anything*. You may be referring to the action of some additional code in an .htaccess file located in the WordPress subdirectory, or possibly to an "Alias" directive installed in your .httpd.conf file by the WordPress installer, but WordPress is a content-handler and therefore cannot do "a rewrite". It can issue a redirect, or it can "print" modified links on your HTML pages, but it cannot by definition do an internal rewrite.
I'm not trying to be pedantic here, but just stating the facts in hopes of clarifying things.
Since it'll be impossible to get anything resolved here unless you understand what is going on and can comunicate your requirements completely and concisely, perhaps some more basic info is needed:
Wordpress now outputs "friendly" URLs in the links that appear on your HTML pages. A user clicks on one of those links, and their browser sends a request to your server for that "friendly" URL. The request is passed through the server config files, where it might be redirected to a new URL, rewritten to a non-default server filepath, or "Aliased" to a non-default directory-path. If none of these things happen, the request is passed to your top-level .htaccess file. Within that file, your mod_rewrite code may redirect that URL to a new URL, or rewrite it to a non-default server filepath, as described above.
As long as no external redirect is invoked in your top-level .htaccess file, the request is then passed to the next .htaccess file (if any) in the subdirectory path of the now-updated server filepath. Within that file, your mod_rewrite code may redirect to a new URL, or again rewrite to a different non-default server filepath, as described above.
This continues until the subdirectory containing the file is reached and the .htaccess file in that last subdirectory has been processed. At this point, the content-handling phase is invoked, and the file is served -- or if that file is a script, it is executed to produce a new HTML page to send back to the client/browser.
Note that the setting of RewriteOptions inherit can affect whether the server behaves as described above; If the server is configured without the "inherit' setting, then mod_rewrite code in higher-level .htaccess files won't be executed; only the mod_rewrite code in the requested file's final subdirectory will execute.
So, given that process, it is critical that you (and the members here) understand your goals and requirements in terms of what URL is in the link on your HTML page and will be requested from your server, and what new URL you want that requested URL redirected to... Or what URL is in the link on your HTML page and will be requested from your server, and what internal server filepath you want to call to provide the HTML content for that requested URL. So again, "I want a client request for URL '/xyz' to be externally redirected to new URL http://www.example.com/abc", or "I want a client request for URL '/xyz' to be rewritten to server-filepath /path-to-file-abc".
The link on the HTML page in the browser *defines* the URL, and nothing you can do in the server can change that. All that the server can do is either to redirect the client to another URL when the original URL is requested, or to provide content in response to that requested URL from some server filepath that is different from what that filepath would be if the rewrite code was not present.
So the HTML page defines URLs used on the Web, you (the Webmaster) define files and filepaths inside the server, and the server's fundamental and primary job is to translate URL requests to filepaths, so that Web clients do not have to know what OS your server uses, or what your server filepaths look like.
HTH,
Jim
I simply want to change the client request URL (without turning off permalink) from '/category/xyz/' to '/blog/category/xyz/'. So that a client request for URL '/blog/category/xyz/' (http://example.com/blog/category/xyz/) will be rewritten to the same query string '/index.php?category_name=xyz' (http://example.com/index.php?category_name=xyz). And when I click on the link that has URL of http://example.com/blog/category/xyz/, it will give me the 'xyz' category page.
I hope this is clearer
Joe
[edited by: Murasaki at 1:25 am (utc) on Feb. 11, 2009]
Apache version:
Apache/2.2.11 (Unix) mod_ssl/2.2.11 OpenSSL/0.9.8b mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /### SEARCH ###
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(index\.php)?\?s=(.+)?\ HTTP/
RewriteRule ^(index\.php)?$ /search/%2/? [R=301,L]
# Add a trailing slash
RewriteRule ^search/([^/]+)$ /search/$1/ [R=301,L]RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(index\.php)?\?category_name=([^/]+)\ HTTP/
RewriteRule ^(index\.php)?$ /blog/category/%2/? [R=301,L]
RewriteRule ^blog/category/([^/]+)/$ /index.php?category_name=$1 [L]#RewriteRule ^blog/category/([^/]+)/$ http://example.com/test?DocumentRoot_plus_URL-path=%{DOCUMENT_ROOT}%{REQUEST_URI}&Request_Filename=%{REQUEST_FILENAME} [R=302,L]
# BEGIN WordPress
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress</IfModule>
To do this:
At the moment with permalink on, a client request for URL '/category/xyz/' rewrites to '/index.php?category_name=xyz'.I simply want to change the client request URL (without turning off permalink) from '/category/xyz/' to '/blog/category/xyz/'. So that a client request for URL '/blog/category/xyz/' (http://example.com/blog/category/xyz/) will be rewritten to the same query string '/index.php?category_name=xyz' (http://example.com/index.php?category_name=xyz). And when I click on the link that has URL of http://example.com/blog/category/xyz/, it will give me the 'xyz' category page.
I have tried the following:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(index\.php)?\?category_name=([^/]+)\ HTTP/
RewriteRule ^(index\.php)?$ /blog/category/%2/? [R=301,L]
RewriteRule ^blog/category/([^/]+)/$ /index.php?category_name=$1 [L]
RewriteRule ^blog/category/([^/]+)/$ /index.php?category_name=$1 [R=301,L]
RewriteRule ^blog/category/([^/]+)/$ http://example.com/test?DocumentRoot_plus_URL-path=%{DOCUMENT_ROOT}%{REQUEST_URI}&Request_Filename=%{REQUEST_FILENAME} [R=302,L]
At the moment I'm trying to find out why '/xyz/' is been stripped from the filepath but not sure if it is the one that's causing the problem.
The only part that uses REQUEST_FILENAME is the Wordpress rules
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
But no matter what it does, it shouldn't be interfering with my rewrite rule right? (Please correct if I'm wrong)
RewriteRule ^blog/category/([^/]+)/$ /index.php?category_name=$1 [L]
Joe
[edited by: Murasaki at 5:13 am (utc) on Feb. 12, 2009]
Read the codex from Wordpress http://codex.wordpress.org/Using_Permalinks
You can also try to add the rules in the Wordpress internal system by using the add_filter function and the "rewrite_rules_array" hook. Do some googling to get some example or get code for existing plugin.
add_filter('rewrite_rules_array', array('your_function','your_option'));
or
add_filter('rewrite_rules_array','yourawesomefunction');
Note that:
If you apply new rewrite rules using the rewrite_rules_array filter you need to ensure that you refresh the rewrite rules that Wordpress has stored in a hidden option. You do this by simply resaving the Permalink Structure under the Options menu in the admin area of your WP install.