thephpleague / plates

Native PHP template system
https://platesphp.com
MIT License
1.47k stars 180 forks source link

how to avoid undefined variable? #60

Closed badpenguin closed 7 years ago

badpenguin commented 9 years ago

I've create an extension of mine to automatically handle missing variables and replacing them with a default value, i.e.

$this->plate->registerFunction('default', [$this, 'extension_default']);

    function extension_default($var,$def='') {
        if (isset($var)) return $var;
        return $def;
    }

however when using the code in the template i still getting an error message abount the variable being undefined:

<html lang="<?=$this->default($page_lang,'en')?>">

avoidable with @:

<html lang="<?=@$this->default($page_lang,'en')?>">

Is there a better alternative way to fill up my page with all of those @$this->default() calls?

reinink commented 9 years ago

The reason is because you are still passing $page_lang to the default() function, which will throw an error in your template already, not in your extension method.

This would be the perfect situation to use the new isset ternary syntax coming in PHP7, which wouldn't even require a custom extension:

<html lang="<?=$page_lang ?: 'en'?>">

What you need to do is check if the variable exists within your extension. However, this is currently not possible, since the $template->data parameter is protected, and there is no data access method. This is a bit of an oversight on my part, so I'm going to leave this issue open and actually add this functionality to Plates.

When that is ready, you'll be able to do something like this:

<?php

use League\Plates\Engine;
use League\Plates\Extension\ExtensionInterface;

class MyExtension implements ExtensionInterface
{
    public $template;

    public function register(Engine $engine)
    {
        $this->plate->registerFunction('default', [$this, 'extension_default']);
    }

    function extension_default($var, $def = '')
    {
        $data = $this->template->data();

        if (isset($data[$var])) {
            return $data[$var];
        }

        return $def;
    }
}

And then in your templates:

<html lang="<?=$this->default('page_lang, 'en')?>">
electricjones commented 9 years ago

If you haven't already tackled this, I'd be happy to tackle this. With tests and all

electricjones commented 9 years ago

I've submitted a pull request #66

jenolan commented 9 years ago

Hi any eta for this patch to be included I just whacked my head on it ;-)

electricjones commented 9 years ago

Nothing to do with the PR, but I love your avatar @jenolan

jenolan commented 9 years ago

FWIW I avoided this issue by adding some extra processing....

Re the Avatar I have a lot less hair now ;-)

reinink commented 9 years ago

Sorry for the delay folks. Hoping to have some time to dedicate to my open source projects really soon (within the next couple weeks).

reinink commented 7 years ago

You can now access template data from extensions using the data() method: c9d654e5f8939bc37161b5ecaf2504e26f7536d2