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