DokuWiki

It's better when it's simple

User Tools

Site Tools


devel:syntax_plugins

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
devel:syntax_plugins [2022-02-14 00:00] – first update due refactoring Klap-indevel:syntax_plugins [2023-09-01 23:53] (current) Klap-in
Line 1: Line 1:
 ====== Syntax Plugins ======  ====== Syntax Plugins ====== 
  
-[[plugintype>1#extension__table|Syntax Plugins]] are [[:devel:plugins]] to extend DokuWiki's [[wiki:syntax]]. To be able to understand what is needed to register new Syntax within DokuWiki you should read how the [[Parser]] works.+[[plugintype>1#extension__table|Syntax Plugins]] are [[:devel:plugins]] to extend DokuWiki's [[wiki:syntax]]. To be able to understand what is needed to register new Syntax within DokuWiki you should read [[parser | how the Parser works]]. 
 ===== Synopsis ===== ===== Synopsis =====
  
 A Syntax Plugin //Example// needs: A Syntax Plugin //Example// needs:
   * class name  ''syntax_plugin_example''   * class name  ''syntax_plugin_example''
-  * which extends [[xref>DokuWiki_Syntax_Plugin]]((alias of ''[[xref>dokuwiki\Extension\SyntaxPlugin]]'')). +  * which extends [[xref>SyntaxPlugin]]((defined in ''lib/Extension/SyntaxPlugin.php'', before called ''DokuWiki_Syntax_Plugin'' which is still available as alias)). 
   * to be stored in a file ''lib/plugins/example/syntax.php''.   * to be stored in a file ''lib/plugins/example/syntax.php''.
 Moreover, a [[plugin_info|plugin.info.txt]] file is needed. For full details of plugins and their files and how to create more syntax components refer to [[plugin file structure]]. Moreover, a [[plugin_info|plugin.info.txt]] file is needed. For full details of plugins and their files and how to create more syntax components refer to [[plugin file structure]].
Line 16: Line 17:
   * **''connectTo($mode)''** This function is inherited from dokuwiki\Parsing\ParserMode\AbstractMode ((defined in ''inc/Parsing/ParserMode/AbstractMode.php'', inherited via dokuwiki\Parsing\ParserMode\Plugin)). Here is the place to register the regular expressions needed to match your syntax.   * **''connectTo($mode)''** This function is inherited from dokuwiki\Parsing\ParserMode\AbstractMode ((defined in ''inc/Parsing/ParserMode/AbstractMode.php'', inherited via dokuwiki\Parsing\ParserMode\Plugin)). Here is the place to register the regular expressions needed to match your syntax.
   * **''handle($match, $state, $pos, Doku_Handler $handler)''** to prepare the matched syntax for use in the renderer   * **''handle($match, $state, $pos, Doku_Handler $handler)''** to prepare the matched syntax for use in the renderer
-  * **''render($mode, Doku_Renderer $renderer, $data)''** to render the content+  * **''render($format, Doku_Renderer $renderer, $data)''** to render the content
 \\  \\ 
  
Line 77: Line 78:
   * The ''[[#render_method|render()]]'' method processes the renderer instructions that apply to the plugin's syntax mode - and which were created by the plugin's ''[[#handle_method|handle()]]'' method.   * The ''[[#render_method|render()]]'' method processes the renderer instructions that apply to the plugin's syntax mode - and which were created by the plugin's ''[[#handle_method|handle()]]'' method.
   * add content to the output document with ''%%$renderer->doc .= 'content';%%''   * add content to the output document with ''%%$renderer->doc .= 'content';%%''
-  * access the return value of handle() using the //$data// parameter of render($mode, Doku_Renderer $renderer, $data).+  * access the return value of handle() using the //$data// parameter of render($format, Doku_Renderer $renderer, $data).
   * ensure any content output by the plugin is **safe** - run raw wiki data through an entity conversion function.    * ensure any content output by the plugin is **safe** - run raw wiki data through an entity conversion function. 
   * do the minimum possible processing and decision making here, it should all have been done in the ''[[#handle_method|handle()]]'' method.   * do the minimum possible processing and decision making here, it should all have been done in the ''[[#handle_method|handle()]]'' method.
Line 224: Line 225:
 </code> </code>
  
-:!: Any raw wiki data that passes through ''render()'' should have all special characters converted to HTML entities. You can use the PHP functions, ''[[http://uk.php.net/manual/en/function.htmlspecialchars.php|htmlspecialchars()]]''''[[http://uk.php.net/manual/en/function.htmlentities.php|htmlentities()]]'' or the renderer's own ''xmlEntities()'' method. e.g.<code php>$renderer->doc .= $renderer->_xmlEntities($text);</code>  +:!: Any raw wiki data that passes through ''render()'' should have all special characters converted to HTML entities. You can use DokuWiki's [[xref>hsc()]] or the PHP functions, [[phpfn>htmlspecialchars()]], [[phpfn>htmlentities()]] or the renderer's own [[xref>_xmlEntities()]] method. e.g.<code php>$renderer->doc .= $renderer->_xmlEntities($text);</code>  
  
-The complete signature is: ''public function render($mode, Doku_Renderer $renderer, $data)'' with the arguments:+The complete signature is: ''public function render($format, Doku_Renderer $renderer, $data)'' with the arguments:
  
-**$mode** parameter --- Name for the format mode of the final output produced by the renderer.  At present DokuWiki only supports one output format ''XHTML'' and a special (internal) format ''metadata'' ((The special mode ''metadata'' does not output anything but collects metadata for the page. Use it to insert values into the metadata array. See the translation plugin for an example.)). New modes can be introduced by [[devel:renderer plugins]].  The plugin should only produce output for those formats which it supports - which means this function should be structured ...+**$format** parameter --- Name for the format mode of the final output produced by the renderer.  At present DokuWiki only supports one output format ''XHTML'' and a special (internal) format ''metadata'' ((The special mode ''metadata'' does not output anything but collects metadata for the page. Plugin can add other formats such as the ODT format. Use it to insert values into the metadata array. See the translation plugin for an example.)). New modes can be introduced by [[devel:renderer plugins]].  The plugin should only produce output for those formats which it supports - which means this function should be structured ...
 <code php> <code php>
-if ($mode == 'xhtml') {  // supported mode+if ($format == 'xhtml') {  // supported mode
   // code to generate XHTML output from instruction $data   // code to generate XHTML output from instruction $data
 } }
 </code> </code>
  
-**$renderer** parameter --- Give access to the object [[xref>Doku_Renderer]], which contains useful functions and values. Above you saw already the usage of ''$renderer%%->%%doc'' for storing the render output.+**$renderer** parameter --- Give access to the object [[xref>inc::Doku_Renderer|Doku_Renderer]], which contains useful functions and values. Above you saw already the usage of ''$renderer%%->%%doc'' for storing the render output.
  
 **$data** parameter --- An array containing the instructions previously prepared and returned by the plugin's own ''handle()'' method.  The ''render()'' must interpret the instruction and generate the appropriate output. **$data** parameter --- An array containing the instructions previously prepared and returned by the plugin's own ''handle()'' method.  The ''render()'' must interpret the instruction and generate the appropriate output.
Line 242: Line 243:
 When your plugin needs to extend the content of a wiki page, you need the output format mode ''xhtml''. Because ''render()'' is called for all the format modes, you need to filter by the desired modes. When your plugin needs to extend the content of a wiki page, you need the output format mode ''xhtml''. Because ''render()'' is called for all the format modes, you need to filter by the desired modes.
 <code php> <code php>
-if ($mode == 'xhtml') {  // when the format mode is xhtml+if ($format == 'xhtml') {  // when the format mode is xhtml
     /** @var Doku_Renderer_xhtml $renderer */        /** @var Doku_Renderer_xhtml $renderer */   
     // code to generate XHTML output from instruction $data     // code to generate XHTML output from instruction $data
Line 248: Line 249:
 } }
 </code> </code>
-Detail: the variable ''$renderer'' is now the [[xref>Doku_Renderer_xhtml]] object.+Detail: the variable ''$renderer'' is now the [[xref>inc::Doku_Renderer_xhtml|Doku_Renderer_xhtml]] object.
  
 === Metadata renderer === === Metadata renderer ===
-A special render mode ''metadata'' is for rendering metadata. [[Metadata]] are the extra properties kept for your wiki page, which you can also extend or modify in your plugin.+A special render format ''metadata'' is for rendering metadata. [[Metadata]] are the extra properties kept for your wiki page, which you can also extend or modify in your plugin.
  
-In the metadata rendering mode you extracts metadata from the page. This is particularly important if you manually handle certain kinds of links. If you don't register these, they will not show up as backlinks on the pages that they refer to. Here is an example of how to register these backlinks:+In the metadata rendering format you extracts metadata from the page. This is particularly important if you manually handle certain kinds of links. If you don't register these, they will not show up as backlinks on the pages that they refer to. Here is an example of how to register these backlinks:
  
 <code php> <code php>
-public function render($mode, Doku_Renderer $renderer, $data) { +public function render($format, Doku_Renderer $renderer, $data) { 
-    if($mode == 'xhtml') {+    if($format == 'xhtml') {
         /** @var Doku_Renderer_xhtml $renderer */         /** @var Doku_Renderer_xhtml $renderer */
         // this is where you put all the rendering that will be displayed in the          // this is where you put all the rendering that will be displayed in the 
Line 263: Line 264:
  return true;  return true;
     }     }
-    if($mode == 'metadata') {+    if($format == 'metadata') {
         /** @var Doku_Renderer_metadata $renderer */         /** @var Doku_Renderer_metadata $renderer */
         $renderer->internallink($data[0]);         $renderer->internallink($data[0]);
Line 273: Line 274:
 } }
 </code> </code>
-This example uses the [[xref>internallink]] function from ''inc/parser/metadata.php''. You can also access the metadata directly in the renderer with ''%%$renderer->meta%%'' and ''%%$renderer->persistent%%'', because ''$renderer'' is now the [[xref>Doku_Renderer_metadata]] object. Here is a snippet from the tag plugin:+This example uses the [[xref>internallink()]] function from ''inc/parser/metadata.php''. You can also access the metadata directly in the renderer with ''%%$renderer->meta%%'' and ''%%$renderer->persistent%%'', because ''$renderer'' is now the [[xref>inc::Doku_Renderer_metadata|Doku_Renderer_metadata]] object. Here is a snippet from the tag plugin:
 <code php> <code php>
-public function render($mode, Doku_Renderer $renderer, $data) {+public function render($format, Doku_Renderer $renderer, $data) {
     if ($data === false) return false;     if ($data === false) return false;
  
     // XHTML output     // XHTML output
-    if ($mode == 'xhtml') {+    if ($format == 'xhtml') {
         /** @var Doku_Renderer_xhtml $renderer */         /** @var Doku_Renderer_xhtml $renderer */
         ...         ...
          
     // for metadata renderer     // for metadata renderer
-    } elseif ($mode == 'metadata') {+    } elseif ($format == 'metadata') {
         /** @var Doku_Renderer_metadata $renderer */         /** @var Doku_Renderer_metadata $renderer */
         // erase tags on persistent metadata no more used         // erase tags on persistent metadata no more used
         if (isset($renderer->persistent['subject'])) {         if (isset($renderer->persistent['subject'])) {
             unset($renderer->persistent['subject']);             unset($renderer->persistent['subject']);
-            $renderer->meta['subject'] = array();+            $renderer->meta['subject'] = [];
         }         }
                  
         // merge with previous tags and make the values unique         // merge with previous tags and make the values unique
-        if (!isset($renderer->meta['subject'])) $renderer->meta['subject'] = array();+        if (!isset($renderer->meta['subject'])) 
 +            $renderer->meta['subject'] = []; 
 +        }
         $renderer->meta['subject'] = array_unique(array_merge($renderer->meta['subject'], $data));         $renderer->meta['subject'] = array_unique(array_merge($renderer->meta['subject'], $data));
                  
         // create raw text summary for the page abstract         // create raw text summary for the page abstract
-        if ($renderer->capture) $renderer->doc .= DOKU_LF.implode(' ', $data).DOKU_LF+        if ($renderer->capture) 
 +            $renderer->doc .= implode(' ', $data); 
 +        } 
 +        
         ...         ...
         return true;         return true;
Line 309: Line 314:
 When handling persistent data in the metadata renderer, take care you update also the current metadata, when you update persistent metadata.  When handling persistent data in the metadata renderer, take care you update also the current metadata, when you update persistent metadata. 
  
-The tag plugin stores here 'subject' data by ''$renderer%%->%%meta['subject'] = ...''. Be aware that when you use ''p_set_metadata'' to set current metadata somewhere, that the next time the metadata is rendered it will overwrite this data. Using ''p_get_metadata($ID, $key)'' gives access to stored metadata. For details see [[devel:metadata]].+The tag plugin stores here 'subject' data by ''$renderer%%->%%meta['subject'] = ...''. Be aware that when you use ''p_set_metadata'' to set current metadata somewhere, that the next time the metadata is rendered it will overwrite this data. Using [[xref>p_get_metadata($ID, $key)]] gives access to stored metadata. For details see [[devel:metadata]].
  
 When some raw text from your syntax should be included in the abstract you can append it to ''$renderer%%->%%doc''. When the abstract is long enough, ''$renderer%%->%%capture'' becomes false. When some raw text from your syntax should be included in the abstract you can append it to ''$renderer%%->%%doc''. When the abstract is long enough, ''$renderer%%->%%capture'' becomes false.
  
-The xhtml mode is called when DokuWiki is in need of a new xhtml version of the wikipage. The metadata is a bit different. In general, the metadata of the page is rendered on demand when ''p_get_metadata'' is called somewhere. +The xhtml mode is called when DokuWiki is in need of a new xhtml version of the wikipage. The metadata is a bit different. In general, the metadata of the page is rendered on demand when [[xref>p_get_metadata()]] is called somewhere. 
  
 When someone edit a page and use the preview function, the metadata renderer is not called. So the metadata is not yet updated! This is done when the page is saved. When someone edit a page and use the preview function, the metadata renderer is not called. So the metadata is not yet updated! This is done when the page is saved.
Line 322: Line 327:
  
 ===== Common plugin functions ===== ===== Common plugin functions =====
 +
 Some function are shared between the plugins, refer to next sections for info: Some function are shared between the plugins, refer to next sections for info:
   * [[devel:common_plugin_functions#Configuration|Plugin configuration settings]]    * [[devel:common_plugin_functions#Configuration|Plugin configuration settings]] 
-  * [[devel:common_plugin_functions#localisation|Localisation]]+  * [[devel:common_plugin_functions#localization|Localization]]
   * [[devel:common_plugin_functions#styles and javascript|Using styles and javascript]]    * [[devel:common_plugin_functions#styles and javascript|Using styles and javascript]] 
  
Line 359: Line 365:
 ===== Read also===== ===== Read also=====
  
-  * The [[http://pluginwizard.dokuwiki.org/|Plugin Wizard]] can create a basic skeleton.+  * The [[http://pluginwizard.dokuwiki.org/|Plugin Wizard]] can create a basic skeleton or with the [[plugin:dev]] plugin.
   * [[Plugin file structure]]   * [[Plugin file structure]]
   * [[Common plugin functions]]   * [[Common plugin functions]]
Line 407: Line 413:
     }     }
  
-    public function render($mode, Doku_Renderer $renderer, $data) {+    public function render($format, Doku_Renderer $renderer, $data) {
     // $data is what the function handle return'ed.     // $data is what the function handle return'ed.
-        if($mode == 'xhtml'){+        if($format == 'xhtml'){
             /** @var Doku_Renderer_xhtml $renderer */             /** @var Doku_Renderer_xhtml $renderer */
             $renderer->doc .= date('r');             $renderer->doc .= date('r');
Line 427: Line 433:
 name Now Plugin name Now Plugin
 desc Include the current date and time desc Include the current date and time
-url http://www.dokuwiki.org/devel:syntax_plugins+url https://www.dokuwiki.org/devel:syntax_plugins
 </code> </code>
  
Line 495: Line 501:
      * Create output      * Create output
      */      */
-    public function render($mode, Doku_Renderer $renderer, $data) {+    public function render($format, Doku_Renderer $renderer, $data) {
         // $data is what the function handle() return'ed.         // $data is what the function handle() return'ed.
-        if($mode == 'xhtml'){+        if($format == 'xhtml'){
             /** @var Doku_Renderer_xhtml $renderer */             /** @var Doku_Renderer_xhtml $renderer */
             list($state,$match) = $data;             list($state,$match) = $data;
Line 549: Line 555:
 <code php> <code php>
     public function test_superscript() {     public function test_superscript() {
-        $info = array();+        $info = [];
         $expected = "\n<p>\nThis is <sup>superscripted</sup> text.<br />\n</p>\n";         $expected = "\n<p>\nThis is <sup>superscripted</sup> text.<br />\n</p>\n";
  
Line 559: Line 565:
 </code> </code>
  
-Here we strongly benefit from DokuWiki's good design. The two function calls to ''p_get_instructions()'' and ''p_render()'' are enough to render the example code //'This is ^^superscripted^^ text.'// and store the result in the variable **$xhtml**. Finally we only need a simple assert to check if the result is what we **$expected**.+Here we strongly benefit from DokuWiki's good design. The two function calls to ''p_get_instructions()'' and ''p_render()'' are enough to render the example code ''%%//'This is ^^superscripted^^ text.'//%%'' and store the result in the variable **$xhtml**. Finally we only need a simple assert to check if the result is what we **$expected**.
  
devel/syntax_plugins.txt · Last modified: 2023-09-01 23:53 by Klap-in

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