Chapter 8. Views and layouts

Table of Contents

Views
Helpers
Creating helpers
Using helpers
Layout
View contexts
Controlling views
View's filename extension
Do not render the view from the action
Modify the associated view from the action
Using a custom rendering engine
Rendering views programmatically

Views

Views are stored in the app/views directory. The file extension is by default phtml.

The content of a view file is, as the action file, free. It should mostly be text or HTML (or any presentation content, such as XML).

PHP can be used to print variables from the action or to provide presentation logic like loops.

Example 8.1. Example of a view

				
<html>
	<head>
		<title>Example</title>
	</head>
	<body>
		<?= $myPublicVariable; ?>
	</body>
</html>
			

Tip

If your configuration allows it, it is better to use php's short tags in views for better readibility.

Figure 8.1. A little schema to sum up!

A little schema to sum up!

Helpers

When creating your views, you'll often need to execute the same piece of logic many time. Formating a date for example. An helper is exactly that: a function that you can reuse in your views; format_date() for example.

Creating helpers

Helpers in Atomik are stored in app/helpers. Our format_date helper would be stored in app/helpers/format_date.php. The helpers directory can be changed using atomik/dirs/helpers.

You can then define your helper in two ways: as a function or a class. If you're using a function, just create one with the same name as the helper. For our format_date helper, the function would be format_date(). But you can also use a class which can be pretty useful for more complex ones. The class name is a camel case version (ie. without any underscores or spaces, all words starting with an upper case) of the helper name suffixed with Helper. In our example, it would be FormatDateHelper. This class also needs to have a method named like the helper name but in camel case and starting with a lower case. In this case, it would be formatDate().

Example 8.2. Creating an helper

As a function

					
function format_date($date)
{
	// do the formating
	return $date;
}
				

Or as a class

					
class FormatDateHelper
{
	public function formatDate($date)
	{
		// do the formating
		return $date;
	}
}
				

Using helpers

Helpers are callable from any file that is being rendered. That is to say views, layouts or any file rendered using Atomik::renderFile. They are accessible as methods of $this. Helpers are automatically loaded.

Note

Helpers are also available in the same way from actions, but there are meant to be use from views.

Example 8.3. Calling an helper

					
<span class="date"><?= $this->format_date('01-01-2009') ?></span>
				

Layout

It is common in websites that all pages share the same layout. Atomik allows you to define a layout that will be used with all views.

The layout will be rendered after the view has been rendered. The output of the view will be pass to the layout as a variable named $contentForLayout. Layouts are rendered the same way as views.

Layouts can be placed in the app/views or app/layouts directories. The file extension is the same as the one for views.

The layout name to use has to be defined in the app/layout configuration key. If the value is false (which is the default), no layout will be used.

The layout can be disabled at runtime by calling Atomik::disableLayout(). It can later be re-enabled by passing false as argument to the same method.

Example 8.4. Example layout

A layout file named _layout.phtml in the app/views directory.

				
<html>
	<head>
		<title>My website</title>
	</head>
	<body>
		<h1>My website</h1>
		<div id="content">
			<?= $contentForLayout; ?>
		</div>
	</body>
</html>
			

In the bootstrap file

				
Atomik::set('app/layout', '_layout');
			

Mutliple layouts can also be used. Just use an array instead of a string in the configuration key. Layouts will be rendered in reverse order (the first one in the array wrap the second, the second the third, ...).

View contexts

It is sometimes needed to return content in different formats. Rather than creating multiple actions doing the same thing, Atomik allows you to create a view for each content type. This is called view contexts. The correct view is rendered depending on the current context.

The context is defined using a route parameter. By default it is called format. This can be changed in app/views/context_param. As specified in the urls chapter, the format parameter is by default the file extension. Which means that using an url like index.xml will result in using the xml context.

The default view context is html but it can be changed in atomik/views/default_context.

To create a view for a context just suffix the view name with the context name like an extension. For example, let's say we have an article view. The filename for the xml context would be article.xml.phtml. Some context may not need any prefix like the html one.

Depending on the view context, the layout can be disabled and the response content-type can be changed. The file prefix can also be specified. All of this is done in app/views/contexts.

Example 8.5. Creating a custom view context

Let's create the rdf context.

				
Atomik::set('app/views/contexts/rdf', array(    // the context name, ie. the file extension in the url
	'prefix'        => 'rdf',                   // the view's file extension prefix (set to false for no prefix)
	'layout'        => false,                   // whether to enable the layout
	'content-type'  => 'application/xml+rdf'    // the response content type
));
			

Now you can call an url like http://example.com/article.rdf. In this case the view filename would be article.rdf.phtml, the layout would be disabled and the response content type would be application/xml+rdf.


If a view context is not defined under app/views/contexts, the file prefix will be the context name, the layout won't be disabled and the response content type will be text/html.

By default, four contexts are defined: html, ajax, xml and json. The ajax context is the same as html but with the layout disabled. The last two disable the layout and set the appropriate content type.

Controlling views

View's filename extension

The default filename's extension for views is phtml as said before. This can be change using the configuration key named app/views/file_extension.

Do not render the view from the action

While the action is executing, you may want to avoid rendering the associated view. This can easily be done by calling Atomik::noRender() from your action.

Modify the associated view from the action

While the action is executing, you may want to render a different view. In this case, you can use Atomik::setView() from your action. It takes as unique argument a view name.

Using a custom rendering engine

The default rendering process only uses php's include function. You may however want to use a template engine for example. This is possible by specifying a callback in the app/views/engine configuration key.

The callback will receive two parameters: the first one will be the filename and the second an array containing the view variables.

Example 8.6. Using a custom rendering engine

					
function myCustomRenderingEngine($filename, $vars)
{
	// your custom engine
	return $renderedContent;
}

Atomik::set('app/views/engine', 'myCustomRenderingEngine');
				

The custom rendering engine will be used whenever Atomik::render(), Atomik::renderFile() or Atomik::renderLayout() is used.

Rendering views programmatically

When executing a request, the action and/or the view associated to it are automatically called. You can however render other views using Atomik's API.

The most useful use of this it to render partial views, small part of presentation code that is reusable.

To render a view use the Atomik::render() method.

It takes as first argument the view name and optionally as second argument an array of key/value pairs representing variables. The method returns the view output.

Example 8.7. Rendering a view programmatically

				
$viewOutput = Atomik::render('myView');
$viewOutput = Atomik::render('myView', array('var' => 'value'));
			

It is also possible to render any file using Atomik::renderFile(). It takes as first parameter a filename. Variables can also be passed like with Atomik::render().

Note

You can also render contextual views by adding the file extension prefix to the view name.