Sub views (layouts, templates) in Slim php framework

jfoucher picture jfoucher · Aug 10, 2011 · Viewed 23.5k times · Source

I'm trying out the Slim php framework

Is it possible to have layouts or sub views in Slim? I'd like to use a view file as a template with variables as placeholders for other views loaded separately.

How would I do that?

Answer

josh anyan picture josh anyan · Oct 29, 2011

filename: myview.php

<?php
class myview extends Slim_View
{
    static protected $_layout = NULL;
    public static function set_layout($layout=NULL)
    {
        self::$_layout = $layout;
    }
    public function render( $template ) {
        extract($this->data);
        $templatePath = $this->getTemplatesDirectory() . '/' . ltrim($template, '/');
        if ( !file_exists($templatePath) ) {
            throw new RuntimeException('View cannot render template `' . $templatePath . '`. Template does not exist.');
        }
        ob_start();
        require $templatePath;
        $html = ob_get_clean();
        return $this->_render_layout($html);
    }
    public function _render_layout($_html)
    {
        if(self::$_layout !== NULL)
        {
            $layout_path = $this->getTemplatesDirectory() . '/' . ltrim(self::$_layout, '/');
            if ( !file_exists($layout_path) ) {
                throw new RuntimeException('View cannot render layout `' . $layout_path . '`. Layout does not exist.');
            }
            ob_start();
            require $layout_path;
            $_html = ob_get_clean();
        }
        return $_html;
    }

}
?>

example index.php:

<?php
require 'Slim/Slim.php';
require 'myview.php';

// instantiate my custom view
$myview = new myview();

// seems you need to specify during construction
$app = new Slim(array('view' => $myview));

// specify the a default layout
myview::set_layout('default_layout.php');

$app->get('/', function() use ($app) {
    // you can override the layout for a particular route
    // myview::set_layout('index_layout.php');
    $app->render('index.php',array());
});

$app->run();
?>

default_layout.php:

<html>
    <head>
        <title>My Title</title>
    </head>
    <body>
        <!-- $_html contains the output from the view -->
        <?= $_html ?>
    </body>
</html>