We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 20488
    • 353 Posts
    Mise à jour le 30/10/06 : suppression d’un petit bug relatif à la déclaration du tableau $arrayAllChildren. Tous les paramètres sont conservés et l’utilisation du snippet n’est pas remise en cause. Vous devriez donc copier/coller le nouveau code source du snippet ci-après.


    Bonjour,

    voici une première petite contribution relative à une modification du snippet ListRelated, si cela peut servir.

    Pour info, ce snippet permet à l’origine d’afficher les documents en relation avec le document actif par l’intermédiaire de leurs mots clés respectifs.

    Au programme des modifications :

    - Classement effectué par le dénombrement de mots clés communs en premier lieu, puis par le critère de l’utilisateur :
    ainsi le lien relatif à une page moins récente, mais qui possède 3 mots clés identiques au document courant sera déclaré avant le lien relatif à une page plus récente possédant uniquement 2 mots clés identiques.
    - Possibilité d’éviter d’intégrer ou non l’ensemble des contenus non publiés, supprimés, non cachés, et/ou les documents de type "répertoire"
    - Possibilité de mentionner "manuellement" des id de fichiers qui ne doivent pas être intégrés.
    - Possibilté de redéfinir le contenu du lien généré (label+attribut title)
    - Possibilité de rajouter une description supplémentaire contenue dans une balise <p> à partir d’un attribut du document (pagetitle,longtitle...) et rajout d’une classe LR_description associée.
    - Et de nouvelles possibilité : http://modxcms.com/forums/index.php/topic,8217.msg58754.html#msg58754

    Un exemple d’appel :

    [!ListRelated?&LR_contentParagraph=`description` &LR_label=`pagetitle` &LR_titleAttribute=`longtitle` &LR_skipFolder=`1` &LR_skipUnpublished=`1` &LR_skipDeleted=`1` !]
    Ici, nous allons sélectionner uniquement des documents qui sont publiés et non supprimés et qui ne sont pas des répertoires.

    Les nouvelles variables utilisables :


    [tt]LR_skipPages [ string ]
    Description: Permet de supprimer certaines pages de la recherche.
    exemple : [[ListRelated? &LR_skipPages=’21,45,51’]]
    Valeur par défaut : ’’


    LR_skipDeleted [0 | 1]
    Description:Ne pas prendre en compte les pages supprimées
    Valeur par défaut : 0


    LR_skipUncacheable [0 | 1]
    Description: Ne pas prendre en compte les pages non mise en cache.
    Valeur par défaut : 0



    LR_skipUnsearchable [0 | 1]
    Description: Ne pas prendre en compte les pages non prises en compte pour la recherche.
    Valeur par défaut : 0

    LR_skipFolder [0 | 1]
    Description: Ne pas prendre en compte les documents de type répertoire


    LR_skipUnpublished [0 | 1]
    Description: Ne pas prendre en compte les pages non publiées.
    Valeur par défaut : 0


    LR_label [string]
    Contenu de la balise <a>, la valeur de cet attribut doit être un des champs de la table `prefixe`_site_content
    exemple : [[ListRelated? &LR_label=’description’]] donnera <a href="[~51~]" title="Un titre">Ma description du document 51</a>
    Valeur par défaut : ’page_title’


    LR_titleAttribute [string]
    Contenu de l’attribut "title" de la balise <a>, la valeur de cet attribut doit être un des champs de la table `prefixe`_site_content
    exemple : [[ListRelated? &LR_label=’description’]] donnera <a href="[~51~]" title="Ma description du document 51">Doc 51</a>
    Valeur par défaut : ’longtitle’


    LR_contentParagraph [ string ]
    Contenu de la balise <p></p> si renseigné
    Valeur par défaut : ’’
    La valeur de cet attribut doit être un des champs de la table `prefixe`_site_content
    e.g = [[ListRelated? &LR_contentOption=’description’]] donnera <a href="[~51~]" title="Un titre">Doc 51</a><p class="LR_description">Ma description du document 51</p>[/tt]


    Note, les anciens arguments sont toujours utilisables.

    Le code du snippet (si vous ne possédez pas ce snippet, créez un snippet nommé ListRelated) :

    <?php
    // --------------------
    // Snippet: ListRelated
    // --------------------
    // Version: 0.9.2 ModXfied by mr_go
    // Date: 2006.04.07
    // Originaly made by
    // [email protected]
    // Modxifed by [email protected]
    // Then by mr_go
    // added the option to set the in menu option
    // This snippet was designed to show a list of pages that are
    // related based on specified keywords, or those used in the
    // current page
    //
    
    
    // Configuration Settings
    
       // LR_keywords [ string ]
       // This is a comma separated list of keywords that can be set
       // from the snippet parameter ONLY. Ex:
       // [[ListRelated?LR_keywords=fun,functional,good stuff]]
       // If no snippet variable is set, related pages will be found
       // based on the host page's keywords.
    
       // $maxRelated [ int ]
       // The maximum number of related pages you want to have. Can also
       // be set/overridden as the snippet variable "LR_max" as in:
       // [[ListRelated?LR_max=5]]
       $maxRelated = 10;
    
       // $relatedListTitle [ string ]
       // Give your related list of links a title if you desire- otherwise
       // set as an empty string ''. Can also be declared in snippet call
       // with "LR_title" like:
       // [[ListRelated?LR_title=Other links you might like]]
       $relatedListTitle = 'Et aussi...';
    
       // $removeNewlines [ true | false ]
       // As always, with lists, it's best NOT to have new lines and whitespace
       // with IE. For debugging and reading source code, set to false, for live
       // implementation and styling, try setting to true.
       $removeNewlines = true;
       
       // $sortBy [ 'date' | 'pagetitle' ]
       // Field you would like to sort by. Options include:
       // date       dates will be sorted by pub_date if it exists, else createdon
       // pagetitle  page title
       // Can also be set in snippet call with $LR_sortBy (see example under $sortDir)
       $sortBy = 'date';
       
       // $sortDir [ 'ASC' | 'DESC' ]
       // Choose to sort in ascending (ASC) or descending (DESC) order. Can be set
       // in snippet call with $LR_sortDir:
       // [[ListRelated??LR_sortBy=date&LR_sortDir=DESC]]
       $sortDir = 'DESC';
    
       // $showhidemenu [ 0 | 1 ]
       // Must we hide the documents that are set to hide in menu
       // when set to 0 it wil NOT show the documents that are marked as hide in menu
       $showhidemenu = 0;
       
       // LR_skipPages [ string ]
       // Must we skip some pages (given by page#1,page#2,page#3..) e.g: [[ListRelated? &LR_skipPages='21,45,51']]
       // Default value : ''
       // $skipPages = "";
       
       // LR_skipDeleted [0 | 1]
       // Default value : 0
       // Must we skip deleted pages
       
       // LR_skipUncacheable [0 | 1]
       // Default value : 0
       // Must we skip pages that are not cacheable
       
        // LR_skipUnsearchable [0 | 1]
        // Default value : 0
        // Must we skip pages that are not searchable
    	
    	// LR_skipFolder [0 | 1]
        // Default value : 0 
        // Must we skip pages that are marked as folder
    	
    	// LR_skipUnpublished [0 | 1]
        // Default value : 0
        // Must we skip pages that are not published
    	
    	
    	// LR_label [string]
        // Default value : 'pagetitle'
    	// Content of the title attribute for <a> anchor must be a field label of the prefix_site_content table 
    	// e.g = [[ListRelated? &LR_label='title']]
    	
    	
    	// LR_titleAttribute [string]
        // Default value : 'longtitle'
    	// Content of the title attribute for <a> anchor must be a field label of the prefix_site_content table 
    	// e.g = [[ListRelated? &LR_titleAttribute='description']]
    
    	
    	/*LR_contentParagraph [ string ]
    	// Content of the <p> tag if mentioned. 
    	// Default value : '' 
    	// Content of contentParagraph must be a field label of the prefix_site_content table
    	// e.g = [[ListRelated? &LR_contentOption='description']]
    	*/
    
    	/*LR_selectDocs [ string ]
    	// Default value : '' 
    	// Must we intergrate only pages found in the list e.g = [[ListRelated? &LR_onlyDocs='5,51']]
    	*/
    	
    	
    	/*LR_selectDocsWithChildren [ 0 | 1 ]
    	// Default value : 1; 
    	// If we are in LR_selectDocs mod search, must we include children (recursive).
    	*/
    
    // Styles
    
       // .LR_listTitle     class for list title
       // .LR_linksList     class for ul element
       // .LR_description   class for p element
    
    // ***********************************
    // END CONFIG SETTINGS
    // THE REST SHOULD TAKE CARE OF ITSELF
    // ***********************************
    
    // assign IE variable
    $newline = ($removeNewlines)? '':"\n";
    
    // assign appropriate default or passed variables
    $maxRelated = (isset($LR_max))? $LR_max : $maxRelated;
    $relatedListTitle = (isset($LR_title))? $LR_title : $relatedListTitle ;
    $sortBy = (isset($LR_sortBy))? $LR_sortBy: $sortBy ;
    $sortDir = (isset($LR_sortDir))? $LR_sortDir :$sortDir ;
    $querySkipPages = (isset($LR_skipPages) && ($LR_skipPages!='') )? " AND (NOT(content.id IN(".$LR_skipPages."))) " : "" ;
    $queryOnlyPages =  (isset($LR_selectDocs) && ($LR_selectDocs!=''))? " AND (content.id IN(".$LR_selectDocs.")) " : "" ; 
    
    $querySkipDeleted = (isset($LR_skipDeleted) && ($LR_skipDeleted))? " AND (content.deleted=0) " : "" ;
    $querySkipUnCacheable = (isset($LR_skipUncacheable) && ($LR_skipUncacheable))? " AND (content.cacheable) " : "" ;
    $querySkipUnSearchable = (isset($LR_skipUnsearchable) && ($LR_skipUnsearchable))? " AND (content.searchable) " : "" ;
    $querySkipUnPublished = (isset($LR_skipUnpublished) && ($LR_skipUnpublished))? " AND (content.published) " : "" ;
    $querySkipFolder =  (isset($LR_skipFolder) && ($LR_skipFolder))? " AND (NOT content.isfolder) " : "" ; 
    
    $complete_select_query = array("content.id", "content.pagetitle", "content.description", "content.longtitle");
    $choosenLabel = 'pagetitle';
    $choosenTitleAttribute = 'longtitle';
    $choosenContentParagraph = '';
    
    // assign appropriate displayed values AND query select options
    if(isset($LR_label))
    {
    $choosenLabel = $LR_label;
    	if(!in_array("content.".$LR_label,$complete_select_query))
    		array_push($complete_select_query,"content.".$LR_label);
    }
    
    
    if(isset($LR_titleAttribute))
    {
    	$choosenTitleAttribute = $LR_titleAttribute;
    	if(!in_array("content.".$LR_titleAttribute,$complete_select_query))
    		array_push($complete_select_query,"content.".$LR_titleAttribute);
    }
    
    if(isset($LR_contentParagraph))
    {
    	$choosenContentParagraph = $LR_contentParagraph;
    	if(!in_array("content.".$LR_contentParagraph,$complete_select_query))
    		array_push($complete_select_query,"content.".$LR_contentParagraph);
    	
    }
    
    $choosenContentParagraph = (isset($LR_contentParagraph))? $LR_contentParagraph :'';
    
    // Make array of keywords from snippet or from current page. Snippet
    // variables have priority.
    
    if (isset($LR_keywords)){
      $kArray= explode(",",$LR_keywords);
    } else {
      $kArray = $modx->getKeywords();
    }
    
    
    if(!function_exists('getRecursiveAllChildren'))
    {
    	function getRecursiveAllChildren($modXObject,$idDoc,$arrayChildren = array())
    	  {
       	
    	 array_push($arrayChildren,$idDoc); 
    	 $arrayDocChild  = $modXObject->getAllChildren($idDoc);
    	 
    	 foreach($arrayDocChild as $id=>$val)
    		 $arrayChildren = getRecursiveAllChildren($modXObject,$val['id'],$arrayChildren);
    		
    	 return($arrayChildren);
    	  }
    }
      
     
    
    
    
    
    
    // if there are keywords, make the list
    $relatedOutput = '';
    if ($kArray){
      $keyString = '';
      foreach ($kArray as $key){
        $keyString .= "'".$key."',";
      }
      $keyString = substr($keyString,0,strlen($keyString)-1);
    
      // make sql statement for retreiving similar pages
      $pre= $modx->dbConfig['dbase'].".".$modx->dbConfig['table_prefix'];

    $all_custom_queries = "";
    if (($LR_selectDocs!='') && isset($LR_selectDocsWithChildren) && ($LR_selectDocsWithChildren))
    {
    $arraySelectedDocs = explode(',',trim($LR_selectDocs));
    $arrayAllChildren = array();
    foreach($arraySelectedDocs as $arrayVal)
    {
    $arrayAllChildren = array_unique(array_merge($arrayAllChildren,getRecursiveAllChildren($modx,$arrayVal),array($arrayVal)));
    }

    $queryIn = "AND content.id IN(".implode(",",$arrayAllChildren).") ";
    $all_custom_queries = $queryIn." ".$querySkipFolder." ".$querySkipDeleted." ".$querySkipUnCacheable." ".$querySkipUnSearchable." ".$querySkipUnPublished." ".$querySkipPages;

    }
    else
    $all_custom_queries = $queryOnlyPages." ".$querySkipFolder." ".$querySkipDeleted." ".$querySkipUnCacheable." ".$querySkipUnSearchable." ".$querySkipUnPublished." ".$querySkipPages;



    $complete_select_query = implode(',',$complete_select_query);
    $relatedSql = "SELECT ".$complete_select_query.",
    IF(content.pub_date > 0, content.pub_date, content.createdon) AS date,
    COUNT(keywords.id) as total_kw
    FROM
    ".$pre."site_content AS content,
    ".$pre."keyword_xref AS xref,
    ".$pre."site_keywords AS keywords
    WHERE keywords.keyword IN (".$keyString.")
    $all_custom_queries
    AND xref.keyword_id = keywords.id
    AND content.hidemenu = ".$showhidemenu."
    AND content.id = xref.content_id
    AND content.id != ".$modx->documentObject['id']."
    GROUP BY content.id
    ORDER BY total_kw DESC, ". $sortBy . ' ' . $sortDir ."
    LIMIT ".$maxRelated.";";


    $relatives = $modx->dbQuery($relatedSql);
    $relativeCount = $modx->recordCount($relatives);
    $relArray = array();
    for($i=0;$i<$relativeCount;$i++) {
    array_push($relArray,$modx->fetchRow($relatives));
    }

    $getAttribute = "id,$choosenLabel,$goodTitleAttribute";
    $getAttribute .=($choosenContentParagraph!='')? $choosenContentParagraph:"";


    // start output if we have results
    if ($relativeCount){
    $relatedOutput .= ($relatedListTitle )?'<span class="LR_listTitle">' . $relatedListTitle . '</span>' : '' ;
    $relatedOutput .= '<ul class="LR_linksList">'.$newline;
    for ($li=0;$li<$relativeCount;$li++){
    $goodLabel = $relArray[$li][$choosenLabel];
    $goodTitleAttribute = $relArray[$li][$choosenTitleAttribute];
    $goodContentParagraph = (($choosenContentParagraph!='')&& isset($relArray[$li][$choosenContentParagraph])) ? '<p class="LR_description">'.$relArray[$li][$choosenContentParagraph].'</p>':'';
    $relatedOutput .= '<li><a href=[~' . $relArray[$li]['id'] . '~] title="' .$goodTitleAttribute. '">' .$goodLabel. '</a>'.$goodContentParagraph.'</li>'.$newline;
    }
    $relatedOutput .='</ul>'.$newline;
    }
    }

    return $relatedOutput;
    ?>
    <br /><br /><br />Si vous avez des remarques, des suggestions, des critiques, voires des insultes, n’hésitez pas. Je pense qu’il est possible de faire mieux (sélection de répertoires à parcourir par exemple...). <br /><br />++<br /><br />;)<br /><br />
      • 23050
      • 1,842 Posts
      Salut mr_go

      Perso, je n’ai jamais utilisé ce snippet. Il permet donc d’utiliser les mots-clés préalablement destinés au référencement (dans onglet Mots-clés) ?
        • 6726
        • 7,075 Posts
        Intéressant, j’y jetterai un coup d’oeil dès que j’aurai un peu de temps !
        Merci smiley
          .: COO - Commerce Guys - Community Driven Innovation :.


          MODx est l&#39;outil id
          • 20488
          • 353 Posts
          Bonjour Perrine,

          en réalité, les mots clés ne sont plus interprétés (ou très peu) par les plus grands moteurs de recherche en ce qui concerne le référencement, ce n’est donc pas pour cela que j’utilise cette notion.
          Ils peuvent s’avérer interressants pour certains modules (notamment pour ce qu’on appelle les tags clouds).

          Pour bien comprendre ce snippet, prenons un exemple concret, ce sera plus parlant :


          Admettons qu’un article d’un site généraliste d’informatique parle de... hum au hasard ModX (:)), intitulé "MODX, le meilleur CMS de sa génération". Ses mots clés seront donc "modX, CMS, informatique, développement" par exemple.

          Si, dans ce site, on retrouve un autre article intitulé "Développement spécifique ou CMS ?" avec pour mot clé "CMS, informatique, développement", il peut s’avérer interressant de créer un lien de type "Voir aussi" vers le premier article, et ce, même si le deuxième article n’est pas situé dans le même répertoire que le premier.

          C’est un outil assez puissant en ce qui concerne la gestion d’article, puisqu’il permet de générer automatiquement des liens vers d’autres articles du site ayant plus ou moins la même thématique. Cela permet d’éviter dans un premier temps une recherche longue et fastidieuse d’articles connexes, et parfois un "surlinking" (beaucoup de liens internes) d’un article. Encore faut il bien gérer ses mots clés bien évidemment... wink

            • 23050
            • 1,842 Posts
            Ok, avec l’exemple, c’est en effet très parlant ! Je me le mets derrière l’oreille et bravo pour tes modifs car je devine que ça enrichit sacrément le snippet ! wink
              • 20488
              • 353 Posts
              Oui, enfin j’ai paré au plus pressé dirons nous. smiley

              Une foultitude d’évolutions est possible, mais j’ai avant tout posté cette première contribution pour permetre de cerner vos éventuelles attentes vis à vis de la modification de ce snippet.

              Et surtout histoire de voir si je n’ai pas bossé pour rien grin: Je craignais une réponse de type "pwark, snipMax le gère mieux !".

              Ps : ne cherchez pas de snippet snipMax, il n’y en a pas. wink

              @davidm : avec plaisir ! =)
                • 33175
                • 711 Posts
                Excellent travail mr_go ! J’adopte de suite !!
                Enfin, presque wink dès que j’ai commencé mon nouveau site en fait.
                Je pense que ListRelated a des lacunes rectifié par ton snippet smiley
                  Sorry for my english. I&#39;m french... My dictionary is near me, but it&#39;s only a dictionary !
                  • 6726
                  • 7,075 Posts
                  Le seul concurrent c’est SnipMax... euh, PageKeyworder mais il ne marche pas forcémment comme je voudrai...
                    .: COO - Commerce Guys - Community Driven Innovation :.


                    MODx est l&#39;outil id
                    • 20488
                    • 353 Posts
                    Merci à vous.

                    Si vous avez des bugs n’hésitez pas à me le dire wink

                    En outre, je travaille sur une deuxième version incluant deux nouvelles options :

                    - Possibilité de sélectionner uniquement des documents précis (OK à priori)
                    - Possibilité de choisir un parcours récursif sur des répertoires. Dès lors que j’ai résolu ce problème...

                    ;)
                      • 20488
                      • 353 Posts
                      Nouvelle version à copier coller remplaçant l’original. J’ai modifié directement mon post#1, c’est donc ce nouveau code à télécharger.

                      Au programme des rajouts, et comme prévu :

                      - Possibilité de sélectionner uniquement des documents précis
                      - Possibilité de choisir un parcours récursif sur ces documents (si ce sont des répertoires bien entendu).


                      Quelques applications pour que cela parraisse moins obscur :


                      Tous les documents ayant au moins un mot clé commun avec le document appelé (classé par nombre de mot clé commun décroissant)

                      [!ListRelated!]
                      


                      Tous les documents et personnalisation du texte de sortie

                      [!ListRelated?&LR_titleAttribute=`description` &LR_label=`pagetitle` &LR_contentParagraph=`pagetitle` !]




                      Tous les documents qui ne sont pas des répertoires

                      [!ListRelated?&LR_skipFolder=`1` !]




                      Tous les documents qui ne sont pas supprimés et qui sont publiés

                      [!ListRelated?&LR_skipUnpublished=`1` &LR_skipDeleted=`1` !]




                      Tous les documents sauf les numéros 41,42

                      [!ListRelated?&LR_skipPages=`42,41`!]



                      Uniquement les documents 41 et 43

                      [!ListRelated?&LR_selectDocs=`41,43`!]


                      Uniquement les documents 41 et 43 ainsi que leurs enfants si ils en ont


                      [!ListRelated?&LR_title=`A voir impérativement` &LR_selectDocs=`41,43` &LR_selectDocsWithChildren=`1` !]



                      Un cas concret et plus complexe, mais utile :

                      [!ListRelated?&LR_titleAttribute=`description` &LR_label=`pagetitle` &LR_contentParagraph=`longtitle` &LR_selectDocs=`42` &LR_selectDocsWithChildren=`1` &LR_skipFolder=`1` &LR_max=`6` &LR_skipUnpublished=`1` &LR_skipDeleted=`1` !]


                      Vous pouvez vous entrainer à trouver ce que fait cet appel...




                      Solution

                      Ici, je sélectionne les 6 documents actifs d’un répertoire particulier (42) ainsi que les documents actifs des répertoires enfants de ce dernier, mais aussi les documents actifs des répertoires enfants des enfants etc... (parcours récursif). Une subtilité ici, on ne sélectionne que des documents qui ne sont pas des répertoires.

                      Concretement, cela signifie que l’on va récupérer les 6 documents qui font partie du répertoire 42 ou de ses sous-répertoires qui ne sont pas des répertoires, et qui ont des mots clés communs avec le document appelé (classé par nombre de mots clés commun).
                      Note : cet appel n’est pas obligatorement dans un document du répertoire 42 bien évidemment.

                      Ce dernier cas est très interressant dans le cadre de la mise en place d’un webzine ou d’un blog par exemple, puisqu’il permet de cibler uniquement les articles et non les pages-répertoires ammenant aux articles.

                      Voilà, j’espère que ces deux items, qui me paraissaient indispensables, vous conviendront.

                      L’intégralité des variables précédentes fonctionnent toujours bien entendu.