Jump to content
Magalie Z

Appeler une valeur dans une zone texte CMS

Recommended Posts

Bonjour à tous,

J'ai besoin d'un petit coup de pouce pour un code trop compliqué pour mes connaissances :) 

Je travaille sur Prestashop 1.7.4.4. 

Je souhaite appeler le prix d'une fiche produit sur une page CMS de mon site de manière à ce que quand je change le prix sur ma fiche produit, il change également sur ma page CMS. 

Produit : http://myhande.cluster024.hosting.ovh.net/index.php?id_product=53&id_product_attribute=0&rewrite=iphone-7-argent-32-go&controller=product&id_lang=1 
Page CMS : http://myhande.cluster024.hosting.ovh.net/index.php?id_cms=15&controller=cms&id_lang=1

Est-ce possible à réaliser? 

Merci d'avance,

Magalie

Share this post


Link to post
Share on other sites

Bonjour,

Quote

Je souhaite appeler le prix d'une fiche produit sur une page CMS de mon site de manière à ce que quand je change le prix sur ma fiche produit, il change également sur ma page CMS. 

Si sur une même page CMS le but est afficher le prix de plusieurs produits (par exemple une liste), et que le contenu texte de la page CMS est édité via le back-office>Design>PageCMS, une solution possible :

- Récupérez depuis le controller CMS (...>controllers>CMSController.php) -qui gère les pages CMS- l'objet $allProducts retourné par une fonction (getProducts) de la Class Product

Exemple :
 

$productObj = new Product();

$allProducts = $productObj -> getProducts($id_lang, 0, 0, 'id_product', 'DESC' );

Puis vous l'assignez à Smarty.

Exemple :

$this->context->smarty->assign($allProducts);
$this->setTemplate('cms/category');

Ensuite dans le template vous allez devoir utiliser cet objet.

Lorsque vous utilisez l'éditeur back-office>Design>PageCMS, vous devez étendre votre bloc texte avec l'outil <> code source en haut à gauche.

Puis insérer identifiant dans la balise du prix, identifiant comportant l'ID du produit que vous visez.

Exemple :

<span id="cmsproductprice_id_18" class="cmsproductprice"></span>

Dans le fichier du template (exemple themes>classic>templates>cms>page.tpl) vous envoyez maintenant  à l'environnement JS l'object $allProducts que vous avez crée et assigné précédemment.

Enfin au page load (exemple dans le themes>classic>assets>js>custom.js) vous utilisez l'objet JS en ciblant les éléments du DOM (boucle sur la class .cmsproductprice de l'exemple) pour affecter (jquery .text) à chaque ligne de produit la valeur du prix ceci en récupérant l'ID contenu dans l'identifiant de la balise HTML qui sera la clef de l'objet JS).

Ainsi chaque produit écrit dans la page CMS affichera en front-office son prix actuel.

Il y a peut-être une solution plus rapide et plus performante. Il faut tester et comparer.

Share this post


Link to post
Share on other sites

Bonjour,

Tout d'abord merci pour votre réponse.

Alors c'est exactement ce que je souhaite faire, par contre je suis débutante donc c'est un peu compliqué pour moi.. 

2 hours ago, YopixelAE said:

- Récupérez depuis le controller CMS (...>controllers>CMSController.php) -qui gère les pages CMS- l'objet $allProducts retourné par une fonction (getProducts) de la Class Product

Exemple :
 


$productObj = new Product();

$allProducts = $productObj -> getProducts($id_lang, 0, 0, 'id_product', 'DESC' );

Puis vous l'assignez à Smarty.

Exemple :

$this->context->smarty->assign($allProducts);
$this->setTemplate('cms/category');

C'est cette partie qui me pose problème. Je suis devant mon fichier CMSController.php, par contre je n'ai aucun objet $allProducts. Est-ce à moi de l'ajouter? Si oui, peu importe l'endroit dans la feuille? 

Je vous ai joint mon fichier php. 

Merci beaucoup pour votre aide en tout cas.

Magalie

CmsController.php

Share this post


Link to post
Share on other sites
Quote

C'est cette partie qui me pose problème. Je suis devant mon fichier CMSController.php, par contre je n'ai aucun objet $allProducts. Est-ce à moi de l'ajouter? Si oui, peu importe l'endroit dans la feuille? 

Oui vous devez l'ajouter. Ou mieux, créer un override pour faciliter la maintenance et les mises à jour.

En édition directe, ligne 116 de votre fichier CMSController.php, remplacez :

$this->setTemplate(
                'cms/page',
                array('entity' => 'cms', 'id' => $this->cms->id)
            );

Par :

$productObj = new Product();
			$id_lang = $this->context->language->id;
			$allProducts = $productObj -> getProducts($id_lang, 0, 0, 'id_product', 'DESC' );
			foreach ($allProducts as $key => $val) {
				$id_product = $val['id_product'];
				$price = Product::getPriceStatic($id_product, true, null, 6);
				$allProducts[$key]['priceToDisplay'] = $price;
			}
            $this->context->smarty->assign(array(
                'cms' => $cmsVar,
				'allProducts' => $allProducts
            ));

            if ($this->cms->indexation == 0) {
                $this->context->smarty->assign('nobots', true);
            }
			
            $this->setTemplate(
                'cms/page',
                array('entity' => 'cms', 'id' => $this->cms->id)
            );

Ensuite dans votre fichier de template ...>templates>cms>page.tpl remplacez :

{block name='page_content_container'}

Par :

{block name='page_content_container'}
  <script type="text/javascript">
	var allProducts = {$allProducts|json_encode nofilter};
</script>

Vous disposez alors de l'objet JS de tous les produits avec leurs infos.

1) Utilisez cet objet dans votre fichier custom.js et 2) remplissez votre page CMS.

- Édition du themes>classic>assets>js>custom.js :

/*
 * Custom code goes here.
 * A template should always ship with an empty custom.js
 */
$(document).ready(function() {
	insertProductPrice();
});

function insertProductPrice() {
	// Loop Page
	$('.cmsproductprice').each(function() {
		// Retrieve idProduct from DOM element
		var el = $(this);
		var idProductInDOM = parseInt(el.attr('id').replace('cmsproductprice_id_', ''), 10);
		// Loop JS Object
		var lim = allProducts.length;
		for (var i = 0; i < lim; i++) {
			var item = allProducts[i];
			var id_product = parseInt(item['id_product'], 10);
			if (id_product !== idProductInDOM) {
				continue;
			}
			else {
				var price = item['priceToDisplay'];
				// Insert price in DOM element
				el.text(price);
			}
		}
	});
}

- Puis édition de la page CMS via l'éditeur du back-office :

<p>PRIX : <span id="cmsproductprice_id_1" class="cmsproductprice"></span></p>

Vos prix produits s'affichent désormais dans les lignes dédiées de votre page CMS remplie depuis le back-office.

CmsController.php

custom.js

Edited by YopixelAE (see edit history)
  • Thanks 1

Share this post


Link to post
Share on other sites

Alors j'ai suivi vos conseils de A à Z, par contre chez moi ça plante.. 

Lorsque je fais le changement sur le CMSController.php je n'arrive plus du tout à afficher de page CMS sur mon site. 

Share this post


Link to post
Share on other sites

Bonjour, postez votre CMSController.php modifié posant problème, pour trouver la cause.

Activez le mode Debug lorsque vous êtes confronté à une page blanche.

Share this post


Link to post
Share on other sites

C'est fait

La première erreur que j'obtiens c'est 
Parse error: syntax error, unexpected '}' in /home/myhande/www/controllers/front/CmsController.php on line 124

Et en enlevant le } j'ai celle-ci
Parse error: syntax error, unexpected 'elseif' (T_ELSEIF) in /home/myhande/www/controllers/front/CmsController.php on line 125

CmsController.php

Share this post


Link to post
Share on other sites

Fichier corrigé en pièce-jointe (vous devriez utiliser un override plutôt que de modifier un fichier natif. Ce sera plus facile à maintenir lors des upgrades).

Concernant les erreurs, vous avez supprimé une condition (if ($this->cms->indexation ...) lors de votre copié-collé.

 

Edited by YopixelAE (see edit history)

Share this post


Link to post
Share on other sites

Bonjour, 

Merci pour le fichier. Je viens de le mettre à jour, j'ai également rajouté la ligne dans le fichier page.tpl, j'ai modifié le code source sur ma page CMS pour appeler le prix d'un produit.. rien ne se passe : 

http://myhande.cluster024.hosting.ovh.net/index.php?id_cms=15&amp;controller=cms&amp;id_lang=1 

Dans la case "128 Go", je souhaite faire apparaître le prix de mon produit http://myhande.cluster024.hosting.ovh.net/index.php?id_product=54&amp;id_product_attribute=0&amp;rewrite=iphone-7-argent-128-go&amp;controller=product&amp;id_lang=1 

J'ai donc rajouté cette ligne <span id="cmsproductprice_id_54"></span>

Mais rien d'écrit... 

Est-ce normal? 

Merci d'avance,

Joyeuses fêtes à vous. 

Share this post


Link to post
Share on other sites

Bonjour,

Quote

Merci pour le fichier. Je viens de le mettre à jour, j'ai également rajouté la ligne dans le fichier page.tpl, j'ai modifié le code source sur ma page CMS pour appeler le prix d'un produit.. rien ne se passe

Il vous reste à ajouter la dernière partie (voir mes posts précédents : utilisation de l'objet JS).

Share this post


Link to post
Share on other sites

@Magalie Z, je viens d'éditer et de compléter la marche à suivre (fichiers en pièce-jointe), quelques posts plus haut.

Share this post


Link to post
Share on other sites

Bonjour,

Désolé de vous relancer.. est-ce que la modification fonctionne pour vous?

 

Share this post


Link to post
Share on other sites

Bonjour,

Oui bien sûr que ça fonctionne pour moi, autrement je ne posterai pas de solution.

Vous n'utilisez pas le bon fichier CMSController.php. Voir pièce-jointe quelques posts plus haut (post de la procédure détaillée).

 

Share this post


Link to post
Share on other sites

Merci beaucoup YopixelAE pour cette solution au top, tout fonctionne 👍

J'ai une dernière petite question, pensez-vous que je puisse mettre en place la même boucle mais pour récupérer la date de disponibilité du produit cette fois-ci? 

J'ai suivi exactement votre modèle, sauf que j'ai remplacé la valeur "Price" par "AvailableDate". Pas de bug sur le site, mais la requête m'affiche "false"... 

Pourriez-vous m'expliquer à quoi correspond le 6 ici (ligne 115 du controller) $price = Product::getPriceStatic($id_product, true, null, 6)

Merci d'avance

Edited by Magalie Z (see edit history)

Share this post


Link to post
Share on other sites
Quote

J'ai une dernière petite question, pensez-vous que je puisse mettre en place la même boucle mais pour récupérer la date de disponibilité du produit cette fois-ci? 

Oui vous pouvez. L'info est disponible dans l'objet JS.

Quote

Pourriez-vous m'expliquer à quoi correspond le 6 ici (ligne 115 du controller) $price = Product::getPriceStatic($id_product, true, null, 6)

C'est le nombre de décimales.

Share this post


Link to post
Share on other sites

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...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More