Subviews
x:template gives you the possibility to combine multiple templates with ease.
Scenario
Imagine you are developing a content management system which offers an interface to create custom plug-ins. These plug-ins shall be displayed in a certain area of the site's main template.
To do so, we first have to declare in the main template where the plug-ins are going to be displayed. x:template offers you two ways to do it:
<xsub>-Tags
You can mark the positions in your main template with xsub-tags. When rendering the template these tags will be replaced by the plug-ins. Each tag identified via the name-attribute. This is what your main template might look like.
<!DOCTYPE html> <html> <head> <title>Main template</title> </head> <body> <div id="main"> <div id="content"> <xsub name="content" /> </div> <div id="sidebar"> <xsub name="sidebar" /> </div> </div> <xsub name="footer" /> </body> </html>
As you can see: I declare three positions in the template where plug-ins can be inserted. If you use the xsub-tags, assigned subviews will automatically be put into the template when rendering it.
Attach subviews via PHP
If you don't have access to the template file, you can select any element of your template and append the subviews it. In this case, this is what your template could look like.
<!DOCTYPE html> <html> <head> <title>Main template</title> </head> <body> <div id="main"> <div id="content"></div> <div id="sidebar"></div> </div> <div id="footer"></div> </body> </html>
Now you can use the attachSubViews-method of your view class to attach assigned subviews to certain element. This method expects in the first parameter a string containing a selector or any instance of XTemplate\Interfaces\NodeEdit. The second parameter is a string containing the name of the subviews. In opposite to the xsub-tags which will be replaced, the attachSubViews-method only appends the subviews to the selected element.
The following class shows you how you can use the method.
<?php /** * x:template - PHP based template engine * Copyright (c) 2011 - 2012 by Tobias Pohlen <tobias.pohlen@xtemplate.net> * * Released under the GPL License. * * @author Tobias Pohlen * @ignore */ // Load the x:template engine require_once "../../../Engine.php"; /** * This class demonstrates how to attach subviews to certain elements. * * @author Tobias Pohlen * @version $Id$ * @package xtemplate * @ignore */ class View extends XTemplate\ComfortView { const TEMPLATE = "template2.html"; protected function _render() { // Use the method with a selector string $this->attachSubViews("#content", "content"); // Use the method with any instance of Interfaces/NodeEdit $this->attachSubViews($this["#content"], "content"); $arrElements = $this->getElementsByTagName("div"); $this->attachSubViews($arrElements[0], "content"); } } ?>
Assign subviews
The only thing you still need to know is how to assign subviews to your view class. As you can expect, you can only assign instances of XTemplate\SubView. To do so, you can use the assignSubView([string] $name, [XTemplate\SubView] $subview). The first argument is the name of the subview area. The second argument is the subview instance. The assigned instances are stored in a list.
Example
This is a simple CMS example.
<?php /** * x:template - PHP based template engine * Copyright (c) 2011 - 2012 by Tobias Pohlen <tobias.pohlen@xtemplate.net> * * Released under the GPL License. * * @author Tobias Pohlen * @ignore */ // Load the x:template engine require_once "../../../Engine.php"; /** * This is the plug-in view which is the result of the rendered plug-in and shall be inserted into the main template * * @author Tobias Pohlen * @version $Id$ * @package xtemplate * @ignore */ class Plugin extends XTemplate\ComfortSubView { const TEMPLATE = "plugin.html"; protected function _render() { $this["%headline"] = $this->getDatas("headline"); $this["%content"] = $this->getDatas("content"); } protected function defineModelInterface() { $this->defModel("headline", "string", "No headline"); $this->defModel("content", "string", "No content"); } } ?>
<?php /** * x:template - PHP based template engine * Copyright (c) 2011 - 2012 by Tobias Pohlen <tobias.pohlen@xtemplate.net> * * Released under the GPL License. * * @author Tobias Pohlen * @ignore */ // Load the x:template engine require_once "../../../Engine.php"; /** * This is the main view class of the system. * * @author Tobias Pohlen * @version $Id$ * @package xtemplate * @ignore */ class Main extends XTemplate\ComfortView { const TEMPLATE = "main.html"; protected function _render() { // No need to perform any operation here, since we use the xsub-tags. } } ?>
<!DOCTYPE html> <html> <head> <title>Main template</title> <style type="text/css"> #content { float: left; width: 70%; } #sidebar { float: left; width: 25%; margin-left: 5%; } </style> </head> <body> <div id="main"> <div id="content"> <xsub name="content" /> </div> <div id="sidebar"> <xsub name="sidebar" /> </div> </div> </body> </html>
<?php /** * x:template - PHP based template engine * Copyright (c) 2011 - 2012 by Tobias Pohlen <tobias.pohlen@xtemplate.net> * * Released under the GPL License. * * @author Tobias Pohlen * @ignore */ require 'Main.php'; require 'Plugin.php'; // Create the main view instance $objMain = new Main; // Use some random datas $arrDatas = array( array("Demo headline 1", "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor."), array("Demo headline 2", "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor."), array("Demo headline 3", "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor."), ); foreach ($arrDatas as $arrCurrentData) { // Create the subview instace $objSubView = new Plugin; $objSubView->assign("headline", $arrCurrentData[0])->assign("content", $arrCurrentData[1]); // Assign the subview to the main view $objMain->assignSubView("sidebar", $objSubView); } // Create the main content $objSubView = new Plugin; $objSubView ->assign("headline", "This is the main content") ->assign("content", "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor."); $objMain->assignSubView("content", $objSubView); // Render the template echo $objMain; ?>
This is the result:
Subviews and sections
This subview-functionality is defined by the XTemplate\Interfaces\SubView-interface. As you can see when you look at the engine classes, it is also implemented by the Section-class. But please remember: If you work with a xsub-tag nested in a section, you have to assign the subview instances to every section clone.