Template Selector plugin

This plugin has been superseded by the config plugin, which allows modification of all DokuWiki's configuration settings including the template

Admin Plugins | experimental |

This plugin enables you to interactively select the template for your wiki - from the list of installed templates. For more information on templates and a list of those available, refer to the page on Template.

I consider this plugin highly experimental as it modifies DokuWiki's local configuration file in a pretty simplistic manner, including (and not limited to) no file locking and outputting computed config values. As such please use this template with care.

For most installations I doubt that this plugin will have much use, however I find it particularly useful in maintaining the sidebar template. And perhaps someone else will draw inspiration from it and provide a plugin capable of interactively modifying any/all of DokuWiki's configuration settings. ;-)

Christopher Smith 2005-09-22 16:02

User Instructions

To use this plugin you must be logged into your wiki installation with superuser permissions - i.e. you have access to the Admin menu.

Select Template Selector from the Admin menu, then choose your template from the list shown. The template setting is changed immediately, however DokuWiki needs to be refreshed once more for you to see the new template. Simply, click the refresh button or any other DokuWiki button/link.

Configuration

The plugin has no configuration settings. However for it to work the webserver needs to be able to write to your local dokuwiki configuration file (normally conf/local.php) or to create that file if it doesn't exist.

Installation

Plugin sources: zip format (4k), tar.gz format (3k), darcs repository

If your wiki uses either the plugin manager or the darcs plugin you can use them with the links above to install the plugin.

To install the plugin manually, download the source to your plugin folder, lib/plugins, and extract its contents. That will create a new plugin folder, lib/plugins/tplselector, and install the plugin.

The folder will contain:

admin.php                              plugin script
lang/                                  root localisation folder
lang/xx/                               language folder(s), will always include ''en'' for english
lang/xx/lang.php                       localised language strings
lang/xx/tplfail.txt                    localised text file
lang/xx/tplnew.txt                     localised text file
lang/xx/tplselector.txt                localised text file
style.css                              specific styles for this plugin

The plugin is now installed.

Details

The plugin consists of six files, the plugin script, admin.php, some style rules in style.css plus several localised files.

admin.php

<?php
/**
 * Template Selector admin plugin
 *
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Christopher Smith <chris@jalakai.co.uk>
 */
 
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'admin.php');
 
/**
 * All DokuWiki plugins to extend the admin function
 * need to inherit from this class
 */
class admin_plugin_tplselector extends DokuWiki_Admin_Plugin {
 
    var $templates = array();
    var $_old = '';
    var $_new = '';
    var $_local = array();
    var $_backup = array();
    var $_ok = null;
 
    /**
     * return some info
     */
    function getInfo(){
 
      return array(
        'author' => 'Christopher Smith',
        'email'  => 'chris@jalakai.co.uk',
        'date'   => '2005-09-22',
        'name'   => 'Template Selector',
        'desc'   => "Interactive selection of installed dokuwiki templates",
        'url'    => 'http://www.dokuwiki.org/plugin:template selector',
      );
    }
 
    function getMenuSort() { return 100; }
 
    /**
     * handle user request
     */
    function handle() {
      global $conf;
 
      if (!isset($_REQUEST['tpl'])) return;                      // nothing to do
 
      // retrieve and validate form variables
      $tpl = trim($_REQUEST['tpl']);
 
      if ($tpl == $conf['template']) return;                     // same as current
 
      if (!count($this->templates)) $this->_build_templatelist();
      if (!in_array($tpl, $this->templates)) return;             // unknown template
 
      $this->_new = $tpl;
      $this->_old = $conf['template'];
 
      $this->_read_conflocal();    
      $this->_local['template'] = $tpl;
      $this->_ok = $this->_write_conflocal();
    }
 
    /**
     * output appropriate html
     */
    function html() {      
 
      if (!count($this->templates)) $this->_build_templatelist();      
 
      ptln('<div id="tplselector">');
 
      if ($this->_new) {
        if ($this->_ok === true) {
          print($this->locale_xhtml('tplnew'));
          ptln('  <form action="'.wl($ID).'" method="post">');
          ptln('    <fieldset>');
          ptln('      <input type="hidden" name="do"   value="admin" />');
          ptln('      <input type="hidden" name="page" value="tplselector" />');
          ptln('      <input type="submit" name="submit" value="'.$this->getLang('refresh').'" />');
          ptln('    </fieldset>');
          ptln('  </form>');
        } else {
          print($this->locale_xhtml('tplfail'));
		}
      } else {
        print($this->locale_xhtml('tplselector'));      
        $this->_html_templatelist();
      }
 
      ptln('</div>');
    }
 
    function _build_templatelist() {
 
      $list = array();
      $dir = DOKU_INC.'lib/tpl/';
 
      if ($dh = @opendir($dir)) {        
        while (false !== ($entry = readdir($dh))) {
          if ($entry == '.' || $entry == '..') continue;
 
          $file = (is_link($dir.$entry)) ? readlink($dir.$entry) : $entry;        
          if (is_dir($dir.$file)) $list[] = $entry;             
        }
        closedir($dh);
      }
      sort($list);
      $this->templates = $list;
    }
 
    function _html_templatelist() {
      global $conf;
 
      ptln('  <form action="'.wl($ID).'" method="post">');
      ptln('    <fieldset>');
      ptln('      <input type="hidden" name="do"   value="admin" />');
      ptln('      <input type="hidden" name="page" value="tplselector" />');
 
      foreach ($this->templates as $tpl) {
        if ($tpl == $conf['template']) {
          $current = ' current';
          $disabled = 'disabled="disabled"';
        } else {
          $current = '';
          $disabled = '';
        }
        ptln('<input type="submit" class="button'.$current.'" '.$disabled.' name="tpl" value="'.hsc($tpl).'" />', 6);
      }
 
      ptln('    </fieldset>');
      ptln('  </form>');
    }
 
    /*
     * read dokuwiki's local configuration file into $this->local
     */    
    function _read_conflocal() {
 
      $config = DOKU_CONF.'local.php';
      if (!@file_exists($config)) return;
 
      $contents = join('',@file($config));
      $php_open = ini_get('short_open_tag') ? '<\?' : '<\?php';
 
      preg_match('/(?<='.$php_open.').*?(?=$|\?>)/s', $contents, $match=array());
      $contents = join('\n',$match);
 
      // play safe
      $this->_saveconfig();
 
      eval($contents);
      $this->_local = $conf;
 
      $this->_restoreconfig();
    }
 
    /*
     * write $this->local to dokuwiki's local configuration file
     */
    function _write_conflocal() {
 
      $config = DOKU_CONF.'local.php';
      if (@file_exists($config)) {
        if (@file_exists($config.'.bak')) @unlink($config.'.bak');
        if (!@rename($config, $config.'.bak')) return false;
      }
 
      if (!$fh = @fopen($config, 'wb')) {
        @rename($config.'.bak', $config);
        return false;
      }	  
 
      $out = '<?php'."\n".
             "/*\n".
             " * Dokuwiki Local Configuration File \n".
             " * Auto-generated by ".$this->getPluginName()." plugin \n".
             " * Date: ".date('r')."\n".
             " */\n\n";
 
      $out .= $this->_out_local($this->_local, '$conf');
      $out .= "\n@include(DOKU_CONF.'local.protected.php');\n";
      $out .= "\n// end auto-generated content\n";
 
      @fwrite($fh, $out);
      fclose($fh);
      return true;
    }
 
    function _out_local($array, $prefix) {
 
      // translation string needs to be improved FIXME        
      $tr = array("\n"=>'\n', "\r"=>'\r', "\t"=>'\t', "\\" => '\\\\', "'" => '\\\'');
      $out = '';
 
      foreach ($array as $name => $val) {
        if (is_array($val)) {
          $out .= $this->_out_local($val, $prefix."['$name']");
        } else {
          $out .=  $prefix."['$name'] = '".strtr($val, $tr)."';\n";
        }
      }
 
      return $out;
    }
 
    function _saveconfig() {
        global $conf;
        $this->_backup = $conf;
    }
 
    function _restoreconfig() {
      global $conf;
      $conf = $this->_backup;
      $this->_backup = array();
    }
}

style.css

These may be modified to suit your own requirements.

/* plugin: tplselector styles */
 
#tplselector fieldset {
  border: none;
}
 
#tplselector .current {
  background: #dee7ec;
}
 
#tplselector .button { 
  width: 15em; 
  display: block; 
  padding: 2px; 
  margin: 0.5em;
}
 
/* end plugin: tplselector */

localised files

lang/en/lang.php

<?php
/**
 * english language file
 *
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Christopher Smith <chris@jalakai.co.uk>
 */
 
// settings must be present and set appropriately for the language
$lang['encoding']   = 'utf-8';
$lang['direction']  = 'ltr';
 
// for admin plugins, the menu prompt to be displayed in the admin menu
// if set here, the plugin doesn't need to override the getMenuText() method
$lang['menu'] = 'Template Selector ...'; 
$lang['refresh'] = 'refresh';

lang/en/tplselector.txt

====== Template Selector ======

Choose a template from the list shown below. \\ The template highlighted is your current template.

lang/en/tplnew.txt

====== Template Selector ======

Changing to a new template ...

The new template will start working after the next browser refresh.  
To return to the template selector menu use the button below.  
To return to other parts of DokuWiki use the appropriate buttons.

lang/en/tplfail.txt

====== Template Selector ======

Changing to a new template ... [[failed]]

The template selector was unable to change to the selected template.  
Please check the file permissions settings on your dokuwiki config folder (''conf'') and if it exists, 
your local configuration settings file (''conf/local.php'') file.  The settings need to be set so that 
your webserver can create files in the configuration folder and so it can write to the local configuration
settings file.

Revision History

  • 2005-09-22 — Released.

To Do

  • send a redirect after changing the template to skip the refresh step

Bugs

Discussion

Very good idea ! What must contain the .htaccess in the conf folder to be writable ?

.htaccess shouldn't have any affect. It controls Apache serving pages to the user not files which the scripts can access. Its the file systems permissions, I would think to use the same permissions you use for your wiki data pages.
Great plugin!

#Suggestion: If local.protected.php don't exists (first use) then rename current local.php to local.protected.php to preserve user conf.

#Suggestion: In local.protected.php file execute @include sentence before overwriting template value (if the user assigns a template in local.protected.php)

Natalia Pujol 2005-09-22 19:32
I forgot to mention local.protected.php. Its not a good idea to make a straight copy of the local.php to local.protected.php as if $conf['template'] is set in there it can't be altered. I made the file to allow derived values (i.e. ones that use other PHP variables values or expressions) to be protected. I'll update the above docs to describe it later.
So, if I have a local.php, the plugin simply overwrite it?
Can the plugin add $conf[template] to local.php if it don't have the line or change it if detected?
It doesn't overwrite it exactly. It moves local.php to local.php.bak and then rewrites it with the new template setting. Any settings which were in the original local.php are maintained (at the derived values). e.g. this is my local.php after rewriting
<?php
/*
 * Dokuwiki Local Configuration File 
 * Auto-generated by tplselector plugin 
 * Date: Thu, 22 Sep 2005 16:01:34 +0100
 */
 
$conf['title'] = 'j:insites';
$conf['template'] = 'sidebar-use';
$conf['htmlok'] = '0';
$conf['useheading'] = '1';
$conf['userewrite'] = '2';
$conf['useslash'] = '1';
$conf['canonical'] = '1';
$conf['useacl'] = '1';
$conf['superuser'] = '@admin';
$conf['mailguard'] = 'visible';
$conf['pluginmanager'] = '1';
$conf['subscribers'] = '1';
 
@include(DOKU_CONF.'local.protected.php');
 
// end auto-generated content

By dealing with the whole local.php file the basic concept can be easily extended to include any other config setting.

It would be better if the _read_conflocal() had an understanding of PHP syntax rather than using the php processor. It could then determine the actual setting (rather than its computed value) and maintain comments. I went with eval() for speed and simplicity. By adding a third method _edit_confsetting() to handle changing a particular value you would have an interface to local.conf independent of the plugin's other functions. The three functions could then be upgraded by whomever/whenever. — Christopher Smith 2005-09-23 10:53

How to set default template ?

This plugin is awesome since it can let users easily choose there favorite template. However, is there any possibility of configuring the “default” template (before user makes another choice) to something else than DokuWiki's default ?
Answer to myself : change the “default” folder in /lib/tpl 8-)
 
plugin/template_selector.txt · Last modified: 2008/12/18 00:32 by 70.103.232.219
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Imprint Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki
WikiForumIRCBugsGitXRefTranslate