Jump to content

Change a part of SEF URL, displaying product attribute name


Recommended Posts

Hello,

 

But default the URL of product with selected attribute (say 'color') is generated according to this template:

 

...productname.html#/color-colorname

 

How can I change it to

 

...productname.html#/color-colorID

 

The reason why in need this is because in case my color name uses non-latin characters, there is blank space in URL. So displaying colorID would be a nice and easy workaround about that.

 

Any advices are appreciated

Edited by Amazzing (see edit history)
Link to comment
Share on other sites

  • 2 months later...

I am having the same issue - attribute name and value in Cyrillic are not displayed in the URL. So I get something like:

 

...productname.html#/-

 

instead of

 

...productname.html#/color-colorname 
 
getProductAttribute() function in product.js seems to append the URL with attribute name and value but I am not sure what needs to be changed there or if this is the right place to look at in the first place. So any hint on how to change attribute name to attribute ID or language in which attribute name is displayed would be much appreciated.

 

After some research I found a workaround by switching on 'Use accented characters in URL' setting in Settings > SEO & URLs. Now attribute names and values are displayed in Cyrillic:

 

...productname.html#/цвет-названиецвета

Link to comment
Share on other sites

If anybody needs, here is a workaround for replacing attribute names by ids in URLs:

1) Create an override for product.php: /override/classes/Product.php

2) Override 2 functions: getAttributesParams(..), getAttributesInformationsByProduct(..) by doing 3 sets of replacements: 
--

this    : al.`name` as `attribute`
to this: al.`id_attribute` as `attribute`
--
this    : al.`name`
to this: al.`id_attribute` as `name`
--
this    : agl.`name` as `group`
to this: agl.`id_attribute_group` as `group`
 
You can find a complete override for Product.php inside the spoiler
 

 

 

<?php

class Product extends ProductCore
{    
    //overring links for attributes use id instead of name
    /**
     * Get label by lang and value by lang too
     * @todo Remove existing module condition
     * @param int $id_product
     * @param int $product_attribute_id
     * @return array
     */
    public static function getAttributesParams($id_product, $id_product_attribute)
    {
        // if blocklayered module is installed we check if user has set custom attribute name
        if (Module::isInstalled('blocklayered'))
        {
            $nb_custom_values = Db::getInstance()->executeS('
            SELECT DISTINCT la.`id_attribute`, la.`url_name` as `name`
            FROM `'._DB_PREFIX_.'attribute` a
            LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac
                ON (a.`id_attribute` = pac.`id_attribute`)
            LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa
                ON (pac.`id_product_attribute` = pa.`id_product_attribute`)
            '.Shop::addSqlAssociation('product_attribute', 'pa').'
            LEFT JOIN `'._DB_PREFIX_.'layered_indexable_attribute_lang_value` la
                ON (la.`id_attribute` = a.`id_attribute` AND la.`id_lang` = '.(int)Context::getContext()->language->id.')
            WHERE la.`url_name` IS NOT NULL AND la.`url_name` != \'\'
            AND pa.`id_product` = '.(int)$id_product.'
            AND pac.`id_product_attribute` = '.(int)$id_product_attribute);

            if (!empty($nb_custom_values))
            {
                $tab_id_attribute = array();
                foreach ($nb_custom_values as $attribute)
                {
                    $tab_id_attribute[] = $attribute['id_attribute'];

                    $group = Db::getInstance()->executeS('
                    SELECT g.`id_attribute_group`, g.`url_name` as `group`
                    FROM `'._DB_PREFIX_.'layered_indexable_attribute_group_lang_value` g
                    LEFT JOIN `'._DB_PREFIX_.'attribute` a
                        ON (a.`id_attribute_group` = g.`id_attribute_group`)
                    WHERE a.`id_attribute` = '.(int)$attribute['id_attribute'].'
                    AND g.`id_lang` = '.(int)Context::getContext()->language->id.'
                    AND g.`url_name` IS NOT NULL AND g.`url_name` != \'\'');
                    if (empty($group))
                    {
                        $group = Db::getInstance()->executeS('
                        SELECT g.`id_attribute_group`, g.`name` as `group`
                        FROM `'._DB_PREFIX_.'attribute_group_lang` g
                        LEFT JOIN `'._DB_PREFIX_.'attribute` a
                            ON (a.`id_attribute_group` = g.`id_attribute_group`)
                        WHERE a.`id_attribute` = '.(int)$attribute['id_attribute'].'
                        AND g.`id_lang` = '.(int)Context::getContext()->language->id.'
                        AND g.`name` IS NOT NULL');
                    }
                    $result[] = array_merge($attribute, $group[0]);
                }
                $values_not_custom = Db::getInstance()->executeS('
                SELECT DISTINCT a.`id_attribute_group`, al.`id_attribute` as `name`, agl.`id_attribute_group` as `group`
                FROM `'._DB_PREFIX_.'attribute` a
                LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al
                    ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.(int)Context::getContext()->language->id.')
                LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl
                    ON (a.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.(int)Context::getContext()->language->id.')
                LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac
                    ON (a.`id_attribute` = pac.`id_attribute`)
                LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa
                    ON (pac.`id_product_attribute` = pa.`id_product_attribute`)
                '.Shop::addSqlAssociation('product_attribute', 'pa').'
                WHERE pa.`id_product` = '.(int)$id_product.'
                AND pac.id_product_attribute = '.(int)$id_product_attribute.'
                AND a.`id_attribute` NOT IN('.implode(', ', $tab_id_attribute).')');
                $result = array_merge($values_not_custom, $result);
            }
            else
            {
                $result = Db::getInstance()->executeS('
                SELECT al.`id_attribute` as `name`, agl.`id_attribute_group` as `group`
                FROM `'._DB_PREFIX_.'attribute` a
                LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al
                    ON (al.`id_attribute` = a.`id_attribute` AND al.`id_lang` = '.(int)Context::getContext()->language->id.')
                LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac
                    ON (pac.`id_attribute` = a.`id_attribute`)
                LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa
                    ON (pa.`id_product_attribute` = pac.`id_product_attribute`)
                '.Shop::addSqlAssociation('product_attribute', 'pa').'
                LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl
                    ON (a.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.(int)Context::getContext()->language->id.')
                WHERE pa.`id_product` = '.(int)$id_product.'
                    AND pac.`id_product_attribute` = '.(int)$id_product_attribute.'
                    AND agl.`id_lang` = '.(int)Context::getContext()->language->id);
            }
        }
        else
        {
            $result = Db::getInstance()->executeS('
            SELECT al.`id_attribute` as `name`, agl.`id_attribute_group` as `group`
            FROM `'._DB_PREFIX_.'attribute` a
            LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al
                ON (al.`id_attribute` = a.`id_attribute` AND al.`id_lang` = '.(int)Context::getContext()->language->id.')
            LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac
                ON (pac.`id_attribute` = a.`id_attribute`)
            LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa
                ON (pa.`id_product_attribute` = pac.`id_product_attribute`)
            '.Shop::addSqlAssociation('product_attribute', 'pa').'
            LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl
                ON (a.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.(int)Context::getContext()->language->id.')
            WHERE pa.`id_product` = '.(int)$id_product.'
                AND pac.`id_product_attribute` = '.(int)$id_product_attribute.'
                AND agl.`id_lang` = '.(int)Context::getContext()->language->id);
        }
        return $result;
    }

    /**
     * @todo Remove existing module condition
     * @param int $id_product
     */
    public static function getAttributesInformationsByProduct($id_product)
    {
        // if blocklayered module is installed we check if user has set custom attribute name
        if (Module::isInstalled('blocklayered'))
        {
            $nb_custom_values = Db::getInstance()->executeS('
            SELECT DISTINCT la.`id_attribute`, la.`url_name` as `attribute`
            FROM `'._DB_PREFIX_.'attribute` a
            LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac
                ON (a.`id_attribute` = pac.`id_attribute`)
            LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa
                ON (pac.`id_product_attribute` = pa.`id_product_attribute`)
            '.Shop::addSqlAssociation('product_attribute', 'pa').'
            LEFT JOIN `'._DB_PREFIX_.'layered_indexable_attribute_lang_value` la
                ON (la.`id_attribute` = a.`id_attribute` AND la.`id_lang` = '.(int)Context::getContext()->language->id.')
            WHERE la.`url_name` IS NOT NULL AND la.`url_name` != \'\'
            AND pa.`id_product` = '.(int)$id_product);

            if (!empty($nb_custom_values))
            {
                $tab_id_attribute = array();
                foreach ($nb_custom_values as $attribute)
                {
                    $tab_id_attribute[] = $attribute['id_attribute'];

                    $group = Db::getInstance()->executeS('
                    SELECT g.`id_attribute_group`, g.`url_name` as `group`
                    FROM `'._DB_PREFIX_.'layered_indexable_attribute_group_lang_value` g
                    LEFT JOIN `'._DB_PREFIX_.'attribute` a
                        ON (a.`id_attribute_group` = g.`id_attribute_group`)
                    WHERE a.`id_attribute` = '.(int)$attribute['id_attribute'].'
                    AND g.`id_lang` = '.(int)Context::getContext()->language->id.'
                    AND g.`url_name` IS NOT NULL AND g.`url_name` != \'\'');
                    if (empty($group))
                    {
                        $group = Db::getInstance()->executeS('
                        SELECT g.`id_attribute_group`, g.`name` as `group`
                        FROM `'._DB_PREFIX_.'attribute_group_lang` g
                        LEFT JOIN `'._DB_PREFIX_.'attribute` a
                            ON (a.`id_attribute_group` = g.`id_attribute_group`)
                        WHERE a.`id_attribute` = '.(int)$attribute['id_attribute'].'
                        AND g.`id_lang` = '.(int)Context::getContext()->language->id.'
                        AND g.`name` IS NOT NULL');
                    }
                    $result[] = array_merge($attribute, $group[0]);
                }
                $values_not_custom = Db::getInstance()->executeS('
                SELECT DISTINCT a.`id_attribute`, a.`id_attribute_group`, al.`id_attribute` as `attribute`, agl.`id_attribute_group` as `group`
                FROM `'._DB_PREFIX_.'attribute` a
                LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al
                    ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.(int)Context::getContext()->language->id.')
                LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl
                    ON (a.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.(int)Context::getContext()->language->id.')
                LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac
                    ON (a.`id_attribute` = pac.`id_attribute`)
                LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa
                    ON (pac.`id_product_attribute` = pa.`id_product_attribute`)
                '.Shop::addSqlAssociation('product_attribute', 'pa').'
                '.Shop::addSqlAssociation('attribute', 'pac').'
                WHERE pa.`id_product` = '.(int)$id_product.'
                AND a.`id_attribute` NOT IN('.implode(', ', $tab_id_attribute).')');
                $result = array_merge($values_not_custom, $result);
            }
            else
            {
                $result = Db::getInstance()->executeS('
                SELECT DISTINCT a.`id_attribute`, a.`id_attribute_group`, al.`id_attribute` as `attribute`, agl.`id_attribute_group` as `group`
                FROM `'._DB_PREFIX_.'attribute` a
                LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al
                    ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.(int)Context::getContext()->language->id.')
                LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl
                    ON (a.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.(int)Context::getContext()->language->id.')
                LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac
                    ON (a.`id_attribute` = pac.`id_attribute`)
                LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa
                    ON (pac.`id_product_attribute` = pa.`id_product_attribute`)
                '.Shop::addSqlAssociation('product_attribute', 'pa').'
                '.Shop::addSqlAssociation('attribute', 'pac').'
                WHERE pa.`id_product` = '.(int)$id_product);
            }
        }
        else
        {
            $result = Db::getInstance()->executeS('
            SELECT DISTINCT a.`id_attribute`, a.`id_attribute_group`, al.`id_attribute` as `attribute`, agl.`id_attribute_group` as `group`
            FROM `'._DB_PREFIX_.'attribute` a
            LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al
                ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.(int)Context::getContext()->language->id.')
            LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl
                ON (a.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.(int)Context::getContext()->language->id.')
            LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac
                ON (a.`id_attribute` = pac.`id_attribute`)
            LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa
                ON (pac.`id_product_attribute` = pa.`id_product_attribute`)
            '.Shop::addSqlAssociation('product_attribute', 'pa').'
            '.Shop::addSqlAssociation('attribute', 'pac').'
            WHERE pa.`id_product` = '.(int)$id_product);
        }
        return $result;
    }
    
}

 

 

 

  • Like 1
Link to comment
Share on other sites

If you don't want to make all these code modifications, you can choose this way:

 

1) Install block layered navigation

2) After installation you will have a new field on attribute page, "the attribute url name".

After filling in this field, a new URL name will be used not only for blocklayered, but also for all links on the website

 

If you don't need this module, you can hide it by unhooking it, or by using css styles.

Keep in mind, that it loads an additional .css ans .js even if hidden

Edited by Amazzing (see edit history)
  • Like 1
Link to comment
Share on other sites

  • 4 months later...
  • 1 month later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...