mod_rewrite ecommerce URL design - apache

I have problems with how I should structure my product listing pages, products pages, webpages.
It roughly translate into this:
/bags/nicebag.html = /product.php?product=nicebag&category=bags
/nicebag.html = /product.php?product=nice_bag
/bags = productlisting.php?&category=bags
Problem is that webpages will share same URL structure as no.2 in the list
/contact.html = page.php?page=contact
The reason why it is not listed in .htaccess separatly is that webpages can have different names. And even the same page can be in multiple languages.
The reason of no. 1 and 2 is not combined, is that sometimes I just want to reference only to the product since it can be in multiple categories.
What kind of structure do you suggest?
.htaccess
# Mod rewrite enabled.
Options +FollowSymLinks
RewriteEngine on
# ---- Rules ----
# product.php (Search for category & product name)
RewriteRule ^([A-Za-z0-9-_]+)/([A-Za-z0-9-_]+)\.html?$ product.php?prod_id=$2&cid=$1 [NC,L]
# productlisting.php (Search for category)
RewriteRule ^([A-Za-z0-9-_]+)?$ productlisting.php?&cid=$1 [NC,L]

I would use the path prefix /products/ to identify the products related URLs. So:
/products/bags/nicebag.html → /product.php?product=nicebag&category=bags
/products/nicebag.html → /product.php?product=nice_bag
/products/bags → /productlisting.php?&category=bags
With such a structure you could also rewrite /products/ to /productlisting.php that then shows all products.
# product listing
RewriteRule ^products/$ productlisting.php [L]
RewriteRule ^products/([A-Za-z0-9-_]+])$ productlisting.php?category=$1 [L]
# product details
RewriteRule ^products/([A-Za-z0-9-_]+)\.html$ product.php?prod_id=$1 [L]
RewriteRule ^products/([A-Za-z0-9-_]+)/([A-Za-z0-9-_]+)\.html$ product.php?prod_id=$2&cid=$1 [L]
# other pages
RewriteRule ^([A-Za-z0-9-_]+)\.html$ page.php?page=$1 [L]

use a different suffix for different types, e.g html for products and htm for pages or something like that
/bags/nicebag.html = /product.php?product=nicebag&category=bags
/nicebag.html = /product.php?product=nice_bag
/bags = productlisting.php?&category=bags
/contact.htm = page.php?page=contact
or
/contact/page.html = page.php?page=contact

As it will be messy and cumbersome to maintain your rewriting rules in the .htaccess file, I would only put one rule in there, rewriting to something like:
/dispatch.php?request=[request]
e.g.
RewriteRule ^(.*)$ dispatch.php?request=$1 [L,QSA]
In dispatch.php, you dissect the request into its elements (path, querystring, anchor, ...) and decide where to go from there. That way, you can use code for the decision making, which will give you a lot more flexibility than just maintaining a huge list of custom rewrite mappings.
For example, you can identify product and category elements in the path by querying against your database and base the dispatch logic on the results in a more generic way.
[Pseudocode]
if (isProduct($lastPathElement)) {
// Maybe verify that leading path elements are categories ...
// Other preparations/verifications ...
// refer execution to product.php
}
elseif (isCategory($lastPathElement)) {
// Other preparations/verifications ...
// refer execution to productlisting.php
}
// ... (Checks for other specific stuff)
else {
// Static page or 404
// refer execution to page.php
}

I was facing the very same issue a few weeks ago.
Ended up defining a different structure for the "static" pages.
www.examples.com/contact/
or
www.examples.com/info/contact.html
So it can be distinguished from the "dynamic" pages.

There's pretty much no way to distinguish between www.examples.com/nicebag.html and www.examples.com/contact.html without putting non-product webpage names in .htaccess or doing some preliminary processing in the receiving php script.
As I see, the options are:
rewrite all requests to page.php and for those that don't match any of the non-product pages, include the product script
write the non-product page names to .htaccess dynamically (messy and bug-prone)
rethink the URL structure for non-product pages. Perhaps just as little as www.example.com/page/contact.html might help
I'd go for the third one, anyway.

I would recommend flat structure:
domain.com/bags
domain.com/contact
domain.com/nice-bag

Related

htaccess rewrite to reverse subfolders

As basic as it gets, here is an example of what I'm trying to do:
I have a structure that takes different types of CMS' and inside each of those installations, are language variations.
By default the structure looks like this:
https://[domain]/[country]/[installation]/[language-code]
Ultimately, I'm trying to get this:
https://[domain]/[country]/[language-code]/[installation]/
I'm wondering if this can be accomplished, due to the fact the folders/languages themselves are not actual folders and in fact rewrites from the CMS' settings (within the subfolders).
As unmodified these would be examples of the current urls:
https://example.com/ca/events/en/
https://example.com/ca/store/en/
https://example.com/ca/network/en/
And example of the desired results:
https://example.com/ca/en/events/
https://example.com/ca/en/store/
https://example.com/ca/en/network/
and for each installation, they dont always have the same languages (eg. ca has en and fr, but us has en and es)
Note: subsequent pages would be appended... eg:
https://example.com/ca/en/events/event-name/subpage/
You may be be able to use this single redirect rule on top of your .htaccess:
RewriteEngine On
RewriteRule ^([a-z]{2})/(.+)/([a-z]{2}/?)$ $1/$3/$2 [L]

redirecting multiple mod-rewrite rules to one

I don't know how to title the question, but here's my problem.
I'm trying to turn multiple rules into one rule pointing to one page.
The website has a catalog of photos which can be accessed preferably with the following url structure and the image numbers must start with zero:
(insert base url)/photocategoryname/month-01-2014/image/1
I want (insert base url)/photocategoryname/month-01-2014/image/0 to automatically switch to and load data from (insert base url)/photocategoryname/month-01-2014/image/1
I also want (insert base url)/photocategoryname/month-01-2014/image-1 to convert to (insert base url)/photocategoryname/month-01-2014/image/1 as well because I did a URL redesign and in the past I used image-1 instead of image/1, and search engines are trying to retrieve old files.
I also want to handle cases where an extra slash is added by accident.
When I used this ruleset and tried accessing (insert base url)/photocategoryname/month-01-2014/image-1, it gave me a redirect page with the new URL as (insert base url)/photocategoryname/month-01-2014/image/1/month-01-2014/image-1.
RewriteRule ^(.+)/(.+)-([0-9]+)-([0-9]+)/image-([0-9]+)(/)?$ /$1/$2-$3-$4/image/$5 [NC]
RewriteRule ^(.+)/(.+)-([0-9]+)-([0-9]+)/([0-9]+)(/)?$ /$1/$2-$3-$4/image/$5 [NC]
RewriteRule ^(.+)/(.+)-([0-9]+)-([0-9]+)/([0-9]+)/(.+)$ /$1/$2-$3-$4/image/$5 [NC]
RewriteRule ^(.+)/(.+)-([0-9]+)-([0-9]+)/image/0(/)?$ /$1/$2-$3-$4/image/1 [NC]
RewriteRule ^(.+)/(.+)-([0-9]+)-([0-9]+)/image/([0-9]+)$ /photo.php?TITLE=$1&DATE=$2-$3-$4&PHOTONUMBER=$5 [NC,L]
What I want to do is minimize redirects to maybe 1. I was able to get this setup working before when I used [R=301,NC,L] instead of [NC] for the first 4 rules, but that caused too many redirects and I don't want my server spending resources on handling unnecessary redirects.
Any idea what I could be doing wrong?
UPDATE:
Here's what I'm trying to achieve.
I want to allow people to access the same page (photo) using any one of the following URLs:
(insert base url)/photocategoryname/month-##-####/image#
(insert base url)/photocategoryname/month-##-####/image/#
(insert base url)/photocategoryname/month-##-####/image-#
(insert base url)/photocategoryname/month-##-####/photo#
(insert base url)/photocategoryname/month-##-####/photo/#
(insert base url)/photocategoryname/month-##-####/photo-#
(insert base url)/photocategoryname/month-##-####/picture#
(insert base url)/photocategoryname/month-##-####/picture/#
(insert base url)/photocategoryname/month-##-####/picture-#
and I made PHP code that can help redirect the user to the proper URL:
(insert base url)/photocategoryname/month-##-####/image/#
This old code as the second parameter for the rewrite rule works but only for the one URL.
^(.+)/(.+)-([0-9]+)-([0-9]+)/image/([0-9]+)$
But this one seems to be ignored entirely on the server:
^([^/]+)/([A-Z0-9]+)-([0-9]+)-([0-9]+)/(image|photo|picture|photograph|pic|)(-|/|)([0-9]+)/*$
Both lines of code end with [NC,L].
What could I be doing wrong?
The way you did it before was correct, the first 4 lines should have a R=301 for a proper redirect.
It's not good practice, but if you want make the same page available under these different URLs, you could try changing [NC] to [NC,L]

.htaccess rewrite rules changing dynamic url

I am trying to make the url's better for my website for SEO purposes.
Currently pages are displayed like this:
SITE/[number]-[page name].html
I would like to get the pages to display in a format like below.
example 1.
SITE/[page name].html
or
example 2.
SITE/[page name]-[number].html
(I would prefer to leave the page number out if possible, like example 1 but if it must be included I would like it at the end of the url, like the second example above.)
I have the following rule in the .htaccess file.
RewriteRule ^([0-9]+)-(.*)$ site_page.php?page=$1
My biggest problem is that I have tried many ways to get the rewrite to do what I need.
I am a complete newbie when it comes to rewrite.
I have changed the rewrite to the following with no joy.
RewriteRule ^(.*)-([0-9]+)$ site_page.php?page=$1
RewriteRule ^(.*)-([0-9])$ site_page.php?page=$1
RewriteRule ^(.*+)-([0-9]+)$ site_page.php?page=$1
RewriteRule ^([.*]+)-([0-9]+)$ site_page.php?page=$1
The above that I have tried was to keep the page id number, I would preferably like to get rid of the numbers altogether.
I have the following Lines in the setting.php file that controls how the website creates the relevant links. And it displays them as I would like. But I get a 404 error because I think the rewrite rule is not displaying what I expected it to display.
// non seo url
$setup_url['normal']['resource'] = "$url_base/site_page.php?page=[number]";
// seo url
$setup_url['seo']['resource'] = "$url_base/[number]-[name].html";
I have looked at so many articles on mod rewrite rules, and seem to be getting no where. Any help would be greatly appreciated.
Many thanks.
Mark.
Seems that you've forgot the .html extension in rule.
RewriteRule ^(.+)-(\d+)\.html$ site_page.php?$1=$2 [L]

Abusing Mod Rewrite for a clean file system, and pretty URLs

I have a few php files that do a few different jobs. I'd like to change the way my clients access these php files to make it more clean for the end user. The Mod_Rewrite system has shown that it can do some pretty powerful things when in the hands of the right server admin. So I was wondering how far can you abuse the Mod Rewrite rules for a cleaner file system, and pretty URLs. Considering that the PHP files themselves use query strings to get their data, I'd like to alias the way the query string is built based upon how the how deep into the fake files system we go.
Our website's URL is http://www.domain.tld/, but we shall call it domain.tld for short. I'd like to map a few different address to a few different query strings on a few different files. But I'd also like to to be expandable on a whim.
Or first set would be, anything going past domain.tld/series/ should be directed to the domain.tld/series.php script with any (fake) directory past series to become part of the query-string for series.php. The same should happen to anything directed in the direction of domain.tld/users/ that should be redirected to the domain.tld/users.php file.
So if we had a URLs like, domain.tld/series/Master/2010/ or domain.tld/series/Novice/Season 01/ they would still be redirected to the domain.tld/series.php script, but with the query-string of ?0=Master&1=2010 and ?0=Novice&1=Season 01. But should I want to get an overview of the Master series, I could go the the URL domain.tld/series/Master/ and produce the query-string of just ?0=Master. The idea being that the rewrite rule should allow for infinite expandability.
This is how I'm doing it, and it sure works infinitely:
RewriteRule ^((/?[^/]+)+)/?$ ?q=$1 [L]
The trick is that the whole path is passed on as a single parameter, q, to index.php. So for example domain.tld/series/Novice/Season 01/ becomes domain.tld/?q=series/Novice/Season 01. Then you can do:
<?php
$params = explode('/', $_GET['q']);
var_dump($params);
?>
to get the individual parts.
array(3) { 0 => 'series', 1 => 'Novice', 2 => 'Season 01' }
It is not possible to be completely dynamic in such a system and have, as you say 'infinite expandability. You would have to define a RewriteRule for every 'tier' you will allow in your URL, or alternatively match everything after the first 'tier' as a single variable and do the work with PHP.
Example 1
RewriteRule ^([^/]+)/?$ /$1.php
RewriteRule ^([^/]+)/([^/]+)/?$ /$1.php?0=$2
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ /$1.php?0=$2&1=$3
Example 2
RewriteRule ^([^/]+)/(.*)/? /$1.php?qs=$2
Obviously these are only very simple examples and you'd probably have to use RewriteConds etc. to exempt certain files etc.

rewrite urls with GET reqs

how do I configure my .htaccess rewrite rules to accomodate GET requests?
Currently, /manager/page goes to: ?dept=manager&n=page however, some pages have additional GET reqs, and so this rule doesn't work:
RewriteRule ^([A-Za-z]+)/([A-Za-z]+)$ index.php?dept=$1&n=$2 [QSA]
I would need: ?dept=manager&n=page&id&etc=etc to go to: /manager/page/id/5/etc/6 however, not all pages present the same method of id input, IE. some pages used id, others catid, and others, bugid, so it's a bit difficult.
Thanks :)
UPDATED: END URL - id/5/etc/6
You just need to sepcify a different rule.
RewriteCond ${HTTP_METHOD} "GET"
RewriteRule --your rule--
If your input methods are really that varied, you should use multiple RewriteRules for each different format.