This is an old revision of the document!
Table of Contents
Custom section editors
DokuWiki allows plugins to provide custom edit forms for their syntax elements. First, you need to mark a DIV element in the XHTML output as editable, second you have to provide an editor for your content.
Marking the DIV
The XHTML renderer provides to methods for the DIV section edit marking:
- string startSectionEdit(int $bytepos_start, string $section_type, string $section_title = null)
- void finishSectionEdit(int $bytepos_end = null)
Note that finishSectionEdit
assumes correctly nested edit sections. To use this methods, you will need to save your byte positions in your handle
methods.
A step-by-step example for a syntax plugin:
- syntax.php
function render($format, &$renderer, $data) { $class = ''; // Add section edit infos only in XHTML renderers which are // sufficiently new if ($format === 'xhtml' && method_exists($renderer, 'startSectionEdit')) { // FIXME: Insert plugin name here as section type // If this section has a distinguishable name, you may add it to // the method call as well $class = $renderer->startSectionEdit($data['bytepos_start'], 'plugin_exampleplugin'); } $renderer->doc .= '<div class="' . $class . '">'; // FIXME: Put your content here $renderer->doc .= '</div>'; // Add section edit infos only in XHTML renderers which are // sufficiently new if ($format === 'xhtml' && method_exists($renderer, 'finishSectionEdit')) { $renderer->finishSectionEdit($data['bytepos_end']); } }
You may have noticed that I used $data['bytepos_start']
and $data['bytepos_end']
which your handler has to provide:
- syntax.php
function handle($match, $state, $pos, &$handler) { $data = array(); // FIXME: Do your handling return $data + array('bytepos_start' => $pos, 'bytepos_end' => $pos + strlen($match)); }
If you did not provide a special section name in the startSectionEdit
call, you must hook the HTML_SECEDIT_BUTTON event providing a general-purpose name:
- action.php
function register(&$controller) { $controller->register_hook('HTML_SECEDIT_BUTTON', 'BEFORE', $this, '_editbutton'); } function _editbutton(&$event, $param) { // FIXME: Insert plugin name if ($event->data['target'] !== 'plugin_exampleplugin') { return; } // FIXME: Add lang field to your lang files $event->data['name'] = $this->getLang('sectioneditname'); }
Now your users will get a special edit button for your syntax elements. You will probably want to style it:
- style.css
/* FIXME: Insert plugin name here */ div.dokuwiki div.editbutton_plugin_exampleplugin { } /* FIXME: Insert plugin name here */ div.dokuwiki div.editbutton_plugin_exampleplugin form input.button { }
Now there is a nice button, but still no form – the users have to use the plain wikitext editor!
Providing the form
For this step, we need to hook HTML_EDIT_FORMSELECTION in an action plugin.
- action.php
function register(&$controller) { $controller->register_hook('HTML_SECEDIT_BUTTON', 'BEFORE', $this, '_editbutton'); $controller->register_hook('HTML_EDIT_FORMSELECTION', 'BEFORE', $this, '_editform'); } function _editform(&$event, $param) { global $TEXT; // FIXME: Insert plugin name if ($event->data['target'] !== 'plugin_exampleplugin') { // Not an edit for exampleplugin return; } $event->preventDefault(); // FIXME: Remove this if you want the default edit intro unset($event->data['intro_locale']); // FIXME: Remove this if you want a media manager link // You will probably want a media link if you want a normal toolbar $event->data['media_manager'] = false; // FIXME: Create the lang files edit_intro.txt echo $this->locale_xhtml('edit_intro'); // FIXME: Add real edit form $attr = array(); if (!$event->data['wr']) $attr['readonly'] = 'readonly'; $event->data['form']->addElement(form_makeWikiText($TEXT, $attr)); }
The form you provided here has to be rendered into wiki text again on POST.
- action.php
function register(&$controller) { $controller->register_hook('HTML_SECEDIT_BUTTON', 'BEFORE', $this, '_editbutton'); $controller->register_hook('HTML_EDIT_FORMSELECTION', 'BEFORE', $this, '_editform'); $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, '_editpost'); } function _handle_edit_post($event) { // FIXME: Insert the name of a form field you use if (!isset($_POST['some_of_the_form_fields_you_use'])) { return; } global $TEXT; // FIXME: Create wikitext from post $TEXT = magic_form_to_wiki_function(); }