За последние 24 часа нас посетили 17832 программиста и 1614 роботов. Сейчас ищут 1477 программистов ...

Template Engine

Тема в разделе "Решения, алгоритмы", создана пользователем AntonShevchuk, 2 авг 2007.

  1. AntonShevchuk

    AntonShevchuk Активный пользователь

    С нами с:
    6 июл 2007
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Kharkov
    Просьба велосипедами не кидаться... :)

    Собстно простенький сабж для PHP5, с кэшом и плагинами, может кому пригодиться...
    PHP:
    1. <?php
    2. /**
    3.  * Class Template
    4.  *
    5.  *
    6.  * @author   Anton Shevchuk <AntonShevchuk@gmail.com>
    7.  * @link     [url=http://anton.shevchuk.name]http://anton.shevchuk.name[/url]
    8.  *
    9.  * @access   public
    10.  * @package  Template.class.php
    11.  * @created  Tue Jul 24 16:11:24 EEST 2007
    12.  */
    13.  
    14. // FIXME: remove public data!!!
    15. class Template
    16. {
    17.     const TEMPLATE_OPTION_TPL_PATH    = 'templates';
    18.     const TEMPLATE_OPTION_CACHE_PATH  = 'cache';
    19.     const TEMPLATE_OPTION_PLUGIN_PATH = 'plugins';
    20.     const TEMPLATE_OPTION_DEBUG       = 'debug';
    21.    
    22.     const TEMPLATE_ERROR_FILE  = 1;
    23.     const TEMPLATE_ERROR_CACHE = 2;
    24.    
    25.     /**
    26.      * This is Object Name
    27.      *
    28.      * @var string
    29.      */
    30.     public $_name = 'main';
    31.    
    32.     /**
    33.      * Parent Object
    34.      *
    35.      * @var Template
    36.      */
    37.     protected $_parent = null;
    38.    
    39.     /**
    40.      * Children Objects
    41.      *
    42.      * @var array
    43.      */
    44.     public $_children = array();
    45.    
    46.     /**
    47.      * Options
    48.      *
    49.      * array(
    50.      *       TEMPLATE_OPTION_TPL_PATH    - path to template
    51.      *       TEMPLATE_OPTION_CACHE_PATH  - path to cache
    52.      *       TEMPLATE_OPTION_PLUGIN_PATH - path to plugins
    53.      *       TEMPLATE_OPTION_DEBUG       - debug enabled error reporting
    54.      *       )
    55.      *
    56.      * @var array
    57.      */
    58.     public  $_options = array(
    59.                         self::TEMPLATE_OPTION_TPL_PATH    => 'templates' ,
    60.                         self::TEMPLATE_OPTION_CACHE_PATH  => 'cache'     ,
    61. //                        self::TEMPLATE_OPTION_PLUGIN_PATH => 'plugins'   ,
    62.                         self::TEMPLATE_OPTION_DEBUG       =>  false      ,
    63.                                 );
    64.    
    65.     /**
    66.      * Template file
    67.      *
    68.      * @var string
    69.      */
    70.     public  $_template = null;
    71.    
    72.     /**
    73.      * Variables stack
    74.      *
    75.      * @var array
    76.      */
    77.     private $_vars = array();
    78.    
    79.     /**
    80.      * Cache
    81.      *
    82.      * @var bool
    83.      */
    84.     private $_cache = false;
    85.    
    86.     /**
    87.      * Cache ID
    88.      *
    89.      * @var string
    90.      */
    91.     private $_cacheID = null;
    92.    
    93.     /**
    94.      * Cache TTL (in seconds)
    95.      *
    96.      * @var integer
    97.      */
    98.     private $_cacheTTL = 3600;
    99.    
    100.        
    101.     /**
    102.      * Constructor of Template
    103.      *
    104.      * @access  public
    105.      * @param   array     $aOptions
    106.      */
    107.     function __construct($aOptions = array())
    108.     {
    109.         $this->optionsSet($aOptions);
    110.     }
    111.  
    112.     /**
    113.      * Destructor of Template
    114.      *
    115.      * @access  public
    116.      */
    117.      function __destruct()
    118.      {
    119.          
    120.      }
    121.      
    122.      /**
    123.       * __set
    124.       *
    125.       * @access  public
    126.       * @param   string    $aName   variable name
    127.       * @param   mixed     $aValue  variable value
    128.       */
    129.      public function __set($aName, $aValue)
    130.      {
    131.          $this->varAdd($aName, $aValue);
    132.      }
    133.      
    134.      /**
    135.       * __get
    136.       *
    137.       * @access  public
    138.       * @param   string    $aName   variable name
    139.       */
    140.      public function __get($aName)
    141.      {
    142.          return $this->varGet($aName);
    143.      }
    144.      
    145.      /**
    146.       * __call
    147.       *
    148.       * redaclarate functions
    149.       *
    150.       * @access  public
    151.       * @param   string     $aMethod  method name
    152.       * @param   array      $aParams  method params
    153.       * @return  mixed
    154.       */
    155.      public function __call($aMethod, $aParams)
    156.      {
    157.         $aFunctionName = 'tpl_function_' . strtolower($aMethod);
    158.         $aFunctionFlie = dirname(__FILE__) . DIRECTORY_SEPARATOR .
    159.                          self::TEMPLATE_OPTION_PLUGIN_PATH . DIRECTORY_SEPARATOR .
    160.                          'function.' . strtolower($aMethod) . '.php';
    161.          
    162.         array_unshift($aParams, &$this);
    163.        
    164.         if (!function_exists($aFunctionName) && is_file($aFunctionFlie)) {
    165.             include_once $aFunctionFlie;
    166.             return call_user_func_array($aFunctionName, $aParams);
    167.         } elseif (function_exists($aFunctionName)) {
    168.             return call_user_func_array($aFunctionName, $aParams);
    169.         } else{
    170.             return false;
    171.         }
    172.      }
    173.      
    174.      /**
    175.       * Manipulate options
    176.       *
    177.       * + optionsSet
    178.       * + optionsGet
    179.       */
    180.      
    181.      /**
    182.       * optionSet
    183.       *
    184.       * @access  public
    185.       * @param   string     $aOption
    186.       * @param   string     $aValue
    187.       */
    188.       public function optionSet($aOption, $aValue)
    189.       {
    190.           $this->_options[$aOption] = $aValue;
    191.       }
    192.      
    193.      /**
    194.       * optionsGet
    195.       *
    196.       * @access  public
    197.       * @param   string     $aOption
    198.       */
    199.       public function optionGet($aOption)
    200.       {
    201.           if (isset($this->_options[$aOption])) {
    202.               return $this->_options[$aOption];
    203.           } else {
    204.               return false;
    205.           }
    206.       }
    207.      
    208.      /**
    209.       * optionsSet
    210.       *
    211.       * @access  public
    212.       * @param   array     $aOptions
    213.       */
    214.       public function optionsSet($aOptions = array())
    215.       {
    216.           $this->_options = array_merge($this->_options, $aOptions);
    217.       }
    218.      
    219.      /**
    220.       * optionsGet
    221.       *
    222.       * @access  public
    223.       */
    224.       public function optionsGet()
    225.       {
    226.           return $this->_options;
    227.       }
    228.      
    229.      
    230.      /**
    231.       * Manipulate objects
    232.       *
    233.       * + childAdd
    234.       * + childSet
    235.       * + childGet
    236.       * + childDel
    237.       * + childDelAll
    238.       * + childDisplay
    239.       */
    240.      
    241.      /**
    242.       * childAdd
    243.       *
    244.       * add child to stack
    245.       *
    246.       * @access  public
    247.       * @param   mixed     $aChildName  object name
    248.       * @param   array     $aOptions    options
    249.       * @return  Template  $aChild
    250.       */
    251.      public function childAdd($aChildName, $aOptions = array())
    252.      {
    253.          if (isset($this->_children[$aChildName])) {
    254.              return $this->_children[$aChildName];
    255.          } else {
    256.              $this->_children[$aChildName] =  new Template($this->_options);
    257.              
    258.              if (empty($aOptions[self::TEMPLATE_OPTION_TPL_PATH])) {
    259.                  $aOptions[self::TEMPLATE_OPTION_TPL_PATH]   = $this->_options[self::TEMPLATE_OPTION_TPL_PATH]   . DIRECTORY_SEPARATOR . $this->_name . DIRECTORY_SEPARATOR ;
    260. //                 $aOptions[self::TEMPLATE_OPTION_CACHE_PATH] = $this->_options[self::TEMPLATE_OPTION_CACHE_PATH] . DIRECTORY_SEPARATOR . $this->_name . DIRECTORY_SEPARATOR ;
    261.              }
    262.              
    263.              $this->_children[$aChildName] -> optionsSet($aOptions);
    264.              $this->_children[$aChildName] -> _name = $aChildName;
    265.              return $this->_children[$aChildName];
    266.          }        
    267.      }
    268.      
    269.      /**
    270.       * childSet
    271.       *
    272.       * add child to stack
    273.       *
    274.       * @access  public
    275.       * @param   mixed     $aChildName  object name
    276.       * @param   Template  $aTemplate   object
    277.       * @return  void
    278.       */
    279.      public function childSet($aChildName, &$aTemplate)
    280.      {
    281.          if ($aTemplate instanceof Template) {
    282.             $this->_children[$aChildName] =& $aTemplate;
    283.             return true;
    284.          } else {
    285.              return false;
    286.          }
    287.      }
    288.      
    289.      /**
    290.       * childGet
    291.       *
    292.       * get/create child from stack
    293.       *
    294.       * @access  public
    295.       * @param   mixed     $aChildName  object name
    296.       * @return  void
    297.       */
    298.      public function childGet($aChildName)
    299.      {
    300.          if (!isset($this->_children[$aChildName])) {
    301.             $this->childAdd($aChildName);
    302.          }
    303.          return $this->_children[$aChildName];
    304.      }
    305.      
    306.      
    307.      /**
    308.       * childDel
    309.       *
    310.       * del child from stack
    311.       *
    312.       * @access  public
    313.       * @param   mixed     $aChildName  object name
    314.       */
    315.      public function childDel($aName)
    316.      {
    317.          if (isset($this->_children[$aChildName])) {
    318.              unset($this->_children[$aChildName]);
    319.              return true;
    320.          } else {
    321.              return false;
    322.          }
    323.      }
    324.      
    325.      /**
    326.       * childDelAll
    327.       *
    328.       * clear stack
    329.       *
    330.       * @access  public
    331.       */
    332.      public function childDelAll()
    333.      {
    334.          $this->_children = array();
    335.      }
    336.      
    337.      /**
    338.       * childDisplay
    339.       *
    340.       * display child
    341.       *
    342.       * @access  public
    343.       * @param   mixed     $aChild  object name
    344.       */
    345.      public function childDisplay($aChild)
    346.      {
    347.          if (is_array($aChild)) {
    348.              $aChildName = array_shift($aChild);
    349.          } else {
    350.              $aChildName = $aChild;
    351.          }
    352.          
    353.          
    354.          if (!isset($this->_children[$aChildName])) {
    355.              return false;
    356.          } else {
    357.              if (is_array($aChild) && sizeof($aChild) > 0) {
    358.                 $this->_children[$aChildName] -> childDisplay($aChild);
    359.              } else {
    360.                 $this->_children[$aChildName] -> display();
    361.              }
    362.          }        
    363.      }
    364.      
    365.      /**
    366.       * Manipulate variables
    367.       *
    368.       * + varAdd
    369.       * + varAddGlobal
    370.       * + varGet
    371.       * + varGetGlobal
    372.       * + varDel
    373.       * + varDelAll
    374.       */
    375.      
    376.      
    377.      /**
    378.       * varAdd
    379.       *
    380.       * add variable to stack
    381.       *
    382.       * @access  public
    383.       * @param   string    $aName   variable name
    384.       * @param   mixed     $aValue  variable value
    385.       */
    386.      public function varAdd($aName, $aValue)
    387.      {
    388.          $this->_vars[$aName] = $aValue;
    389.      }
    390.      
    391.      /**
    392.       * varDel
    393.       *
    394.       * del variable from stack
    395.       *
    396.       * @access  public
    397.       * @param   string    $aName   variable name
    398.       * @return  void
    399.       */
    400.      public function varDel($aName)
    401.      {
    402.          if (isset($this->_vars[$aName])) {
    403.              unset($this->_vars[$aName]);
    404.              return true;
    405.          } else {
    406.              return false;
    407.          }
    408.      }
    409.      
    410.      /**
    411.       * varDelAll
    412.       *
    413.       * clear stack
    414.       *
    415.       * @access  public
    416.       */
    417.      public function varDelAll()
    418.      {
    419.          $this->_vars = array();
    420.      }
    421.      
    422.      /**
    423.       * varGet
    424.       *
    425.       * get variable from stack
    426.       *
    427.       * @access  public
    428.       * @param   string    $aName   variable name
    429.       * @param   mixed     $aValue  variable value
    430.       * @return  mixed
    431.       */
    432.      public function varGet($aName)
    433.      {
    434.          if (isset($this->_vars[$aName])) {
    435.              return $this->_vars[$aName];
    436.          } else {
    437.              return $this->varGetGlobal($aName);
    438.          }
    439.      }
    440.      
    441.      /**
    442.       * varAddGlobal
    443.       *
    444.       * add variable to stack
    445.       *
    446.       * @access  public
    447.       * @param   string    $aName   variable name
    448.       * @param   mixed     $aValue  variable value
    449.       * @return  rettype  return
    450.       */
    451.      public function varAddGlobal($aName, $aValue)
    452.      {
    453.          if (!$this->_parent) {
    454.              $this->varAdd($aName, $aValue);
    455.          } else {
    456.              $this->_parent->varAddGlobal($aName, $aValue);
    457.          }
    458.      }
    459.      
    460.      /**
    461.       * varGetGlobal
    462.       *
    463.       * add variable to stack
    464.       *
    465.       * @access  public
    466.       * @param   string    $aName   variable name
    467.       * @param   mixed     $aValue  variable value
    468.       * @return  rettype  return
    469.       */
    470.      public function varGetGlobal($aName)
    471.      {
    472.          if (!$this->_parent) {
    473.              return false;
    474.          } else {
    475.              $this->_parent->varGet($aName);
    476.          }
    477.      }
    478.      
    479.      
    480.      /**
    481.       * Manipulate templates
    482.       *
    483.       * + tplSet
    484.       * + tplDel
    485.       */
    486.            
    487.      /**
    488.       * tplGet
    489.       *
    490.       * set template
    491.       *
    492.       * @access  public
    493.       * @return string  template file
    494.       */
    495.      public function tplGet()
    496.      {
    497.          return $this->_template;
    498.      }
    499.      
    500.      /**
    501.       * tplAdd
    502.       *
    503.       * set template
    504.       *
    505.       * @access  public
    506.       * @param   mixed     $aTemplateFile  template file
    507.       */
    508.      public function tplSet($aTemplateFile)
    509.      {
    510.          $aTemplate = $this->_options[self::TEMPLATE_OPTION_TPL_PATH] . $aTemplateFile;
    511.         if (!file_exists($aTemplate)) {
    512.              return false;
    513.          } else {
    514.              $this->_template = $aTemplate;
    515.              return true;
    516.          }
    517.      }
    518.      
    519.      /**
    520.       * tplDel
    521.       *
    522.       * remove template
    523.       *
    524.       * @access  public
    525.       */
    526.      public function tplDel()
    527.      {
    528.          $this->_template = null;
    529.      }
    530.      
    531.      /**
    532.       * Manipulate cache
    533.       *
    534.       * + cacheSet
    535.       * + cacheId
    536.       * + cacheIs
    537.       */
    538.      
    539.      /**
    540.       * set cache
    541.       *
    542.       * @author  dark
    543.       * @class   HSTemplateDisplay
    544.       * @access  public
    545.       * @param   mixed      $aId            
    546.       * @param   integer    $aTime
    547.       * @return  void
    548.       */
    549.      public function cacheSet($aId, $aTTL = 3600)
    550.      {
    551.         $this->_cache    = true;
    552.         $this->_cacheTTL = $aTTL;
    553.        
    554.         $this->cacheId($aId);
    555.        
    556.         try {
    557.             if ( is_dir($this->_options[self::TEMPLATE_OPTION_CACHE_PATH] ) &&
    558.                  is_writable($this->_options[self::TEMPLATE_OPTION_CACHE_PATH] )) {
    559.                  // all OK
    560.                  return true;    
    561.             } elseif ( is_dir($this->_options[self::TEMPLATE_OPTION_CACHE_PATH] ) &&
    562.                  !is_writable($this->_options[self::TEMPLATE_OPTION_CACHE_PATH] )) {
    563.                      
    564.                 throw new Exception('Template Error: Cannot write directory "' . $this->_options[self::TEMPLATE_OPTION_CACHE_PATH] . '"');   
    565.                    
    566.             } elseif (!@mkdir($this->_options[self::TEMPLATE_OPTION_CACHE_PATH] )) {
    567.                
    568.                 throw new Exception('Template Error: Cannot create directory "' . $this->_options[self::TEMPLATE_OPTION_CACHE_PATH] . '"');                
    569.             }
    570.         } catch (Exception $e) {
    571.             echo $e->getMessage();
    572.             return false;
    573.         }
    574.      }
    575.      
    576.      /**
    577.       * set/get cache id
    578.       *
    579.       * @access  public
    580.       * @param   mixed  $aId  
    581.       * @return  mixed
    582.       */
    583.      public function cacheId($aId = null)
    584.      {
    585.          if ($aId) {         
    586.             if (is_array($aId)) {
    587.                $this->_cacheID = implode("::", $aId);
    588.             } else {
    589.                $this->_cacheID = $aId;
    590.             }
    591.         }
    592.         return $this->_cacheID;
    593.      }
    594.  
    595.      /**
    596.       * Check cache
    597.       *
    598.       * @access  public
    599.       * @return  void
    600.       */
    601.      public function cacheIs()
    602.      {
    603.         if ($this->cacheId() === null) {
    604.             return false;
    605.         }
    606.        
    607.         $aFileName = $this->_cacheFile();
    608.  
    609.         if (!file_exists($aFileName)) {
    610.             return false;
    611.         } else {
    612.            
    613.             if ((filemtime($aFileName) + $this->_cacheTTL) < time()) {
    614.                 return false;
    615.             } else {
    616.                 return true;
    617.             }
    618.         }
    619.      }
    620.  
    621.      /**
    622.       * create cache file
    623.       *
    624.       * @access  private
    625.       * @param   string     $aContent       content for file
    626.       * @return  void
    627.       */
    628.      private function _cacheCreate($aContent = '')
    629.      {
    630.         $aFileName = $this->_cacheFile();
    631.        
    632.         @unlink($aFileName);
    633.        
    634.         // create file with cache
    635.         $fp = fopen($aFileName, "at") or
    636.                 die(trigger_error('Template Error: Cannot create file "'. $aFileName . '"', E_USER_ERROR));
    637.        
    638.         flock ($fp, LOCK_EX);// lock file
    639.         rewind($fp); // rewind the position of a file pointer
    640.         fwrite($fp, $aContent); // write data
    641.         flock ($fp, LOCK_UN); // release the lock
    642.         fclose($fp); // close file
    643.      }
    644.      
    645.      /**
    646.       * get cache file name
    647.       *
    648.       * @access  private
    649.       * @return  string
    650.       */
    651.      private function _cacheFile()
    652.      {
    653.         return $this->_options[self::TEMPLATE_OPTION_CACHE_PATH] . DIRECTORY_SEPARATOR .
    654. //               $this->_name . DIRECTORY_SEPARATOR .
    655.                $this->_name . '_' . md5($this->_name . '#' . $this->_cacheID) . '.html';
    656.      }
    657.      
    658.      /**
    659.       * Manipulate output
    660.       *
    661.       * + display
    662.       * + fetch
    663.       */
    664.          
    665.      /**
    666.       * display
    667.       *
    668.       * @access  public
    669.       * @return  rettype  return
    670.       */
    671.      public function display()
    672.      {
    673.          if ($this->_template) {
    674.             $this->fetch(true);
    675.          }
    676.      }
    677.      
    678.      /**
    679.       * fetch
    680.       *
    681.       * cetch all (or selected) template
    682.       *
    683.       * @access  public
    684.       * @param   bool       $aDisplay   template name
    685.       * @return  rettype  return
    686.       */
    687.      public function fetch($aDisplay = false)
    688.      {
    689. //      $oldErrorReporting = error_reporting();
    690. //     
    691. //        if ($this->_options[self::TEMPLATE_OPTION_DEBUG ]) {
    692. //          error_reporting(E_ALL);
    693. //      }  else {
    694. //          error_reporting(E_ALL ^ E_NOTICE);
    695. //      }
    696.         ob_start();
    697.        
    698.         if ($this->_cache && $this->cacheIs()) {        
    699.             include $this->_cacheFile();    
    700.         } else {           
    701.             include $this->_template;
    702.         }
    703.         $cache = ob_get_contents();
    704.         ob_end_clean();
    705.        
    706.         if ($this->_cache && !$this->cacheIs()) {
    707.            
    708.             $this->_cacheCreate($cache);
    709.         }
    710.        
    711.         // for cache system
    712.         if ($aDisplay) {
    713.             echo $cache;
    714.         } else {
    715.             return $cache;
    716.         }
    717.        
    718. //      error_reporting($oldErrorReporting);
    719.        
    720.      }
    721. }
    722. ?>
    723.  
    Пример плагина:
    PHP:
    1.  
    2. <?php
    3. /**
    4.  * tpl_function_percent
    5.  *
    6.  * count percent
    7.  *
    8.  * @access  public
    9.  * @param   Template  $Template
    10.  * @param   integer   $aCount
    11.  * @param   integer   $aTotal  
    12.  * @param   integer   $aPercent
    13.  * @param   string    $aFormat  
    14.  * @return  rettype  return
    15.  */
    16. function tpl_function_percent(&$Template, $aCount, $aTotal, $aPercent = false, $aFormat = '')
    17. {
    18.     // calculate percent or
    19.     if (!$aPercent) {
    20.         $tmp = ($aTotal / 100 );
    21.         if ($tmp != 0) {
    22.             $aResult = $aCount / $tmp;
    23.         } else {
    24.             $aResult = 0;
    25.         }
    26.     } else {
    27.         $aResult = ($aTotal / 100 ) * $aCount;
    28.     }
    29.  
    30.     // output data
    31.     if (empty($aFormat)) {
    32.         return $aResult;
    33.     } else {
    34.         sprintf($aFormat, $aResult);
    35.     }
    36. }
    37. ?>
    38.  
    Пример использования:
    PHP:
    1.  
    2. <?php
    3.  
    4. require_once('Template.class.php');
    5.  
    6. /* Template initialization */
    7. $options = array(
    8.                 Template::TEMPLATE_OPTION_TPL_PATH    => dirname(__FILE__) . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR ,
    9.                 Template::TEMPLATE_OPTION_CACHE_PATH  => dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR ,
    10.                 Template::TEMPLATE_OPTION_DEBUG       => false,
    11.                 );
    12.                
    13. $Template = new Template($options);
    14. $Template -> field1 = 'field1';
    15. $Template -> varAdd('field2', 'field2');
    16. $Template -> tplSet('index.html');
    17.  
    18.     $Child = $Template->childAdd('child');
    19.     $Child -> tplSet('child.html');
    20.    
    21.  
    22.         $Child1 = $Child->childAdd('child1');
    23.         $Child1 -> varAdd('time1', date('H:i:s'));
    24.         $Child1 -> tplSet('child1.html');
    25.        
    26.         $Child2 = $Child->childAdd('child2');
    27.         $Child2 -> varAdd('time2', date('H:i:s'));
    28.         $Child2 -> tplSet('child2.html');
    29.         $Child2 -> cacheSet('child2', 5);
    30.        
    31.  
    32. $Template -> display();
    33. ?>
    34.  
    Пример файла шаблона ('index.html'):
    PHP:
    1.  
    2. Percent: <?php echo $this->percent(5, 20); ?><br/>
    3. Field1: <?php echo $this->field1; ?><br/>
    4. Field2: <?php echo $this->field2; ?><br/>
    5.  
    6. <?php $this->childDisplay('child'); ?>
    7.  
    Дерево категорий будет типа:
    Код (Text):
    1.  
    2. |\ cache
    3. |\ plugins
    4. |  | - function.percent.php
    5. |\ templates
    6. |  |\ main
    7. |  |   |\ child
    8. |  |   |   | - child1.html
    9. |  |   |   | - child2.html
    10. |  |   | - child.html
    11. |  | - index.html
    12. | - index.php
    13. | - Template.class.php
     
  2. lexa

    lexa Активный пользователь

    С нами с:
    22 июл 2007
    Сообщения:
    1.746
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    PHP:
    1. $field2 = 'field2';
    2. include 'templates/main/index.html';
    3.  
    4. $time1 = date('H:i:s');
    5. include 'templates/main/child/child1.html';
    Разве не кошерно? :)

    З.Ы. Я вообще велосипеды люблю, потому что если ты сам ничего не делаешь, значит ничему и не научишься. Но зачем же себе жизнь так сильно усложнять? ИМХО, конечно.

    upd ты полностью извратил ту идею Димы Смирнова, которую он нёс. Говорил-то он про easy, а тут hard с надстройкой :).
     
  3. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    1. не надо комментировать каждую строчку.
    2. предвещаю тебе появление мозолей на подушечках пальцев ;-)
     
  4. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Кода много, толку мало.
    1). Зачем такие длинные названия? set/append/get/load хватает выше крыши. Очистка нафиг вообще нужна? Крайне глупо набирать кучу HTML'a а потом внезапно его обнулять. Это уже грубые ошибки в проэктировании - такого не должно быть в принципе. Если надо перезаписать какую-то переменную - это прекрасно делает set.
    2). Кешировщик в шаблонизаторе плохая идея. Почему? Потому что придёться использовать шаблонизаор там, где его быть не должно. До вызова метода/модуля.
    3). Кешировщик в шабонизаторе не даёт той гибкости, которую может дать отдельный кешировщик. Кеширующий движок должен уметь работать с несколькими типами кеша - HTML держать на фаиловой системе можно, прочий стафф в XCache/APC и Memcache в зависимости от того, нужны ли данные на нескольких серверах или только локально. Можно и HTML кеш там же держать, если его не очень много или хватает памяти. Надеюсь идею поняли.

    Шаблонизатор должен уметь только 3 вещи: Принимать данные, отдавать и загружать шаблоны. ВСЁ. Больше там __Н-И-Ч-Е-Г-О__ быть не должно.
     
  5. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Psih
    Не соглашусь... мне лично от хорошего шаблонизатора еще нужны возможности параметризованной вставки вспомогательного шаблона и враппинг. Без этого верстать сложные дизайны становится реально неудобно. А если по-хорошему, так уважающий себя шаблонизатор должен еще поддерживать модификаторы, генераторы простых конструкций (типа списка <option> у <select>) и шаблонные комментарии.
     
  6. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Dagdamor
    1). Помните я выкладывал свой движок? Парсер там простейший. Но сама структура позволяет делать сложные вещи. Всё что надо, это правильно по шаблонам расположить вызовы $parser->get(); и вовремя в нужные переменные подгрузить данные.
    http://blogs.boomtime.lv/Psih.html

    В чём фикус этой страницы - в том, что здесь 2 глобальных шаблона. Один layout сновной, а второй layout это где уже сам дневник. И каждый блок в этом большом блоке отдельный шаблон. Причём правая колонка строиться из вывода двух модулей. Вызываються они естественно сперва один, потом второй, только вот шаблоны там в перемешку проставленны и идут так:
    Код (Text):
    1. Blogs
    2. Blog
    3. Blog
    4. Blogs
    Хотя если заглянуть в контроллер, то вызова всего 2:
    PHP:
    1. <?php
    2. module('Blogs', RIGHT);
    3. module('Blog', RIGHT);
    4. ?>
    Так что при правильном проэктировании ничего лишнего не требуеться. А подгрузить дополнительный шаблон в другой шаблон - проще парёной репы: <?=$parser->load('template_name')?> - вот вам подгрузка другого шаблона прямо в шаблоне.

    Модификаторы? ЗАЧЕМ? DATE_FORMAT прекрасно делаеться в SQL.
    htmlspecialchars & co ? Сделайте это при раскрутке результата из базы, а в шаблоне просто надо просто ВЫВЕСТИ. В шаблоне должно быть МИНИМУМ КАКОГО-ЛИБО кода и МАКСИМУМ HTML'a (ну и JavaScript если надо)
     
  7. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Psih
    Форматирование даты - далеко не единственный пример модификатора. Да и не вижу я преимуществ в подготовке данных для шаблона на уровне SQL запросов.

    Во-первых, давай не будем кричать (аргументы от этого не станут более убедительными), во вторых - нет, неверно. Когда мы работаем в скрипте, мы не должны задумываться об особенностях вывода данных в HTML - это ипостась шаблонизатора, одна из его функций. Да и просто неудобно все данные, предназначенные для вывода в шаблоне, экранировать вручную.

    P.S. Сайт твой не открывается...
     
  8. AntonShevchuk

    AntonShevchuk Активный пользователь

    С нами с:
    6 июл 2007
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Kharkov
    Да я и не комментирую их особо - большинство комментариев - это шаблоны в Zend Studio...
     
  9. AntonShevchuk

    AntonShevchuk Активный пользователь

    С нами с:
    6 июл 2007
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Kharkov
    Насчет методов очистки переменных и тд - я тоже не особо вижу в них смысл - писал наверное уже по инерции...

    А вот кэширование вынесено в шаблонизатор, т.к. того требует разрабатываемая моим тимом CMF, данный шаблонизатор заточен под её нужды...

    И модификаторы, я считаю, должны быть в шаблонизаторе...
     
  10. ustas

    ustas Активный пользователь

    С нами с:
    17 сен 2007
    Сообщения:
    59
    Симпатии:
    0
    А что ты понимаешь под словом враппинг, я вот никак не пойму. Хотелось бы услышать твое мнение.
     
  11. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    ustas
    Враппинг (обертывание) - это возможность писать такое (пишу на примере своего шаблонизатора):

    Код (Text):
    1. <insert:myBlock title="Ссылки по теме">
    2.  
    3. <a href="http://php.net">php.net</a><br>
    4. <a href="http://php.ru">php.ru</a><br>
    5. <a href="http://php.com.ua">php.com.ua</a><br>
    6.  
    7. </insert:myBlock>
    где вспомогательный шаблон "myBlock" выглядит примерно так:

    Код (Text):
    1. <table border="1">
    2. <tr><td><var:title></td></tr>
    3. <tr><td><var:content></td></tr>
    4. </table>
    Здесь <var:title> выводит заголовок блока (переданный ему при вызове), а <var:content> подставляет "обернутый" фрагмент шаблона. Получается красиво оформленный блок с нужным тебе содержимым.
     
  12. ustas

    ustas Активный пользователь

    С нами с:
    17 сен 2007
    Сообщения:
    59
    Симпатии:
    0
    Dagdamor
    Вот блин, одни вещи разными словами пишем. Получается макрос = Враппинг . Спасибо.
     
  13. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    ustas
    Ну, враппинг (wrapping, wrap=обертывать) - все-таки более-менее официальный термин :)
    Если твой шаблонизатор поддерживает такую возможность, это хороший плюс, для меня во всяком случае.
     
  14. ustas

    ustas Активный пользователь

    С нами с:
    17 сен 2007
    Сообщения:
    59
    Симпатии:
    0
    вопрос другой, myBlock должен содержать php код для вставки, или результат выполнения php-кода.
    если первое, есть api для буфера php кода, наподобие ob_start
    function compiler_wraper($act, $parser) {
    $attr = $parser->parseDirectiveAttributes();
    if ($act == 1)
    parser->outputNew();
    else
    $buff = parser->outputGet();
    }

    {wraper атрибуты=блаблабла}

    любые команды, вложенные враперы, вставки и инклюды

    {/wraper}
    , если второе, то это банальный capture
     
  15. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    ustas
    Враппер должен быть динамическим, конечно же. Т.е. должна быть возможность делать в нем условия, циклы и прочее на основе переданных ему данных, то же самое в обертываемом фрагменте. В твоих терминах - это должен быть "php код для вставки", да.