Delayed rendering feature #73

Open
velosipedist opened this Issue Feb 22, 2015 · 4 comments

Projects

None yet

3 participants

@velosipedist

Here is an idea, how to avoid default section value overhead for that cases:

// somewhere in template
print $this->section('name', $this->fetch('default-template-name', [/* params maybe */]));

The fetch() call calls unnecessary rendering procedure immediately.

What if pass an array or callback as default value (instead of direct fetch()), and later, on section() call process possible section values like following (my own override from real project):

protected function section($name, $default = null)
    {
        if (isset($this->sections[$name]) && !is_string($this->sections[$name])) {
            // not rendered yet
            $section = $this->sections[$name];
            if ($section instanceof \Closure) {
                // we may even give hook for inject context params at sub-implementations, if needed :)
                $this->sections[$name] = (string)$section();
                return $this->sections[$name];
            } elseif (is_array($section)) {
                list($template, $data) = $section;
                $this->sections[$name] = $this->render($template, (array)$data);
                return $this->sections[$name];
            }
        }
        // if rendered, give ready string back
        return parent::section($name, $default);
    }
@ragboyjr
Contributor

Ya, this is a good feature, you should submit a PR for this.

@reinink
Member
reinink commented Dec 27, 2016

The idea behind the default value for sections was really more intended for inline short hand, such as:

<title><?=$this->section('title', 'The default title')?></title>

For more complex defaults, I sort of feel like a simple if statement is a better approach, similar to what we have in the Plates documentation:

<html>
<head>
    <title><?=$this->e($title)?></title>
</head>
<body>

<img src="logo.png">

<div id="page">
    <?=$this->section('page')?>
</div>

<div id="sidebar">
    <?php if ($this->section('sidebar')): ?>
        <?=$this->section('sidebar')?>
    <?php else: ?>
        <?=$this->fetch('default-sidebar')?>
    <?php endif ?>
</div>

</body>
</html>

That avoids rendering the default-sidebar unless no sidebar section has been set.

@reinink
Member
reinink commented Dec 27, 2016

That being said, it would be interesting to make the section default also accept a template name, in addition to only a string. That default template would only be rendered in the event that no section was found.

But how do we identify that a default template was provided and not just some string to output? We could:

  1. Check to see if the string provided resolves to a template, and if it does render it.
    $this->section('sidebar', 'default-sidebar', ['some' => 'data']);
  2. Append a value to indicate that this is a template, not a string.
    $this->section('sidebar', 'template:default-sidebar', ['some' => 'data']);
  3. Assume this is a template if data is provided (meaning you need the 3rd param even if you don't have any data)
    // with data:
    $this->section('sidebar', 'default-sidebar', ['some' => 'data']);
    // without data:
    $this->section('sidebar', 'default-sidebar', []);
@velosipedist

@reinink in my experience i rarely had to specify just default string, maybe solution 3 is most useful with some fallback extension:

// default template
$this->section('sidebar', 'default-sidebar', ['some' => 'data']);
// default string
$this->section('sidebar')->or('No sidebar :(');

I think that is intuitive enough and makes unnecessary to specify empty data array.
Also or() can have alternative signature to pass also template name and params, so we can even leave strictly one param to section() call — ultimately transparent and intuitive.

// by prefix
$this->section('sidebar')->or('::template/name' /*, ['optional'=>'data']*/);
// separate method
$this->section('sidebar')->orTemplate('template/name' /*, ['optional'=>'data']*/);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment