Pergunta

I'm currently working on making a nested tag extension, where the parent tag (in my case <tabs>) needs to be able to influence the contents of the child tag (in my case <tab>). I've tried doing this by just running $parser->recursiveTagParse($input) where $input is the contents of the <tabs> tag, but in the returned string, it seems to be impossible to match for anything. To test this in the most basic way possible I did the following:

add to LocalSettings.php:

require_once "$IP\\extensions\\Test\\Test.php";

Create Test.php in its Test directory with:

<?php
$wgAutoloadClasses['Test'] = __DIR__ . '/Test.body.php';
$wgHooks['ParserFirstCallInit'][] = 'Test::init';

Create Test.body.php with:

<?php
class Test {
    public static function init( &$parser ) {
        $parser->setHook( 'testfoo', array( 'Test', 'firstTag' ) );
        $parser->setHook( 'testbar', array( 'Test', 'secondTag' ) );
        return true;
    }

    public static function firstTag($input, $attr = array(), $parser, $frame) {
        $newinput = $parser->recursiveTagParse($input);
        return preg_match_all("/ /", $newinput);
    }

    public static function secondTag($input, $attr = array(), $parser, $frame) {
        return htmlspecialchars($input);
    }
}

and finally, put the following on a page on the wiki:

<testfoo>three spaces out here<testbar>and four more spaces here</testbar></testfoo>

This should make the final output for be 7, since there are 7 spaces in the output string. The problem is that this instead returns 3, the amount of spaces that are outside the <testbar> tag.

What I'd like to know is if it is possible at all to match and/or replace the results of parsing the nested tag (so what the nested tag outputs), and if that is not possible, is it possible to make the <testbar> tag behave differently when nested inside a <testfoo> tag?


I've also tried adding a PPFrame as second argument to the part of $parser->recursiveTagParse($input) to attempt making it possible to detect nesting, but the documentation for PPFrame is so unclear that I have no idea what I need to do. What I do now, based on what the documentation says is this:

    public static function firstTag($input, $attr = array(), $parser, $frame) {
        $newframe = $frame->newChild(array('nested'=>'true'), $frame->getTitle(), 0);
        $newinput = $parser->recursiveTagParse($input, $newframe);
        return preg_match_all("/ /", $newinput);
    }

But that causes errors. What it says when I do that is:

Notice: Trying to get property of non-object in C:\hiddenpath\w\includes\parser\Preprocessor_DOM.php on line 984

Catchable fatal error: Argument 1 passed to DOMXPath::__construct() must be an instance of DOMDocument, null given, called in C:\hiddenpath\w\extensions\Test\Test.body.php on line 10 and defined in C:\hiddenpath\w\includes\parser\Preprocessor_DOM.php on line 984

But I've got no idea what I need to do to fix this. Do I need to make my first argument a special object? And if so, why does the documentation say I need to put an array as first argument?

Foi útil?

Solução

Answering this question myself with an alternative because there were no other answers

The way I managed to get the result I wanted is to just give up on the original first part of the question: "What I'd like to know is if it is possible at all to match and/or replace the results of parsing the nested tag (so what the nested tag outputs)" and just move along to the second part, "if that is not possible, is it possible to make the tag behave differently when nested inside a tag".

The way I did this is by defining a variable within the class, and then changing that whether I was doing a recursiveTagParse on the content of a or not. The code in Test.php would then be:

    public static function init( &$parser ) {
        $parser->setHook( 'testfoo', array( new self(), 'firstTag' ) );
        $parser->setHook( 'testbar', array( new self(), 'secondTag' ) );
        return true;
    }

    function firstTag($input, $attr = array(), $parser, $frame) {
        $this::$nested = true;
        $newinput = $parser->recursiveTagParse($input);
        $this::$nested = false;
        return preg_match_all("/ /", $newinput);
    }

    function secondTag($input, $attr = array(), $parser, $frame) {
        if ($this::$nested) {
            $output = 'Display for when nested'.$input;
        } else {
            $output = 'Display for when not nested'.$input;
        }
        return htmlspecialchars($output);
    }
}

That way I was still able to make the <testbar> tag behave differently when inside the <testfoo> tag. I'm not sure if this is the way it's supposed to be done, but it works.

PS: I've also ignored the $frame->newChild() code, since that didn't seem to work, and no clear documentation or examples were available.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top