Forum Moderators: coopster

Message Too Old, No Replies

Mod rewrite with PHP - issues with query string

Have to write a massive .htaccess file for many variables

         

tensai288

6:25 pm on Mar 24, 2009 (gmt 0)

10+ Year Member



Hi

I'm trying to build a php driven site with rewritten URLs. I have the done the basics and have rewritten URLs working on my site.

The problem I now have is that I want to sort my data, and since you have to use the query string to do this, you end up having a very large htaccess file (which you have to write manually).

Example

I have a page listing 9 products out of 100 products.

I have a sorting navigation where users can select products by Gender, Type, Price, Colour. Users can also press "View All" to see all 100 products.

The URL that displays 9 products is:

www.domain.com/product

When the user clicks "Mens" from the sorting navigation, the URL changes to www.domain.com/product/gender/mens and my htaccess file instructs that "mens" should be considered part of the gender variable in the query string.

Now if on the mens product page, they press "color = red" the URL changes to

www.domain.com/product/gender/mens/color/red and htaccess file instructs that color variable should be red.

My PHP page has the relevant queries set up that see if color/gender etc is set().

now the issue is, to my (basic) knowledge, you have to rewrite regular expressions in the correct order. So for example i have to have both: color/([^/]+)/gender([^/]+) and gender([^/]+)/color([^/]+) set up in my htaccess to drop the words in the correct variables.

This gets extremely complex if you throw other sorts into the mix - depending on the user journey, the URL is different

www.domain.com/color/red/gender/ladies/speed/fast
www.domain.com/speed/fast/color/red/gender/ladies
www.domain.com/gender/ladies/color/red/speed/fast etc etc all have to be accounted for in the htaccess.

BTW
I'm using a script that takes the current URL of my page, and appends the relevant /gender etc onto the end for the creation of links on my page.

Can anyone assist me with this dilema?

I want to make the sort work like www.asos.com (clothes shopping site). YOu can sort by various things - they don't use rewritten URLs though so it's a LOT easier?

g1smd

6:30 pm on Mar 24, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Why bulk up the URL with literal /color/ and /gender/ and /speed/ words?

The user journey should not affect the URL of the final product page.

The URL should be both simplified and normalised. I'd use /m-red/fast and /f-green/slow and so on here.

tensai288

6:39 pm on Mar 24, 2009 (gmt 0)

10+ Year Member



g1smd

I'm quite new to PHP and this is basically the first way I could so to do what I want to achieve.

I'd like the URLs to be as simple as possible for this part

(btw, I have denied access to /price, /view, /color etc with robots.txt as obviously I don't want these duplicate content pages indexed).

I'm not sure how to simpify it using htaccess using the method you are suggesting,

If they click men and fast, how would the URL look /m-blank/fast etc. I'm not really sure how to approach this?

jdMorgan

6:41 pm on Mar 24, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Since the URLs are created and defined by the links on your pages, why not simply do all the "heavy lifting" in your php script, and force a standard URL-path-variable order when creating the links?

That leaves you with only the problem of "missing" variables in the URL-path, which you can deal with either in .htaccess (with far fewer rules) or you could even "stuff" the missing URL-path-parts with "null" or "all," quite possibly leaving only the requirement for a single rule in .htaccess.

It is possible to "sort" the variables in .htaccess if each variable has a finite set of values which is mutually-exclusive with the variable values of all the other variables, but why bother with all that if you can use the much more powerful and flexible tools in PHP to do the job?

One more hint: If you do end up with a few remaining variations on URL-format, beyond the easily-classifiable things like color, gender, size, speed, put those special-case variables at the end of the URL, so that the preceding fixed-position variables can be used to identify what they mean.

Also, by adopting a fixed-position-per-variable approach, you might be able to do away with the color, gender, size parts of the URL entirely, leaving only a URL format like /dress/red/ladies/8/formal

The important thing to grasp is that a well-defined and well-ordered URL taxonomy will result in fewer and simpler (and faster) rules.

Jim

tensai288

6:50 pm on Mar 24, 2009 (gmt 0)

10+ Year Member



Thanks for the useful replies guys,

jdMorgan,

I think my main problem here is that I'm currently creating my URLs by using this: $url = (!empty($_SERVER['HTTPS'])) ? "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] : "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
(I found this when Googling on how to get current URL in PHP).

THen I have it setup so that /type/sports or whatever is appended to that URL automatically. This is why the ordering always changes.

I'm not really sure how to "force the URL" to be in a specific order easily but am going to give it some thought now. Any more advice would be appreciated

I spent ages getting my method working too hehe :)

tensai288

6:52 pm on Mar 24, 2009 (gmt 0)

10+ Year Member



I'm going to make all my links have this format:

domain.com/product/all/all/mens/fast/all (if they select mens, and then fast for example).

The URL doesn't look very nice but I guess this is the best way of doing what I want to do?

tensai288

8:14 pm on Mar 24, 2009 (gmt 0)

10+ Year Member



Hi guys

I've decided to via another method (i was browsing ebuyer.com and noticed the way they do things).

What I want to do now is have it so my links are in this format:

domain.com/sort/?type=sports

I've made a rewrite in htaccess of this format:
RewriteRule ^([^/]+)-product/sort/$ categorypage.php?brand=$1 [L]

in theory this link should work:

http://www.example.com/name-product/sort/&type=sports

I was hoping &type=sports just got appended to the end of my rewritten URL (you know what I mean?) but it doesn't work... not sure why, I've also tried with ?type= with no luck.

Any ideas?

[edited by: dreamcatcher at 10:25 am (utc) on Mar. 25, 2009]
[edit reason] use example.com. Thanks. [/edit]

tensai288

11:26 pm on Mar 24, 2009 (gmt 0)

10+ Year Member



Hmm I still can't seem to get this working (regarding my previous post).

I have my rewrite setup in the way I described in the last post and have tried linking to:

http://www.example.com/name-product/sort/?type=sports
http://www.example.com/brand-product/sort/&type=sports
http://www.example.com/brand-product/sort?type=sports
http://www.example.com/brand-product/sort&type=sports

but none of these are working

What I want to happen is that my link on the backend is actually domain.co.uk/categorypage.php?brand=$1&type=sports

Doing it this way means that any order of parameters will have the same results and avoid any further regular expressions

Can anyone see what i'm doing wrong?

[edited by: dreamcatcher at 10:25 am (utc) on Mar. 25, 2009]
[edit reason] use example.com. Thanks. [/edit]

g1smd

11:43 pm on Mar 24, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



URLs are used 'out on the web'. User agents 'see' a URL by reading the href attribute of the link on your page. You can make the format of that link anything you want. For any given content 'page' of the site, you need one fixed format URL that can access that content. To have multiple URLs is Duplicate Content.

The backend script likely works with parameters. Those parameters can be in any order when the script is called. It is a very bad idea to have those parameters in the URL, with multiple orders.

This is where the rewrite comes in. It maps the 'friendly' URL requests to the parameter-based format needed inside the server. The rewrite does not 'make' URLs. URLs are defined only by what you place in the links on the pages of your site.

Your latest URL formats are adding complexity, not simplifying things.

I worked on a site where all URLs for product pages were in the form example.com/123/1234567 and that was very easy to rewrite to the internal script, without it rewriting for any other format of URL request.

Category indexes and drill-down pages used a different format of URL. The path a user took to get to a product page did not change the URL for, and was not reflected in, the URL for that product page. The database had entries for the product categories, and the user path was stored, and updated in a cookie, to use for building their breadcrumb navigation.

tensai288

12:36 am on Mar 25, 2009 (gmt 0)

10+ Year Member



Hi,
Thanks for the response

I am blocking the /sort folder with robots.txt to avoid duplicate content - will likely add the canonical meta tag and maybe a no index meta tag to for good measure.

You mentioned that your category indexes and drill-down pages used a different format, which format did you have for this?

Out of all the formats listed (or even not listed), in this thread, what would you recommend would be the best practice method of approaching what i'm trying to achieve?

I only suggested my most recent method because I've noticed some shop websites seem to do this

check out ebuyer.com as an example, if you go to the monitors page, and click 17 inch, then choose a brand, the parameters appear in a different order as to if you pick a brand, then drill down to 17 inch.

thanks again

g1smd

12:45 am on Mar 25, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The page that listed all the mens, large size, blue, items was maybe:

/mens/large/blue

One item on that page might have had product code 1023472.

The URL for the product page for that item was simply: /1023472.

It was not: /mens/large/blue/1023472

See the difference?

tensai288

12:58 am on Mar 25, 2009 (gmt 0)

10+ Year Member



ah i see what you mean and I think I might have been misleading before.

I don't wish to have product ID put in the URL like that

my "category page" is actually a brand page. This page is defined by the link to that page from the index page. For example I might link to "audi cars" with the URL domain.com/audi-cars

I have my htaccess setup to assign the part before -cars as a variable, $brand on categorypage.php . Then on the category page the default mySQL query lists ALL products under that brand.

The category page also has a sub menu which you can sort by Gender and Type (but soon more variables too). There is also a link to "view all products" as I have limited the mySQL to 9 results to keep the page looking good.

When someone "drills down" to find just mens cars, then the link to "Mens" goes to domain.com/audi-cars/gender/mens and my htaccess matches the (mens) part and assigns that to $gender, which is also drawn into the category page (category.php?brand=audi&gender=mens

So the issue was that i have to create different htaccess directives for each variation. e.g. they might click mens / sports / view all and i will need my htaccess to rewrite that to: categorypage.php?brand=audi&gender=mens&type=sports&viewall=yes

It was initially suggested to keep everything in the same order e.g. if someone only clicked "Sports" as the type of car they were looking for. It would have a link like domain.com/audi-cars/all/sports/all/all

where all just means "all genders", "all prices", "all etc" - this is one method I could go for but I think it perhaps be more work than just having the parameters in the URL the users see (as I am blocking these with robots.txt duplicate content isnt an issue).

I am also considering using Ajax/ javascript to just keep the URL the same and refresh the Div that has the products that appear when drilled down. But I am a long way off working of how to do that !

tensai288

1:02 am on Mar 25, 2009 (gmt 0)

10+ Year Member



contd.

So If we use my latest method:

Lets say I want to select sports cars, I click the "Sports" link that links to

http://www.example.com/audi-cars/sort/?type=sports I need that "type" to be passed through to the next page, but for some reason it doesn't get passed through, I thought maybe it's because I have used a question mark, when there is already one in my redirect to cover the brand. e.g. RewriteRule ^([^/]+)-product/sort/$ categorypage.php?brand=$1 [L]

so in the theory the URL on the backend is categorypage.php?brand=$1?type=sports ? Or so I think?

[edited by: dreamcatcher at 10:26 am (utc) on Mar. 25, 2009]
[edit reason] use example.com. Thanks. [/edit]

tensai288

1:19 pm on Mar 25, 2009 (gmt 0)

10+ Year Member



I've been googling around still trying to find what the perfect solution is :)

Actually stumbled across a post over at dave naylor's site that you commented on g1smd. Within it someone mentioned Magento as a good CMS for e-commerce websites. I went to one of their "showcase" websites that uses Magento and tested to see how their URLs work.

<snipped urls>

bring up the same products, but as you can see the folders are in a different order (essentially the original problem I had where i'd have to make rewrite rules for every combination).

So my latest question is :) is it possible to match whatever comes after a certain term in the htaccess? I've always assumed that when you have rules such as:

RewriteRule ^([^/]+)-product/sort/$ categorypage.php?brand=$1 [L]

it matches whatever is straight after the domain e.g. example.com/ANYTHING-product/sort

but can you rewrite rules in this way:

RewriteRule ^color/([^/]+)$ ?color=$1
RewriteRule ^view/([^/]+)$ ?view=$1
RewriteRule ^gender/([^/]+)$ ?gender=$1

so it only places things into query string on the backend, not the whole URL?

[edited by: coopster at 11:11 am (utc) on Mar. 26, 2009]
[edit reason] removed urls per TOS [webmasterworld.com] [/edit]

tensai288

3:46 pm on Mar 25, 2009 (gmt 0)

10+ Year Member



Just did some research and discovered the [QSA] flag - seems to have solved my previous problem!