📜 ⬆️ ⬇️

Pattern Inheritance in Smarty - An Alternative Approach

In the footsteps of habratopeka Pattern inheritance in Smarty I want to tell you how about one and a half years ago I solved a similar problem. I didn’t know the sign of marazmiki from Django (although I’m studying it now). But he was extremely superficially familiar with the Master Pages mechanism from ASP.NET. The mechanism is that we have almost a full page, which lacks only a block with the main content.

Having estimated a little, a solution was thought up through the standard Smarty functions and the PHP inheritance mechanism.


First of all, the template Smarty:
')
<! DOCTYPE html PUBLIC "- // W3C // DTD XHTML 1.0 Strict // EN" " www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd " >
< html xmlns = " www.w3.org/1999/xhtml " >

< head >
< title > Main title {if i $ ADDITIONAL_TITLE} | {$ ADDITIONAL_TITLE} {/ if} </ title >
< base href = "{$ ROOT_URL}" />
< meta http-equiv = "Content-Type" content = "text / html; charset = UTF-8 " />
</ head >

< body >

< div id = "base_div" >
< div id = "header_logo_div" > {include file = "header_logo.tpl"} </ div >
< div >
< div id = "user_login_info" > {include file = "users / user_login_info.tpl"} </ div >
< div id = "lang_selector" > {include file = "lang / selector.tpl"} </ div >
</ div >
< div >
< div id = "main_block" >
{include file = $ __ file_to_display}
</ div >
</ div >
</ div >
* This source code was highlighted with Source Code Highlighter .


The main elements to pay attention to are:
1. Main title {if $ ADDITIONAL_TITLE} | {$ ADDITIONAL_TITLE} {/ if}
2. {include file = $ __ file_to_display}

Next comes the code that works with all of this. First of all, to apply the Smarti settings and work with the data common to the entire site, I had an abstract class, which was inherited directly from Smarty:

<?php
abstract
class smarty_page_ex extends Smarty {
protected $module ;
protected $action ;

public function __construct ( $module = "" , $action = "" , smarty_config_wrapper $config = null ) {
parent :: Smarty ();

$this -> module = $module ;
$this -> action = $action ;

$gconfig = global_config :: get_instance ();

if (
$config === null ) $config = $gconfig -> get_smarty_config ();

$this -> compile_check = $config -> get_tpl_compile_check ();
$this -> debugging = $config -> get_smarty_debug ();

$this -> compile_dir = $config -> get_tpl_compiled_path ();
$this -> cache_dir = $config -> get_tpl_cache_path ();

$this -> template_dir = $config -> get_tpl_path ();
$this -> config_dir = $config -> get_tpl_config_path ();

$lang = lang :: get_instance ();
$this -> assign_by_ref ( "lang" , $lang );

$this -> assign ( "ROOT_URL" , $gconfig -> root_url );
$this -> assign ( "MODULE" , $module );

$this -> assign ( "ACTION" , $action );

$this -> register_object ( "smarty_page_ex" , $this );
}

/**
* Gets template full path
*
* @param string $base_path
* @return string
*/
protected function get_full_path () {
return (
strlen ( $this -> module ) > 0 ? ( $this -> module . "/" ) : "" );
}
}
?>



It is worth mentioning here that the structure of storing templates in the project was as follows:
<templates-dir>/
|-<module>
| |-<action>.tpl
|-home
| |-index.tpl
|-common_page.tpl
|-admin_page.tpl
|-mail_page.tpl


And the template above is common_page.tpl (simplified metacharacter for custom pages).

For each type of page there is a successor of the extended class of smart, which was engaged in the transfer of some additional data to the template. In particular, the successor for common_page.tpl looks like this:

<?php
class common_page extends smarty_page_ex {
public function __construct ( $module = "" , $action = "" , $title = "" , smarty_config_wrapper $config = null ) {
parent :: __construct ( $module , $action , $config );

$options = options :: get_instance ();
$this -> assign_by_ref ( "options" , $options );

$auth_user = auth_user :: get_instance ();
$this -> assign_by_ref ( "auth_user" , $auth_user );

$gconfig = global_config :: get_instance ();
$this -> assign_by_ref ( "gconfig" , $gconfig );

$lang = new languages ();
$lang_list = db_adapter :: get_instance ()-> get_list ( $lang );
$this -> assign_by_ref ( "__languages" , $lang_list );

$this -> assign ( "ADDITIONAL_TITLE" , $title );
}

/**
* Executes & returns or displays the template results
*
* @param string $template
* @param string $cache_id
* @param string $compile_id
* @param boolean $display
*/
public function fetch ( $template , $cache_id = null , $compile_id = null , $display = false ) {
$this -> assign ( "__file_to_display" , $this -> get_full_path () . $template );
return
parent :: fetch ( "common_page.tpl" , $cache_id , $compile_id , $display );
}
}
?>


Here some general data and an additional header are sent to the template, if required, everything is as usual. And then we redefine the fetch method of the Smarty base class so that it does not compile the template given to it, but instead inserts it into the metachlablon, and we are already compiling a metacharacter with an inserted data block.

In its simplest form, the use of such a code structure is as follows:

<?php
$tpl
= new common_page ( "home" , "index" , "Welcome!" );
$tpl -> display ();
?>



Having written 1 main template and creating a small chain of sentences in the php code, we were able to inherit the smarti template for the same type pages. For the introduction of additional blocks on the pages of the heirs, Smarti will have to complicate a little, but this is not a very time-consuming and difficult task.

I am ready to listen to criticism in my address regarding this pattern inheritance in smarti.

Source: https://habr.com/ru/post/38174/


All Articles