Parse Wordpress as Shortcode

I want to parse a short code like Wordpress with attributes:

Input:

[include file="header.html"] 

I need output as an array, the name of the "include" function and attributes with values, any help would be appreciated.

thanks

+7
source share
4 answers

Using 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 will include include

Attribute

$ will be "file"

$ attributeValue will be "header.html"

+4
source

Here is the utility class that we used in our project. It will correspond to all shortcodes in a line (including html), and it will output an associative array containing their name , attributes and 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"]')); 

Output:

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

I also need this functionality in my PHP environment. This is what I wrote, it works very well. It works with anonymous functions that I really like (this is a bit like JavaScript callback functions).

 <?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); ?> 

Result:
Hi, my name is John, my age is 22.
Hi, my name is Carol, my age is 17 years old.

+2
source

This is actually more complicated than it might seem on the surface. Andrew answers, but begins to break down if square brackets appear in the source text [for example, this]. WordPress works by pre-registering a list of valid shortcodes and only acting on the text inside the brackets if it matches one of these predefined values. Thus, it does not distort any plain text that could have a set of square brackets in it.

The actual source code for the WordPress shortcode engine is strong enough, and it doesn't seem like it would be very difficult to modify the file to run on its own - then you can use this in your application to handle the tough work. (If you're interested, see get_shortcode_regex() in this file to see how hairy the correct solution to this problem can be.)

A very crude implementation of your question using WP shortcodes.php will look something like:

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

Again, not tested at all, but it is not a very hard API to use.

+1
source

All Articles