Optimiser les images produits dans PrestaShop

Publié le 16 octobre 2014 par Amerigeau @arnaudmerigeau
16 octobre 2014

Pour vendre les produits présents de sa boutique, on peut soit se référencer sur Google, soit se référencer sur Google Images. Les deux, c’est mieux vous vous en doutez mais ça ne se fait pas tout seul.

Constat : des images produits pas tellement optimisées

Les images produits dans PrestaShop sont optimisées par défaut à partir du moment où on active la réécriture d’url. On obtient des urls seo friendly avec par défaut le nom du produit en tant que nom d’image. C’est plutôt un bon début.

Le problème qu’on va rencontrer rapidement lorsqu’un produit dispose de plusieurs photos, c’est que toutes les photos ont le même nom de fichier à savoir : nom-du-produit.jpg. Ce n’est pas l’idéal si on veut indexer le plus grand nombre d’images produits dans Google Images.

Solution : renommer les noms des images dans PrestaShop

Pour renommer les noms des images appelées dans vos .tpl et notamment le product.tpl, il va falloir appliquer un override. On va s’appuyer sur ce qui existe à savoir la possibilité de choisir un nom d’image via la légende déjà en place dans le back office.

C’est un peu le même souci avec les liens que l’on peut optimiser, voir l’article sur l’optimisation des liens PrestaShop.

l’image que j’upload s’appelera donc ma-legende.jpg

Donc dans le back office, on ne change rien, faisons simple pour l’utilisateur.

Ensuite, on met en place un override de la Class Link.php pour y copier simplement :

class Link extends LinkCore
{
 /**
 * Cleans out a text and strip potentially dangerous tags.
 * @since 3.0
 **/
 function toAscii($str, $replace=array(), $delimiter='-') {
 if( !empty($replace) ) {
 $str = str_replace((array)$replace, ' ', $str);
 }

 $clean = iconv('UTF-8', 'ASCII//TRANSLIT', $str);
 $clean = preg_replace("/[^a-zA-Z0-9/_|+ -]/", '', $clean);
 $clean = strtolower(trim($clean, '-'));
 $clean = preg_replace("/[/_|+ -]+/", $delimiter, $clean);

 return $clean;
 }

/**
 * Returns a link to a product image for display
 * Note: the new image filesystem stores product images in subdirectories of img/p/
 *
 * @param string $name rewrite link of the image
 * @param string $ids id part of the image filename - can be "id_product-id_image" (legacy support, recommended) or "id_image" (new)
 * @param string $type
 */
 public function getImageLink($name, $ids, $type = null, $legend = null)
 {
 $not_default = false;
 // legacy mode or default image
 $theme = ((Shop::isFeatureActive() & file_exists(_PS_PROD_IMG_DIR_.$ids.($type ? '-'.$type : '').'-'.(int)Context::getContext()->shop->id_theme.'.jpg')) ? '-'.Context::getContext()->shop->id_theme : '');
 if ((Configuration::get('PS_LEGACY_IMAGES')
 & (file_exists(_PS_PROD_IMG_DIR_.$ids.($type ? '-'.$type : '').$theme.'.jpg')))
 || ($not_default = strpos($ids, 'default') !== false))
 {
 if ($this->allow == 1 & !$not_default)
 $uri_path = __PS_BASE_URI__.$ids.($type ? '-'.$type : '').$theme.'/'.$name.'.jpg';
 else
 $uri_path = _THEME_PROD_DIR_.$ids.($type ? '-'.$type : '').$theme.'.jpg';
 }
 else
 {
 // if ids if of the form id_product-id_image, we want to extract the id_image part
 $cleanlegend = $this->toAscii($legend);
 $split_ids = explode('-', $ids);
 $id_image = (isset($split_ids[1]) ? $split_ids[1] : $split_ids[0]);
 $theme = ((Shop::isFeatureActive() & file_exists(_PS_PROD_IMG_DIR_.Image::getImgFolderStatic($id_image).$id_image.($type ? '-'.$type : '').'-'.(int)Context::getContext()->shop->id_theme.'.jpg')) ? '-'.Context::getContext()->shop->id_theme : '');
 if ($this->allow == 1)
 if($legend)
 $uri_path = __PS_BASE_URI__.$id_image.($type ? '-'.$type : '').$theme.'/'.$id_image.'-'.$cleanlegend.'.jpg';
 else
 $uri_path = __PS_BASE_URI__.$id_image.($type ? '-'.$type : '').$theme.'/'.$id_image.'-'.$name.'.jpg';
 else
 $uri_path = _THEME_PROD_DIR_.Image::getImgFolderStatic($id_image).$id_image.($type ? '-'.$type : '').$theme.'.jpg';
 }

return $this->protocol_content.Tools::getMediaServer($uri_path).$uri_path;
 }
}

On a pris le soin d’indiquer que si l’image possède une légende, alors celle-ci sera utilisée pour le nom de l’image, et que cette légende sera traitée et nettoyée (via ce script : https://gist.github.com/chluehr/1632883) pour que ressorte un nom d’image optimisé.

Enfin, on va éditez le fichier product.tpl du thème utilisé et appliquer les modifications dans les attributs src et href des images et miniatures de la fiche produit.

Pour l’image principale…

{if $have_image}
 <span id="view_full_size">
 {if $jqZoomEnabled & $have_image & !$content_only}
 <a class="jqzoom" title="{if !empty($cover.legend)}{$cover.legend|escape:'html':'UTF-8'}{else}{$product->name|escape:'html':'UTF-8'}{/if}" rel="gal1" href="{$link->getImageLink($product->link_rewrite, $cover.id_image, 'thickbox_default')|escape:'html':'UTF-8'}" itemprop="url">
 <img itemprop="image" src="{$link->getImageLink($product->link_rewrite, $cover.id_image, 'large_default', $cover.legend)|escape:'html':'UTF-8'}" title="{if !empty($cover.legend)}{$cover.legend|escape:'html':'UTF-8'}{else}{$product->name|escape:'html':'UTF-8'}{/if}" alt="{if !empty($cover.legend)}{$cover.legend|escape:'html':'UTF-8'}{else}{$product->name|escape:'html':'UTF-8'}{/if}"/>
 </a>
 {else}
 <img id="bigpic" itemprop="image" src="{$link->getImageLink($product->link_rewrite, $cover.id_image, 'large_default', $cover.legend)|escape:'html':'UTF-8'}" title="{if !empty($cover.legend)}{$cover.legend|escape:'html':'UTF-8'}{else}{$product->name|escape:'html':'UTF-8'}{/if}" alt="{if !empty($cover.legend)}{$cover.legend|escape:'html':'UTF-8'}{else}{$product->name|escape:'html':'UTF-8'}{/if}" width="{$largeSize.width}" height="{$largeSize.height}"/>
 {if !$content_only}
 <span class="span_link no-print">{l s='View larger'}</span>
 {/if}
 {/if}
 </span>
 {else}
 <span id="view_full_size">
 <img itemprop="image" src="{$img_prod_dir}{$lang_iso}-default-large_default.jpg" id="bigpic" alt="" title="{$product->name|escape:'html':'UTF-8'}" width="{$largeSize.width}" height="{$largeSize.height}"/>
 {if !$content_only}
 <span class="span_link">
 {l s='View larger'}
 </span>
 {/if}
 </span>
 {/if}

Et pour les miniatures…

<ul id="thumbs_list_frame">
 {if isset($images)}
 {foreach from=$images item=image name=thumbnails}
 {assign var=imageIds value="`$product->id`-`$image.id_image`"}
 {if !empty($image.legend)}
 {assign var=imageTitle value=$image.legend|escape:'html':'UTF-8'}
 {else}
 {assign var=imageTitle value=$product->name|escape:'html':'UTF-8'}
 {/if}
 <li id="thumbnail_{$image.id_image}"{if $smarty.foreach.thumbnails.last} class="last"{/if}>
 <a{if $jqZoomEnabled & $have_image & !$content_only} href="javascript:void(0);" rel="{literal}{{/literal}gallery: 'gal1', smallimage: '{$link->getImageLink($product->link_rewrite, $imageIds, 'large_default', $image.legend)|escape:'html':'UTF-8'}',largeimage: '{$link->getImageLink($product->link_rewrite, $imageIds, 'thickbox_default', $image.legend)|escape:'html':'UTF-8'}'{literal}}{/literal}"{else} href="{$link->getImageLink($product->link_rewrite, $imageIds, 'thickbox_default', $image.legend)|escape:'html':'UTF-8'}" data-fancybox-group="other-views" class="fancybox{if $image.id_image == $cover.id_image} shown{/if}"{/if} title="{$imageTitle}">
 <img class="img-responsive" id="thumb_{$image.id_image}" src="{$link->getImageLink($product->link_rewrite, $imageIds, 'cart_default', $image.legend)|escape:'html':'UTF-8'}" alt="{$imageTitle}" title="{$imageTitle}" height="{$cartSize.height}" width="{$cartSize.width}" itemprop="image" />
 </a>
 </li>
 {/foreach}
 {/if}
 </ul>

C’est terminé, vos photos produits ont chacune un nom unique et sont appelés par cette url unique ce qui permet aux robots d’avoir des images à positionner sur plusieurs mots ou expressions clés potentiellement. Pour info, le tutotiel est réalisé sous PrestaShop 1.6.0.9.

Un grand merci à PrestaRocket pour son aide précieuse sur ce développement PrestaShop

A vous de jouer !

Tags: