iapetus logo
Druckansicht

SPIP Filter ’liens_mots’

20. Dezember 2003, aktualisiert am 31. Mai 2011, bearbeitet von Tinu
(Übersetzungen: français)

Dieses SPIP Filter unterlegt in einem Text vorkommende Schlagworte automatisch mit einem Link zur Definition. Entworfen wurde es für http://www.apotheke-scheibbs.at. Es wird ebenfalls auf dieser Site verwendet (siehe unten für eine Funktionsbeschreibung).

Installation: untenstehenden Code in mes_fonctions.php einfügen und Squelette entsprechend anpassen.

/***********************************************************/
// autolink keywords in articles (version 5):
// webmaster (at) iapetus.ch or webmaster (at) apotheke-scheibbs.at
// site: http://www.iapetus.ch or http://www.apotheke-scheibbs.at
// usage : [(#TEXTE*|liens_mots|propre)]
// or    : [(#TEXTE*|liens_mots{4}|propre)]
// or    : [(#TEXTE*|liens_mots{4,en}|propre)]
//         to only replace the 4 first occurences of each keyword, set to -1 to replace all

function liens_mots($texte, $count = -1,$lang='') {

 global $traduc_hash_lang;

 $query_liens_autos = "SELECT id_mot, titre, type FROM spip_mots ".
                           "as liens ORDER BY CHAR_LENGTH(titre) DESC";
 $result_liens_autos = spip_query($query_liens_autos);

 $regexp_echap = "/(<html>.*?<\/html>|<code>.*?<\/code>|<cadre>.*?<\/cadre>)/si";
 $elements = preg_split($regexp_echap,$texte,-1,PREG_SPLIT_DELIM_CAPTURE);

 foreach (array_keys($elements) as $key) {
   $block =& $elements[$key];

   if ($lang == '') { //
     $lang = $GLOBALS['spip_lang'];
   }

   if (!preg_match($regexp_echap, $block)) {
     $block .= '['; // append a delimiter to simplify the pattern
     mysql_data_seek($result_liens_autos, 0);
     while($row_liens = mysql_fetch_array($result_liens_autos)) {
       $lang_mot = extraire_alphanumero($row_liens["type"]);
       if (($lang=='tous') || ($lang_mot == $lang) || (strlen($lang_mot) == 0)) {
         if (!$countdown[$row_liens["titre"]]) $countdown[$row_liens["titre"]] = $count;
       
         $regexp_search  = '/\\b'.preg_quote($row_liens["titre"],'/').'\\b(?=[^\\]]*?\\[)/';
         $regexp_replace = '[' . $row_liens["titre"].'-> mot'.$row_liens["id_mot"].']';
       
         if ($count != -1) {
           $delta = preg_match_all($regexp_search,$block,$matches);
           $block = preg_replace($regexp_search, $regexp_replace, $block, $countdown[$row_liens["titre"]]);
           $countdown[$row_liens["titre"]] = max(0,  $countdown[$row_liens["titre"]]-$delta);
         }
         else
           $block=preg_replace($regexp_search,$regexp_replace,$block);
       }
     }
   $block = substr($block, 0, -1);  // remove [ - delimiter
   }
 }
 return implode($elements);      
}
/***********************************************************/

Funktionsbeschreibung

Zuerst wird $texte in code, html und sonstige Textblöcke aufgeteilt. code und html-Blöcke werden nicht modifiziert. Alle anderen Blöcke werden nach zu ersetzenden Schlagwörtern durchsucht.

Das Regex-Pattern matcht Wörter aus der Liste $row_lines in $block, die sich nicht zwischen eckigen Klammern befinden. preg_replace ersetzt diese Wörter durch einen SPIP-Link auf die Definition des Wortes.

Das Pattern sieht ohne PHP-String-Escaping so aus:

/             : Patternanfang  
\b            : Wortgrenze        \  
wort          : der Suchbegriff   ¦- wird durch [wort->mot21]-Link ersetzt
\b            : Wortgrenze        /
(?=           : Lock Ahead Match Anfang
 [^\]]*?      : so viele Zeichen wie möglich ohne ] ,
                weil sonst wäre der Suchbegriff innerhalb []  
 \[           : abschliessendes [, entweder der Anfang
                vom nächsten Klammernpaar oder das [ -Zeichen
                am Stringende
)             : Ende Lock Ahead
/             : Patternende  

Da der Suchbegriff direkt in das Pattern eingesetzt wird (anstelle von wort), muss er ’patternkompatibel’ mit preg_quote escaped werden - sonst ergeben Sonderzeichen und / oder \ im Suchbegriff einen Syntaxfehler im Pattern.

Weil das Pattern als String in PHP verwendet wird, muss es noch PHP-String-Escaped werden (d.h. alle \ verdoppeln und ’ duch \’ ersetzen), was zusammen mit preg_quote folgendes ergibt:

'/\\b'.preg_quote($row_liens["titre"],'/').'\\b(?=[^\\]]*?\\[)/'

Alle Matches werden dann von preg_replace durch

'[' . $row_liens["titre"].'-> mot'.$row_liens["id_mot"].']'

ersetzt.

Das Pattern funktioniert nur, wenn mindestens eine öffnende eckige Klammer im Text vorkommt (sonst funktioniert der Lock Ahead Match nicht). Die Funktion wird garantiert, indem vor dem Matching eine öffnende eckige Klammer am Ende angefügt wird. Dieser Delimiter wird nachher wieder entfernt.

Zum Schluss werden alle Blöcke (modifizierte und nicht modifizierte) wieder zusammengefügt.

 

SPIP filter ’liens_mots’

2.3 kB

 

 

 

mehr davon:

 

 
Mail: crater * iapetus.ch
aktualisiert am 31. Mai 2011