Quite often the task of generating a set of complex web pages arises, particluraly when application pages share common design and contain several dynamic content blocks, some of which may be the same for all such pages or only for some of them. For example, pages, regardless of their main content, which must contain the dynamically generated menu of the currently active section and the latest news list.
To facilitate implementation of such tasks, the framework offers the layout mechanism.
General concept
Layout is the main structural template which contains areas where HTML code generated by different actions is dynamically included. One of these areas is considered as default and is filled with the content generated by the action or controller, which was called to process the user request. In other words, the main areas where the page content is displayed. Actions used to fill the remaining content areas are called directly from within the layout.
Layouts get connected to actions and controllers in addition to templates. The action/controller to which a layout has been connected transfers control over the final web page rendering to the layout. The layout receives the HTML code generated using the action's template and inserts it into the main content area of the resulting page. To fill the remaining dynamic blocks, the layout calls other actions specified in the code of the layout class.
Each layout consists of two files:
- a template file containing the basic HTML markup
- a PHP class file containing the code of actions, which are called to fill additional dynamic blocks.
Simple example
A classic scheme with a common page layout with two dynamic blocks:
- menu on the left (
$sidebar
) - main content area (
$content
).
Layout template files must reside inside application directory templates/layouts/
.
The name of a template file must be the same as that of the corresponding template name.
Let us name a layout Default and create template file
templates/layouts/Default.html
for it:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>{$wa->appName()} — {$wa->accountName()}</title> {$wa->css()} <script type="text/javascript" src="{$wa_url}wa-content/js/jquery/jquery-1.5.2.min.js"></script> </head> <body> <div id="wa"> {$wa->header()} <div id="wa-app"> <div class="sidebar left200px"> {$sidebar} </div> <div class="content left200px"> {$content} </div> </div> </div> </body> </html>
Variable $content
used in the template is a system one; it is automatically replaced with the execution result of the main action, when
a web page is generated by this layout.
The name of a layout class name must comply with the "lowerCamelCase" notation rules: {APP_ID}{Layout Name}Layout
.
The layout PHP class file must reside inside application directory lib/
(we recommend using a separate subdirectory for layout classes:
lib/layouts/
) and must be named in accordance with the rule
{class name without Layout suffix}.layout.php
.
Let us create layout class file dummyDefault.layout.php
. The layout class must extend system class waLayout
:
<?php class dummyDefaultLayout extends waLayout { // Defining template blocks public function execute() { // Execution result of action dummySidebarAction will be // accessible via variable $sidebar in the layout template $this->executeAction('sidebar', new dummySidebarAction()); } }
Now the layout can be attached to actions and controllers.
Layouts are available for classes waViewAction
, waViewActions
, waViewController
.
Here is how a layout is attached:
$this->setLayout(new dummyDefaultLayout());
With this line of code, the execution result of an action is inserted into the layout template instead of variable $content
and other
variables in the layout template are replaced with the code generated by the actions specified in the dummyDefaultLayout
layout class.
Layout use options
Below are described several practical tips on organizing and using layouts in an application.
Common layout for the entire application
All application pages have the same design layout; only the contents of the main page area are different.
Suppose all pages are implemented in separate classes extending waViewAction
. In order to avoid attaching the layout to each action, we
can override the default controller.
Some information about the default controller.
Even if no controller has been explicitly defined in an application, there is still a default controller in the system when an action class is called,
because an action never returns data directly to a browser — it saves its execution result to a variable. The rest is taken care of by the controller.
When no controller is specified, default controller waDefaultViewController
is used, which is informed by the system which action must be
executed.
The default controller can be overridden in an application by creating configuration file
wa-apps/{APP_ID}/lib/config/factories.php
with the following contents:
<?php return array( 'default_controller' => 'dummyViewController' );
Here dummyViewController
is the name of the default controller class.
If file factories.php
already exists in an application,
then simply add this line to it.
Controller class in this case extends waDefaultViewController
and must have the following structure:
<?php class dummyViewController extends waDefaultViewController { public function execute() { $this->setLayout(new dummyDefaultLayout()); parent::execute(); } }
Layout for a set of pages with simple logic
Suppose we have several sets of simple middle-sized pages where each set requires its own layout.
Pages have simple design; therefore, actions are based on class waViewActions
,
where individual actions are implemented as methods of a single class.
- Create the desired number of layouts.
- Create a separate action class extending
waViewActions
for each set of pages and specify the desired layout for the corresponding page set in methodpreExecute
:
<?php class dummyTestActions extends waViewActions { // This method is called before the execution of any action public function preExecute() { $this->setLayout(new dummyDefaultLayout()); } public function defaultAction() { ... } // template file templates/actions/test/TestPage1.html public function page1Action() { ... } // template file templates/actions/test/TestPage2.html public function page2Action() { ... } }
An individual layout for a single page
If individual layouts are required for several single application pages,
you can create separate controllers extending class waViewController
for each page:
<?php class dummyTestPageController extends waViewController { public function execute() { $this->setLayout(new dummyDefaultLayout()); $this->executeAction(new dummyTestPageAction()); } }