.htaccess rewrite rules changing dynamic url - apache

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]

Related

Make optional parameter with .htaccess

I have looked for the answer to my problem here, but the solution is always provided without explaining how to do it, that's the reason I can not do it properly.
I have this code:
RewriteRule ^dex/([^_]*)/([^_]*)/([^_]*)/([^_]*)/([^_]*)$ /dex.php?one=$1&two=$2&three=$3&four=$4&five=$5 [L]
This htaccess as it is makes it mandatory that all parameters are given. This URL works:
http://example.com/dex/one/two/three/four/five
I also want to make it work like this:
http://example.com/dex/one/two/three/four
Making the last (or some) parameters optional. I read something about QSA|qsappend here: http://httpd.apache.org/docs/current/en/rewrite/flags.html#flag_qsa but I can't understand it completely.
Any help? Thank you
To anyone having the same issue, this is the code used to fix it:
RewriteRule ^dex/([^/]*)/([^/]*)/([^/]*)/([^/]*)/?([^/]*)?$ /dex.php?one=$1&two=$2&three=$3&four=$4&five=$5 [L]
Changed ([^_]*) to ([^/]*) and added ? after what I wanted to make optional.
In this case: /? is making a end slash optional, and ([^/]*)? is making the last parameter optional. So it works when the URL is like this:
http://example.com/dex/one/two/three/four/
http://example.com/dex/one/two/three/four
http://example.com/dex/one/two/three/four/five
http://example.com/dex/one/two/three/four/five/
Hope this helps someone.
Rewrite rules use regular expressions. These regular expressions are always tiresome and difficult to maintain. The following, for example, is an answer to question about regex parsers on HTML, and the difficulty you may find with them:
RegEx match open tags except XHTML self-contained tags
Your htaccess file is an Apache configuration file. It should be used for simple configuration, and not for programming. Have it point to the code, and then let the code do the rest. For example, your .htaccess file:
RewriteRule ^(.*)$ index.php [QSA,NC,L]
And, if you're using PHP with index.php...
$objects = explode('/', ltrim($_SERVER[REDIRECT_URL], '/'));
print_r($objects); // list of items from URL
You may end up wanting to grab a different SERVER parameter, but you'll want to keep this complicated stuff in the code, not in configuration files.

Mod Rewrite on get vars

I'm working on a private project, which is basicly a profile system.
Now I've been trying how to improve the URL formatting.
At this moment, I am using URL's which look like:
-> http://example.com/overview
-> http://example.com/profile/?name=foo
-> http://example.com/jobs/?name=foo
Both overview and profile are directories on my website, which contain a single index.php file, which holds the PageID of which should be retrieved from the database.
Now, my goal is to format the URL to something as:
-> http://example.com/foo OR http://example.com/profile/foo
-> http://example.com/foo/jobs OR http://example.com/profile/foo/jobs
Is there anyway to do this with MOD_REWRITE?
This would mean the original url would look something like http://example.com/?character=foo/jobs which is http://example.com/get_var/directory.
I've done my research on Stackoverflow and Google, searching for 'mod_rewrite get variables'. But nothing seemed to be what I'd like to see happening.
Yours Sincerely,
Larssy1
To extract a portion of the URI between slashes and append it as a URL parameter, use the expression ([^/]+) to capture all characters up to but not including the next / into $1:
RewriteEngine On
RewriteRule ^profile/([^/]+)/([^/]+/?)?$ profile/$2?character=$1 [L]
The above rule will dynamically capture what follows Foo from your example, meaning that whether it was followed by /jobs or /other or /somethingelse, it would be appended as /profile/somethingelse?character=Foo. If that isn't necessary, and /jobs is static, you don't need to capture it into $2:
RewriteEngine On
# Don't dynamically capture what comes after the first variable group...
RewriteRule ^profile/([^/]+)/jobs$ profile/jobs?character=$1 [L]

Apache mod_rewrite path name as query parameters?

I want to use Apache's mod_rewrite in order to be able to take each folder of a path as a particular query parameter, for example consider the following:
Basic example
Url requested: http://domain.com/shoes/prada/image-1/
Page served: http://domain.com/?cid=shoes&bid=prada&pid=image-1
In this scenario, there are 3 sub-folders requested (/shoes/, /prada/ then image-1), so the first sub-folder is passed in the actual page served as cid, the second as bid and the third as pid.
Full example
However, I would also like it to serve a particular page depending on the number of sub-folders requested, e.g.
Url requested: http://domain.com/shoes/prada/
Page served: http://domain.com/shop.php?cid=shoes&bid=prada
So far all I've managed to find is regex based matching for mod_rewrite but my path's will vary a lot, which is why I would like to have conditions based on the number of folders accessed (please note, I'm not that good with regex - I reckon a wildcard character would help with this, but I wouldn't be sure where to start).
Any help on this would be greatly appreciated! This is pretty long winded, so if you need any more info for clarifying, please let me know!
With a little bit of work I was able to tweak some regex and get a working rule set for what I wanted:
RewriteEngine on
RewriteRule ^(.*)/(.*)/(.*)/(.)?$ product.php?tid=$1&sid=$2&eid=$3 [L]
RewriteRule ^(.*)/(.*)/(.)?$ brand.php?tid=$1&sid=$2 [L]
RewriteRule ^(.*)/(.)?$ shop.php?tid=$1 [L]
This is a bit different to the example, however it's what I intended for in the first place.
This allows for the rewriting of url's up to four folders deep, with the "name" of each folder being given as a parameter, and each additional level of depth rewriting the url to a separate resource for example:
http://x.com/shoes/prada/2011-high-heels/ -> http://x.com/product.php?tid=shoes&sid=prada&eid=2011-high-heels
Tested on http://martinmelin.se/rewrite-rule-tester/

mod_rewrite ecommerce URL design

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

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.