La problématique n’est pas nouvelle sur Prestashop, et c’est un point qui me frustre assez souvent et pour lequel j’avais déjà fait un module en 2014 ( cf. https://www.h-hennes.fr/blog/2014/01/18/prestashop-liens-dynamiques-vers-les-pages-cms-dans-lediteur-tinymce/ )
Ce module n’est malheureusement plus fonctionnel sur Prestashop 1.7.

Dans les éditeurs de contenus, il n’est pas possible  des mettre des liens ou des contenus dynamiques.
La bonne nouvelle cependant c’est que la version 1.7 de Prestashop apporte de nouveaux hooks qui vont permettre de modifier ces contenus avant l’affichage des éléments, et donc sans surcharge  🙂

Les éléments dont les contenus sont modifiables sont les suivants :

  • Pages cms
  • Catégories cms
  • Contenu produit
  • Contenu catégorie
  • Contenu Fabriquants
  • Contenu fournisseurs

Pour l’exemple on va partir sur le besoin suivant :

Je souhaite afficher un élément de configuration  dans l’ensemble des contenus noté ci-dessous.
Ce sera la configuration PS_SHOP_EMAIL , qui correspond à l’émail par défaut de la boutique.

Pour afficher cette variable il faudra intégrer dans les zones de contenus le code suivant :

{{configuration name=PS_SHOP_EMAIL}}

Le but du module sera donc de remplacer cet élément par sa valeur de configuration.

Voici le contenu qui sera saisi dans l’admin :

Cms placeholder

Et le résultat :

Cms placeholder result

Vous trouverez ci-dessous le code complet du module qui permets de gérer cela

<?php
class HhContentVars extends Module {
 
    public function __construct() {
        $this->name = 'hhcontentvars';
        $this->tab = 'others';
        $this->author = 'hhennes';
        $this->version = '1.0.0';
        $this->need_instance = 0;
        $this->bootstrap = true;
 
        parent::__construct();
 
        $this->displayName = $this->l('Hh content var');
        $this->description = $this->l('Add content var in wysiwyg editors');
    }
 
    public function install() {
        if (!parent::install() 
                //Hooks Fronts d'affichage
                || !$this->registerHook('filterCmsContent') 
                || !$this->registerHook('filterCmsCategoryContent') 
                || !$this->registerHook('filterProductContent') 
                || !$this->registerHook('filterCategoryContent') 
                || !$this->registerHook('filterManufacturerContent') 
                || !$this->registerHook('filterSupplierContent')
        )
            return false;
 
        return true;
    }
 
 
    /**
     * Filtre des contenus Cms
     * @param $params
     * @return array
     */
    public function hookFilterCmsContent($params) {
 
        $params['object']['content'] = $this->_updateContentVars($params['object']['content']);
 
        return [
            'object' => $params['object']
        ];
    }
 
    /**
     * Filtre des contenus des catégories cms
     * @param $params
     * @return array
     */
    public function hookFilterCmsCategoryContent($params) {
 
        $params['object']['description'] = $this->_updateContentVars($params['object']['description']);
 
        return [
            'object' => $params['object']
        ];
    }
 
    /**
     * Filtre des contenu des produits
     * @param $params
     */
    public function hookFilterProductContent($params) {
        $params['object']['description'] = $this->_updateContentVars($params['object']['description']);
        return [
            'object' => $params['object']
        ];
    }
 
    /**
     * Filtre des contenus des catégories produits
     * @param $params
     * @return array
     */
    public function hookFilterCategoryContent($params) {
 
        $params['object']['description'] = $this->_updateContentVars($params['object']['description']);
 
        return [
            'object' => $params['object']
        ];
    }
 
    /**
     * Filtre des contenus des Marques
     * @param $params
     * @return mixed
     */
    public function hookFilterManufacturerContent($params) {
 
        return $this->_updateContentVars($params['filtered_content']);
    }
 
    /**
     * Filtre des contenus des fournisseurs
     * @param $params
     * @return array
     */
    public function hookFilterSupplierContent($params) {
        $params['object']['description'] = $this->_updateContentVars($params['object']['description']);
 
        return [
            'object' => $params['object']
        ];
    }
 
    /**
     * Mise à jour du contenu
     * @param string : contenu ou il faut remplacer les variables
     * @return string : contenu avec les variables remplacées
     */
    protected function _updateContentVars($content) {
 
        $content = urldecode($content);
 
        //Récupération des éléments de configuration
        preg_match_all('#{{configuration name=(.*)}}#i', $content, $configurations);
        if (isset($configurations[1]) && sizeof($configurations[1])) {
            foreach ($configurations[1] as $conf) {
                if ( $value = Configuration::get($conf) ) {
                    $content = preg_replace('#{{configuration name=' . $conf . '}}#',$value, $content);
                }
            }
        }
 
        return $content;
    }
}

Ceci n’est qu’un exemple, il donc possible de mettre en place autant de tags que souhaités.
Si j’ai le temps durant les prochaines semaines je verrais peu être pour mettre à jour mon module précédent uniquement PS 1.7