Saturday, March 16, 2013

Polishing up the magento mini search

 Magento comes with a mini search form complete with search suggestions. To fetch and show the search suggestions magento uses the prototype Ajax.Autocompleter. This works well but it's not fully configured in the default magento setup. The aim of this post is to complement the magento search suggestions with the following:
  • limit the number of returned results - magento returns all results by default and this can generate a long list as well as adding some overhead
  • add a search indicator so the user knows that a search is in progress
  • highlight the search term in the returned results
  • remove the number of results that magento adds to each returned result

Preparing files for editing

To achieve the points above we'll need to edit some of the magento files. As it's not good to change the magento core files we'll copy these files to the local code pool. We'll need to copy the following files:
  • app/code/core/Mage/CatalogSearch/Model/Query.php to app/code/local/Mage/CatalogSearch/Model/
  • app/code/core/Mage/CatalogSearch/Block/Autocomplete.php to app/code/local/Mage/CatalogSearch/Block/
  • app/design/frontend/base/default/template/catalogsearch/ to app/design/frontend/default/default/template/catalogsearch/
 In addition to the above files we will need to edit js/varien/js.js and add some css styling. You can add the css either to your theme's css files or directly in the updated file

Limit the number of results returned by magento

Limiting the number of results is quite simple. All we need to do is edit app/code/local/Mage/CatalogSearch/Model/Query.php and add a line to the getSuggestCollection function so it looks like the following:
     * Retrieve collection of suggest queries
     * @return Mage_CatalogSearch_Model_Resource_Query_Collection
    public function getSuggestCollection()
        $collection = $this->getData('suggest_collection');
        if (is_null($collection)) {
            $collection = Mage::getResourceModel('catalogsearch/query_collection')
            //limit the number of returned results
            $this->setData('suggest_collection', $collection);
        return $collection;
The code that limits the result numbers is on line 14.

Removing results numbers and adding highlights to results

Ajax.Autocompleter needs a ul returned containing the search suggestions. Magento creates the list in Mage/CatalogSearch/Block/Autocomplete.php in the _toHtml() function. Edit app/code/local/Mage/CatalogSearch/Block/Autocomplete.php and change the _toHtml function as below. You can also add other changes you want applied to the results list.
    protected function _toHtml()
     //change html to return a list on error otherwise the loader image doesn't go away
        $html = '
    '; if (!$this->_beforeToHtml()) { return $html; } $suggestData = $this->getSuggestData(); if (!($count = count($suggestData))) { return $html; } $count--; //get the query text $query = $this->helper('catalogsearch')->getQueryText(); $html = '
    • '; foreach ($suggestData as $index => $item) { if ($index == 0) { $item['row_class'] .= ' first'; } if ($index == $count) { $item['row_class'] .= ' last'; } $text = $this->htmlEscape($item['title']); //get the first case insensitive query occurence in the text $pos = stripos($text,$query); $length = strlen($query); if ($pos !== false) { //get the actual case sensitive piece of text that matches the query and highlight it $replacement="".substr($text, $pos, $length).""; //replace the query in the text with the highlighted version $text = substr_replace($text,$replacement,$pos, $length); } $html .= '
    • '. $text.'
    • '; } $html.= '
    '; return $html; }

    Adding the search indicator element

    The autocompleter plugin can display a visual indicator while the ajax request is running. You can generate a loading indicator at We'll need to add a div that will contain our progress indicator. To do this edit app/design/frontend/default/default/template/catalogsearch/ and add the following somewhere inside the search form div (or in another place where you want it displayed):
    I've uploaded my indicator to the skin/frontend/default/default/images/ folder so I can reference it using the magento getSkinUrl function.
    I want my loading image to show over the search input so I added the css styles to the element to make sure it's positioned correctly and in front of the input.

    Updating the autocomplete javascript

    The last thing we need to do is update the javascript used to initialize the Ajax.Autocompleter. Open js/varien/js.js and search for the following lines of code:
            new Ajax.Autocompleter(
                    method: 'get',
                    minChars: 2,

    Add the following lines after the miChars line:
                    frequency: 0.5,
                    indicator: 'search-running',
    The frequency tells autocompleter how often it should poll the input for changes and the indicator is the id of the element that should be shown while the ajax request is running.

    That's it. Comments are always welcome.

    Friday, March 8, 2013

    Random vi shortcuts

    Toggling syntax highlighting

    :syntax [on/off]

    Changing the colorscheme

    :colorscheme [colorscheme]

    Short form (actually can be anything from colo to colorscheme):
    :colo [colorscheme]

    Some default colorschemes:torte, morning, evening, desert, pablo etc. To cycle through the available colorchemes press tab after the command
    To set a colorscheme by default for a profile edit ~/.vimrc and add the following lines:

    syntax on
    colorscheme [colorscheme]

    Saturday, March 2, 2013

    Getting magento product custom options

    In one case custom options for products were supposed to be required but they were not set to required in the admin.As there were a lot of products it was impractical to set those manually so the only solution was a script. The easy way is to go into the database and set the is_require field to 1 in the catalog_product_option table. The following query can be used:
    UPDATE `catalog_product_option` SET `is_require`=1

    Getting the values for those options is difficult using sql queries so here's a bit of code to achieve that.
    require_once (str_replace('//','/',dirname(__FILE__).'/') .'../app/Mage.php');
    $collection = Mage::getModel('catalog/product')->getCollection()->load();
    echo $collection->count(),"<b r/>";
    foreach ($collection as $product) {
     echo "<b>",$product->getId(), " - ",$product->getSku(),"</b><b r/>"; 
     $i = 1;
     echo "<pre>";
     foreach ($product->getOptions() as $o) {
         echo "<strong>Custom Option:" . $i . "</strong><b r/>";
         echo "Custom Option TYPE: " . $o->getType() . "<b r/>";
         echo "Custom Option TITLE: " . $o->getTitle() . "<b r/>";
         echo "Custom Option Required: " . $o->getIsRequire() . "<b r/>";
         echo "Custom Option Values: <b r/>";
         $values = $o->getValues();
         foreach ($values as $v) {
         echo "----------------------------------<b r/>";

    Thanks to Subesh Pokhrel
    Due to some unknown black magic the br tags in the code snippets get interpreted and having no time to deal with it now I've just  put a space between the b and the r

    Friday, March 1, 2013

    Linux admin shortcuts

    List of sometimes useful commands

    System information

    Getting hardware information

    Hardware information can be obtained using the dmidecode tool that tries to decode the dmi table. It can also filter the information provided using the -t flag.
    Getting information the physical memory:

    dmidecode -t memory


    Getting information about a domain

    Domain information cat be obtained using the DNS lookup utility dig. The simplest usage would be:

    dig domainname

    and it returns information on the A record of the host.
    The utility can be used to get other types of information by using the -t switch and specifying the record type. For nameservers the query is:
    dig domainname -t NS

    For mail records:
    dig domainname -t MX

    Reverse lookups can be prformed using the -x flag:
    dig -x ip_address