Skip to content
Derek Jones edited this page Jul 5, 2012 · 7 revisions

Introduction

I have whipped up a very simple and easy-to-use library for automatically building sitemaps for your CodeIgniter web application.

Features

  • NEW: generate() method to build a complete site map
  • NEW: easy filtering in case you want to exclude certain controllers or method names (see the sample controller below)
  • Supports templates
  • Can be used to just show pages in one specific controller via the get_links() method

Requirements

  • CodeIgniter (Built on version 1.53, should work with later versions fine)
  • Extended Parser class -- I created an extension of the parser class, which simply adds a method called sparse() which will allow you to parse a template stored as a string variable instead of a file. You can get the extended library below.
  • PHP5. This library uses PHP5's Reflection class to analyze CodeIgniter controllers.

Sample controller

<?php

class Sitemap extends Controller {

    function Sitemap()
    {
        parent::Controller();
            $this->load->library('sitemap'); 
    }
    
    function index()
    {
        // Show the index page of each controller (default is FALSE)
        $this->sitemap->set_option('show_index', true);

        // Exclude all methods from the "Test" controller
        $this->sitemap->ignore('Test', '*');

        // Exclude all methods from the "Job" controller
        $this->sitemap->ignore('Job', '*');

        // Exclude a list of methods from any controller
        $this->sitemap->ignore('*', array('view', 'create', 'edit', 'delete'));

        // Exclude this controller
        $this->sitemap->ignore('Sitemap', '*'); 

        // Show the sitemap
        echo '<h1>Sitemap</h1>';
        echo $this->sitemap->generate();
    }
}

?>

Setup

Just copy and paste both of the libraries below into your application/libraries folder:

Sitemap.php

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
 * A very simple sitemap link generator
 *
 * This class uses the PHP5 Reflection class to find all the public methods
 * in a CodeIgniter controller class and generate a list of links.
 *
 * @author         Jonathon Hill 
 * @license        CodeIgniter license
 * @requires    MY_Parser extended Parser class [added sparse() for parsing templates stored in a string var]
 * @requires    CodeIgniter 1.6 and PHP5
 * @version        1.1
 *
 */
class Sitemap {


    /**
     * CodeIgniter base object reference
     *
     * @var object
     */
    private $CI;


    /**
     * Sitemap links template
     *
     * @var string
     */
    private $template = '

{section_text}

'
; private $template_file; // optional sitemap template file /** * Hide the index page by default * * @var boolean */ private $show_index = false; /** * Method names to ignore * * @var array */ private $ignore = array( '*' => array( 'get_instance', 'controller', 'ci_base' ) ); /** * Sitemap object initialization * */ function __construct() { $this->CI =& get_instance(); $this->CI->load->library('parser'); } /** * Set configuration option(s). * * Usage: * $this->sitemap->set_option($option, $value); * $this->sitemap->set_option(array( * 'option' => 'value', * ... * )); * * Options: * template (string) template stored in string * template_file (string) template stored in file * show_index (bool) show or hide the index page * * @param mixed $option * @param mixed $value * @return boolean */ function set_option($option, $value) { if(is_array($option)) { foreach($option as $opt => $val) { if($opt == 'ignore') continue; if(isset($this->$opt)) $this->$opt = $val; } return true; } elseif(isset($this->$option) && $option != 'ignore') { $this->$option = $value; return true; } else { return false; } } /** * Return a configuration option * * @param string $option * @return mixed */ function get_option($option) { return ($this->$option)? $this->option : false; } /** * Ignore a controller or specific pages in a controller * Usage: * $this->sitemap->ignore('controller', '*'); // completely ignore a controller * $this->sitemap->ignore('controller', array('page1', 'page2')); // ignore certain pages * * * @param string $controller * @param mixed $pages */ function ignore($controller, $pages) { $controller = strtolower($controller); if(is_array($pages)) { array_walk_recursive($pages, 'Sitemap::stl_callback'); } else { $pages = strtolower($pages); } if(isset($this->ignore[$controller]) AND is_array($this->ignore[$controller])) $pages = array_merge($this->ignore[$controller], (array) $pages); $this->ignore[$controller] = $pages; } /** * Build a list of pages in a controller * * @param string $page (optional) Build all the links for a specific controller * @return string */ function get_links($class = null) { // Use the PHP5 Reflection class to introspect the controller $controller = new ReflectionClass($class); $data['links'] = array(); $data['section_index'] = strtolower(site_url($class)); $data['section_text'] = ucwords(strtr($class, array('_'=>' '))); foreach($controller->getMethods() as $method) { // skip methods that begin with '_' if(substr($method->name, 0, 1) == '_') continue; // skip globally ignored names if(in_array(strtolower($method->name), $this->ignore['*'])) continue; // skip ignored controller methods if(isset($this->ignore[strtolower($class)]) AND in_array(strtolower($method->name), (array) $this->ignore[strtolower($class)])) continue; // skip index page if($method->name == 'index' && !$this->show_index) continue; // skip old-style constructor if(strtolower($method->name) == strtolower($class)) continue; // skip methods that aren't public if(!$method->isPublic()) continue; // build link data for parser class $data['links'][] = array( 'link_url' => strtolower(site_url("$class/$method->name")), 'link_text'=> ucwords(strtr($method->name, array('_'=>' '))), ); } return ($this->template_file)? $this->CI->parser->parse($this->template_file, $data, true) : $this->CI->parser->sparse($this->template, $data, true); } /** * Build a complete sitemap from your CI application controllers * * @return string */ function generate() { $this->CI->load->helper('file'); $sitemap = ''; $controllers_path = APPPATH.'controllers/'; foreach(get_filenames($controllers_path, true) as $controller) { list($class, $ext) = explode('.', ucfirst(basename($controller))); if($ext != 'php') continue; // skip anything other than PHP files if(isset($this->ignore[strtolower($class)]) AND $this->ignore[strtolower($class)] == '*') continue; // skip controllers marked as 'ignore' if(!class_exists($class)) include($controller); // include the class for access $sitemap .= $this->get_links($class) . "\n"; } return $sitemap; } /* * Callback wrapper function for strtolower * Has 2 args to prevent warnings from the strtolower() function */ static function stl_callback($a, $b) { return strtolower($a); } }

MY_Parser.php

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

// ------------------------------------------------------------------------

/**
 * Sparser Class
 *
 * @package        CodeIgniter
 * @subpackage    Libraries
 * @category    Parser
 * @author        Jonathon Hill
 * @link        jhill@goyoders.com
 */
class MY_Parser extends CI_Parser {

    /**
     *  Parse a string
     *
     * Parses pseudo-variables contained in the specified string,
     * replacing them with the data in the second param
     *
     * @access    public
     * @param    string
     * @param    array
     * @param    bool
     * @return    string
     */
    function sparse($template, $data, $return = FALSE)
    {
        $CI =& get_instance();
        
        if ($template == '')
        {
            return FALSE;
        }
        
        foreach ($data as $key => $val)
        {
            if (is_array($val))
            {
                $template = $this->_parse_pair($key, $val, $template);        
            }
            else
            {
                $template = $this->_parse_single($key, (string)$val, $template);
            }
        }
        
        if ($return == FALSE)
        {
            $CI->output->final_output = $template;
        }
        
        return $template;
    }
    
}
// END Sparser Class
?>

Clone this wiki locally