Una de Presta: Anidar categoria/ en la URL de subcategoria

Una de Presta: Anidar categoria/subcategoria en la URL de subcategoria

Este post vale tanto para Prestashop versión 1.6 como 1.7, lo que nos interesa es anidar una subcategoría a una categoría, para dejar la url así midominio.com/categoria/subcategoria.

Esta modificación de código sólo afectará a las páginas de subcategorías, no afecta a la página de cada producto, ya que el producto cogerá la siguiente url: midominio/subcategoria/producto.html. Entonces os preguntaréis, para que sirve esto si no se anida la categoria y subcategoria en la página de productos. Bueno, interesa si tenemos una estrategia de posicionar categorías y subcategorías en vez de posicionar productos, si que sirve, y bastante. Aquí te paso vínculo de un post relacionado con esto.

Entonces, si queremos hacer esta anidación, tenemos que hacer cambios en el archivo Dispatcher.php y el Link.php ubicados en la carpeta /classes/

En Prestashop 1.6

Dispatcher.php (línea 47 aprox.) cambiar:

'category_rule' => array(
    'controller' =>	'category',
    'rule' =>		'{id}-{rewrite}',
    'keywords' => array(
      'id' =>			array('regexp' => '[0-9]+', 'param' => 'id_category'),
      'rewrite' =>		array('regexp' => '[_a-zA-Z0-9\pL\pS-]*'),
      'meta_keywords' =>	array('regexp' => '[_a-zA-Z0-9-\pL]*'),
      'meta_title' =>		array('regexp' => '[_a-zA-Z0-9-\pL]*'),
    ),
  ),

por:

'category_rule' => array(
        'controller' =>    'category',
        'rule' => '{category:/}{rewrite}-{id}/',
        'keywords' => array(
            'id' =>            array('regexp' => '[0-9]+', 'param' => 'id_category'),
            'category' =>      array('regexp' => '[_a-zA-Z0-9-\pL]*'),
            'rewrite' =>        array('regexp' => '[_a-zA-Z0-9\pL\pS-]*'),
            'meta_keywords' =>    array('regexp' => '[_a-zA-Z0-9-\pL]*'),
            'meta_title' =>        array('regexp' => '[_a-zA-Z0-9-\pL]*'),
        ),
    ),

La id de la subcategoría se mostraría detrás, con esto conseguimos doble efecto, primero anidar la subcategoría, luego ponerle la id al final.

Link.php (línea 155 aprox)

// Set available keywords
$params = array();
$params['id'] = $category->id;
$params['rewrite'] = (!$alias) ? $category->link_rewrite : $alias;
$params['meta_keywords'] = Tools::str2url($category->meta_keywords);
$params['meta_title'] = Tools::str2url($category->meta_title);

// Selected filters is used by the module blocklayered
$selected_filters = is_null($selected_filters) ? '' : $selected_filters;

modificar por:

// Set available keywords
$params = array();
$params['id'] = $category->id;
$params['rewrite'] = (!$alias) ? $category->link_rewrite : $alias;
$params['meta_keywords'] = Tools::str2url($category->meta_keywords);
$params['meta_title'] = Tools::str2url($category->meta_title);

$pcategory= new Category($category->id_parent, $id_lang);
if($category->id_parent!=1 && $category->id_parent!=2)
$params['category'] = $pcategory->link_rewrite; 

// Selected filters is used by the module blocklayered
$selected_filters = is_null($selected_filters) ? '' : $selected_filters;

Por último hay que ir al BO, y al apartado Preferencias -> SEO&URL cambiar la ruta de las categorías:

por:

Et voilà!

Pero, si tenemos Prestashop 1.7, hacemos el mismo procedimiento en Dispatcher.php, pero en Link.php hay un pequeño cambio en la id de la variable de lenguaje, entonces donde pone:

public function getCategoryLink(
        $category,
        $alias = null,
        $idLang = null,
        $selectedFilters = null,
        $idShop = null,
        $relativeProtocol = false
    ) {
        $dispatcher = Dispatcher::getInstance();

        if (!$idLang) {
            $idLang = Context::getContext()->language->id;
        }

        $url = $this->getBaseLink($idShop, null, $relativeProtocol).$this->getLangLink($idLang, null, $idShop);

        // Set available keywords
        $params = array();

        if (!is_object($category)) {
            $params['id'] = $category;
        } else {
            $params['id'] = $category->id;
        }

        // Selected filters is used by the module ps_facetedsearch
        $selectedFilters = is_null($selectedFilters) ? '' : $selectedFilters;

Debemos dejarlo así:

public function getCategoryLink(
        $category,
        $alias = null,
        $idLang = null,
        $selectedFilters = null,
        $idShop = null,
        $relativeProtocol = false
    ) {
        $dispatcher = Dispatcher::getInstance();

        if (!$idLang) {
            $idLang = Context::getContext()->language->id;
        }

        $url = $this->getBaseLink($idShop, null, $relativeProtocol).$this->getLangLink($idLang, null, $idShop);

        // Set available keywords
        $params = array();

        if (!is_object($category)) {
            $params['id'] = $category;
        } else {
            $params['id'] = $category->id;
        }
        
        $pcategory= new Category($category->id_parent, $idLang);
        if($category->id_parent!=1 && $category->id_parent!=2)
        $params['category'] = $pcategory->link_rewrite; 


        // Selected filters is used by the module ps_facetedsearch
        $selectedFilters = is_null($selectedFilters) ? '' : $selectedFilters;

Como podréis ver hemos insertado:

$pcategory= new Category($category->id_parent, $idLang);
if($category->id_parent!=1 && $category->id_parent!=2)
$params['category'] = $pcategory->link_rewrite; 

La variación en Prestashop 1.7 es que la variable $id_lang pasa a ser $idLang.

Hecho esto, sólo me falta decir: Vekia is god.