CodeIgniter
[ class tree: CodeIgniter ] [ index: CodeIgniter ] [ all elements ]

Source for file Template.php

Documentation is available at Template.php

  1. <?php if (!defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3.  * CodeIgniter
  4.  *
  5.  * An open source application development framework for PHP 4.3.2 or newer
  6.  *
  7.  * @package CodeIgniter
  8.  * @author ExpressionEngine Dev Team
  9.  * @copyright Copyright (c) 2006, EllisLab, Inc.
  10.  * @license http://codeigniter.com/user_guide/license.html
  11.  * @link http://codeigniter.com
  12.  * @since Version 1.0
  13.  * @filesource
  14.  */
  15. // --------------------------------------------------------------------
  16. /**
  17.  * CodeIgniter Template Class
  18.  *
  19.  * This class is and interface to CI's View class. It aims to improve the
  20.  * interaction between controllers and views. Follow
  21.  *
  22.  * @link
  23.  * @package CodeIgniter
  24.  * @author Colin Williams
  25.  * @subpackage Libraries
  26.  * @category Libraries
  27.  * @link http://www.williamsconcepts.com/ci/libraries/template/index.html
  28.  * @copyright Copyright (c) 2008, Colin Williams.
  29.  * @version 1.4.1
  30.  */
  31. class CI_Template {
  32.     var $CI;
  33.     var $config;
  34.     var $template;
  35.     var $master_path;
  36.     var $regions = array('_scripts' => array(),
  37.         '_styles' => array(),
  38.         );
  39.     var $output;
  40.     var $js = array();
  41.     var $css = array();
  42.     var $parser = 'parser';
  43.     var $parser_method = 'parse';
  44.     var $parse_template = false;
  45.  
  46.     /**
  47.      * Constructor
  48.      *
  49.      * Loads template configuration, template regions, and validates existence of
  50.      * default template
  51.      *
  52.      * @access public
  53.      */
  54.  
  55.     function CI_Template()
  56.     {
  57.         // Copy an instance of CI so we can use the entire framework.
  58.         $this->CI = &get_instance();
  59.         // Load the template config file and setup our master template and regions
  60.         include(APPPATH 'config/template' EXT);
  61.         if (isset($template)) {
  62.             $this->config = $template;
  63.             // check if administration part is showing and select template
  64.             if ($this->CI->uri->segment(1== 'admin'{
  65.                 $this->set_template($template['admin_active_template']);
  66.             else {
  67.                 $is_set FALSE;
  68.                 if($this->CI->myauth->check()){
  69.                     $template_index $this->CI->entity_model->selectOne('user','template',array('username'=>$this->CI->myauth->getUser()),TRUE);
  70.                     if(isset($template[$template_index])){
  71.                         $this->set_template($template_index);
  72.                         $is_set TRUE;
  73.                     }
  74.                 }
  75.                 if(!$is_set$this->set_template($template['active_template']);
  76.             }
  77.         }
  78.     }
  79.     // --------------------------------------------------------------------
  80.     /**
  81.      * Use given template settings
  82.      *
  83.      * @access public
  84.      * @param string array key to access template settings
  85.      * @return void 
  86.      */
  87.  
  88.     function set_template($group)
  89.     {
  90.         if (isset($this->config[$group])) {
  91.             $this->template = $this->config[$group];
  92.         else {
  93.             show_error('The "' $group '" template group does not exist. Provide a valid group name or add the group first.');
  94.         }
  95.         $this->initialize($this->template);
  96.     }
  97.     // --------------------------------------------------------------------
  98.     /**
  99.      * Set master template
  100.      *
  101.      * @access public
  102.      * @param string filename of new master template file
  103.      * @return void 
  104.      */
  105.  
  106.     function set_master_template($filename)
  107.     {
  108.         if (file_exists(APPPATH 'views/' $filenameor file_exists(APPPATH 'views/' $filename EXT)) {
  109.             $this->master $filename;
  110.         else {
  111.             show_error('The filename provided does not exist in <strong>' APPPATH 'views</strong>. Remember to include the extension if other than ".php"');
  112.         }
  113.     }
  114.     // --------------------------------------------------------------------
  115.     /**
  116.      * Dynamically add a template and optionally switch to it
  117.      *
  118.      * @access public
  119.      * @param string array key to access template settings
  120.      * @param array properly formed
  121.      * @return void 
  122.      */
  123.  
  124.     function add_template($group$template$activate false)
  125.     {
  126.         if (isset($this->config[$group])) {
  127.             $this->config[$group$template;
  128.             if ($activate === true{
  129.                 $this->initialize($template);
  130.             }
  131.         else {
  132.             show_error('The "' $group '" template group already exists. Use a different group name.');
  133.         }
  134.     }
  135.     // --------------------------------------------------------------------
  136.     /**
  137.      * Get information about all templates
  138.      *
  139.      * @access public
  140.      * @return array 
  141.      */
  142.     function templates_info($type ''){
  143.         $infos array();
  144.         foreach($this->config as $index=>$template){
  145.             if (isset($template['template']&& (file_exists(APPPATH 'views/' $template['template''template.' $template['extension']))) {
  146.                 if($type == ''){
  147.                     if(!starts_with($template['template'],'admin')){
  148.                         $infos[$index;
  149.                     }
  150.                 }else{
  151.                     if(starts_with($template['template'],'admin')){
  152.                         $infos[$index;
  153.                     }
  154.                 }
  155.             }
  156.         }
  157.         return $infos;
  158.      }
  159.     // --------------------------------------------------------------------
  160.     /**
  161.      * Initialize class settings using config settings
  162.      *
  163.      * @access public
  164.      * @param array configuration array
  165.      * @return void 
  166.      */
  167.  
  168.     function initialize($props)
  169.     {
  170.         // Set master template
  171.         if (isset($props['template']&& (file_exists(APPPATH 'views/' $props['template''template.' $props['extension']))) {
  172.             $this->master $props['template''template.' $props['extension'];
  173.             // $this->master_path = APPPATH .'views/'. $props['template'];
  174.             $this->master_path = base_url('system/application/views/' $props['template'];
  175.         else {
  176.             // Master template must exist. Throw error.
  177.             show_error('Either you have not provided a master template or the one provided does not exist in <strong>' APPPATH 'views</strong>. Remember to set the extension');
  178.         }
  179.         // Load our regions
  180.         if (isset($props['regions'])) {
  181.             $this->set_regions($props['regions']);
  182.         }
  183.         // Set parser and parser method
  184.         if (isset($props['parser'])) {
  185.             $this->set_parser($props['parser']);
  186.         }
  187.         if (isset($props['parser_method'])) {
  188.             $this->set_parser_method($props['parser_method']);
  189.         }
  190.         // Set master template parser instructions
  191.         $this->parse_template = isset($props['parse_template']$props['parse_template'false;
  192.     }
  193.     // --------------------------------------------------------------------
  194.     /**
  195.      * Set regions for writing to
  196.      *
  197.      * @access public
  198.      * @param array properly formed regions array
  199.      * @return void 
  200.      */
  201.  
  202.     function set_regions($regions)
  203.     {
  204.         if (count($regions)) {
  205.             $this->regions = array('_scripts' => array(),
  206.                 '_styles' => array(),
  207.                 );
  208.             foreach ($regions as $key => $region{
  209.                 // Regions must be arrays, but we take the burden off the template
  210.                 // developer and insure it here
  211.                 if (is_array($region)) {
  212.                     $this->add_region($region);
  213.                 else {
  214.                     $this->add_region($key$region);
  215.                 }
  216.             }
  217.         }
  218.     }
  219.     // --------------------------------------------------------------------
  220.     /**
  221.      * Dynamically add region to the currently set template
  222.      *
  223.      * @access public
  224.      * @param string Name to identify the region
  225.      * @param array Optional array with region defaults
  226.      * @return void 
  227.      */
  228.  
  229.     function add_region($name$props array())
  230.     {
  231.         if (is_array($props)) {
  232.             $props array();
  233.         }
  234.  
  235.         if (isset($this->regions[$name])) {
  236.             $this->regions[$name$props;
  237.         else {
  238.             show_error('The "' $name '" region has already been defined.');
  239.         }
  240.     }
  241.     // --------------------------------------------------------------------
  242.     /**
  243.      * Empty a region's content
  244.      *
  245.      * @access public
  246.      * @param string Name to identify the region
  247.      * @return void 
  248.      */
  249.  
  250.     function empty_region($name)
  251.     {
  252.         if (isset($this->regions[$name]['content'])) {
  253.             $this->regions[$name]['content'array();
  254.         else {
  255.             show_error('The "' $name '" region is undefined.');
  256.         }
  257.     }
  258.     // --------------------------------------------------------------------
  259.     /**
  260.      * Set parser
  261.      *
  262.      * @access public
  263.      * @param string name of parser class to load and use for parsing methods
  264.      * @return void 
  265.      */
  266.  
  267.     function set_parser($parser$method null)
  268.     {
  269.         $this->parser = $parser;
  270.         $this->CI->load->library($parser);
  271.  
  272.         if ($method{
  273.             $this->set_parser_method($method);
  274.         }
  275.     }
  276.     // --------------------------------------------------------------------
  277.     /**
  278.      * Set parser method
  279.      *
  280.      * @access public
  281.      * @param string name of parser class member function to call when parsing
  282.      * @return void 
  283.      */
  284.  
  285.     function set_parser_method($method)
  286.     {
  287.         $this->parser_method = $method;
  288.     }
  289.     // --------------------------------------------------------------------
  290.     /**
  291.      * Write contents to a region
  292.      *
  293.      * @access public
  294.      * @param string region to write to
  295.      * @param string what to write
  296.      * @param boolean FALSE to append to region, TRUE to overwrite region
  297.      * @return void 
  298.      */
  299.  
  300.     function write($region$content$overwrite false)
  301.     {
  302.         if (isset($this->regions[$region])) {
  303.             if ($overwrite === true// Should we append the content or overwrite it
  304.                 $this->regions[$region]['content'array($content);
  305.             else {
  306.                 $this->regions[$region]['content'][$content;
  307.             }
  308.         }
  309.         // Regions MUST be defined
  310.         else {
  311.             show_error("Cannot write to the '{$region}regionThe region is undefined.");
  312.         }
  313.     }
  314.     // --------------------------------------------------------------------
  315.     /**
  316.      * Write content from a View to a region. 'Views within views'
  317.      *
  318.      * @access public
  319.      * @param string region to write to
  320.      * @param string view file to use
  321.      * @param array variables to pass into view
  322.      * @param boolean FALSE to append to region, TRUE to overwrite region
  323.      * @return void 
  324.      */
  325.  
  326.     function write_view($region$view$data null$overwrite false)
  327.     {
  328.         $args func_get_args();
  329.         // Get rid of non-views
  330.         unset($args[0]$args[2]$args[3]);
  331.         // Do we have more view suggestions?
  332.         if (count($args1{
  333.             foreach ($args as $suggestion{
  334.                 if (file_exists(APPPATH 'views/' $suggestion EXTor file_exists(APPPATH 'views/' $suggestion)) {
  335.                     // Just change the $view arg so the rest of our method works as normal
  336.                     $view $suggestion;
  337.                     break;
  338.                 }
  339.             }
  340.         }
  341.  
  342.         $content $this->CI->load->view($view$datatrue);
  343.         $this->write($region$content$overwrite);
  344.     }
  345.     // --------------------------------------------------------------------
  346.     /**
  347.      * Parse content from a View to a region with the Parser Class
  348.      *
  349.      * @access public
  350.      * @param string region to write to
  351.      * @param string view file to parse
  352.      * @param array variables to pass into view for parsing
  353.      * @param boolean FALSE to append to region, TRUE to overwrite region
  354.      * @return void 
  355.      */
  356.  
  357.     function parse_view($region$view$data null$overwrite false)
  358.     {
  359.         $this->CI->load->library('parser');
  360.  
  361.         $args func_get_args();
  362.         // Get rid of non-views
  363.         unset($args[0]$args[2]$args[3]);
  364.         // Do we have more view suggestions?
  365.         if (count($args1{
  366.             foreach ($args as $suggestion{
  367.                 if (file_exists(APPPATH 'views/' $suggestion EXTor file_exists(APPPATH 'views/' $suggestion)) {
  368.                     // Just change the $view arg so the rest of our method works as normal
  369.                     $view $suggestion;
  370.                     break;
  371.                 }
  372.             }
  373.         }
  374.  
  375.         $content $this->CI-> {
  376.             $this->parser-> {
  377.             $this->parser_method}
  378.         ($view$datatrue);
  379.         $this->write($region$content$overwrite);
  380.     }
  381.     // --------------------------------------------------------------------
  382.     /**
  383.      * Dynamically include javascript in the template
  384.      *
  385.      * NOTE: This function does NOT check for existence of .js file
  386.      *
  387.      * @access public
  388.      * @param string $ script to import or embed
  389.      * @param string $ 'import' to load external file or 'embed' to add as-is
  390.      * @param boolean $ TRUE to use 'defer' attribute, FALSE to exclude it
  391.      * @return TRUE on success, FALSE otherwise
  392.      */
  393.  
  394.     function add_js($script$type 'import'$defer false)
  395.     {
  396.         $success true;
  397.         $js null;
  398.  
  399.         $this->CI->load->helper('url');
  400.  
  401.         switch ($type{
  402.             case 'import':
  403.                 $filepath base_url($script;
  404.                 $js '<script type="text/javascript" src="' $filepath '"';
  405.                 if ($defer{
  406.                     $js .= ' defer="defer"';
  407.                 }
  408.                 $js .= "></script>";
  409.                 break;
  410.  
  411.             case 'embed':
  412.                 $js '<script type="text/javascript"';
  413.                 if ($defer{
  414.                     $js .= ' defer="defer"';
  415.                 }
  416.                 $js .= ">";
  417.                 $js .= $script;
  418.                 $js .= '</script>';
  419.                 break;
  420.  
  421.             default:
  422.                 $success false;
  423.                 break;
  424.         }
  425.         // Add to js array if it doesn't already exist
  426.         if ($js != null && !in_array($js$this->js)) {
  427.             $this->js[$js;
  428.             $this->write('_scripts'$js);
  429.         }
  430.  
  431.         return $success;
  432.     }
  433.     // --------------------------------------------------------------------
  434.     /**
  435.      * Dynamically include CSS in the template
  436.      *
  437.      * NOTE: This function does NOT check for existence of .css file
  438.      *
  439.      * @access public
  440.      * @param string $ CSS file to link, import or embed
  441.      * @param string $ 'link', 'import' or 'embed'
  442.      * @param string $ media attribute to use with 'link' type only, FALSE for none
  443.      * @return TRUE on success, FALSE otherwise
  444.      */
  445.  
  446.     function add_css($style$type 'link'$media false)
  447.     {
  448.         $success true;
  449.         $css null;
  450.  
  451.         $this->CI->load->helper('url');
  452.         $filepath $this->master_path . $style;
  453.         // $filepath = base_url() . $style;
  454.         switch ($type{
  455.             case 'link':
  456.  
  457.                 $css '<link type="text/css" rel="stylesheet" href="' $filepath '"';
  458.                 if ($media{
  459.                     $css .= ' media="' $media '"';
  460.                 }
  461.                 $css .= ' />';
  462.                 break;
  463.  
  464.             case 'import':
  465.                 $css '<style type="text/css">@import url(' $filepath ');</style>';
  466.                 break;
  467.  
  468.             case 'embed':
  469.                 $css '<style type="text/css">';
  470.                 $css .= $style;
  471.                 $css .= '</style>';
  472.                 break;
  473.  
  474.             default:
  475.                 $success false;
  476.                 break;
  477.         }
  478.         // Add to js array if it doesn't already exist
  479.         if ($css != null && !in_array($css$this->css)) {
  480.             $this->css[$css;
  481.             $this->write('_styles'$css);
  482.         }
  483.  
  484.         return $success;
  485.     }
  486.     // --------------------------------------------------------------------
  487.     /**
  488.      * Render the master template or a single region
  489.      *
  490.      * @access public
  491.      * @param string $ optionally opt to render a specific region
  492.      * @param boolean $ FALSE to output the rendered template, TRUE to return as a string. Always TRUE when $region is supplied
  493.      * @return void or string (result of template build)
  494.      */
  495.  
  496.     function render($region null$buffer false$parse false)
  497.     {
  498.         $this->write_view('menu''menu'array('menu' => $this->CI->menu->getMenu()));
  499.         // Just render $region if supplied
  500.         if ($region// Display a specific regions contents
  501.             if (isset($this->regions[$region])) {
  502.                 $output $this->_build_content($this->regions[$region]);
  503.             else {
  504.                 show_error("Cannot render the '{$region}regionThe region is undefined.");
  505.             }
  506.         }
  507.         // Build the output array
  508.         else {
  509.             foreach ($this->regions as $name => $region{
  510.                 $this->output[$name$this->_build_content($region);
  511.             }
  512.  
  513.             if ($this->parse_template === true or $parse === true{
  514.                 // Use provided parser class and method to render the template
  515.                 $output $this->CI-> {
  516.                     $this->parser-> {
  517.                     $this->parser_method}
  518.                 ($this->master$this->outputtrue);
  519.                 // Parsers never handle output, but we need to mimick it in this case
  520.                 if ($buffer === false{
  521.                     $this->CI->output->set_output($output);
  522.                 }
  523.             else {
  524.                 // Use CI's loader class to render the template with our output array
  525.                 $output $this->CI->load->view($this->master$this->output$buffer);
  526.             }
  527.         }
  528.  
  529.         return $output;
  530.     }
  531.     // --------------------------------------------------------------------
  532.     /**
  533.      * Load the master template or a single region
  534.      *
  535.      * DEPRECATED!
  536.      *
  537.      * Use render() to compile and display your template and regions
  538.      */
  539.  
  540.     function load($region null$buffer false)
  541.     {
  542.         $region null;
  543.         $this->render($region$buffer);
  544.     }
  545.     // --------------------------------------------------------------------
  546.     /**
  547.      * Build a region from it's contents. Apply wrapper if provided
  548.      *
  549.      * @access private
  550.      * @param string $ region to build
  551.      * @param string $ HTML element to wrap regions in; like '<div>'
  552.      * @param array $ Multidimensional array of HTML elements to apply to $wrapper
  553.      * @return string Output of region contents
  554.      */
  555.  
  556.     function _build_content($region$wrapper null$attributes null)
  557.     {
  558.         $output null;
  559.         // Can't build an empty region. Exit stage left
  560.         if (isset($region['content']or count($region['content'])) {
  561.             return false;
  562.         }
  563.         // Possibly overwrite wrapper and attributes
  564.         if ($wrapper{
  565.             $region['wrapper'$wrapper;
  566.         }
  567.         if ($attributes{
  568.             $region['attributes'$attributes;
  569.         }
  570.         // Open the wrapper and add attributes
  571.         if (isset($region['wrapper'])) {
  572.             // This just trims off the closing angle bracket. Like '<p>' to '<p'
  573.             $output .= substr($region['wrapper']0strlen($region['wrapper']1);
  574.             // Add HTML attributes
  575.             if (isset($region['attributes']&& is_array($region['attributes'])) {
  576.                 foreach ($region['attributes'as $name => $value{
  577.                     // We don't validate HTML attributes. Imagine someone using a custom XML template..
  578.                     $output .= " $name=\"$value\"";
  579.                 }
  580.             }
  581.  
  582.             $output .= ">";
  583.         }
  584.         // Output the content items.
  585.         foreach ($region['content'as $content{
  586.             $output .= $content;
  587.         }
  588.         // Close the wrapper tag
  589.         if (isset($region['wrapper'])) {
  590.             // This just turns the wrapper into a closing tag. Like '<p>' to '</p>'
  591.             $output .= str_replace('<''</'$region['wrapper']"\n";
  592.         }
  593.  
  594.         return $output;
  595.     }
  596. }
  597. // END Template Class
  598. /* End of file Template.php */
  599. /* Location: ./system/application/libraries/Template.php */

Documentation generated on Sun, 11 Jan 2009 04:21:13 +0100 by phpDocumentor 1.4.1