The .htaccess file for a wordpress site looks something like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
...and there is no rewrite map set in htdocs. How does this work? How does Apache know how to rewrite these url?
The Apache does not know. All the requests are sent to index.php and Wordpress keeps an internal log of which page to redirect where, and it redirects it. So, in essence, Wordpress actually has two sets of rewrite rules, one internally and a "greedy" external rule in your .htaccess which basically makes all requests refer to the internal rewrite rules.
You may be interested in using this plugin which shows all the internal rewrites that Wordpress is doing itself.
Related
Long story short, I updated an e-commerce website but had to install the new static CMS system into a sub-directory (/wear). The main e-commerce store is still sitting in the root directory (/), and due to the large amount of products and SEO impact, I need to leave it there.
I would like to setup a requests for just index.php to redirect to /wear/
At the same time, if there is a request for index.php?XXXXX I would like it to still use the index.php file.
I've tried using the following .htaccess code but it's redirecting everything. Can anyone help me with this? I apologize for asking this as I know there are multiple threads, but none seemed to provide a good answer.
Attempt 1
RedirectMatch /index.php https://domain/wear/
Attemp 2
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /wear/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
The issue comes from your RewriteBase. When setting it up to /wear/, RewriteRule ^index\.php$ - [L] actually translates to RewriteRule ^wear/index\.php$ - [L] which is not really what you want.
I would try something like this:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^index\.php$ /wear/ [L,R=301]
What it does is: check that the query string is empty, and if it is, redirect index.php (at the beginning of the request URI, so /index.php only) to /wear/
You will also need to make sure than mod_rewrite is active.
To do so, you can remove the <IfModule mod_rewrite.c> and </IfModule> parts. If mod_rewrite is not available, it will trigger an Error 500 as the RewriteEngine command will not be recognised.
I've taken over a former site/domain, and set up a new site using Wordpress. The WP installation rewrites URL's to static ones, as you'd expect it to.
At the same time I want to preserve the former pages, as they have incoming links. I'm not interested in 301'ing them to "new" pages.
The old URL structure is /index.php?id=123, which I suspect is causing the problem with the WP .htaccess file. For reference, this is what it looks like:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
I've tried adding the following:
RewriteRule ^([0-9]+).html index.php?id=$1 [R,L]
Doesn't work. Just redirects to site.com/?id=123 and shows the front page.
I should add that I plan on just adding these new pages as regular static HTML files in the format of 123.html, 321.html etc.
How do I use .htaccess to make this work together with the WP installation and what WP puts into the .htaccess file?
To clarify:
I want to have my 123.html static HTML page be index.php?id=123. When you access index.php?id=123 it should bring up 123.html, but show index.php?id=123 in the address bar. If you access 123.html it should 301 to index.php?id=123.
To map an URL with a querystring up to an actual file you'll need to use a RewriteCond to match the querystring itself (as RewriteRule doesn't):
Something along these lines ought to do it:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# retrieve X.html when index.php?id=X is requested
RewriteCond %{REQUEST_FILENAME} index\.php
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
RewriteCond %1.html -F
RewriteRule .* %1.html? [L]
# standard WordPress routing
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
This will first check to see if you've got a request for index.php with a querystring like id=X.
Then it'll check to see if a file called X.html actually exists; I'm not 100% happy about having to use the more system hungry subrequest file check -F rather than the standard -f but I can't see a way around it in .htaccess in this case.
If X.html actually exists, it'll fetch that file whilst leaving the URL as index.php?id=X.
However if that file doesn't exist it'll fall back to standard WordPress no file, no directory routing to index.php
I'm not a WordPress expert but that should work; I guess the main WordPress controller uses $_SERVER['REQUEST_URI'] to determine the action.
Note: This won't, however, prevent people from accessing 123.html directly by going to the URL www.site.com/123.html - I kept falling into infinite loops and Apache 500 errors trying to prevent that :|
I am trying to create mod_rewrite rules to redirect the following url in my wordpress site:
www.mywebsite.com/pg/2/row/20/filter/all/filtercity/foo,bar
to
www.mywebsite.com/detail?pg=2&row=20&filter=all&filtercity=foo,bar
My problem is that wordpress included the following rules in the .htaccess:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
I tried the following RewriteRule and it kind of works if I comment the last RewrireRule from Wordpress.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule . /index.php [L]]
RewriteRule ^pg/([a-zA-Z0-9]+)/?$ ?pg=$2 [R]
</IfModule>
# END WordPress
The above works only for urls like
www.mywebsite.com/pg/2 => www.mywebsite.com?pg=2
A few questions:
1 - how can I configure .htaccess to process the url only when it finds the following keys
/pg and/or /row and/or /filter and/or /filtercity
for all other urls, it should execute the standard Wordpress RewriteRule . /index.php
2 - also the url can have all of the keys or only a few of them. For example:
/pg/2/row/20
/row/20/filter/all
how can I configure the .htaccess to process all the different combinations of keys?
3 - when I tried replacing
RewriteRule ^pg/([a-zA-Z0-9]+)/?$ ?pg=$2 [R]
with
RewriteRule ^pg/([a-zA-Z0-9]+)/?$ detail?pg=$1 [R]
I got a 404 error from the server. Not sure why. Any ideas?
Thank you.
EDIT 1:
I tried adding [L] to the end of my RewriteRule (see below)
RewriteRule ^pg/([a-zA-Z0-9]+)/?$ ?pg=$1 [R,L]
and moving the standard Wordpress rewrite rule to the next line
RewriteRule . /index.php [L]
After doing that I no longer get server 404 error. However the CSS files stop loading.
1 - how can I configure .htaccess to process the url only when it
finds the following keys
/pg and/or /row and/or /filter and/or /filtercity
Read this Rewrite URL with .htaccess for multiple parameters
The above answer helps you to solve your problem when have a standard url format.
2 - also the url can have all of the keys or only a few of them. For
example:
/pg/2/row/20
/row/20/filter/all
You are trying to do something out of URL semantics. When you try to access a resource, the path should be same every time. You can pass pg/0/ if you are on the starting page. But who can stop you from going out of URL semantics? :) In that case you have to have all the combinations as rules in your .htaccess. Follow the above solution, with all URL combinations it will work.
My Suggestions:
Don't Struggle with .htaccess if you are not familiar and your need is only URL rewrite (it is powerful though)
Pass everything to the index file and parse in your code, for your case have a look at this page http://codex.wordpress.org/Query_Overview
We have a site running on WordPress ada.localhost.com
Now all request to base url (http://ada.localhost.com/) have to go through tracking page (track.com/c/0912321323/?u=xxx) where u parameter is where to redirect user after he is tracked.
I've created a copy of index.php (index2.php) and I want to create htaccess rule to redirect all base url traffic to:
http://track.com/c/0912321323?u=http%3A%2F%2Fada.localhost.com%2Findex2.html (http://ada.localhost.com/index2.php)
Typical WP htaccess file looks like this
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Any clue on how to set it up and if WordPress allow this configuration?
From what I found WordPress won't work with index2.php.
Solution for this is to write a plugin which deals with it.
I have started a site up using html only, switched it over to php to make my life easier and have used the following code in the .htaccess to ensure all users (who may have bookmarked) are still seeing the right pages:
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^(.+)\.html$ http://domain.com/$1.php [R,NC]
Now I am working on the news section a wordpress blog (inside a /news directory) that would be lovely to use permalinks with, when I slap the rewrite code below into my .htaccess all my files outside of the wordpress directory default to wordpresses 404, they still have the correct address in the bar, but no information.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /news/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /news/index.php [L]
</IfModule>
Can anyone help on the correct structure for the .htaccess - I tend to use snippets for specific tasks rather than write htaccess stuff.
Thanks
Your rules have to be come before the Wordpress rules and you need to add an [L] to your RewriteRule:
RewriteRule ^(.+)\.html$ http://domain.com/$1.php [R,NC,L]
Which will tell .htaccess to stop processing rules.
I would recommend a permanent (301) redirect so Google and the other search engines will update their listings:
RewriteRule ^(.+)\.html$ http://domain.com/$1.php [R=301,NC,L]