The Mojavi 3 Book/Tutorials/Decorator Profiling
Prerequisites
[edit | edit source]Before reading this tutorial, one should introduce themself to the ((Global Templating - The Decorator Pattern Tutorial)(Tutorials)). Before reading this tutorial, one should introduce themself to the ((http://wiki.mojavi.org:81/159.html)(Global Templating Tutorial)).
++ Profiling
++ Profiling
Decorator profiling is a simple idea: Separate your different arrangements of Decorator template, and populators, into scripts that make those calls automatically.
Decorator profiling is a simple idea: Separate your different arrangements of Decorator template, and populators, into scripts that make those calls automatically. To begin, let us take a look, evolutionarily, how one might separate the different display modes, or profiles, from the actual views.
++ Stage 1: Hardcode
In this example, a simple example of direct decoration of templates, does it's job. But it fails to provide a simple means for replicating this pattern of decorator/slot population in other Views without a copy/paste. // 1 ka ans kya h?
Example 1: Hardcoded decorator information
[edit | edit source]class IndexSuccessView extends PHPView
{
public function execute ()
{
// set our template
$this->setTemplate('IndexSuccess.php');
//setup our decorator template
$this->setDecoratorDirectory(MO_TEMPLATE_DIR);
$this->setDecoratorTemplate('myGlobalTemplate.php');
//setup our slots
//(SlotName, Module, Action)
$this->setSlot('menu', 'Content', 'PopulateMenu');
$this->setSlot('css', 'Content', 'PopulateCss');
// set the title
$this->setAttribute('title', 'Default Action');
}
}
++ Step 2: Include
The second stage of abstraction is to create a separate script (a separate php file) and directly include it into your Views - eliminating copied code.
Example 2: Included decorator information
[edit | edit source]class IndexSuccessView extends PHPView
{
public function execute ()
{
// set our template
$this->setTemplate('IndexSuccess.php');
// set the title
$this->setAttribute('title', 'Default Action');
//get our profile
require(MO_TEMPLATE_DIR . '/profiles/Default.profile.php');
}
}
As you can see, all the decorator calls have been removed, and an include place in their stead. The include file is below:
Example Profile: Default.profile.php
[edit | edit source]<?php
//setup our decorator template
$this->setDecoratorDirectory(MO_TEMPLATE_DIR);
$this->setDecoratorTemplate('myGlobalTemplate.php');
//setup our slots
$this->setSlot('menu', 'Content', 'PopulateMenu');
$this->setSlot('css', 'Content', 'PopulateCss');
?>
++ Step 3: =setProfile()=
The last stage, or what I would propose, is to create a simple method that loads our profiles for us, and perhaps provides with a few other utility functions such as
hasProfile()
loadProfile() or setProfile()
Example 3: Included decorator information
[edit | edit source]class IndexSuccessView extends PHPView
{
public function execute ()
{
// set our template
$this->setTemplate('IndexSuccess.php');
// set the title
$this->setAttribute('title', 'Default Action');
//get our profile
$this->setProfile('Default');
}
}
++ The =setProfile()= Method
Don't be deceived, the =setProfile()= method and the include method are, in the end, equivalent. One requires one more function call than the other, but I believe that the simplicity of the =setProfile()= makes it superior, along with providing automatic detection of profiles, and automatically searching in the proper directories (The directories that would store profiles, I suppose, would be MO_TEMPLATE_DIR/templates/profiles/).
Example 4: The setProfile() method
[edit | edit source]Note: This function is untested and may contain errors.
public function setProfile($name, $module = null)
{
//is the module null?
if($module === null)
{
//set the directory to the global profile directory
$dir = MO_TEMPLATE_DIR . '/profiles';
}
else
{
//set the directory to the module profile directory
$dir = MO_MODULE_DIR . '/' . $module . '/templates/profiles';
}
//setup the profile path
$profile = $dir . '/' . $name . '.profile.php';
//can we read it?
if(is_readable($profile))
{
//get the file
require($profile);
//set the profile up
$this->profile = $name;
return true;
}
else
{
//profile failed, set null
$this->profile = null;
return false;
}
}
The member variable =$profile= will allow for a check to be run during View's preRenderCheck()