#Plugin System
-> Note: Plugin current status - in developpement (not merged into master).
-
-[**I am a user.** Plugin User Guide.](#plugin-user-guide)[](.html)
-
-[**I am a developper.** Developper API.](#developper-api)[](.html)
+[**I am a developer.** Developer API.](#developer-api)[](.html)
[**I am a template designer.** Guide for template designer.](#guide-for-template-designer)[](.html)
-## Plugin User Guide
-
-### Manage plugins
-
-In `config.php`, change $GLOBALS['config'['ENABLED_PLUGINS'] array:]('ENABLED_PLUGINS']-array:.html)
-
-```php
-$GLOBALS['config'['ENABLED_PLUGINS']]('ENABLED_PLUGINS'].html)
-```
-
-Full list:
-
-```php
-$GLOBALS['config'['ENABLED_PLUGINS'] = array(]('ENABLED_PLUGINS']-=-array(.html)
- 'qrcode', 'archiveorg', 'readityourself', 'playvideos',
- 'wallabag', 'markdown', 'addlink_toolbar',
-);
-```
-
-### List of plugins
-
-Plugin maintained by the community:
-
- * Archive.org - add a clickable icon to every link to archive.org.
- * Addlink in toolbar - add a field to paste new links URL in toolbar.
- * Markdown - write and display Shaare in Markdown.
- * Play videos - popup to play all videos displayed in linklist.
- * QRCode - add a clickable icon generating a QRCode for every link.
- * ReadItYourself - add a clickable icon for ReadItYourself.
- * Wallabag - add a clickable icon for Wallabag.
-
-## Developper API
+## Developer API
### What can I do with plugins?
| |---| demo_plugin.php
```
+### Plugin initialization
+
+At 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.
+
+ <plugin_name>_init($conf)
+
+This 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.
+
### Understanding hooks
A plugin is a set of functions. Each function will be triggered by the plugin system at certain point in Shaarli execution.
These functions need to be named with this pattern:
```
-hook_<plugin_name>_<hook_name>
+hook_<plugin_name>_<hook_name>($data, $conf)
```
+Parameters:
+
+ - data: see [$data section](https://github.com/shaarli/Shaarli/wiki/Plugin-System#plugins-data)[](.html)
+ - conf: the `ConfigManager` instance.
+
For exemple, if my plugin want to add data to the header, this function is needed:
- hook_demo_plugin_render_header()
+ hook_demo_plugin_render_header
If this function is declared, and the plugin enabled, it will be called every time Shaarli is rendering the header.
return $data;
```
+### Metadata
+
+Every plugin needs a `<plugin_name>.meta` file, which is in fact an `.ini` file (`KEY="VALUE"`), to be listed in plugin administration.
+
+Each file contain two keys:
+
+ * `description`: plugin description
+ * `parameters`: user parameter names, separated by a `;`.
+ * `parameter.<PARAMETER_NAME>`: add a text description the specified parameter.
+
+> Note: In PHP, `parse_ini_file()` seems to want strings to be between by quotes `"` in the ini file.
+
### It's not working!
Use `demo_plugin` as a functional example. It covers most of the plugin system features.
| [render_editlink](#render_editlink) | Allow to add fields in the form, or display elements. |[](.html)
| [render_tools](#render_tools) | Allow to add content at the end of the page. |[](.html)
| [render_picwall](#render_picwall) | Allow to add content at the top and bottom of the page. |[](.html)
-| [render_tagcloud](#render_tagcloud) | Allow to add content at the top and bottom of the page. |[](.html)
+| [render_tagcloud](#render_tagcloud) | Allow to add content at the top and bottom of the page, and after all tags. |[](.html)
+| [render_taglist](#render_taglist) | Allow to add content at the top and bottom of the page, and after all tags. |[](.html)
| [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. |[](.html)
-| [savelink](#savelink) | Allow to alter the link being saved in the datastore. |[](.html)
+| [render_feed](#render_feed) | Allow to do add tags in RSS and ATOM feeds. |[](.html)
+| [save_link](#save_link) | Allow to alter the link being saved in the datastore. |[](.html)
+| [delete_link](#delete_link) | Allow to do an action before a link is deleted from the datastore. |[](.html)
+
#### render_header
List of placeholders:
* `text`: called after the end of the footer text.
+ * `endofpage`: called at the end of the page.
![text_example](http://i.imgur.com/L5S2YEH.png)[](.html)
* `plugin_end_zone`: after displaying the template content.
+For each tag, the following placeholder can be used:
+
+ * `tag_plugin`: after each tag
+
![plugin_start_end_zone_example](http://i.imgur.com/vHmyT3a.png)[](.html)
+
+#### render_taglist
+
+Triggered when taglist is displayed.
+
+Allow to add content at the top and bottom of the page.
+
+##### Data
+
+`$data` is an array containing:
+
+ * `_LOGGEDIN_`: true if user is logged in, false otherwise.
+ * All templates data.
+
+##### Template placeholders
+
+Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.[](.html)
+
+List of placeholders:
+
+ * `plugin_start_zone`: before displaying the template content.
+
+ * `plugin_end_zone`: after displaying the template content.
+
+For each tag, the following placeholder can be used:
+
+ * `tag_plugin`: after each tag
+
#### render_daily
Triggered when tagcloud is displayed.
* `plugin_end_zone`: after displaying the template content.
-#### savelink
+#### render_feed
+
+Triggered when the ATOM or RSS feed is displayed.
+
+Allow to add tags in the feed, either in the header or for each items. Items (links) can also be altered before being rendered.
+
+##### Data
+
+`$data` is an array containing:
+
+ * `_LOGGEDIN_`: true if user is logged in, false otherwise.
+ * `_PAGE_`: containing either `rss` or `atom`.
+ * All templates data, including links.
+
+##### Template placeholders
+
+Tags can be added in feeds by adding an entry in `$data['<placeholder>']` array.[](.html)
+
+List of placeholders:
+
+ * `feed_plugins_header`: used as a header tag in the feed.
+
+For each links:
+
+ * `feed_plugins`: additional tag for every link entry.
+
+#### save_link
Triggered when a link is save (new link or edit).
`$data` is an array containing the link being saved:
+ * id
* title
* url
+ * shorturl
* description
- * linkdate
* private
* tags
+ * created
+ * updated
+
+
+#### delete_link
+
+Triggered when a link is deleted.
+
+Allow to execute any action before the link is actually removed from the datastore
+
+##### Data
+
+`$data` is an array containing the link being saved:
+
+ * id
+ * title
+ * url
+ * shorturl
+ * description
+ * private
+ * tags
+ * created
+ * updated
## Guide for template designer
+### Plugin administration
+
+Your theme must include a plugin administration page: `pluginsadmin.html`.
+
+> Note: repo's template link needs to be added when the PR is merged.
+
+Use the default one as an example.
+
+Aside from classic RainTPL loops, plugins order is handle by JavaScript. You can just include `plugin_admin.js`, only if:
+
+ * you're using a table.
+ * you call orderUp() and orderUp() onclick on arrows.
+ * you add data-line and data-order to your rows.
+
+Otherwise, you can use your own JS as long as this field is send by the form:
+
+<input type="hidden" name="order_{$key}" value="{$counter}">
+
### Placeholder system
In order to make plugins work with every custom themes, you need to add variable placeholder in your templates.
{$value}
{/loop}
+At the end of file, before clearing floating blocks:
+
+ {if="!empty($plugin_errors) && isLoggedIn()"}
+ <ul class="errors">
+ {loop="plugin_errors"}
+ <li>{$value}</li>
+ {/loop}
+ </ul>
+ {/if}
+
**includes.html**
At the end of the file:
{/loop}
</div>
```
+
+**feed.atom.xml** and **feed.rss.xml**:
+
+In headers tags section:
+```xml
+{loop="$feed_plugins_header"}
+ {$value}
+{/loop}
+```
+
+After each entry:
+```xml
+{loop="$value.feed_plugins"}
+ {$value}
+{/loop}
+```