bez/zfview-bundle

Multi-step layouts and view helpers for Symfony2 via Zend\View component

Installs: 7

Dependents: 0

Stars: 3

Watchers: 2

Forks: 1

Language: PHP

v0.1.0 2014-01-22 16:50 UTC

README

Brings the Zend\View templating paradigm of composite views and view helpers within your Symfony2 project.

2014-01-22 update:

  • $container->get('templating')->renderResponse('path/to/template.phtml', array $vars) should now be working as expected.
  • Layout can now be set from within templates.

Installation

You can install this bundle via Composer:

php composer.phar require bez/zfview-bundle:v0.1.0

Register the bundle in app/AppKernel.php:

<?php
class AppKernel extends Kernel
{

    public function registerBundles()
    {
        $bundles = array(
            /* ... */
            new Bez\ZfViewBundle\ZfViewBundle(),
        );

        /* ... */

        return $bundles;
    }

Add "zf_view" to the templating engines in your config.yml:

framework:
    templating:
        engines: [ 'twig', 'zf_view' ]

Defining Templates and Layouts

Define the template and the layout to use using the @Bez\ZfViewBundle\Configuration\Rendering annotation.

<?php

namespace FooBundle\Controller;

use Bez\ZfViewBundle\Configuration\Rendering;

/**
 *
 * @Rendering(layout="FooBundle::layout.phtml")
 */
class SomeController extends Controller
{
    /**
     * @Rendering("FooBundle:Some:some.phtml")
     */
    public function someAction($name)
    {
        return array(
            'name' => $name,
        );
    }

    /**
     * @Rendering()
     * 
     * The template name will guessed if none is specified. 
     * In this example, FooBundle:Some:baz.phtml will be used.
     */
    public function bazAction()
    {
        return array();
    }
}

In src/FooBundle/Resources/views/Some/some.phtml:

Hello <?php echo $this->name; ?>!

Child views -- in this case, src/FooBundle/Resources/views/Some/some.phtml -- are evaluated before the parent layouts. The output is captured to the $this->content variable and thus can be injected into the layout as follows:

In src/FooBundle/Resources/layout.phtml

<html>
    <head>...</head>
    <body>
        <div class="container">
            <?php

                echo $this->content;

            ?>
        </div>
    </body>
</html>

The fact that child views are evaluated first is very significant. This allows child views to modify elements (i.e., stylesheets, scripts, menus, etc.) in the parent layout by means of view helpers.

Overriding rendering options

Layouts can also be defined within the @Rendering annotation in a method and will take precedence:

<?php

    /**
     * @Rendering("FooBundle:Some:other.phtml", layout="FooBundle::secondary.phtml")
     */
    public function otherAction($name)
    {
        return array(
            'name' => $name,
        );
    }

You can also set layout to "none" to disable a layout if one is defined at the class level. This will simply render the template without wrapping it any layout:

<?php

/**
 * @Rendering(layout="::base.phtml")
 */
class FooController
{
    /**
     * @Rendering("FooBundle:Foo:bar.phtml", layout="none")
     */
    public function barAction()
    {
        return array();
    }
}

Defining the layout within templates

This is certainly useful when you wish to substitute templates used by third-party bundles through your application configuration. Declaring layouts in this manner will override any rendering configuration on the controller that are set via annotations.

In your template file:

<?php

/* path/to/some.phtml */

$this->layout('FooBundle::responsive.phtml'); //Define the layout file to use.

$this->placeholder('sidebar')->captureStart();

    /* Display stuff */

$this->placeholder('sidebar')->captureEnd();

Template names

As you can see in the above examples, you can omit the format part in naming your phtml templates. That is, FooBundle:Controller:template.phtml is equivalent to FooBundle:Controller:template.html.phtml.

The bundle will look for bundle:controller:name.format.phtml or bundle:controller:name.phtml and will use whichever exists.

Explicit view composition

Returning a pre-configured ViewModel is also possible:

use Zend\View\Model\ViewModel;

class DefaultController
{
    public function indexAction()
    {
        $content = new ViewModel();
        $content->setTemplate('FooBundle:Default:index.phtml')
                ->setCaptureTo('content'); //Default.

        $sideBar = new ViewModel();
        $sideBar->setTemplate('FooBundle::sidebar.phtml');
        $sideBar->setCaptureTo('sidebar'); //This child-view will be outputted via $this->sidebar in the parent view.

        $layout = new ViewModel();
        $layout->setTemplate('FooBundle::layout.phtml');
        $layout->addChild($content);
        $layout->addChild($sideBar);

        return $layout;
    }
}

View Helpers

Learn more about view helpers here: View helpers documentation

Contributing

Contributions are very welcome!

No unit tests yet.