devel:plugin_programming_tips
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
devel:plugin_programming_tips [2013-02-26 02:35] – made link internal ach | devel:plugin_programming_tips [2023-09-20 23:34] (current) – Klap-in | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Tips for programming plugins ====== | ====== Tips for programming plugins ====== | ||
- | Please write down tips you've discovered making it easier for others to make plugins. | + | Please write down tips you've discovered making it easier for others to [[plugins|make plugins]]. |
I actually had to sit down and fgrep myself to this info, and I hope that it will help others ;-) | 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: | On this page are some tips (see ToC right). Useful resources elsewhere in the wiki are: | ||
* [[common plugin functions# | * [[common plugin functions# | ||
- | * [[common plugin functions#Localisation]] | + | * [[common plugin functions#Localization]] |
* Plugin [[plugin file structure|file structure]] and [[plugin file structure|name conventions]] | * Plugin [[plugin file structure|file structure]] and [[plugin file structure|name conventions]] | ||
- | * Using a customized | + | * [[devel: |
+ | |||
+ | =====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 to [[section editor]] for details on the implementation in your plugin. | ||
Line 15: | Line 20: | ||
<code php> | <code php> | ||
- | | + | global $auth; |
- | if($auth-> | + | if ($auth-> |
- | $auth-> | + | $auth-> |
- | } | + | } |
</ | </ | ||
Where '' | Where '' | ||
- | Several values in each using ' | + | Several values in each using ''|'' as a separator. |
For example, to retrieve all users in the group ' | For example, to retrieve all users in the group ' | ||
<code php> | <code php> | ||
- | | + | $filter[' |
- | $array_of_matches = retrieveUsers(0, | + | $array_of_matches = $auth->retrieveUsers(0, |
</ | </ | ||
- | Be aware that the user backend | + | Be aware that the authentication plugin |
- | See also [[devel:authentication_backends#optional_methods|authentication | + | See also [[devel:auth_plugins#retrieveusers|authentication |
===== DokuWiki Global Variables ===== | ===== DokuWiki Global Variables ===== | ||
Line 48: | Line 54: | ||
===Protect forms and action urls=== | ===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 function | + | 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 function |
// | // | ||
Line 56: | Line 62: | ||
Other security tips are listed and explained [[devel: | Other security tips are listed and explained [[devel: | ||
+ | |||
+ | ===== 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 like '' | ||
+ | |||
+ | ==== Correct regular expression ==== | ||
+ | |||
+ | < | ||
+ | < | ||
+ | |||
+ | < | ||
+ | < | ||
+ | |||
+ | < | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | ~~tag\b.*? | ||
+ | ~~tag> | ||
+ | ~~tag> | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ==== False regular expression ==== | ||
+ | |||
+ | Example 1: | ||
+ | |||
+ | < | ||
+ | < | ||
+ | <tag ? | ||
+ | <tag *.*> | ||
+ | </ | ||
+ | |||
+ | Start tag is not a word, the end-of-word marker '' | ||
+ | |||
+ | This produces a wrong result in this case: | ||
+ | |||
+ | < | ||
+ | < | ||
+ | Text | ||
+ | </ | ||
+ | |||
+ | <tag> | ||
+ | Text | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | Example 2: | ||
+ | |||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | |||
+ | The search pattern is " | ||
+ | |||
+ | This produces a wrong result in this case: | ||
+ | |||
+ | < | ||
+ | <tag> | ||
+ | Text | ||
+ | </ | ||
+ | |||
+ | <tag> | ||
+ | Text | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ===== 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 a [[plugin: | ||
+ | |||
+ | See the plugin page for description of the [[plugin: | ||
+ | |||
+ | ===Example implementation=== | ||
+ | The [[plugin: | ||
+ | |||
+ | |||
===== Adding JavaScript ===== | ===== Adding JavaScript ===== | ||
Line 65: | Line 153: | ||
===Distribute JavaScript and CSS files by pseudo plugins=== | ===Distribute JavaScript and CSS files by pseudo plugins=== | ||
- | If you want to add some JavaScript and CSS at the same time and make it easier to distribute, you can create a //' | + | If you want to add some JavaScript and CSS at the same time and make it easier to distribute, you can create a //' |
Examples pseudo plugins: [[plugin: | Examples pseudo plugins: [[plugin: | ||
Line 71: | Line 159: | ||
More about [[plugin file structure# | More about [[plugin file structure# | ||
+ | |||
+ | =====Using cookies===== | ||
+ | When you like to store some preferences, | ||
+ | * in PHP: | ||
+ | * set a value '' | ||
+ | * delete an entry '' | ||
+ | * and retrieve its value with '' | ||
+ | * and in javascript: | ||
+ | * set a value '' | ||
+ | * and retrieve value '' | ||
+ | |||
+ | For other usages you use a separated cookie. Next snippet shows how you set cookies with the correct path in DokuWiki. | ||
+ | |||
+ | In PHP: | ||
+ | <code php> | ||
+ | global $conf; | ||
+ | $cookieDir = empty($conf[' | ||
+ | setCookie(" | ||
+ | </ | ||
+ | and in javascript: | ||
+ | <code javascript> | ||
+ | jQuery.cookie(" | ||
+ | expires: 7, //days | ||
+ | path: DOKU_COOKIE_PARAM.path, | ||
+ | secure: DOKU_COOKIE_PARAM.secure | ||
+ | }); | ||
+ | </ | ||
+ | |||
+ | |||
+ | More general info about cookies: [[faq: | ||
===== Handle JSON ajax request ===== | ===== Handle JSON ajax request ===== | ||
- | An action plugin that register the [[devel: | + | An action plugin that register the [[devel: |
Create an [[Action Plugin]] which should contain: | Create an [[Action Plugin]] which should contain: | ||
<code php lib/ | <code php lib/ | ||
- | /* | + | use dokuwiki\Extension\ActionPlugin; |
- | * plugin should | + | use dokuwiki\Extension\EventHandler; |
- | * with the dokuwiki's event controller | + | use dokuwiki\Extension\Event; |
- | */ | + | |
- | function register(& | + | |
- | $controller-> | + | |
- | } | + | |
- | + | ||
- | /** | + | |
- | * handle ajax requests | + | |
- | */ | + | |
- | function _ajax_call(& | + | |
- | if ($event-> | + | |
- | return; | + | |
- | } | + | |
- | //no other ajax call handlers needed | + | |
- | $event-> | + | |
- | $event-> | + | |
- | //e.g. access additional request variables | + | class action_plugin_example extends ActionPlugin { |
- | | + | |
- | $name = $INPUT->str('name')) { | + | /** |
+ | * plugin should use this method to register its handlers | ||
+ | * with the dokuwiki' | ||
+ | */ | ||
+ | | ||
+ | | ||
+ | } | ||
| | ||
- | //data | + | /** |
- | $data = array(); | + | * handle ajax requests |
+ | */ | ||
+ | | ||
+ | if ($event-> | ||
+ | return; | ||
+ | } | ||
+ | //no other ajax call handlers needed | ||
+ | $event-> | ||
+ | $event-> | ||
- | | + | |
- | require_once DOKU_INC | + | global $INPUT; |
- | $json = new JSON(); | + | $name = $INPUT-> |
| | ||
- | | + | //data |
- | header(' | + | $data = []; |
- | echo $json-> | + | |
+ | | ||
+ | header(' | ||
+ | echo json_encode($data); | ||
+ | } | ||
} | } | ||
</ | </ | ||
Line 118: | Line 239: | ||
jQuery.post( | jQuery.post( | ||
DOKU_BASE + ' | DOKU_BASE + ' | ||
- | {call: 'example', name: ' | + | { |
+ | | ||
+ | | ||
+ | | ||
function(data) { | function(data) { | ||
alert(' | alert(' | ||
Line 156: | Line 280: | ||
Example: | Example: | ||
<code php> | <code php> | ||
+ | global $INPUT; | ||
+ | |||
// we are parsing a submitted comment... | // we are parsing a submitted comment... | ||
- | if (isset($_REQUEST[' | + | if ($INPUT-> |
return false; | return false; | ||
+ | } | ||
</ | </ | ||
+ | |||
+ | ===== Sending popularity data ===== | ||
+ | Since release 2015-08-10 " | ||
+ | |||
+ | :!: As a plugin developer, beware: since popularity data is public, you must not send sensitive information with this feature. | ||
+ | |||
+ | The [[plugin: | ||
+ | |||
+ | 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 the [[devel: | ||
+ | |||
+ | Example: | ||
+ | |||
+ | <code php action.php> | ||
+ | use dokuwiki\Extension\ActionPlugin; | ||
+ | use dokuwiki\Extension\EventHandler; | ||
+ | use dokuwiki\Extension\Event; | ||
+ | |||
+ | class action_plugin_example extends ActionPlugin { | ||
+ | public function register(EventHandler $controller) { | ||
+ | $controller-> | ||
+ | } | ||
+ | | ||
+ | public function usageData(Event $event){ | ||
+ | $event-> | ||
+ | |||
+ | /* or: | ||
+ | $event-> | ||
+ | ' | ||
+ | ' | ||
+ | ]; | ||
+ | */ | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | A plugin which uses this feature is the [[plugin: |
devel/plugin_programming_tips.1361842553.txt.gz · Last modified: 2013-02-26 02:35 by ach