So I've been searching for a while now and can't find anything specific on how to create a pretty url / seo / slug url type system WITHOUT sending everything to a index.php or moving things into subfolders.
Basically I'm making a website which you can currently go to urls like movie.php?id=#### / show.php?id=####. Ideally I'd like the url to be movie/#### or movie/id/#### (or down the line slugs of the name that i can use to grab the right one) etc.
Is there a way to do it without having a single index.php router or am I just going to have to rewrite all my files to adhere to this style?
You can create a rewrite rule in .htaccess that routes the movie urls to movie.php as follows:
movie/123:
RewriteRule ^movie/(\d+)$ movie.php?id=$1 [L]
movie/id/123:
RewriteRule ^movie/id/(\d+)$ movie.php?id=$1 [L]
movie/title-of-movie:
RewriteRule ^movie/(\S+)$ movie.php?slug=$1 [L]
movie/title/title-of-movie:
RewriteRule ^movie/title/(\S+)$ movie.php?slug=$1 [L]
combination movie/123/title-of-movie:
RewriteRule ^movie/(\d+)/(\S+)$ movie.php?id=$1&slug=$2 [L]
Edit: added a full .htaccess example for 1 required with up to 2 extra optional parameters with a fallback on index.php if the url is not for movies.
Options -Indexes
IndexIgnore */*
Options FollowSymLinks
AddDefaultCharset utf-8
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^movie/([^/]+)/?([^/]*)/?([^/]*)$ movie.php?param1=$1¶m2=$2¶m3=$3 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . index.php [L]
</IfModule>
^ to match from the beginning
$ to match until the end
? for 0 or 1 occurrence
+ for 1 or more occurrences
* for 0 or more occurrences
If the url rule does not match and the file does not exist then it will route the url to index.php, but you can remove that last part if you don't want that.
Yes, assuming your URL structure follows a relatively consistent pattern, you can definitely do this with an .htaccess file and mod_rewrite (without the need for an index.php file, commonly referred to as a front controller).
Here's a really simple example:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)/(.*)$ $1.php?id=$2 [NC,L]
This takes an incoming URL like http://example.com/movie/3 and performs a transparent/internal rewrite (so the user doesn't see the URL change) to http://example.com/movie.php?id=3.
Of course, this example could be expanded to handle more parameters, etc. but hopefully this gets you started on the right path. I highly recommend you read the mod_rewrite documentation for more details: http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html
Related
I ned to change this url
https://halopredictions.com/blog/index.php?url=german-bundesliga-prepare-to-return-on-9-may
to
https://halopredictions.com/blog/german-bundesliga-prepare-to-return-on-9-may
This is my .htaccess that am currently using
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ index.php?url=$1 [NC,L]
I have already enabled mod rewrite
The htaccess is on this path ...\blog\.htaccess
Any help I will highly appreciate
Before proceeding with the answer, if I understand correctly you want to redirect from https://halopredictions.com/blog/german-bundesliga-prepare-to-return-on-9-may To https://halopredictions.com/blog/index.php?url=german-bundesliga-prepare-to-return-on-9-may.
Since SEO Urls are used by the visitors, we have to convert them to actual path.
The below RewriteRule will be sufficient to achieve the above condition.
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^blog/([A-Za-z0-9-\+]+)/?$ blog/index.php?url=$1 [NC,L,QSA]
Explanation:
^blog/([A-Za-z0-9-\+]+)/?$ - This part is what you want to rewrite from. Since, your URLs will be like in the pattern https://halopredictions.com/blog/german-bundesliga-prepare-to-return-on-9-may, we need to get the url part after blog/.
I have used a regular expression ([A-Za-z0-9-\+]+)/? to match the url part and it can be referrenced using $1.
Now we have to use $1 in our new url. For that, we have written the second part of RewriteRule where you can assign the referrence.
blog/index.php?url=$1 - Now, as you would assume we are using the $1 reference after index.php?url=, so that it will append it to the URL Query param and should lead to a valid path.
By the way, ^ this is used to indicate the start and $ for the end.
I`ve got an internet shop and want to use htaccess to shorten links
there are 3 cases of urls:
shop.com/shop/18 (number) - products.php?categoryid=$1
shop.com/shop/18/page-2 (number)/(page+number) - products.php?categoryid=$1&page=$2
shop.com/shop/18/9877 (number)/(number) - description?categoryid=$1&productid=$2
my try
RewriteRule ^shop/?$ shop.php
RewriteRule ^shop/(.*)/([0-9]+)/?$ description.php?categoryid=$1&productid=$2
RewriteRule ^shop/(.*)/page-(.*)/?$ products.php?categoryid=$1&page=$2
RewriteRule ^shop/(.*)/?$ products.php?categoryid=$1
With my try - 1 (works), 2 (works), 3 (doesn`t work)
How can I rewrite urls so?
How can I redirect to 404 page if e.g. there is no such number of
category or such product (guess check with php and mysql and then
redirect) ?
There are a number of ways that this can be dealt with;
All in htaccess (gets messy with multiple depths)
Combined htaccess and server side code
The best approach is the one that suits you based on how your store is coded. I personally feel that handling it in the server side code is better, it simplifies the htaccess file, and gives you more control with regards to validating data, and how you handle what is sent, to where, and how its processed when it gets there.
For example, in my htaccess file I have;
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine on
#
# Do not apply rewrite rules for non required areas
RewriteCond %{REQUEST_URI} "/hidden-areas/" [OR]
RewriteCond %{REQUEST_URI} "/other-areas/"
RewriteRule (.*) $1 [L]
# Do Not apply if a specific file or folder exists
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# The rules on how to rewrite the urls
RewriteRule (.*) /index.php?url=$1 [QSA,L]
</IfModule>
Basically, to explain this in a nutshell, I DONT rewrite anything for certain folders, I forward them straight on. This is to stop calls to scripts externally, or extra added systems being able to be accessed without issue.
I then, forward the entire url as a string through to my index page, and deal with what comes through using PHP, an example is below.
// collect the passed url
$url = $_GET['url'];
// split the url into parts
$url_parts = explode('/', $url);
/*
* start sorting what is what in the url
*/
// count how many parts there are
$url_parts_count = count($url_parts);
// determine the class/module
$class = $url_parts[0]; // generally the class/method/module depending on your system, thgough could be a category so run some checks
// determine the last part in the array
$last_url_part = ($url_parts_count - 1);
// set the last part of the url to be used
$slug = $url_parts[$last_url_part]; // generally the slug and will be empty if theres a trailing slash
etc etc etc
This is just a summary, i do far more, as this is taken from a CMS I wrote, but it should give you a very good starting point should you wish to get your hands dirty. Of course, Im happy to elaborate further if necessary.
The caveat of course, is if you are using an off-the-shelf system, they should provide you with this code already ;)
I have added below something based on your updated question, this will help if you do still plan to go the way you are :)
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
#
# Do not apply rewrite rules for non required areas
RewriteCond %{REQUEST_URI} "/hidden-areas/" [OR]
RewriteCond %{REQUEST_URI} "/other-areas/"
RewriteRule (.*) $1 [L]
# Do Not apply if a specific file or folder exists
# RewriteCond %{REQUEST_FILENAME} !-f
# RewriteCond %{REQUEST_FILENAME} !-d
# The rules on how to rewrite the urls
RewriteRule ^([a-zA-Z0-9_-]+)$ /index.php?slug=$1 [QSA,L]
RewriteRule ^([a-zA-Z0-9_-]+)/$ /index.php?type=$1 [QSA,L]
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ /index.php?type=$1&slug=$2 [QSA,L]
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/$ /index.php?type=$1&cat=$2 [QSA,L]
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ /index.php?type=$1&cat=$2&slug=$3 [QSA,L]
</IfModule>
Thanks, ended with
RewriteRule ^shop$ shop.php [L]
RewriteRule ^shop/([0-9]+)$ products.php?categoryid=$1 [L]
RewriteRule ^shop/([0-9]+)/(page-[0-9]+)$ products.php?categoryid=$1&page=$2 [L]
RewriteRule ^shop/([0-9]+)/([0-9]+)$ description.php?categoryid=$1&productid=$2 [L]
I am currently making a website (http://tannernelson.me/ehs)
It's hosted on Godaddy, and I'm using wordpress as a CMS.
I want to be able to make:
http://tannernelson.me/ehs/school/academics/teachers/jsmith
turn into
http://tannernelson.me/ehs/index.php?pagename=teachers&detail=jsmith
So, basically, if there are 4 segments to the url (school/academics/teachers/jsmith) I want the last one to be a variable. So the fourth segment of any url will be the variable "detail"
My current URL rewrite is currently
# Mod Rewrite
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /ehs/index.php [L]
Options -Multiviews
It won't work any other way, even with the default WordPress .htaccess file. And I have no idea what that means, or what kind of request URI is made out of it. It's really confusing.
Any ideas?
The code you have right now means:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
If the requested filename is not (!) a regular file -f and if the requested filename is not (!) a directory -d then:
RewriteRule . /ehs/index.php [L]
Match any single character (.) and if a match is found rewrite the URL to /ehs/index.php and then make this the last rule ([L]) so don't process any further rules.
This doesn't look like what you want, but seems to be working. http://tannernelson.me/ehs/school/academics/teachers/jsmith serves up (I think) http://tannernelson.me/ehs/index.php because I get a custom 404 not found page.
Try the following .htaccess code:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# Redirect the ehs/school/academics/$1/$2 URIs to /ehs/index.php?pagename=$1&detail=$2
RewriteRule ^ehs/school/academics/([^/]+)/([^/]+)$ /ehs/index.php?pagename=$1&detail=$2 [L]
# Otherwise if the requested URI is not found (not a file nor a directory)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#Redirect everything else to index.php
RewriteRule .* /ehs/index.php [L]
Options -Multiviews
I just tested this on my Apache server and it works.
I have a site that currently serves results as example.com/index.php?show=foo
and I'd like it to read example.com/show/foo.
My understanding is this would make them visible to search engine robots, and it seems a much simpler way to do this than to create a couple hundred html files...
I've tried the following .htaccess code:
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^show/(.*)$ index.php?show=$1 [NC,L]
No dice.
Also tried this, which I found on another stack overflow question:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([0-9A-Za-z]+)/?$ /index.php?show=$1 [L]
</IfModule>
Any ideas on what I'm missing here?
Note that ^([0-9A-Za-z]+)/?$ will try to match a request URI that only includes alphanumeric characters optionally trailed by a slash. Therefore the URI show/foo will not be matched because there are more characters at the end (ie, after the slash, where the expression expects to find the end of the string).
Try:
RewriteRule ^show/([0-9A-Za-z]+)/?$ /index.php?show=$1 [L]
Also, to capture aditional query parameters, you could do:
RewriteRule ^show/([0-9A-Za-z]+)/?$ /index.php?show=$1&%{QUERY_STRING} [L]
This means a URL like /show/page?id=1 rewrites to /index.php?show=page&id=1
I do something like this on sites that use 'seo-friendly' URLs.
In .htaccess:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /index.php [L]
Then on index.php:
if ($_SERVER['REQUEST_URI']=="home") {
include ("home.php");
}
The .htaccess rule tells it to load index.php if the file or directory asked for was not found. Then you just parse the request URI to decide what index.php should do.
You're on the right track, but your rule has issues. .* is pretty all inclusive. Start there and go more restrictive if needed.
At the root of my site... www.domain.com . want to add some static pages that the page url can be set from the user.
So if the users set as url profile then full page url should be www.domain.com/profile ..
So far a simple rewrite rule would do the job.
trasnlate it to something like /staticpage.php?tag=profile
The problem that i want some pages like www.domain.com/shop at the root which arent static...
So what can i do if all the requests for the main directory go to /staticpage.php?tag=$1 ?
I recommend using mod rewrite to send everything to your index.php file and using a front controller to do this. It makes it much easier.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
</IfModule>
You'll find a lot more help about mod_rewrite on ServerFault as a general rule, but I tend to do this:
RewriteEngine on
RewriteRule ^static.*$ - [L]
RewriteRule ^assets.*$ - [L]
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule .* /router.php
where "static" are uploaded files, and "assets" are production graphics/stylesheets/js libraries etc.