Guru Forum - Aliro, PHP, Mambo, Joomla, ...


Reply
 
Thread Tools Display Modes
  #1  
Old November 1st, 2007, 08:43 AM
counterpoint counterpoint is offline
Administrator
 
Join Date: Jun 2007
Posts: 200
Default Template base class to ease development

To simplify the development of templates for Aliro, I've written a base template class so that all standard logic can be removed from actual templates. The base class is used by writing a template as a class that extends aliroUserTemplateBase (or on the admin side, aliroAdminTemplateBase).

For anyone who has a basic understanding of Mambo or Joomla templates, the key thing to Aliro templates is that screen areas are actual objects instead of being merely names. Screen areas relate to things that might be more familiar as "left", "right", "banner" etc. It is the template's responsibiity to define the key parameters for the screen areas - the base class will create the actual objects.

Building on the greater functionality of screen areas, a call is made to the template as module output for a particular area is being pieced together. Older systems have included code in the core that wrapped HTML around each individual module's output, with choices determined by parameters. This seems the wrong approach when the template should have complete freedom to determine what HTML should be wrapped round module output. Aliro aims to avoid building HTML into the core, especially where styling is involved. So the call to wrap (or do nothing) for each module is to a template method that has a suffix matching the information in the screen areas table created by the template. That is, the template decides which of its own methods should be called for modules in each of the screen areas defined by the template. Doing it is easier than saying it!

A shift of emphasis in terms of Aliro best practice is that I strongly believe that screen areas should have functional (not positional) names, such as "navigation" rather than "left". The reason for this is obvious - there are plenty of templates that implement the "left" screen area towards the right hand side of the screen!

To illustrate the result, here is the latest code for the Aliro template derived from Water & Stone:
PHP Code:
class waterandstone extends aliroUserTemplateBase implements ifAliroTemplate {

    public function 
__construct () {
        
$this->areas = array (
        array (
'position' => 'topmenu',        'min' => 519'max' => 519'style' => 1),
        array (
'position' => 'navigation',    'min' => 200'max' => 200'style' => 0),
        array (
'position' => 'user1',         'min' => 259'max' => 259'style' => 0),
        array (
'position' => 'feature1',    'min' => 259'max' => 259'style' => 0),
        array (
'position' => 'feature2',    'min' => 200'max' => 200'style' => 0),
        array (
'position' => 'searchbox',     'min' => 800'max' => 800'style' => 0),
        array (
'position' => 'newsflash',     'min' => 200'max' => 200'style' => 0),
        array (
'position' => 'extra',         'min' => 200'max' => 200'style' => 0),
        array (
'position' => 'user4',         'min' => 200'max' => 200'style' => 0),
        array (
'position' => 'banner',         'min' => 468'max' => 468'style' => 0),
        array (
'position' => 'debug',         'min' => 400'max' => 400'style' => 1)
        );
        
// All the Aliro error levels must have matching colour classes, with definitions in the CSS
        
$this->colours = array (
        
_ALIRO_ERROR_FATAL => 'fatalcolour',
        
_ALIRO_ERROR_SEVERE => 'severecolour',
        
_ALIRO_ERROR_WARN => 'warncolour',
        
_ALIRO_ERROR_INFORM => 'informcolour'
        
);
        
parent::__construct();
    }

    public static function 
defaultModulePosition () {
        return 
'extra';
    }

    
// Define the HTML for an error message
    
protected function oneErrorMessage ($colour$text) {
        return <<<ONE_ERROR_MESSAGE
                            <div class="$colour">
                                $text
                            </div>
ONE_ERROR_MESSAGE;

    }

    
// Define the HTML for the whole set of error messages
    
protected function errorSet ($errorsHTML) {
            return <<<FULL_MESSAGE_SET
                    <!-- start Error Message area -->
                    <div id="errormessage">
                        $errorsHTML
                    </div>
                    <!-- end Error Message area -->
FULL_MESSAGE_SET;

    }

    
// These "style" methods are invoked by the module handler as modules are processed
    // Their function is to place any required HTML around the content created by the module
    // The digit on the end relates to the style number for a screen area
    
public function moduleStyle0 ($moduleclass_sfx$title$content) {
        
$html =  "<table cellpadding=\"0\" cellspacing=\"0\" class=\"moduletable$moduleclass_sfx\">";
        if (
$title$html .= '<tr><th valign="top">'.$title.'</th></tr>';
        
$html .= '<tr><td>';
        
$html .= $content;
        
$html .= '</td></tr></table>';
        return 
$html;
    }

    public function 
moduleStyle1 ($moduleclass_sfx$title$content) {
        return 
$content;
    }

    
// HTML for the feature1 and feature2 areas is conditional on there being anything in either area
    
private function makeUser23 () {
        if (
$this->screenarea['feature1']->countModules() >= OR $this->screenarea['feature2']->countModules() >= ) {
            
$html = <<<USER_23

                        <div id="content_top_wrapper">
                            <!-- start content top 1.  -->
                            <div id="content_top1">
                            
{$this->screenarea['feature1']->getData()}
                            </div>
                            <!-- end content top 1 -->
                            <!-- start content top 2.  -->
                            <div id="content_top2">
                            
{$this->screenarea['feature2']->getData()}
                            </div>
                            <!-- end content top 2 -->
                        </div>

USER_23;
        }
        else 
$html '';
        return 
$html;
    }

    
// HTML for banners is conditional on there being any banner modules present
    
private function makeBanner () {
        if (
$this->screenarea['banner']->countModules() >= 1) {
            
$html = <<<BANNER

                    <!-- start banner.  -->
                    <div id="banner">
                    
{$this->screenarea['banner']->getData()}
                    </div>
                    <!-- end banner. -->

BANNER;
        }
        else 
$html '';
        return 
$html;
    }

    public function 
render () {
        echo <<<MAIN_HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        
{$this->prepareHeader()}
        <meta http-equiv='Content-Type' content='text/html; $this
->iso' />
        <link href='$this
->live_site/templates/waterandstone/css/template_css.css' rel='stylesheet' type='text/css' />
        <link rel='shortcut icon' href='
{$this->request->getFavIcon()}' />
    </head>

    <body class="waterbody">
        
{$this->request->requestOverlib()}
        <div align="center">
        <div id="container">
            <div id="containerbg">
                <div id="outerleft">
                    <!-- start logo -->
                    <div id="logo">
                      <a href="index.php"><img src="$this
->live_site/templates/waterandstone/images/logo.gif" alt="logo image" border="0" align="top" /></a>
                    </div>
                    <!-- end logo -->
                    <!-- start top menu -->
                    <div id="topmenu">
                    
{$this->screenarea['topmenu']->getData()}
                    </div>
                    <!-- end top menu.  -->
                    <!-- start image header -->
                    <div id="imgheader">
                    <img src="$this
->live_site/templates/waterandstone/images/img_header.jpg" alt="header image" />
                    </div>
                    <!-- end image header -->
                    <div id="container_inner">
                        <!-- start navigation column. -->
                        <div id="leftcol">
                        
{$this->screenarea['navigation']->getData()}
                        </div>
                        <div id="leftcolmenu">
                        
{$this->screenarea['user1']->getData()}
                        </div>
                        <!-- end left column. -->
                        <!-- start content top wrapper -->
                        
{$this->makeUser23()}
                        <!-- end content top wrapper -->
                        <!-- start Error Message area -->
                        <div id="errormessage">
                            
{$this->errorMessage()}
                        </div>
                        <!-- end Error Message area -->
                        <!-- start main body -->
                        <div id="content_main">
                            
{$this->pathway->makePathway()}
                            <table width="519" border="0" cellspacing="0" cellpadding="0">
                              <tr>
                                <td>
                                
{$this->mainBody()}
                                </td>
                              </tr>
                            </table>
                        </div>
                        <!-- end main body -->
                    </div>
                </div>
                <div id="outerright">
                    <!-- start right top header.  -->
                    <div id="rightcol_top">
                    
{$this->screenarea['searchbox']->getData()}
                    </div>
                    <!-- end right top header.-->
                    <!-- start right column. -->
                    <div id="rightcol">
                    
{$this->screenarea['newsflash']->getData()}
                    
{$this->screenarea['extra']->getData()}
                    
{$this->screenarea['user4']->getData()}
                    </div>
                    <!-- end right column. -->
                </div>

                <div class="clear">
                </div>
                
{$this->makeBanner()}

                <div id="blackline">
                </div>
                <div class="clear">
                </div>
                <div id="bottompadding"></div>
            </div>
            <!-- copyright notice -->
            <div id="copyright">
            <div align="center"><br />
{$this->version->footer()}</div>
            </div>

        </div>
        </div>
        <div style='clear:left'>
            
{$this->debugOutput()}
        </div>
    </body>
</html>

MAIN_HTML;
    }

    
// Only the most basic HTML combined with the output of the invoked component
    
public function component_render () {
        echo <<<COMPONENT_HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv='Content-Type' content='text/html; $this
->iso' />
        <link href='$this
->live_site/templates/waterandstone/css/template_css.css' rel='stylesheet' type='text/css' />
        <link rel='shortcut icon' href='
{$this->request->getFavIcon()}' />
    </head>
    <body>
        
{$this->mainBody()}
    </body>
</html>

COMPONENT_HTML;

    }


Reply With Quote
  #2  
Old December 6th, 2007, 08:03 PM
newart newart is offline
Member
 
Join Date: Nov 2007
Posts: 98
Default

"A shift of emphasis in terms of Aliro best practice is that I strongly believe that screen areas should have functional (not positional) names, such as "navigation" rather than "left". The reason for this is obvious - there are plenty of templates that implement the "left" screen area towards the right hand side of the screen!"

A splendid idea!


Moreover about footer:

<!-- copyright notice -->
<div id="copyright">
<div align="center"><br />{$this->version->footer()}</div>
</div>



why not to do as follows:


<!-- start footer copyright box. -->
<div id="footer">
{$this->screenarea['copyright']->getData()}
</div>


Then I think it'b be better to choose the name of BOX instead of MODULE. The name ELEMENT instead of COMPONENT, and so on...
Reply With Quote
  #3  
Old December 7th, 2007, 02:37 PM
counterpoint counterpoint is offline
Administrator
 
Join Date: Jun 2007
Posts: 200
Default

Yes, good point, the HTML you quote is pretty horrible! The template now driving the Aliro site is closer to your suggestion, and is currently:
PHP Code:
        <div id="footer">
            <
div id="footer-left">
                
Copyright &copy2007 Aliro Software Ltd {$this->version->footer()}
            </
div><!-- end left footer -->

            <
div id="footer-right">
                
Originally designed by <a href="http://www.s0rd.com">s0rd</a>
            </
div><!-- end right footer -->

            <
div class="clear">
                {
$this->debugOutput()}
            </
div><!-- dont touch this -->
        </
div><!-- end footer --> 
I guess it would make sense to turn the footer into a fully fledged screen area (or box), or possibly more than one as shown above. The creation of text out of the version class could easily be wrapped as a module.

The suggestion for the term BOX is excellent - I've struggled to find new words and that is one I hadn't thought of. ELEMENT is nice, but I'm not quite so sure about it, since components are pretty substantial things, maybe not fully captured by "element".

Also, I have some other ideas about how the architecture should develop - will post again later
Reply With Quote
  #4  
Old December 7th, 2007, 02:53 PM
newart newart is offline
Member
 
Join Date: Nov 2007
Posts: 98
Default

Good news waiting so...

About Box, I like very much this idea. And about Component, I agree with you. The problem is that the right word should be Module as a CMS has its principles in a modularity system, but it's too confusioning for people Mambo born.
Reply With Quote
  #5  
Old December 7th, 2007, 02:58 PM
newart newart is offline
Member
 
Join Date: Nov 2007
Posts: 98
Default

just for clarify my ideas, I like the idea of Module instead of component.
Reply With Quote
  #6  
Old December 11th, 2007, 09:33 AM
newart newart is offline
Member
 
Join Date: Nov 2007
Posts: 98
Default

what about Theme (I think more professional) instead of template? (The style is applied by CSS)
Reply With Quote
  #7  
Old March 6th, 2008, 02:33 PM
counterpoint counterpoint is offline
Administrator
 
Join Date: Jun 2007
Posts: 200
Default Improved template base classes

(For this post, I've stuck to old terminology to be consistent with earlier messages in this thread)

The mechanism of providing a base class for template development has been further improved. If you don't want to know about the details of the classes involved, then skip down to the example! There is now a simple structure of classes, starting with the abstract aliroTemplateBase which provides common features for all kinds of templates, including internal templates used by components to structure their area and build the HTML using multiple modules.

Inheriting from it is another abstract class, aliroMainTemplateBase which contains common code for user side and admin side templates, but goes beyond what is needed for internal templates. Next down the inheritance scheme are two different abstract classes. One is aliroMainTemplateBase for building user side templates, and the other is aliroAdminTemplateBase (only available on the admin side) for building admin templates.

An actual specific template can inherit a number of methods from the parent classes and not bother to implement them at all. OTOH the template is free to override the methods provided and implement them differently. The logic of an Aliro template should be fairly clear from the example.

A complete user side template is shown here, and illustrates just how simple it is to create an Aliro template:
PHP Code:
class ut_darkened extends aliroUserTemplateBase implements ifAliroTemplate {
    
// Options are 'xhtml_10_trans', 'xhtml_10_strict' or 'xhtml_11'
    
protected $doctype 'xhtml_10_trans';
    
// Formal name of this template
    
protected $tname 'ut_darkened';
    
// File name of CSS file, relative to the template
    
protected $cssname 'css/template_css.css';

    public function 
__construct () {
        
$this->areas = array (
        array (
'position' => 'main',        'min' => 519'max' => 519'style' => 'Null'),
        array (
'position' => 'topmenu',        'min' => 519'max' => 519'style' => 'Null'),
        array (
'position' => 'navigation',    'min' => 200'max' => 200'style' => 'Nav'),
        array (
'position' => 'searchbox',     'min' => 200'max' => 200'style' => 'Null'),
        array (
'position' => 'banner',         'min' => 468'max' => 468'style' => 'Null'),
        array (
'position' => 'debug',         'min' => 600'max' => 600'style' => 'Null')
        );
        
// All the Aliro error levels must have matching colour classes, with definitions in the CSS
        
$this->colours = array (
        
_ALIRO_ERROR_FATAL => 'fatalcolour',
        
_ALIRO_ERROR_SEVERE => 'severecolour',
        
_ALIRO_ERROR_WARN => 'warncolour',
        
_ALIRO_ERROR_INFORM => 'informcolour'
        
);
        
parent::__construct();
    }

    public static function 
defaultModulePosition () {
        return 
'navigation';
    }
    
    public function 
mainScreenBox () {
        return 
$this->screenarea['main'];
    }


    
// These "style" methods are invoked by the module handler as modules are processed
    // Their function is to place any required HTML around the content created by the module
    // The digit on the end relates to the style number for a screen area
    
public function moduleStyle0 ($moduleclass_sfx$title$content) {
        
$html =  "<table cellpadding=\"0\" cellspacing=\"0\" class=\"moduletable$moduleclass_sfx\">";
        if (
$title$html .= '<tr><th valign="top">'.$title.'</th></tr>';
        
$html .= '<tr><td>';
        
$html .= $content;
        
$html .= '</td></tr></table>';
        return 
$html;
    }

    public function 
moduleStyleNull ($moduleclass_sfx$title$content) {
        return 
$content;
    }

    public function 
moduleStyleNav ($moduleclass_sfx$title$content) {
        return <<<NAV_MODULE

            <h3>$title</h3>
                    $content

NAV_MODULE;

    }

    
// HTML for banners is conditional on there being any banner modules present
    
private function makeBanner () {
        if (
$this->screenarea['banner']->countModules() >= 1) {
            
$html = <<<BANNER

                    <!-- start banner.  -->
                    <div id="banner">
                    
{$this->screenarea['banner']->getData()}
                    </div>
                    <!-- end banner. -->

BANNER;
        }
        else 
$html '';
        return 
$html;
    }

    public function 
render () {
        echo <<<MAIN_HTML
{
$this->header ()}
        
<body>

    <div id="header">
        <h1>Black Sheep Research</h1>
        
{$this->screenarea['topmenu']->getData()}
    </div>
        
    <div id="content">
        <div id="colOne">
            <!-- start sidebar boxes -->
            
{$this->screenarea['searchbox']->getData()}
            
{$this->screenarea['navigation']->getData()}
            <!-- end sidebar boxes -->
        </div><!-- end col One -->

        <!-- start main content; the right column -->
        <div id="colTwo">
            <div id="pathway">
                
{$this->pathway->makePathway()}
            </div>
            
{$this->mainBody()}
            
{$this->makeBanner()}
        </div><!-- end col Two -->

        <div id="footer">
            <div id="footer-first">
                Copyright &copy; 2008 Aliro Software Ltd. All rights reserved. 
                Originally designed by <a href="http://freecsstemplates.org/">Free CSS Templates</a>
            </div>
            
{$this->version->footer()}

            <div class="clear">
                
{$this->debugOutput()}
            </div><!-- don't touch this -->
        </div><!-- end footer -->
    </div>
</body>
</html>

MAIN_HTML;
    }


Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 10:39 PM.


A vBSkinworks Design
Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Posts copyright respective authors; compilation copyright Aliro Ltd