Version: 2.0
Type: Class
Category: Other
License: GNU General Public License
Description: Guise is a template class written in PHP that allows you to keep HTML seperate from your PHP code. This is especially helpful for larger projects or when you’re working with a team in keeping things organized and readable.
<?php /** * Guise Template Class 2.0 * (c)2008 TD Fellows * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /**#@+ * Constants */ /** * New Line */ define( 'GUISE_NL', "n" ); /** * @author TD Fellows <[email protected]> * @copyright 2008 TD Fellows * @version 2.0 * @package Guise */ class Guise { /** * The last occuring error. * * @access public * @var string */ public $errstr = ''; /**#@+ * Private variables * @access private */ /** * With Debugging enabled, errors will be verbose. * * @var boolean */ private $debugging = false; /** * Array containing structured template data. * * @var array */ private $template_items = array(); /** * Array containing structured template data. * * @var array */ private $block_templates = array(); /** * Root template directory. * * @var string */ private $template_root = ''; /**#@-*/ /**#@+ * Public functions * @access public */ /** * Constructor. * * @param string $path Path to template directory * @param boolean $debug Enables debugging */ public function Guise( $path = '/', $debug = false ) { if ( !$this->set_root( $path ) ) { return false; } else { $this->debugging = $debug; return true; } } /** * Clear item and block template arrays. */ public function clear() { $this->template_items = array(); $this->block_templates = array(); } /** * Set template root directory. {@link $template_root} * * @param string $path Path to template directory * @return boolean */ public function set_root( $path ) { if ( substr( $path, -1 ) != '/' ) { $path .= '/'; } if ( is_dir( $path ) ) { $this->template_root = $path; return true; } else { $this->set_error( 'Guise->set_root', "(<b>$root</b>) is not a valid directory." ); return false; } } /** * Add an item or array to the item array. * * @param string $item_name Name of variable or array * @param string $item_value Value of variable * @return boolean */ public function add_item( $item_name, $item_value = null ) { if ( is_array( $item_name ) ) { foreach( $item_name as $key => $value ) { $this->template_items[$key] = $value; } return true; } else { if ( empty( $item_name ) ) { $this->set_error( 'Guise->add_item', 'item name must not be empty.' ); return false; } else { $this->template_items[$item_name] = $item_value; return true; } } } /** * Compile files with structured array. * * @param string $files List of files to be parsed seperated by commas. * @return string|boolean */ public function compile( $files ) { $handle = 0; $page = ''; $line = ''; $file_list = explode( ',', $files ); foreach( $file_list as $file ) { if ( substr( $file, 1, 2 ) != ":/" && substr( $file, 0, 1 ) != "/" ) { $file = $this->template_root.$file; } if ( !file_exists( $file ) ) { $this->set_error( 'Guise->compile', "(<b>$file</b>) no such file." ); return false; } else { $handle = @fopen( $file, 'r' ); } if ( $handle ) { while ( !feof( $handle ) ) { $line = fgets( $handle ); if ( preg_match( '/^(.*?)(<block(.*?)name=("|')(.*?)("|')(.*?)>)(.*?)$/i', $line, $block_matches ) ) { $line = $this->load_blocks( $handle, $block_matches ); } if ( preg_match_all( '/<item(.*?)name=("|')(.*?)("|')(.*?)>/i', $line, $vars ) ) { foreach( $vars[0] as $key => $value ) { $line = str_replace( $value, $this->template_items[$vars[3][$key]], $line ); } } if ( preg_match_all( '/("|')(item.([a-z0-9_]*))("|')/i', $line, $vars ) ) { foreach( $vars[2] as $key => $value ) { $line = str_replace( $value, $this->template_items[$vars[3][$key]], $line ); } } $page .= $line; } } else { $this->set_error( 'Guise->compile', "(<b>$file</b>) unable to open stream." ); return false; } } $page = $this->compile_blocks( $this->template_items, $page ); $page = $this->cleanup( $page ); return $page; } /**#@-*/ /**#@+ * Private functions * @access private */ /** * Remove left over template information. * * @param string $string The string to be cleaned * @return string */ private function cleanup( $string ) { $matches = array( "/<item(.*?)>/i", "/<block(.*?)>/i" ); $string = preg_replace( $matches, "", $string ); if ( preg_match( '/</block>/', $string ) ) { $this->set_error( 'Guise->compile', 'invalid block usage. One or more blocks may not be parsed.' ); } return $string; } /** * Set last occuring error, echo on debug. * * @param string $subject Where the error was encountered * @param string $error Error string */ private function set_error( $subject, $error ) { $this->last_error = "<br /><b>Warning</b>: $subject, $error<br />"; if ( $this->debugging ) { echo $this->last_error; } } /** * Move block templates from the main template to an array. * * @param integer $handle File handle * @param string $block_matches Array from preg_match matching start of block * @return string */ private function load_blocks( $handle, $block_matches ) { if ( trim( $block_matches[1] ) != '' ) { $source_tpl = $block_matches[1]; } if ( trim( $block_matches[8] ) != '' ) { $block_tpl = $block_matches[8].GUISE_NL; } $block_name = $block_matches[5]; if ( empty( $block_name ) ) { $this->set_error( 'Guise->compile', 'invalid BLOCK format. NAME attribute must contain a value.' ); $source_tpl = $block_matches[0]; return $source_tpl; } else { $source_tpl .= "<block name='$block_name'>"; } while ( !feof( $handle ) ) { $line = fgets( $handle ); if ( preg_match( '/^(.*?)</block>(.*?)$/i', $line, $end_matches ) ) { if ( trim( $end_matches[1] ) != '' ) { $block_tpl .= $end_matches[1]; } $source_tpl .= $end_matches[2]; break; } elseif ( preg_match( '/^(.*?)(<block(.*?)name=("|')(.*?)("|')(.*?)>)(.*?)$/i', $line, $child_matches ) ) { $block_tpl .= $this->load_blocks( $handle, $child_matches ); } else { $block_tpl .= $line; } } $this->block_templates[$block_name] = $block_tpl; return $source_tpl; } /** * Compile blocks. * * @param array $start_array Point in the item array to begin parsing * @param string $source_tpl The source template, either a page or block * @return string */ private function compile_blocks( $start_array, $source_tpl ) { $result = $source_tpl; $cycle_result = ''; $block_name = ''; $block_tpl = ''; foreach( $start_array as $start_key => $start_value ) { if ( is_array( $start_array[$start_key] ) ) { $block_name = $start_key; $block_tpl = $this->block_templates[$start_key]; for ( $i=0; ;$i++ ) { if ( array_key_exists( $i, $start_array[$block_name] ) ) { $cycle_result = $block_tpl; foreach( $start_array[$block_name][$i] as $contents_key => $contents_value ) { if ( is_array( $contents_value ) ) { $cycle_result = $this->compile_blocks( $start_array[$block_name][$i], $cycle_result ); } else { $cycle_result = preg_replace( "/<item(.*?)name=("|')$contents_key("|')(.*?)>/i", $contents_value, $cycle_result ); $cycle_result = preg_replace( "/("|')(item.($contents_key))("|')/i", '"'.$contents_value.'"', $cycle_result ); } } $result = str_replace( "<block name='$block_name'>", $cycle_result."<block name='$block_name'>", $result ); } else { break; } } } } return $result; } /**#@-*/ } ?>