Next Spaceship

Driving into future…

How to Translate Apache’s “RewriteRule” Into Nginx’s “Rewrite”

| Comments

There are many cases you need to use friendly url. If you are using Apache, tipcially you can activate the URL rewriting module and write some rewriting rules with .htaccess file; While if you are using Nginx, you can also write some rewriting rules. Both of them support regular expression, so it’s easy to translate from one to the other.

To translate from the Apache’s rewriting rule to the Nginx’s, simply do the following substitutions:

  1. Replace RewriteRule with rewrite
  2. Replace ^ with ^/
  3. Replace [L] or [QSA,L] with last; (note the “;” is needed)
  4. If a rule contains curly braces( { or } ), you need to surround the regular expression with quotes.

    That’s all.

Here I will use an example to show how to do this. The following rules are automaticaly generated by PrestaShop(Prestashop doesn’t provide the Nginx’s rewrite rules): (I’m using the latest version of PrestaShop, currently it’s 1.4.8)

RewriteRule ^([a-z0-9]+)\-([a-z0-9]+)(\-[_a-zA-Z0-9-]*)/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1-$2$3.jpg [L] 
RewriteRule ^([0-9]+)\-([0-9]+)/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1-$2.jpg [L] 
RewriteRule ^([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$1$2.jpg [L] 
RewriteRule ^([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$2/$1$2$3.jpg [L] 
RewriteRule ^([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$2/$3/$1$2$3$4.jpg [L] 
RewriteRule ^([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$2/$3/$4/$1$2$3$4$5.jpg [L] 
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6.jpg [L] 
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7.jpg [L] 
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8.jpg [L] 
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9.jpg [L] 
RewriteRule ^c/([0-9]+)(\-[_a-zA-Z0-9-]*)/[_a-zA-Z0-9-]*\.jpg$ /img/c/$1$2.jpg [L] 
RewriteRule ^c/([a-zA-Z-]+)/[a-zA-Z0-9-]+\.jpg$ /img/c/$1.jpg [L] 
RewriteRule ^([0-9]+)(\-[_a-zA-Z0-9-]*)/[_a-zA-Z0-9-]*\.jpg$ /img/c/$1$2.jpg [L] 
RewriteRule ^([0-9]+)\-[a-zA-Z0-9-]*\.html /product.php?id_product=$1 [QSA,L]
RewriteRule ^[a-zA-Z0-9-]*/([0-9]+)\-[a-zA-Z0-9-]*\.html /product.php?id_product=$1 [QSA,L]
RewriteRule ^([0-9]+)\-[a-zA-Z0-9-]*(/[a-zA-Z0-9-]*)+ /category.php?id_category=$1&noredirect;=1 [QSA,L]
RewriteRule ^([0-9]+)\-[a-zA-Z0-9-]* /category.php?id_category=$1 [QSA,L]
RewriteRule ^([0-9]+)__([a-zA-Z0-9-]*) /supplier.php?id_supplier=$1 [QSA,L]
RewriteRule ^([0-9]+)_([a-zA-Z0-9-]*) /manufacturer.php?id_manufacturer=$1 [QSA,L]
RewriteRule ^content/([0-9]+)\-([a-zA-Z0-9-]*) /cms.php?id_cms=$1 [QSA,L]
RewriteRule ^content/category/([0-9]+)\-([a-zA-Z0-9-]*) /cms.php?id_cms_category=$1 [QSA,L]
RewriteRule ^page-not-found$ /404.php [QSA,L]
RewriteRule ^address$ /address.php [QSA,L]
RewriteRule ^addresses$ /addresses.php [QSA,L]
RewriteRule ^authentication$ /authentication.php [QSA,L]
RewriteRule ^best-sales$ /best-sales.php [QSA,L]
RewriteRule ^cart$ /cart.php [QSA,L]
RewriteRule ^contact-us$ /contact-form.php [QSA,L]
RewriteRule ^discount$ /discount.php [QSA,L]
RewriteRule ^guest-tracking$ /guest-tracking.php [QSA,L]
RewriteRule ^order-history$ /history.php [QSA,L]
RewriteRule ^identity$ /identity.php [QSA,L]
RewriteRule ^manufacturers$ /manufacturer.php [QSA,L]
RewriteRule ^my-account$ /my-account.php [QSA,L]
RewriteRule ^new-products$ /new-products.php [QSA,L]
RewriteRule ^order$ /order.php [QSA,L]
RewriteRule ^order-follow$ /order-follow.php [QSA,L]
RewriteRule ^quick-order$ /order-opc.php [QSA,L]
RewriteRule ^order-slip$ /order-slip.php [QSA,L]
RewriteRule ^password-recovery$ /password.php [QSA,L]
RewriteRule ^prices-drop$ /prices-drop.php [QSA,L]
RewriteRule ^search$ /search.php [QSA,L]
RewriteRule ^sitemap$ /sitemap.php [QSA,L]
RewriteRule ^stores$ /stores.php [QSA,L]
RewriteRule ^supplier$ /supplier.php [QSA,L]

Here are the corresponding rules for Nginx:

    rewrite ^/([a-z0-9]+)\-([a-z0-9]+)(\-[_a-zA-Z0-9-]*)/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1-$2$3.jpg last;
    rewrite ^/([0-9]+)\-([0-9]+)/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1-$2.jpg last;
    rewrite ^/([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$1$2.jpg last;
    rewrite ^/([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$2/$1$2$3.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$2/$3/$1$2$3$4.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$2/$3/$4/$1$2$3$4$5.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9.jpg last;
    rewrite ^/c/([0-9]+)(\-[_a-zA-Z0-9-]*)/[_a-zA-Z0-9-]*\.jpg$ /img/c/$1$2.jpg last;
    rewrite ^/c/([a-zA-Z-]+)/[a-zA-Z0-9-]+\.jpg$ /img/c/$1.jpg last; 
    rewrite ^/([0-9]+)(\-[_a-zA-Z0-9-]*)/[_a-zA-Z0-9-]*\.jpg$ /img/c/$1$2.jpg last;
    rewrite ^/([0-9]+)\-[a-zA-Z0-9-]*\.html /product.php?id_product=$1 last;
    rewrite ^/[a-zA-Z0-9-]*/([0-9]+)\-[a-zA-Z0-9-]*\.html /product.php?id_product=$1 last;
    rewrite ^/([0-9]+)\-[a-zA-Z0-9-]*(/[a-zA-Z0-9-]*)+ /category.php?id_category=$1&noredirect;=1 last;
    rewrite ^/([0-9]+)\-[a-zA-Z0-9-]* /category.php?id_category=$1 last;
    rewrite ^/([0-9]+)__([a-zA-Z0-9-]*) /supplier.php?id_supplier=$1 last;
    rewrite ^/([0-9]+)_([a-zA-Z0-9-]*) /manufacturer.php?id_manufacturer=$1 last;
    rewrite ^/content/([0-9]+)\-([a-zA-Z0-9-]*) /cms.php?id_cms=$1 last;
    rewrite ^/content/category/([0-9]+)\-([a-zA-Z0-9-]*) /cms.php?id_cms_category=$1 last;
    rewrite ^/page-not-found$ /404.php last;
    rewrite ^/address$ /address.php last;
    rewrite ^/addresses$ /addresses.php last;
    rewrite ^/authentication$ /authentication.php last;
    rewrite ^/best-sales$ /best-sales.php last;
    rewrite ^/cart$ /cart.php last;
    rewrite ^/contact-us$ /contact-form.php last;
    rewrite ^/discount$ /discount.php last;
    rewrite ^/guest-tracking$ /guest-tracking.php last;
    rewrite ^/order-history$ /history.php last;
    rewrite ^/identity$ /identity.php last;
    rewrite ^/manufacturers$ /manufacturer.php last;
    rewrite ^/my-account$ /my-account.php last;
    rewrite ^/new-products$ /new-products.php last;
    rewrite ^/order$ /order.php last;
    rewrite ^/order-follow$ /order-follow.php last;
    rewrite ^/quick-order$ /order-opc.php last;
    rewrite ^/order-slip$ /order-slip.php last;
    rewrite ^/password-recovery$ /password.php last;
    rewrite ^/prices-drop$ /prices-drop.php last;
    rewrite ^/search$ /search.php last;
    rewrite ^/sitemap$ /sitemap.php last;
    rewrite ^/stores$ /stores.php last;

So, the complete nginx configuration is:

server {
    #listen   80; ## listen for ipv4; this line is default and implied
    #listen   [::]:80 default ipv6only=on; ## listen for ipv6

    root /prestashop;
    index index.php index.html index.htm;

    # Make site accessible from http://localhost/
    server_name localhost;


    rewrite ^/([a-z0-9]+)\-([a-z0-9]+)(\-[_a-zA-Z0-9-]*)/[_a-zA-Z0-9-]*\.jpg$ /img/p/$1-$2$3.jpg last;

    ......

    rewrite ^/supplier$ /supplier.php last;


    rewrite_log on;


    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to index.html
        try_files $uri $uri/ /index.html =404;
        # Uncomment to enable naxsi on this location
        # include /etc/nginx/naxsi.rules
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
    #   # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

        fastcgi_pass 127.0.0.1:9000;

        fastcgi_index index.php;
        include fastcgi_params;
    }
}

However, for more complicate rules, you need more work to translate. There is a online tool, which maybe helpful, but as the author says, “you still need to check the result manually before use”.

Comments