Movatterモバイル変換


[0]ホーム

URL:


DokuWiki

It's better when it's simple

User Tools

Site Tools


devel:plugin_programming_tips

Tips for programming plugins

Please write down tips you've discovered making it easier for others tomake plugins.I actually had to sit down and fgrep myself to this info, and I hope that it will help others;-)

On this page are some tips (see ToC right). Useful resources elsewhere in the wiki are:

Customized Section editing

When you like to change only small pieces of the wiki text via your plugin, it is recommended to look for section editing. This let you provide your interface elements that can edit a specific marked piece of wiki text.

Please refer tosection editor for details on the implementation in your plugin.

User lists and info

You can access user-lists/info and more for internal use by declaring the following in a function that needs it:

global$auth;if($auth->canDo('getUsers')){// is this feature available?$auth->retrieveUsers(0,0,$filter);}

Where$filter is an array with one or more of the following keysuser,name,mail, orgrps.Several values in each using| as a separator.

For example, to retrieve all users in the group 'admin', one would use:

$filter['grps']='admin';$array_of_matches=$auth->retrieveUsers(0,0,$filter);

Be aware that the authentication plugin needs to implement this function. Otherwise it returns always an empty array.

See alsoauthentication plugins mention ofretrieveUsers() and other functions.

DokuWiki Global Variables

DokuWiki uses a number ofglobal variables to hold information about the current page, current user and the actions being performed.
Details of these can be found on theenvironment page.

Making your plugins more secure

Clean all input and output

Be aware that every one can do 'requests' on your forms and pages with all data they think off. People can send the same kind of data as a brave one using your form, without using your form itself. So everything can be included. So check always whether the given data is that whatyou allowed.

And when you output data, especially in theHTML of your interface, your plugin should ensure any data output has allHTML special characters converted toHTML entities using thehtmlspecialchars() function. DokuWiki provides a convenient shortcut calledhsc() for the function. URLs values should be escaped usingrawurlencode(). This makes sure input is always outputted as text and not as executable code. Malicious users could otherwise introduce what ever JavaScript andHTML code they want on your site and can manipulate and change everything.

Protect forms and action urls

If you use forms in your plugins or urls that initiate actions, you should include a hidden form field with the session-based security token. In the current version of DokuWiki you can generate this field by calling the functionformSecurityToken(). Before you process the form input, callcheckSecurityToken(). This function checks if the sent security token is correct.

Scenario If you wonder, why this will make your plugins more secure, consider the following scenario:

You have written a plugin that displays a form to delete several pages at once.
An attacker knows you regularly log in to your wiki and you use a site that is under his control.
He places an images tag on his page that links to your doku.php and has all the form parameters for deleting pages in theURL.
Each time you see the page form the attacker, your browser requests the image from your DokuWiki installation, thereby deleting pages.

This attack is calledCross Site Request forgery.

Other security tips are listed and explainedon the dedicated page.

Use correct regular expressions

Use correct regular expressions for syntax search patterns. If the search pattern is incorrect, it can produce unwanted effects in combination with other plugins.

Use reasonable tag names to avoid conflicts with other plugins. For example don't use a name liketest butpluginname_test instead. Maybe check existing search patterns heresyntax, but don't use them as example because many of them are incorrect regular expressions.

Correct regular expression

<tag\b.*?>.*?</tag><tag\b[^>\r\n]*?>.*?</tag><tag\b[^>\r\n]*?>[^\r\n]*?</tag><tag\b.*?>(?:.*?</tag>)<tag\b(?:\s+(?:par1|par2)="[^">\r\n]*")*\s*>(?:.*?</tag>)
~~tag\b.*?~~~~tag>.+?~~~~tag>[^\r\n]+?~~

False regular expression

Example 1:

<tag.*>.*?</tag><tag ?.*>.*?</tag><tag *.*>.*?</tag>

Start tag is not a word, the end-of-word marker\b is missing, any pattern for example tagmore or taged is found too.

This produces a wrong result in this case:

<tagmore>Text</tagmore><tag>Text</tag>

Example 2:

<tag\b.*>.*?</tag><tag\b.*?>.*</tag>

The search pattern is “greedy”, the not-greedy marker? is missing, to long pieces are included in one search match.

This produces a wrong result in this case:

<tag>Text</tag><tag>Text</tag>

Spam prevention

When you offer a form in your plugin and this can be also used by public users of a wiki, it's recommended to use CAPTCHA to defeat spambots. There is already aCAPTCHA plugin available, which provides different formats, visible and invisible CAPTCHAs.

See the plugin page for description of theintegration and theconfiguration options.

Example implementation

TheBureaucracy plugin supports this plugin. The CAPTCHA is integrated in the submit button, seesubmit.php.

Adding JavaScript

Modify your wiki via local JavaScripts

If you need to enhance DokuWiki's capabilities, you can consider JavaScript beside creating a new plugin.
Just put the JavaScript code intoconf/userscript.js(create this file if it doesn't exists).

Examples JavaScripts additions:wordcounter orcopy_section_link

Distribute JavaScript and CSS files by pseudo plugins

Using cookies

When you like to store some preferences, you can add to and retrieve of DokuWikis preferences cookie by:

For other usages you use a separated cookie. Next snippet shows how you set cookies with the correct path in DokuWiki.

In PHP:

global$conf;$cookieDir=empty($conf['cookiedir']) ? DOKU_REL:$conf['cookiedir'];setCookie("yourCookieName",$value,$expire,$cookieDir,'',($conf['securecookie']&& is_ssl()));

and in #"/faq:cookies" title="faq:cookies" data-wiki-id="faq:cookies">DokuWiki's cookies,cookiedir config,securecookie config.

Handle JSON ajax request

An action plugin that register theAJAX_CALL_UNKNOWN event, you can handle your own ajax requests. Here a sample how you can return JSON to your javascript. Plugin name isexample.

Create anAction Plugin which should contain:

lib/plugin/example/action.php
use dokuwiki\Extension\ActionPlugin;use dokuwiki\Extension\EventHandler;use dokuwiki\Extension\Event; class action_plugin_exampleextends ActionPlugin{ /**     * plugin should use this method to register its handlers      * with the dokuwiki's event controller     */publicfunction register(EventHandler$controller){$controller->register_hook('AJAX_CALL_UNKNOWN','BEFORE',$this,'ajaxCall');} /**     * handle ajax requests     */publicfunction ajaxCall(Event$event){if($event->data!=='plugin_example'){return;}//no other ajax call handlers needed$event->stopPropagation();$event->preventDefault(); //e.g. access additional request variablesglobal$INPUT;$name=$INPUT->str('name'); //data$data=[]; //set content typeheader('Content-Type: application/json');echojson_encode($data);}}

You can request the data in javascript, for example:

lib/plugins/example/script.js
jQuery.post(    DOKU_BASE+'lib/exe/ajax.php',{        call:'plugin_example',         name:'local'},function(data){        alert('Received response');// data is array you returned with action.php},'json');

Checking user-input text against the DokuWiki blacklist

You have some user input you want to validate using the internal blacklist (e.g. as an anti-spam measure for comments or anything like that).

Make a temporary backup of the current content of the internal$TEXT variable (which usually contains the wiki text of the displayed page), then put your text into$TEXT. A call tocheckwordblock() should then yield a result oftrue if the processed text contains any blocked words, andfalse otherwise. Don't forget to restore the original content of$TEXT after you are done checking your user input by copying it back from the backup you made.

Example:

// backup and reset the current $TEXT variable$backupText=$TEXT;$TEXT=$userinput; if(checkwordblock()){// text contains blocked words ...} // restore $TEXT$TEXT=$backupText;

Disabling syntax plugins in user comments

You have written a syntax plugin which will be used in a restricted environment where anonymous users are not allowed to edit pages but allowed to comment using thediscussion plugin. You do not want to disable wiki syntax in comments completely, but want to disable the syntax provided by your plugin as it can become a risk in the wrong hands.

In your plugin'shandle method, check whether$_REQUEST['comment'] is set – this indicates that the parsing process is working on a discussion comment.

Example:

global$INPUT; // we are parsing a submitted comment...if($INPUT->has('comment')){returnfalse;}

Sending popularity data

Since release 2015-08-10 “Detritus”

:!: As a plugin developer, beware: since popularity data is public, you must not send sensitive information with this feature.

Thepopularity plugin already gather the number of time a plugin is installed on an instance of Dokuwiki.

It also let the possibility to developers, to send more data about usage. It can be used by plugins developers to know if a given obsolete feature is still used. To do it, you need to subscribe to thePLUGIN_POPULARITY_DATA_SETUP event. This event contains a key-value array. You should add a key which is the name of your plugin. The value should be either a string, or a key-value array itself (in this latter case, the data will be sent with the key<plugin-name>_<key>)

Example:

action.php
use dokuwiki\Extension\ActionPlugin;use dokuwiki\Extension\EventHandler;use dokuwiki\Extension\Event; class action_plugin_exampleextends ActionPlugin{publicfunction register(EventHandler$controller){$controller->register_hook('PLUGIN_POPULARITY_DATA_SETUP','AFTER',$this,'usageData');} publicfunction usageData(Event$event){$event->data['my_plugin_name']='my usage data'; /* or:         $event->data['my_plugin_name'] = [            'k1' => 'v1',             'k2' => 'v2'        ];    */}}

A plugin which uses this feature is thenspages Plugin.

devel/plugin_programming_tips.txt · Last modified: byKlap-in


[8]ページ先頭

©2009-2025 Movatter.jp