2013-03-31 57 views
7

Tôi muốn phân tích shortcode như Wordpress với các thuộc tính:Parse Wordpress như SHORTCODE

Input:

[include file="header.html"] 

tôi cần đầu ra như mảng, tên hàm "bao gồm" và các thuộc tính với các giá trị là tốt, bất kỳ sự giúp đỡ sẽ được đánh giá cao.

Cảm ơn

+3

Vui lòng thử thư viện của tôi, đó là độc lập và đã chiến đấu thử nghiệm trong sản xuất: https://github.com/thunderer/Shortcode. Nếu bạn cần bất cứ điều gì cho tôi biết! –

+0

@TomaszKowalczyk cảm ơn!:) – Iamzozo

Trả lời

4

Sử dụng 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 

$ command sẽ "bao gồm"

$ thuộc tính sẽ "nộp"

$ attributeValue sẽ là "header.html"

+0

Tôi có thể thấy lỗi: Lỗi nghiêm trọng: Gọi hàm không xác định GetBetween() trong wp_parse.php trên dòng 4 –

+0

Đọc dòng đầu tiên trong câu trả lời của tôi, bạn cần dán mã này vào tệp của mình: 'function GetBetween ($ content , $ bắt đầu, $ end) { $ r = phát nổ ($ start, $ content); nếu (isset ($ r [1])) { $ r = phát nổ ($ end, $ r [1]); trả về $ r [0]; } trả lại ''; } ' – Andrew

+0

@ShahzabAsif ​​Tôi không kiểm tra mã của mình để cho tôi biết nếu nó hoạt động cho bạn. – Andrew

1

Điều này thực sự khó khăn hơn có thể xuất hiện trên bề mặt. Câu trả lời của Andrew hoạt động, nhưng bắt đầu phá vỡ nếu các dấu ngoặc vuông xuất hiện trong văn bản nguồn [như thế này, ví dụ]. WordPress hoạt động bằng cách đăng ký trước một danh sách các mã ngắn hợp lệ và chỉ hoạt động trên văn bản bên trong dấu ngoặc đơn nếu nó khớp với một trong các giá trị được xác định trước này. Bằng cách đó nó không mangle bất kỳ văn bản thường xuyên mà chỉ có thể xảy ra để có một tập hợp các dấu ngoặc vuông trong đó.

Thực tế source code của công cụ shortcode WordPress khá mạnh mẽ, và có vẻ như sẽ khó thay đổi tệp để tự chạy - sau đó bạn có thể sử dụng nó trong ứng dụng của mình để xử lý công việc khó khăn. (Nếu bạn quan tâm, hãy xem get_shortcode_regex() trong tệp đó để xem cách giải quyết đúng đắn của vấn đề này đối với vấn đề này thực sự có thể có được.)

Việc triển khai rất nghiêm ngặt câu hỏi của bạn bằng cách sử dụng WP shortcodes.php sẽ xem xét một cái gì đó như:

// 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!'); 

một lần nữa, không được kiểm tra ở tất cả, nhưng nó không phải là một API rất khó để sử dụng.

+0

Sẽ tốt hơn nếu bạn đưa vào một ví dụ làm việc. –

2

Tôi cũng cần chức năng này trong khuôn khổ PHP của mình. Đây là những gì tôi đã viết, nó hoạt động khá tốt. Nó hoạt động với các hàm ẩn danh mà tôi thực sự thích (nó giống như các hàm gọi lại trong 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); 
?> 

Kết quả:
Xin chào, tôi tên là John một tuổi của tôi là 22.
Xin chào, tôi tên là Carol một tuổi của tôi là 17.

3

Dưới đây là một lớp tiện ích mà chúng tôi sử dụng trên dự án của chúng tôi nó sẽ phù hợp với tất cả shortcodes trong một chuỗi (bao gồm html) và nó sẽ ra một mảng kết hợp bao gồm họ name, attributescontent

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"]')); 

Output:

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

Điều này là tuyệt vời .. nhưng có cách nào để làm điều đó như là một thay thế .. nó chỉ biến đổi shortcode và nó loại bỏ bất kỳ văn bản khác có thể được xung quanh nó .. – Kravitz

+0

@REPTILE Câu hỏi yêu cầu nó sẽ phân tích các shortcode và đầu ra nó như là một mảng kết hợp. Sau đó, bạn có thể lấy từng phần tử và tạo ra bất kỳ đầu ra nào bạn thích. Bạn có thể làm một cái gì đó như '' 'str_replace ($ shortcode, $ compiled_shortcode, $ string)' '' Điều đó sẽ tìm kiếm shortcode, và thay thế nó bằng '' '$ compiled_output''' mà bạn đã tạo ra bên trong một chuỗi. Thông thường, chuỗi là toàn bộ html giống như '' 'post_content''' –