]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - doc/md/Plugin-System.md
Default colors plugin - Documentation
[github/shaarli/Shaarli.git] / doc / md / Plugin-System.md
CommitLineData
43ad7c8e 1[**I am a developer: ** Developer API](#developer-api)
992af0b9 2
43ad7c8e
V
3[**I am a template designer: ** Guide for template designers](#guide-for-template-designer)
4
5---
992af0b9 6
5409ade2 7## Developer API
992af0b9
V
8
9### What can I do with plugins?
10
11The plugin system let you:
12
43ad7c8e
V
13- insert content into specific places across templates.
14- alter data before templates rendering.
15- alter data before saving new links.
992af0b9
V
16
17### How can I create a plugin for Shaarli?
18
19First, chose a plugin name, such as `demo_plugin`.
20
21Under `plugin` folder, create a folder named with your plugin name. Then create a <plugin_name>.php file in that folder.
22
23You should have the following tree view:
24
25```
26| index.php
27| plugins/
28|---| demo_plugin/
29| |---| demo_plugin.php
30```
31
b230bf20
A
32### Plugin initialization
33
34At the beginning of Shaarli execution, all enabled plugins are loaded. At this point, the plugin system looks for an `init()` function to execute and run it if it exists. This function must be named this way, and takes the `ConfigManager` as parameter.
35
36 <plugin_name>_init($conf)
37
38This function can be used to create initial data, load default settings, etc. But also to set *plugin errors*. If the initialization function returns an array of strings, they will be understand as errors, and displayed in the header to logged in users.
39
992af0b9
V
40### Understanding hooks
41
42A plugin is a set of functions. Each function will be triggered by the plugin system at certain point in Shaarli execution.
43
44These functions need to be named with this pattern:
45
46```
b230bf20 47hook_<plugin_name>_<hook_name>($data, $conf)
992af0b9
V
48```
49
b230bf20
A
50Parameters:
51
cc8f572b 52- data: see [$data section](https://shaarli.readthedocs.io/en/master/Plugin-System/#plugins-data)
43ad7c8e 53- conf: the `ConfigManager` instance.
b230bf20 54
cc8f572b 55For example, if my plugin want to add data to the header, this function is needed:
992af0b9 56
b230bf20 57 hook_demo_plugin_render_header
992af0b9
V
58
59If this function is declared, and the plugin enabled, it will be called every time Shaarli is rendering the header.
60
61### Plugin's data
62
63#### Parameters
64
65Every hook function has a `$data` parameter. Its content differs for each hooks.
66
67**This parameter needs to be returned every time**, otherwise data is lost.
68
69 return $data;
70
71#### Filling templates placeholder
72
73Template placeholders are displayed in template in specific places.
74
75RainTPL displays every element contained in the placeholder's array. These element can be added by plugins.
76
77For example, let's add a value in the placeholder `top_placeholder` which is displayed at the top of my page:
78
79```php
53ed6d7d 80$data['top_placeholder'][] = 'My content';
992af0b9 81# OR
53ed6d7d 82array_push($data['top_placeholder'], 'My', 'content');
992af0b9
V
83
84return $data;
85```
86
87#### Data manipulation
88
89When a page is displayed, every variable send to the template engine is passed to plugins before that in `$data`.
90
91The data contained by this array can be altered before template rendering.
92
93For exemple, in linklist, it is possible to alter every title:
94
95```php
96// mind the reference if you want $data to be altered
53ed6d7d 97foreach ($data['links'] as &$value) {
992af0b9 98 // String reverse every title.
53ed6d7d 99 $value['title'] = strrev($value['title']);
992af0b9
V
100}
101
102return $data;
103```
104
5409ade2
A
105### Metadata
106
107Every plugin needs a `<plugin_name>.meta` file, which is in fact an `.ini` file (`KEY="VALUE"`), to be listed in plugin administration.
108
109Each file contain two keys:
110
43ad7c8e
V
111- `description`: plugin description
112- `parameters`: user parameter names, separated by a `;`.
113- `parameter.<PARAMETER_NAME>`: add a text description the specified parameter.
5409ade2
A
114
115> Note: In PHP, `parse_ini_file()` seems to want strings to be between by quotes `"` in the ini file.
116
992af0b9
V
117### It's not working!
118
119Use `demo_plugin` as a functional example. It covers most of the plugin system features.
120
53ed6d7d 121If it's still not working, please [open an issue](https://github.com/shaarli/Shaarli/issues/new).
992af0b9
V
122
123### Hooks
124
125| Hooks | Description |
126| ------------- |:-------------:|
53ed6d7d 127| [render_header](#render_header) | Allow plugin to add content in page headers. |
128| [render_includes](#render_includes) | Allow plugin to include their own CSS files. |
129| [render_footer](#render_footer) | Allow plugin to add content in page footer and include their own JS files. |
130| [render_linklist](#render_linklist) | It allows to add content at the begining and end of the page, after every link displayed and to alter link data. |
131| [render_editlink](#render_editlink) | Allow to add fields in the form, or display elements. |
132| [render_tools](#render_tools) | Allow to add content at the end of the page. |
133| [render_picwall](#render_picwall) | Allow to add content at the top and bottom of the page. |
134| [render_tagcloud](#render_tagcloud) | Allow to add content at the top and bottom of the page, and after all tags. |
135| [render_taglist](#render_taglist) | Allow to add content at the top and bottom of the page, and after all tags. |
136| [render_daily](#render_daily) | Allow to add content at the top and bottom of the page, the bottom of each link and to alter data. |
137| [render_feed](#render_feed) | Allow to do add tags in RSS and ATOM feeds. |
138| [save_link](#save_link) | Allow to alter the link being saved in the datastore. |
139| [delete_link](#delete_link) | Allow to do an action before a link is deleted from the datastore. |
a8fb97a0 140| [save_plugin_parameters](#save_plugin_parameters) | Allow to manipulate plugin parameters before they're saved. |
b230bf20 141
992af0b9
V
142
143
144#### render_header
145
146Triggered on every page.
147
148Allow plugin to add content in page headers.
149
150##### Data
151
152`$data` is an array containing:
153
43ad7c8e
V
154- `_PAGE_`: current target page (eg: `linklist`, `picwall`, etc.).
155- `_LOGGEDIN_`: true if user is logged in, false otherwise.
992af0b9
V
156
157##### Template placeholders
158
53ed6d7d 159Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
992af0b9
V
160
161List of placeholders:
162
43ad7c8e 163- `buttons_toolbar`: after the list of buttons in the header.
992af0b9 164
53ed6d7d 165![buttons_toolbar_example](http://i.imgur.com/ssJUOrt.png)
992af0b9 166
43ad7c8e 167- `fields_toolbar`: after search fields in the header.
992af0b9
V
168
169> Note: This will only be called in linklist.
170
53ed6d7d 171![fields_toolbar_example](http://i.imgur.com/3GMifI2.png)
992af0b9
V
172
173#### render_includes
174
175Triggered on every page.
176
177Allow plugin to include their own CSS files.
178
179##### Data
180
181`$data` is an array containing:
182
43ad7c8e
V
183- `_PAGE_`: current target page (eg: `linklist`, `picwall`, etc.).
184- `_LOGGEDIN_`: true if user is logged in, false otherwise.
992af0b9
V
185
186##### Template placeholders
187
53ed6d7d 188Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
992af0b9
V
189
190List of placeholders:
191
43ad7c8e 192- `css_files`: called after loading default CSS.
992af0b9
V
193
194> Note: only add the path of the CSS file. E.g: `plugins/demo_plugin/custom_demo.css`.
195
196#### render_footer
197
198Triggered on every page.
199
200Allow plugin to add content in page footer and include their own JS files.
201
202##### Data
203
204`$data` is an array containing:
205
43ad7c8e
V
206- `_PAGE_`: current target page (eg: `linklist`, `picwall`, etc.).
207- `_LOGGEDIN_`: true if user is logged in, false otherwise.
992af0b9
V
208
209##### Template placeholders
210
53ed6d7d 211Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
992af0b9
V
212
213List of placeholders:
214
43ad7c8e
V
215- `text`: called after the end of the footer text.
216- `endofpage`: called at the end of the page.
992af0b9 217
53ed6d7d 218![text_example](http://i.imgur.com/L5S2YEH.png)
992af0b9 219
43ad7c8e 220- `js_files`: called at the end of the page, to include custom JS scripts.
992af0b9
V
221
222> Note: only add the path of the JS file. E.g: `plugins/demo_plugin/custom_demo.js`.
223
224#### render_linklist
225
226Triggered when `linklist` is displayed (list of links, permalink, search, tag filtered, etc.).
227
228It allows to add content at the begining and end of the page, after every link displayed and to alter link data.
229
230##### Data
231
232`$data` is an array containing:
233
43ad7c8e
V
234- `_LOGGEDIN_`: true if user is logged in, false otherwise.
235- All templates data, including links.
992af0b9
V
236
237##### Template placeholders
238
53ed6d7d 239Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
992af0b9
V
240
241List of placeholders:
242
43ad7c8e 243- `action_plugin`: next to the button "private only" at the top and bottom of the page.
992af0b9 244
53ed6d7d 245![action_plugin_example](http://i.imgur.com/Q12PWg0.png)
992af0b9 246
43ad7c8e 247- `link_plugin`: for every link, between permalink and link URL.
992af0b9 248
53ed6d7d 249![link_plugin_example](http://i.imgur.com/3oDPhWx.png)
992af0b9 250
43ad7c8e 251- `plugin_start_zone`: before displaying the template content.
992af0b9 252
53ed6d7d 253![plugin_start_zone_example](http://i.imgur.com/OVBkGy3.png)
992af0b9 254
43ad7c8e 255- `plugin_end_zone`: after displaying the template content.
992af0b9 256
53ed6d7d 257![plugin_end_zone_example](http://i.imgur.com/6IoRuop.png)
992af0b9
V
258
259#### render_editlink
260
261Triggered when the link edition form is displayed.
262
263Allow to add fields in the form, or display elements.
264
265##### Data
266
267`$data` is an array containing:
268
43ad7c8e 269- All templates data.
992af0b9
V
270
271##### Template placeholders
272
53ed6d7d 273Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
992af0b9
V
274
275List of placeholders:
276
43ad7c8e 277- `edit_link_plugin`: after tags field.
992af0b9 278
53ed6d7d 279![edit_link_plugin_example](http://i.imgur.com/5u17Ens.png)
992af0b9
V
280
281#### render_tools
282
283Triggered when the "tools" page is displayed.
284
285Allow to add content at the end of the page.
286
287##### Data
288
289`$data` is an array containing:
290
43ad7c8e 291- All templates data.
992af0b9
V
292
293##### Template placeholders
294
53ed6d7d 295Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
992af0b9
V
296
297List of placeholders:
298
43ad7c8e 299- `tools_plugin`: at the end of the page.
992af0b9 300
53ed6d7d 301![tools_plugin_example](http://i.imgur.com/Bqhu9oQ.png)
992af0b9
V
302
303#### render_picwall
304
305Triggered when picwall is displayed.
306
307Allow to add content at the top and bottom of the page.
308
309##### Data
310
311`$data` is an array containing:
312
43ad7c8e
V
313- `_LOGGEDIN_`: true if user is logged in, false otherwise.
314- All templates data.
992af0b9
V
315
316##### Template placeholders
317
53ed6d7d 318Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
992af0b9
V
319
320List of placeholders:
321
43ad7c8e
V
322- `plugin_start_zone`: before displaying the template content.
323- `plugin_end_zone`: after displaying the template content.
992af0b9 324
53ed6d7d 325![plugin_start_end_zone_example](http://i.imgur.com/tVTQFER.png)
992af0b9
V
326
327#### render_tagcloud
328
329Triggered when tagcloud is displayed.
330
331Allow to add content at the top and bottom of the page.
332
333##### Data
334
335`$data` is an array containing:
336
43ad7c8e
V
337- `_LOGGEDIN_`: true if user is logged in, false otherwise.
338- All templates data.
992af0b9
V
339
340##### Template placeholders
341
53ed6d7d 342Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
992af0b9
V
343
344List of placeholders:
345
43ad7c8e
V
346- `plugin_start_zone`: before displaying the template content.
347- `plugin_end_zone`: after displaying the template content.
992af0b9 348
b230bf20
A
349For each tag, the following placeholder can be used:
350
43ad7c8e 351- `tag_plugin`: after each tag
b230bf20 352
53ed6d7d 353![plugin_start_end_zone_example](http://i.imgur.com/vHmyT3a.png)
992af0b9 354
b230bf20
A
355
356#### render_taglist
357
358Triggered when taglist is displayed.
359
360Allow to add content at the top and bottom of the page.
361
362##### Data
363
364`$data` is an array containing:
365
43ad7c8e
V
366- `_LOGGEDIN_`: true if user is logged in, false otherwise.
367- All templates data.
b230bf20
A
368
369##### Template placeholders
370
53ed6d7d 371Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
b230bf20
A
372
373List of placeholders:
374
43ad7c8e
V
375- `plugin_start_zone`: before displaying the template content.
376- `plugin_end_zone`: after displaying the template content.
b230bf20
A
377
378For each tag, the following placeholder can be used:
379
43ad7c8e 380- `tag_plugin`: after each tag
b230bf20 381
992af0b9
V
382#### render_daily
383
384Triggered when tagcloud is displayed.
385
386Allow to add content at the top and bottom of the page, the bottom of each link and to alter data.
387
388##### Data
389
390`$data` is an array containing:
391
43ad7c8e
V
392- `_LOGGEDIN_`: true if user is logged in, false otherwise.
393- All templates data, including links.
992af0b9
V
394
395##### Template placeholders
396
53ed6d7d 397Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
992af0b9
V
398
399List of placeholders:
400
43ad7c8e 401- `link_plugin`: used at bottom of each link.
992af0b9 402
53ed6d7d 403![link_plugin_example](http://i.imgur.com/hzhMfSZ.png)
992af0b9 404
43ad7c8e
V
405- `plugin_start_zone`: before displaying the template content.
406- `plugin_end_zone`: after displaying the template content.
992af0b9 407
b230bf20
A
408#### render_feed
409
410Triggered when the ATOM or RSS feed is displayed.
411
412Allow to add tags in the feed, either in the header or for each items. Items (links) can also be altered before being rendered.
413
414##### Data
415
416`$data` is an array containing:
417
43ad7c8e
V
418- `_LOGGEDIN_`: true if user is logged in, false otherwise.
419- `_PAGE_`: containing either `rss` or `atom`.
420- All templates data, including links.
b230bf20
A
421
422##### Template placeholders
423
53ed6d7d 424Tags can be added in feeds by adding an entry in `$data['<placeholder>']` array.
b230bf20
A
425
426List of placeholders:
427
43ad7c8e 428- `feed_plugins_header`: used as a header tag in the feed.
b230bf20
A
429
430For each links:
431
43ad7c8e 432- `feed_plugins`: additional tag for every link entry.
b230bf20
A
433
434#### save_link
992af0b9
V
435
436Triggered when a link is save (new link or edit).
437
438Allow to alter the link being saved in the datastore.
439
440##### Data
441
442`$data` is an array containing the link being saved:
443
43ad7c8e
V
444- id
445- title
446- url
447- shorturl
448- description
449- private
450- tags
451- created
452- updated
b230bf20
A
453
454
455#### delete_link
456
457Triggered when a link is deleted.
458
459Allow to execute any action before the link is actually removed from the datastore
460
461##### Data
462
463`$data` is an array containing the link being saved:
464
43ad7c8e
V
465- id
466- title
467- url
468- shorturl
469- description
470- private
471- tags
472- created
473- updated
992af0b9 474
a8fb97a0
A
475
476#### save_plugin_parameters
477
478Triggered when the plugin parameters are saved from the plugin administration page.
479
480Plugins can perform an action every times their settings are updated.
481For example it is used to update the CSS file of the `default_colors` plugins.
482
483##### Data
484
485`$data` input contains the `$_POST` array.
486
487So if the plugin has a parameter called `MYPLUGIN_PARAMETER`,
488the array will contain an entry with `MYPLUGIN_PARAMETER` as a key.
489
490
992af0b9
V
491## Guide for template designer
492
5409ade2
A
493### Plugin administration
494
495Your theme must include a plugin administration page: `pluginsadmin.html`.
496
497> Note: repo's template link needs to be added when the PR is merged.
498
499Use the default one as an example.
500
501Aside from classic RainTPL loops, plugins order is handle by JavaScript. You can just include `plugin_admin.js`, only if:
502
43ad7c8e
V
503- you're using a table.
504- you call orderUp() and orderUp() onclick on arrows.
505- you add data-line and data-order to your rows.
5409ade2
A
506
507Otherwise, you can use your own JS as long as this field is send by the form:
508
509<input type="hidden" name="order_{$key}" value="{$counter}">
510
992af0b9
V
511### Placeholder system
512
513In order to make plugins work with every custom themes, you need to add variable placeholder in your templates.
514
515It's a RainTPL loop like this:
516
517 {loop="$plugin_variable"}
518 {$value}
519 {/loop}
520
521You should enable `demo_plugin` for testing purpose, since it uses every placeholder available.
522
523### List of placeholders
524
525**page.header.html**
526
527At the end of the menu:
528
529 {loop="$plugins_header.buttons_toolbar"}
530 {$value}
531 {/loop}
532
5409ade2
A
533At the end of file, before clearing floating blocks:
534
535 {if="!empty($plugin_errors) && isLoggedIn()"}
536 <ul class="errors">
537 {loop="plugin_errors"}
538 <li>{$value}</li>
539 {/loop}
540 </ul>
541 {/if}
542
992af0b9
V
543**includes.html**
544
545At the end of the file:
546
547```html
548{loop="$plugins_includes.css_files"}
549<link type="text/css" rel="stylesheet" href="{$value}#"/>
550{/loop}
551```
552
553**page.footer.html**
554
555At the end of your footer notes:
556
557```html
558{loop="$plugins_footer.text"}
559 {$value}
560{/loop}
561```
562
563At the end of file:
564
565```html
566{loop="$plugins_footer.js_files"}
567 <script src="{$value}#"></script>
568{/loop}
569```
570
571**linklist.html**
572
573After search fields:
574
575```html
576{loop="$plugins_header.fields_toolbar"}
577 {$value}
578{/loop}
579```
580
581Before displaying the link list (after paging):
582
583```html
584{loop="$plugin_start_zone"}
585 {$value}
586{/loop}
587```
588
589For every links (icons):
590
591```html
592{loop="$value.link_plugin"}
593 <span>{$value}</span>
594{/loop}
595```
596
597Before end paging:
598
599```html
600{loop="$plugin_end_zone"}
601 {$value}
602{/loop}
603```
604
605**linklist.paging.html**
606
607After the "private only" icon:
608
609```html
610{loop="$action_plugin"}
611 {$value}
612{/loop}
613```
614
615**editlink.html**
616
617After tags field:
618
619```html
620{loop="$edit_link_plugin"}
621 {$value}
622{/loop}
623```
624
625**tools.html**
626
627After the last tool:
628
629```html
630{loop="$tools_plugin"}
631 {$value}
632{/loop}
633```
634
635**picwall.html**
636
637Top:
638
639```html
640<div id="plugin_zone_start_picwall" class="plugin_zone">
641 {loop="$plugin_start_zone"}
642 {$value}
643 {/loop}
644</div>
645```
646
647Bottom:
648
649```html
650<div id="plugin_zone_end_picwall" class="plugin_zone">
651 {loop="$plugin_end_zone"}
652 {$value}
653 {/loop}
654</div>
655```
656
657**tagcloud.html**
658
659Top:
660
661```html
662 <div id="plugin_zone_start_tagcloud" class="plugin_zone">
663 {loop="$plugin_start_zone"}
664 {$value}
665 {/loop}
666 </div>
667```
668
669Bottom:
670
671```html
672 <div id="plugin_zone_end_tagcloud" class="plugin_zone">
673 {loop="$plugin_end_zone"}
674 {$value}
675 {/loop}
676 </div>
677```
678
679**daily.html**
680
681Top:
682
683```html
684<div id="plugin_zone_start_picwall" class="plugin_zone">
685 {loop="$plugin_start_zone"}
686 {$value}
687 {/loop}
688</div>
689```
690
691After every link:
692
693```html
694<div class="dailyEntryFooter">
695 {loop="$link.link_plugin"}
696 {$value}
697 {/loop}
698</div>
699```
700
701Bottom:
702
703```html
704<div id="plugin_zone_end_picwall" class="plugin_zone">
705 {loop="$plugin_end_zone"}
706 {$value}
707 {/loop}
708</div>
709```
b230bf20
A
710
711**feed.atom.xml** and **feed.rss.xml**:
712
713In headers tags section:
714```xml
715{loop="$feed_plugins_header"}
716 {$value}
717{/loop}
718```
719
720After each entry:
721```xml
722{loop="$value.feed_plugins"}
723 {$value}
724{/loop}
725```