Gixxy22
Gixxy22

Reputation: 507

Submit form to rewritten URLs?

I am trying to create nice URL's for my Magento search form, to make:

http://domain.com/catalogsearch/result/?q=KEYWORD

look like this:

http://domain.com/search/KEYWORD

I have written this is my htaccess file:

RewriteRule ^search/([^/]+)/?$ /catalogsearch/result/?q=$1 [QSA,P,NC]

Which works nicely, when I type in http://domain.com/search/KEYWORD it displays the results as it should.

BUT...

I can't workout how to get my search form to go to the nice format URL, it still goes to the original.

My search form is currently like this:

<form id="search_form" action="http://domain.com/catalogsearch/result/" method="get">
        <input id="search" type="search" name="q" value="KEYWORD" maxlength="128">
        <button type="submit">search</button>
</form>

Any point in the right direction much appreciated.

Upvotes: 0

Views: 833

Answers (1)

Agop
Agop

Reputation: 1917

There are a couple of things going on here, so let me try to explain the best I can.

First and foremost, your main issue is the generation of this new "pretty" search URL. When you use a <form> with method="GET", each input (i.e. <input name="q">) will get appended to the form's action as a query parameter (you'll get /search?q=foo instead of /search/foo).

In order to fix this, you need to do two things:

  1. Change your form tag to look like this:

    <form id="search_form" action="<?php echo Mage::getUrl('search'); ?>" method="GET">
    

    This will ensure that the form is submitted to /search instead of /catalogsearch/result. (You'll still get a ?q=foo, though, and that will be resolved in #2.)

  2. Add a bit of JavaScript which hijacks the form submission and forms the desired URL:

    var form = document.getElementById('search_form'),
        input = document.getElementById('search');
    
    form.onsubmit = function() {
        // navigate to the desired page
        window.location = form.action + input.value;
    
        // don't actually submit the form
        return false;
    };
    

That'll get you up and running, but there are still some other issues which you should resolve.

Using RewriteRule based rewrites with Magento does not work well. I haven't quite figured out the technical reason for this, but I've had the same trouble that you're having. The reason that your rewrite works with the P flag is because the P flag turns the rewrite into a proxy request. This means that your web server will make another request to itself with the new URL, which avoids the typical RewriteRule trouble you'd run into.

So, how do you utilize a custom pretty URL without using RewriteRule? You use Magento's internal rewrite logic! Magento offers regex-based rewrite logic similar to RewriteRule through its configuration XML:

<config>
    <global>
        <rewrite>
            <some_unique_identifier>
                <from><![CDATA[#/search/(.*)/?$#]]></from>
                <to><![CDATA[/catalogsearch/result/index/q/$1/]]></to>
                <complete />
            </some_unique_identifier>
        </rewrite>
    </global>
</config>

By putting that configuration in one of your modules, Magento will internally rewrite requests of the form /search/foo to /catalogsearch/result/index/q/foo/. Note that you have to use Magento's custom parameter structure (name-value pairs separated by /), as it will not parse query string parameters after it performs this internal rewrite. Also note that you have to specify the full module-controller-action trio (/catalogsearch/result/index/) because otherwise q would be interpreted as an action name, not a parameter name.

This is much better than using a proxy request because it doesn't issue a secondary request, and the rewrite happens in Magento's core route handling logic.

This should be enough to get you completely up and running on the right path. However, if you're interested, you could take this one step further.

By using the above techniques, you'll end up with three URLs for your searches: /search/foo, /catalogsearch/result/?q=foo, and /catalogsearch/result/q/foo. This means that you essentially have three pages for each search query, all with the same content. This is not great for SEO purposes. In order to combat this drawback, you can create a 301 permanent redirect from the second two URLs to redirect to your pretty URL, or you can use a <link rel="canonical"> tag to tell search engines that your pretty URL is the main one.

Anyways, I hope that all of this helps and puts you on the right track!

Upvotes: 1

Related Questions