Rewrite rule issue - capture unique identifier - mod-rewrite

I am trying to apply logic where i have to capture unique identifier passed to the URL
http://abzc.com/1235a -> http://abzc.com/content/abc.htm/1235a.htm
The logic that i applied is as below and it works fine-
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(.htm)
RewriteRule ^/([a-zA-Z0-9]{5})$ /content/abc.htm/$1.htm [R=301,L]
there could be situation where a user navigates to
http://abzc.com/content/ars.htm/1235a after the initial landing page so i would need to append .htm again to this URL
tried below logic but it fails totally -
RewriteCond %{REQUEST_URI} ^\/*.html/(.*)$
RewriteRule .html/([a-zA-Z0-9]{5})$ /.html? [L,R=301]
Also I need to achieve
http://abzc.com -> http://xayz.com (i.e. no unique id passed as paramater to abzc.com)
but not sure how to capture if say $1 is null or something like that to handle this one.
Your help is appreciated!

Related

Mod rewrite rule for mapping one or two parameters

I have the following .htaccess:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([^/]+)/?$ /?page=$1 [L,QSA]
RewriteRule ^/?([^/]+)/([^/]+)/?$ /?page=$1&id=$2 [L,QSA]
This rules allow to enter urls like:
example.com/my-account-dashboard
example.com/my-account-dashboard/1
which are pretty urls for:
example.com?page=my-account-dashboard
example.com?page=my-account-dashboard&id=1
This works fine so far. But internaly the links are with those parameters. Is it possible to redirect (or something) to the pretty urls if possible? What are the rewrite rules for that?
First of all, a few remarks about your current code which contains some errors.
1) RewriteCond only applies on the very next RewriteRule. So your second RewriteRule can match without that condition (you can try it, you'll see). You need to put (again) that condition to the other RewriteRule (or use S skip flag to simulate if/else condition but it gets complicated for nothing).
2) I'm pretty sure you don't want to use QSA flag the way you do. By using it, you tell mod_rewrite to append any query string to the rewrite. Example: example.com/my-account-dashboard/?foo=bar will rewrite to /?page=my-account-dashboard&foo=bar. So unless you really want that, you don't need it. A lot of people think that they need QSA when adding some query string directly in the rewrite, just like you do. Again, this is not an error that will make everything crash, but still it's not totally correct.
3) Your rules create duplicate content which is bad for SEO (referencing). For instance, example.com/my-account-dashboard and example.com/my-account-dashboard/ (notice the trailing slash) both lead to the same page. But search engines won't consider them as the same. I invite you to search "duplicate content" on Google (or any other search engine you like) and have a look at it. A simple way to avoid this is to chose either with or without the trailing slash.
Now that the base is clear, let's answer to your question. You can't simply use a redirect R from old-url to new-url because you'd end up with an infinite loop. Something is there for this problem: THE_REQUEST. When mod_rewrite uses it, it is able to know that it comes from a direct client request, not a redirect/rewrite by itself.
All-in-one, here is how your code should look like:
RewriteEngine On
RewriteBase /
# Redirect old-url /?page=XXX to new-url equivalent /XXX
RewriteCond %{THE_REQUEST} \s/\?page=([^/&\s]+)\s [NC]
RewriteRule ^ /%1? [R=301,L]
# Redirect old-url /?page=XXX&id=YYY to new-url equivalent /XXX/YYY
RewriteCond %{THE_REQUEST} \s/\?page=([^/&\s]+)&id=([0-9]+)\s [NC]
RewriteRule ^ /%1/%2? [R=301,L]
# if /XXX is not a file/directory then rewrite to /?page=XXX
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([^/]+)$ /?page=$1 [L]
# if /XXX/YYY is not a file/directory then rewrite to /?page=XXX&id=YYY
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([^/]+)/([0-9]+)$ /?page=$1&id=$2 [L]
NB: i chose to use the "without trailing slash" option (e.g. example.com/my-account-dashboard and example.com/my-account-dashboard/1). Feel free to ask if you want with.

mod_rewrite forward shortend URL

I am looking for a way to create a short URL path for a longer URL on my page
the long url is: domain.com/tagcloud/user.html?t=1234ABCD
i would like to offer a short version of the URL to easy access it:
domain.com/t/1234ABCD
I tried a few examples but I just don't get it how I could forward these rules.
RewriteRule ^(.*)/t/$ /tagcloud/user.html?t=$1 [L]
I am also using MODX so they already use rules.
in addition my htaccess file
RewriteEngine On
RewriteBase /
# Always use www
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\.domain\.com [NC]
RewriteRule (.*) http://www.domain.com/$1 [R=301,L]
# The Friendly URLs part
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
I must keep the code snippets above in my htaccess file. The first one simply forwards http://domain.com requests to www.domain.com
The friendly URLs part is needed to translate the internal IDs of my CMS with the alias of the URL. This feature must remain because the entire site cannot be influencted by the changes I try to make in htaccess...
I simply would like to add a listener that only if the URL matches www.domain.com/t/abcd1234
Therefore I need something that identifies the www.domain.com/t/ URL
your help is much appreciated
Try this:
RewriteCond %{REQUEST_URI} ^/t/.*
RewriteRule ^t/(.*)$ /tagcloud/user.html?t=$1 [R=301,L]

Mod_Rewrite: Transform normal /url into /#!/url

I have the following two url cases …
http://url.com/one
http://url.com/category/some
If those urls are called I want mod_rewrite to call …
http://url.com/#!/one
http://url.com/#!/category/some
How can I do that?
Something like this?
# not existing file (images, css, etc)
RewriteCond %{REQUEST_FILENAME} !-f
# no query parameters
RewriteCond %{QUERY_STRING} =""
# not /
RewriteCond %{REQUEST_URI} !^/$
# external redirect and pass along query string and uri as fragment
# i guess this must be an external redirect as the server side should
# not see the fragment, R=redirect, NE=dont escape #, L=last rule
RewriteRule ^(.*)$ /#!/$1 [R,NE,L]
# same but with query parameter
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/$
RewriteRule ^(.*)$ /?%{QUERY_STRING}#!/$1 [R,NE,L]
But im not sure if this is good idea. Maybe you should do the redirect in application logic or with a client side script instead.

Hiding php extension for static files

I have used this rule in categories:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9-/]+)$ categories.php?url=$1
RewriteRule ^([a-zA-Z0-9-/]+)/$ categories.php?url=$1
I want to hide php extension already for static files like xxx.php. Im using this rule:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
This rule not working and xxx.php goes to categories.php page. What rule may I use for static pages? may I use any "folder/(.*)$ $1.php" ?
Should work fine, if you make sure to put the second set of rules first. Remember, the rules are executed in order. So, in the order you have the rules in your post, a request to xxx will be rewritten as categories.php?url=xxx before the second rule ever sees the request... so it never triggers.

mod_rewrite precedence

Let's say I want to support urls like twitter where:
twitter.com/username redirects to twitter.com/user_name.php?user=username
I have the following
RewriteRule ^(.*)$ user_name.php?user=$1
And that works fine. But the problem is now that everything, including twitter.com/index.php will of course redirect to user_name.php
How can I either create exceptions or precedence so that "real files" don't get rewritten? I tried adding an explicit rule for index.php before and after that one, but it doesn't seem to take effect.
You need to add RewriteCond for this
RewriteCond %{REQUEST_URI} !-f [OR] # for existing files
RewriteCond %{REQUEST_URI} !-d # for existing directories
RewriteRule ^(.*)$ user_name.php?user=$1

Resources