Rewrite to "Pretty Url"

Reference: mod_rewrite, URL rewriting and pretty links explained

To understand what mod_rewrite does you first need to understand how a web server works. A web server responds to HTTP requests. An HTTP request at its most basic level looks like this:

GET /foo/bar.html HTTP/1.1

This is the simple request of a browser to a web server requesting the URL /foo/bar.html from it. It is important to stress that it does not request a file, it requests just some arbitrary URL. The request may also look like this:

GET /foo/bar?baz=42 HTTP/1.1

This is just as valid a request for a URL, and it has more obviously nothing to do with files.

The web server is an application listening on a port, accepting HTTP requests coming in on that port and returning a response. A web server is entirely free to respond to any request in any way it sees fit/in any way you have configured it to respond. This response is not a file, it's an HTTP response which may or may not have anything to do with physical files on any disk. A web server doesn't have to be Apache, there are many other web servers which are all just programs which run persistently and are attached to a port which respond to HTTP requests. You can write one yourself. This paragraph was intended to divorce you from any notion that URLs directly equal files, which is really important to understand. :)

The default configuration of most web servers is to look for a file that matches the URL on the hard disk. If the document root of the server is set to, say, /var/www, it may look whether the file /var/www/foo/bar.html exists and serve it if so. If the file ends in ".php" it will invoke the PHP interpreter and then return the result. All this association is completely configurable; a file doesn't have to end in ".php" for the web server to run it through the PHP interpreter, and the URL doesn't have to match any particular file on disk for something to happen.

mod_rewrite is a way to rewrite the internal request handling. When the web server receives a request for the URL /foo/bar, you can rewrite that URL into something else before the web server will look for a file on disk to match it. Simple example:

RewriteEngine On
RewriteRule /foo/bar /foo/baz

This rule says whenever a request matches "/foo/bar", rewrite it to "/foo/baz". The request will then be handled as if /foo/baz had been requested instead. This can be used for various effects, for example:

RewriteRule (.*) $1.html

This rule matches anything (.*) and captures it ((..)), then rewrites it to append ".html". In other words, if /foo/bar was the requested URL, it will be handled as if /foo/bar.html had been requested. See http://regular-expressions.info for more information about regular expression matching, capturing and replacements.

Another often encountered rule is this:

RewriteRule (.*) index.php?url=$1

This, again, matches anything and rewrites it to the file index.php with the originally requested URL appended in the url query parameter. I.e., for any and all requests coming in, the file index.php is executed and this file will have access to the original request in $_GET['url'], so it can do anything it wants with it.

Primarily you put these rewrite rules into your web server configuration file. Apache also allows* you to put them into a file called .htaccess within your document root (i.e. next to your .php files).

* If allowed by the primary Apache configuration file; it's optional, but often enabled.

What mod_rewrite does not do

mod_rewrite does not magically make all your URLs "pretty". This is a common misunderstanding. If you have this link in your web site:

<a href="/my/ugly/link.php?is=not&very=pretty">

there's nothing mod_rewrite can do to make that pretty. In order to make this a pretty link, you have to:

  1. Change the link to a pretty link:

    <a href="/my/pretty/link">
  2. Use mod_rewrite on the server to handle the request to the URL /my/pretty/link using any one of the methods described above.

(One could use mod_substitute in conjunction to transform outgoing HTML pages and their contained links. Though this is usally more effort than just updating your HTML resources.)

There's a lot mod_rewrite can do and very complex matching rules you can create, including chaining several rewrites, proxying requests to a completely different service or machine, returning specific HTTP status codes as responses, redirecting requests etc. It's very powerful and can be used to great good if you understand the fundamental HTTP request-response mechanism. It does not automatically make your links pretty.

See the official documentation for all the possible flags and options.

htaccess url rewrite for pretty url not working on Apache localhost

This htaccess looks fine. htaccess override and apache rewrite module was not enabled.
I had to edit the file /etc/apache2/apache2.conf:

<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>

and change it to;

<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>

then,

sudo a2enmod rewrite

to enable apache rewrite module .

and finally restart apache using sudo service apache2 restart to see the changes in action .

Htaccess Rewrite Pretty URL

To rewrite to index, use:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)/?$ /index.php?s=$1 [L]

And for css, scripts, or pictures, use absolutes links (which begin with / or http://...) or add <base href="/"> in html head.

.htaccess rewrite pretty URL without affecting default page

You may use this code in site root .htaccess:

# ensure permalink when url rewriting was enabled 
# (login.php?r=content/perma&id=6 => /content/perma/?id=6

RewriteEngine On

RewriteCond %{QUERY_STRING} ^r=content(/|%2)perma&id=([0-9]*)$
RewriteRule ^login\.php$ %{REQUEST_URI}/content/perma/?id=%2 [R=302,L]

# Sets the HTTP_AUTHORIZATION header removed by apache
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . login.php [L]

Pretty URLs with .htaccess

Thanks for the idea @denoise and @mogosselin. Also with @stslavik for pointing out some of the drawback of my code example.

Here's how I do it:

Options +FollowSymLinks
RewriteEngine On

RewriteRule ^user/([0-9]*)/([a-z]*)$ ./index.php?user=$1&action=$2
RewriteRule ^user/([a-z]*)$ ./index.php?user&action=$1

by using var_dump($_GET); on the link localhost/user/1234/update I got

array (size=2)
'user' => string '1234' (length=4)
'action' => string 'update' (length=3)

while localhost/user/add

array (size=2)
'user' => string '' (length=4)
'action' => string 'update' (length=3)

which is my goal. I will just only do other stuffs under the hood with PHP.

Rewrite Pretty or SEO friendly URL via htaccess

Let's understand RewriteRule directive which is the real rewriting workhorse.

A RewriteRule consists of three arguments separated by spaces. The arguments are

  • Pattern: which incoming URLs should be affected by the rule;
  • Substitution: where should the matching requests be sent;
  • [flags]: options affecting the rewritten request.

Let's start with the following snippet:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

First line of code, describes RewriteEngine is turned on. Here I use RewriteCond directive which defines a rewrite rule condition. Using RewriteCond directive we defined two conditions here. This directive took a server variable called REQUEST_FILENAME. The two conditions above tell if the request is not a file or a directory, then meet the rule set by RewriteRule. See more details on this issue.

Now it's time to write some rewrite rules. Let's convert

www.example.com/?pr=project-abc123

// to

www.example.com/project-abc123

and rewrite rule will be:

RewriteRule ^(.*)$ index.php/?pr=$1 [L]

And to get the www.example.com/pr/project-abc123 we need the rule as the below:

RewriteRule ^/?([a-z]+)/(.*)$ index.php/?$1=$2 [L]

// or

RewriteRule ^/?pr/(.*)$ index.php/?pr=$1 [L]

The [L] flag tells mod_rewrite to stop processing the rule set. This means that if the rule matches, no further rules will be processed.

mod_rewrite Clean URL rewriting

You can combine two line in one line:

RewriteEngine On
RewriteRule ^([a-zA-Z0-9-]+)/?$ something.php?query=$1

In this case / will be optional

No php extension and pretty url nginx config alternative

Try this

map $uri $pretty_url {
~/(.*)$ $1;
}

server {

...

location / {
index index.php; # replace this to 'index index.php index.html index.htm;' if needed
try_files $uri $uri/ @extensionless-php;
}

location ~ \.php$ {
# default PHP-FPM handler here
...
}

location @extensionless-php {
if ( -f $document_root$uri.php ) {
rewrite ^ $uri.php last;
}
rewrite ^ /index.php?url=$pretty_url last;
}

}

Using IIS Rewrite for Clean URLs: Any difference between matching ^ or .*?

In this context both mean the same:

  • regex ^ means beginning of a string, and is a match, even for an empty string.
  • regex .* means everything up to next newline, and is a match, even for an empty string.

Using URL Rewrite Rules for Dynamic and Pretty URLs in Wordpress

As I understand right:

  • you have page example.com/book-store/
  • you want to create urls like:

    example.com/book-store/category/{category_name}
    example.com/book-store/book/{book_id}

    where the {category_name} and {book_id} are query vars

The code you added into page-book-store.php file will not work, just because the url was queried before your code. Also, the filter add_filter('query_vars', 'add_state_var', 0, 1); will not work, too. The priority of this filter is 10, but you used 0.

To achieve your goal add this code into your functions.php file:

add_action('init', 'ww_rewrite_book_store');
function ww_rewrite_book_store(){
add_rewrite_tag('%book_id%', '([^&]+)');
add_rewrite_rule('^(book-store)/book/([^/]*)/?', 'index.php?pagename=$matches[1]&book_id=$matches[2]', 'top');

add_rewrite_tag('%category_name%', '([^&]+)');
add_rewrite_rule('^(book-store)/category/([^/]*)/?', 'index.php?pagename=$matches[1]&category_name=$matches[2]', 'top');
}

After go to Dashboard > Settings > Permalinks and just click to Save Changes button.

First, we used add_rewrite_tag() to establish the query vars. And used add_rewrite_rule() to make it work right.

For example, if your url will be example.com/book-store/category/some_category, you can use query vars( get {some_category} ) in the page-book-store.php file like:

echo get_query_var('category_name');


Related Topics



Leave a reply



Submit