I have a PHP website. I want to convert the PHP page names into SEO friendly page names.
So, first of all I want to convert the homepage, I want to remove the mention of "index". As its a multilanguage site, there are english and french versions of the homepage.
I want:
www.abc.com/index.php?lang=fr
to become
www.abc.com/fr/
However, after that, I want other pages to keep their name, for example:
I want:
www.abc.com/links.php?lang=fr
to become
www.abc.com/fr/links/
I also want the url to work without the trailing slash.
So this:
www.abc.com/fr/links
should give the same page as this:
www.abc.com/fr/links/
and this:
www.abc.com/fr
should give the same page as this:
www.abc.com/fr/
The contents of my htaccess file so far is below.
It enables me to change the links page correctly, however, I can't figure out how to do the index page in the way I describe above (plus it is possible that the code below is very bad, as I am only a starter on htaccess so don't hold back on the criticism, I'm mainly advancing by guesswork so far...)
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/index(/*)$ index.php?lang=$1 [L]
RewriteRule ^(.+)/links(/*)$ links.php?lang=$1 [L]
I would match allowed languages explicitly to have more control about what URLs are matched.
If you had "fr" and "en" allowed, it should work with the following:
RewriteEngine On
# Rewrite /fr/links and /fr/links/ to links.php?lang=fr
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(en|fr)/(.+)(/?)$ $2.php?lang=$1 [L]
# Rewrite /fr and /fr/ to index.php?lang=fr
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(en|fr)(/?)$ index.php?lang=$1 [L]
While this should work, I would rather go a different route in the actual implementation. I would redirect all requests to a single index.php file and do the route matching there, which keeps your .htaccess clean and simple:
RewriteEngine On
# Rewrite everything not existing to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]
And in index.php parse language and page and do your includes appropriately.
Related
I have this url:
www.mywebsite.com/news/best-ever-phones
The part best-ever-phones is variable and could be anything.
index.php file is checking database for article with url best-ever-phones
The problem is that in ./news/.htaccess file I have this code:
RewriteEngine On
RewriteBase /news/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\w-]+)/?$ index.php?article=$1 [L,QSA]
which is supposed to load index.php file but server returns error 404 Not found when I visit www.mywebsite.com/news/best-ever-phones url.
What is wrong?
Try this
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?article=$1 [L]
I think the problem may be with Rewrite base and your relative path. But this is how i'ld do it.
<IfModule mod_rewrite.c>
Options -Indexes
RewriteEngine On
RewriteRule ^news/([A-Za-z-.]+)/?$ news.php?article=$1 [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ $1.php [NC,L]
</IfModule>
This should fix you up, rename your index to news.php
Perhaps give this a shot:
RewriteEngine On
RewriteBase /news/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\w-\/]+)\/?$ index.php?article=$1 [L,QSA]
This is presuming that you want the / character to appear in your $article variable, so you can logically separate different parts of the friendly URI if you want to in /news/index.php. Otherwise, single segment friendly URIs like /news-item-1 or whatnot can end with a trailing slash or not.
Really you don't want trailing slashes, as it might result in duplicate content penalties for loading the same page with a different URL (the / counts), so you could either not match \/? outside of the capture group or 301 redirect in index.php to the URL with the trailing slash removed. This way you also have clean query arguments, e.g. /news/something-big?orly=yes instead of /news/something-big/?orly=yes
I am using this site to test the rewrites. Otherwise untested as we don't have your code handy, so no way to tell whether it would work or not in your environment.
This code is used when we click on any url it will hide its extension.
But If you want to goto index.php page then write
echo 'Index Page ';
?>
I am building a clean url system using .htaccess and php.
The main idea is to rewrite everything to index.php and to split the url to segments separated by /.
It works but when I upload it to web server I get an infinite loop error.
My .htaccess file is:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
If I get things correctly - the problem is that it redirects index.php to itself but it shouldn't because I have index.php file that handles everything and RewriteCond %{REQUEST_FILENAME} !-f which should prevent that rewrite.
Could you please help me with this .htaccess - I want it to rewrite everything to index.php and to be as portable as it can be, so I can use it in:
www.mysite.com
www.myothersite.com
or even
www.mysite.com/new/
I also want to redirect something like www.mysite.com/articles/2 to index.php as well as www.mysite.com/articles/it/2 or even www.mysite.com/articles/it/search/searchterm
Here's code taken from Drupal's .htaccess which uses the "clean urls" approach you are trying to achieve.
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
In this case, it appends the clean URL as the "q" querystring parameter. So then your script can detect what content to deliver based on $_GET['q'].
And here's another approach, this one from Wordpress.
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
This one specifically looks for requests to index.php and filters them out before doing the redirection.
I have a problem with mod_rewrite.
I want to redirect those URIs in the title. I use the following rule
RewriteEngine on
RewriteCond $1 !^(folders not to be redirected e.g. css|images)
RewriteCond $1 !^(.*).(file extension e.g. png|css|txt|php)
RewriteRule ^(.*)$ index.php?id=$1 [L]
It work only if I put all the resources in a folder, else it would tell me:
"/foo/index.php" not found.
So to solve that I put all the resources in the folder "www"
But when I try to load the resources from a subfolder of e.g. "foo" it tells me:
The requested URL "/foo/foo2" was not found on this server.
How can I load resources from a subfolder like "/foo/foo2" or even "/foo/foo2/foo3"?
And how can I solve the problem with the automatic search for index.php in a folder?
I believe you can use the following to achieve your desired result. It doesn't filter by file extension, but rather checks to see if the file actually exists. One thing that is a little different is that it first appends a trailing slash to your links, something you may not want.
RewriteEngine on
RewriteBase /
# This appends a trailing slash. You will have to update http://so with your domain.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://so/$1/ [L,R=301]
# This does the internal redirect
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)/$ /index.php?id=$1 [L]
If you don't want the tailing slashes, you could use the following
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?id=$1 [L]
My end goal is to have something like this.
127.0.0.1/site/search/search-term
Rather than,
127.0.0.1/site/search.php?term=
I have tried two pieces of code, first being.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ../search.php?term=$1
And i put this inside a folder called /search. The HTACCESS works perfectly but the css gets messed up for my website, it just shows everything as plain text without any styling.
Secondly i tried
RewriteEngine On
RewriteBase /search/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ../search.php?term=$1
And put that in 127.0.0.1/site/ root. But when i tried 127.0.0.1/site/search/searchterm I get a 404.
Can anyone see where i am going wrong? I am guessing the first option is the best one to work towards getting fixed as it is so close, i look through the source of the page i receive after using the vainty url and i think it might be something to do with how im linking the style sheet? It works if i put the full address in for the link (127.0.0.1/site/main.css) But then all it fails on all my jquery includes etc. Is it wise to just put the full address in when ever i want to use vanity urls?
First make sure you're using absolute paths in CSS, JS and images files. That means path to these resources should either start with a slash / or http://. If you don't already have it then please make necessary code changes. Once that is done use following .htaccess in $DOCUMENT_ROOT (not in $DOCUMENT_ROOT/site):
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^site/search/(.+)/?$ site/search.php?term=$1 [L,QSA,NC]
EDIT: As per your comments here is the code to make a URI in lowercase:
First add this line in section OR at the end of your httpd.conf file:
RewriteMap lc int:tolower
Then have your rules like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^site/search/(.+)/?$ site/search.php?term=${lc:$1] [L,QSA,NC]
Let me preface by saying that I'm fairly new to .htaccess authoring and have usually left the nitty gritty up to my hosting provider. I've recently decided to implement a hand rolled MVC framework in php and was using the .htaccess file to redirect using "seo" friendly urls. My MVC implementation uses the variables module, class, event, and parameter. They are specified in the url in that order, e.g. http://mydomain.com/module/class/event/parameter. I want it to work if you chop off any part of the url. This was all working fine until I moved my site up one level and subsequently copied my .htaccess file. Now I'm getting an infinite redirect loop with one of the rules that was working fine before I moved it.
Here is my .htaccess file:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^$ /index.php?module=default&class=home [QSA,L]
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)$ /index.php?module=$1 [QSA,L]
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ \
/index.php?module=$1&class=$2&event=$3 [QSA,L]
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)$ \
/index.php?module=$1&class=$2&event=$3¶meter=$4 [QSA,L]
Now, if I take out the section that reads:
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)$ /index.php?module=$1 [QSA,L]
It works great. The problem is if I leave that out and someone types http://mydomain.com/module I get a 404 (since that directory doesn't exist and none of the rules are matching). So why does that rule now not work and why did it work when index.php (and this .htaccess file) are in a sub-directory?
Well it looks like the php router solution is the best. Thanks to #prodigitalson for the heads up.
Here is the simplified .htaccess I am now using
RewriteEngine On
# Disable rewriting for existing files or directories
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# redirect all other requests to index.php
RewriteRule ^.*$ index.php [PT,L]
RewriteRule ^$ index.php [PT,L]
And this "magic" line of code does all the heavy lifting that the .htaccess was doing before:
$url = explode('/', trim($_SERVER['REQUEST_URI'], '/'));
Now I can assign my module, class, event, and parameter values from the $url array. It also solves a problem I had where I may need more than one parameter to an event. I didn't want to have to keep adding rules to the .htaccess file for each level. Now I can supply an arbitrary number of parameters and deal with the routing logic in code.