2 <!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
3 <!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
6 <meta http-equiv=
"X-UA-Compatible" content=
"IE=edge">
7 <meta name=
"viewport" content=
"width=device-width, initial-scale=1.0">
10 <link rel=
"shortcut icon" href=
"../img/favicon.ico">
11 <title>Plugin System - Shaarli Documentation
</title>
12 <link href='https://fonts.googleapis.com/css?family=Lato:
400,
700|Roboto+Slab:
400,
700|Inconsolata:
400,
700' rel='stylesheet' type='text/css'
>
14 <link rel=
"stylesheet" href=
"../css/theme.css" type=
"text/css" />
15 <link rel=
"stylesheet" href=
"../css/theme_extra.css" type=
"text/css" />
16 <link rel=
"stylesheet" href=
"../css/highlight.css">
17 <link href=
"../github-markdown.css" rel=
"stylesheet">
21 var mkdocs_page_name = "Plugin System";
22 var mkdocs_page_input_path = "Plugin-System.md";
23 var mkdocs_page_url = "/Plugin-System/";
26 <script src=
"../js/jquery-2.1.1.min.js"></script>
27 <script src=
"../js/modernizr-2.8.3.min.js"></script>
28 <script type=
"text/javascript" src=
"../js/highlight.pack.js"></script>
32 <body class=
"wy-body-for-nav" role=
"document">
34 <div class=
"wy-grid-for-nav">
37 <nav data-toggle=
"wy-nav-shift" class=
"wy-nav-side stickynav">
38 <div class=
"wy-side-nav-search">
39 <a href=
".." class=
"icon icon-home"> Shaarli Documentation
</a>
41 <form id =
"rtd-search-form" class=
"wy-form" action=
"../search.html" method=
"get">
42 <input type=
"text" name=
"q" placeholder=
"Search docs" />
47 <div class=
"wy-menu wy-menu-vertical" data-spy=
"affix" role=
"navigation" aria-label=
"main navigation">
51 <li class=
"toctree-l1">
53 <a class=
"" href=
"..">Home
</a>
56 <li class=
"toctree-l1">
58 <span class=
"caption-text">Setup
</span>
62 <a class=
"" href=
"../Download-and-Installation/">Download and Installation
</a>
66 <a class=
"" href=
"../Upgrade-and-migration/">Upgrade and migration
</a>
70 <a class=
"" href=
"../Server-requirements/">Server requirements
</a>
74 <a class=
"" href=
"../Server-configuration/">Server configuration
</a>
78 <a class=
"" href=
"../Server-security/">Server security
</a>
82 <a class=
"" href=
"../Shaarli-configuration/">Shaarli configuration
</a>
86 <a class=
"" href=
"../Plugins/">Plugins
</a>
91 <li class=
"toctree-l1">
93 <span class=
"caption-text">Docker
</span>
97 <a class=
"" href=
"../Docker-101/">Docker
101</a>
101 <a class=
"" href=
"../Shaarli-images/">Shaarli images
</a>
105 <a class=
"" href=
"../Reverse-proxy-configuration/">Reverse proxy configuration
</a>
109 <a class=
"" href=
"../Docker-resources/">Docker resources
</a>
114 <li class=
"toctree-l1">
116 <span class=
"caption-text">Usage
</span>
120 <a class=
"" href=
"../Features/">Features
</a>
124 <a class=
"" href=
"../Bookmarklet/">Bookmarklet
</a>
128 <a class=
"" href=
"../Browsing-and-searching/">Browsing and searching
</a>
132 <a class=
"" href=
"../Firefox-share/">Firefox share
</a>
136 <a class=
"" href=
"../RSS-feeds/">RSS feeds
</a>
140 <a class=
"" href=
"../REST-API/">REST API
</a>
145 <li class=
"toctree-l1">
147 <span class=
"caption-text">How To
</span>
151 <a class=
"" href=
"../Backup,-restore,-import-and-export/">Backup, restore, import and export
</a>
155 <a class=
"" href=
"../Copy-an-existing-installation-over-SSH-and-serve-it-locally/">Copy an existing installation over SSH and serve it locally
</a>
159 <a class=
"" href=
"../Create-and-serve-multiple-Shaarlis-(farm)/">Create and serve multiple Shaarlis (farm)
</a>
163 <a class=
"" href=
"../Download-CSS-styles-from-an-OPML-list/">Download CSS styles from an OPML list
</a>
167 <a class=
"" href=
"../Datastore-hacks/">Datastore hacks
</a>
172 <li class=
"toctree-l1">
174 <a class=
"" href=
"../Troubleshooting/">Troubleshooting
</a>
177 <li class=
"toctree-l1">
179 <span class=
"caption-text">Development
</span>
183 <a class=
"" href=
"../Development-guidelines/">Development guidelines
</a>
187 <a class=
"" href=
"../Continuous-integration-tools/">Continuous integration tools
</a>
191 <a class=
"" href=
"../GnuPG-signature/">GnuPG signature
</a>
195 <a class=
"" href=
"../Coding-guidelines/">Coding guidelines
</a>
199 <a class=
"" href=
"../Directory-structure/">Directory structure
</a>
203 <a class=
"" href=
"../3rd-party-libraries/">3rd party libraries
</a>
205 <li class=
" current">
207 <a class=
"current" href=
"./">Plugin System
</a>
210 <li class=
"toctree-l3"><a href=
"#developer-api">Developer API
</a></li>
214 <li><a class=
"toctree-l4" href=
"#what-can-i-do-with-plugins">What can I do with plugins?
</a></li>
216 <li><a class=
"toctree-l4" href=
"#how-can-i-create-a-plugin-for-shaarli">How can I create a plugin for Shaarli?
</a></li>
218 <li><a class=
"toctree-l4" href=
"#plugin-initialization">Plugin initialization
</a></li>
220 <li><a class=
"toctree-l4" href=
"#understanding-hooks">Understanding hooks
</a></li>
222 <li><a class=
"toctree-l4" href=
"#plugins-data">Plugin's data
</a></li>
224 <li><a class=
"toctree-l4" href=
"#metadata">Metadata
</a></li>
226 <li><a class=
"toctree-l4" href=
"#its-not-working">It's not working!
</a></li>
228 <li><a class=
"toctree-l4" href=
"#hooks">Hooks
</a></li>
233 <li class=
"toctree-l3"><a href=
"#guide-for-template-designer">Guide for template designer
</a></li>
237 <li><a class=
"toctree-l4" href=
"#plugin-administration">Plugin administration
</a></li>
239 <li><a class=
"toctree-l4" href=
"#placeholder-system">Placeholder system
</a></li>
241 <li><a class=
"toctree-l4" href=
"#list-of-placeholders">List of placeholders
</a></li>
250 <a class=
"" href=
"../Release-Shaarli/">Release Shaarli
</a>
254 <a class=
"" href=
"../Versioning-and-Branches/">Versioning and Branches
</a>
258 <a class=
"" href=
"../Security/">Security
</a>
262 <a class=
"" href=
"../Static-analysis/">Static analysis
</a>
266 <a class=
"" href=
"../Theming/">Theming
</a>
270 <a class=
"" href=
"../Unit-tests/">Unit tests
</a>
275 <li class=
"toctree-l1">
277 <span class=
"caption-text">About
</span>
281 <a class=
"" href=
"../FAQ/">FAQ
</a>
285 <a class=
"" href=
"../Community-&-Related-software/">Community & Related software
</a>
295 <section data-toggle=
"wy-nav-shift" class=
"wy-nav-content-wrap">
298 <nav class=
"wy-nav-top" role=
"navigation" aria-label=
"top navigation">
299 <i data-toggle=
"wy-nav-top" class=
"fa fa-bars"></i>
300 <a href=
"..">Shaarli Documentation
</a>
304 <div class=
"wy-nav-content">
305 <div class=
"rst-content">
306 <div role=
"navigation" aria-label=
"breadcrumbs navigation">
307 <ul class=
"wy-breadcrumbs">
308 <li><a href=
"..">Docs
</a> »</li>
312 <li>Development
»</li>
316 <li>Plugin System
</li>
317 <li class=
"wy-breadcrumbs-aside">
319 <a href=
"https://github.com/shaarli/Shaarli/edit/master/docs/Plugin-System.md"
320 class=
"icon icon-github"> Edit on GitHub
</a>
327 <div class=
"section">
329 <p><a href=
"#developer-api"><strong>I am a developer.
</strong> Developer API.
</a></p>
330 <p><a href=
"#guide-for-template-designer"><strong>I am a template designer.
</strong> Guide for template designer.
</a></p>
331 <h2 id=
"developer-api">Developer API
</h2>
332 <h3 id=
"what-can-i-do-with-plugins">What can I do with plugins?
</h3>
333 <p>The plugin system let you:
</p>
335 <li>insert content into specific places across templates.
</li>
336 <li>alter data before templates rendering.
</li>
337 <li>alter data before saving new links.
</li>
339 <h3 id=
"how-can-i-create-a-plugin-for-shaarli">How can I create a plugin for Shaarli?
</h3>
340 <p>First, chose a plugin name, such as
<code>demo_plugin
</code>.
</p>
341 <p>Under
<code>plugin
</code> folder, create a folder named with your plugin name. Then create a
<plugin_name>.php file in that folder.
</p>
342 <p>You should have the following tree view:
</p>
343 <pre><code>| index.php
346 | |---| demo_plugin.php
349 <h3 id=
"plugin-initialization">Plugin initialization
</h3>
350 <p>At the beginning of Shaarli execution, all enabled plugins are loaded. At this point, the plugin system looks for an
<code>init()
</code> function to execute and run it if it exists. This function must be named this way, and takes the
<code>ConfigManager
</code> as parameter.
</p>
351 <pre><code><plugin_name
>_init($conf)
353 <p>This function can be used to create initial data, load default settings, etc. But also to set
<em>plugin errors
</em>. If the initialization function returns an array of strings, they will be understand as errors, and displayed in the header to logged in users.
</p>
354 <h3 id=
"understanding-hooks">Understanding hooks
</h3>
355 <p>A plugin is a set of functions. Each function will be triggered by the plugin system at certain point in Shaarli execution.
</p>
356 <p>These functions need to be named with this pattern:
</p>
357 <pre><code>hook_
<plugin_name
>_
<hook_name
>($data, $conf)
362 <li>data: see
<a href=
"https://github.com/shaarli/Shaarli/wiki/Plugin-System#plugins-data">$data section
</a></li>
363 <li>conf: the
<code>ConfigManager
</code> instance.
</li>
365 <p>For exemple, if my plugin want to add data to the header, this function is needed:
</p>
366 <pre><code>hook_demo_plugin_render_header
368 <p>If this function is declared, and the plugin enabled, it will be called every time Shaarli is rendering the header.
</p>
369 <h3 id=
"plugins-data">Plugin's data
</h3>
370 <h4 id=
"parameters">Parameters
</h4>
371 <p>Every hook function has a
<code>$data
</code> parameter. Its content differs for each hooks.
</p>
372 <p><strong>This parameter needs to be returned every time
</strong>, otherwise data is lost.
</p>
373 <pre><code>return $data;
375 <h4 id=
"filling-templates-placeholder">Filling templates placeholder
</h4>
376 <p>Template placeholders are displayed in template in specific places.
</p>
377 <p>RainTPL displays every element contained in the placeholder's array. These element can be added by plugins.
</p>
378 <p>For example, let's add a value in the placeholder
<code>top_placeholder
</code> which is displayed at the top of my page:
</p>
379 <pre><code class=
"php">$data['top_placeholder'][] = 'My content';
381 array_push($data['top_placeholder'], 'My', 'content');
386 <h4 id=
"data-manipulation">Data manipulation
</h4>
387 <p>When a page is displayed, every variable send to the template engine is passed to plugins before that in
<code>$data
</code>.
</p>
388 <p>The data contained by this array can be altered before template rendering.
</p>
389 <p>For exemple, in linklist, it is possible to alter every title:
</p>
390 <pre><code class=
"php">// mind the reference if you want $data to be altered
391 foreach ($data['links'] as
&$value) {
392 // String reverse every title.
393 $value['title'] = strrev($value['title']);
399 <h3 id=
"metadata">Metadata
</h3>
400 <p>Every plugin needs a
<code><plugin_name
>.meta
</code> file, which is in fact an
<code>.ini
</code> file (
<code>KEY="VALUE"
</code>), to be listed in plugin administration.
</p>
401 <p>Each file contain two keys:
</p>
403 <li><code>description
</code>: plugin description
</li>
404 <li><code>parameters
</code>: user parameter names, separated by a
<code>;
</code>.
</li>
405 <li><code>parameter.
<PARAMETER_NAME
></code>: add a text description the specified parameter.
</li>
408 <p>Note: In PHP,
<code>parse_ini_file()
</code> seems to want strings to be between by quotes
<code>"</code> in the ini file.</p>
410 <h3 id="its-not-working
">It's not working!</h3>
411 <p>Use <code>demo_plugin</code> as a functional example. It covers most of the plugin system features.</p>
412 <p>If it's still not working, please <a href="https://github.com/shaarli/Shaarli/issues/new
">open an issue</a>.</p>
413 <h3 id="hooks
">Hooks</h3>
418 <th align="center
">Description</th>
423 <td><a href="#render_header
">render_header</a></td>
424 <td align="center
">Allow plugin to add content in page headers.</td>
427 <td><a href="#render_includes
">render_includes</a></td>
428 <td align="center
">Allow plugin to include their own CSS files.</td>
431 <td><a href="#render_footer
">render_footer</a></td>
432 <td align="center
">Allow plugin to add content in page footer and include their own JS files.</td>
435 <td><a href="#render_linklist
">render_linklist</a></td>
436 <td align="center
">It allows to add content at the begining and end of the page, after every link displayed and to alter link data.</td>
439 <td><a href="#render_editlink
">render_editlink</a></td>
440 <td align="center
">Allow to add fields in the form, or display elements.</td>
443 <td><a href="#render_tools
">render_tools</a></td>
444 <td align="center
">Allow to add content at the end of the page.</td>
447 <td><a href="#render_picwall
">render_picwall</a></td>
448 <td align="center
">Allow to add content at the top and bottom of the page.</td>
451 <td><a href="#render_tagcloud
">render_tagcloud</a></td>
452 <td align="center
">Allow to add content at the top and bottom of the page, and after all tags.</td>
455 <td><a href="#render_taglist
">render_taglist</a></td>
456 <td align="center
">Allow to add content at the top and bottom of the page, and after all tags.</td>
459 <td><a href="#render_daily
">render_daily</a></td>
460 <td align="center
">Allow to add content at the top and bottom of the page, the bottom of each link and to alter data.</td>
463 <td><a href="#render_feed
">render_feed</a></td>
464 <td align="center
">Allow to do add tags in RSS and ATOM feeds.</td>
467 <td><a href="#save_link
">save_link</a></td>
468 <td align="center
">Allow to alter the link being saved in the datastore.</td>
471 <td><a href="#delete_link
">delete_link</a></td>
472 <td align="center
">Allow to do an action before a link is deleted from the datastore.</td>
476 <h4 id="render_header
">render_header</h4>
477 <p>Triggered on every page.</p>
478 <p>Allow plugin to add content in page headers.</p>
479 <h5 id="data
">Data</h5>
480 <p><code>$data</code> is an array containing:</p>
482 <li><code>_PAGE_</code>: current target page (eg: <code>linklist</code>, <code>picwall</code>, etc.).</li>
483 <li><code>_LOGGEDIN_</code>: true if user is logged in, false otherwise.</li>
485 <h5 id="template-placeholders
">Template placeholders</h5>
486 <p>Items can be displayed in templates by adding an entry in <code>$data['<placeholder>']</code> array.</p>
487 <p>List of placeholders:</p>
489 <li><code>buttons_toolbar</code>: after the list of buttons in the header.</li>
491 <p><img alt="buttons_toolbar_example
" src="http://i.imgur.com/ssJUOrt.png
" /></p>
493 <li><code>fields_toolbar</code>: after search fields in the header.</li>
496 <p>Note: This will only be called in linklist.</p>
498 <p><img alt="fields_toolbar_example
" src="http://i.imgur.com/
3GMifI2.png
" /></p>
499 <h4 id="render_includes
">render_includes</h4>
500 <p>Triggered on every page.</p>
501 <p>Allow plugin to include their own CSS files.</p>
502 <h5 id="data_1
">Data</h5>
503 <p><code>$data</code> is an array containing:</p>
505 <li><code>_PAGE_</code>: current target page (eg: <code>linklist</code>, <code>picwall</code>, etc.).</li>
506 <li><code>_LOGGEDIN_</code>: true if user is logged in, false otherwise.</li>
508 <h5 id="template-placeholders_1
">Template placeholders</h5>
509 <p>Items can be displayed in templates by adding an entry in <code>$data['<placeholder>']</code> array.</p>
510 <p>List of placeholders:</p>
512 <li><code>css_files</code>: called after loading default CSS.</li>
515 <p>Note: only add the path of the CSS file. E.g: <code>plugins/demo_plugin/custom_demo.css</code>.</p>
517 <h4 id="render_footer
">render_footer</h4>
518 <p>Triggered on every page.</p>
519 <p>Allow plugin to add content in page footer and include their own JS files.</p>
520 <h5 id="data_2
">Data</h5>
521 <p><code>$data</code> is an array containing:</p>
523 <li><code>_PAGE_</code>: current target page (eg: <code>linklist</code>, <code>picwall</code>, etc.).</li>
524 <li><code>_LOGGEDIN_</code>: true if user is logged in, false otherwise.</li>
526 <h5 id="template-placeholders_2
">Template placeholders</h5>
527 <p>Items can be displayed in templates by adding an entry in <code>$data['<placeholder>']</code> array.</p>
528 <p>List of placeholders:</p>
530 <li><code>text</code>: called after the end of the footer text.</li>
531 <li><code>endofpage</code>: called at the end of the page.</li>
533 <p><img alt="text_example
" src="http://i.imgur.com/L5S2YEH.png
" /></p>
535 <li><code>js_files</code>: called at the end of the page, to include custom JS scripts.</li>
538 <p>Note: only add the path of the JS file. E.g: <code>plugins/demo_plugin/custom_demo.js</code>.</p>
540 <h4 id="render_linklist
">render_linklist</h4>
541 <p>Triggered when <code>linklist</code> is displayed (list of links, permalink, search, tag filtered, etc.).</p>
542 <p>It allows to add content at the begining and end of the page, after every link displayed and to alter link data.</p>
543 <h5 id="data_3
">Data</h5>
544 <p><code>$data</code> is an array containing:</p>
546 <li><code>_LOGGEDIN_</code>: true if user is logged in, false otherwise.</li>
547 <li>All templates data, including links.</li>
549 <h5 id="template-placeholders_3
">Template placeholders</h5>
550 <p>Items can be displayed in templates by adding an entry in <code>$data['<placeholder>']</code> array.</p>
551 <p>List of placeholders:</p>
553 <li><code>action_plugin</code>: next to the button "private only" at the top and bottom of the page.
</li>
555 <p><img alt=
"action_plugin_example" src=
"http://i.imgur.com/Q12PWg0.png" /></p>
557 <li><code>link_plugin
</code>: for every link, between permalink and link URL.
</li>
559 <p><img alt=
"link_plugin_example" src=
"http://i.imgur.com/3oDPhWx.png" /></p>
561 <li><code>plugin_start_zone
</code>: before displaying the template content.
</li>
563 <p><img alt=
"plugin_start_zone_example" src=
"http://i.imgur.com/OVBkGy3.png" /></p>
565 <li><code>plugin_end_zone
</code>: after displaying the template content.
</li>
567 <p><img alt=
"plugin_end_zone_example" src=
"http://i.imgur.com/6IoRuop.png" /></p>
568 <h4 id=
"render_editlink">render_editlink
</h4>
569 <p>Triggered when the link edition form is displayed.
</p>
570 <p>Allow to add fields in the form, or display elements.
</p>
571 <h5 id=
"data_4">Data
</h5>
572 <p><code>$data
</code> is an array containing:
</p>
574 <li>All templates data.
</li>
576 <h5 id=
"template-placeholders_4">Template placeholders
</h5>
577 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
</p>
578 <p>List of placeholders:
</p>
580 <li><code>edit_link_plugin
</code>: after tags field.
</li>
582 <p><img alt=
"edit_link_plugin_example" src=
"http://i.imgur.com/5u17Ens.png" /></p>
583 <h4 id=
"render_tools">render_tools
</h4>
584 <p>Triggered when the "tools" page is displayed.
</p>
585 <p>Allow to add content at the end of the page.
</p>
586 <h5 id=
"data_5">Data
</h5>
587 <p><code>$data
</code> is an array containing:
</p>
589 <li>All templates data.
</li>
591 <h5 id=
"template-placeholders_5">Template placeholders
</h5>
592 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
</p>
593 <p>List of placeholders:
</p>
595 <li><code>tools_plugin
</code>: at the end of the page.
</li>
597 <p><img alt=
"tools_plugin_example" src=
"http://i.imgur.com/Bqhu9oQ.png" /></p>
598 <h4 id=
"render_picwall">render_picwall
</h4>
599 <p>Triggered when picwall is displayed.
</p>
600 <p>Allow to add content at the top and bottom of the page.
</p>
601 <h5 id=
"data_6">Data
</h5>
602 <p><code>$data
</code> is an array containing:
</p>
604 <li><code>_LOGGEDIN_
</code>: true if user is logged in, false otherwise.
</li>
605 <li>All templates data.
</li>
607 <h5 id=
"template-placeholders_6">Template placeholders
</h5>
608 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
</p>
609 <p>List of placeholders:
</p>
612 <p><code>plugin_start_zone
</code>: before displaying the template content.
</p>
615 <p><code>plugin_end_zone
</code>: after displaying the template content.
</p>
618 <p><img alt=
"plugin_start_end_zone_example" src=
"http://i.imgur.com/tVTQFER.png" /></p>
619 <h4 id=
"render_tagcloud">render_tagcloud
</h4>
620 <p>Triggered when tagcloud is displayed.
</p>
621 <p>Allow to add content at the top and bottom of the page.
</p>
622 <h5 id=
"data_7">Data
</h5>
623 <p><code>$data
</code> is an array containing:
</p>
625 <li><code>_LOGGEDIN_
</code>: true if user is logged in, false otherwise.
</li>
626 <li>All templates data.
</li>
628 <h5 id=
"template-placeholders_7">Template placeholders
</h5>
629 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
</p>
630 <p>List of placeholders:
</p>
633 <p><code>plugin_start_zone
</code>: before displaying the template content.
</p>
636 <p><code>plugin_end_zone
</code>: after displaying the template content.
</p>
639 <p>For each tag, the following placeholder can be used:
</p>
641 <li><code>tag_plugin
</code>: after each tag
</li>
643 <p><img alt=
"plugin_start_end_zone_example" src=
"http://i.imgur.com/vHmyT3a.png" /></p>
644 <h4 id=
"render_taglist">render_taglist
</h4>
645 <p>Triggered when taglist is displayed.
</p>
646 <p>Allow to add content at the top and bottom of the page.
</p>
647 <h5 id=
"data_8">Data
</h5>
648 <p><code>$data
</code> is an array containing:
</p>
650 <li><code>_LOGGEDIN_
</code>: true if user is logged in, false otherwise.
</li>
651 <li>All templates data.
</li>
653 <h5 id=
"template-placeholders_8">Template placeholders
</h5>
654 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
</p>
655 <p>List of placeholders:
</p>
658 <p><code>plugin_start_zone
</code>: before displaying the template content.
</p>
661 <p><code>plugin_end_zone
</code>: after displaying the template content.
</p>
664 <p>For each tag, the following placeholder can be used:
</p>
666 <li><code>tag_plugin
</code>: after each tag
</li>
668 <h4 id=
"render_daily">render_daily
</h4>
669 <p>Triggered when tagcloud is displayed.
</p>
670 <p>Allow to add content at the top and bottom of the page, the bottom of each link and to alter data.
</p>
671 <h5 id=
"data_9">Data
</h5>
672 <p><code>$data
</code> is an array containing:
</p>
674 <li><code>_LOGGEDIN_
</code>: true if user is logged in, false otherwise.
</li>
675 <li>All templates data, including links.
</li>
677 <h5 id=
"template-placeholders_9">Template placeholders
</h5>
678 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
</p>
679 <p>List of placeholders:
</p>
681 <li><code>link_plugin
</code>: used at bottom of each link.
</li>
683 <p><img alt=
"link_plugin_example" src=
"http://i.imgur.com/hzhMfSZ.png" /></p>
686 <p><code>plugin_start_zone
</code>: before displaying the template content.
</p>
689 <p><code>plugin_end_zone
</code>: after displaying the template content.
</p>
692 <h4 id=
"render_feed">render_feed
</h4>
693 <p>Triggered when the ATOM or RSS feed is displayed.
</p>
694 <p>Allow to add tags in the feed, either in the header or for each items. Items (links) can also be altered before being rendered.
</p>
695 <h5 id=
"data_10">Data
</h5>
696 <p><code>$data
</code> is an array containing:
</p>
698 <li><code>_LOGGEDIN_
</code>: true if user is logged in, false otherwise.
</li>
699 <li><code>_PAGE_
</code>: containing either
<code>rss
</code> or
<code>atom
</code>.
</li>
700 <li>All templates data, including links.
</li>
702 <h5 id=
"template-placeholders_10">Template placeholders
</h5>
703 <p>Tags can be added in feeds by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
</p>
704 <p>List of placeholders:
</p>
706 <li><code>feed_plugins_header
</code>: used as a header tag in the feed.
</li>
708 <p>For each links:
</p>
710 <li><code>feed_plugins
</code>: additional tag for every link entry.
</li>
712 <h4 id=
"save_link">save_link
</h4>
713 <p>Triggered when a link is save (new link or edit).
</p>
714 <p>Allow to alter the link being saved in the datastore.
</p>
715 <h5 id=
"data_11">Data
</h5>
716 <p><code>$data
</code> is an array containing the link being saved:
</p>
728 <h4 id=
"delete_link">delete_link
</h4>
729 <p>Triggered when a link is deleted.
</p>
730 <p>Allow to execute any action before the link is actually removed from the datastore
</p>
731 <h5 id=
"data_12">Data
</h5>
732 <p><code>$data
</code> is an array containing the link being saved:
</p>
744 <h2 id=
"guide-for-template-designer">Guide for template designer
</h2>
745 <h3 id=
"plugin-administration">Plugin administration
</h3>
746 <p>Your theme must include a plugin administration page:
<code>pluginsadmin.html
</code>.
</p>
748 <p>Note: repo's template link needs to be added when the PR is merged.
</p>
750 <p>Use the default one as an example.
</p>
751 <p>Aside from classic RainTPL loops, plugins order is handle by JavaScript. You can just include
<code>plugin_admin.js
</code>, only if:
</p>
753 <li>you're using a table.
</li>
754 <li>you call orderUp() and orderUp() onclick on arrows.
</li>
755 <li>you add data-line and data-order to your rows.
</li>
757 <p>Otherwise, you can use your own JS as long as this field is send by the form:
</p>
758 <p><input type=
"hidden" name=
"order_{$key}" value=
"{$counter}"></p>
759 <h3 id=
"placeholder-system">Placeholder system
</h3>
760 <p>In order to make plugins work with every custom themes, you need to add variable placeholder in your templates.
</p>
761 <p>It's a RainTPL loop like this:
</p>
762 <pre><code>{
loop="$plugin_variable"}
766 <p>You should enable
<code>demo_plugin
</code> for testing purpose, since it uses every placeholder available.
</p>
767 <h3 id=
"list-of-placeholders">List of placeholders
</h3>
768 <p><strong>page.header.html
</strong></p>
769 <p>At the end of the menu:
</p>
770 <pre><code>{
loop="$plugins_header.buttons_toolbar"}
774 <p>At the end of file, before clearing floating blocks:
</p>
775 <pre><code>{
if="!empty($plugin_errors)
&& isLoggedIn()"}
776 <ul
class="errors"
>
777 {
loop="plugin_errors"}
778 <li
>{$value}
</li
>
783 <p><strong>includes.html
</strong></p>
784 <p>At the end of the file:
</p>
785 <pre><code class=
"html">{loop=
"$plugins_includes.css_files
"}
786 <link type=
"text/css
" rel=
"stylesheet
" href=
"{$value}#
"/
>
790 <p><strong>page.footer.html
</strong></p>
791 <p>At the end of your footer notes:
</p>
792 <pre><code class=
"html">{loop=
"$plugins_footer.text
"}
797 <p>At the end of file:
</p>
798 <pre><code class=
"html">{loop=
"$plugins_footer.js_files
"}
799 <script src=
"{$value}#
"></script
>
803 <p><strong>linklist.html
</strong></p>
804 <p>After search fields:
</p>
805 <pre><code class=
"html">{loop=
"$plugins_header.fields_toolbar
"}
810 <p>Before displaying the link list (after paging):
</p>
811 <pre><code class=
"html">{loop=
"$plugin_start_zone
"}
816 <p>For every links (icons):
</p>
817 <pre><code class=
"html">{loop=
"$value.link_plugin
"}
818 <span
>{$value}
</span
>
822 <p>Before end paging:
</p>
823 <pre><code class=
"html">{loop=
"$plugin_end_zone
"}
828 <p><strong>linklist.paging.html
</strong></p>
829 <p>After the "private only" icon:
</p>
830 <pre><code class=
"html">{loop=
"$action_plugin
"}
835 <p><strong>editlink.html
</strong></p>
836 <p>After tags field:
</p>
837 <pre><code class=
"html">{loop=
"$edit_link_plugin
"}
842 <p><strong>tools.html
</strong></p>
843 <p>After the last tool:
</p>
844 <pre><code class=
"html">{loop=
"$tools_plugin
"}
849 <p><strong>picwall.html
</strong></p>
851 <pre><code class=
"html"><div id=
"plugin_zone_start_picwall
" class=
"plugin_zone
">
852 {loop=
"$plugin_start_zone
"}
859 <pre><code class=
"html"><div id=
"plugin_zone_end_picwall
" class=
"plugin_zone
">
860 {loop=
"$plugin_end_zone
"}
866 <p><strong>tagcloud.html
</strong></p>
868 <pre><code class=
"html"> <div id=
"plugin_zone_start_tagcloud
" class=
"plugin_zone
">
869 {loop=
"$plugin_start_zone
"}
876 <pre><code class=
"html"> <div id=
"plugin_zone_end_tagcloud
" class=
"plugin_zone
">
877 {loop=
"$plugin_end_zone
"}
883 <p><strong>daily.html
</strong></p>
885 <pre><code class=
"html"><div id=
"plugin_zone_start_picwall
" class=
"plugin_zone
">
886 {loop=
"$plugin_start_zone
"}
892 <p>After every link:
</p>
893 <pre><code class=
"html"><div class=
"dailyEntryFooter
">
894 {loop=
"$link.link_plugin
"}
901 <pre><code class=
"html"><div id=
"plugin_zone_end_picwall
" class=
"plugin_zone
">
902 {loop=
"$plugin_end_zone
"}
908 <p><strong>feed.atom.xml
</strong> and
<strong>feed.rss.xml
</strong>:
</p>
909 <p>In headers tags section:
</p>
910 <pre><code class=
"xml">{loop=
"$feed_plugins_header
"}
915 <p>After each entry:
</p>
916 <pre><code class=
"xml">{loop=
"$value.feed_plugins
"}
925 <div class=
"rst-footer-buttons" role=
"navigation" aria-label=
"footer navigation">
927 <a href=
"../Release-Shaarli/" class=
"btn btn-neutral float-right" title=
"Release Shaarli">Next
<span class=
"icon icon-circle-arrow-right"></span></a>
930 <a href=
"../3rd-party-libraries/" class=
"btn btn-neutral" title=
"3rd party libraries"><span class=
"icon icon-circle-arrow-left"></span> Previous
</a>
937 <div role=
"contentinfo">
938 <!-- Copyright etc -->
942 Built with
<a href=
"http://www.mkdocs.org">MkDocs
</a> using a
<a href=
"https://github.com/snide/sphinx_rtd_theme">theme
</a> provided by
<a href=
"https://readthedocs.org">Read the Docs
</a>.
952 <div class=
"rst-versions" role=
"note" style=
"cursor: pointer">
953 <span class=
"rst-current-version" data-toggle=
"rst-current-version">
955 <a href=
"https://github.com/shaarli/Shaarli" class=
"fa fa-github" style=
"float: left; color: #fcfcfc"> GitHub
</a>
958 <span><a href=
"../3rd-party-libraries/" style=
"color: #fcfcfc;">« Previous
</a></span>
961 <span style=
"margin-left: 15px"><a href=
"../Release-Shaarli/" style=
"color: #fcfcfc">Next
»</a></span>
965 <script src=
"../js/theme.js"></script>