2013-03-31 6 views
7

Ich möchte mit Attributen Shortcode wie Wordpress analysieren:Parse Wordpress wie Short

Eingang:

[include file="header.html"] 

Ich brauche Ausgabe als Array Funktionsnamen „include“ und Attribute mit Werten als auch, jede mögliche Hilfe wird geschätzt werden.

Dank

+3

Bitte versuchen Sie meine Bibliothek, es ist eigenständigen und bereits kampferprobt in der Produktion: https://github.com/thunderer/Shortcode. Wenn du etwas brauchst, lass es mich wissen! –

+0

@TomaszKowalczyk danke!:) – Iamzozo

Antwort

4

this function

$code = '[include file="header.html"]'; 
$innerCode = GetBetween($code, '[', ']'); 
$innerCodeParts = explode(' ', $innerCode); 

$command = $innerCodeParts[0]; 

$attributeAndValue = $innerCodeParts[1]; 
$attributeParts = explode('=', $attributeParts); 
$attribute = $attributeParts[0]; 
$attributeValue = str_replace('\"', '', $attributeParts[1]); 

echo $command . ' ' . $attribute . '=' . $attributeValue; 
//this will result in include file=header.html 

$ Befehl verwendet, wird "include"

$ Attribut sein wird

$ attribute wird "header.html" "Datei"

+0

Ich kann Fehler sehen: Schwerwiegender Fehler: Aufruf zu undefinierter Funktion GetBetween() in wp_parse.php in Zeile 4 –

+0

Lesen Sie die erste Zeile meiner Antwort, müssen Sie diesen Code in Ihre Datei einfügen: 'Funktion GetBetween ($ Inhalt , $ start, $ end) { $ r = explodieren ($ start, $ content); if (isset ($ r [1])) { $ r = explodieren ($ end, $ r [1]); zurückgeben $ r [0]; } Rückgabe ''; } ' – Andrew

+0

@ShahzabAsif ​​Ich habe meinen Code nicht getestet, also lassen Sie mich wissen, ob es für Sie funktioniert. – Andrew

1

Das ist eigentlich härter als es scheint an der Oberfläche. Andrews Antwort funktioniert, bricht aber zusammen, wenn eckige Klammern im Quelltext erscheinen [wie dies zum Beispiel]. WordPress funktioniert, indem er eine Liste gültiger Shortcodes vorregistriert und nur auf Text in Klammern reagiert, wenn er mit einem dieser vordefinierten Werte übereinstimmt. Auf diese Weise wird kein normaler Text verfehlt, in dem möglicherweise gerade eckige Klammern stehen.

Die tatsächliche source code der WordPress-Shortcode-Engine ist ziemlich robust, und es sieht nicht so aus, als wäre es so schwer zu ändern, die Datei selbst zu laufen - dann könnten Sie das in Ihrer Anwendung verwenden harte Arbeit. (Wenn Sie interessiert sind, werfen Sie einen Blick auf get_shortcode_regex() in dieser Datei, um zu sehen, wie haarig die richtige Lösung für dieses Problem tatsächlich bekommen kann.)

Eine sehr grobe Umsetzung Ihrer Frage mit der WP shortcodes.php würde aussehen etwas wie:

// Define the shortcode 
function inlude_shortcode_func($attrs) { 
    $data = shortcode_atts(array(
     'file' => 'default' 
    ), $attrs); 

    return "Including File: {$data['file']}"; 
} 
add_shortcode('include', 'inlude_shortcode_func'); 

// And then run your page content through the filter 
echo do_shortcode('This is a document with [include file="header.html"] included!'); 

Auch hier überhaupt nicht getestet, aber es ist nicht eine sehr harte API zu verwenden.

+0

Es wäre besser gewesen, wenn Sie ein funktionierendes Beispiel enthalten hätten. –

2

Ich brauchte diese Funktionalität auch in meinem PHP-Framework. Das ist, was ich geschrieben habe, es funktioniert ziemlich gut. Es funktioniert mit anonymen Funktionen, die ich wirklich mag (es ist ein bisschen wie die Callback-Funktionen in JavaScript).

<?php 
//The content which should be parsed 
$content = '<p>Hello, my name is John an my age is [calc-age day="4" month="10" year="1991"].</p>'; 
$content .= '<p>Hello, my name is Carol an my age is [calc-age day="26" month="11" year="1996"].</p>'; 

//The array with all the shortcode handlers. This is just a regular associative array with anonymous functions as values. A very cool new feature in PHP, just like callbacks in JavaScript or delegates in C#. 
$shortcodes = array(
    "calc-age" => function($data){ 
     $content = ""; 
     //Calculate the age 
     if(isset($data["day"], $data["month"], $data["year"])){ 
      $age = date("Y") - $data["year"]; 
      if(date("m") < $data["month"]){ 
       $age--; 
      } 
      if(date("m") == $data["month"] && date("d") < $data["day"]){ 
       $age--; 
      } 
      $content = $age; 
     } 
     return $content; 
    } 
); 
//http://stackoverflow.com/questions/18196159/regex-extract-variables-from-shortcode 
function handleShortcodes($content, $shortcodes){ 
    //Loop through all shortcodes 
    foreach($shortcodes as $key => $function){ 
     $dat = array(); 
     preg_match_all("/\[".$key." (.+?)\]/", $content, $dat); 
     if(count($dat) > 0 && $dat[0] != array() && isset($dat[1])){ 
      $i = 0; 
      $actual_string = $dat[0]; 
      foreach($dat[1] as $temp){ 
       $temp = explode(" ", $temp); 
       $params = array(); 
       foreach ($temp as $d){ 
        list($opt, $val) = explode("=", $d); 
        $params[$opt] = trim($val, '"'); 
       } 
       $content = str_replace($actual_string[$i], $function($params), $content); 
       $i++; 
      } 
     } 
    } 
    return $content; 
} 
echo handleShortcodes($content, $shortcodes); 
?> 

Das Ergebnis:
Hallo, mein Name ist John ein mein Alter ist 22
Hallo, mein Name Carol ist ein in meinem Alter 17.

3

ist Hier ist eine Utility-Klasse, die wir früher auf unser Projekt es werden alle Kurzwahlnummern in einem String (einschließlich html) entsprechen und gibt er ein assoziatives Array einschließlich ihrer name, attributes und content

final class Parser { 

    // Regex101 reference: https://regex101.com/r/pJ7lO1 
    const SHORTOCODE_REGEXP = "/(?P<shortcode>(?:(?:\\s?\\[))(?P<name>[\\w\\-]{3,})(?:\\s(?P<attrs>[\\w\\d,\\s=\\\"\\'\\-\\+\\#\\%\\!\\~\\`\\&\\.\\s\\:\\/\\?\\|]+))?(?:\\])(?:(?P<content>[\\w\\d\\,\\!\\@\\#\\$\\%\\^\\&\\*\\(\\\\)\\s\\=\\\"\\'\\-\\+\\&\\.\\s\\:\\/\\?\\|\\<\\>]+)(?:\\[\\/[\\w\\-\\_]+\\]))?)/u"; 

    // Regex101 reference: https://regex101.com/r/sZ7wP0 
    const ATTRIBUTE_REGEXP = "/(?<name>\\S+)=[\"']?(?P<value>(?:.(?![\"']?\\s+(?:\\S+)=|[>\"']))+.)[\"']?/u"; 

    public static function parse_shortcodes($text) { 
     preg_match_all(self::SHORTOCODE_REGEXP, $text, $matches, PREG_SET_ORDER); 
     $shortcodes = array(); 
     foreach ($matches as $i => $value) { 
      $shortcodes[$i]['shortcode'] = $value['shortcode']; 
      $shortcodes[$i]['name'] = $value['name']; 
      if (isset($value['attrs'])) { 
       $attrs = self::parse_attrs($value['attrs']); 
       $shortcodes[$i]['attrs'] = $attrs; 
      } 
      if (isset($value['content'])) { 
       $shortcodes[$i]['content'] = $value['content']; 
      } 
     } 

     return $shortcodes; 
    } 

    private static function parse_attrs($attrs) { 
     preg_match_all(self::ATTRIBUTE_REGEXP, $attrs, $matches, PREG_SET_ORDER); 
     $attributes = array(); 
     foreach ($matches as $i => $value) { 
      $key = $value['name']; 
      $attributes[$i][$key] = $value['value']; 
     } 
     return $attributes; 
    } 
} 

print_r(Parser::parse_shortcodes('[include file="header.html"]')); 
Ausgang 10

:

Array 
(
    [0] => Array 
     (
      [shortcode] => [include file="header.html"] 
      [name] => include 
      [attrs] => Array 
       (
        [0] => Array 
         (
          [file] => header.html 
         ) 
       ) 
     ) 
) 
+1

Das ist großartig .. aber gibt es eine Möglichkeit, es als Ersatz zu tun .. es verwandelt nur den Shortcode und es entfernt jeden anderen Text, der es sein kann .. – Kravitz

+0

@REPTILE Die Frage angefordert, dass es den Shortcode und analysieren wird Die Ausgabe erfolgt als assoziatives Array. Sie können dann jedes Element nehmen und produzieren, was auch immer Sie wollen. Du könntest etwas wie '' 'str_replace ($ shortcode, $ compiled_shortcode, $ string)' '' Das wird nach dem shortcode suchen und ihn durch '' $ compiled_output''' ersetzen, das du in einer Zeichenkette erzeugt hast. Normalerweise ist der String der gesamte HTML-Code wie '' 'post_content''' –