DokuWiki

It's better when it's simple

User Tools

Site Tools


devel:section_editor

This is an old revision of the document!


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();
    }
devel/section_editor.1287591957.txt.gz · Last modified: 2010-10-20 18:25 by adrianlang

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki