Boucle personnalisée

Salut à vous

quelqu'un sait-il comment utiliser la boucle mais sur un tableau de résultats personnalisés ..?

Je souhaite afficher une liste d'articles en utilisant un template déjà présent et je trouve dommage de recopier/modifier chacune des méthodes d'affichage des tags/catégories/etc

Merci à vous

Réponses

  • Avec un peu plus de précision, je pourrai possiblement t'aider. J'utilise toujours des gabarits qui existent déjà et j'y insère les fonctions standards de PluXml. Tu nous donnes un peu de détails sur ce qui doit être fait et on trouvera bien quelque chose.

    Si le gabarit démo a des listes "bidon" qui sont des UL avec une suite de LI, c'est très simple, même chose avec des DIV qui se succèdent. les fonctions de liste d'articles, de catégories et de tags fonctionnent sensiblement sur le même principe.
  • si je me souviens bien, je souhaites afficher des articles correspondant à une ou X catégories ET possédant au moins un ou X tags ...
  • OK, la description d'origine du problème semblait parler de personnalisation du gabarit, pas de la liste elle-même.

    À ce moment il faut utiliser une boucle WHILE, tirer la totalité des articles et tester chacun d'eux avant de l'afficher s'il respecte les critères désirés. Tu pourras donner un extrait de ton code et ça deviendra plus clair.
  • pour comprendre le pourquoi de la chose, j'ai une liste de pizza ( :P )
    j'ai mis en ligne une version en développement : daniel-rolland.com/pluxml/pizza_ce_soir/

    comme tags j'ai les ingrédients (ça permet de faire une recherche par ingrédient ;) )
    comme catégorie j'ai du style "fromagères" (4 fromages, savoyardes, etc) ; "sucrée/salée", "avec viande", "végétariennes" etc

    je souhaite afficher les pizzas "végétariennes" avec "fromage de chèvre" (je filtre donc sur la catégorie "végétariennes" + tags "fromage de chèvre")

    dans mes recherches de développement,
    je bouclais sur tous les articles selon 1 critère : la catégorie OU le mot-clefs (via le template, normal)
    puis je trie en fonction d'un 2ème critère : un autre ou plusieurs tags.
    Ce 2ème paramètre passe en GET via les liens généré dans la sidebar

    (note : j'ai enlevé cette fonction dans le site en ligne)

    Mon code du template catégorie
    [== PHP ==]
    <?php include(dirname(__FILE__).'/header.php'); ?>
    
    <?php
    if(isset($_GET['tags']) AND $_GET['tags']!=""){						// si la variable "tags" est présente dans l'URL
    	$filtre_tag = htmlspecialchars($_GET["tags"]);					// récupèration et nettoyage la liste des tags de l'URL
    	$filtre_tag_array = explode(",",$filtre_tag);					// transformation de la liste en tableau
    	$url_active = 'index.php?'.plxUtils::getGets().',';				// création de l'url des liens pour les filtres si déjà présent
    	$url_active = $plxShow->plxMotor->urlRewrite($url_active);		// formatage des liens
    }else{
    	$url_active = 'index.php?'.plxUtils::getGets().'&tags=';		// création de l'URL si pas de variable "tags" dans l'URL
    	$url_active = $plxShow->plxMotor->urlRewrite($url_active);		// formatage de l'URL
    }
    
    ob_start();															// initialisation du tampon
    $plxShow->tagList('#tag_name,', 99, 'alpha');						// "affichage" de la liste des tags
    $contents = substr(ob_get_contents(),0,-1);							// récupération de l'affichage
    ob_end_clean();														// Déstruction des données du tampon de sortie et éteint la temporisation de sortie
    $tagList = explode(",", $contents);									// transformation de la liste en tableau														// variable pour tester l'existence d'article filtré
    $result=0;
    ?>
    
    	<main class="main grid" role="main">
    
    		<section class="col sml-12 med-8">
    
    			<ul class="repertory menu breadcrumb">
    				<li><a href="<?php $plxShow->racine() ?>"><?php $plxShow->lang('HOME'); ?></a></li>
    				<li><?php $plxShow->catName(); ?>
    				<?php $plxShow->catDescription(' : #cat_description'); ?></li>	
    			</ul>
    
    <?php while($plxShow->plxMotor->plxRecord_arts->loop()): ?>
    <?php
    		$taglist = $plxShow->plxMotor->plxRecord_arts->f('tags');	// récupération de la liste de tous les tags de l'article
    		if(!empty($taglist) AND  is_array($filtre_tag_array)) :		// test si le tableau des tags existe et si celui de l'URL existe
    			$tags = array_map('trim', explode(',', $taglist));		// nettoyage et formatage de la liste des tags
    			foreach($tags as $k=>$v){
    				$tags[$k] = plxUtils::title2url($v);				// formatage des tags
    			}
    			if(count(array_intersect($tags, $filtre_tag_array))>0	// test s'il existe des tags de l'URL dans celle de tous les tags
    			AND count(array_intersect($tags, $filtre_tag_array))==count($filtre_tag_array)): // test si la comparaison a la même taille que le tableau de l'URL (pour formater les liens de filtres)
    
    			?>
    
    			<article class="article" role="article" id="post-<?php echo $plxShow->artId(); ?>">
    
    				<header>
    					<h1>
    						<?php $plxShow->artTitle('link'); ?>
    					</h1>
    					<small>
    						<?php $plxShow->lang('WRITTEN_BY'); ?> <?php $plxShow->artAuthor() ?> -
    						<time datetime="<?php $plxShow->artDate('#num_year(4)-#num_month-#num_day'); ?>"><?php $plxShow->artDate('#num_day #month #num_year(4)'); ?></time> -
    						<?php $plxShow->artNbCom(); ?>
    					</small>
    				</header>
    
    				<section>
    					<?php $plxShow->artChapo(); ?>
    				</section>
    
    				<footer>
    					<small>
    						<?php $plxShow->lang('CLASSIFIED_IN') ?> : <?php $plxShow->artCat() ?> - 
    						<?php $plxShow->lang('TAGS') ?> : <?php $plxShow->artTags() ?>
    					</small>
    				</footer>
    
    			</article>
    <?php $result++; else: ?>
    <?php endif; ?>
    
    <?php else:  $result++; // il n'y a pas de variable TAG dans l'URL ?>
    		
    			<article class="article" role="article" id="post-<?php echo $plxShow->artId(); ?>">
    
    				<header>
    					<h1>
    						<?php $plxShow->artTitle('link'); ?>
    					</h1>
    					<small>
    						<?php $plxShow->lang('WRITTEN_BY'); ?> <?php $plxShow->artAuthor() ?> -
    						<time datetime="<?php $plxShow->artDate('#num_year(4)-#num_month-#num_day'); ?>"><?php $plxShow->artDate('#num_day #month #num_year(4)'); ?></time> -
    						<?php $plxShow->artNbCom(); ?>
    					</small>
    				</header>
    
    				<section>
    					<?php $plxShow->artChapo(); ?>
    				</section>
    
    				<footer>
    					<small>
    						<?php $plxShow->lang('CLASSIFIED_IN') ?> : <?php $plxShow->artCat() ?> - 
    						<?php $plxShow->lang('TAGS') ?> : <?php $plxShow->artTags() ?>
    					</small>
    				</footer>
    
    			</article>
    		<?php endif; ?>
    <?php endwhile; ?>
    <?php if($result==0): ?>
    <p>Il n'y a pas d'article correspondant à votre recherche.</p>
    <?php endif; ?>
    
    			<nav class="pagination text-center">
    				<?php $plxShow->pagination(); ?>
    			</nav>
    
    			<span>
    				<?php $plxShow->artFeed('rss',$plxShow->catId()); ?>
    			</span>
    
    		</section>
    
    		<?php // include(dirname(__FILE__).'/sidebar.php'); ?>
    		<?php include(dirname(__FILE__).'/tagFiltre.php'); ?>
    
    	</main>
    
    <?php include(dirname(__FILE__).'/footer.php'); ?>
    

    et la sidebar personnalisée (je n'ai fait le test que sur les tags) :
    [== PHP ==]
    <?php if(!defined('PLX_ROOT')) exit; ?>
    
    	<aside class="aside col sml-12 med-4" role="complementary">
    
    			<h3>Filtrer par <?php $plxShow->lang('TAGS'); ?></h3>
    	
    			<ul class="unstyled-list">
    <?php foreach($tagList as $k=>$v): ?>
    				<li>
    <?php if(in_array(plxUtils::title2url($v),$filtre_tag_array)): ?>
    <?php
    				$key = array_search(plxUtils::title2url($v), $filtre_tag_array);
    				$urlString = $filtre_tag_array;
    				unset($urlString[$key]);
    				$filtre_tag = implode(",",$urlString);
    				$urlGet = explode("&",plxUtils::getGets());
    				$urlSansGet = $urlGet[0];
    				if(count($filtre_tag_array)>1){
    					$url_active_clear = 'index.php?'.$urlSansGet."&tags=";
    				}else{
    					$url_active_clear = 'index.php?'.$urlSansGet;
    				}
    				$url_active_clear = $plxShow->plxMotor->urlRewrite($url_active_clear.$filtre_tag);
    				?>
    					<a class="active" href="<?php echo $url_active_clear; ?>" title="Retirer le filtre <?php echo $v;?>">
    <?php else: ?>
    					<a class="noactive" href="<?php echo $url_active.plxUtils::title2url($v); ?>" title="Ajouter le filtre <?php echo $v;?>">
    <?php endif; ?>
    <?php echo $v; ?>
    					</a>
    				</li>
    <?php endforeach; ?>
    			</ul>
    
    		
    		<h3>Filtrer par
    			<?php $plxShow->lang('CATEGORIES'); ?>
    		</h3>
    
    		<ul class="cat-list unstyled-list">
    			<?php $plxShow->catList('','<li id="#cat_id"><a class="#cat_status" href="#cat_url" title="#cat_name">#cat_name</a> (#art_nb)</li>'); ?>
    		</ul>
    	</aside>
    

    voilou ;D
  • j'ai tellement faim...
  • PierrePierre Member
    janvier 2016 modifié
    Moi j'aurais utilisé à nouveau des catégories pour les ingrédients mais bon, ça multiplie les tests mais ça peut finir par fonctionner.

    Est-ce que le souhait est de permettre au visiteur de faire un choix multiple et de lancer la recherche ensuite? Ça serait plus efficace et rapide. Pour ce faire, ma première idée serait d'utiliser une matrice (array) de ces ingrédients souhaités dans l'adresse url et de bâtir la requête en rejetant tout ce qui ne fait pas partie de la liste. Parce que les catégories sont à part, la recherche ne se fait que sur la catégorie en question. Si tout était une catégorie (croûtes et ingrédients), tout sortirait sur une page statique unique.

    Avec cette méthode, tu pourrais même faire une page de "cases à cocher" et ne lancer la recherche qu'une seule fois.

    Je me demandais aussi pourquoi impliquer la sidebar dans le processus de recherche. Si tout se fait dans le body, la sidebar reste indépendante avec son contenu bien à elle.
  • utiliser les tags pour les ingrédients et les catégories pour les critères permet de séparer "physiquement" ces paramètres.
    De cette manière dans l'article je peux placer les critères d'un côté et les ingrédients de l'autre. C'est plus facile et propre.

    J'ai déjà un plugin qui crée des groupes de catégories, j'ai des meta-catégories "carte des pizzas", "carte des desserts", "boissons" etc ...
    mini_545600metaCat.png
    mini_254832metaCat2.png
    et dans ma sidebar, je n'ai plus qu'à appeler l'id de la meta-catégorie "pizza" pour que ça me retourne la liste des catégories associées, que j'injecte dans la méthode catList et un plugin qui affiche les tags après ce filtre ...
    Cela me crée aussi des pages statics qui affichent la liste des articles des catégories ciblées (d'ailleurs ça ne marche pas en ligne :/ )

    J'ai fait ça pour éviter d'avoir dans la sidebar de recherche de pizzas les catégories liées à la vie de la pizzeria, l'actu divers etc ...
    et de ne pas avoir à modifier les templates (tout doit se faire en admin).

    Et aussi pour la liste des allergies (il est maintenant obligatoire pour tout restaurateur d'informer pour chaque plat les allergies possibles).
    J'ai donc un autre plugin qui associe les allergies en fonction des ingrédients. Si un article (une pizza) possède certains tags (ingrédients), on affiche les allergies.
    En admin je liste tous les tags et je coche les allergies associées
    mini_156649allergies.png

    Pour faire la recherche, au lieu de passer par une page "recherche", de sélectionner des boîtes à cocher puis de lancer une recherche,
    je trouve plus conviviale de passer d'abord par la sidebar, de manière à utiliser d'abord les fonctions natives de PluXml (catégories/tags) et d'éventuellement rajouter un bandeau au dessus de la liste d'articles "ajouter d'autres critères de recherche" qui là utiliserai une fonction particulière.

    Si les paramètres sont passés en GET, suffit de générer des liens appropriés :
    Je suis sur la page du tag boeuf haché (index.php?tag/boeuf-hache),
    les liens pour rajouter les autres critères deviennent index.php?tag/boeuf-hache&tag_search=oignons-rouges pour les pizzas à base de boeuf haché ET oignons rouges
    ou index.php?tag/boeuf-hache&cat_search=pizzas-sucree-salee pour les pizzas à base de boeuf hâché ET pizza sucrée/salée

    si j'étais sur la catégorie "sucrée/salée" (index.php?categorie13/pizzas-sucree-salee)
    j'aurai index.php?categorie13/pizzas-sucree-salee&tag_search=oignons-rouges

    Je ne cherche pas le plus efficace et rapide pour PluXml mais le plus simple et convivial pour l'utilisateur :D

    pas facile tout ça ...
  • Tout notre travail est fait dans l'intérêt de l'utilisateur, la surmultiplication des tests et des boucles dans d'autres boucles n'aident personne et prennent peut-être une ou quelques secondes de plus. Toute amélioration de la simplicité et de la vitesse d'exécution aide tout le monde.

    Ne sachant toujours pas quel problème est à régler au juste, je ne lancerai pas dans la solution mais, pour l'instant, cette solution n'impliquerait probablement aucun tag et certainement pas de plugin.
  • d'une manière générale, JE DOIS différencier les ingrédients des critères.
    Que ça soit pour la recherche comme pour le balisage des données (j'utilise les microdata).

    Si je devais tout regrouper dans des catégories, un moment ou un autre il me faudra faire une condition :
    si cette catégorie est un critère // si cette catégorie est un ingrédient.
    Je ne peux faire un réglage en brut, dans le template pour paramétrer ces listes.
    Si demain j'ajoute un ingrédient (donc une catégorie), je devrais modifier obligatoirement le template, chose impensable.
    L'usage doit être aussi conviviale dans l'admin.

    Dans ce cas-là, comment tu verrais la chose sans plugin ..?

    Le problème est qu'en dehors de la boucle native de PluXml il n'est pas possible d'utiliser les méthodes de plxShow ( $plxShow->artTags, $plxShow->artCat etc ). L'est là le hic, faut tout réécrire, faire appel à plxMotor etc
  • Puisque tu contrôles la nomenclature de tous ces critères, c'est très simple de faire la séparation entre ce qui est un "type de croûte" et un ingrédient, même chose pour les allergies ou les produits autres que les pizzas.

    En imaginant que tous ces articles ont une ou plusieurs catégories qui leur sont associées, on part d'une boucle unique qui teste l'appartenance à telle ou telle catégorie puis qui passe ou non à un test subséquent selon la réponse. En faisant l'extraction totale en boucle, on peut mettre dans des matrices (array) séparées les "croûtes", ingrédients, restrictions alimentaires, etc. On teste alors avec la fonction "in_array" qu'on répète avec autant de critères que désiré.

    En effet, je suis d'accord, les fonctions classiques de PluXml sont trop restrictives pour permettre ce genre de tests. Je milite depuis un certain temps pour laisser l'option d'afficher ou pas le résultat d'une fonction. On verra dans le futur si la tendance fait des adeptes, le support est déjà évident des experts résidants.

    La boucle WHILE "qui n'affiche pas tout de suite" est donc de rigueur, toujours selon mon avis. Ma suggestion d'utiliser les variables d'url me semble encore la plus claire, encore place à débat. Des experts du forum auront peut-être une autre suggestion mais pour moi ça rend les choses bien plus simples à coder et surtout débugger.

    Le problème que je cherche dans l'histoire est un problème fonctionnel, une suite d'opérations par l'usager qui ne peut pas être menée à destination, désolé mais je n'en trouve toujours pas. Aucun développeur ne "doit" faire quoique ce soit avant d'avoir maîtrisé clairement le fonctionnel. Quand on commence la solution avant cette étape, on s'imagine des barrières.

    Je suis client affamé, aujourd'hui j'opte pour la croûte alsacienne, j'adore le saucisson sec et le fromage de chèvre, je suis allergique aux oeufs, balancez-moi la liste des choix qui vont me satisfaire sans mettre ma vie en danger. Dans un tel scénario, on écarte les desserts, on accepte ou refuse les pizzas une à une. À la fin de la liste, il ne reste que les "survivantes" aux multiples tests (effectués une fois chacun par cycle) et on procède à leur affichage.

    ...?produit=pizza&croute=alsacienne&ingredients=saucissonSec,chevre&restriction=oeufs

    J'appelle l'exclusion une "restriction" plutôt que le terme "allergie", ça laisse la l'option d'inclure un test super sympathique du genre "je déteste les artichauts même si ma vie n'est pas en danger"...
  • dans ton raisonnement, ce qui m'intrigue est à quel moment et par quel moyen, sans plugin et sans modification du template, j'indique que telle catégorie est un ingrédient, un critère, une allergie :cool:

    Sinon j'utilise la temporisation dans la boucle ... je trie ensuite ... et j'affiche en fin.

    M'enfin pour l'instant, avec 20 articles à trier, en choisissant par catégorie ou par mot-clef, on réduit le choix à pas beaucoup.
    Donc pour l'instant ce n'est pas urgent.

    Ceci-dit, dans tous les systèmes de blog, où il y a une quantité d'articles impressionnant, je trouve que trier en fonction de la catégorie ET les mots-clefs serait un plus ... mais je n'ai jamais vu cela. Faut soit se palucher les X pages à la recherche d'articles intéressants, soit passer par la recherche :(

    Note qui n'a rien à voir : tu peux choisir une végétarienne MAIS sans artichaut, que tu n'aimes pas ou que tu sois allergique ;)
    Nous avons l'obligation d'afficher les allergies ... alors soit !
  • PierrePierre Member
    juillet 2016 modifié
    Très bien, on y arrive.

    Les matrices qui forment les sous-groupes comme les croûtes, les ingrédients, les restrictions, etc seraient créées et maintenues à la main dans mon obsession pour la simplicité. Ce n'est pas idéal mais puisque ces listes ne sont pas trop dynamiques et certainement pas créées par les utilisateurs, je les imagine nécessitant très peu de maintenance. Dans mes utilisations de cette méthode, je les mettais tout en haut de la page statique, elles auraient l'air de:

    $produit = array("pizza", "dessert", "breuvage");
    $croute = array("mince","epaisse");
    $ingrédients = array("saucisse","tomates","fromageBleu", "fromageSuisse"...);
    $restrictions = array("porc","oeufs","gluten"...);

    Alors mon histoire de if(in_array($_GET('restriction'),$ingrédients)) prend tout son sens et permet de faire le tri en rejetant les non-conformes selon les critères choisis par le visiteur. Ces valeurs se retrouvent dans l'url et sont pêchées par le $_GET. Dans un élan de folie d'ergonomie, on peut même trouver la perle rare qui me gardera en vie, qui contient tout ce que j'aime mais qui contient malheureusement un ingrédient de trop que j'ai identifié comme "non-désiré". Ça me suggèrerait alors de prendre la végétarienne mais en spécifiant de ne pas mettre d'artichaut. Une seule page statique, une grosse boucle qui cycle la vingtaine de pizzas, quelques tests roulés sur chacune des répétitions, pas le moindre plugin.

    Parfaitement d'accord, cette méthode s'applique bien parce qu'on a une liste assez raisonnable d'articles et de catégories. On ne ferait pas ça avec un site de nouvelles qui recherche en plein texte tous les sujets d'intérêt des lecteurs et des milliers d'articles de 3 pages. L'invention des tags est venue d'un genre d'indexation pour s'en sortir vivant et voir notre page retournée avant la retraite.
  • j'entendais bien que ton approche "simplissime" obligeait un maintient du template :lol:
    Perso ça ne me gêne pas puisque je sais lire un code et mettre les mains dedans.
    Sauf que mon site peut-être réutilisé par un confrère qui le désire, et là, on oublie, il faut qu'il puisse gérer tout ça en admin.
    Création de catégories, regroupement de ces catégories, ajout d'ingrédients (tags), liaison avec les allergies.
    A savoir que je vais certainement mettre en cache le plus de résultat des routines des plugins.

    Voir mettre tout le site en cache, mais pour l'instant ce n'est pas possible, à mon niveau ]:D
  • Tout est possible quand on connaît la contrainte avant de coder.

    Les listes peuvent très bien venir d'une suite d'articles associés à quelques catégories qui les regroupent. Aucun tag, seulement des catégories. Mais, à mon avis, enseigner à quelqu'un comment ajouter un item dans une matrice est bien plus simple que de s'emmerder à allonger la liste de catégories qui sera déjà assez longue avec tout ce qui peut recouvrir une pizza. Le diabolique fichier de page statique est accessible par l'admin, les matrices sont au début de ladite page, c'est tout de même assez simple. Il faut pas tenter d'immuniser un administrateur de site contre la calamité d'avoir à lire des lignes de code qu'on a bien pensées et commentées pour guider un peu.
  • re :D

    voilou, j'ai tenté un truc, qui correspond à ce que j'imaginais : un système de recherche par filtre, en tunnel :
    plus on ajoute des paramètres de filtre, plus le nombre de résultat diminue ainsi que le nombre de filtres complémentaires ...
    résultat en test ici

    on filtre en fonction des catégories (critère) ET des tags (ingrédient) ... et j'ai bien galéré avec ce "développement sauvage" ]:D
Connectez-vous ou Inscrivez-vous pour répondre.