Rewrite single and consecutive underscores to dashes - apache

I'm trying to rewrite URLs with underscores in to dashes for a shopping site.
Product names currently have underscores for spaces. A typical URL is as follows:
http://test.local/category-name/product_name_a
My current .htaccess is as follows and successfully rewrites this to:
http://test.local/category-name/product-name-a
RewriteEngine On
RewriteBase /
#Rewrite Underscores to dashes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^_]*)_([^_]*)$ $1-$2 [L,R=302,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^_]*)_+(.+)$ $1-$2 [L]
# Redirect to index.php & standard Opencart stuff
RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L]
RewriteRule ^download/(.*) /index.php?route=error/not_found [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
However some products have consecutive underscores in them such as
http://test.local/category-name/product__name__b
or a mixture of the two such as:
http://test.local/category-name/product__name_a
I've tried and failed to get these to rewrite to:
http://test.local/category-name/product--name--b
http://test.local/category-name/product--name-a
Without breaking the existing rewrites. Any help much appreciated.

Just tweak your regex in 2nd rule:
RewriteEngine On
RewriteBase /
#Rewrite Underscores to dashes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^_]*)_([^_]*)$ $1-$2 [L,R=302,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^_]*)_(.+)$ $1-$2 [L]
# Redirect to index.php & standard Opencart stuff
RewriteRule ^sitemap\.xml$ index.php?route=feed/google_sitemap [L]
RewriteRule ^googlebase\.xml$ index.php?route=feed/google_base [L]
RewriteRule ^download/(.*) /index.php?route=error/not_found [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

Related

Infinite redirect after htaccess

RewriteEngine On
RewriteBase /worksheet/
# \?\S matches at least one character after ?
RewriteCond %{THE_REQUEST} \s/(worksheet/rebus)/\?\S [NC]
RewriteRule ^ /%1/? [R=301,L]
RewriteRule ^rebus/?$ /worksheet/rebus/? [L,R=301,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)?$ index.php?url=$2&tableName=$1 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)?$ index.php?url=$2&tableName=$1 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)?$ index.php?url=$2&tableName=$1&showSol=$3 [L,QSA]
I changed it for
xyz.com/worksheet/rebus/?random=testing11
to be forwarded for
xyz.com/worksheet/rebus/
buts its endup in infinite redirect.
With your shown samples, please try following htaccess Rules file. Please make sure you keep your htaccess Rules file along with worksheet folder NOT inside worksheet folder.
Clear your browser cache before testing your URLs.
RewriteEngine On
RewriteBase /worksheet/
# \?\S matches at least one character after ?
RewriteCond %{THE_REQUEST} \s/(worksheet/rebus)/\?\S [NC]
RewriteRule ^ /%1/? [R=301,L]
RewriteRule ^rebus/?$ /worksheet/rebus/? [L,R=301,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ index.php?url=$2&tableName=$1&showSol=$3 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?url=$2&tableName=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ index.php?tableName=$1 [L,QSA]

Rewrite htaccess so it doesn't need to repeat itself

I have one big htaccess file that does all the redirects for a site. Here is what I do for each directory:
RewriteRule ^CAKE_MIX/.php$ CAKE_MIX/index.php [R,L]
RewriteRule ^CAKE_MIX$ CAKE_MIX/ [R,L]
RewriteRule CAKE_MIX/faqs.php$ /faqs/faqs.php?cat=CAKE_MIX [QSA]
RewriteRule CAKE_MIX/index.php$ /overview/overview.php?cat=CAKE_MIX [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /CAKE_MIX/*
RewriteRule . /faqs/faqs.php?cat=CAKE_MIX&question=%{REQUEST_URI}
RewriteRule ^COOKIE_DOUGH/.php$ COOKIE_DOUGH/index.php [R,L]
RewriteRule ^COOKIE_DOUGH$ COOKIE_DOUGH/ [R,L]
RewriteRule COOKIE_DOUGH/faqs.php$ /faqs/faqs.php?cat=COOKIE_DOUGH [QSA]
RewriteRule COOKIE_DOUGH/index.php$ /overview/overview.php?cat=COOKIE_DOUGH [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /COOKIE_DOUGH/*
RewriteRule . /faqs/faqs.php?cat=COOKIE_DOUGH&question=%{REQUEST_URI}
And I do this for 18 different directories. How would I rewrite the htaccess to say something like "for any of the following directories: COOKIE_DOUGH, CAKE_MIX,ICE_CREAM, follow these rules?" and then the rules could be like:
RewriteRule ^DIRECTORY/.php$ DIRECTORY/index.php [R,L]
And would only have to be written once? Is that possible?
You can use regex alternation:
RewriteRule ^(CAKE_MIX|COOKIE_DOUGH|ICE_CREAM)/\.php$ $1/index.php [R,L]
RewriteRule ^(CAKE_MIX|COOKIE_DOUGH|ICE_CREAM)$ $1/ [R,L]
RewriteRule (CAKE_MIX|COOKIE_DOUGH|ICE_CREAM)/faqs\.php$ /faqs/faqs.php?cat=$1 [QSA]
RewriteRule (CAKE_MIX|COOKIE_DOUGH|ICE_CREAM)/index\.php$ /overview/overview.php?cat=$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /(CAKE_MIX|COOKIE_DOUGH|ICE_CREAM)/
RewriteRule . /faqs/faqs.php?cat=%1&question=%{REQUEST_URI}

htaccess issue in accessing the directory

My Blog link is http://www.example.com/blog when i am trying to access it it converts the url into http://www.example.com/blog/?ID=blog which is not correct. But when i put the backslash at the end of the blog it works fine but i don't want this back slash at the end
I try to change every thing inside htaccess file but failed.
Here is my htaccess file
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ - [L]
RewriteRule ^products products.php
RewriteRule ^websitemap sitemap.php
RewriteRule ^aboutus aboutus.php
RewriteRule ^clients clients.php
RewriteRule ^shoppingcart inq.php
RewriteRule ^contactus contact.php
RewriteRule ^finished finished.php
RewriteRule ^product/([a-zA-Z0-9_-]+)$ product_large.php?ID=$1
RewriteRule ^([a-zA-Z0-9_-]+)$ category.php?ID=$1
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ products.php?ID=$2&MID=$1
ErrorDocument 404 http://www.example.co.uk/error404.php
RewriteCond %{HTTP_HOST} ^example.co.uk$
RewriteRule ^/?$ "http\:\/\/www\.example\.co\.uk\/" [R=301,L]
Insert this rule after RewriteRule ^ - [L] to force a trailing slash:
DirectorySlash On
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{THE_REQUEST} \s/+(.*?)[^/][?\s]
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=301]
RewriteRule ^blog(/.*)?$ - [L,NC]
# your rest of the rules

URL RewriteRule in .htaccess for index.php query parameters

Example URL's:-
www.domain.com/index.php?bob
www.domain.com/index.php?jane
www.domain.com/index.php?fred
Need rewriting like:-
www.domain.com/bob
www.domain.com/jane
www.domain.com/fred
Have tried with many variations now but the closest I can get to is:-
www.domain.com/?bob
www.domain.com/?jane
www.domain.com/?fred
The below in .htaccess achieves this...
RewriteRule ^(.*)$ index.php?$1 [L,QSA]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)/index\.php [NC]
RewriteRule ^ %1 [R=301,L]
Please could someone point out what I need to modify to bin the ? (question mark) in the URL?
Edit
Just noticed that since applying the answer given by anubhava below that robots.txt for example doesn't resolve to the .txt file but just displays the homepage.
.htaccess below:-
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} \s/+index\.php\?([^\s&]+) [NC]
RewriteRule ^ %1? [R=301,L]
RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L]
RewriteRule ^download/(.*) /index.php?route=error/not_found [L]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#pos1
RewriteRule ^([^/]+)/?$ index.php?$1 [L,QSA] <--
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
#pos2
If I add the <-- line in pos1, the robots.txt URL returns a 404 page not found error.
If I add the <-- line in pos2, the robots.txt URL just displays the homepage.
Edit2
In the meantime, I have excluded robots.txt from rewrites by adding the following under Rewrite Base /:-
RewriteRule ^robots.txt - [L]
You can use this code:
RewriteEngine On
RewriteCond %{THE_REQUEST} \s/+index\.php\?([^\s&]+) [NC]
RewriteRule ^ %1? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ index.php?$1 [L,QSA]
You can also use this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ %{ENV:BASE}index.php [QSA,L]

add trailing slash and remove .htaccess

How can I do something like this that:
website.com/store/ redirect to website.com/store
website.com/outbound/store/5 redirect to website.com/outbound/store/5/
what I want is to have for urls without prefix to remove trailing slash and for those with prefix to add trailing slash
my .htaccess:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)/$ /$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^pa/?$ /admin/index.php [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/?$ stores.php?store=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^outbound/([^/]*)/([^/]*)$ /outbound.php?type=$1&id=$2 [L]
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
# force tailing slash for all urls starting with /outbound/
RewriteRule ^outbound/.*[^/]$ /$0/ [R=301,L]
#remove tailing slash for all except urls starting with /outbound/
RewriteCond $1 !^outbound/
RewriteRule ^(.+)/$ /$1 [R=301,L]
RewriteRule ^pa/?$ /admin/index.php [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^outbound/([^/]*)/([^/]*)/$ /outbound.php?type=$1&id=$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)$ stores.php?store=$1 [L]
I also cleaned it up a bit.