PHP Classes

File: class-block_template.php

Recommend this page to a friend!
  Classes of Jonathan Gotti   Block template   class-block_template.php   Download  
File: class-block_template.php
Role: Class source
Content type: text/plain
Description: main class file
Class: Block template
Template engine based in the concept of blocks
Author: By
Last change: made it public
Date: 17 years ago
Size: 36,694 bytes


Class file image Download
<?php /** * manage the HTML output. * block_template is a template parser/renderer see the template sample for more info on the way the template work * @changelog 2005-12-07 - bugfixes _templatize didn't correctly send content parameter to _emit_signal method * 2005-09-30 - remove no more used footer property * - reset_ method now reset _sections property too * - clean the box method * 2005-09-28 - new parameter include_vars for method get_section_vars * 2005-07-13 - new predefined tag parameter 'require' for required vars in section includes * 2005-06-18 - new reset_ method * 2005-06-17 - new predefined tag parameter 'tagcontent' for open/close tags * - new predefined tag parameter 'preparse' to enable preparsing of parameter value * 2005-06-07 - now register_callback() will return a pointer * - add new method unregister_callback() * - new methods highlight_str() & highlight_template_file() * 2005-06-01 - add callback support on 'on-output' signal * - output can return var or file * - new set_safe_output method to protect block_template tags * - bugfixes no more problem on file finishing on a sectioname (@#sectioname) * 2005-05-24 - add new get_sections_select() method * 2005-05-18 - add comment line support (with #) * - new method choose_section * - bugfix to avoid infinite loop problem when including section into themselves * 2005-04-29 - removed some unused properties and method regarding sitename and page_title * clean some error notice * 2005-04-12 - add_css now support alternate stylesheets and direct css rules inputs, idem for js * 2005-03-14 - remove some deprecated methods (no more menu related methods) * - replace some deprecated method by some more logical ones * 2005-03-10 - *NEW callback support * - tags can now be closed with a / or by a closing tag and %= are replaced with @= * 2005-02-27 - add the content-type meta tag support and betterify the meta management * - add support for parameters in template tags ie: %=tagname param='value'=% * - menu entrys can now be passed as a full html by setting the URL to null */ class block_template{ /** where all the body content will go */ var $content; var $header; /** string favicon link tag */ var $favicon; /** array of css link tags */ var $css = array(); /** array of js link tags */ var $js = array(); /** string css definition that will go in the <style></style> tags inside the header */ var $_css; /** string javascript code that will go in the <script></script> tags inside the header */ var $_js; /** @private metas tags parameters */ var $metas = array(); /** * @param str $page_title * @param str $template_name (the directory containing the template must have the same name (case sensitive)) * @param str $template_dir directory containing templates subdirs */ function block_template($page_title,$template_name='default',$template_dir='template'){ $this->template_dir = $template_dir.(substr($template_dir,-1)=='/'?'':'/'); $this->template = $template_name?$template_name:'default'; $this->set_title($page_title); # essaie de charger le fichier de template $this->parse_template(); # ajoute les css par defaut if(is_file($css = $this->template_dir.$this->template.'/css.css')) $this->add_css($css); elseif(is_file($css = $this->template_dir.$this->template.'/'.$this->template.'.css')) $this->add_css($css); } /** * send the rendered html code to STD-OUT (browser) * cette fonction emetra le signal on-output voici prototype de rappelle callback(&$block_template,$vars,$return) * si la fonction de rapelle renvoie autrechose que FALSE alors la sortie sera remplacé * par la valeur retourné par la fonction de rappelle *@param array $vars same as setcionvars in *templatize* methods *@param mixed $return FALSE as default it will print the output to STDOUT as always * you can set it to true to get the output page return as a function returned value * and at last but not least you can pass a filename to save the document to. *@return void (if $return=FALSE)| string HTML code of the page (if $return=TRUE) | bool (if $return='/path/to/filesave'); */ function output($vars=null,$return=FALSE){ $out = $this->_emit_signal('on-output',$vars,$return); # return callback value if any if(! $return){ # DEFAULT CASE PRINT ON STDOUT if($out){ print($out); }else{ print("<html>\n"); print($this->_header()); print($this->_body($vars)); print('</html>'); } }elseif(is_string($return)){ if(! $fout = fopen($return,'w')) return FALSE; fwrite($fout,$out?$out:"<html>\n".$this->_header().$this->_body($vars).'</html>'); fclose($fout); return TRUE; }else{ return $out?$out:"<html>\n".$this->_header().$this->_body($vars).'</html>'; } } /* * You will probably never use this one but if you need to display block_template tags (@=tagname/=@) in the output * you can use this method to set the output safe. * WARNING: this method won't work when the output mode is value (block_template::output(null,TRUE)). * other way to say the same: it will only work in STDOUT and file output mode. * @param bool $set set it either true or false * @return handler | bool */ function set_safe_output($set=TRUE){ static $handle; if($set){ # renvoie le pointeur de callback if(isset($handle)) return $handle; else return $handle = $this->register_callback('on-output',array($this,'_safe_output')); # no need to work with reference as the emit_signal will send only a reference }elseif($handle){ # libere le pointeur de callback si existant $ret = $this->unregister_callback($handle); unset($handle); return TRUE; } return FALSE; } /** * internally used as callback to protect eventual block_template tags in the output * @see set_safe_output * @private */ function _safe_output($block_template,$vars,$return){ if($return && !is_string($return) ) return FALSE; # avoid inifnite loop so kill if not in stdout or file output mode # protect tags $block_template->content = str_replace('@=','@=__SAFE__',$block_template->content); if(! substr_count($block_template->content,'@=__SAFE__')) # no replacement so continue as always return FALSE; # some vars have been protected so we clean them return str_replace("@=__SAFE__","@=",$block_template->output($vars,1)); } /** * */ /** * parse a template file * @param string $template_file filepath to the template file * @param bool $overwrite will overwrite any previously loaded sections if a new one have the same name * @param bool $halt_on_error will stop the script execution on error else will return FALSE * @return bool * @todo add dynamic include support */ function parse_template($template_file=null,$overwrite=TRUE,$halt_on_error=TRUE){ if(! $template_file) $template_file = $this->template_dir.$this->template.'/template.php'; elseif( (! file_exists($template_file)) && file_exists($this->template_dir.$this->template.'/'.$template_file) ) $template_file = $this->template_dir.$this->template.'/'.$template_file; if(! ($template = @file_get_contents($template_file)) ){ if(! $halt_on_error){ return FALSE; }else{ echo "<b style='color:red;'>[TEMPLATE ERROR] can't open '$this->template' template files</b>"; exit(); } } # suppression des lignes de commentaires $template = preg_replace("!^\s*#[^\n]*$!m",'',$template); if(! preg_match_all("!(?:@#(\w+)\s*((?:[^@]+|@[^#])+)+)!",$template."\n",$m,PREG_SET_ORDER)) # add \n to correct a bug on last empty section loading return FALSE; foreach($m as $v){ if( (!$overwrite) && $this->section_exists($v[1])) continue; $this->_sections[$v[1]] = trim($v[2]); } return TRUE; } /** * clean all read template sections,all css rules and the template name. * @param string $template_name if passed then will load the new template files; * @param bool $full if set to true then will also clean page_title, favicon, content, js, metas, _header */ function reset_($template_name=null,$full=FALSE){ $this->_css = null; $this->css = array(); $this->template = null; $this->_sections = array(); if($full){ # reset others vars $this->_js = $this->favicon = $this->page_title = $this->content = $this->_header = null; $this->js = $this->metas = array(); } if(is_string($template_name)) $this->block_template($this->page_title,$template_name); } ##### SETTINGS METHODS##### /** * set the page title * @param string $title */ function set_title($title){ $this->page_title = strip_tags($title); } ###### ADD HEAD CONTENT METHODS ##### /** * add a favicon to the page */ function add_favicon($favicon){ $this->favicon = '<link rel="shortcut icon" href="'.$favicon.'" type="image/'.substr($favicon,strrpos('.',$favicon)+1).'">'; } /** * add an external css stylesheet or css header definition * @param string $css path to css file or css rules * @param string $title optionnal title for the stylesheet * @param bool $alternate set to true for alternate stylesheet */ function add_css($css,$title=null,$alternate=FALSE){ if(preg_match('!{[^}]+}!',$css)) # in this case we consider that we received a css string @$this->_css .= $css."\n"; else $this->css[] = '<link href="'.$css.'" rel="'.($alternate?'alternate ':'').'stylesheet" type="text/css" ' .(is_string($title)?"title=\"$title\" ":'').'/>'; } /** * add a javascript file or function in the header * @param string $js path to js file or javascript code to include in the header */ function add_js($js){ if(substr_count($js,';')) # in this case we consider that we received a js string @$this->_js .= $js."\n"; else $this->js[] = '<script src="'.$js.'" type="text/javascript" language="javascript"></script>'; } /** * prepare meta tags * be aware that multiple calls to this methods for the same type will only append to the previous setted tag. * in a word you can only set asingle meta tag for each type (so you can add keywords by successives call of this method usefull * when you want to dinamicly set it form your content) * @param string $content * @param string $type (publisher,keywords,robots,description,author,copyright,...) New refresh,no-cache */ function add_meta($content,$type='description',$lang=null){ $type = strtolower($type); if(! isset($this->metas[$type])) $this->metas[$type] = $content.($lang?"\" lang=\"$lang":''); else $this->metas[$type] .= $content.($lang?"\" lang=\"$lang":''); } /** * add a string to the header * @param string $str string to hadd in the <head></head> HTML tags */ function add_header($str){ @$this->_header .= "$str\n"; } ###### ADD BODY CONTENT METHODS ##### /** * ajoute du contenu dans la page */ function add_content($content){ if( func_num_args()>1) # @todo supprimer cette ligne # this is for old stuff detection you can safely delete those 2 lines show(print_r(func_get_args(),1).print_r(debug_backtrace(),1),red,1,1); $this->content .= $content; } /** * add content by calling the templatize method */ function add_templatize_content($vars,$sectioname){ if(! $this->section_exists($sectioname)){ $this->content .= '<b style="color:red;">Missing section '.$sectioname.'</b>'; }else{ $this->content .= $this->templatize($vars,$sectioname); } } function add_templatize_string_content($string,$sectionvars=null){ $this->content .= $this->templatize_string($string,$sectionvars=null); } /** * easy way to add a box to content, that's only a quick way of doing block_template::add_content(block_template::box($content,$title,$boxname)) * see box for more details */ function add_box_content($content,$title=null,$boxname=''){ if($str = $this->box($content,$title,$boxname)) $this->add_content($str); } /** * return a 'BOX_*' section in a more common way * BOX_* sections are section containings 2 vars boxtitle and boxcontent * this function is the same as calling block_template::templatize(array('boxtitle'=>'title','boxcontent'=>'content'),'BOX_NAME'); * @param string $content * @param string $title may be ommit * @param string $boxname the BOX_ section to use */ function box($content,$title='',$boxname=''){ if(! $boxname) $boxname = 'BOX'; if( substr($boxname,0,3) != 'BOX' ) $boxname = 'BOX_'.$boxname; # maintenant la boite if( $boxname = $this->choose_section(array($boxname,'BOX')) ) $out = $this->templatize(array('boxtitle'=>$title,'boxcontent'=>$content),$boxname); else $out = "<div id=\"$boxname\"'>".($title?"$title ":'')."$content</div>"; return $out; } /** * add some attribute to the body tag, an onload event for example * @param string $paramname name of the attribute * @param mixed $paramvalue value of the attribute */ function add_body_param($paramname,$paramvalue,$overwrite=FALSE){ if($overwrite) $this->body_params[$paramname] = $paramvalue; else $this->body_params[$paramname] .= $paramvalue; } ##### GESTION DES SIGNAUX ##### /** * enregistre une fonction de callback qui sera appelé lors de certains signaux. * @param string $signame nom du signal (on-load, on-output, on-templatize) * @param mixed $callback nom de la fonction de callback (peut prendre un tableau array($object,$method)) * @param string $tagtype type de tag sur lequel on applique le callback * 0|3| applique le callback sur tout les types de tag * 1| applique le callback uniquement au tag unique * 2| applique le callback sur des tags disposant de tag de fermeture * @param string $sectioname null par defaut, contraint le callback a la section précisé, ou toutes les sections si null * @see _emit_signal pour le prototype de rappelle * @return int callback handler id */ function register_callback($signame,$callback,$tagtype=3,$sectioname=null){ static $handlers=array() ,$hid=0; # gestion de pointeurs sur les signaux # dereferencement d'un signal pé-éxistant if( $signame=='-unregister-' && is_int($callback)){ # on detruit le pointeur sur ce signal if( count($handlers) <1 || ! is_array($h=$handlers[$callback]) ) # pointeur invalide return FALSE; unset($this->callbacks[$h[0]][$h[1]][$h[2]][$callback]); unset($handlers[$callback]); return TRUE; } # referencement du signal if($tagtype != 1 && $tagtype !=2) $tagtype = 3; if(! $sectioname>0) $sectioname = 'ALL'; $hid++; $this->callbacks[$signame][$tagtype][$sectioname][$hid] = $callback; $handlers[$hid] = array($signame,$tagtype,$sectioname); return $hid; } /** * permet de dereferencer un callback associé a un signal par le biais de la methode register_callback() * @param int $cb_handler pointeur de callback renvoyé par la methode register_callback() * @see register_callback() * @return bool */ function unregister_callback($cb_handler){ return $this->register_callback('-unregister-',$cb_handler); } /** * le prototype de la fonction de rappelle sera function callback(block_template object,$section,$tagname,$params,$content) * @private * cette methode est utilisé par l'objet en interne afin de gerer les signaux * @param string $signame nom du signal emis (on-templatize,on-output); * @see _templatize output */ function _emit_signal($signame,$params=null,$tagname=null,$content=null,$section=null){ $tagtype = (strlen($content)?2:1); if(! isset($this->callbacks[$signame])) return FALSE; # on test d'abord les callbacks restreint a cette section et a ce type de tag if(@is_array($this->callbacks[$signame][$tagtype][$section])){ foreach($this->callbacks[$signame][$tagtype][$section] as $cb){ $res = call_user_func($cb,&$this,$section,$tagname,$params,$content); if($res !== FALSE && $res !==null ) return $res; } } # ensuite ceux restreint a cette section quel que soit le type de tag if(@is_array($this->callbacks[$signame][3][$section])){ foreach($this->callbacks[$signame][3][$section] as $cb){ $res = call_user_func($cb,&$this,$section,$tagname,$params,$content); if($res !== FALSE && $res !==null ) return $res; } } # puis ceux restreint a ce type de tag if(@is_array($this->callbacks[$signame][$tagtype]['ALL'])){ foreach($this->callbacks[$signame][$tagtype]['ALL'] as $cb){ $res = call_user_func($cb,&$this,$section,$tagname,$params,$content); if($res !== FALSE && $res !==null ) return $res; } } # puis enfin les generalistes qui se foutent de la section ou du type de tag if(@is_array($this->callbacks[$signame][3]['ALL'])){ foreach($this->callbacks[$signame][3]['ALL'] as $cb){ $res = call_user_func($cb,&$this,$section,$tagname,$params,$content); if($res !== FALSE && $res !==null ) return $res; } } return FALSE; } ##### TEMPLATIZE METHODS ##### /* * will templatize your datas you can have as much vars as you like * optionnal sub section tag can be used by adding a * to the sectioname (ie: sectioname*) * if so thoose sections will be checked that there's either subsection or at least one not null (null or false but not 0) value in it * @param array $sectionvars is an indexed array with index in $sectionkey giving the correspoding datas * @param string $sectioname self explain * @param bool $section_optional (used in internal for optionnal sub section you'll normally never use this one by your own) */ function templatize($sectionvars,$sectioname,$section_optional=FALSE){ $sectioname = strtoupper($sectioname); if(! $this->section_exists($sectioname) ) return FALSE; $section = $this->_sections[$sectioname]; # recupere le contenu de la section # $section_keys = $this->get_section_vars($sectioname); # recupere les tags de la section return $this->_templatize($section,$sectionvars,$sectioname,$section_optional); } /** * parse la chaine $string comme une section de template. * Cela permet au programmeur de parser une chaine recue d'une base de données ou encore généré dynamiquement. * @note Cette méthode à été ajouter car elle me parassait apporter une certaine souplesse dans l'utilisation de block_template, * cependant n'en ayant jamais fait usage, je serais tres interresser d'etre informé de l'utilisation que vous pouriez en faire. */ function templatize_string($string,$sectionvars=null){ # $section_tags = $this->get_string_vars($string); return $this->_templatize($string,$sectionvars); } /** * methode interne pour les methodes 'templatize' * @see templatize,templatize_string * @private * @param string $section contenu de la section (ou chaine si on a appeller templatize_string) * @param array $sectionvars variables en provenance du programmeur * @param string $sectioname le nom de la section sur laquelle on travaille * @param bool $section_optional flag pour le traitement des sections incluse (par un tag) * @return string */ function _templatize($section,$sectionvars,$sectioname=null,$section_optional=FALSE){ # recuperation des variables if($sectioname && ($keys = $this->get_section_vars($sectioname)) ) $section_keys = &$keys; elseif($section && ($keys = $this->get_string_vars($section)) ) $section_keys = &$keys; if( @is_array($section_keys) ){ # ne traite les variables que si il y en a # on verifie que les sections optionnelles recoivent au moins une variable non null if( $section_optional){ if(isset($sectionvars['require'])){ # verifie les prérequis $required = explode(',',$sectionvars['require']); foreach($required as $req){ if(! (@$sectionvars[$req] || $this->section_exists($req))) return FALSE; } }else{ foreach($section_keys as $key){ if( $this->section_exists($key['tagname']) || (isset($sectionvars[$key['tagname']]) && $sectionvars[$key['tagname']]!='') ){ $vars=TRUE;break; } } if(! isset($vars)) return FALSE; } } if(! is_array($sectionvars)) $sectionvars = array(); # on remplace les tags foreach($section_keys as $var){ #preparation des parametres de la fonction de callback $_params = array_merge((array) @$var['params'],$sectionvars); # peparsing des parametre si demandé if(isset($_params['preparse'])){ if($preparse = explode(',',$_params['preparse'])){ unset($_params['preparse']); foreach($preparse as $k){ $_params[$k] = $this->templatize_string($_params[$k],$_params); } } } # emission du signal on-templatize sur ce tag $tmp_str = $this->_emit_signal('on-templatize',$_params,$var['tagname'] ,@$_params['tagcontent'],$sectioname); if($tmp_str!==FALSE){ $section = str_replace($var['str_replace'],$tmp_str,$section); continue; } # si le tag porte le nom d'une section on l'inclus if(isset($this->_sections[$var['tagname']])){ if( (! $var['is_optionnal']) && isset($_params['require'])) $var['is_optionnal']=TRUE; $section = str_replace($var['str_replace'],$this->templatize($_params,$var['tagname'],$var['is_optionnal']),$section); continue; } # prepare la valeur de remplacement if( isset($_params[$var['tagname']]) ){ # cherche un parametre du meme nom $value = $_params[$var['tagname']]; # on verifie que ce n'est pas une reference vers un autre parametre if( $value && $value[0]=='@' && isset($_params[substr($value,1)]) ){ $value = $_params[substr($value,1)]; } }elseif( isset($_params['default']) ){ # sinon prend la valeur par defaut $value = $_params['default']; }else{ $value = '' ; } # si c'est le nom d'une section on remplace par la section (pas d'inclusion optionnelle ici) if($this->section_exists($value) && $value !== $sectioname) $section = str_replace($var['str_replace'],$this->templatize($_params,$value),$section); else # sinon on remplace par sa valeur $section = str_replace($var['str_replace'],$value,$section); } } return $section; } ##### GETTING VARS ##### /** * renvoie les variables attendus par la section $sectioname du template * @param string $sectioname le nom de la section * @param bool $nocache par defaut vaut false ainsi les resultats sont gardé en cache de facon a accellerer les futures requetes. * il peut s'averer utile de ne pas caché ses resultats (pour une section appeller une seule fois par exemple) * auquel cas il suffit de passer cette option a TRUE * @param bool $include_vars par defaut vaut FALSE si passer a TRUE alors retourne aussi les variables attendu par les sections incluses ou imbriqués. * @return array or FALSE if none * the array will contain arrays(tagname,params,str_replace,is_optionnal[,content]) for complex vars, * where sectionvarname is equal to the sting return for single vars, params is an array of parameter array('paramname or int'=>'value',...) * and finally the original_tag which is the complete tag as it is in the template (will be use for string replacement) */ function get_section_vars($sectioname,$nocache=FALSE,$include_vars=FALSE){ static $sectionvars,$fullsectionvars; if(! $this->section_exists($sectioname)) # first of all check that the section exists return FALSE; if($include_vars){ # recursively append all included sections vars to the result if( (!$nocache) && @is_array($fullsectionvars[$sectioname]) ) # return cached datas if exists according to $nocache return $fullsectionvars[$sectioname]; # get first level sectionvars using or not cached datas if(! is_array($svars = $this->get_section_vars($sectioname,$nocache,FALSE)) ) return FALSE; # walk thru sectionvars to get vars of included sections. foreach($svars as $var){ if($this->section_exists($var['tagname']) && is_array($vars_ = $this->get_section_vars($var['tagname'],$nocache,TRUE)) ) foreach($vars_ as $vars__) $svars[] = $vars__; } if($nocache) return $svars; else return $fullsectionvars[$sectioname] = $svars; } if($nocache) # no cache so give the result as is return $this->get_string_vars($this->_sections[$sectioname]); # return cached content and create it if needed if(isset($sectionvars[$sectioname]) && is_array($sectionvars[$sectioname])) return $sectionvars[$sectioname]; else return $sectionvars[$sectioname] = $this->get_string_vars($this->_sections[$sectioname]); } /** * renvoie les variables contenue dans la chaine $string comme si c'était une section de template * @param string string * @todo devrait fonctionner selon un principe de 'pile' afin de permettre la lecture de tags imbriqués */ function get_string_vars($string){ # $tagexp = "!@=(\w+)(\*)?" # tagname # ."((?:[^@]+|[^=]@)+)?" # params #// ."(/)?=@((?(4)(.*?)@=/\\1=@))!s" ; # ."(?:/=@|=@(.*?)@=/\\2=@)!s" ; $tagexp = "!@=(\w+)(\*)?((?:\s+\w+(?:\s*=\s*([\"']).*?\\4))+)?\s*(?:/=@|=@(.*?)@=/\\1=@)!s"; # check single vars as needed if(! preg_match_all($tagexp,$string,$m,PREG_SET_ORDER)){ $vars = FALSE; }else{ foreach($m as $k=>$tagdata){ $vars[$k]['tagname'] = $tagdata[1]; $vars[$k]['is_optionnal'] = (bool) @$tagdata[2]; # $vars[$k]['is_optionnal'] = (bool) (substr($tagdata[1],-1)==='*'); if(isset($tagdata[3])){ preg_match_all("!\s+(\w+)(?:\s*=\s*(([\"'])?(?(3).*?\\3|[^\s=]+)))?!s",$tagdata[3],$m2,PREG_SET_ORDER); unset($params); foreach($m2 as $k2=>$v2){ if(! isset($v2[2])){ $params[] = $v2[1]; }else{ if(! isset($v2[3])) $params[$v2[1]] = $v2[2]; else eval('$params[$v2[1]] = '.$v2[2].';'); } } $vars[$k]['params'] = @$params; } if(isset($tagdata[5])){ # $vars[$k]['content'] = $tagdata[5]; # $vars[$k]['params']['tagcontent'] = $vars[$k]['content']; # Quick and dirty hack to enable the 'tagcontent' parameter $vars[$k]['params']['tagcontent'] = $tagdata[5]; } $vars[$k]['str_replace'] = $tagdata[0]; } } return $vars; } ##### MANIPULATION DES SECTIONS ##### /** * renvoie un tableau contenant le nom des sections disponibles dans le template * @return array or FALSE si pas de sections */ function get_sections(){ if(! is_array($this->_sections)) return FALSE; return array_keys($this->_sections); } /** * retourne le code html d'un element select contenant la liste des sections du template. * @param string $name nom de l'element de formulaire (valeur de l'attribut name de la balise select) * @param string $selected nom de la section preselectionnée (si null alors essaie de trouver une occurence dans _POST ou _GET) * @param bool $autoselect si oui alors ajoute un submit onchange * @param string $id attribut id optionnel de la balise select. * @return string HTML code */ function get_sections_select($name='template_section',$selected=null,$autoselect=TRUE,$id=null){ if(! $sections = $this->get_sections()) return "<b style='color:silver;'>Aucune section disponible</b>"; # try to find the selected value if(is_null($selected) && (isset($_GET[$name])||isset($_POST[$name])) ) $selected = (@$_POST[$name]?$_POST[$name]:(@$_GET[$name]?$_GET[$name]:null)); # make option list $opts[] = "<option value=\"\">- Sections du template $this->template -</option>"; foreach($sections as $sec){ $opts[] = "<option value=\"$sec\"".(($selected && $sec==$selected)?' selected="selected"':'')." >$sec</option>"; } return "\n\t<select name=\"$name\"".($autoselect?' onchange="if(this.value!=\'\')this.form.submit();"':'').(is_string($id)?" id=\"$id\"":'')." >\n\t\t".implode("\n\t\t",$opts)."\n\t</select>"; } /** * retourne le contenue d'une section de template tel quel sans le parser * @param string $sectioname * @return string */ function get_section($sectioname){ return $this->section_exists($sectioname)?$this->_sections[$sectioname]:FALSE; } /** * verifie qu'une section existe * @param string $sectioname nom de la section dont on veut verifier l'existence * @param bool $returnname si passer a TRUE alors la fonction retournera le nom de la section en cas de succes au lieu de TRUE * @return bool */ function section_exists($sectioname,$returnname=FALSE){ $ret = isset($this->_sections[$sectioname]); if($returnname && $ret) return $sectioname; return $ret; } /** * prend une liste de nom de section sous forme de tableau ou de chaine et retourne la premiere qui est trouvé. * cette fonction peut etre utile si votre application veut permettre l'utilisation de section par defaut au cas ou le * template ne fournirais pas la section données par exemple: block_template->choose_section('SEC1|SEC2|SEC3) testera successivement * les sections passé en arguments et retournera la premiere section existante. * @param mixed $section_list string('SEC1|SEC2...') ou array(SEC1,SEC2..) * @return string first section name matching an existing section or '' if no section match and false on input error */ function choose_section($section_list){ if(is_string($section_list)) $section_list = explode('|',$section_list); if(! is_array($section_list)) return FALSE; foreach($section_list as $v){ if($this->section_exists($v) ) return $v; } return ''; } /** * permet l'ajout dynamique de section par le programmeur * @param string $sectioname le nom de la section * @param string $section_content le contenu de la section * @param bool $overwrite si passe a TRUE alors ecrasera une eventuelle section existante au lieu de renvoyer FALSE */ function add_section($sectioname,$section_content='',$overwrite=FALSE){ if($overwrite || !$this->section_exists($sectioname) ) $this->_sections[$sectioname] = $section_content; else return FALSE; } /** * ajoute du contenu a la fin d'une section * @param string $sectioname le nom de la section * @param string $section_content contenu a ajouter * @param bool $autocreate TRUE par defaut, si FALSE ne creera pas la section si elle n'existe pas */ function append_section($sectioname,$section_content,$autocreate=TRUE){ if( (!$this->section_exists($sectioname)) && !$autocreate ) return FALSE; $this->_sections[$sectioname] = ($this->section_exists($sectioname)?$this->_sections[$sectioname]:'').$section_content; } /** * ajoute du contenu au debut d'une section * @param string $sectioname le nom de la section * @param string $section_content contenu a ajouter * @param bool $autocreate TRUE par defaut, si FALSE ne creera pas la section si elle n'existe pas */ function prepend_section($sectioname,$section_content,$autocreate=TRUE){ if( (!$this->section_exists($sectioname)) && !$autocreate ) return FALSE; $this->_sections[$sectioname] = $section_content.($this->section_exists($sectioname)?$this->_sections[$sectioname]:''); } ##### PREPARATION DES SORIES ##### /** *Prepare the header to output *@access Private */ function _header(){ $this->header = "<head>\n"; $this->header .= "<title>$this->page_title</title>\n"; # add the meta tags if($this->metas){ $equivs = array('content-type','refresh','pragma','expires'); foreach($this->metas as $name=>$value){ if(in_array($name ,$equivs)) $this->header .= "<meta http-equiv='$name' content='$value' />\n"; else $this->header .= "<meta name=\"$name\" content=\"$value\" />\n"; } } # add favicon if(is_string($this->favicon)) $this->header .= $this->favicon."\n"; # add css if(is_array($this->css)) $this->header .= implode("\n",$this->css); if(is_string($this->_css)) $this->header .= '<style type="text/css">'.$this->_css.'</style>'; # add js if(is_array($this->js)) $this->header .= implode("\n",$this->js); if(is_string($this->_js)) $this->header .= "<script type=\"text/javascript\" language=\"javascript\">\n<!--\n".$this->_js."\n//-->\n</script>"; # add user specific content $this->header .= (isset($this->_header)?$this->_header:'')."\n</head>\n"; return $this->header; } /** *Prepare the body content to output *@access Private *@todo supprimer les variables logo et consorts */ function _body($bodyvars=null){ if(! is_array($bodyvars)) $bodyvars = array(); # prepare les parametres du tag body if(@is_array($this->body_params)){ foreach($this->body_params as $paramname=>$paramvalue) $bodytag .= " $paramname=\"$paramvalue\""; $bodyvars['bodyparams'] = $bodytag; } $bodyvars['content'] = isset($this->content)?$this->content:''; return $this->body = $this->templatize($bodyvars,'BODY'); } /** * retourne le code de la chaine comme un code source de template avec coloration syntaxique au format html * @param str $str chaine de caractere a colorer * @param str $outfile nom de fichier de sortie optionnel, si fournis alors la sortie sera sauvegarder dans un fichier. */ function highlight_str($str,$outfile=null){ if(! is_string($str)) return FALSE; $str = htmlspecialchars($str); $str = preg_replace('!(@#\w+)!',"<b style='color:#3333cc;'>$1</b>",$str); $str = preg_replace('!(@=\w+)!',"<b style='color:#33cc33;'>$1",$str); $str = preg_replace('!(=@)!',"$1</b>",$str); # return "$str"; return "<code><pre>$str</pre></code>"; } function highlight_section($sectioname,$outfile=null){ return $this->highlight_str($this->_sections[$sectioname],$outfile); } function highlight_template_file($file=null,$outfile=null){ if(is_null($file)) $file = $this->template_dir.$this->template.DIRECTORY_SEPARATOR.'template.php'; return $this->highlight_str(join('',file($file)),$outfile); } } ?>