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 [2017-07-25 12:10] – [Sort Number] belonging two => belonging to two 109.218.95.146devel: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]]((defined in ''lib/plugins/syntax.php'')). +  * 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 14: Line 15:
   * **''getType()''** Should return the type of syntax this plugin defines ([[#syntax_types|see below]])   * **''getType()''** Should return the type of syntax this plugin defines ([[#syntax_types|see below]])
   * **''getSort()''** Returns a number used to determine in which order modes are added, also see [[parser#order_of_adding_modes_important|parser, order of adding modes]] and [[devel:parser:getSort list]].   * **''getSort()''** Returns a number used to determine in which order modes are added, also see [[parser#order_of_adding_modes_important|parser, order of adding modes]] and [[devel:parser:getSort list]].
-  * **''connectTo($mode)''** This function is inherited from Doku_Parser_Mode ((defined in ''inc/parser/parser.php'')). 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 28: Line 29:
   * **''accepts($mode)''** This function is used to tell the parser if the plugin accepts syntax mode $mode within its own markup. The default behaviour is to test $mode against the array of modes held by the inherited property ''allowedModes''. This array is also filled with modes from the mode types given in ''getAllowedTypes()''.   * **''accepts($mode)''** This function is used to tell the parser if the plugin accepts syntax mode $mode within its own markup. The default behaviour is to test $mode against the array of modes held by the inherited property ''allowedModes''. This array is also filled with modes from the mode types given in ''getAllowedTypes()''.
  
-Additional functions can be defined as needed. It is recommended to prepend an underscore to self defined functions to avoid possible nameclashes with future plugin specification enhancements.+Additional functions can be defined as needed. 
  
 \\  \\ 
 Inherited Properties Inherited Properties
  
-  * **''allowedModes''** --- initial value, an empty array, inherited from Doku_Parser_Mode ((defined in ''inc/parser/parser.php'')). Contains a list of other syntax modes which are allowed to occur within the plugin's own syntax mode (ie. the modes which belong to any other DokuWiki markup that can be nested inside the plugin's own markup).  Normally, it is automatically populated by the ''accepts()'' function using the results of ''getAllowedTypes()''.+  * **''allowedModes''** --- initial value, an empty array, inherited from AbstractMode ((defined in ''inc/Parsing/ParserMode/AbstractMode.php'')). Contains a list of other syntax modes which are allowed to occur within the plugin's own syntax mode (ie. the modes which belong to any other DokuWiki markup that can be nested inside the plugin's own markup).  Normally, it is automatically populated by the ''accepts()'' function using the results of ''getAllowedTypes()''.
  
 Inherited Functions Inherited Functions
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 199: Line 200:
 This is the part of your plugin which should do all the work.  Before DokuWiki renders the wiki page it creates a list of instructions for the renderer.  The plugin's ''handle()'' method generates the render instructions for the plugin's own syntax mode.  At some later time, these will be interpreted by the plugin's ''render()'' method.  The instruction list is cached and can be used many times, making it sensible to maximize the work done once by this function and minimize the work done many times by ''render()''. This is the part of your plugin which should do all the work.  Before DokuWiki renders the wiki page it creates a list of instructions for the renderer.  The plugin's ''handle()'' method generates the render instructions for the plugin's own syntax mode.  At some later time, these will be interpreted by the plugin's ''render()'' method.  The instruction list is cached and can be used many times, making it sensible to maximize the work done once by this function and minimize the work done many times by ''render()''.
  
-The complete signature is: ''public handle($match, $state, $pos, Doku_Handler $handler)'' with the arguments:+The complete signature is: ''public function handle($match, $state, $pos, Doku_Handler $handler)'' with the arguments:
  
 **$match** parameter --- The text matched by the patterns, or in the case of **''DOKU_LEXER_UNMATCHED''** the contiguous piece of ordinary text which didn't match any pattern. **$match** parameter --- The text matched by the patterns, or in the case of **''DOKU_LEXER_UNMATCHED''** the contiguous piece of ordinary text which didn't match any pattern.
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 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.1500977436.txt.gz · Last modified: 2017-07-25 12:10 by 109.218.95.146

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