Bullet comes with full PHP template support that can be used to render basic PHP files as templates with some nice enhancements and features bundled in.
Before Bullet can know how to render your templates, you have to let Bullet
know where they are. If you want to use layouts, Bullet has to know where those
are too. Template support can be configured with a simple array when creating
the main Bullet\App
object:
$app = new Bullet\App(array( 'template' => array( 'path' => __DIR__ . '/templates/', 'path_layouts' => __DIR__ . '/templates/layout/', 'auto_layout' => 'application' ) ));
The auto_layout
flag, if set to a string, will automatically wrap all templates
in a layout file of the same name if no other layout is specified. So in this
example, a layout file would have to exist at src/templates/layout/application.html.php
.
If you don’t want this behavior, set the flag to boolean false
or simply remove
it (it is off by default).
Bullet has a built-in helper method template
for rendering templates as HTTP
responses from routes:
$app->path('/', function($request) use($app) { return $app->template('hello', array('name' => 'World')); });
Note that you are using return
instead of echo
or print
. This is an important
feature of Bullet. Every route should respond with a valid response type, and
the Bullet\View\Template
object is actually a valid HTTP response that knows
how to render itself on-demand. This means that you are returning a template
object, and not a rendered chunk of content. This allows you to further
manipulate the response and alter it in events and nested
sub-requests, even after this route is matched and executed.
Here is a more full-featured example of template usage, just so you can see all
the options that are available to you. The header
and status
methods come
from the Bullet\Request
object that the template object extends (a template
is literally a form of an HTTP response in Bullet).
$app->path('/', function($request) use($app) { return $app->template('hello') ->set(array('name' => 'World')) ->layout('auth') ->format('xml') // makes it xml.php instead of html.php ->header('Content-Type', 'text/xml') ->status(200); });
Templates will have local variables set that match the names of the variables
that are passed to them. The ->set(array('name' => 'World'))
call will make
the variable $name
available inside the template.
src/templates/hello.html.php
<p>Hello, <?php echo $name; ?>!</p>
Layouts have a special variable $yield
that holds the template content. You
can use this variable to render the template content inside your layout
wherever you want it to go.
src/templates/layouts/auth.html.php
<html> <head> <title>Hello World</title> </head> <body> <div> <?php echo $yield; ?> </div> </body> </html>
Often you will need to include assets like CSS and JavaScript files or other
content within template files that need to be made available in layouts. Blocks
allow you to achieve this. Content can be added to blocks using 3 different
methods, depending on your desired result: content
, append
, and prepend
.
Templates can define blocks with content (without an echo
statement) that
will be set in the block content and then later rendered in the layout or
another template that it is nested in. Note that content
will clear any
previously set content, so if you want to add a stack of things to a block
from several different templates, use append
or prepend
instead.
src/templates/awesome.html.php
<p>I need a custom javascript on this page because it's awesome.</p> <?php $view->block('js')->content(function() { ?> <script type="text/javascript" src="http://www.cornify.com/js/cornify.js"></script> <?php }); ?>
This layout prints the content of two blocks - one named css
and one named
js
. The css
block uses prepend with the global site styles so that the
content defined here will appear before any other content added by templates.
src/templates/layouts/application.html.php
<html> <head> <title>Hello World</title> <?php echo $view->block('css')->prepend(function() { ?> <style type="text/css" href="/assets/styles/site.css" /> <?php }); ?> </head> <body> <div> <?php echo $yield; ?> </div> <?php echo $view->block('js'); ?> </body> </html>Note that the block does not have to be defined beforehand for the set content to be displayed. In this example, the
css
block is never used first in the
template, but the content set here will be displayed normally without errors.