The toolbar makes DokuWiki easy to use even for novice users. Sometimes you may want to extend the toolbar with another button. This page will tell you a bit how the toolbar works and how to extend it.
The toolbar is completely built through JavaScript. Which buttons the toolbar contains, is read from an array called toolbar. This array is initialized in /lib/exe/js.php. This is simply done by converting the PHP array structure defined in inc/toolbar.php to JavaScript using JSON.
This means, the toolbar gets cached like any other JavaScript in DokuWiki. When ever you do changes affecting the toolbar you should invalidate DokuWiki's cache (eg. touch conf/local.php) and refresh your browser cache while editing a page (Hit Shift/Ctrl-Reload and ignore the post warning).
The mentioned toolbar array contains one entry per button. The order of the entries defines the position of the button, with the first entry defining the most left button.
Each entry is an associative array itself, defining the behavior of the button. The following table explains the available fields for the entries.
| Name | Description |
|---|---|
type | button action type: format ⇒ wiki markup mediapopup ⇒ popup window picker ⇒ picker menu signature ⇒ signature generation and insertion |
title | title of the button, displayed on mouseover |
icon | icon to use for the button |
key | Hotkey for the button, a value of n here would result in the button being pressed when the user presses ALT + n in his browser |
format type specific parameters |
|
open | opening tag of wiki markup to insert, cursor will be placed between opening and closing tag |
sample | example input to be placed between opening and closing tag, will be automatically selected to be overwritten on first input |
close | closing tag of the wiki markup to insert, cursor will be placed between opening and closing tag |
insert | wiki markup to insert (for full substitutions) |
mediapopup type specific parameters |
|
url | URL of the popup to open |
name | internal name of the popup to open |
options | additional options for the popup window (comma-separated name-value-pairs valid as parameters for the JS function window.open |
picker type specific parameters |
|
list | list of insertable items. can either be an associative array (with the item to insert as the key and an image to use as the value) or just a simple array (with the text-items to insert directly displayed) |
icobase | basedirectory for item images |
A look at inc/toolbar.php should give you enough examples of what can be defined. Because the array is simply translated from PHP to JavaScript, the above description applies to the PHP array as well as to the resulting JavaScript array from which the toolbar is finally built.
The toolbar can be customized in two ways - via JavaScript or PHP. Which method you choose basically depends on your skills and familiarity with the language at hand. For the PHP approach you will always need to write a plugin, the JavaScript method can be used from a userscript as well.
To extend the toolbar from your plugin you need to write a Action Plugin which registers as handler for the TOOLBAR_DEFINE event with an AFTER advise. Your handler function will receive the toolbar array as described earlier.
Create your button structure according to the above information and add it to the received event data.-function in inc/toolbar.php.
Example:
function register(&$controller) { $controller->register_hook('TOOLBAR_DEFINE', 'AFTER', $this, 'insert_button', array ()); } // ... /** * Inserts a toolbar button */ function insert_button(& $event, $param) { $event->data[] = array ( 'type' => 'format', 'title' => $this->getLang('abutton'), 'icon' => '../../plugins/example/abutton.png', 'open' => '<abutton>', 'close' => '</abutton>', ); }
Adding a button using JavaScript is similar to doing it in PHP. You just extend the toolbar array.
Because user and plugin scripts will be loaded on all requests, but the toolbar is initialized on editing only, you need to make sure the toolbar array does exist first. Do this by checking if window.toolbar is defined. If it is, you can add your button at the end of the array.
if(window.toolbar!=undefined){ toolbar[toolbar.length] = {"type":"format", "title":"A Button", "icon":"abutton.png", "key":"", "open":"<abutton>", "sample":"Text between the tags", "close":"</abutton>"}; }
Here is another example defining a picker dropdown:
if(window.toolbar!=undefined){ var notes_arr = new Array(); /* array[key]= insertion string , value = icon filename. */ notes_arr['<note></note>\\n'] ='note.png'; notes_arr['<note tip></note>\\n'] ='tip.png'; notes_arr['<note important></note>\\n']='important.png'; notes_arr['<note warning></note>\\n'] ='warning.png'; toolbar[toolbar.length] = {"type":"picker", "title":"Notes", "icon":"note.png", "key":"", "list": notes_arr, "icobase":"notes"}; /* subdir of lib/images/ where images found.*/ }
The above methods work well for adding static buttons that add static data. When you need to do something more dynamic like adding the current date, you can not simply extend the toolbar array. Instead you need to dynamically add your button into the DOM using JavaScript.
lib/scripts/edit.js and lib/scripts/linkwiz.js contains some useful functions to help you with this.
Here's an example partly from the link wizard:
/** * With the first function we create a new button type called Click * * the function name must be addBtnAction<Your type name> * in our case it is addBtnActionClick * * in the other function we simply use the simple toolbar method with the new type * * you can easily extend it to complex scripts like the link wizard etc */ /** * Add button action for the link wizard button * * @param DOMElement btn Button element to add the action to * @param array props Associative array of button properties * @param string edid ID of the editor textarea * @return boolean If button should be appended */ function addBtnActionClick(btn, props, edid) { addEvent(btn,'click',function(){ alert('hey you clicked me'); return false; }); return true; } // add a new toolbar button just like the simple way addInitEvent(function() { // but first check if there is a toolbar if (window.toolbar != undefined) { window.toolbar[window.toolbar.length] = { "type":"Click", // we have a new type that links to the function "title":"Hey Click me!", "icon":"/lib/plugins/klick/klickme.png" } } });
toolbar array at the position where you want your button, shifting the other buttons to the right.data/cache) completely with your ftp client program AND delete your browser cache! Than reload the editor page and your button should appear.