5 <meta name=
"generator" content=
"pandoc">
6 <meta name=
"viewport" content=
"width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli – Plugin System
</title>
8 <style type=
"text/css">code{white-space: pre;}
</style>
9 <style type=
"text/css">
10 div.sourceCode { overflow-x: auto; }
11 table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
12 margin:
0; padding:
0; vertical-align: baseline; border: none; }
13 table.sourceCode { width:
100%; line-height:
100%; }
14 td.lineNumbers { text-align: right; padding-right:
4px; padding-left:
4px; color: #aaaaaa; border-right:
1px solid #aaaaaa; }
15 td.sourceCode { padding-left:
5px; }
16 code
> span.kw { color: #
007020; font-weight: bold; } /* Keyword */
17 code
> span.dt { color: #
902000; } /* DataType */
18 code
> span.dv { color: #
40a070; } /* DecVal */
19 code
> span.bn { color: #
40a070; } /* BaseN */
20 code
> span.fl { color: #
40a070; } /* Float */
21 code
> span.ch { color: #
4070a0; } /* Char */
22 code
> span.st { color: #
4070a0; } /* String */
23 code
> span.co { color: #
60a0b0; font-style: italic; } /* Comment */
24 code
> span.ot { color: #
007020; } /* Other */
25 code
> span.al { color: #ff0000; font-weight: bold; } /* Alert */
26 code
> span.fu { color: #
06287e; } /* Function */
27 code
> span.er { color: #ff0000; font-weight: bold; } /* Error */
28 code
> span.wa { color: #
60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29 code
> span.cn { color: #
880000; } /* Constant */
30 code
> span.sc { color: #
4070a0; } /* SpecialChar */
31 code
> span.vs { color: #
4070a0; } /* VerbatimString */
32 code
> span.ss { color: #bb6688; } /* SpecialString */
33 code
> span.im { } /* Import */
34 code
> span.va { color: #
19177c; } /* Variable */
35 code
> span.cf { color: #
007020; font-weight: bold; } /* ControlFlow */
36 code
> span.op { color: #
666666; } /* Operator */
37 code
> span.bu { } /* BuiltIn */
38 code
> span.ex { } /* Extension */
39 code
> span.pp { color: #bc7a00; } /* Preprocessor */
40 code
> span.at { color: #
7d9029; } /* Attribute */
41 code
> span.do { color: #ba2121; font-style: italic; } /* Documentation */
42 code
> span.an { color: #
60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43 code
> span.cv { color: #
60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44 code
> span.in { color: #
60a0b0; font-weight: bold; font-style: italic; } /* Information */
46 <link rel=
"stylesheet" href=
"github-markdown.css">
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
52 <div id=
"local-sidebar">
54 <li><a href=
"Home.html">Home
</a></li>
57 <li><a href=
"Download-and-Installation.html">Download and Installation
</a></li>
58 <li><a href=
"Upgrade-and-migration.html">Upgrade and migration
</a></li>
59 <li><a href=
"Server-requirements.html">Server requirements
</a></li>
60 <li><a href=
"Server-configuration.html">Server configuration
</a></li>
61 <li><a href=
"Server-security.html">Server security
</a></li>
62 <li><a href=
"Shaarli-configuration.html">Shaarli configuration
</a></li>
63 <li><a href=
"Plugins.html">Plugins
</a></li>
65 <li><a href=
"Docker.html">Docker
</a></li>
66 <li><a href=
"Usage.html">Usage
</a>
68 <li><a href=
"Sharing-button.html">Sharing button
</a> (bookmarklet)
</li>
69 <li><a href=
"Browsing-and-Searching.html">Browsing and Searching
</a></li>
70 <li><a href=
"Firefox-share.html">Firefox share
</a></li>
71 <li><a href=
"RSS-feeds.html">RSS feeds
</a></li>
72 <li><a href=
"REST-API.html">REST API
</a></li>
76 <li><a href=
"Backup,-restore,-import-and-export.html">Backup, restore, import and export
</a></li>
77 <li><a href=
"Copy-an-existing-installation-over-SSH-and-serve-it-locally.html">Copy an existing installation over SSH and serve it locally
</a></li>
78 <li><a href=
"Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)
</a></li>
79 <li><a href=
"Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list
</a></li>
80 <li><a href=
"Datastore-hacks.html">Datastore hacks
</a></li>
82 <li><a href=
"Troubleshooting.html">Troubleshooting
</a></li>
83 <li><a href=
"Development.html">Development
</a>
85 <li><a href=
"GnuPG-signature.html">GnuPG signature
</a></li>
86 <li><a href=
"Coding-guidelines.html">Coding guidelines
</a></li>
87 <li><a href=
"Directory-structure.html">Directory structure
</a></li>
88 <li><a href=
"3rd-party-libraries.html">3rd party libraries
</a></li>
89 <li><a href=
"Plugin-System.html">Plugin System
</a></li>
90 <li><a href=
"Release-Shaarli.html">Release Shaarli
</a></li>
91 <li><a href=
"Versioning-and-Branches.html">Versioning and Branches
</a></li>
92 <li><a href=
"Security.html">Security
</a></li>
93 <li><a href=
"Static-analysis.html">Static analysis
</a></li>
94 <li><a href=
"Theming.html">Theming
</a></li>
95 <li><a href=
"Unit-tests.html">Unit tests
</a></li>
99 <li><a href=
"FAQ.html">FAQ
</a></li>
100 <li><a href=
"Community-&-Related-software.html">Community
& Related software
</a></li>
104 <h1 id=
"plugin-system">Plugin System
</h1>
105 <p><a href=
"#developer-api"><strong>I am a developer.
</strong> Developer API.
</a><a href=
".html"></a></p>
106 <p><a href=
"#guide-for-template-designer"><strong>I am a template designer.
</strong> Guide for template designer.
</a><a href=
".html"></a></p>
107 <h2 id=
"developer-api">Developer API
</h2>
108 <h3 id=
"what-can-i-do-with-plugins">What can I do with plugins?
</h3>
109 <p>The plugin system let you:
</p>
111 <li>insert content into specific places across templates.
</li>
112 <li>alter data before templates rendering.
</li>
113 <li>alter data before saving new links.
</li>
115 <h3 id=
"how-can-i-create-a-plugin-for-shaarli">How can I create a plugin for Shaarli?
</h3>
116 <p>First, chose a plugin name, such as
<code>demo_plugin
</code>.
</p>
117 <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>
118 <p>You should have the following tree view:
</p>
119 <pre><code>| index.php
122 | |---| demo_plugin.php
</code></pre>
123 <h3 id=
"plugin-initialization">Plugin initialization
</h3>
124 <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>
125 <pre><code><plugin_name
>_init($conf)
</code></pre>
126 <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>
127 <h3 id=
"understanding-hooks">Understanding hooks
</h3>
128 <p>A plugin is a set of functions. Each function will be triggered by the plugin system at certain point in Shaarli execution.
</p>
129 <p>These functions need to be named with this pattern:
</p>
130 <pre><code>hook_
<plugin_name
>_
<hook_name
>($data, $conf)
</code></pre>
133 <li>data: see
<a href=
"https://github.com/shaarli/Shaarli/wiki/Plugin-System#plugins-data">$data section
</a><a href=
".html"></a></li>
134 <li>conf: the
<code>ConfigManager
</code> instance.
</li>
136 <p>For exemple, if my plugin want to add data to the header, this function is needed:
</p>
137 <pre><code>hook_demo_plugin_render_header
</code></pre>
138 <p>If this function is declared, and the plugin enabled, it will be called every time Shaarli is rendering the header.
</p>
139 <h3 id=
"plugins-data">Plugin's data
</h3>
140 <h4 id=
"parameters">Parameters
</h4>
141 <p>Every hook function has a
<code>$data
</code> parameter. Its content differs for each hooks.
</p>
142 <p><strong>This parameter needs to be returned every time
</strong>, otherwise data is lost.
</p>
143 <pre><code>return $data;
</code></pre>
144 <h4 id=
"filling-templates-placeholder">Filling templates placeholder
</h4>
145 <p>Template placeholders are displayed in template in specific places.
</p>
146 <p>RainTPL displays every element contained in the placeholder's array. These element can be added by plugins.
</p>
147 <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>
148 <div class=
"sourceCode"><pre class=
"sourceCode php"><code class=
"sourceCode php"><span class=
"kw">$data
</span><span class=
"ot">[
</span><span class=
"st">'top_placeholder
'</span><span class=
"ot">[]
</span> =
<span class=
"st">'My content
'</span><span class=
"ot">;](]
</span>-=-
<span class=
"st">'My-content
'</span><span class=
"ot">;
</span>.html
<span class=
"ot">)
</span>
149 <span class=
"co"># OR
</span>
150 <span class=
"fu">array_push
</span><span class=
"ot">(
</span><span class=
"kw">$data
</span><span class=
"ot">[
</span><span class=
"st">'top_placeholder
'</span><span class=
"ot">],
</span> <span class=
"st">'My
'</span><span class=
"ot">,
</span> <span class=
"st">'content
'</span><span class=
"ot">);[](
</span>.html
<span class=
"ot">)
</span>
152 <span class=
"kw">return
</span> <span class=
"kw">$data
</span><span class=
"ot">;
</span></code></pre></div>
153 <h4 id=
"data-manipulation">Data manipulation
</h4>
154 <p>When a page is displayed, every variable send to the template engine is passed to plugins before that in
<code>$data
</code>.
</p>
155 <p>The data contained by this array can be altered before template rendering.
</p>
156 <p>For exemple, in linklist, it is possible to alter every title:
</p>
157 <div class=
"sourceCode"><pre class=
"sourceCode php"><code class=
"sourceCode php"><span class=
"co">// mind the reference if you want $data to be altered
</span>
158 <span class=
"kw">foreach
</span> <span class=
"ot">(
</span><span class=
"kw">$data
</span><span class=
"ot">[
</span><span class=
"st">'links
'</span><span class=
"ot">]
</span> <span class=
"kw">as
</span> &<span class=
"kw">$value
</span><span class=
"ot">)
</span> {
<span class=
"ot">[](
</span>.html
<span class=
"ot">)
</span>
159 <span class=
"co">// String reverse every title.
</span>
160 <span class=
"kw">$value
</span><span class=
"ot">[
</span><span class=
"st">'title
'</span><span class=
"ot">]
</span> =
<span class=
"fu">strrev
</span><span class=
"ot">(
</span><span class=
"kw">$value
</span><span class=
"ot">[
</span><span class=
"st">'title
'</span><span class=
"ot">]);[](
</span>.html
<span class=
"ot">)
</span>
163 <span class=
"kw">return
</span> <span class=
"kw">$data
</span><span class=
"ot">;
</span></code></pre></div>
164 <h3 id=
"metadata">Metadata
</h3>
165 <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>
166 <p>Each file contain two keys:
</p>
168 <li><code>description
</code>: plugin description
</li>
169 <li><code>parameters
</code>: user parameter names, separated by a
<code>;
</code>.
</li>
170 <li><code>parameter.
<PARAMETER_NAME
></code>: add a text description the specified parameter.
</li>
173 <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>
175 <h3 id=
"its-not-working">It's not working!
</h3>
176 <p>Use
<code>demo_plugin
</code> as a functional example. It covers most of the plugin system features.
</p>
177 <p>If it's still not working, please
<a href=
"https://github.com/shaarli/Shaarli/issues/new">open an issue
</a>.
<a href=
".html"></a></p>
178 <h3 id=
"hooks">Hooks
</h3>
179 <table style=
"width:42%;">
181 <col style=
"width: 19%" />
182 <col style=
"width: 22%" />
187 <th style=
"text-align: center;">Description
</th>
192 <td><a href=
"#render_header">render_header
</a></td>
193 <td style=
"text-align: center;">Allow plugin to add content in page headers.
</td>
196 <td><a href=
"#render_includes">render_includes
</a></td>
197 <td style=
"text-align: center;">Allow plugin to include their own CSS files.
</td>
200 <td><a href=
"#render_footer">render_footer
</a></td>
201 <td style=
"text-align: center;">Allow plugin to add content in page footer and include their own JS files.
</td>
204 <td><a href=
"#render_linklist">render_linklist
</a></td>
205 <td style=
"text-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>
208 <td><a href=
"#render_editlink">render_editlink
</a></td>
209 <td style=
"text-align: center;">Allow to add fields in the form, or display elements.
</td>
212 <td><a href=
"#render_tools">render_tools
</a></td>
213 <td style=
"text-align: center;">Allow to add content at the end of the page.
</td>
216 <td><a href=
"#render_picwall">render_picwall
</a></td>
217 <td style=
"text-align: center;">Allow to add content at the top and bottom of the page.
</td>
220 <td><a href=
"#render_tagcloud">render_tagcloud
</a></td>
221 <td style=
"text-align: center;">Allow to add content at the top and bottom of the page, and after all tags.
</td>
224 <td><a href=
"#render_taglist">render_taglist
</a></td>
225 <td style=
"text-align: center;">Allow to add content at the top and bottom of the page, and after all tags.
</td>
228 <td><a href=
"#render_daily">render_daily
</a></td>
229 <td style=
"text-align: center;">Allow to add content at the top and bottom of the page, the bottom of each link and to alter data.
</td>
232 <td><a href=
"#render_feed">render_feed
</a></td>
233 <td style=
"text-align: center;">Allow to do add tags in RSS and ATOM feeds.
</td>
236 <td><a href=
"#save_link">save_link
</a></td>
237 <td style=
"text-align: center;">Allow to alter the link being saved in the datastore.
</td>
240 <td><a href=
"#delete_link">delete_link
</a></td>
241 <td style=
"text-align: center;">Allow to do an action before a link is deleted from the datastore.
</td>
245 <h4 id=
"render_header">render_header
</h4>
246 <p>Triggered on every page.
</p>
247 <p>Allow plugin to add content in page headers.
</p>
248 <h5 id=
"data">Data
</h5>
249 <p><code>$data
</code> is an array containing:
</p>
251 <li><code>_PAGE_
</code>: current target page (eg:
<code>linklist
</code>,
<code>picwall
</code>, etc.).
</li>
252 <li><code>_LOGGEDIN_
</code>: true if user is logged in, false otherwise.
</li>
254 <h5 id=
"template-placeholders">Template placeholders
</h5>
255 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
<a href=
".html"></a></p>
256 <p>List of placeholders:
</p>
258 <li><code>buttons_toolbar
</code>: after the list of buttons in the header.
</li>
260 <p><img src=
"http://i.imgur.com/ssJUOrt.png" alt=
"buttons_toolbar_example" /><a href=
".html"></a></p>
262 <li><code>fields_toolbar
</code>: after search fields in the header.
</li>
265 <p>Note: This will only be called in linklist.
</p>
267 <p><img src=
"http://i.imgur.com/3GMifI2.png" alt=
"fields_toolbar_example" /><a href=
".html"></a></p>
268 <h4 id=
"render_includes">render_includes
</h4>
269 <p>Triggered on every page.
</p>
270 <p>Allow plugin to include their own CSS files.
</p>
271 <h5 id=
"data-1">Data
</h5>
272 <p><code>$data
</code> is an array containing:
</p>
274 <li><code>_PAGE_
</code>: current target page (eg:
<code>linklist
</code>,
<code>picwall
</code>, etc.).
</li>
275 <li><code>_LOGGEDIN_
</code>: true if user is logged in, false otherwise.
</li>
277 <h5 id=
"template-placeholders-1">Template placeholders
</h5>
278 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
<a href=
".html"></a></p>
279 <p>List of placeholders:
</p>
281 <li><code>css_files
</code>: called after loading default CSS.
</li>
284 <p>Note: only add the path of the CSS file. E.g:
<code>plugins/demo_plugin/custom_demo.css
</code>.
</p>
286 <h4 id=
"render_footer">render_footer
</h4>
287 <p>Triggered on every page.
</p>
288 <p>Allow plugin to add content in page footer and include their own JS files.
</p>
289 <h5 id=
"data-2">Data
</h5>
290 <p><code>$data
</code> is an array containing:
</p>
292 <li><code>_PAGE_
</code>: current target page (eg:
<code>linklist
</code>,
<code>picwall
</code>, etc.).
</li>
293 <li><code>_LOGGEDIN_
</code>: true if user is logged in, false otherwise.
</li>
295 <h5 id=
"template-placeholders-2">Template placeholders
</h5>
296 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
<a href=
".html"></a></p>
297 <p>List of placeholders:
</p>
299 <li><code>text
</code>: called after the end of the footer text.
</li>
300 <li><code>endofpage
</code>: called at the end of the page.
</li>
302 <p><img src=
"http://i.imgur.com/L5S2YEH.png" alt=
"text_example" /><a href=
".html"></a></p>
304 <li><code>js_files
</code>: called at the end of the page, to include custom JS scripts.
</li>
307 <p>Note: only add the path of the JS file. E.g:
<code>plugins/demo_plugin/custom_demo.js
</code>.
</p>
309 <h4 id=
"render_linklist">render_linklist
</h4>
310 <p>Triggered when
<code>linklist
</code> is displayed (list of links, permalink, search, tag filtered, etc.).
</p>
311 <p>It allows to add content at the begining and end of the page, after every link displayed and to alter link data.
</p>
312 <h5 id=
"data-3">Data
</h5>
313 <p><code>$data
</code> is an array containing:
</p>
315 <li><code>_LOGGEDIN_
</code>: true if user is logged in, false otherwise.
</li>
316 <li>All templates data, including links.
</li>
318 <h5 id=
"template-placeholders-3">Template placeholders
</h5>
319 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
<a href=
".html"></a></p>
320 <p>List of placeholders:
</p>
322 <li><code>action_plugin
</code>: next to the button
"private only
" at the top and bottom of the page.
</li>
324 <p><img src=
"http://i.imgur.com/Q12PWg0.png" alt=
"action_plugin_example" /><a href=
".html"></a></p>
326 <li><code>link_plugin
</code>: for every link, between permalink and link URL.
</li>
328 <p><img src=
"http://i.imgur.com/3oDPhWx.png" alt=
"link_plugin_example" /><a href=
".html"></a></p>
330 <li><code>plugin_start_zone
</code>: before displaying the template content.
</li>
332 <p><img src=
"http://i.imgur.com/OVBkGy3.png" alt=
"plugin_start_zone_example" /><a href=
".html"></a></p>
334 <li><code>plugin_end_zone
</code>: after displaying the template content.
</li>
336 <p><img src=
"http://i.imgur.com/6IoRuop.png" alt=
"plugin_end_zone_example" /><a href=
".html"></a></p>
337 <h4 id=
"render_editlink">render_editlink
</h4>
338 <p>Triggered when the link edition form is displayed.
</p>
339 <p>Allow to add fields in the form, or display elements.
</p>
340 <h5 id=
"data-4">Data
</h5>
341 <p><code>$data
</code> is an array containing:
</p>
343 <li>All templates data.
</li>
345 <h5 id=
"template-placeholders-4">Template placeholders
</h5>
346 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
<a href=
".html"></a></p>
347 <p>List of placeholders:
</p>
349 <li><code>edit_link_plugin
</code>: after tags field.
</li>
351 <p><img src=
"http://i.imgur.com/5u17Ens.png" alt=
"edit_link_plugin_example" /><a href=
".html"></a></p>
352 <h4 id=
"render_tools">render_tools
</h4>
353 <p>Triggered when the
"tools
" page is displayed.
</p>
354 <p>Allow to add content at the end of the page.
</p>
355 <h5 id=
"data-5">Data
</h5>
356 <p><code>$data
</code> is an array containing:
</p>
358 <li>All templates data.
</li>
360 <h5 id=
"template-placeholders-5">Template placeholders
</h5>
361 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
<a href=
".html"></a></p>
362 <p>List of placeholders:
</p>
364 <li><code>tools_plugin
</code>: at the end of the page.
</li>
366 <p><img src=
"http://i.imgur.com/Bqhu9oQ.png" alt=
"tools_plugin_example" /><a href=
".html"></a></p>
367 <h4 id=
"render_picwall">render_picwall
</h4>
368 <p>Triggered when picwall is displayed.
</p>
369 <p>Allow to add content at the top and bottom of the page.
</p>
370 <h5 id=
"data-6">Data
</h5>
371 <p><code>$data
</code> is an array containing:
</p>
373 <li><code>_LOGGEDIN_
</code>: true if user is logged in, false otherwise.
</li>
374 <li>All templates data.
</li>
376 <h5 id=
"template-placeholders-6">Template placeholders
</h5>
377 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
<a href=
".html"></a></p>
378 <p>List of placeholders:
</p>
380 <li><p><code>plugin_start_zone
</code>: before displaying the template content.
</p></li>
381 <li><p><code>plugin_end_zone
</code>: after displaying the template content.
</p></li>
383 <p><img src=
"http://i.imgur.com/tVTQFER.png" alt=
"plugin_start_end_zone_example" /><a href=
".html"></a></p>
384 <h4 id=
"render_tagcloud">render_tagcloud
</h4>
385 <p>Triggered when tagcloud is displayed.
</p>
386 <p>Allow to add content at the top and bottom of the page.
</p>
387 <h5 id=
"data-7">Data
</h5>
388 <p><code>$data
</code> is an array containing:
</p>
390 <li><code>_LOGGEDIN_
</code>: true if user is logged in, false otherwise.
</li>
391 <li>All templates data.
</li>
393 <h5 id=
"template-placeholders-7">Template placeholders
</h5>
394 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
<a href=
".html"></a></p>
395 <p>List of placeholders:
</p>
397 <li><p><code>plugin_start_zone
</code>: before displaying the template content.
</p></li>
398 <li><p><code>plugin_end_zone
</code>: after displaying the template content.
</p></li>
400 <p>For each tag, the following placeholder can be used:
</p>
402 <li><code>tag_plugin
</code>: after each tag
</li>
404 <p><img src=
"http://i.imgur.com/vHmyT3a.png" alt=
"plugin_start_end_zone_example" /><a href=
".html"></a></p>
405 <h4 id=
"render_taglist">render_taglist
</h4>
406 <p>Triggered when taglist is displayed.
</p>
407 <p>Allow to add content at the top and bottom of the page.
</p>
408 <h5 id=
"data-8">Data
</h5>
409 <p><code>$data
</code> is an array containing:
</p>
411 <li><code>_LOGGEDIN_
</code>: true if user is logged in, false otherwise.
</li>
412 <li>All templates data.
</li>
414 <h5 id=
"template-placeholders-8">Template placeholders
</h5>
415 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
<a href=
".html"></a></p>
416 <p>List of placeholders:
</p>
418 <li><p><code>plugin_start_zone
</code>: before displaying the template content.
</p></li>
419 <li><p><code>plugin_end_zone
</code>: after displaying the template content.
</p></li>
421 <p>For each tag, the following placeholder can be used:
</p>
423 <li><code>tag_plugin
</code>: after each tag
</li>
425 <h4 id=
"render_daily">render_daily
</h4>
426 <p>Triggered when tagcloud is displayed.
</p>
427 <p>Allow to add content at the top and bottom of the page, the bottom of each link and to alter data.
</p>
428 <h5 id=
"data-9">Data
</h5>
429 <p><code>$data
</code> is an array containing:
</p>
431 <li><code>_LOGGEDIN_
</code>: true if user is logged in, false otherwise.
</li>
432 <li>All templates data, including links.
</li>
434 <h5 id=
"template-placeholders-9">Template placeholders
</h5>
435 <p>Items can be displayed in templates by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
<a href=
".html"></a></p>
436 <p>List of placeholders:
</p>
438 <li><code>link_plugin
</code>: used at bottom of each link.
</li>
440 <p><img src=
"http://i.imgur.com/hzhMfSZ.png" alt=
"link_plugin_example" /><a href=
".html"></a></p>
442 <li><p><code>plugin_start_zone
</code>: before displaying the template content.
</p></li>
443 <li><p><code>plugin_end_zone
</code>: after displaying the template content.
</p></li>
445 <h4 id=
"render_feed">render_feed
</h4>
446 <p>Triggered when the ATOM or RSS feed is displayed.
</p>
447 <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>
448 <h5 id=
"data-10">Data
</h5>
449 <p><code>$data
</code> is an array containing:
</p>
451 <li><code>_LOGGEDIN_
</code>: true if user is logged in, false otherwise.
</li>
452 <li><code>_PAGE_
</code>: containing either
<code>rss
</code> or
<code>atom
</code>.
</li>
453 <li>All templates data, including links.
</li>
455 <h5 id=
"template-placeholders-10">Template placeholders
</h5>
456 <p>Tags can be added in feeds by adding an entry in
<code>$data['
<placeholder
>']
</code> array.
<a href=
".html"></a></p>
457 <p>List of placeholders:
</p>
459 <li><code>feed_plugins_header
</code>: used as a header tag in the feed.
</li>
461 <p>For each links:
</p>
463 <li><code>feed_plugins
</code>: additional tag for every link entry.
</li>
465 <h4 id=
"save_link">save_link
</h4>
466 <p>Triggered when a link is save (new link or edit).
</p>
467 <p>Allow to alter the link being saved in the datastore.
</p>
468 <h5 id=
"data-11">Data
</h5>
469 <p><code>$data
</code> is an array containing the link being saved:
</p>
481 <h4 id=
"delete_link">delete_link
</h4>
482 <p>Triggered when a link is deleted.
</p>
483 <p>Allow to execute any action before the link is actually removed from the datastore
</p>
484 <h5 id=
"data-12">Data
</h5>
485 <p><code>$data
</code> is an array containing the link being saved:
</p>
497 <h2 id=
"guide-for-template-designer">Guide for template designer
</h2>
498 <h3 id=
"plugin-administration">Plugin administration
</h3>
499 <p>Your theme must include a plugin administration page:
<code>pluginsadmin.html
</code>.
</p>
501 <p>Note: repo's template link needs to be added when the PR is merged.
</p>
503 <p>Use the default one as an example.
</p>
504 <p>Aside from classic RainTPL loops, plugins order is handle by JavaScript. You can just include
<code>plugin_admin.js
</code>, only if:
</p>
506 <li>you're using a table.
</li>
507 <li>you call orderUp() and orderUp() onclick on arrows.
</li>
508 <li>you add data-line and data-order to your rows.
</li>
510 <p>Otherwise, you can use your own JS as long as this field is send by the form:
</p>
511 <p><input type=
"hidden" name=
"order_{$key}" value=
"{$counter}"></p>
512 <h3 id=
"placeholder-system">Placeholder system
</h3>
513 <p>In order to make plugins work with every custom themes, you need to add variable placeholder in your templates.
</p>
514 <p>It's a RainTPL loop like this:
</p>
515 <pre><code>{loop=
"$plugin_variable
"}
518 <p>You should enable
<code>demo_plugin
</code> for testing purpose, since it uses every placeholder available.
</p>
519 <h3 id=
"list-of-placeholders">List of placeholders
</h3>
520 <p><strong>page.header.html
</strong></p>
521 <p>At the end of the menu:
</p>
522 <pre><code>{loop=
"$plugins_header.buttons_toolbar
"}
525 <p>At the end of file, before clearing floating blocks:
</p>
526 <pre><code>{if=
"!empty($plugin_errors)
&& isLoggedIn()
"}
527 <ul class=
"errors
">
528 {loop=
"plugin_errors
"}
529 <li
>{$value}
</li
>
533 <p><strong>includes.html
</strong></p>
534 <p>At the end of the file:
</p>
535 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html">{loop=
"$plugins_includes.css_files
"}
536 <span class=
"kw"><link
</span><span class=
"ot"> type=
</span><span class=
"st">"text/css
"</span><span class=
"ot"> rel=
</span><span class=
"st">"stylesheet
"</span><span class=
"ot"> href=
</span><span class=
"st">"{$value}#
"</span><span class=
"kw">/
></span>
537 {/loop}
</code></pre></div>
538 <p><strong>page.footer.html
</strong></p>
539 <p>At the end of your footer notes:
</p>
540 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html">{loop=
"$plugins_footer.text
"}
542 {/loop}
</code></pre></div>
543 <p>At the end of file:
</p>
544 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html">{loop=
"$plugins_footer.js_files
"}
545 <span class=
"kw"><script
</span><span class=
"ot"> src=
</span><span class=
"st">"{$value}#
"</span><span class=
"kw">></script
></span>
546 {/loop}
</code></pre></div>
547 <p><strong>linklist.html
</strong></p>
548 <p>After search fields:
</p>
549 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html">{loop=
"$plugins_header.fields_toolbar
"}
551 {/loop}
</code></pre></div>
552 <p>Before displaying the link list (after paging):
</p>
553 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html">{loop=
"$plugin_start_zone
"}
555 {/loop}
</code></pre></div>
556 <p>For every links (icons):
</p>
557 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html">{loop=
"$value.link_plugin
"}
558 <span class=
"kw"><span
></span>{$value}
<span class=
"kw"></span
></span>
559 {/loop}
</code></pre></div>
560 <p>Before end paging:
</p>
561 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html">{loop=
"$plugin_end_zone
"}
563 {/loop}
</code></pre></div>
564 <p><strong>linklist.paging.html
</strong></p>
565 <p>After the
"private only
" icon:
</p>
566 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html">{loop=
"$action_plugin
"}
568 {/loop}
</code></pre></div>
569 <p><strong>editlink.html
</strong></p>
570 <p>After tags field:
</p>
571 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html">{loop=
"$edit_link_plugin
"}
573 {/loop}
</code></pre></div>
574 <p><strong>tools.html
</strong></p>
575 <p>After the last tool:
</p>
576 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html">{loop=
"$tools_plugin
"}
578 {/loop}
</code></pre></div>
579 <p><strong>picwall.html
</strong></p>
581 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html"><span class=
"kw"><div
</span><span class=
"ot"> id=
</span><span class=
"st">"plugin_zone_start_picwall
"</span><span class=
"ot"> class=
</span><span class=
"st">"plugin_zone
"</span><span class=
"kw">></span>
582 {loop=
"$plugin_start_zone
"}
585 <span class=
"kw"></div
></span></code></pre></div>
587 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html"><span class=
"kw"><div
</span><span class=
"ot"> id=
</span><span class=
"st">"plugin_zone_end_picwall
"</span><span class=
"ot"> class=
</span><span class=
"st">"plugin_zone
"</span><span class=
"kw">></span>
588 {loop=
"$plugin_end_zone
"}
591 <span class=
"kw"></div
></span></code></pre></div>
592 <p><strong>tagcloud.html
</strong></p>
594 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html"> <span class=
"kw"><div
</span><span class=
"ot"> id=
</span><span class=
"st">"plugin_zone_start_tagcloud
"</span><span class=
"ot"> class=
</span><span class=
"st">"plugin_zone
"</span><span class=
"kw">></span>
595 {loop=
"$plugin_start_zone
"}
598 <span class=
"kw"></div
></span></code></pre></div>
600 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html"> <span class=
"kw"><div
</span><span class=
"ot"> id=
</span><span class=
"st">"plugin_zone_end_tagcloud
"</span><span class=
"ot"> class=
</span><span class=
"st">"plugin_zone
"</span><span class=
"kw">></span>
601 {loop=
"$plugin_end_zone
"}
604 <span class=
"kw"></div
></span></code></pre></div>
605 <p><strong>daily.html
</strong></p>
607 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html"><span class=
"kw"><div
</span><span class=
"ot"> id=
</span><span class=
"st">"plugin_zone_start_picwall
"</span><span class=
"ot"> class=
</span><span class=
"st">"plugin_zone
"</span><span class=
"kw">></span>
608 {loop=
"$plugin_start_zone
"}
611 <span class=
"kw"></div
></span></code></pre></div>
612 <p>After every link:
</p>
613 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html"><span class=
"kw"><div
</span><span class=
"ot"> class=
</span><span class=
"st">"dailyEntryFooter
"</span><span class=
"kw">></span>
614 {loop=
"$link.link_plugin
"}
617 <span class=
"kw"></div
></span></code></pre></div>
619 <div class=
"sourceCode"><pre class=
"sourceCode html"><code class=
"sourceCode html"><span class=
"kw"><div
</span><span class=
"ot"> id=
</span><span class=
"st">"plugin_zone_end_picwall
"</span><span class=
"ot"> class=
</span><span class=
"st">"plugin_zone
"</span><span class=
"kw">></span>
620 {loop=
"$plugin_end_zone
"}
623 <span class=
"kw"></div
></span></code></pre></div>
624 <p><strong>feed.atom.xml
</strong> and
<strong>feed.rss.xml
</strong>:
</p>
625 <p>In headers tags section:
</p>
626 <div class=
"sourceCode"><pre class=
"sourceCode xml"><code class=
"sourceCode xml">{loop=
"$feed_plugins_header
"}
628 {/loop}
</code></pre></div>
629 <p>After each entry:
</p>
630 <div class=
"sourceCode"><pre class=
"sourceCode xml"><code class=
"sourceCode xml">{loop=
"$value.feed_plugins
"}
632 {/loop}
</code></pre></div>