This is an old revision of the document!
Table of Contents
xfortune Plugin
Compatible with DokuWiki
2006-03-05 and higher
The missing download url means that this extension cannot be installed via the Extension Manager. Please see Publishing a Plugin on dokuwiki.org. Recommended are public repository hosts like GitHub, GitLab or Bitbucket.
This extension has not been updated in over 2 years. It may no longer be maintained or supported and may have compatibility issues.
This plugin is able to read datafiles used by the popular Unix tool fortune and to display a random one. It then replaces the displayed one every few seconds with a new one using an AJAX request.
Usage
Just reference a textfile with the correct format with the following syntax:
{{xfortune>namespace:cookiefile.txt}}
You may specify the interval for changing the cookie in seconds:
{{xfortune>namespace:cookiefile.txt?15}}
The default is 30 seconds.
Input files
The cookie file needs to be a text file 1) where each cookie is separated by a % char on it's own line. You need to upload those files through the mediamanager.
Here is an example:
% My first cookie % Another cookie with multiple lines % Third cookie %
Code
Create a directory called xfortune
in the lib/plugins
directory and place the following files in there.
syntax.php
Create this file in lib/plugins/xfortune/syntax.php
- syntax.php
<?php /** * Display Fortune cookies * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Andreas Gohr <andi@splitbrain.org> */ 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.'syntax.php'); class syntax_plugin_xfortune extends DokuWiki_Syntax_Plugin { /** * return some info */ function getInfo(){ return array( 'author' => 'Andreas Gohr', 'email' => 'andi@splitbrain.org', 'date' => '2008-01-25', 'name' => 'Fortune Plugin', 'desc' => 'Displays random fortune cookies using AJAX requests', 'url' => 'http://www.dokuwiki.org/plugin:gallery', ); } /** * What kind of syntax are we? */ function getType(){ return 'substition'; } /** * What about paragraphs? */ function getPType(){ return 'block'; } /** * Where to sort in? */ function getSort(){ return 302; } /** * Connect pattern to lexer */ function connectTo($mode) { $this->Lexer->addSpecialPattern('\{\{xfortune>[^}]*\}\}',$mode,'plugin_xfortune'); } /** * Handle the match */ function handle($match, $state, $pos, &$handler){ $match = substr($match,11,-2); //strip markup from start and end $data = array(); //handle params list($cookie,$params) = explode('?',$match,2); //xfortune cookie file $data['cookie'] = cleanID($cookie); //time interval for changing cookies if(preg_match('/\b(\d+)\b/i',$params,$match)){ $data['time'] = $match[1]; }else{ $data['time'] = 30; } //no hammering please! if($data['time'] < 5) $data['time'] = 5; return $data; } /** * Create output */ function render($mode, &$renderer, $data) { if($mode == 'xhtml'){ $renderer->doc .= '<div id="plugin_xfortune">'; $renderer->doc .= $this->_getCookie($data['cookie']); $renderer->doc .= '</div>'; $renderer->doc .= $this->_script($data['cookie'],$data['time']); return true; } return false; } function _script($cookie,$time){ $str = '<script type="text/javascript" language="javascript">'; $str .= 'var plugin_xfortune_time = '.($time*1000).';'; $str .= 'var plugin_xfortune_cookie = \''.$cookie."';"; $str .= "addEvent(window,'load',plugin_xfortune);"; $str .= '</script>'; return $str; } /** * Returns one random cookie * * @author Andreas Gohr <andi@splitbrain.org> */ function _getCookie($cookie){ $file = mediaFN($cookie); if(!@file_exists($file)) return 'ERROR: cookie file not found'; $dim = filesize($file); if($dim < 2) return "ERROR: invalid cookie file $file"; mt_srand( (double) microtime() * 1000000); $rnd = mt_rand(0,$dim); $fd = fopen($file, 'r'); if (!$fd) return "ERROR: reading cookie file $file failed"; // jump to random place in file fseek($fd, $rnd); $text = ''; $line = ''; $cookie = false; $test = 0; while(true){ $seek = ftell($fd); $line = fgets($fd, 1024); if($seek == 0){ // start of file always starts a cookie $cookie = true; if($line == "%\n"){ // ignore delimiter if exists continue; }else{ // part of the cookie $text .= htmlspecialchars($line).'<br />'; continue; } } if(feof($fd)){ if($cookie){ // we had a cookie already, stop here break; }else{ // no cookie yet, wrap around fseek($fd,0); continue; } } if($line == "%\n"){ if($cookie){ // we had a cookie already, stop here break; }elseif($seek == $dim -2){ // it's the end of file delimiter, wrap around fseek($fd,0); continue; }else{ // start of the cookie $cookie = true; continue; } } // part of the cookie? if($cookie){ $text .= htmlspecialchars($line).'<br />'; } } fclose($fd); // if it is not valid UTF-8 assume it's latin1 if(!utf8_check($text)) return utf8_encode($text); return $text; } } //Setup VIM: ex: et ts=4 enc=utf-8 :
ajax.php
This is the backend to handle the AJAX requests. Put it into lib/plugins/xfortune/ajax.php
.
- ajax.php
<?php /** * AJAX Backend Function for plugin_xfortune * * @author Andreas Gohr <andi@splitbrain.org> */ //fix for Opera XMLHttpRequests if(!count($_POST) && $HTTP_RAW_POST_DATA){ parse_str($HTTP_RAW_POST_DATA, $_POST); } if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_INC.'inc/init.php'); //close sesseion session_write_close(); require_once(DOKU_INC.'inc/pageutils.php'); require_once(DOKU_INC.'inc/utf8.php'); require_once(DOKU_PLUGIN.'xfortune/syntax.php'); header('Content-Type: text/html; charset=utf-8'); $cookie = cleanID($_POST['cookie']); print syntax_plugin_xfortune::_getCookie($cookie); ?>
script.js
The needed JavaScript goes into lib/plugins/xfortune/script.js
- script.js
/** * Script for plugin_xfortune * * Fetches a new cookie * * @author Andreas Gohr <andi@splitbrain.org> */ function plugin_xfortune(){ if(!document.getElementById){ return; } var obj = document.getElementById('plugin_xfortune'); if(obj === null){ return; } // We use SACK to do the AJAX requests var ajax = new sack(DOKU_BASE+'lib/plugins/xfortune/ajax.php'); ajax_qsearch.sack.AjaxFailedAlert = ''; ajax_qsearch.sack.encodeURIString = false; // define callback ajax.onCompletion = function(){ var data = this.response; if(data === ''){ return; } var out = document.getElementById('plugin_xfortune'); out.style.visibility = 'hidden'; out.innerHTML = data; out.style.visibility = 'visible'; // restart timer window.setTimeout("plugin_xfortune()",plugin_xfortune_time); }; ajax.runAJAX('cookie='+encodeURI(plugin_xfortune_cookie)); }
style.css
Style your fortune cookies through this file: lib/plugins/xfortune/style.css
div#plugin_xfortune{ height: 120px; padding: 0.5em; margin: 1em; text-align: right; font-style: italic; overflow: auto; }
Known Shortcomings
- If your input files are not in UTF-8 this plugin will assume they are in latin1 and tries to convert them to UTF-8. If you get any charset problems, make sure the file is valid UTF-8.
- Using compiled fortune cookies may be more effective