Add trailing slash if url contains keyword - .htaccess

I've tried several versions of trailing slash code but none of them are working for me. I want a trailing slash to be added only when url contains a keyword news, so
domain.com/news
domain.com/news/category/foo
domain.com/news/archive/august-2018
should trigger it to add a slash. I have this right now
RewriteCond %{REQUEST_URI} ^/(news.*)$
RewriteRule ^/news(.*[^/])$ %{REQUEST_URI}/ [R=301,L]

Try using below rule,
RewriteRule ^news$ http://%{HTTP_HOST}%{REQUEST_URI}/ [R=301]

You can do this using two separate rules, one for just news on it's own, and another for news/categroy/foo:
# direct news to news/
RewriteRule ^news$ news/ [L,R=301]
# if no trailing slash, direct news/* to news/*/
RewriteCond %{REQUEST_URI} ^(.*[^/])$
RewriteRule ^news/(.*)$ news/$1/ [L,R=301]
These three rules result in:
http://www.example.com/news => http://www.example.com/news/
http://www.example.com/news/category/foo => http://www.example.com/news/category/foo/
http://www.example.com/news/archive/august-2018 => http://www.example.com/news/archive/august-2018/
You can test these rules using htaccess.madewithlove.be.

Related

Removing Double Slashes From URL By .htaccess does not work

How come that none of these solutions work on my Apache servers:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/{2,} [NC]
RewriteRule ^(.*) $1 [R=302,L]
or
RewriteCond %{REQUEST_URI} ^(.*)/{2,}(.*)$
RewriteRule . %1/%2 [R=302,L]
or
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=302,L]
among others that I tried.
I tried ALL solutions from this page: Issue In Removing Double Or More Slashes From URL By .htaccess
and other pages as well.
The problem is that the rule in the htaccess does not match the double slashes within these above patterns.
I tried also "literal" patterns, with exact urls without regex patterns. Still nothing. But with a single slash - all work.
It seems like Apache has a problem when it finds: "//" - the url is clearly not recognized and the rule is ommited.
The idea is simple: to get rid of double slashes and replace them with one slash:
http://demo.codesamplez.com/html5//audio -> http://demo.codesamplez.com/html5/audio
Do you know how can I redirect URL with double slash "//" to a single onen "/"?
Here's htaccess (removed the longest comments in the file):
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/test//slash
RewriteRule ^(.*)$ /test/slash [R=302,L]
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
# Sets the HTTP_AUTHORIZATION header removed by Apache
RewriteCond %{HTTP:Authorization} .
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]
# If the requested filename exists, simply serve it.
# We only want to let Apache serve files and not directories.
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# Rewrite all other queries to the front controller.
RewriteRule ^ %{ENV:BASE}/app.php [L]
</IfModule>
Try the following instead, near the top of the root .htaccess file, before any existing rewrites:
# Remove multiple slashes anywhere in the URL-path
RewriteCond %{THE_REQUEST} \s[^?]*//
RewriteRule (.*) /$1 [R=302,L]
This uses the fact that multiple slashes have already been reduced in the URL-path matched by the RewriteRule pattern. And the check against THE_REQUEST (which contains the first line of the request headers and does not change throughout the request) ensures that multiple slashes were initially present somewhere in the URL-path (excluding the query string).
Another potential issue is if you have a proxy server (or load balancer) in front of your application (Apache) server and this is perhaps normalizing the request (reducing multiple slashes, removing trailing space, etc) as it forwards the request to your application (Apache) server. The application server then never sees the original request (with multiple slashes) that you see in the browser.
Looking at your attempts...
RewriteCond %{REQUEST_URI} ^/test//slash
RewriteRule ^(.*)$ /test/slash [R=302,L]
This "should" work, with the limited example as posted. However, the REQUEST_URI server variable is modified throughout the request, so if the URL has already been modified (perhaps in the server config) then this may not match.
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/{2,} [NC]
RewriteRule ^(.*) $1 [R=302,L]
This only matches multiple slashes at the start of the URL-path, not anywhere in the URL-path. This would also result in a malformed redirect if used in .htaccess (unless you also had a RewriteBase directive set). Without the slash prefix on the substitution string this rule is probably intended for a server or virtualhost context, not .htaccess.
RewriteCond %{REQUEST_URI} ^(.*)/{2,}(.*)$
RewriteRule . %1/%2 [R=302,L]
The same issue with the use of REQUEST_URI as mentioned above. Otherwise, this should work. However, it results in multiple redirects if there are more than 1 group of multiple slashes. eg. //foo//bar.
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=302,L]
The same as above, except this only matches double slashes, rather than groups of two or more slashes. So if there are more than two slashes in a group it will result in multiple redirects.

.htaccess redirects with multiple paramenters

I am rebuilding a real estate site and we have completely restructured how the database handles the properties and I am now trying to redirect all of the old property urls to the new ones. The problem that I am having is that the old urls used multiple parameters(including the section and the property id) for a single property and the new urls only use a slug for the property name.
Example:
OLD: https://www.example.com/listings.php?sect=1&view=92
NEW: https://www.example.com/listings/tombstone-ranch
My current .htaccess looks like the following with the last two lines being the rewrites for converting the slugs into clean urls...all of this works fine.
RewriteEngine On
RewriteBase /
# remove .php; use THE_REQUEST to prevent infinite loops
RewriteCond %{THE_REQUEST} ^GET\ (.*)\.php\ HTTP
RewriteRule (.*)\.php$ $1 [R=301]
# remove index
RewriteRule (.*)/index$ $1/ [R=301]
# remove slash if not directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*)/ $1 [R=301]
# add .php to access file, but don't redirect
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]
RewriteRule ^listings/([a-zA-Z0-9-/]+)$ /listings/index.php?s=$1 [L]
RewriteRule ^listings/([a-zA-Z0-9-/]+)/$ /listings/index.php?s=$1 [L]
The Problem that I am having is that neither of the following seems to work:
Redirect 301 /listings.php?sect=1&view=92 /listings/tombstone-ranch
and neither does this:
RewriteRule ^listings.php?sect=3&view=33 /listings/tombstone-ranch
or any other variations that I have tried.
Any thoughts? .htaccess is not my strong suit and unfortuinately I need to get these to work considering the old version of the site and it's urls have been around for almost 8 years now so there is the potential for dead links on about 75 properties.
Could you try this rule. Can't test it at the moment.
RewriteCond %{QUERY_STRING} sect=1&view=92
RewriteRule ^listings\.php$ /listings/thombstone-ranch/? [L,R=301]
Also the rule you added will not work because you must add a backslash
Wrong:
RewriteRule ^listings.php?sect=3&view=33 /listings/tombstone-ranch
Right:
RewriteRule ^listings\.php?sect=3&view=33 /listings/tombstone-ranch
Don't forget since your main URL is a query, you should use the first option that I gave to you. If that doesn't work leave a comment and I'll be glad to help you out

Adding trailing slash - Specific rules

I've got this setup:
RewriteRule ^brands$ brands/ [R=301,L]
RewriteRule ^brands/$ /brands.php
RewriteRule ^brands/([A-ZÆØÅæøåa-z0-9-]+)-([0-9]+)/$ index.php?manufacturers_name=$1&manufacturers_id=$2 [L,QSA]
RewriteRule ^brands/([0-9]+)$ index.php?manufacturers_id=$1 [L]
How would I fix it so there's alway a trailing slash on this - Those specific urls?
xxx.com/brands/brand-id
So if I either went to xxx.com/brands/brand-id OR xxx.com/brands/brand-id/ - It'll work as having a trailing slash?
Replace your Rule with this
RewriteRule ^brands/([0-9]+)/?$ index.php?manufacturers_id=$1 [L]
/? means that the / is optional in uri. Your rule will match both uri strings ending with or without a traling slash.
And to add the traling slash to specific uris,put the following before your existing rules
RewriteRule ^brands/[0-9]+$ %{REQUEST_URI}/ [L,R]
This will redirect /brands/123 to /brands/123/ .

Loosening .htaccess file's RewriteRule(s) to also access URL without a trailing slash

My .htaccess file always requires URL with trailing slash such as:
http://localhost/menjaraz/webroot/about/
http://localhost/menjaraz/webroot/2013/03/21/you-are-my-heart-you-are-my-soul/
to work, otherwise a 404 error is fired.
I wish to loosen the rule(s) so that an URL without an ending slash will also do as well.
Excerpt
RewriteBase /menjaraz/webroot
RewriteRule ^([^/]*)/$ index.php?page=$1
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ index.php?a=$1&b=$2&c=$3&page=$4
How should I do that ? I'm not very comfortable neither with regex nor with mod_rewrite.
Thanx in advance.
You need to make the last slash optional using the ?:
RewriteBase /menjaraz/webroot
RewriteCond %{REQUEST_URI} !index.php
RewriteRule ^([^/]*)/?$ index.php?page=$1
RewriteCond %{REQUEST_URI} !index.php
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/?$ index.php?a=$1&b=$2&c=$3&page=$4
The ? makes the character or group right before it optional. Because there's no trailing slash, you need to add a condition to make sure index.php doesn't get rewritten.

Skip a directory with htaccess

RewriteCond %{HTTP_HOST} ^(www.)?example\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
So i have this in my htaccess file to take care of the trailing slash problem . It redirects you every time you add a trailing slash on a url.
The issue here is the fact there is one directory where it needs the trailing slash or it breaks. How do I add a exception for a directory like http://www.example.com/com/ to this rule..
The simplest to understand approach is to use an additional condition:
RewriteCond $1 !=com
RewriteCond %{HTTP_HOST} ^(www.)?example\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
This works because the order of execution is rule.regexp, cond1, cond2, rule.substitution. Hence the $1 variable is available to the (new) cond1. You could also use a negative assertion on your regexp.
Incidentally, the http://%{HTTP_HOST}/ is assumed in the case of a [R=301] for http. Why do you not want to remove / for other host aliases?

Resources