📜 ⬆️ ⬇️

PHP Matryoshka or Templates for any site of 8 lines

I will talk about my templates (of eight lines), which I invented in 2003 and since then they have not let me down and have not required any improvements.

The essence of the patterns is the principle of the matryoshka, when the little matryoshka is part of the larger one.
In practice, it looks like this: we specify the name of the first pkhp-template, inside which we write the name of the higher template, which, in turn, can also point to its pkhp-parent, etc.

image
')
Physically, it looks like this. My host is configured in Apache http://start.local http://start.local with the home directory for browsers /home/start.local/www , where the starting root file /home/start.local/www/index.php , which contains only one line:

 <?load::integration('main.tpl');?> 


This text should be read like this: the load class calls the function (method) load::integration() , to which it passes one parameter - the string 'main.tpl' .

Where, main.tpl is the file name of the first php template, and the load::integration() function contains a mechanism that allows the specified template to be processed. More specifically, it allows us to register in the template main.tpl, another template, such as default.tpl, which will contain the result of the execution of mail.tpl. In turn, default.tpl can also specify a higher template (as shown in the figure). If the upstream templates are not specified, then the load::integration() function will stop building the templates and return the total result of the execution of all templates to the browser.

Next, I will tell you how it works and give a link to download the code.



This scheme works due to the fact that before starting to process each page on the server (in this case, the start-up file index.php), we prescribe for php that before you execute any script, you must first download the file we specified. This is done in the file /home/start.local/www/.htaccess one line, like this:

 php_value auto_prepend_file /home/start.local/bin/lib/config.mdl 


In this case, I have a config.mdl file for convenience. Here is its content:

 #  OC:    define("OS", getenv("COMSPEC")? ";": ":"); # ,  -    #   -. #,    dirname,   , # -    , #   , ..    /home/start.local/bin ini_set("include_path", ini_get("include_path").OS.dirname(dirname(__FILE__))); #   - load.cls require_once 'lib/load.cls'; #  - create.cls,     require_once 'lib/create.cls'; # - db.cls,      #require_once 'lib/db.cls'; 


Thus, the load class ( /home/start.local/bin/lib/load.cls ) and its load::integration() function are pre-loaded for all scripts using the config.mdl file.

Let's look at the load class code:

 <? class load { static $layout = ''; static $title = ''; static $body = ''; static $path; static $db; static function integration($maket) { #    self::$path = self::path(); #    //self::$db = new db(); do { $current = self::$layout; ob_start(); require_once "tpl/" .$maket; self::$body = ob_get_clean(); $maket = self::$layout; } while ($current != self::$layout); echo self::$body; } static function path($url='') { $var = (!$url)? dirname(getenv("SCRIPT_NAME")): $url; return explode("/", trim($var, "/\\") ); } } ?> 


As you can see, the load::integration() function contains only 8 significant lines, starting with do {}. The essence of which is to execute the code of our template and save the result of execution in the variable self::$body . And besides, it is worth checking whether it is necessary to repeat the operation if the starting pattern has been changed.

Now look at the code of our template main.tpl
 <? load::$layout = 'default.tpl'; load::$title = ' '; ?> <h2> </h2> <p>  </p> 


Here is the control variable load::$layout , which points to the parent template. And an optional variable load::$title , which is used in the default.tpl template

Let's look at the template code default.tpl
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional"> <html> <head> <title><?=load::$title?></title> </head> <body> <table align="center" width="600"> <tr valign="top"> <td width="150"> <? if ( !empty(load::$path[0]) ) { ?> <p><a href="<?=create::file('/', 'main.tpl')?>"></a></p> <? } else { ?> <p>:</p> <? } ?> <p><a href="<?=create::file('/news/', 'page.tpl')?>"></a></p> <p><a href="<?=create::file('/cont/', 'page.tpl')?>"></a></p> </td> <td> <?=load::$body?> </td> </tr> </table> </body> </html> 


As you can see, this is just a html markup over which the usual php code is placed. Among the php-inserts there is a printout of the variable load::$body . This variable contains the result of the execution of the main.tpl code, or any other template that the load::$layout variable specifies as its parent.

It is important that in the default.tpl template there is no load::$layout variable with an indication of the parent template, therefore the load::integration() function, inside which the whole action with templates occurs, completes its do {} loop and prints the final result i.e. gives the result of execution to the browser.

Now look at the links in the menu of our site which are recorded in default.tpl, for example

 <a href="<?=create::file('/news/', 'page.tpl')?>"></a> 


Here, in the href attribute of the a tag instead of the link, it is indicated that the result of the create::file() function of the create::file() class should be printed.

The essence of this function is very simple - create a file at the specified path (this is the first parameter - '/news/' ) and record the call to the first template inside it (this is the second parameter 'page.tpl' ).

The result of the create::file() function will be two actions:
  1. in the href attribute, the link will be added, i.e. in the browser such a link will look like
     <a href="/news/"></a> 
  2. a file will be created on the server at the specified path to display /home/start.local/www/news/index.php , with the following content
     <?load::integration('page.tpl');?> 


Those. the specified path will contain the starting template page.tpl, the processing of which will be similar to that of main.tpl.

About the condition if () in the template default.tpl I will not tell, because this does not affect the logic of the templates, but refers purely to the design of the site and nothing more.

Finally, it remains to look at the code of the create class with the function create::file() . The code is:
 <? class create { #    static function dir($arr, $dir='') { if ($dir=='') $dir = $_SERVER['DOCUMENT_ROOT']; #  chdir($dir); #    foreach ($arr as $a) { if ( $a=='' ) continue; if( !is_dir($a.'/') ){ mkdir($a, 0770) or print("   $dir/<b>$a</b><br>"); } chdir($a); $dir .= '/' .$a; } return $dir; } #       static function file($path, $template, $content='') { #    $path = trim($path, '/'); #  $arr = explode('/', $path); #    $end = array_pop($arr); #     if ( !strpos($end, '.php') ) { #    array_push($arr, $end); $end = 'index.php'; $temp[ $path ] = '/'.$path.'/'; $temp[ '' ] = '/'; $path = $temp[ $path ]; } else { $path = '/'.$path; } $dir = self::dir($arr); #   #   . $fp = fopen($end, "w+") or print ("   $dir/<b>$end</b>!"); #  $content = $content==''? "<?load::integration('$template');?>": $content; #  . fputs($fp, $content); # . fclose ($fp); return $path; } } ?> 


There are actually two functions (methods):
  1. Create folders, create::dir() function
  2. Creating a file inside the folder and filling the file with one line indicating which template to use for the start, the create::file() function discussed

That's all! 8 lines. More clearly you can download the archive of my host start.local .

With this technique I have been writing sites on pure PCP for 8 years and I don’t know grief.
Need a custom design section? In two accounts I make a new template and connect another design there.
Need to add a form to the site? I make the form in a separate template and connect it using the template mechanism or the usual require_once insert.

Of course, I have accumulated quite a few different related classes and functions: for working with a database, or forms, or letters. But the bottom line is that you can just take it and easily use both your work and connect third-party libraries to php matrices . It will work thanks to only 8 lines. Without vypilivaniya, stretching and dancing with a tambourine.

I hope my experience will be useful and will serve well. For example, in a situation where, you need to prove that you can do it, but within the framework of some kind of site, you simply do not know how to achieve this.

Ps.
In the next article I will tell you that you can use phpMyAdmin to manage the site database, which can work with related tables, i.e. You do not just change the ID in the linked field, but you can also see the full-fledged linked data from the related tables that are behind this ID.

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


All Articles