tob88
tob88

Reputation: 2211

Permanent URL Parameters

I have been building a fashion e-commerce app that is quite far along the development cycle. It caters for both men's and women's products. At the moment, the user selects their gender at the start, and a gender_id is then passed into the user's session. This ID is then used in many of the queries throughout the site, and it determines which gender products the user is shown.

However, for SEO purposes, it is necessary that this information is shown in the URL and not the session. I do not want to have to pass a gender parameter for every link I do, like this...

http://www.shop.com/products?category=Jeans&gender=women

Essentially what I'd like to do is input the gender into the route, and have it stay. I have seen some sites where the URL is structured as follows...

http://www.shop.com/women/products?category=Jeans

How can I achieve this second URL structure with minimal impact to my controllers? Or perhaps there is a different way I could achieve my goal? Thanks!

Upvotes: 1

Views: 271

Answers (3)

Lukas Eklund
Lukas Eklund

Reputation: 6138

Put it in your routes with a scope:

scope ':gender', :constraints => {:gender => /women|men/} do
  resources :products
  resources :cart
  # other routes here
end

You can access gender with params[:gender]. Any routes you place in that block will be scoped to a gender context.

Additionally, the gender scope will default to the current scope when generating urls. For example, if I browse to /men/products and in that view I have a link to cart, if the url is generated with cart_path the url will be /men/cart. Once the select a gender you could write redirect them to the proper scoped path. The one problem I see is that you lose the unstopped routes for product and cart with this method.

Upvotes: 3

ClydeFrog
ClydeFrog

Reputation: 1012

Instead of doing a HTTP-GET, you may want to take a look at HTTP-POST which doesn't pass variables in the URL. For example, here is a simple HTML-page with one HETT-GET action and one HTTP-POST action:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
    <meta http-equiv="content-type" content="text/html;charset=ISO-8859-1"> 
    <title>HTTP example</title>        
</head> 

<body> 

<h1>POST & GET example</h1> 

    <h2> Post form</h2> 
    <form method="post" action="post_get2.php"> 
    text:<input type="text" size =40 name="name"> 
    <input type=submit value="Submit Post"> 
    </form> 

    <h2> GET form</h2> 
    <form method="get" action="post_get2.php"> 
    text:<input type="text" size =40 name="name"> 
    <input type=submit value="Submit Get" > 
    </form> 

</body> 
</html>

And here's a simple PHP-page (post_get2.php) that detects if you made a POST or GET action and prints it on the page:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
<meta http-equiv="content-type" content="text/html;charset=ISO-8859-1"> 
<title>HTTP example</title>        
</head> 

<body> 

<h1>POST & GET example</h1> 

<? 

    function stripFormSlashes($arr) 
        { 
        if (!is_array($arr)) 
                { 
                return stripslashes($arr); 
                } 
            else 
                { 
                return array_map('stripFormSlashes', $arr); 
                } 
        } 

    if (get_magic_quotes_gpc()) 
        { 
        $_GET  = stripFormSlashes($_GET); 
        $_POST = stripFormSlashes($_POST); 
        } 

    echo ("<br/>"); 
    echo ("<pre>"); 
    echo ("POST info:\n"); 
    print_r($_POST); 
    echo("</pre>"); 

    echo ("<br/>"); 
    echo ("<pre>"); 
    echo ("GET info:\n"); 
    print_r($_GET); 
    echo("</pre>"); 

    if($_GET['name']) 
        { 
        $name = $_GET['name']; 
        } 

    echo($name); 

?> 

<p> 
    <a><input type="button" value="back" onclick="history.go(-1)"></a> 
</p> 

</body> 
</html>

The great thing with POST is that it doesn't show what choices you made on your page. It just shows 'http://www.shop.com/products' all the time. Unlike GET 'http://www.shop.com/products?category=Jeans&gender=women'

Upvotes: 1

Greg W
Greg W

Reputation: 5239

You can pass in default GET parameters to your routes. For example, the pattern below would match http://www.shop.com/women/products?category=Jeans and automatically append gender=women to your params hash.

get '/women/products' => 'Products#index', :gender => 'women'
get '/men/products' => 'Products#index', :gender => 'men'

You could also generalize this a little more by using a placeholder and a constraint in the route definition.

get '/:gender/products' => 'Products#index', :constraints => {:gender => /men|women/}

Upvotes: 2

Related Questions