PS : Mise en forme des prix sur Prestashop

Ce tuto concerne Prestashop 1.6, mais je pense qu’il pourrait être mis en place sur les autres versions
à condition de savoir ce que l’on fait.

Justement de quoi s’agit il ?

Je vous propose de voir comment mettre en forme vos prix sur un site Prestashop et pouvoir faire ressortir les unités, les dizaines et la devise de façon différente, ce qui donnera pour sur un cachet unique à votre thème.

Dans l’état actuel le mieux que vous puissiez faire c’est :

<span class="price">19,90 €</span>

Une fois que vous aurez mis en place mes modifications, vous pourrez obtenir ceci :

<span class="price">
	<span>19</span>
    <span>, 90</span>
    <span> €</span>
</span>

Ainsi grâce à un peut de mise en forme vous pourrez modifier la font-size des décimales ou faire un retour à la ligne de la devise.
Prix-mis-en-forme

Commençons avec un peu de php

Il va falloir faire une sur couche (override) de la class Tools.

  1. Créez le fichier : racine de votre site /override/classes/Tools.php
  2. le fichier devra contenir le code suivant :
class Tools extends ToolsCore 
{
	public static function displayPrice($price, $currency = NULL, $no_utf8 = false, Context $context = NULL){
		if(context::getContext()->controller->controller_type == 'admin')
			return parent::displayPrice($price, $currency, $no_utf8, $context);
		
		if ($currency === NULL)
		$currency = Currency::getCurrent();
		if (is_int($currency))
			$currency = Currency::getCurrencyInstance((int)($currency));
		$c_char = (is_array($currency) ? $currency['sign'] : $currency->sign);
		$c_format = (is_array($currency) ? $currency['format'] : $currency->format);
		$c_decimals = (is_array($currency) ? (int)($currency['decimals']) : (int)($currency->decimals)) * _PS_PRICE_DISPLAY_PRECISION_;
		$c_blank = (is_array($currency) ? $currency['blank'] : $currency->blank);
		$blank = ($c_blank ? ' ' : '');
		$ret = 0;
		if (($isNegative = ($price < 0)))
			$price *= -1;
		$price = self::ps_round($price, $c_decimals);
		switch ($c_format){
			/* X 0,000.00 */
			case 1:
				$ret = $c_char.$blank.number_format($price, $c_decimals, '.', ',');
				break;
			/* 0000,00 X*/
			case 2:
				$price = explode(",", strval(number_format($price, $c_decimals, ',', '')));
				$ret  = '<span>'.(isset($price[0])?$price[0]:0).'</span>';
				$ret .= '<span>,'.(isset($price[1])?$price[1]:'00').'</span>';
				$ret .= '<span>'.$c_char.'</span>';
				break;
				/* X 0.000,00 */
				case 3:
				$ret = $c_char.$blank.number_format($price, $c_decimals, ',', '.');
				break;
			/* 0,000.00 X */
			case 4:
				$ret = number_format($price, $c_decimals, '.', ',').$blank.$c_char;
				break;
		}
		if ($isNegative)
			$ret = '-'.$ret;
		if ($no_utf8)
			return str_replace('€', chr(128), $ret);
		return $ret;
	}	
}

Voila une sur couche de la classe Tools.
Maintenant lorsque vous appeler la fonction smarty {displayPrice price=19.90} vous obtenez bien :

<span class="price">
	<span>19</span>
    <span>, 90</span>
    <span> €</span>
</span>

Un peu de javascript …

Maintenant que vous avez une jolie mise en forme de vos prix, ça serait bien qu’ils ne sautent pas lorsque le javascript s’en mêle, par exemple lorsque vous changez une déclinaison d’un produit, ça interfère aussi sur le prix.
Nous allons donc aussi sur coucher le javascript.

Dans votre thème prestashop vous allez trouver js/global.js
Ca peut être un bon endroit pour placer la fonction qui suit :

function formatCurrency(price, currencyFormat, currencySign, currencyBlank)
{
	var blank = '';
	price = parseFloat(price.toFixed(6));
	price = ps_round(price, priceDisplayPrecision);
	if (currencyBlank > 0)
		blank = ' ';
	if (currencyFormat == 1)
		return currencySign + blank + formatNumber(price, priceDisplayPrecision, ',', '.');
	if (currencyFormat == 2) {
		var price = formatNumber(price, priceDisplayPrecision, ' ', ',').split(',');
		var output  = '<span>'+(price[0] ? price[0] : 0)+'</span>';
			output += '<span>,'+(price[1] ? price[1] : '00')+'</span>';
		return output + '<span>'+currencySign+'</span>';
	}
	if (currencyFormat == 3)
		return (currencySign + blank + formatNumber(price, priceDisplayPrecision, '.', ','));
	if (currencyFormat == 4)
		return (formatNumber(price, priceDisplayPrecision, ',', '.') + blank + currencySign);
	if (currencyFormat == 5)
		return (currencySign + blank + formatNumber(price, priceDisplayPrecision, '\'', '.'));
	return price;
}

Puis dans votre thème, vous allez devoir modifier le fichier js/product.js et js/modules/blockcart/ajax-cart.js
La fonction formatCurrency est nativement insérée dans le Dom via la fonction text() qui ne tient pas compte des éléments html, il va donc falloir la remplacer par la fonction html().
Par exemple sur le fichier natif à la ligne 297 il y a l’instruction suivante :

$('#our_price_display').text(formatCurrency(parseFloat($('#our_price_display').attr('content')), currencyFormat, currencySign, currencyBlank));

Qu’il faut donc remplacer par l’instruction :

$('#our_price_display').html(formatCurrency(parseFloat($('#our_price_display').attr('content')), currencyFormat, currencySign, currencyBlank));

Vous allez devoir apporter cette modification plusieurs fois dans le fichier.
Je ne peux pas vous proposer une version de ce fichier car en fonction de votre thème et de la version de Prestashop il a de grandes chances pour qu’il soit différent de celui que je proposerais.
Pour ma part dans ce cas, je fais une recherche sur « formatCurrency » et pour chaque occurence, je remplace le text(… par html(…

En fin une touche de css

Voila on se penche un peut sur le css et le tour est joué
Vous pouvez voir les sujets suivants pour vous faciliter la vie en css :