[eluser]wiredesignz[/eluser]
Code: <?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Template Engine.
*
* Has 2 modes of use:
* 1: Using a container template with template parts (blocks) inside.
* 2: Using template parts only (header,content,footer. etc).
*
* Allows any data part to be re-assigned to all parts (global data).
* Allows a template source directory to be specified.
* Can be used with Matchbox modules.
*
* In future: Output could render PDF files from HTML content.
*/
class Template
{
var $file, $data;
/**
* Constructor
*
* @param string the file name of the template to load
*/
function Template($file = null)
{
$this->file = $file;
$this->data = array
(
'module' => null, // use with Matchbox modules
'directory' => null,
);
}
/**
* Assign data to this template object.
*
* @param string
* @param array or string
*/
function assign($key, $value = null)
{
if (is_array($key))
{
foreach ($key as $k => $v)
{
$this->data[$k] = $v;
}
}
else
{
$this->data[$key] = $value;
}
}
/**
* Assign data to a specific template object.
*
* @param string
* @param string
* @param array or string
*/
function assign_to($tpl, $key, $value = null)
{
$this->data[$tpl]->assign($key, $value);
}
/**
* Assign data to all template objects.
*
* @param string
* @param array or string
*/
function assign_global($key, $value = null)
{
foreach ($this->data as $k => $v) // iterate through data
{
if (get_class($v) == 'Template') // if data is template object
{
$v->assign($key, $value); // assign to it
}
}
$this->assign($key, $value); // assign to this template also
}
/**
* Assign new template object parts to this template.
*
* @param string
* @param array or string
*/
function assign_tpl($tpl, $file = null)
{
if (is_array($tpl))
{
foreach ($tpl as $k => $v)
{
$this->assign($k, new Template($v));
}
}
else
{
$this->assign($tpl, new Template($file));
}
}
/**
* fetch a specific template data value.
*
* @param string the template name
* @param string the data key
* @return string
*/
function fetch($tpl, $key)
{
return $this->data[$tpl]->data[$key];
}
/**
* Build the HTML output.
*
* @param bool set the output mode
* @return string the rendered template
*/
function render($return = FALSE)
{
foreach ($this->data as $k => $v) // iterate through data
{
if (get_class($v) == 'Template') // if data is template object
{
$this->data[$k] = $v->out(TRUE); // render it
if (!$this->file) echo $this->data[$k]; // output the part
}
}
if ($this->file) return $this->out($return);
}
/**
* render this template.
*
* @param bool set the output mode
* @return string the rendered template
*/
function out($return = FALSE)
{
$CI = & get_instance();
return $CI->load->view($this->data['directory'].$this->file, $this->data, $return, $this->data['module']);
}
}
UPDATED:
Added fetch() - template data.
Added assign_to() - assign data to a specific template
[eluser]wiredesignz[/eluser]
Usage: Rendering page parts only
Autoload library template.php
Code: $this->template->assign_tpl( array(
'header' => 'header', // name of the content part => file name to load
'header_write' => 'header_write',
'sidebar' => 'sidebar_posts_form',
'editorjs' => 'editorjs',
'posts_form' => 'posts_form',
'footer' => 'footer',
));
$this->template->assign_global( array( // all the above parts have access to this data
'postid' => $this->postID,
'users' => $users,
'categories' => $categories,
'writestyle' => "active",
'writepostsstyle' => "active",
'pagetitle' => "Administration Panel - Manage Posts",
'categoryids' => $categoryids,
'directory' => 'admin/', // the template source directory
));
$this->template->render();
[eluser]wiredesignz[/eluser]
Usage: Rendering page parts within container template.
Autoload library template.php
Code: $base_nav = new Template('nav'); // navigation template part
$base_nav->assign('some', $data);
$content = new Template('content'); // content template part
$content->assign('some', $data);
$this->template->file = 'main_view'; // container template
$this->template->assign(array(
'base_nav' => $base_nav,
'content' => $content,
));
$this->template->render();
With the template library autoloaded page parts can be assigned to the template object from within controllers or models.
[eluser]wiredesignz[/eluser]
Usage: Rendering different page parts in different Controller methods.
Autoload library template.php
Code: function index()
{
$indexView = new Template('index');
$indexView->assign( array(
"blogtitle" => $this->blogTitle,
"blogdescription" => $this->blogDescription,
"categories" => $this->categories,
"pages" => $this->pages,
"blogroll" => $this->blogroll,
"posts" => $this->posts,
"page" => $this->page,
"numpages" => $this->mdl_posts->numpages,
"prevpage" => $this->prevpage,
"nextpage" => $this->nextpage,
"nav" => $this->nav
));
$this->_final_out($indexView);
}
function _final_out($contentView)
{
$this->template->assign_tpl( array(
'header' => 'header',
'sidebar' => 'sidebar',
'content' => 'content',
'footer' => 'footer',
));
$this->template->assign('content', $contentView); // re-assign the content part
$this->template->assign_global($contentView->data); // assign as global data
$this->template->assign_global('directory', $directoryName); // add template directory
$this->template->render();
}
[eluser]wiredesignz[/eluser]
Updated: See first post.
Added fetch()
Added assign_to()
Code: $title = $this->template->fetch('content','page_title');
$title .= 'Website name';
$this->template->assign_to('header', 'site_title', $title);
[eluser]ralf57[/eluser]
Thank you for your contribution.
Please also add a dedicated page in the wiki and provide some documentation.
CI story shows how a clean documentation can lead to success ;-)
[eluser]sophistry[/eluser]
thanks for the contribution!
as well as adding some short instructions for usage, could you add some information on how this approach is different from and/or the same as and/or better than other view libraries (and related solutions) detailed in the FAQ section on view libraries?
that would really help differentiate your approach. i've added this forum post to the FAQ already.
|