Value pair url modeling for subpages via htaccess - regex

Ok, currently to get the URL in the format I want I use this in my .htaccess
RewriteRule ^user.php/([0-9]+)/?$ user.php?id=$1 [NC,L]
RewriteRule ^user.php/edit/([0-9]+)/?$ user.php?id=$1&type=edit [NC,L]
Urls, redirect to
domain/user/7/ -> domain/user?id=7
domain/user/edit/7/ -> domain/user?id=7&type=edit
Works fine, but I want to be able to do better value pair urls instead of just strict matches.
An example is
domain/user/key/value/key/value/key/value/
-> domain/user.php?key=value&key=value&key=value
I was looking at
.htaccess rewrite to convert directories into /key/value/key/value
The example works well if you just want to redirect from the main path, ie localhost/index.php, but I want to only be triggered when it's domain/user and I couldn't get it to match with using 'user' as the trigger
My current .htaccess
# Pretty url's
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
RewriteRule ^user.php/([0-9]+)/?$ user.php?id=$1 [NC,L]
RewriteRule ^user.php/edit/([0-9]+)/?$ user.php?id=$1&type=edit [NC,L]
Is this possible, and if so how?

Deja vu time!!! I wrote that answer sometime back :P
Here is what you can do for your case:
RewriteEngine On
RewriteRule ^(user)/([^/]*)/([^/]*)(/.*)?$ /$1/$4?$2=$3 [L,QSA,NC]
RewriteRule ^(user)/?$ /$1.php [L,NC]
RewriteRule ^user.php/([0-9]+)/?$ user.php?id=$1 [NC,L]
RewriteRule ^user.php/edit/([0-9]+)/?$ user.php?id=$1&type=edit [NC,L]
# Pretty url's
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
Using these rules a URL of /user/n1/v1/n2/v2/n3/v3/n4/v4 will be INTERNALLY forwarded to /user.php?n4=v4&n3=v3&n2=v2&n1=v1 treating each pair of URL segments separated by / as a name-value pair forQUERY_STRING`.

Ok this is working for me
RewriteRule ^(user.php)/([^/]*)/([^/]*)(/.*)?$ /$1/$4?$2=$3 [L,QSA,NC]
RewriteRule ^(user)/?$ /$1.php [L,NC]
# Pretty url's
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
URL
/user/n1/v1/n2/v2/n3/v3/n4/v4
Outputs
Array ( [n4] => v4 [n3] => v3 [n2] => v2 [n1] => v1 )
anubhava, you da man :)

Related

Use .htaccess to rewrite a sub directory to root but keep access to other sub directories

I am trying to rewrite a subdirectory out of my URL structure but have other URLs within that directory structure also work. I have this scenario:
// This should load the content of mysite.com/foo/15 but not redirect
mysite.com/foo/
// Subdirectories within /15 should also work
mysite.com/foo/bar // the actual location of this is mysite.com/foo/15/bar
// Other URLs within this directory structure should also work, such as
mysite.com/foo/12
mysite.com/foo/13
mysite.com/foo/14
// Lastly, we have redirects from 2012 -> 12, 2013 -> 13 such that
mysite.com/foo/2012 becomes mysite.com/foo/12
mysite.com/foo/2013 becomes mysite.com/foo/13
... and so on
Here's where i'm at. I can't get the right combination of htaccess rules to achieve what I want.
RewriteEngine On
RewriteBase /foo/
// This makes mysite.com/foo/ load the content of mysite.com/foo/15 without redirecting, but makes mysite.com/foo/14 404
RewriteRule ^((?!15/).*)$ 15/$1 [NC,L]
// This works pretty well, except the rules below don't redirect
RewriteRule ^$ 15/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ 15/$1
// Rewrite old years to the two digit form
RewriteRule ^2010/(.*)$ 10/$1 [R=301]
RewriteRule ^2011/(.*)$ 11/$1 [R=301]
RewriteRule ^2012/(.*)$ 12/$1 [R=301]
RewriteRule ^2013/(.*)$ 13/$1 [R=301]
RewriteRule ^2014/(.*)$ 14/$1 [R=301]
RewriteRule ^2015/(.*)$ 15/$1 [R=301]
What am I missing? What combination of rules will help me achieve what i'm looking for?
Your redirect rules can be combined into single rule using regex matching:
RewriteEngine On
RewriteBase /foo/
// Rewrite old years to the two digit form
RewriteRule ^20(1[0-5])/(.*)$ $1/$2 [R=301,L]
RewriteRule ^$ 15/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^((?!15/).*)$ 15/$1 [L]
Try including the L flag in all your rules and then put all your redirects at the top of the htaccess file:
RewriteEngine On
RewriteBase /foo/
// Rewrite old years to the two digit form
RewriteRule ^2010/(.*)$ 10/$1 [R=301,L]
RewriteRule ^2011/(.*)$ 11/$1 [R=301,L]
RewriteRule ^2012/(.*)$ 12/$1 [R=301,L]
RewriteRule ^2013/(.*)$ 13/$1 [R=301,L]
RewriteRule ^2014/(.*)$ 14/$1 [R=301,L]
RewriteRule ^2015/(.*)$ 15/$1 [R=301,L]
// This makes mysite.com/foo/ load the content of mysite.com/foo/15 without redirecting, but makes mysite.com/foo/14 404
RewriteRule ^((?!15/).*)$ 15/$1 [NC,L]
// This works pretty well, except the rules below don't redirect
RewriteRule ^$ 15/ [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ 15/$1 [L]

Rewrite URL if page exists in a sub folder

I was wondering if there is a way to achieve this sort of URL rewriting;
RewriteRule ^example-link-1?$ /blog/example-link-1 [NC,L]
RewriteRule ^example-link-2?$ /blog/example-link-2 [NC,L]
RewriteRule ^example-link-3?$ /blog/example-link-3 [NC,L]
RewriteRule ^example-link-4?$ /blog/example-link-4 [NC,L]
where you go directly to a link such as example.com/example-link-1 and you are actually shown content from example.com/blog/example-link-1, but without the need for a new rule per page i add. Is there a dynamic way to do this in the htaccess? ie;
IF exists('blog/'+pageURI)
THEN rewrite to 'blog/'+pageURI but keep the uri without 'blog/' in it.
Yes sure you can do:
RewriteRule ^(example-link-[1234])/?$ /blog/$1 [NC,L]
for above 4 rules. But in general you can do this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/blog/$1 -f
RewriteRule ^(.+?)/?$ /blog/$1 [NC,L]
This will rewrite to /blog/something if /blog/something exists while keeping the same URI without /blog/.

301 Redirects: /article_list.php?parent_cat=152&catid=187??? How Do I Redirect This?

I'm setting up 301 Redirects in my .htaccess and 1 of them is:
Redirect 301 /article_list.php?parent_cat=152&catid=187 http://mysitehere.com/resources/objects/tribulus/
When I double check it by going to http://mysitehere.com/article_list.php?parent_cat=152&catid=187 it just stays there on that page and it says 404: Page Not Found. Did I do this incorrectly?
You need mod_rewrite rule to match query string. Consider this rule in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^parent_cat=152&catid=187$ [NC]
RewriteRule ^article_list\.php$ /resources/objects/tribulus/? [R=301,L,NC]
Reference: Apache mod_rewrite Introduction
UPDATE:: Your full .htaccess:
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^parent_cat=152&catid=187$ [NC]
RewriteRule ^article_list\.php$ /resources/objects/tribulus/? [R=301,L,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ /$1/ [L,R=301]
# Removes index.php from ExpressionEngine URLs
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1/ [L]
I believe the Redirect directive of the mod_alias module doesn't really handle/match query strings at all, cf. its documentation:
mod_alias is designed to handle simple URL manipulation tasks. For more
complicated tasks such as manipulating the query string, use the tools provided
by mod_rewrite.
For matching a query string, I suggest you use a RewriteCond+RewriteRule combination, where the RewriteCond matches your %{QUERY_STRING} lexicographically. :)

htaccess rewrite different directories

There are 4 rewrite rules, but only the first 2 work:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^news/article/([^/]+)$ /path/to/news/?id=$1
RewriteRule ^news/page/([^/]+)$ /path/to/news/?page=$1
RewriteRule ^company/careers/id/([^/]+)$ /path/to/company/careers.php?id=$1
RewriteRule ^company/careers/page/([^/]+)$ /path/to/company/careers.php?page=$1
/path/to is always the same for all. The two news rules work perfectly, but the two company rules do not.
What's wrong here?
Edit to add (via comments):
This is how the 4 URLs look like.
http://domain.com/folder/folder2/news/article/1
=> translates correctly to http://domain.com/folder/folder2/news/?id=1
http://domain.com/folder/folder2/news/page/2
=> translates correctly to http://domain.com/folder/folder2/news/?page=2
http://domain.com/folder/folder2/company/careers/id/1
=> should translate to http://domain.com/folder/folder2/company/careers.php?id=1, but doesn't
http://domain.com/folder/folder2/company/careers/page/2
=> should translate to http://domain.com/folder/folder2/company/careers.php?page=2, but doesn't
The .htaccess file is located in http://domain.com/folder/folder2/.htaccess.
Change your .htaccess to this:
Options -MultiViews
RewriteEngine On
RewriteBase /folder/folder2/
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^news/article/([^/]+)/?$ news/?id=$1 [L]
RewriteRule ^news/page/([^/]+)/?$ news/?page=$1 [L]
RewriteRule ^company/careers/id/([^/]+)/?$ company/careers.php?id=$1 [L]
RewriteRule ^company/careers/page/([^/]+)/?$ company/careers.php?page=$1 [L]

mod_rewrite - Only use whatever is after the last forward slash

So I already have my .htaccess file configured so that when I load the webpage (http://example.com/about), it transparently redirects it to http://example.com/about.html, however, I'd like it now to be able to do (http://example.com/about/contact), then have it transparently redirect to http://example.com/about/contact.html. I guess ideally it'd completely ignore the "/about/" part of the URL and only use the contact part.
This is what I'm using right now:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
Use this:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
# folder/file => folder/file.html
RewriteRule ^([a-z0-9_\-]+)/([a-z0-9_\-]+)/?$ $2.html [NC,L]
# file => file.html
RewriteRule ^([a-z0-9_\-]+)/?$ $1.html [NC,L]