thephpleague / plates

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

Add 'parent' method #1

Closed doorhinge closed 10 years ago

doorhinge commented 10 years ago

It would be awesome to have a method similar to Twig's parent method: http://twig.sensiolabs.org/doc/functions/parent.html.

reinink commented 10 years ago

Replicating Twig's functionally isn't always easy in native PHP. A compiled language (like Twig) has the advantage of full visibility of an entire template before rendering it. Native PHP (like Plates) on the other hand have to be creative with output buffering and includes, and the order becomes important.

In this case the layout (parent) template is rendered after the current template, meaning its content isn't available to the current template, and generally this is a good thing.

You can however still get this sort of functionality with Plates. Here's how:

The layout template

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title><?=$this->title?></title>
</head>

<body>

<div id="content">
    <?=$this->content?>
</div>

<?php if (isset($this->sidebar)): ?>

    <div id="sidebar">

        <?=$this->sidebar?>

        <?php if (isset($this->showSidebarDefault) and $this->showSidebarDefault === true): ?>
            <p>Some default sidebar content</p>
        <?php endif ?>

    </div>

<?php endif ?>

</body>
</html>

The page template

<?php $this->layout('template') ?>

<?php $this->title = 'User Profile' ?>

<?php $this->start('content') ?>
    <h1>Welcome!</h1>
    <p>Welcome, <?=$this->e($this->name)?></p>
<?php $this->end() ?>

<?php $this->start('sidebar') ?>
    <ul>
        <li><a href="/link">Example Link</a></li>
        <li><a href="/link">Example Link</a></li>
        <li><a href="/link">Example Link</a></li>
        <li><a href="/link">Example Link</a></li>
        <li><a href="/link">Example Link</a></li>
    </ul>

    <?php $this->showSidebarDefault = true ?>

<?php $this->end() ?>
doorhinge commented 10 years ago

:+1:

morphsteve commented 10 years ago

I have achieved this in pure PHP before, but it would require a change in the order templates are rendered (I think, not too familiar with the source yet) and possibly to the way sections are stored.

The solution is to render the parent template first. When a child template starts a section, any existing content for that section is moved to a 'discarded' pile. It is then easy to provide a 'parent' or 'inherit' method to recover that and insert it at the given location.

What are the advantages of not making a parent's content available to children?