开发者

ExpressionEngine templates: pass a plugin/module's output as parameter to another plugin/module

开发者 https://www.devze.com 2023-01-27 17:57 出处:网络
Here\'s basically what I want to accomplish: {exp:plugin1:method arg=\"{exp:plugin2:method}\"} I’ve tried a number of different approaches.

Here's basically what I want to accomplish:

{exp:plugin1:method arg="{exp:plugin2:method}"}

I’ve tried a number of different approaches.

Approach 1:

{exp:plugin1:method arg="{exp:plugin2:method}"}

Result: Plugin1->method’s arg parameter value is the string, {exp:plugin2:method}, and it’s never parsed.

Approach 2:

My understanding of the parsing order suggests that this might have different results, but apparently it does not.

{preload_replace:replaced="{exp:plugin2:method}"}
{exp:plugin1:method arg="{replaced}"}

Result: The arg parameter has the same value as approach 1.

Approach 3:

First I define a snippet (snip), whose content is:

{exp:plugin2:method}

Then in the template:

{exp:plugin1:method arg="{snip}"}

Result: Same as approaches 1 and 2.

Approach 4:

Noting that plugins are processed in th开发者_如何学Goe order they appear, I have even tested simply placing an instance of {exp:plugin2:method} before the {exp:plugin1:method} call. My thinking is that I could wrap this first call in a regex replacement plugin in order to suppress output, but that it would trigger Plugin2’s parsing first.

{exp:plugin2:method}
{exp:plugin1:method arg="{exp:plugin2:method}"}

Result: Plugin1->method’s arg parameter value is the temporary hash placeholder for Plugin2->method’s output (MD5 I believe) that the Template class reserves until later.


Interesting approach. However, this can be achieved more simply like this:

{exp:plugin1:method arg="{exp:plugin2:method}" parse="inward"}


I have a workaround, but I'll wait a while to see if a better solution comes up before I accept my own answer. The workaround is to wrap plugin1 with plugin2 and replace template tags referring to its methods within the tagdata. Note that this requires a parse="inward" parameter on the plugin2 call.

In the template:

{exp:plugin2 parse="inward"}
    {exp:plugin1:method arg="{someplugin2method}"}
{/exp:plugin2}

In the plugin class:

static $public_methods;

function __construct() {
    // Actual construction code omitted...

    if(($tagdata = $this->EE->TMPL->tagdata) !== false && trim($tagdata) !== '') {
        if(!isset(self::$public_methods)) {
            self::$public_methods = array();
            $methods = get_class_methods($this);
            foreach($methods as $method) {
                if($method == get_class($this) || $method == '__construct') {
                    continue;
                }
                $reflection = new ReflectionMethod(get_class($this), $method);
                if($reflection->isPublic()) {
                    self::$public_methods[] = $method;
                }
            }

            self::$public_methods = implode('|', self::$public_methods);
        }

        $tagdata = preg_replace_callback('/\{(' . self::$public_methods . ')\}/',
            array($this, 'tagdata_callback'), $tagdata);
        $this->return_data = $tagdata;
    }
}

private function tagdata_callback($matches) {
    $method = $matches[1];
    return $this->$method();
}

Caveats:

  • This can make for messier templates.
  • Maintaining a list of public methods apparently requires Reflection which is not available in PHP 4. You can, of course, maintain a list of expected methods manually.
0

精彩评论

暂无评论...
验证码 换一张
取 消