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.
The XHTML renderer provides two methods for the DIV section edit marking:
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:
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:
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:
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:
/* 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!
For this step, we need to hook HTML_EDIT_FORMSELECTION in an action plugin.
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.
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(); }