Merge pull request #2507 from ajshort/pull-3

API: Pass extra context information to shortcode handlers.
This commit is contained in:
Ingo Schommer 2013-10-09 01:14:35 -07:00
commit 156679ff14
3 changed files with 24 additions and 9 deletions

View File

@ -64,6 +64,9 @@ These parameters are passed to the callback:
will not have been parsed, and can optionally be fed back into the parser.
- The ShortcodeParser instance used to parse the content.
- The shortcode tag name that was matched within the parsed content.
- An associative array of extra information about the shortcode being parsed. For example, if the shortcode is
is inside an attribute, the `element` key contains a reference to the parent `DOMElement`, and the `node`
key the attribute's `DOMNode`.
## Example: Google Maps Iframe by Address

View File

@ -68,6 +68,7 @@ class ShortcodeParser {
* this will not have been parsed, and can optionally be fed back into the parser.
* - The {@link ShortcodeParser} instance used to parse the content.
* - The shortcode tag name that was matched within the parsed content.
* - An associative array of extra information about the shortcode being parsed.
*
* @param string $shortcode The shortcode tag to map to the callback - normally in lowercase_underscore format.
* @param callback $callback The callback to replace the shortcode with.
@ -102,9 +103,9 @@ class ShortcodeParser {
$this->shortcodes = array();
}
public function callShortcode($tag, $attributes, $content) {
public function callShortcode($tag, $attributes, $content, $extra = array()) {
if (!isset($this->shortcodes[$tag])) return false;
return call_user_func($this->shortcodes[$tag], $attributes, $content, $this, $tag);
return call_user_func($this->shortcodes[$tag], $attributes, $content, $this, $tag, $extra);
}
// --------------------------------------------------------------------------------------------------------------
@ -332,11 +333,12 @@ class ShortcodeParser {
for($i = 0; $i < $attributes->length; $i++) {
$node = $attributes->item($i);
$tags = $this->extractTags($node->nodeValue);
$extra = array('node' => $node, 'element' => $node->ownerElement);
if($tags) {
$node->nodeValue = $this->replaceTagsWithText($node->nodeValue, $tags,
function($idx, $tag) use ($parser){
$content = $parser->callShortcode($tag['open'], $tag['attrs'], $tag['content']);
function($idx, $tag) use ($parser, $extra){
$content = $parser->callShortcode($tag['open'], $tag['attrs'], $tag['content'], $extra);
if ($content === false) {
if(ShortcodeParser::$error_behavior == ShortcodeParser::ERROR) {

View File

@ -6,6 +6,7 @@
class ShortcodeParserTest extends SapphireTest {
protected $arguments, $contents, $tagName, $parser;
protected $extra = array();
public function setUp() {
ShortcodeParser::get('test')->register('test_shortcode', array($this, 'shortcodeSaver'));
@ -210,15 +211,24 @@ class ShortcodeParserTest extends SapphireTest {
);
}
public function testExtraContext() {
$this->parser->parse('<a href="[test_shortcode]">Test</a>');
$this->assertInstanceOf('DOMNode', $this->extra['node']);
$this->assertInstanceOf('DOMElement', $this->extra['element']);
$this->assertEquals($this->extra['element']->tagName, 'a');
}
// -----------------------------------------------------------------------------------------------------------------
/**
* Stores the result of a shortcode parse in object properties for easy testing access.
*/
public function shortcodeSaver($arguments, $content = null, $parser, $tagName = null) {
public function shortcodeSaver($arguments, $content, $parser, $tagName, $extra) {
$this->arguments = $arguments;
$this->contents = $content;
$this->tagName = $tagName;
$this->contents = $content;
$this->tagName = $tagName;
$this->extra = $extra;
return $content;
}