2017-01-26 18:52:54 +01:00
<!DOCTYPE html>
<!-- [if IE 8]><html class="no - js lt - ie9" lang="en" > <![endif] -->
<!-- [if gt IE 8]><! --> < html class = "no-js" lang = "en" > <!-- <![endif] -->
< head >
< meta charset = "utf-8" >
< meta http-equiv = "X-UA-Compatible" content = "IE=edge" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< link rel = "shortcut icon" href = "../img/favicon.ico" >
< title > Plugin System - Shaarli Documentation< / title >
< link href = 'https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel = 'stylesheet' type = 'text/css' >
< link rel = "stylesheet" href = "../css/theme.css" type = "text/css" / >
< link rel = "stylesheet" href = "../css/theme_extra.css" type = "text/css" / >
< link rel = "stylesheet" href = "../css/highlight.css" >
< link href = "../github-markdown.css" rel = "stylesheet" >
< script >
// Current page data
var mkdocs_page_name = "Plugin System";
var mkdocs_page_input_path = "Plugin-System.md";
var mkdocs_page_url = "/Plugin-System/";
< / script >
< script src = "../js/jquery-2.1.1.min.js" > < / script >
< script src = "../js/modernizr-2.8.3.min.js" > < / script >
< script type = "text/javascript" src = "../js/highlight.pack.js" > < / script >
< / head >
< body class = "wy-body-for-nav" role = "document" >
< div class = "wy-grid-for-nav" >
< nav data-toggle = "wy-nav-shift" class = "wy-nav-side stickynav" >
< div class = "wy-side-nav-search" >
< a href = ".." class = "icon icon-home" > Shaarli Documentation< / a >
< div role = "search" >
< form id = "rtd-search-form" class = "wy-form" action = "../search.html" method = "get" >
< input type = "text" name = "q" placeholder = "Search docs" / >
< / form >
< / div >
< / div >
< div class = "wy-menu wy-menu-vertical" data-spy = "affix" role = "navigation" aria-label = "main navigation" >
< ul class = "current" >
< li class = "toctree-l1" >
< a class = "" href = ".." > Home< / a >
< / li >
< li class = "toctree-l1" >
< span class = "caption-text" > Setup< / span >
< ul class = "subnav" >
< li class = "" >
< a class = "" href = "../Download-and-Installation/" > Download and Installation< / a >
< / li >
< li class = "" >
< a class = "" href = "../Upgrade-and-migration/" > Upgrade and migration< / a >
< / li >
< li class = "" >
< a class = "" href = "../Server-requirements/" > Server requirements< / a >
< / li >
< li class = "" >
< a class = "" href = "../Server-configuration/" > Server configuration< / a >
< / li >
< li class = "" >
< a class = "" href = "../Server-security/" > Server security< / a >
< / li >
< li class = "" >
< a class = "" href = "../Shaarli-configuration/" > Shaarli configuration< / a >
< / li >
< li class = "" >
< a class = "" href = "../Plugins/" > Plugins< / a >
< / li >
< / ul >
< / li >
< li class = "toctree-l1" >
< span class = "caption-text" > Docker< / span >
< ul class = "subnav" >
< li class = "" >
2017-07-29 15:29:54 +02:00
< a class = "" href = "../docker/docker-101/" > Docker 101< / a >
2017-01-26 18:52:54 +01:00
< / li >
< li class = "" >
2017-07-29 15:29:54 +02:00
< a class = "" href = "../docker/shaarli-images/" > Shaarli images< / a >
2017-01-26 18:52:54 +01:00
< / li >
< li class = "" >
2017-07-29 15:29:54 +02:00
< a class = "" href = "../docker/reverse-proxy-configuration/" > Reverse proxy configuration< / a >
2017-01-26 18:52:54 +01:00
< / li >
< li class = "" >
2017-07-29 15:29:54 +02:00
< a class = "" href = "../docker/resources/" > Docker resources< / a >
2017-01-26 18:52:54 +01:00
< / li >
< / ul >
< / li >
< li class = "toctree-l1" >
< span class = "caption-text" > Usage< / span >
< ul class = "subnav" >
< li class = "" >
< a class = "" href = "../Features/" > Features< / a >
< / li >
< li class = "" >
< a class = "" href = "../Bookmarklet/" > Bookmarklet< / a >
< / li >
< li class = "" >
< a class = "" href = "../Browsing-and-searching/" > Browsing and searching< / a >
< / li >
< li class = "" >
< a class = "" href = "../Firefox-share/" > Firefox share< / a >
< / li >
< li class = "" >
< a class = "" href = "../RSS-feeds/" > RSS feeds< / a >
< / li >
< li class = "" >
< a class = "" href = "../REST-API/" > REST API< / a >
< / li >
< / ul >
< / li >
< li class = "toctree-l1" >
< span class = "caption-text" > How To< / span >
< ul class = "subnav" >
< li class = "" >
< a class = "" href = "../Backup,-restore,-import-and-export/" > Backup, restore, import and export< / a >
< / li >
< li class = "" >
2017-06-18 06:32:30 +02:00
< a class = "" href = "../Various-hacks/" > Various hacks< / a >
2017-01-26 18:52:54 +01:00
< / li >
< / ul >
< / li >
< li class = "toctree-l1" >
< a class = "" href = "../Troubleshooting/" > Troubleshooting< / a >
< / li >
< li class = "toctree-l1" >
< span class = "caption-text" > Development< / span >
< ul class = "subnav" >
< li class = "" >
< a class = "" href = "../Development-guidelines/" > Development guidelines< / a >
< / li >
< li class = "" >
< a class = "" href = "../Continuous-integration-tools/" > Continuous integration tools< / a >
< / li >
< li class = "" >
< a class = "" href = "../GnuPG-signature/" > GnuPG signature< / a >
< / li >
< li class = "" >
< a class = "" href = "../Coding-guidelines/" > Coding guidelines< / a >
< / li >
< li class = "" >
< a class = "" href = "../Directory-structure/" > Directory structure< / a >
< / li >
< li class = "" >
< a class = "" href = "../3rd-party-libraries/" > 3rd party libraries< / a >
< / li >
< li class = " current" >
< a class = "current" href = "./" > Plugin System< / a >
< ul class = "subnav" >
< li class = "toctree-l3" > < a href = "#developer-api" > Developer API< / a > < / li >
< ul >
< li > < a class = "toctree-l4" href = "#what-can-i-do-with-plugins" > What can I do with plugins?< / a > < / li >
< li > < a class = "toctree-l4" href = "#how-can-i-create-a-plugin-for-shaarli" > How can I create a plugin for Shaarli?< / a > < / li >
< li > < a class = "toctree-l4" href = "#plugin-initialization" > Plugin initialization< / a > < / li >
< li > < a class = "toctree-l4" href = "#understanding-hooks" > Understanding hooks< / a > < / li >
< li > < a class = "toctree-l4" href = "#plugins-data" > Plugin's data< / a > < / li >
< li > < a class = "toctree-l4" href = "#metadata" > Metadata< / a > < / li >
< li > < a class = "toctree-l4" href = "#its-not-working" > It's not working!< / a > < / li >
< li > < a class = "toctree-l4" href = "#hooks" > Hooks< / a > < / li >
< / ul >
< li class = "toctree-l3" > < a href = "#guide-for-template-designer" > Guide for template designer< / a > < / li >
< ul >
< li > < a class = "toctree-l4" href = "#plugin-administration" > Plugin administration< / a > < / li >
< li > < a class = "toctree-l4" href = "#placeholder-system" > Placeholder system< / a > < / li >
< li > < a class = "toctree-l4" href = "#list-of-placeholders" > List of placeholders< / a > < / li >
< / ul >
< / ul >
< / li >
< li class = "" >
< a class = "" href = "../Release-Shaarli/" > Release Shaarli< / a >
< / li >
< li class = "" >
< a class = "" href = "../Versioning-and-Branches/" > Versioning and Branches< / a >
< / li >
< li class = "" >
< a class = "" href = "../Security/" > Security< / a >
< / li >
< li class = "" >
< a class = "" href = "../Static-analysis/" > Static analysis< / a >
< / li >
< li class = "" >
< a class = "" href = "../Theming/" > Theming< / a >
< / li >
< li class = "" >
< a class = "" href = "../Unit-tests/" > Unit tests< / a >
< / li >
< / ul >
< / li >
< li class = "toctree-l1" >
< span class = "caption-text" > About< / span >
< ul class = "subnav" >
< li class = "" >
< a class = "" href = "../FAQ/" > FAQ< / a >
< / li >
< li class = "" >
< a class = "" href = "../Community-&-Related-software/" > Community & Related software< / a >
< / li >
< / ul >
< / li >
< / ul >
< / div >
< / nav >
< section data-toggle = "wy-nav-shift" class = "wy-nav-content-wrap" >
< nav class = "wy-nav-top" role = "navigation" aria-label = "top navigation" >
< i data-toggle = "wy-nav-top" class = "fa fa-bars" > < / i >
< a href = ".." > Shaarli Documentation< / a >
< / nav >
< div class = "wy-nav-content" >
< div class = "rst-content" >
< div role = "navigation" aria-label = "breadcrumbs navigation" >
< ul class = "wy-breadcrumbs" >
< li > < a href = ".." > Docs< / a > » < / li >
< li > Development » < / li >
< li > Plugin System< / li >
< li class = "wy-breadcrumbs-aside" >
< a href = "https://github.com/shaarli/Shaarli/edit/master/docs/Plugin-System.md"
class="icon icon-github"> Edit on GitHub< / a >
< / li >
< / ul >
< hr / >
< / div >
< div role = "main" >
< div class = "section" >
< p > < a href = "#developer-api" > < strong > I am a developer.< / strong > Developer API.< / a > < / p >
< p > < a href = "#guide-for-template-designer" > < strong > I am a template designer.< / strong > Guide for template designer.< / a > < / p >
< h2 id = "developer-api" > Developer API< / h2 >
< h3 id = "what-can-i-do-with-plugins" > What can I do with plugins?< / h3 >
< p > The plugin system let you:< / p >
< ul >
< li > insert content into specific places across templates.< / li >
< li > alter data before templates rendering.< / li >
< li > alter data before saving new links.< / li >
< / ul >
< h3 id = "how-can-i-create-a-plugin-for-shaarli" > How can I create a plugin for Shaarli?< / h3 >
< p > First, chose a plugin name, such as < code > demo_plugin< / code > .< / p >
< 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 >
< p > You should have the following tree view:< / p >
< pre > < code > | index.php
| plugins/
|---| demo_plugin/
| |---| demo_plugin.php
< / code > < / pre >
< h3 id = "plugin-initialization" > Plugin initialization< / h3 >
< 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 >
< pre > < code > < plugin_name> _init($conf)
< / code > < / pre >
< 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 >
< h3 id = "understanding-hooks" > Understanding hooks< / h3 >
< p > A plugin is a set of functions. Each function will be triggered by the plugin system at certain point in Shaarli execution.< / p >
< p > These functions need to be named with this pattern:< / p >
< pre > < code > hook_< plugin_name> _< hook_name> ($data, $conf)
< / code > < / pre >
< p > Parameters:< / p >
< ul >
< li > data: see < a href = "https://github.com/shaarli/Shaarli/wiki/Plugin-System#plugins-data" > $data section< / a > < / li >
< li > conf: the < code > ConfigManager< / code > instance.< / li >
< / ul >
< p > For exemple, if my plugin want to add data to the header, this function is needed:< / p >
< pre > < code > hook_demo_plugin_render_header
< / code > < / pre >
< p > If this function is declared, and the plugin enabled, it will be called every time Shaarli is rendering the header.< / p >
< h3 id = "plugins-data" > Plugin's data< / h3 >
< h4 id = "parameters" > Parameters< / h4 >
< p > Every hook function has a < code > $data< / code > parameter. Its content differs for each hooks.< / p >
< p > < strong > This parameter needs to be returned every time< / strong > , otherwise data is lost.< / p >
< pre > < code > return $data;
< / code > < / pre >
< h4 id = "filling-templates-placeholder" > Filling templates placeholder< / h4 >
< p > Template placeholders are displayed in template in specific places.< / p >
< p > RainTPL displays every element contained in the placeholder's array. These element can be added by plugins.< / p >
< 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 >
< pre > < code class = "php" > $data['top_placeholder'][] = 'My content';
# OR
array_push($data['top_placeholder'], 'My', 'content');
return $data;
< / code > < / pre >
< h4 id = "data-manipulation" > Data manipulation< / h4 >
< p > When a page is displayed, every variable send to the template engine is passed to plugins before that in < code > $data< / code > .< / p >
< p > The data contained by this array can be altered before template rendering.< / p >
< p > For exemple, in linklist, it is possible to alter every title:< / p >
< pre > < code class = "php" > // mind the reference if you want $data to be altered
foreach ($data['links'] as & $value) {
// String reverse every title.
$value['title'] = strrev($value['title']);
}
return $data;
< / code > < / pre >
< h3 id = "metadata" > Metadata< / h3 >
< 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 >
< p > Each file contain two keys:< / p >
< ul >
< li > < code > description< / code > : plugin description< / li >
< li > < code > parameters< / code > : user parameter names, separated by a < code > ;< / code > .< / li >
< li > < code > parameter.< PARAMETER_NAME> < / code > : add a text description the specified parameter.< / li >
< / ul >
< blockquote >
< 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 >
< / blockquote >
< h3 id = "its-not-working" > It's not working!< / h3 >
< p > Use < code > demo_plugin< / code > as a functional example. It covers most of the plugin system features.< / p >
< p > If it's still not working, please < a href = "https://github.com/shaarli/Shaarli/issues/new" > open an issue< / a > .< / p >
< h3 id = "hooks" > Hooks< / h3 >
< table >
< thead >
< tr >
< th > Hooks< / th >
< th align = "center" > Description< / th >
< / tr >
< / thead >
< tbody >
< tr >
< td > < a href = "#render_header" > render_header< / a > < / td >
< td align = "center" > Allow plugin to add content in page headers.< / td >
< / tr >
< tr >
< td > < a href = "#render_includes" > render_includes< / a > < / td >
< td align = "center" > Allow plugin to include their own CSS files.< / td >
< / tr >
< tr >
< td > < a href = "#render_footer" > render_footer< / a > < / td >
< td align = "center" > Allow plugin to add content in page footer and include their own JS files.< / td >
< / tr >
< tr >
< td > < a href = "#render_linklist" > render_linklist< / a > < / td >
< 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 >
< / tr >
< tr >
< td > < a href = "#render_editlink" > render_editlink< / a > < / td >
< td align = "center" > Allow to add fields in the form, or display elements.< / td >
< / tr >
< tr >
< td > < a href = "#render_tools" > render_tools< / a > < / td >
< td align = "center" > Allow to add content at the end of the page.< / td >
< / tr >
< tr >
< td > < a href = "#render_picwall" > render_picwall< / a > < / td >
< td align = "center" > Allow to add content at the top and bottom of the page.< / td >
< / tr >
< tr >
< td > < a href = "#render_tagcloud" > render_tagcloud< / a > < / td >
< td align = "center" > Allow to add content at the top and bottom of the page, and after all tags.< / td >
< / tr >
< tr >
< td > < a href = "#render_taglist" > render_taglist< / a > < / td >
< td align = "center" > Allow to add content at the top and bottom of the page, and after all tags.< / td >
< / tr >
< tr >
< td > < a href = "#render_daily" > render_daily< / a > < / td >
< 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 >
< / tr >
< tr >
< td > < a href = "#render_feed" > render_feed< / a > < / td >
< td align = "center" > Allow to do add tags in RSS and ATOM feeds.< / td >
< / tr >
< tr >
< td > < a href = "#save_link" > save_link< / a > < / td >
< td align = "center" > Allow to alter the link being saved in the datastore.< / td >
< / tr >
< tr >
< td > < a href = "#delete_link" > delete_link< / a > < / td >
< td align = "center" > Allow to do an action before a link is deleted from the datastore.< / td >
< / tr >
< / tbody >
< / table >
< h4 id = "render_header" > render_header< / h4 >
< p > Triggered on every page.< / p >
< p > Allow plugin to add content in page headers.< / p >
< h5 id = "data" > Data< / h5 >
< p > < code > $data< / code > is an array containing:< / p >
< ul >
< li > < code > _PAGE_< / code > : current target page (eg: < code > linklist< / code > , < code > picwall< / code > , etc.).< / li >
< li > < code > _LOGGEDIN_< / code > : true if user is logged in, false otherwise.< / li >
< / ul >
< h5 id = "template-placeholders" > Template placeholders< / h5 >
< p > Items can be displayed in templates by adding an entry in < code > $data['< placeholder> ']< / code > array.< / p >
< p > List of placeholders:< / p >
< ul >
< li > < code > buttons_toolbar< / code > : after the list of buttons in the header.< / li >
< / ul >
< p > < img alt = "buttons_toolbar_example" src = "http://i.imgur.com/ssJUOrt.png" / > < / p >
< ul >
< li > < code > fields_toolbar< / code > : after search fields in the header.< / li >
< / ul >
< blockquote >
< p > Note: This will only be called in linklist.< / p >
< / blockquote >
< p > < img alt = "fields_toolbar_example" src = "http://i.imgur.com/3GMifI2.png" / > < / p >
< h4 id = "render_includes" > render_includes< / h4 >
< p > Triggered on every page.< / p >
< p > Allow plugin to include their own CSS files.< / p >
< h5 id = "data_1" > Data< / h5 >
< p > < code > $data< / code > is an array containing:< / p >
< ul >
< li > < code > _PAGE_< / code > : current target page (eg: < code > linklist< / code > , < code > picwall< / code > , etc.).< / li >
< li > < code > _LOGGEDIN_< / code > : true if user is logged in, false otherwise.< / li >
< / ul >
< h5 id = "template-placeholders_1" > Template placeholders< / h5 >
< p > Items can be displayed in templates by adding an entry in < code > $data['< placeholder> ']< / code > array.< / p >
< p > List of placeholders:< / p >
< ul >
< li > < code > css_files< / code > : called after loading default CSS.< / li >
< / ul >
< blockquote >
< p > Note: only add the path of the CSS file. E.g: < code > plugins/demo_plugin/custom_demo.css< / code > .< / p >
< / blockquote >
< h4 id = "render_footer" > render_footer< / h4 >
< p > Triggered on every page.< / p >
< p > Allow plugin to add content in page footer and include their own JS files.< / p >
< h5 id = "data_2" > Data< / h5 >
< p > < code > $data< / code > is an array containing:< / p >
< ul >
< li > < code > _PAGE_< / code > : current target page (eg: < code > linklist< / code > , < code > picwall< / code > , etc.).< / li >
< li > < code > _LOGGEDIN_< / code > : true if user is logged in, false otherwise.< / li >
< / ul >
< h5 id = "template-placeholders_2" > Template placeholders< / h5 >
< p > Items can be displayed in templates by adding an entry in < code > $data['< placeholder> ']< / code > array.< / p >
< p > List of placeholders:< / p >
< ul >
< li > < code > text< / code > : called after the end of the footer text.< / li >
< li > < code > endofpage< / code > : called at the end of the page.< / li >
< / ul >
< p > < img alt = "text_example" src = "http://i.imgur.com/L5S2YEH.png" / > < / p >
< ul >
< li > < code > js_files< / code > : called at the end of the page, to include custom JS scripts.< / li >
< / ul >
< blockquote >
< p > Note: only add the path of the JS file. E.g: < code > plugins/demo_plugin/custom_demo.js< / code > .< / p >
< / blockquote >
< h4 id = "render_linklist" > render_linklist< / h4 >
< p > Triggered when < code > linklist< / code > is displayed (list of links, permalink, search, tag filtered, etc.).< / p >
< p > It allows to add content at the begining and end of the page, after every link displayed and to alter link data.< / p >
< h5 id = "data_3" > Data< / h5 >
< p > < code > $data< / code > is an array containing:< / p >
< ul >
< li > < code > _LOGGEDIN_< / code > : true if user is logged in, false otherwise.< / li >
< li > All templates data, including links.< / li >
< / ul >
< h5 id = "template-placeholders_3" > Template placeholders< / h5 >
< p > Items can be displayed in templates by adding an entry in < code > $data['< placeholder> ']< / code > array.< / p >
< p > List of placeholders:< / p >
< ul >
< li > < code > action_plugin< / code > : next to the button "private only" at the top and bottom of the page.< / li >
< / ul >
< p > < img alt = "action_plugin_example" src = "http://i.imgur.com/Q12PWg0.png" / > < / p >
< ul >
< li > < code > link_plugin< / code > : for every link, between permalink and link URL.< / li >
< / ul >
< p > < img alt = "link_plugin_example" src = "http://i.imgur.com/3oDPhWx.png" / > < / p >
< ul >
< li > < code > plugin_start_zone< / code > : before displaying the template content.< / li >
< / ul >
< p > < img alt = "plugin_start_zone_example" src = "http://i.imgur.com/OVBkGy3.png" / > < / p >
< ul >
< li > < code > plugin_end_zone< / code > : after displaying the template content.< / li >
< / ul >
< p > < img alt = "plugin_end_zone_example" src = "http://i.imgur.com/6IoRuop.png" / > < / p >
< h4 id = "render_editlink" > render_editlink< / h4 >
< p > Triggered when the link edition form is displayed.< / p >
< p > Allow to add fields in the form, or display elements.< / p >
< h5 id = "data_4" > Data< / h5 >
< p > < code > $data< / code > is an array containing:< / p >
< ul >
< li > All templates data.< / li >
< / ul >
< h5 id = "template-placeholders_4" > Template placeholders< / h5 >
< p > Items can be displayed in templates by adding an entry in < code > $data['< placeholder> ']< / code > array.< / p >
< p > List of placeholders:< / p >
< ul >
< li > < code > edit_link_plugin< / code > : after tags field.< / li >
< / ul >
< p > < img alt = "edit_link_plugin_example" src = "http://i.imgur.com/5u17Ens.png" / > < / p >
< h4 id = "render_tools" > render_tools< / h4 >
< p > Triggered when the "tools" page is displayed.< / p >
< p > Allow to add content at the end of the page.< / p >
< h5 id = "data_5" > Data< / h5 >
< p > < code > $data< / code > is an array containing:< / p >
< ul >
< li > All templates data.< / li >
< / ul >
< h5 id = "template-placeholders_5" > Template placeholders< / h5 >
< p > Items can be displayed in templates by adding an entry in < code > $data['< placeholder> ']< / code > array.< / p >
< p > List of placeholders:< / p >
< ul >
< li > < code > tools_plugin< / code > : at the end of the page.< / li >
< / ul >
< p > < img alt = "tools_plugin_example" src = "http://i.imgur.com/Bqhu9oQ.png" / > < / p >
< h4 id = "render_picwall" > render_picwall< / h4 >
< p > Triggered when picwall is displayed.< / p >
< p > Allow to add content at the top and bottom of the page.< / p >
< h5 id = "data_6" > Data< / h5 >
< p > < code > $data< / code > is an array containing:< / p >
< ul >
< li > < code > _LOGGEDIN_< / code > : true if user is logged in, false otherwise.< / li >
< li > All templates data.< / li >
< / ul >
< h5 id = "template-placeholders_6" > Template placeholders< / h5 >
< p > Items can be displayed in templates by adding an entry in < code > $data['< placeholder> ']< / code > array.< / p >
< p > List of placeholders:< / p >
< ul >
< li >
< p > < code > plugin_start_zone< / code > : before displaying the template content.< / p >
< / li >
< li >
< p > < code > plugin_end_zone< / code > : after displaying the template content.< / p >
< / li >
< / ul >
< p > < img alt = "plugin_start_end_zone_example" src = "http://i.imgur.com/tVTQFER.png" / > < / p >
< h4 id = "render_tagcloud" > render_tagcloud< / h4 >
< p > Triggered when tagcloud is displayed.< / p >
< p > Allow to add content at the top and bottom of the page.< / p >
< h5 id = "data_7" > Data< / h5 >
< p > < code > $data< / code > is an array containing:< / p >
< ul >
< li > < code > _LOGGEDIN_< / code > : true if user is logged in, false otherwise.< / li >
< li > All templates data.< / li >
< / ul >
< h5 id = "template-placeholders_7" > Template placeholders< / h5 >
< p > Items can be displayed in templates by adding an entry in < code > $data['< placeholder> ']< / code > array.< / p >
< p > List of placeholders:< / p >
< ul >
< li >
< p > < code > plugin_start_zone< / code > : before displaying the template content.< / p >
< / li >
< li >
< p > < code > plugin_end_zone< / code > : after displaying the template content.< / p >
< / li >
< / ul >
< p > For each tag, the following placeholder can be used:< / p >
< ul >
< li > < code > tag_plugin< / code > : after each tag< / li >
< / ul >
< p > < img alt = "plugin_start_end_zone_example" src = "http://i.imgur.com/vHmyT3a.png" / > < / p >
< h4 id = "render_taglist" > render_taglist< / h4 >
< p > Triggered when taglist is displayed.< / p >
< p > Allow to add content at the top and bottom of the page.< / p >
< h5 id = "data_8" > Data< / h5 >
< p > < code > $data< / code > is an array containing:< / p >
< ul >
< li > < code > _LOGGEDIN_< / code > : true if user is logged in, false otherwise.< / li >
< li > All templates data.< / li >
< / ul >
< h5 id = "template-placeholders_8" > Template placeholders< / h5 >
< p > Items can be displayed in templates by adding an entry in < code > $data['< placeholder> ']< / code > array.< / p >
< p > List of placeholders:< / p >
< ul >
< li >
< p > < code > plugin_start_zone< / code > : before displaying the template content.< / p >
< / li >
< li >
< p > < code > plugin_end_zone< / code > : after displaying the template content.< / p >
< / li >
< / ul >
< p > For each tag, the following placeholder can be used:< / p >
< ul >
< li > < code > tag_plugin< / code > : after each tag< / li >
< / ul >
< h4 id = "render_daily" > render_daily< / h4 >
< p > Triggered when tagcloud is displayed.< / p >
< p > Allow to add content at the top and bottom of the page, the bottom of each link and to alter data.< / p >
< h5 id = "data_9" > Data< / h5 >
< p > < code > $data< / code > is an array containing:< / p >
< ul >
< li > < code > _LOGGEDIN_< / code > : true if user is logged in, false otherwise.< / li >
< li > All templates data, including links.< / li >
< / ul >
< h5 id = "template-placeholders_9" > Template placeholders< / h5 >
< p > Items can be displayed in templates by adding an entry in < code > $data['< placeholder> ']< / code > array.< / p >
< p > List of placeholders:< / p >
< ul >
< li > < code > link_plugin< / code > : used at bottom of each link.< / li >
< / ul >
< p > < img alt = "link_plugin_example" src = "http://i.imgur.com/hzhMfSZ.png" / > < / p >
< ul >
< li >
< p > < code > plugin_start_zone< / code > : before displaying the template content.< / p >
< / li >
< li >
< p > < code > plugin_end_zone< / code > : after displaying the template content.< / p >
< / li >
< / ul >
< h4 id = "render_feed" > render_feed< / h4 >
< p > Triggered when the ATOM or RSS feed is displayed.< / p >
< 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 >
< h5 id = "data_10" > Data< / h5 >
< p > < code > $data< / code > is an array containing:< / p >
< ul >
< li > < code > _LOGGEDIN_< / code > : true if user is logged in, false otherwise.< / li >
< li > < code > _PAGE_< / code > : containing either < code > rss< / code > or < code > atom< / code > .< / li >
< li > All templates data, including links.< / li >
< / ul >
< h5 id = "template-placeholders_10" > Template placeholders< / h5 >
< p > Tags can be added in feeds by adding an entry in < code > $data['< placeholder> ']< / code > array.< / p >
< p > List of placeholders:< / p >
< ul >
< li > < code > feed_plugins_header< / code > : used as a header tag in the feed.< / li >
< / ul >
< p > For each links:< / p >
< ul >
< li > < code > feed_plugins< / code > : additional tag for every link entry.< / li >
< / ul >
< h4 id = "save_link" > save_link< / h4 >
< p > Triggered when a link is save (new link or edit).< / p >
< p > Allow to alter the link being saved in the datastore.< / p >
< h5 id = "data_11" > Data< / h5 >
< p > < code > $data< / code > is an array containing the link being saved:< / p >
< ul >
< li > id< / li >
< li > title< / li >
< li > url< / li >
< li > shorturl< / li >
< li > description< / li >
< li > private< / li >
< li > tags< / li >
< li > created< / li >
< li > updated< / li >
< / ul >
< h4 id = "delete_link" > delete_link< / h4 >
< p > Triggered when a link is deleted.< / p >
< p > Allow to execute any action before the link is actually removed from the datastore< / p >
< h5 id = "data_12" > Data< / h5 >
< p > < code > $data< / code > is an array containing the link being saved:< / p >
< ul >
< li > id< / li >
< li > title< / li >
< li > url< / li >
< li > shorturl< / li >
< li > description< / li >
< li > private< / li >
< li > tags< / li >
< li > created< / li >
< li > updated< / li >
< / ul >
< h2 id = "guide-for-template-designer" > Guide for template designer< / h2 >
< h3 id = "plugin-administration" > Plugin administration< / h3 >
< p > Your theme must include a plugin administration page: < code > pluginsadmin.html< / code > .< / p >
< blockquote >
< p > Note: repo's template link needs to be added when the PR is merged.< / p >
< / blockquote >
< p > Use the default one as an example.< / p >
< p > Aside from classic RainTPL loops, plugins order is handle by JavaScript. You can just include < code > plugin_admin.js< / code > , only if:< / p >
< ul >
< li > you're using a table.< / li >
< li > you call orderUp() and orderUp() onclick on arrows.< / li >
< li > you add data-line and data-order to your rows.< / li >
< / ul >
< p > Otherwise, you can use your own JS as long as this field is send by the form:< / p >
< p > < input type = "hidden" name = "order_{$key}" value = "{$counter}" > < / p >
< h3 id = "placeholder-system" > Placeholder system< / h3 >
< p > In order to make plugins work with every custom themes, you need to add variable placeholder in your templates. < / p >
< p > It's a RainTPL loop like this:< / p >
< pre > < code > {loop="$plugin_variable"}
{$value}
{/loop}
< / code > < / pre >
< p > You should enable < code > demo_plugin< / code > for testing purpose, since it uses every placeholder available.< / p >
< h3 id = "list-of-placeholders" > List of placeholders< / h3 >
< p > < strong > page.header.html< / strong > < / p >
< p > At the end of the menu:< / p >
< pre > < code > {loop="$plugins_header.buttons_toolbar"}
{$value}
{/loop}
< / code > < / pre >
< p > At the end of file, before clearing floating blocks:< / p >
< pre > < code > {if="!empty($plugin_errors) & & isLoggedIn()"}
< ul class="errors">
{loop="plugin_errors"}
< li> {$value}< /li>
{/loop}
< /ul>
{/if}
< / code > < / pre >
< p > < strong > includes.html< / strong > < / p >
< p > At the end of the file:< / p >
< pre > < code class = "html" > {loop=" $plugins_includes.css_files" }
< link type=" text/css" rel=" stylesheet" href=" {$value}#" />
{/loop}
< / code > < / pre >
< p > < strong > page.footer.html< / strong > < / p >
< p > At the end of your footer notes:< / p >
< pre > < code class = "html" > {loop=" $plugins_footer.text" }
{$value}
{/loop}
< / code > < / pre >
< p > At the end of file:< / p >
< pre > < code class = "html" > {loop=" $plugins_footer.js_files" }
< script src=" {$value}#" > < /script>
{/loop}
< / code > < / pre >
< p > < strong > linklist.html< / strong > < / p >
< p > After search fields:< / p >
< pre > < code class = "html" > {loop=" $plugins_header.fields_toolbar" }
{$value}
{/loop}
< / code > < / pre >
< p > Before displaying the link list (after paging):< / p >
< pre > < code class = "html" > {loop=" $plugin_start_zone" }
{$value}
{/loop}
< / code > < / pre >
< p > For every links (icons):< / p >
< pre > < code class = "html" > {loop=" $value.link_plugin" }
< span> {$value}< /span>
{/loop}
< / code > < / pre >
< p > Before end paging:< / p >
< pre > < code class = "html" > {loop=" $plugin_end_zone" }
{$value}
{/loop}
< / code > < / pre >
< p > < strong > linklist.paging.html< / strong > < / p >
< p > After the "private only" icon:< / p >
< pre > < code class = "html" > {loop=" $action_plugin" }
{$value}
{/loop}
< / code > < / pre >
< p > < strong > editlink.html< / strong > < / p >
< p > After tags field:< / p >
< pre > < code class = "html" > {loop=" $edit_link_plugin" }
{$value}
{/loop}
< / code > < / pre >
< p > < strong > tools.html< / strong > < / p >
< p > After the last tool:< / p >
< pre > < code class = "html" > {loop=" $tools_plugin" }
{$value}
{/loop}
< / code > < / pre >
< p > < strong > picwall.html< / strong > < / p >
< p > Top:< / p >
< pre > < code class = "html" > < div id=" plugin_zone_start_picwall" class=" plugin_zone" >
{loop=" $plugin_start_zone" }
{$value}
{/loop}
< /div>
< / code > < / pre >
< p > Bottom:< / p >
< pre > < code class = "html" > < div id=" plugin_zone_end_picwall" class=" plugin_zone" >
{loop=" $plugin_end_zone" }
{$value}
{/loop}
< /div>
< / code > < / pre >
< p > < strong > tagcloud.html< / strong > < / p >
< p > Top:< / p >
< pre > < code class = "html" > < div id=" plugin_zone_start_tagcloud" class=" plugin_zone" >
{loop=" $plugin_start_zone" }
{$value}
{/loop}
< /div>
< / code > < / pre >
< p > Bottom:< / p >
< pre > < code class = "html" > < div id=" plugin_zone_end_tagcloud" class=" plugin_zone" >
{loop=" $plugin_end_zone" }
{$value}
{/loop}
< /div>
< / code > < / pre >
< p > < strong > daily.html< / strong > < / p >
< p > Top:< / p >
< pre > < code class = "html" > < div id=" plugin_zone_start_picwall" class=" plugin_zone" >
{loop=" $plugin_start_zone" }
{$value}
{/loop}
< /div>
< / code > < / pre >
< p > After every link:< / p >
< pre > < code class = "html" > < div class=" dailyEntryFooter" >
{loop=" $link.link_plugin" }
{$value}
{/loop}
< /div>
< / code > < / pre >
< p > Bottom:< / p >
< pre > < code class = "html" > < div id=" plugin_zone_end_picwall" class=" plugin_zone" >
{loop=" $plugin_end_zone" }
{$value}
{/loop}
< /div>
< / code > < / pre >
< p > < strong > feed.atom.xml< / strong > and < strong > feed.rss.xml< / strong > :< / p >
< p > In headers tags section:< / p >
< pre > < code class = "xml" > {loop=" $feed_plugins_header" }
{$value}
{/loop}
< / code > < / pre >
< p > After each entry:< / p >
< pre > < code class = "xml" > {loop=" $value.feed_plugins" }
{$value}
{/loop}
< / code > < / pre >
< / div >
< / div >
< footer >
< div class = "rst-footer-buttons" role = "navigation" aria-label = "footer navigation" >
< a href = "../Release-Shaarli/" class = "btn btn-neutral float-right" title = "Release Shaarli" > Next < span class = "icon icon-circle-arrow-right" > < / span > < / a >
< a href = "../3rd-party-libraries/" class = "btn btn-neutral" title = "3rd party libraries" > < span class = "icon icon-circle-arrow-left" > < / span > Previous< / a >
< / div >
< hr / >
< div role = "contentinfo" >
<!-- Copyright etc -->
< / div >
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 > .
< / footer >
< / div >
< / div >
< / section >
< / div >
< div class = "rst-versions" role = "note" style = "cursor: pointer" >
< span class = "rst-current-version" data-toggle = "rst-current-version" >
< a href = "https://github.com/shaarli/Shaarli" class = "fa fa-github" style = "float: left; color: #fcfcfc" > GitHub< / a >
< span > < a href = "../3rd-party-libraries/" style = "color: #fcfcfc;" > « Previous< / a > < / span >
< span style = "margin-left: 15px" > < a href = "../Release-Shaarli/" style = "color: #fcfcfc" > Next » < / a > < / span >
< / span >
< / div >
< script src = "../js/theme.js" > < / script >
< / body >
< / html >