• elite核心类库之模板类


    模板类为系统核心类库,为能更好的组织主题,使模板更加高效。

    /**
     */
    class Template
    {
        private $_module = '';
        private $_controller = '';
        private $_method = '';
    
        private $_theme = NULL;
        private $_theme_path = NULL; //主题的路径可以在配置文件中设置
        private $_layout = FALSE; // By default, dont wrap the view with anything
        private $_layout_subdir = ''; // Layouts and partials will exist in views/layouts
        // but can be set to views/foo/layouts with a subdirectory
    
        private $_title = '';
        private $_metadata = array();
    
        private $_partials = array();
    
        private $_breadcrumbs = array();
    
        private $_title_separator = ' | ';
    
        private $_parser_enabled = TRUE;
        private $_parser_body_enabled = TRUE;
    
        private $_theme_locations = array();
    
        private $_is_mobile = FALSE;
    
        // 缓存保存的时间:分钟
        private $cache_lifetime = 0;
    
        private $_ci;
    
        private $_data = array();
    
        /**
         * Constructor - Sets Preferences
         *
         * The constructor can be passed an array of config values
         */
        function __construct($config = array())
        {
            $this->_ci =& get_instance();
    
            if ( ! empty($config))
            {
                $this->initialize($config);
            }
    
            log_message('debug', 'Template Class Initialized');
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Initialize preferences
         *
         * @access    public
         * @param    array
         * @return    void
         */
        function initialize($config = array())
        {
            foreach ($config as $key => $val)
            {
                if ($key == 'theme' AND $val != '')
                {
                    $this->set_theme($val);
                    continue;
                }
    
                $this->{'_'.$key} = $val;
            }
    
            // No locations set in config?
            if ($this->_theme_locations === array())
            {
                // Let's use this obvious default
                $this->_theme_locations = array(APPPATH . 'themes/');
            }
            
            // Theme was set
            if ($this->_theme)
            {
                $this->set_theme($this->_theme);
            }
    
            // If the parse is going to be used, best make sure it's loaded
            if ($this->_parser_enabled === TRUE)
            {
                $this->_ci->load->library('parser');
            }
    
            // Modular Separation / Modular Extensions has been detected
            if (method_exists( $this->_ci->router, 'fetch_module' ))
            {
                $this->_module     = $this->_ci->router->fetch_module();
            }
    
            // What controllers or methods are in use
            $this->_controller    = $this->_ci->router->fetch_class();
            $this->_method         = $this->_ci->router->fetch_method();
    
            // Load user agent library if not loaded
            $this->_ci->load->library('user_agent');
    
            // We'll want to know this later
            $this->_is_mobile    = $this->_ci->agent->is_mobile();
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Magic Get function to get data
         *
         * @access    public
         * @param      string
         * @return    mixed
         */
        public function __get($name)
        {
            return isset($this->_data[$name]) ? $this->_data[$name] : NULL;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Magic Set function to set data
         *
         * @access    public
         * @param      string
         * @return    mixed
         */
        public function __set($name, $value)
        {
            $this->_data[$name] = $value;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Set data using a chainable metod. Provide two strings or an array of data.
         *
         * @access    public
         * @param      string
         * @return    mixed
         */
        public function set($name, $value = NULL)
        {
            // Lots of things! Set them all
            if (is_array($name) OR is_object($name))
            {
                foreach ($name as $item => $value)
                {
                    $this->_data[$item] = $value;
                }
            }
    
            // Just one thing, set that
            else
            {
                $this->_data[$name] = $value;
            }
    
            return $this;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Build the entire HTML output combining partials, layouts and views.
         *
         * @access    public
         * @param    string
         * @return    void
         */
        public function build($view, $data = array(), $return = FALSE)
        {
            // Set whatever values are given. These will be available to all view files
            is_array($data) OR $data = (array) $data;
    
            // Merge in what we already have with the specific data
            $this->_data = array_merge($this->_data, $data);
    
            // We don't need you any more buddy
            unset($data);
    
            if (empty($this->_title))
            {
                $this->_title = $this->_guess_title();
            }
    
            // Output template variables to the template
            $template['title']    = $this->_title;
            $template['breadcrumbs'] = $this->_breadcrumbs;
            $template['metadata']    = implode("\n\t\t", $this->_metadata);
            $template['partials']    = array();
    
            // Assign by reference, as all loaded views will need access to partials
            $this->_data['template'] =& $template;
    
            foreach ($this->_partials as $name => $partial)
            {
                // We can only work with data arrays
                is_array($partial['data']) OR $partial['data'] = (array) $partial['data'];
    
                // If it uses a view, load it
                if (isset($partial['view']))
                {
                    $template['partials'][$name] = $this->_find_view($partial['view'], $partial['data']);
                }
    
                // Otherwise the partial must be a string
                else
                {
                    if ($this->_parser_enabled === TRUE)
                    {
                        $partial['string'] = $this->_ci->parser->parse_string($partial['string'], $this->_data + $partial['data'], TRUE, TRUE);
                    }
    
                    $template['partials'][$name] = $partial['string'];
                }
            }
    
            // Disable sodding IE7's constant cacheing!!
            $this->_ci->output->set_header('Expires: Sat, 01 Jan 2000 00:00:01 GMT');
            $this->_ci->output->set_header('Cache-Control: no-store, no-cache, must-revalidate');
            $this->_ci->output->set_header('Cache-Control: post-check=0, pre-check=0, max-age=0');
            $this->_ci->output->set_header('Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
            $this->_ci->output->set_header('Pragma: no-cache');
    
            // Let CI do the caching instead of the browser
            $this->_ci->output->cache($this->cache_lifetime);
    
            // Test to see if this file
            $this->_body = $this->_find_view($view, array(), $this->_parser_body_enabled);
    
            // Want this file wrapped with a layout file?
            if ($this->_layout)
            {
                // Added to $this->_data['template'] by refference
                $template['body'] = $this->_body;
    
                // Find the main body and 3rd param means parse if its a theme view (only if parser is enabled)
                $this->_body =  self::_load_view('layouts/'.$this->_layout, $this->_data, TRUE, self::_find_view_folder());
            }
    
            // Want it returned or output to browser?
            if ( ! $return)
            {
                $this->_ci->output->set_output($this->_body);
            }
    
            return $this->_body;
        }
    
        /**
         * Set the title of the page
         *
         * @access    public
         * @param    string
         * @return    void
         */
        public function title()
        {
            // If we have some segments passed
            if (func_num_args() >= 1)
            {
                $title_segments = func_get_args();
                $this->_title = implode($this->_title_separator, $title_segments);
            }
    
            return $this;
        }
    
    
        /**
         * Put extra javascipt, css, meta tags, etc before all other head data
         *
         * @access    public
         * @param     string    $line    The line being added to head
         * @return    void
         */
        public function prepend_metadata($line)
        {
            array_unshift($this->_metadata, $line);
            return $this;
        }
    
    
        /**
         * Put extra javascipt, css, meta tags, etc after other head data
         *
         * @access    public
         * @param     string    $line    The line being added to head
         * @return    void
         */
        public function append_metadata($line)
        {
            $this->_metadata[] = $line;
            return $this;
        }
    
    
        /**
         * Set metadata for output later
         *
         * @access    public
         * @param      string    $name        keywords, description, etc
         * @param      string    $content    The content of meta data
         * @param      string    $type        Meta-data comes in a few types, links for example
         * @return    void
         */
        public function set_metadata($name, $content, $type = 'meta')
        {
            $name = htmlspecialchars(strip_tags($name));
            $content = htmlspecialchars(strip_tags($content));
    
            // Keywords with no comments? ARG! comment them
            if ($name == 'keywords' AND ! strpos($content, ','))
            {
                $content = preg_replace('/[\s]+/', ', ', trim($content));
            }
    
            switch($type)
            {
                case 'meta':
                    $this->_metadata[$name] = '<meta name="'.$name.'" content="'.$content.'" />';
                break;
    
                case 'link':
                    $this->_metadata[$content] = '<link rel="'.$name.'" href="'.$content.'" />';
                break;
            }
    
            return $this;
        }
    
    
        /**
         * Which theme are we using here?
         *
         * @access    public
         * @param    string    $theme    Set a theme for the template library to use
         * @return    void
         */
        public function set_theme($theme = NULL)
        {
            $this->_theme = $theme;
            foreach ($this->_theme_locations as $location)
            {
                if ($this->_theme AND file_exists($location.$this->_theme))
                {
                    $this->_theme_path = rtrim($location.$this->_theme.'/');
                    break;
                }
            }
    
            return $this;
        }
    
        /**
         * Get the current theme
         *
         * @access public
         * @return string    The current theme
         */
         public function get_theme()
         {
             return $this->_theme;
         }
    
        /**
         * Get the current theme path
         *
         * @access    public
         * @return    string The current theme path
         */
        public function get_theme_path()
        {
            return $this->_theme_path;
        }
    
    
        /**
         * Which theme layout should we using here?
         *
         * @access    public
         * @param    string    $view
         * @return    void
         */
        public function set_layout($view, $_layout_subdir = '')
        {
            $this->_layout = $view;
    
            $_layout_subdir AND $this->_layout_subdir = $_layout_subdir;
    
            return $this;
        }
    
        /**
         * Set a view partial
         *
         * @access    public
         * @param    string
         * @param    string
         * @param    boolean
         * @return    void
         */
        public function set_partial($name, $view, $data = array())
        {
            $this->_partials[$name] = array('view' => $view, 'data' => $data);
            return $this;
        }
    
        /**
         * Set a view partial
         *
         * @access    public
         * @param    string
         * @param    string
         * @param    boolean
         * @return    void
         */
        public function inject_partial($name, $string, $data = array())
        {
            $this->_partials[$name] = array('string' => $string, 'data' => $data);
            return $this;
        }
    
    
        /**
         * Helps build custom breadcrumb trails
         *
         * @access    public
         * @param    string    $name        What will appear as the link text
         * @param    string    $url_ref    The URL segment
         * @return    void
         */
        public function set_breadcrumb($name, $uri = '')
        {
            $this->_breadcrumbs[] = array('name' => $name, 'uri' => $uri );
            return $this;
        }
    
        /**
         * Set a the cache lifetime
         *
         * @access    public
         * @param    string
         * @param    string
         * @param    boolean
         * @return    void
         */
        public function set_cache($minutes = 0)
        {
            $this->cache_lifetime = $minutes;
            return $this;
        }
    
    
        /**
         * enable_parser
         * Should be parser be used or the view files just loaded normally?
         *
         * @access    public
         * @param     string    $view
         * @return    void
         */
        public function enable_parser($bool)
        {
            $this->_parser_enabled = $bool;
            return $this;
        }
    
        /**
         * enable_parser_body
         * Should be parser be used or the body view files just loaded normally?
         *
         * @access    public
         * @param     string    $view
         * @return    void
         */
        public function enable_parser_body($bool)
        {
            $this->_parser_body_enabled = $bool;
            return $this;
        }
    
        /**
         * theme_locations
         * List the locations where themes may be stored
         *
         * @access    public
         * @param     string    $view
         * @return    array
         */
        public function theme_locations()
        {
            return $this->_theme_locations;
        }
    
        /**
         * add_theme_location
         * Set another location for themes to be looked in
         *
         * @access    public
         * @param     string    $view
         * @return    array
         */
        public function add_theme_location($location)
        {
            $this->_theme_locations[] = $location;
        }
    
        /**
         * theme_exists
         * Check if a theme exists
         *
         * @access    public
         * @param     string    $view
         * @return    array
         */
        public function theme_exists($theme = NULL)
        {
            $theme OR $theme = $this->_theme;
    
            foreach ($this->_theme_locations as $location)
            {
                if (is_dir($location.$theme))
                {
                    return TRUE;
                }
            }
    
            return FALSE;
        }
    
        /**
         * get_layouts
         * Get all current layouts (if using a theme you'll get a list of theme layouts)
         *
         * @access    public
         * @param     string    $view
         * @return    array
         */
        public function get_layouts()
        {
            $layouts = array();
    
            foreach(glob(self::_find_view_folder().'layouts/*.*') as $layout)
            {
                $layouts[] = pathinfo($layout, PATHINFO_BASENAME);
            }
    
            return $layouts;
        }
    
    
        /**
         * get_layouts
         * Get all current layouts (if using a theme you'll get a list of theme layouts)
         *
         * @access    public
         * @param     string    $view
         * @return    array
         */
        public function get_theme_layouts($theme = NULL)
        {
            $theme OR $theme = $this->_theme;
    
            $layouts = array();
    
            foreach ($this->_theme_locations as $location)
            {
                // Get special web layouts
                if( is_dir($location.$theme.'/views/web/layouts/') )
                {
                    foreach(glob($location.$theme . '/views/web/layouts/*.*') as $layout)
                    {
                        $layouts[] = pathinfo($layout, PATHINFO_BASENAME);
                    }
                    break;
                }
    
                // So there are no web layouts, assume all layouts are web layouts
                if(is_dir($location.$theme.'/views/layouts/'))
                {
                    foreach(glob($location.$theme . '/views/layouts/*.*') as $layout)
                    {
                        $layouts[] = pathinfo($layout, PATHINFO_BASENAME);
                    }
                    break;
                }
            }
    
            return $layouts;
        }
    
        /**
         * layout_exists
         * Check if a theme layout exists
         *
         * @access    public
         * @param     string    $view
         * @return    array
         */
        public function layout_exists($layout)
        {
            // If there is a theme, check it exists in there
            if ( ! empty($this->_theme) AND in_array($layout, self::get_theme_layouts()))
            {
                return TRUE;
            }
    
            // Otherwise look in the normal places
            return file_exists(self::_find_view_folder().'layouts/' . $layout . self::_ext($layout));
        }
    
        /**
         * load_view
         * Load views from theme paths if they exist.
         *
         * @access    public
         * @param    string    $view
         * @param    mixed    $data
         * @return    array
         */
        public function load_view($view, $data = array())
        {
            return $this->_find_view($view, (array)$data);
        }
    
        // find layout files, they could be mobile or web
        private function _find_view_folder()
        {
            if ($this->_ci->load->get_var('template_views'))
            {
                return $this->_ci->load->get_var('template_views');
            }
    
            // Base view folder
            $view_folder = APPPATH.'views/';
    
            // Using a theme? Put the theme path in before the view folder
            if ( ! empty($this->_theme))
            {
                $view_folder = $this->_theme_path.'views/';
            }
    
            // Would they like the mobile version?
            if ($this->_is_mobile === TRUE AND is_dir($view_folder.'mobile/'))
            {
                // Use mobile as the base location for views
                $view_folder .= 'mobile/';
            }
    
            // Use the web version
            else if (is_dir($view_folder.'web/'))
            {
                $view_folder .= 'web/';
            }
    
            // Things like views/admin/web/view admin = subdir
            if ($this->_layout_subdir)
            {
                $view_folder .= $this->_layout_subdir.'/';
            }
    
            // If using themes store this for later, available to all views
            $this->_ci->load->vars('template_views', $view_folder);
            
            return $view_folder;
        }
    
        // A module view file can be overriden in a theme
        private function _find_view($view, array $data, $parse_view = TRUE)
        {
            // Only bother looking in themes if there is a theme
            if ( ! empty($this->_theme))
            {
                foreach ($this->_theme_locations as $location)
                {
                    $theme_views = array(
                        $this->_theme . '/views/modules/' . $this->_module . '/' . $view,
                        $this->_theme . '/views/' . $view
                    );
    
                    foreach ($theme_views as $theme_view)
                    {
                        if (file_exists($location . $theme_view . self::_ext($theme_view)))
                        {
                            return self::_load_view($theme_view, $this->_data + $data, $parse_view, $location);
                        }
                    }
                }
            }
    
            // Not found it yet? Just load, its either in the module or root view
            return self::_load_view($view, $this->_data + $data, $parse_view);
        }
    
        private function _load_view($view, array $data, $parse_view = TRUE, $override_view_path = NULL)
        {
            // Sevear hackery to load views from custom places AND maintain compatibility with Modular Extensions
            if ($override_view_path !== NULL)
            {
                if ($this->_parser_enabled === TRUE AND $parse_view === TRUE)
                {
                    // Load content and pass through the parser
                    $content = $this->_ci->parser->parse_string($this->_ci->load->file(
                        $override_view_path.$view.self::_ext($view), 
                        TRUE
                    ), $data, TRUE);
                }
    
                else
                {
                    $this->_ci->load->vars($data);
                    
                    // Load it directly, bypassing $this->load->view() as ME resets _ci_view
                    $content = $this->_ci->load->file(
                        $override_view_path.$view.self::_ext($view),
                        TRUE
                    );
                }
            }
    
            // Can just run as usual
            else
            {
                // Grab the content of the view (parsed or loaded)
                $content = ($this->_parser_enabled === TRUE AND $parse_view === TRUE)
    
                    // Parse that bad boy
                    ? $this->_ci->parser->parse($view, $data, TRUE)
    
                    // None of that fancy stuff for me!
                    : $this->_ci->load->view($view, $data, TRUE);
            }
    
            return $content;
        }
    
        private function _guess_title()
        {
            $this->_ci->load->helper('inflector');
    
            // Obviously no title, lets get making one
            $title_parts = array();
    
            // If the method is something other than index, use that
            if ($this->_method != 'index')
            {
                $title_parts[] = $this->_method;
            }
    
            // Make sure controller name is not the same as the method name
            if ( ! in_array($this->_controller, $title_parts))
            {
                $title_parts[] = $this->_controller;
            }
    
            // Is there a module? Make sure it is not named the same as the method or controller
            if ( ! empty($this->_module) AND ! in_array($this->_module, $title_parts))
            {
                $title_parts[] = $this->_module;
            }
    
            // Glue the title pieces together using the title separator setting
            $title = humanize(implode($this->_title_separator, $title_parts));
    
            return $title;
        }
    
        private function _ext($file)
        {
            return pathinfo($file, PATHINFO_EXTENSION) ? '' : '.php';
        }
    }
  • 相关阅读:
    浅谈分布式 ID 的实践与应用
    Mobile DevOps 之 Proxmox 实现节流提效
    AI驱动的超分辨技术落地实践
    element ui 的 element-tree文字显示不全的问题
    Skype for business Server 2019 私有化部署
    VSCode+XAMAPP的PHP断点调试环境搭建XDebug
    Office的密码破和原理说明Excel,ppt,word
    Exchange2016 归档功能设置保留策略就地存档Archive
    基于windows server216自带的备份服务windows server backup
    C# 操作xml基础整理【转】
  • 原文地址:https://www.cnblogs.com/kelite/p/2892157.html
Copyright © 2020-2023  润新知