htaccess folder organization and rewrite - .htaccess

I am having trouble figuring out how to work a rewrite, or even if it is a good idea.
I would like to name my folders in my webroot the following way for the sake of organization:
_fol.A
_fol.B
_fol.C
But I would like, using .htaccess mod_rewrite, people to reach the above folders when they visit
http://example.com/Alpha
http://example.com/Bravo
http://example.com/Charlie
Is this just over-complicating my life so that I can have my folders all appear together?

I think it's valid to group the folders in the physical _fol. I do this with products, where the url will be simply the product name /alpha, but they are in a products/alpha folder. This separates them nicely from the rest of the stuff on the website.
The other comments address your question of whether you're over-complicating, e.g., consider using the final names, and just put them down in the folder for organization.
That said, to answer how to do it, as CBroe said in the comments, RewriteMap is the answer.
This is one that doesn't rely on any particular url pattern - the product itself is the entire url. The RewriteCond line is making sure that it is in the map file. Keep or remove the leading slash in front of _fol as needed.
RewriteMap map_folder txt:d:\somepath\map_folder.txt [NC]
# Map folders.
RewriteCond ${map_folder:$1|NOT_FOUND} !NOT_FOUND
RewriteRule (.*) /_fol.${map_folder:$1} [NC,L]
The map_folder.txt file has entries like these:
Alpha A
Bravo B
Charlie C
If it's some other url, like /help, then it won't be found in the map file, and will fall through to further rules.

Related

.htaccess rewrite for orphaned URLs containing underscores and arguments

I only modify the .htaccess with great care for the purposes of my online store.
Some time ago, I did a website migration from osCommerce to OpenCart. This resulted in orphaned osCommerce-style URLs with these two example formats:
http://www.londonpower.com/catalog/product_info.php?products_id=75
http://www.londonpower.com/catalog/product_info.php?cPath=15&products_id=75
Lots of websites in internet-land have links to my old-style URLs, and I have about 100 of them, so I would like to redirect them to new URLs with the following format:
http://www.londonpower.com/2-channel-guitar-preamp
If I understand correctly, the problem has two parts:
to eliminate the underscores, as they baffle the .htaccess engine;
to then perform a 301 redirect on the URL.
So far, I have been able to get the first underscore to change to a hyphen, with this Rewrite Rule:
RewriteRule ^([^_]*)_(.*)$ /$1-$2 [R=301,L]
...but no luck with the second underscore (the one that is part of the query string after the "?"). I am stuck there.
I would avoid using rewriting for this. Does the file catalog/product_info.php exist in the new store? If not, create it and add a simple redirection using a map of old IDs to new URLs. If so, do the same thing in a different file, like old-redirector.php then rewrite requests to it.

.htaccess dynamic links rewrite engine

I need your help creating some links using mod_rewrite.
I have some pages like:
register.php
login.php
And have the code for them:
RewriteRule ^register/?$ register.php [NC,L]
RewriteRule ^login/?$ login.php [NC,L]
My problem is with "dynamic" links I have since I can't get them working.
For exemple I have links like:
index.php?id=news
índex.php?id=news&article=2
How can I transform those links into:
/news/
/news/article_name
And I have some products (that could have the same name in the same category) but with different ID's like:
índex.php?id=products&p=30
How can I change it to
/products/product-name
After this, is it possible to "generate" an unique name? Since I would like not set in the link the unique ID like products/45342/product-name?
What are the changes I need to make to my code to work with those links?
For example I have links like:
To clarify, you must first change the links in your application to be of the form /news/ or /news/article_name (but see below). You then rewrite these "pretty" URLs back to the underlying filesystem path.
So, to rewrite /news/ back to index.php?id=news you can do something like:
RewriteRule ^(news)/$ index.php?id=$1 [L]
Using the $1 backreference just saves typing. Only use the NC flag if this must be a case-sensitive match, but note that this potentially creates duplicate content, so you must specify the canonical URL in some other way (eg. rel="canonical" link element). For the same reason, only make the trailing slash optional if this is a specific requirement.
However, it's not possible to rewrite /news/article_name back to index.php?id=news&article=2 (I assume that should be i, and not í, as in your question?) since the article ID (ie. 2) is not present in the source URL. You need to include the ID in the source URL (or make the article_name unique and a key in your lookup). It would be more usual to create a URL like /news/2/article_name (which is what StackOverflow does), which can be easily rewritten. The article_name in the URL is purely for users (and indirect SEO). In which case you could rewrite this like so:
RewriteRule ^(news)/(\d+)/ index.php?id=$1&article=$2 [L]
This will rewrite /news/N/<anything> to /index.php?id=news&article=N (where N is 1 or more digits).
However, since it rewrites <anything> you should also implement a redirect in your application when the non-canonical article_name is accessed. (Which again, is what StackOverflow does.)
And I have some products (that could have the same name in the same category) but with different ID's like: índex.php?id=products&p=30
How can I change it to /products/product-name
The same principle as mentioned above applies here also.
After this, is possible to "generate" an unique name?
You can generate this "unique name" in your application, not .htaccess. Build you URLs in your application etc.
Since I would like not set in the link the unique ID like "products/45342/product-name" ?
As mentioned above, either your product-name is unique, and behaves like your id. Or you incorporate the unique ID in the URL - this is the far more common approach, offers greatest flexibility and is less prone to error. A "short" URL like /products/45342 will redirect you to the correct canonical URL.

.htaccess rewrite to add query parameter

I need to modify all requests bearing the form
http://example.com/dw2/dokuwiki/doku.php/page to
http://example.com/dw2/dokuwiki/doku.php/page?do=export_xhtml
The page bit is variable - it corresponds to each paage in the wiki. I should mention that given the way dokuwiki syntax works page could contain one or more colons. e.g. glossary:archive.
The intent here is to extract the bare page content (shorn of the header, sidebar etc) of the wiki for distribution via a CDN. This does not give a complete solution since dokuwiki still leaves in a lot of unrequired verbiage in the exported markup file but gets me most of the way there. I'd much appreciate any help with this.
Place this rule as your very first rule in /dw2/dokuwiki/.htaccess:
RewriteEngine On
RewriteBase /dw2/dokuwiki/
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(doku\.php/[^/]+)/?$ $1?do=export_xhtml [L,NC,QSA,R,NE]

Create search engine friendly urls for our blog

We run a blog, and really need to tidy up the URLs using htaccess, but I am really stumped.
Example:
Working on a site, and I need to generate search engine friendly URLs
So I have the url currently as:
http://mywebsite.com/blog/read.php?art_id=11
Title of this page is:
Why do Australians pay so much for Cars ?
I need to change it to its corresponding SEF url. like so:
http://mywebsite.com/blog/Why-do-Australians-pay-so-much-for-Cars-?
The question mark is part of the title, and we could remove these if its a issue. Any suggestions please?
Also would prefer to drop the read.php portion. Need to create a rule that works across our entire blog.
They all follow the same pattern, only the art_id number changes.
(Assuming that you're using apache as a webserver)
Take a look at this answer for a very similar question: https://stackoverflow.com/a/8030760/851273
The problem here is that .htaccess and mod_rewrite doesn't know how to map page names to art_id's so there's 2 ways you can try to do this.
You can add some functionality to your read.php so that it can do a similar lookup but instead of art_id, it uses art_title or something. Essentially you'll have to do the backend lookup of a database (or wherever your articles are stored) and use the title as a key instead of the ID. This is a little messy since it's possible to have weird characters in titles such as non-ascii or reserved characters (like ? for instance), so you'll need to create a title encoder and decoder when pulling titles out of the database or when using titles to lookup an article in your database.
If you have access to the server config or vhost config, you may be able to setup a RewriteMap using an outside program (the prg type) and create a php script that does the title-to-ID lookup for you. Then you can create rewrite rules in your .htaccess that does something along the lines of:
RewriteRule ^blog/(.*)$ /blog/read.php?art_id=${title-to-id:$1} [L]
Where you are extracting the article title from your pretty URL, and feeding it through a rewrite map called title-to-id to get the art_id. Again you'll need to setup a title encoder/decoder so your titles will have the non-ascci and reserved characters dealt with.
Another thing that you can do is to stick an article ID in your pretty URLs so they look like this: http://mywebsite.com/blog/11-Why-do-Australians-pay-so-much-for-Cars. This is still pretty easy to see what the link is about, it's SEO friendly, and it bypasses the need to do title-to-ID lookups. The Rewrite Rules would also equally be simpler:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# add whatever other special conditions you need here
RewriteRule ^blog/([0-9]+)-(.*)$ /blog/read.php?art_id=$1 [L]
And that's it. Of course, you'd have to now generate all of your blog URL's to be of the form: http://(host)/blog/(art_id)-(art_title), and you'd also have to remove special characters from the title, but you don't have to worry about writing additional code to translate titles back to IDs.

.htaccess and seo friendly search query string

I am really new to .htaccess. I was wondering how to create a complex seo friendly urls for the search string and selected filters.
I'm using following code currently for the search.
ReWriteRule ^search/(.*)/(.*) ?module=search&q=$1&page=$2 [L]
ReWriteRule ^search/(.*) ?module=search&q=$1 [L]
When it comes to adding filter options it starts to be a nightmare. Consider following filters;
Short by: none, name, date + ASC, DESC.
Category: none, category ID.
Search In: All, title, Message, Author.
When all filters are selected our address would be;
Raw :
www.site.com/?module=search&q=test&shortBy=name_ASC&catID=1&searchIn=title
Seo Friendly : www.site.com/search/test/name_ASC/1/title/
Now that's not complex at all but I just want to understand the how things work.
Do I have to apply all the filters to URL even if they are not selected? This would create longer URLs for no reason so I believe there must be another approach to this.
How do I define the rule in .htaccess? As in my example, I am writing at least 2 rules in my .htaccess file (2nd one is for pagination).
All I could think right now to do something like this ^search/(.*)/(.*) ?module=search&$1=$2 [L] but this doesn't look elegant.
I will be glad if you could help me out with this problem. I will be grateful if you could also share some of your experiences to a .htaccess newbie like I am.
Put the rules below at the top of your .htaccess file (in the root directory of your site) and then select one of the options below, modify it to your needs and place in after in your .htaccess file.
The first option will match the most urls and is not recommended. The second will only match urls with 5 directories, but requires all the paramters, so I recommend the 3rd.
Though the pattern below may not look elegant, it is a featured solution in The Definitive Guide to Apache mod_rewrite
For more details look at the apache docs or some examples or this post
In all cases, I am assuming that the requests go to index.php, so you should modify this to match the actual page.
This section should go at top of .htaccess file for all 3 options
#for all 3 options these 2 lines should be at the top of the .htaccess file
RewriteEngine On
RewriteBase /
Option1
#1 if all parameters are optional, and you page (index.php) can handle blank parameters use
RewriteRule ^([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/$ index.php?module=$1&q=$2&shortBy=$3&catID=$4&searchIn=$5 [L]
Option2
#2 if all parameters are required use
RewriteRule ^([^/]+)/([^/]+)/([^/]+)?([^/]+)/([^/]+)/$ index.php?module=$1&q=$2&shortBy=$3&catID=$4&searchIn=$5 [L]
Option3
#3 if the module is required and other parameters are optional, then this is better
RewriteCond %{REQUEST_URI} ^/(search|produce_detail|other_modules_here)/
RewriteRule ^([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/$ index.php?module=%1&q=$1&shortBy=$2&catID=$3&searchIn=$4 [L]

Resources