aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2016-10-12 13:58:35 +0200
committerArthurHoaro <arthur@hoa.ro>2016-10-12 13:58:35 +0200
commitbc22c9a0acb095970e9494cbe8954f0612e05dc0 (patch)
tree4e3a94b7469f5b2e3eaf946756235730429bf9d4
parent890afc32f744859d11b97eb26ed5c030af9b4145 (diff)
parentebd67c6e1b40aebdd3a52285ce9ff9412b2a3038 (diff)
downloadShaarli-bc22c9a0acb095970e9494cbe8954f0612e05dc0.tar.gz
Shaarli-bc22c9a0acb095970e9494cbe8954f0612e05dc0.tar.zst
Shaarli-bc22c9a0acb095970e9494cbe8954f0612e05dc0.zip
Merge tag 'v0.7.0' of github.com:shaarli/Shaarli into stable
Release v0.7.0
-rw-r--r--README.md3
-rw-r--r--application/FeedBuilder.php279
-rw-r--r--application/HttpUtils.php62
-rw-r--r--application/LinkDB.php99
-rw-r--r--application/LinkFilter.php16
-rw-r--r--application/LinkUtils.php22
-rw-r--r--application/NetscapeBookmarkUtils.php54
-rw-r--r--application/PageBuilder.php145
-rw-r--r--application/Router.php40
-rw-r--r--application/TimeZone.php4
-rw-r--r--application/Updater.php2
-rw-r--r--application/Url.php74
-rw-r--r--application/Utils.php32
-rw-r--r--composer.json2
-rw-r--r--doc/3rd-party-libraries.html14
-rw-r--r--doc/Backup,-restore,-import-and-export.html62
-rw-r--r--doc/Browsing-and-searching.html83
-rw-r--r--doc/Browsing-and-searching.md28
-rw-r--r--doc/Coding-guidelines.html14
-rw-r--r--doc/Community-&-Related-software.html25
-rw-r--r--doc/Community-&-Related-software.md14
-rw-r--r--doc/Copy-an-existing-installation-over-SSH-and-serve-it-locally.html66
-rw-r--r--doc/Create-and-serve-multiple-Shaarlis-(farm).html159
-rw-r--r--doc/Create-and-serve-multiple-Shaarlis-(farm).md58
-rw-r--r--doc/Datastore-hacks.html66
-rw-r--r--doc/Datastore-hacks.md7
-rw-r--r--doc/Development.html16
-rw-r--r--doc/Directory-structure.html62
-rw-r--r--doc/Docker.html244
-rw-r--r--doc/Docker.md157
-rw-r--r--doc/Download-CSS-styles-from-an-OPML-list.html62
-rw-r--r--doc/Download.html70
-rw-r--r--doc/Example-patch---add-new-via-field-for-links.html14
-rw-r--r--doc/FAQ.html14
-rw-r--r--doc/Firefox-share.html29
-rw-r--r--doc/GnuPG-signature.html142
-rw-r--r--doc/GnuPG-signature.md70
-rw-r--r--doc/Home.html16
-rw-r--r--doc/Home.md2
-rw-r--r--doc/Plugin-System.html222
-rw-r--r--doc/Plugin-System.md79
-rw-r--r--doc/Plugins.html156
-rw-r--r--doc/Plugins.md77
-rw-r--r--doc/RSS-feeds.html28
-rw-r--r--doc/RSS-feeds.md12
-rw-r--r--doc/Release-Shaarli.html170
-rw-r--r--doc/Release-Shaarli.md72
-rw-r--r--doc/Security.html62
-rw-r--r--doc/Server-configuration.html99
-rw-r--r--doc/Server-configuration.md28
-rw-r--r--doc/Server-requirements.html67
-rw-r--r--doc/Server-requirements.md11
-rw-r--r--doc/Server-security.html165
-rw-r--r--doc/Server-security.md60
-rw-r--r--doc/Shaarli-configuration.html83
-rw-r--r--doc/Shaarli-configuration.md24
-rw-r--r--doc/Shaarli-installation.html72
-rw-r--r--doc/Shaarli-installation.md6
-rw-r--r--doc/Sharing-button.html22
-rw-r--r--doc/Sharing-button.md12
-rw-r--r--doc/Static-analysis.html14
-rw-r--r--doc/TODO.html14
-rw-r--r--doc/Theming.html72
-rw-r--r--doc/Troubleshooting.html69
-rw-r--r--doc/Unit-tests.html80
-rw-r--r--doc/Upgrade-from-original-sebsauvage-Shaarli.html74
-rw-r--r--doc/Upgrade-from-original-sebsauvage-Shaarli.md4
-rw-r--r--doc/Usage.html14
-rw-r--r--doc/_Footer.html17
-rw-r--r--doc/_Sidebar.html22
-rw-r--r--doc/_Sidebar.md8
-rw-r--r--doc/images/doc-logo.svg522
-rw-r--r--doc/sidebar.html8
-rw-r--r--inc/awesomplete-multiple-tags.js4
-rw-r--r--index.php665
-rw-r--r--plugins/demo_plugin/demo_plugin.php27
-rw-r--r--plugins/markdown/README.md34
-rw-r--r--plugins/markdown/markdown.css7
-rw-r--r--plugins/markdown/markdown.php49
-rw-r--r--shaarli_version.php2
-rw-r--r--tests/FeedBuilderTest.php212
-rw-r--r--tests/HttpUtils/GetHttpUrlTest.php27
-rw-r--r--tests/LinkDBTest.php63
-rw-r--r--tests/LinkFilterTest.php17
-rw-r--r--tests/LinkUtilsTest.php11
-rw-r--r--tests/NetscapeBookmarkUtilsTest.php134
-rw-r--r--tests/TimeZoneTest.php2
-rw-r--r--tests/Updater/UpdaterTest.php4
-rw-r--r--tests/Url/UrlTest.php22
-rw-r--r--tests/plugins/PluginMarkdownTest.php37
-rw-r--r--tests/utils/ReferenceLinkDB.php20
-rw-r--r--tpl/configure.html7
-rw-r--r--tpl/export.bookmarks.html10
-rw-r--r--tpl/export.html32
-rw-r--r--tpl/feed.atom.html40
-rw-r--r--tpl/feed.rss.html34
-rw-r--r--tpl/loginform.html46
-rw-r--r--tpl/page.footer.html4
-rw-r--r--tpl/page.header.html3
-rw-r--r--tpl/tagcloud.html4
100 files changed, 5032 insertions, 1258 deletions
diff --git a/README.md b/README.md
index a693e47a..d67c10ac 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
1![Shaarli logo](doc/images/doc-logo.png) 1![Shaarli logo](doc/images/doc-logo.png)
2 2
3The personal, minimalist, super-fast, no-database delicious clone. 3The personal, minimalist, super-fast, database free, bookmarking service.
4 4
5_Do you want to share the links you discover?_ 5_Do you want to share the links you discover?_
6_Shaarli is a minimalist delicious clone that you can install on your own server._ 6_Shaarli is a minimalist delicious clone that you can install on your own server._
@@ -43,6 +43,7 @@ Login: `demo`; Password: `demo`
43 - daily RSS feed 43 - daily RSS feed
44- permalinks for easy reference 44- permalinks for easy reference
45- links can be public or private 45- links can be public or private
46- extensible through [plugins](https://github.com/shaarli/Shaarli/wiki/Plugins#plugin-usage)
46 47
47### Tag, view and search your links! 48### Tag, view and search your links!
48- add a custom title and description to archived links 49- add a custom title and description to archived links
diff --git a/application/FeedBuilder.php b/application/FeedBuilder.php
new file mode 100644
index 00000000..ddefe6ce
--- /dev/null
+++ b/application/FeedBuilder.php
@@ -0,0 +1,279 @@
1<?php
2
3/**
4 * FeedBuilder class.
5 *
6 * Used to build ATOM and RSS feeds data.
7 */
8class FeedBuilder
9{
10 /**
11 * @var string Constant: RSS feed type.
12 */
13 public static $FEED_RSS = 'rss';
14
15 /**
16 * @var string Constant: ATOM feed type.
17 */
18 public static $FEED_ATOM = 'atom';
19
20 /**
21 * @var string Default language if the locale isn't set.
22 */
23 public static $DEFAULT_LANGUAGE = 'en-en';
24
25 /**
26 * @var int Number of links to display in a feed by default.
27 */
28 public static $DEFAULT_NB_LINKS = 50;
29
30 /**
31 * @var LinkDB instance.
32 */
33 protected $linkDB;
34
35 /**
36 * @var string RSS or ATOM feed.
37 */
38 protected $feedType;
39
40 /**
41 * @var array $_SERVER.
42 */
43 protected $serverInfo;
44
45 /**
46 * @var array $_GET.
47 */
48 protected $userInput;
49
50 /**
51 * @var boolean True if the user is currently logged in, false otherwise.
52 */
53 protected $isLoggedIn;
54
55 /**
56 * @var boolean Use permalinks instead of direct links if true.
57 */
58 protected $usePermalinks;
59
60 /**
61 * @var boolean true to hide dates in feeds.
62 */
63 protected $hideDates;
64
65 /**
66 * @var string PubSub hub URL.
67 */
68 protected $pubsubhubUrl;
69
70 /**
71 * @var string server locale.
72 */
73 protected $locale;
74
75 /**
76 * @var DateTime Latest item date.
77 */
78 protected $latestDate;
79
80 /**
81 * Feed constructor.
82 *
83 * @param LinkDB $linkDB LinkDB instance.
84 * @param string $feedType Type of feed.
85 * @param array $serverInfo $_SERVER.
86 * @param array $userInput $_GET.
87 * @param boolean $isLoggedIn True if the user is currently logged in, false otherwise.
88 */
89 public function __construct($linkDB, $feedType, $serverInfo, $userInput, $isLoggedIn)
90 {
91 $this->linkDB = $linkDB;
92 $this->feedType = $feedType;
93 $this->serverInfo = $serverInfo;
94 $this->userInput = $userInput;
95 $this->isLoggedIn = $isLoggedIn;
96 }
97
98 /**
99 * Build data for feed templates.
100 *
101 * @return array Formatted data for feeds templates.
102 */
103 public function buildData()
104 {
105 // Optionally filter the results:
106 $linksToDisplay = $this->linkDB->filterSearch($this->userInput);
107
108 $nblinksToDisplay = $this->getNbLinks(count($linksToDisplay));
109
110 // Can't use array_keys() because $link is a LinkDB instance and not a real array.
111 $keys = array();
112 foreach ($linksToDisplay as $key => $value) {
113 $keys[] = $key;
114 }
115
116 $pageaddr = escape(index_url($this->serverInfo));
117 $linkDisplayed = array();
118 for ($i = 0; $i < $nblinksToDisplay && $i < count($keys); $i++) {
119 $linkDisplayed[$keys[$i]] = $this->buildItem($linksToDisplay[$keys[$i]], $pageaddr);
120 }
121
122 $data['language'] = $this->getTypeLanguage();
123 $data['pubsubhub_url'] = $this->pubsubhubUrl;
124 $data['last_update'] = $this->getLatestDateFormatted();
125 $data['show_dates'] = !$this->hideDates || $this->isLoggedIn;
126 // Remove leading slash from REQUEST_URI.
127 $data['self_link'] = $pageaddr . escape(ltrim($this->serverInfo['REQUEST_URI'], '/'));
128 $data['index_url'] = $pageaddr;
129 $data['usepermalinks'] = $this->usePermalinks === true;
130 $data['links'] = $linkDisplayed;
131
132 return $data;
133 }
134
135 /**
136 * Build a feed item (one per shaare).
137 *
138 * @param array $link Single link array extracted from LinkDB.
139 * @param string $pageaddr Index URL.
140 *
141 * @return array Link array with feed attributes.
142 */
143 protected function buildItem($link, $pageaddr)
144 {
145 $link['guid'] = $pageaddr .'?'. smallHash($link['linkdate']);
146 // Check for both signs of a note: starting with ? and 7 chars long.
147 if ($link['url'][0] === '?' && strlen($link['url']) === 7) {
148 $link['url'] = $pageaddr . $link['url'];
149 }
150 if ($this->usePermalinks === true) {
151 $permalink = '<a href="'. $link['url'] .'" title="Direct link">Direct link</a>';
152 } else {
153 $permalink = '<a href="'. $link['guid'] .'" title="Permalink">Permalink</a>';
154 }
155 $link['description'] = format_description($link['description']) . PHP_EOL .'<br>&#8212; '. $permalink;
156
157 $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']);
158
159 if ($this->feedType == self::$FEED_RSS) {
160 $link['iso_date'] = $date->format(DateTime::RSS);
161 } else {
162 $link['iso_date'] = $date->format(DateTime::ATOM);
163 }
164
165 // Save the more recent item.
166 if (empty($this->latestDate) || $this->latestDate < $date) {
167 $this->latestDate = $date;
168 }
169
170 $taglist = array_filter(explode(' ', $link['tags']), 'strlen');
171 uasort($taglist, 'strcasecmp');
172 $link['taglist'] = $taglist;
173
174 return $link;
175 }
176
177 /**
178 * Assign PubSub hub URL.
179 *
180 * @param string $pubsubhubUrl PubSub hub url.
181 */
182 public function setPubsubhubUrl($pubsubhubUrl)
183 {
184 $this->pubsubhubUrl = $pubsubhubUrl;
185 }
186
187 /**
188 * Set this to true to use permalinks instead of direct links.
189 *
190 * @param boolean $usePermalinks true to force permalinks.
191 */
192 public function setUsePermalinks($usePermalinks)
193 {
194 $this->usePermalinks = $usePermalinks;
195 }
196
197 /**
198 * Set this to true to hide timestamps in feeds.
199 *
200 * @param boolean $hideDates true to enable.
201 */
202 public function setHideDates($hideDates)
203 {
204 $this->hideDates = $hideDates;
205 }
206
207 /**
208 * Set the locale. Used to show feed language.
209 *
210 * @param string $locale The locale (eg. 'fr_FR.UTF8').
211 */
212 public function setLocale($locale)
213 {
214 $this->locale = strtolower($locale);
215 }
216
217 /**
218 * Get the language according to the feed type, based on the locale:
219 *
220 * - RSS format: en-us (default: 'en-en').
221 * - ATOM format: fr (default: 'en').
222 *
223 * @return string The language.
224 */
225 public function getTypeLanguage()
226 {
227 // Use the locale do define the language, if available.
228 if (! empty($this->locale) && preg_match('/^\w{2}[_\-]\w{2}/', $this->locale)) {
229 $length = ($this->feedType == self::$FEED_RSS) ? 5 : 2;
230 return str_replace('_', '-', substr($this->locale, 0, $length));
231 }
232 return ($this->feedType == self::$FEED_RSS) ? 'en-en' : 'en';
233 }
234
235 /**
236 * Format the latest item date found according to the feed type.
237 *
238 * Return an empty string if invalid DateTime is passed.
239 *
240 * @return string Formatted date.
241 */
242 protected function getLatestDateFormatted()
243 {
244 if (empty($this->latestDate) || !$this->latestDate instanceof DateTime) {
245 return '';
246 }
247
248 $type = ($this->feedType == self::$FEED_RSS) ? DateTime::RSS : DateTime::ATOM;
249 return $this->latestDate->format($type);
250 }
251
252 /**
253 * Returns the number of link to display according to 'nb' user input parameter.
254 *
255 * If 'nb' not set or invalid, default value: $DEFAULT_NB_LINKS.
256 * If 'nb' is set to 'all', display all filtered links (max parameter).
257 *
258 * @param int $max maximum number of links to display.
259 *
260 * @return int number of links to display.
261 */
262 public function getNbLinks($max)
263 {
264 if (empty($this->userInput['nb'])) {
265 return self::$DEFAULT_NB_LINKS;
266 }
267
268 if ($this->userInput['nb'] == 'all') {
269 return $max;
270 }
271
272 $intNb = intval($this->userInput['nb']);
273 if (! is_int($intNb) || $intNb == 0) {
274 return self::$DEFAULT_NB_LINKS;
275 }
276
277 return $intNb;
278 }
279}
diff --git a/application/HttpUtils.php b/application/HttpUtils.php
index af7cb371..2e0792f9 100644
--- a/application/HttpUtils.php
+++ b/application/HttpUtils.php
@@ -27,7 +27,9 @@
27function get_http_response($url, $timeout = 30, $maxBytes = 4194304) 27function get_http_response($url, $timeout = 30, $maxBytes = 4194304)
28{ 28{
29 $urlObj = new Url($url); 29 $urlObj = new Url($url);
30 if (! filter_var($url, FILTER_VALIDATE_URL) || ! $urlObj->isHttp()) { 30 $cleanUrl = $urlObj->idnToAscii();
31
32 if (! filter_var($cleanUrl, FILTER_VALIDATE_URL) || ! $urlObj->isHttp()) {
31 return array(array(0 => 'Invalid HTTP Url'), false); 33 return array(array(0 => 'Invalid HTTP Url'), false);
32 } 34 }
33 35
@@ -35,22 +37,27 @@ function get_http_response($url, $timeout = 30, $maxBytes = 4194304)
35 'http' => array( 37 'http' => array(
36 'method' => 'GET', 38 'method' => 'GET',
37 'timeout' => $timeout, 39 'timeout' => $timeout,
38 'user_agent' => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:23.0)' 40 'user_agent' => 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:45.0)'
39 .' Gecko/20100101 Firefox/23.0', 41 .' Gecko/20100101 Firefox/45.0',
40 'request_fulluri' => true, 42 'accept_language' => substr(setlocale(LC_COLLATE, 0), 0, 2) . ',en-US;q=0.7,en;q=0.3',
41 ) 43 )
42 ); 44 );
43 45
44 $context = stream_context_create($options);
45 stream_context_set_default($options); 46 stream_context_set_default($options);
47 list($headers, $finalUrl) = get_redirected_headers($cleanUrl);
48 if (! $headers || strpos($headers[0], '200 OK') === false) {
49 $options['http']['request_fulluri'] = true;
50 stream_context_set_default($options);
51 list($headers, $finalUrl) = get_redirected_headers($cleanUrl);
52 }
46 53
47 list($headers, $finalUrl) = get_redirected_headers($urlObj->cleanup());
48 if (! $headers || strpos($headers[0], '200 OK') === false) { 54 if (! $headers || strpos($headers[0], '200 OK') === false) {
49 return array($headers, false); 55 return array($headers, false);
50 } 56 }
51 57
52 try { 58 try {
53 // TODO: catch Exception in calling code (thumbnailer) 59 // TODO: catch Exception in calling code (thumbnailer)
60 $context = stream_context_create($options);
54 $content = file_get_contents($finalUrl, false, $context, -1, $maxBytes); 61 $content = file_get_contents($finalUrl, false, $context, -1, $maxBytes);
55 } catch (Exception $exc) { 62 } catch (Exception $exc) {
56 return array(array(0 => 'HTTP Error'), $exc->getMessage()); 63 return array(array(0 => 'HTTP Error'), $exc->getMessage());
@@ -60,16 +67,19 @@ function get_http_response($url, $timeout = 30, $maxBytes = 4194304)
60} 67}
61 68
62/** 69/**
63 * Retrieve HTTP headers, following n redirections (temporary and permanent). 70 * Retrieve HTTP headers, following n redirections (temporary and permanent ones).
64 * 71 *
65 * @param string $url initial URL to reach. 72 * @param string $url initial URL to reach.
66 * @param int $redirectionLimit max redirection follow.. 73 * @param int $redirectionLimit max redirection follow.
67 * 74 *
68 * @return array 75 * @return array HTTP headers, or false if it failed.
69 */ 76 */
70function get_redirected_headers($url, $redirectionLimit = 3) 77function get_redirected_headers($url, $redirectionLimit = 3)
71{ 78{
72 $headers = get_headers($url, 1); 79 $headers = get_headers($url, 1);
80 if (!empty($headers['location']) && empty($headers['Location'])) {
81 $headers['Location'] = $headers['location'];
82 }
73 83
74 // Headers found, redirection found, and limit not reached. 84 // Headers found, redirection found, and limit not reached.
75 if ($redirectionLimit-- > 0 85 if ($redirectionLimit-- > 0
@@ -79,6 +89,7 @@ function get_redirected_headers($url, $redirectionLimit = 3)
79 89
80 $redirection = is_array($headers['Location']) ? end($headers['Location']) : $headers['Location']; 90 $redirection = is_array($headers['Location']) ? end($headers['Location']) : $headers['Location'];
81 if ($redirection != $url) { 91 if ($redirection != $url) {
92 $redirection = getAbsoluteUrl($url, $redirection);
82 return get_redirected_headers($redirection, $redirectionLimit); 93 return get_redirected_headers($redirection, $redirectionLimit);
83 } 94 }
84 } 95 }
@@ -87,6 +98,35 @@ function get_redirected_headers($url, $redirectionLimit = 3)
87} 98}
88 99
89/** 100/**
101 * Get an absolute URL from a complete one, and another absolute/relative URL.
102 *
103 * @param string $originalUrl The original complete URL.
104 * @param string $newUrl The new one, absolute or relative.
105 *
106 * @return string Final URL:
107 * - $newUrl if it was already an absolute URL.
108 * - if it was relative, absolute URL from $originalUrl path.
109 */
110function getAbsoluteUrl($originalUrl, $newUrl)
111{
112 $newScheme = parse_url($newUrl, PHP_URL_SCHEME);
113 // Already an absolute URL.
114 if (!empty($newScheme)) {
115 return $newUrl;
116 }
117
118 $parts = parse_url($originalUrl);
119 $final = $parts['scheme'] .'://'. $parts['host'];
120 $final .= (!empty($parts['port'])) ? $parts['port'] : '';
121 $final .= '/';
122 if ($newUrl[0] != '/') {
123 $final .= substr(ltrim($parts['path'], '/'), 0, strrpos($parts['path'], '/'));
124 }
125 $final .= ltrim($newUrl, '/');
126 return $final;
127}
128
129/**
90 * Returns the server's base URL: scheme://domain.tld[:port] 130 * Returns the server's base URL: scheme://domain.tld[:port]
91 * 131 *
92 * @param array $server the $_SERVER array 132 * @param array $server the $_SERVER array
@@ -153,7 +193,7 @@ function server_url($server)
153function index_url($server) 193function index_url($server)
154{ 194{
155 $scriptname = $server['SCRIPT_NAME']; 195 $scriptname = $server['SCRIPT_NAME'];
156 if (endswith($scriptname, 'index.php')) { 196 if (endsWith($scriptname, 'index.php')) {
157 $scriptname = substr($scriptname, 0, -9); 197 $scriptname = substr($scriptname, 0, -9);
158 } 198 }
159 return server_url($server) . $scriptname; 199 return server_url($server) . $scriptname;
diff --git a/application/LinkDB.php b/application/LinkDB.php
index 1b505620..1cb70de0 100644
--- a/application/LinkDB.php
+++ b/application/LinkDB.php
@@ -66,21 +66,39 @@ class LinkDB implements Iterator, Countable, ArrayAccess
66 private $_redirector; 66 private $_redirector;
67 67
68 /** 68 /**
69 * Set this to `true` to urlencode link behind redirector link, `false` to leave it untouched.
70 *
71 * Example:
72 * anonym.to needs clean URL while dereferer.org needs urlencoded URL.
73 *
74 * @var boolean $redirectorEncode parameter: true or false
75 */
76 private $redirectorEncode;
77
78 /**
69 * Creates a new LinkDB 79 * Creates a new LinkDB
70 * 80 *
71 * Checks if the datastore exists; else, attempts to create a dummy one. 81 * Checks if the datastore exists; else, attempts to create a dummy one.
72 * 82 *
73 * @param string $datastore datastore file path. 83 * @param string $datastore datastore file path.
74 * @param boolean $isLoggedIn is the user logged in? 84 * @param boolean $isLoggedIn is the user logged in?
75 * @param boolean $hidePublicLinks if true all links are private. 85 * @param boolean $hidePublicLinks if true all links are private.
76 * @param string $redirector link redirector set in user settings. 86 * @param string $redirector link redirector set in user settings.
87 * @param boolean $redirectorEncode Enable urlencode on redirected urls (default: true).
77 */ 88 */
78 function __construct($datastore, $isLoggedIn, $hidePublicLinks, $redirector = '') 89 function __construct(
90 $datastore,
91 $isLoggedIn,
92 $hidePublicLinks,
93 $redirector = '',
94 $redirectorEncode = true
95 )
79 { 96 {
80 $this->_datastore = $datastore; 97 $this->_datastore = $datastore;
81 $this->_loggedIn = $isLoggedIn; 98 $this->_loggedIn = $isLoggedIn;
82 $this->_hidePublicLinks = $hidePublicLinks; 99 $this->_hidePublicLinks = $hidePublicLinks;
83 $this->_redirector = $redirector; 100 $this->_redirector = $redirector;
101 $this->redirectorEncode = $redirectorEncode === true;
84 $this->_checkDB(); 102 $this->_checkDB();
85 $this->_readDB(); 103 $this->_readDB();
86 } 104 }
@@ -278,7 +296,12 @@ You use the community supported version of the original Shaarli project, by Seba
278 296
279 // Do not use the redirector for internal links (Shaarli note URL starting with a '?'). 297 // Do not use the redirector for internal links (Shaarli note URL starting with a '?').
280 if (!empty($this->_redirector) && !startsWith($link['url'], '?')) { 298 if (!empty($this->_redirector) && !startsWith($link['url'], '?')) {
281 $link['real_url'] = $this->_redirector . urlencode($link['url']); 299 $link['real_url'] = $this->_redirector;
300 if ($this->redirectorEncode) {
301 $link['real_url'] .= urlencode(unescape($link['url']));
302 } else {
303 $link['real_url'] .= $link['url'];
304 }
282 } 305 }
283 else { 306 else {
284 $link['real_url'] = $link['url']; 307 $link['real_url'] = $link['url'];
@@ -341,17 +364,71 @@ You use the community supported version of the original Shaarli project, by Seba
341 } 364 }
342 365
343 /** 366 /**
344 * Filter links. 367 * Returns the shaare corresponding to a smallHash.
368 *
369 * @param string $request QUERY_STRING server parameter.
345 * 370 *
346 * @param string $type Type of filter. 371 * @return array $filtered array containing permalink data.
347 * @param mixed $request Search request, string or array. 372 *
373 * @throws LinkNotFoundException if the smallhash is malformed or doesn't match any link.
374 */
375 public function filterHash($request)
376 {
377 $request = substr($request, 0, 6);
378 $linkFilter = new LinkFilter($this->_links);
379 return $linkFilter->filter(LinkFilter::$FILTER_HASH, $request);
380 }
381
382 /**
383 * Returns the list of articles for a given day.
384 *
385 * @param string $request day to filter. Format: YYYYMMDD.
386 *
387 * @return array list of shaare found.
388 */
389 public function filterDay($request) {
390 $linkFilter = new LinkFilter($this->_links);
391 return $linkFilter->filter(LinkFilter::$FILTER_DAY, $request);
392 }
393
394 /**
395 * Filter links according to search parameters.
396 *
397 * @param array $filterRequest Search request content. Supported keys:
398 * - searchtags: list of tags
399 * - searchterm: term search
348 * @param bool $casesensitive Optional: Perform case sensitive filter 400 * @param bool $casesensitive Optional: Perform case sensitive filter
349 * @param bool $privateonly Optional: Returns private links only if true. 401 * @param bool $privateonly Optional: Returns private links only if true.
350 * 402 *
351 * @return array filtered links 403 * @return array filtered links, all links if no suitable filter was provided.
352 */ 404 */
353 public function filter($type = '', $request = '', $casesensitive = false, $privateonly = false) 405 public function filterSearch($filterRequest = array(), $casesensitive = false, $privateonly = false)
354 { 406 {
407 // Filter link database according to parameters.
408 $searchtags = !empty($filterRequest['searchtags']) ? escape($filterRequest['searchtags']) : '';
409 $searchterm = !empty($filterRequest['searchterm']) ? escape($filterRequest['searchterm']) : '';
410
411 // Search tags + fullsearch.
412 if (empty($type) && ! empty($searchtags) && ! empty($searchterm)) {
413 $type = LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT;
414 $request = array($searchtags, $searchterm);
415 }
416 // Search by tags.
417 elseif (! empty($searchtags)) {
418 $type = LinkFilter::$FILTER_TAG;
419 $request = $searchtags;
420 }
421 // Fulltext search.
422 elseif (! empty($searchterm)) {
423 $type = LinkFilter::$FILTER_TEXT;
424 $request = $searchterm;
425 }
426 // Otherwise, display without filtering.
427 else {
428 $type = '';
429 $request = '';
430 }
431
355 $linkFilter = new LinkFilter($this->_links); 432 $linkFilter = new LinkFilter($this->_links);
356 return $linkFilter->filter($type, $request, $casesensitive, $privateonly); 433 return $linkFilter->filter($type, $request, $casesensitive, $privateonly);
357 } 434 }
diff --git a/application/LinkFilter.php b/application/LinkFilter.php
index 3fd803cb..e693b284 100644
--- a/application/LinkFilter.php
+++ b/application/LinkFilter.php
@@ -44,7 +44,7 @@ class LinkFilter
44 * Filter links according to parameters. 44 * Filter links according to parameters.
45 * 45 *
46 * @param string $type Type of filter (eg. tags, permalink, etc.). 46 * @param string $type Type of filter (eg. tags, permalink, etc.).
47 * @param string $request Filter content. 47 * @param mixed $request Filter content.
48 * @param bool $casesensitive Optional: Perform case sensitive filter if true. 48 * @param bool $casesensitive Optional: Perform case sensitive filter if true.
49 * @param bool $privateonly Optional: Only returns private links if true. 49 * @param bool $privateonly Optional: Only returns private links if true.
50 * 50 *
@@ -110,6 +110,8 @@ class LinkFilter
110 * @param string $smallHash permalink hash. 110 * @param string $smallHash permalink hash.
111 * 111 *
112 * @return array $filtered array containing permalink data. 112 * @return array $filtered array containing permalink data.
113 *
114 * @throws LinkNotFoundException if the smallhash doesn't match any link.
113 */ 115 */
114 private function filterSmallHash($smallHash) 116 private function filterSmallHash($smallHash)
115 { 117 {
@@ -121,6 +123,11 @@ class LinkFilter
121 return $filtered; 123 return $filtered;
122 } 124 }
123 } 125 }
126
127 if (empty($filtered)) {
128 throw new LinkNotFoundException();
129 }
130
124 return $filtered; 131 return $filtered;
125 } 132 }
126 133
@@ -315,6 +322,11 @@ class LinkFilter
315 $tagsOut = $casesensitive ? $tags : mb_convert_case($tags, MB_CASE_LOWER, 'UTF-8'); 322 $tagsOut = $casesensitive ? $tags : mb_convert_case($tags, MB_CASE_LOWER, 'UTF-8');
316 $tagsOut = str_replace(',', ' ', $tagsOut); 323 $tagsOut = str_replace(',', ' ', $tagsOut);
317 324
318 return array_filter(explode(' ', trim($tagsOut)), 'strlen'); 325 return array_values(array_filter(explode(' ', trim($tagsOut)), 'strlen'));
319 } 326 }
320} 327}
328
329class LinkNotFoundException extends Exception
330{
331 protected $message = 'The link you are trying to reach does not exist or has been deleted.';
332}
diff --git a/application/LinkUtils.php b/application/LinkUtils.php
index 26dd6b67..da04ca97 100644
--- a/application/LinkUtils.php
+++ b/application/LinkUtils.php
@@ -9,8 +9,8 @@
9 */ 9 */
10function html_extract_title($html) 10function html_extract_title($html)
11{ 11{
12 if (preg_match('!<title>(.*)</title>!is', $html, $matches)) { 12 if (preg_match('!<title.*?>(.*?)</title>!is', $html, $matches)) {
13 return trim(str_replace("\n", ' ', $matches[1])); 13 return trim(str_replace("\n", '', $matches[1]));
14 } 14 }
15 return false; 15 return false;
16} 16}
@@ -70,10 +70,26 @@ function headers_extract_charset($headers)
70function html_extract_charset($html) 70function html_extract_charset($html)
71{ 71{
72 // Get encoding specified in HTML header. 72 // Get encoding specified in HTML header.
73 preg_match('#<meta .*charset="?([^">/]+)"? */?>#Usi', $html, $enc); 73 preg_match('#<meta .*charset=["\']?([^";\'>/]+)["\']? */?>#Usi', $html, $enc);
74 if (!empty($enc[1])) { 74 if (!empty($enc[1])) {
75 return strtolower($enc[1]); 75 return strtolower($enc[1]);
76 } 76 }
77 77
78 return false; 78 return false;
79} 79}
80
81/**
82 * Count private links in given linklist.
83 *
84 * @param array $links Linklist.
85 *
86 * @return int Number of private links.
87 */
88function count_private($links)
89{
90 $cpt = 0;
91 foreach ($links as $link) {
92 $cpt = $link['private'] == true ? $cpt + 1 : $cpt;
93 }
94 return $cpt;
95}
diff --git a/application/NetscapeBookmarkUtils.php b/application/NetscapeBookmarkUtils.php
new file mode 100644
index 00000000..fdbb0ad7
--- /dev/null
+++ b/application/NetscapeBookmarkUtils.php
@@ -0,0 +1,54 @@
1<?php
2
3/**
4 * Utilities to import and export bookmarks using the Netscape format
5 */
6class NetscapeBookmarkUtils
7{
8
9 /**
10 * Filters links and adds Netscape-formatted fields
11 *
12 * Added fields:
13 * - timestamp link addition date, using the Unix epoch format
14 * - taglist comma-separated tag list
15 *
16 * @param LinkDB $linkDb Link datastore
17 * @param string $selection Which links to export: (all|private|public)
18 * @param bool $prependNoteUrl Prepend note permalinks with the server's URL
19 * @param string $indexUrl Absolute URL of the Shaarli index page
20 *
21 * @throws Exception Invalid export selection
22 *
23 * @return array The links to be exported, with additional fields
24 */
25 public static function filterAndFormat($linkDb, $selection, $prependNoteUrl, $indexUrl)
26 {
27 // see tpl/export.html for possible values
28 if (! in_array($selection, array('all', 'public', 'private'))) {
29 throw new Exception('Invalid export selection: "'.$selection.'"');
30 }
31
32 $bookmarkLinks = array();
33
34 foreach ($linkDb as $link) {
35 if ($link['private'] != 0 && $selection == 'public') {
36 continue;
37 }
38 if ($link['private'] == 0 && $selection == 'private') {
39 continue;
40 }
41 $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']);
42 $link['timestamp'] = $date->getTimestamp();
43 $link['taglist'] = str_replace(' ', ',', $link['tags']);
44
45 if (startsWith($link['url'], '?') && $prependNoteUrl) {
46 $link['url'] = $indexUrl . $link['url'];
47 }
48
49 $bookmarkLinks[] = $link;
50 }
51
52 return $bookmarkLinks;
53 }
54}
diff --git a/application/PageBuilder.php b/application/PageBuilder.php
new file mode 100644
index 00000000..82580787
--- /dev/null
+++ b/application/PageBuilder.php
@@ -0,0 +1,145 @@
1<?php
2
3/**
4 * This class is in charge of building the final page.
5 * (This is basically a wrapper around RainTPL which pre-fills some fields.)
6 * $p = new PageBuilder();
7 * $p->assign('myfield','myvalue');
8 * $p->renderPage('mytemplate');
9 */
10class PageBuilder
11{
12 /**
13 * @var RainTPL RainTPL instance.
14 */
15 private $tpl;
16
17 /**
18 * PageBuilder constructor.
19 * $tpl is initialized at false for lazy loading.
20 */
21 function __construct()
22 {
23 $this->tpl = false;
24 }
25
26 /**
27 * Initialize all default tpl tags.
28 */
29 private function initialize()
30 {
31 $this->tpl = new RainTPL();
32
33 try {
34 $version = ApplicationUtils::checkUpdate(
35 shaarli_version,
36 $GLOBALS['config']['UPDATECHECK_FILENAME'],
37 $GLOBALS['config']['UPDATECHECK_INTERVAL'],
38 $GLOBALS['config']['ENABLE_UPDATECHECK'],
39 isLoggedIn(),
40 $GLOBALS['config']['UPDATECHECK_BRANCH']
41 );
42 $this->tpl->assign('newVersion', escape($version));
43 $this->tpl->assign('versionError', '');
44
45 } catch (Exception $exc) {
46 logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], $exc->getMessage());
47 $this->tpl->assign('newVersion', '');
48 $this->tpl->assign('versionError', escape($exc->getMessage()));
49 }
50
51 $this->tpl->assign('feedurl', escape(index_url($_SERVER)));
52 $searchcrits = ''; // Search criteria
53 if (!empty($_GET['searchtags'])) {
54 $searchcrits .= '&searchtags=' . urlencode($_GET['searchtags']);
55 }
56 if (!empty($_GET['searchterm'])) {
57 $searchcrits .= '&searchterm=' . urlencode($_GET['searchterm']);
58 }
59 $this->tpl->assign('searchcrits', $searchcrits);
60 $this->tpl->assign('source', index_url($_SERVER));
61 $this->tpl->assign('version', shaarli_version);
62 $this->tpl->assign('scripturl', index_url($_SERVER));
63 $this->tpl->assign('pagetitle', 'Shaarli');
64 $this->tpl->assign('privateonly', !empty($_SESSION['privateonly'])); // Show only private links?
65 if (!empty($GLOBALS['title'])) {
66 $this->tpl->assign('pagetitle', $GLOBALS['title']);
67 }
68 if (!empty($GLOBALS['titleLink'])) {
69 $this->tpl->assign('titleLink', $GLOBALS['titleLink']);
70 }
71 if (!empty($GLOBALS['pagetitle'])) {
72 $this->tpl->assign('pagetitle', $GLOBALS['pagetitle']);
73 }
74 $this->tpl->assign('shaarlititle', empty($GLOBALS['title']) ? 'Shaarli': $GLOBALS['title']);
75 if (!empty($GLOBALS['plugin_errors'])) {
76 $this->tpl->assign('plugin_errors', $GLOBALS['plugin_errors']);
77 }
78 }
79
80 /**
81 * The following assign() method is basically the same as RainTPL (except lazy loading)
82 *
83 * @param string $placeholder Template placeholder.
84 * @param mixed $value Value to assign.
85 */
86 public function assign($placeholder, $value)
87 {
88 // Lazy initialization
89 if ($this->tpl === false) {
90 $this->initialize();
91 }
92 $this->tpl->assign($placeholder, $value);
93 }
94
95 /**
96 * Assign an array of data to the template builder.
97 *
98 * @param array $data Data to assign.
99 *
100 * @return false if invalid data.
101 */
102 public function assignAll($data)
103 {
104 // Lazy initialization
105 if ($this->tpl === false) {
106 $this->initialize();
107 }
108
109 if (empty($data) || !is_array($data)){
110 return false;
111 }
112
113 foreach ($data as $key => $value) {
114 $this->assign($key, $value);
115 }
116 }
117
118 /**
119 * Render a specific page (using a template file).
120 * e.g. $pb->renderPage('picwall');
121 *
122 * @param string $page Template filename (without extension).
123 */
124 public function renderPage($page)
125 {
126 // Lazy initialization
127 if ($this->tpl===false) {
128 $this->initialize();
129 }
130 $this->tpl->draw($page);
131 }
132
133 /**
134 * Render a 404 page (uses the template : tpl/404.tpl)
135 * usage : $PAGE->render404('The link was deleted')
136 *
137 * @param string $message A messate to display what is not found
138 */
139 public function render404($message = 'The page you are trying to reach does not exist or has been deleted.')
140 {
141 header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
142 $this->tpl->assign('error_message', $message);
143 $this->renderPage('404');
144 }
145}
diff --git a/application/Router.php b/application/Router.php
index 6185f08e..2c3934b0 100644
--- a/application/Router.php
+++ b/application/Router.php
@@ -15,6 +15,10 @@ class Router
15 15
16 public static $PAGE_DAILY = 'daily'; 16 public static $PAGE_DAILY = 'daily';
17 17
18 public static $PAGE_FEED_ATOM = 'atom';
19
20 public static $PAGE_FEED_RSS = 'rss';
21
18 public static $PAGE_TOOLS = 'tools'; 22 public static $PAGE_TOOLS = 'tools';
19 23
20 public static $PAGE_CHANGEPASSWORD = 'changepasswd'; 24 public static $PAGE_CHANGEPASSWORD = 'changepasswd';
@@ -49,7 +53,7 @@ class Router
49 * @param array $get $_SERVER['GET']. 53 * @param array $get $_SERVER['GET'].
50 * @param bool $loggedIn true if authenticated user. 54 * @param bool $loggedIn true if authenticated user.
51 * 55 *
52 * @return self::page found. 56 * @return string page found.
53 */ 57 */
54 public static function findPage($query, $get, $loggedIn) 58 public static function findPage($query, $get, $loggedIn)
55 { 59 {
@@ -59,19 +63,19 @@ class Router
59 return self::$PAGE_LINKLIST; 63 return self::$PAGE_LINKLIST;
60 } 64 }
61 65
62 if (startswith($query, 'do='. self::$PAGE_LOGIN) && $loggedIn === false) { 66 if (startsWith($query, 'do='. self::$PAGE_LOGIN) && $loggedIn === false) {
63 return self::$PAGE_LOGIN; 67 return self::$PAGE_LOGIN;
64 } 68 }
65 69
66 if (startswith($query, 'do='. self::$PAGE_PICWALL)) { 70 if (startsWith($query, 'do='. self::$PAGE_PICWALL)) {
67 return self::$PAGE_PICWALL; 71 return self::$PAGE_PICWALL;
68 } 72 }
69 73
70 if (startswith($query, 'do='. self::$PAGE_TAGCLOUD)) { 74 if (startsWith($query, 'do='. self::$PAGE_TAGCLOUD)) {
71 return self::$PAGE_TAGCLOUD; 75 return self::$PAGE_TAGCLOUD;
72 } 76 }
73 77
74 if (startswith($query, 'do='. self::$PAGE_OPENSEARCH)) { 78 if (startsWith($query, 'do='. self::$PAGE_OPENSEARCH)) {
75 return self::$PAGE_OPENSEARCH; 79 return self::$PAGE_OPENSEARCH;
76 } 80 }
77 81
@@ -79,28 +83,36 @@ class Router
79 return self::$PAGE_DAILY; 83 return self::$PAGE_DAILY;
80 } 84 }
81 85
86 if (startsWith($query, 'do='. self::$PAGE_FEED_ATOM)) {
87 return self::$PAGE_FEED_ATOM;
88 }
89
90 if (startsWith($query, 'do='. self::$PAGE_FEED_RSS)) {
91 return self::$PAGE_FEED_RSS;
92 }
93
82 // At this point, only loggedin pages. 94 // At this point, only loggedin pages.
83 if (!$loggedIn) { 95 if (!$loggedIn) {
84 return self::$PAGE_LINKLIST; 96 return self::$PAGE_LINKLIST;
85 } 97 }
86 98
87 if (startswith($query, 'do='. self::$PAGE_TOOLS)) { 99 if (startsWith($query, 'do='. self::$PAGE_TOOLS)) {
88 return self::$PAGE_TOOLS; 100 return self::$PAGE_TOOLS;
89 } 101 }
90 102
91 if (startswith($query, 'do='. self::$PAGE_CHANGEPASSWORD)) { 103 if (startsWith($query, 'do='. self::$PAGE_CHANGEPASSWORD)) {
92 return self::$PAGE_CHANGEPASSWORD; 104 return self::$PAGE_CHANGEPASSWORD;
93 } 105 }
94 106
95 if (startswith($query, 'do='. self::$PAGE_CONFIGURE)) { 107 if (startsWith($query, 'do='. self::$PAGE_CONFIGURE)) {
96 return self::$PAGE_CONFIGURE; 108 return self::$PAGE_CONFIGURE;
97 } 109 }
98 110
99 if (startswith($query, 'do='. self::$PAGE_CHANGETAG)) { 111 if (startsWith($query, 'do='. self::$PAGE_CHANGETAG)) {
100 return self::$PAGE_CHANGETAG; 112 return self::$PAGE_CHANGETAG;
101 } 113 }
102 114
103 if (startswith($query, 'do='. self::$PAGE_ADDLINK)) { 115 if (startsWith($query, 'do='. self::$PAGE_ADDLINK)) {
104 return self::$PAGE_ADDLINK; 116 return self::$PAGE_ADDLINK;
105 } 117 }
106 118
@@ -108,19 +120,19 @@ class Router
108 return self::$PAGE_EDITLINK; 120 return self::$PAGE_EDITLINK;
109 } 121 }
110 122
111 if (startswith($query, 'do='. self::$PAGE_EXPORT)) { 123 if (startsWith($query, 'do='. self::$PAGE_EXPORT)) {
112 return self::$PAGE_EXPORT; 124 return self::$PAGE_EXPORT;
113 } 125 }
114 126
115 if (startswith($query, 'do='. self::$PAGE_IMPORT)) { 127 if (startsWith($query, 'do='. self::$PAGE_IMPORT)) {
116 return self::$PAGE_IMPORT; 128 return self::$PAGE_IMPORT;
117 } 129 }
118 130
119 if (startswith($query, 'do='. self::$PAGE_PLUGINSADMIN)) { 131 if (startsWith($query, 'do='. self::$PAGE_PLUGINSADMIN)) {
120 return self::$PAGE_PLUGINSADMIN; 132 return self::$PAGE_PLUGINSADMIN;
121 } 133 }
122 134
123 if (startswith($query, 'do='. self::$PAGE_SAVE_PLUGINSADMIN)) { 135 if (startsWith($query, 'do='. self::$PAGE_SAVE_PLUGINSADMIN)) {
124 return self::$PAGE_SAVE_PLUGINSADMIN; 136 return self::$PAGE_SAVE_PLUGINSADMIN;
125 } 137 }
126 138
diff --git a/application/TimeZone.php b/application/TimeZone.php
index e363d90a..26f2232d 100644
--- a/application/TimeZone.php
+++ b/application/TimeZone.php
@@ -101,10 +101,6 @@ function generateTimeZoneForm($preselectedTimezone='')
101 */ 101 */
102function isTimeZoneValid($continent, $city) 102function isTimeZoneValid($continent, $city)
103{ 103{
104 if ($continent == 'UTC' && $city == 'UTC') {
105 return true;
106 }
107
108 return in_array( 104 return in_array(
109 $continent.'/'.$city, 105 $continent.'/'.$city,
110 timezone_identifiers_list() 106 timezone_identifiers_list()
diff --git a/application/Updater.php b/application/Updater.php
index 773a1ffa..58c13c07 100644
--- a/application/Updater.php
+++ b/application/Updater.php
@@ -137,7 +137,7 @@ class Updater
137 */ 137 */
138 public function updateMethodRenameDashTags() 138 public function updateMethodRenameDashTags()
139 { 139 {
140 $linklist = $this->linkDB->filter(); 140 $linklist = $this->linkDB->filterSearch();
141 foreach ($linklist as $link) { 141 foreach ($linklist as $link) {
142 $link['tags'] = preg_replace('/(^| )\-/', '$1', $link['tags']); 142 $link['tags'] = preg_replace('/(^| )\-/', '$1', $link['tags']);
143 $link['tags'] = implode(' ', array_unique(LinkFilter::tagsStrToArray($link['tags'], true))); 143 $link['tags'] = implode(' ', array_unique(LinkFilter::tagsStrToArray($link['tags'], true)));
diff --git a/application/Url.php b/application/Url.php
index a4ac2e73..77447c8d 100644
--- a/application/Url.php
+++ b/application/Url.php
@@ -62,7 +62,21 @@ function add_trailing_slash($url)
62{ 62{
63 return $url . (!endsWith($url, '/') ? '/' : ''); 63 return $url . (!endsWith($url, '/') ? '/' : '');
64} 64}
65/**
66 * Converts an URL with an IDN host to a ASCII one.
67 *
68 * @param string $url Input URL.
69 *
70 * @return string converted URL.
71 */
72function url_with_idn_to_ascii($url)
73{
74 $parts = parse_url($url);
75 $parts['host'] = idn_to_ascii($parts['host']);
65 76
77 $httpUrl = new \http\Url($parts);
78 return $httpUrl->toString();
79}
66/** 80/**
67 * URL representation and cleanup utilities 81 * URL representation and cleanup utilities
68 * 82 *
@@ -118,7 +132,8 @@ class Url
118 */ 132 */
119 public function __construct($url) 133 public function __construct($url)
120 { 134 {
121 $this->parts = parse_url(trim($url)); 135 $url = self::cleanupUnparsedUrl(trim($url));
136 $this->parts = parse_url($url);
122 137
123 if (!empty($url) && empty($this->parts['scheme'])) { 138 if (!empty($url) && empty($this->parts['scheme'])) {
124 $this->parts['scheme'] = 'http'; 139 $this->parts['scheme'] = 'http';
@@ -126,6 +141,35 @@ class Url
126 } 141 }
127 142
128 /** 143 /**
144 * Clean up URL before it's parsed.
145 * ie. handle urlencode, url prefixes, etc.
146 *
147 * @param string $url URL to clean.
148 *
149 * @return string cleaned URL.
150 */
151 protected static function cleanupUnparsedUrl($url)
152 {
153 return self::removeFirefoxAboutReader($url);
154 }
155
156 /**
157 * Remove Firefox Reader prefix if it's present.
158 *
159 * @param string $input url
160 *
161 * @return string cleaned url
162 */
163 protected static function removeFirefoxAboutReader($input)
164 {
165 $firefoxPrefix = 'about://reader?url=';
166 if (startsWith($input, $firefoxPrefix)) {
167 return urldecode(ltrim($input, $firefoxPrefix));
168 }
169 return $input;
170 }
171
172 /**
129 * Returns a string representation of this URL 173 * Returns a string representation of this URL
130 */ 174 */
131 public function toString() 175 public function toString()
@@ -191,6 +235,22 @@ class Url
191 } 235 }
192 236
193 /** 237 /**
238 * Converts an URL with an International Domain Name host to a ASCII one.
239 * This requires PHP-intl. If it's not available, just returns this->cleanup().
240 *
241 * @return string converted cleaned up URL.
242 */
243 public function idnToAscii()
244 {
245 $out = $this->cleanup();
246 if (! function_exists('idn_to_ascii') || ! isset($this->parts['host'])) {
247 return $out;
248 }
249 $asciiHost = idn_to_ascii($this->parts['host']);
250 return str_replace($this->parts['host'], $asciiHost, $out);
251 }
252
253 /**
194 * Get URL scheme. 254 * Get URL scheme.
195 * 255 *
196 * @return string the URL scheme or false if none is provided. 256 * @return string the URL scheme or false if none is provided.
@@ -203,6 +263,18 @@ class Url
203 } 263 }
204 264
205 /** 265 /**
266 * Get URL host.
267 *
268 * @return string the URL host or false if none is provided.
269 */
270 public function getHost() {
271 if (empty($this->parts['host'])) {
272 return false;
273 }
274 return $this->parts['host'];
275 }
276
277 /**
206 * Test if the Url is an HTTP one. 278 * Test if the Url is an HTTP one.
207 * 279 *
208 * @return true is HTTP, false otherwise. 280 * @return true is HTTP, false otherwise.
diff --git a/application/Utils.php b/application/Utils.php
index 3d819716..da521cce 100644
--- a/application/Utils.php
+++ b/application/Utils.php
@@ -41,8 +41,14 @@ function smallHash($text)
41 41
42/** 42/**
43 * Tells if a string start with a substring 43 * Tells if a string start with a substring
44 *
45 * @param string $haystack Given string.
46 * @param string $needle String to search at the beginning of $haystack.
47 * @param bool $case Case sensitive.
48 *
49 * @return bool True if $haystack starts with $needle.
44 */ 50 */
45function startsWith($haystack, $needle, $case=true) 51function startsWith($haystack, $needle, $case = true)
46{ 52{
47 if ($case) { 53 if ($case) {
48 return (strcmp(substr($haystack, 0, strlen($needle)), $needle) === 0); 54 return (strcmp(substr($haystack, 0, strlen($needle)), $needle) === 0);
@@ -52,8 +58,14 @@ function startsWith($haystack, $needle, $case=true)
52 58
53/** 59/**
54 * Tells if a string ends with a substring 60 * Tells if a string ends with a substring
61 *
62 * @param string $haystack Given string.
63 * @param string $needle String to search at the end of $haystack.
64 * @param bool $case Case sensitive.
65 *
66 * @return bool True if $haystack ends with $needle.
55 */ 67 */
56function endsWith($haystack, $needle, $case=true) 68function endsWith($haystack, $needle, $case = true)
57{ 69{
58 if ($case) { 70 if ($case) {
59 return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0); 71 return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0);
@@ -63,14 +75,22 @@ function endsWith($haystack, $needle, $case=true)
63 75
64/** 76/**
65 * Htmlspecialchars wrapper 77 * Htmlspecialchars wrapper
78 * Support multidimensional array of strings.
66 * 79 *
67 * @param string $str the string to escape. 80 * @param mixed $input Data to escape: a single string or an array of strings.
68 * 81 *
69 * @return string escaped. 82 * @return string escaped.
70 */ 83 */
71function escape($str) 84function escape($input)
72{ 85{
73 return htmlspecialchars($str, ENT_COMPAT, 'UTF-8', false); 86 if (is_array($input)) {
87 $out = array();
88 foreach($input as $key => $value) {
89 $out[$key] = escape($value);
90 }
91 return $out;
92 }
93 return htmlspecialchars($input, ENT_COMPAT, 'UTF-8', false);
74} 94}
75 95
76/** 96/**
@@ -226,7 +246,7 @@ function space2nbsp($text)
226 * 246 *
227 * @return string formatted description. 247 * @return string formatted description.
228 */ 248 */
229function format_description($description, $redirector) { 249function format_description($description, $redirector = false) {
230 return nl2br(space2nbsp(text2clickable($description, $redirector))); 250 return nl2br(space2nbsp(text2clickable($description, $redirector)));
231} 251}
232 252
diff --git a/composer.json b/composer.json
index f6d92c92..2ded0920 100644
--- a/composer.json
+++ b/composer.json
@@ -8,7 +8,7 @@
8 "require": {}, 8 "require": {},
9 "require-dev": { 9 "require-dev": {
10 "phpmd/phpmd" : "@stable", 10 "phpmd/phpmd" : "@stable",
11 "phpunit/phpunit": "4.6.*", 11 "phpunit/phpunit": "4.8.*",
12 "sebastian/phpcpd": "*", 12 "sebastian/phpcpd": "*",
13 "squizlabs/php_codesniffer": "2.*" 13 "squizlabs/php_codesniffer": "2.*"
14 } 14 }
diff --git a/doc/3rd-party-libraries.html b/doc/3rd-party-libraries.html
index 21fa20aa..f6ff4763 100644
--- a/doc/3rd-party-libraries.html
+++ b/doc/3rd-party-libraries.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - 3rd party libraries</title> 7 <title>Shaarli – 3rd party libraries</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
diff --git a/doc/Backup,-restore,-import-and-export.html b/doc/Backup,-restore,-import-and-export.html
index 5724b689..4d72728e 100644
--- a/doc/Backup,-restore,-import-and-export.html
+++ b/doc/Backup,-restore,-import-and-export.html
@@ -4,31 +4,49 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Backup, restore, import and export</title> 7 <title>Shaarli – Backup, restore, import and export</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <style type="text/css"> 9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
13table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
14 margin: 0; padding: 0; vertical-align: baseline; border: none; } 12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
15table.sourceCode { width: 100%; line-height: 100%; } 13table.sourceCode { width: 100%; line-height: 100%; }
16td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } 14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
17td.sourceCode { padding-left: 5px; } 15td.sourceCode { padding-left: 5px; }
18code > span.kw { color: #007020; font-weight: bold; } 16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
19code > span.dt { color: #902000; } 17code > span.dt { color: #902000; } /* DataType */
20code > span.dv { color: #40a070; } 18code > span.dv { color: #40a070; } /* DecVal */
21code > span.bn { color: #40a070; } 19code > span.bn { color: #40a070; } /* BaseN */
22code > span.fl { color: #40a070; } 20code > span.fl { color: #40a070; } /* Float */
23code > span.ch { color: #4070a0; } 21code > span.ch { color: #4070a0; } /* Char */
24code > span.st { color: #4070a0; } 22code > span.st { color: #4070a0; } /* String */
25code > span.co { color: #60a0b0; font-style: italic; } 23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
26code > span.ot { color: #007020; } 24code > span.ot { color: #007020; } /* Other */
27code > span.al { color: #ff0000; font-weight: bold; } 25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
28code > span.fu { color: #06287e; } 26code > span.fu { color: #06287e; } /* Function */
29code > span.er { color: #ff0000; font-weight: bold; } 27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
30 </style> 45 </style>
31 <link rel="stylesheet" href="github-markdown.css"> 46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
32</head> 50</head>
33<body> 51<body>
34<div id="local-sidebar"> 52<div id="local-sidebar">
@@ -39,18 +57,25 @@ code > span.er { color: #ff0000; font-weight: bold; }
39<li><a href="Download.html">Download</a></li> 57<li><a href="Download.html">Download</a></li>
40<li><a href="Server-requirements.html">Server requirements</a></li> 58<li><a href="Server-requirements.html">Server requirements</a></li>
41<li><a href="Server-configuration.html">Server configuration</a></li> 59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
42<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
43</ul></li> 64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
44<li><a href="Usage.html">Usage</a> 66<li><a href="Usage.html">Usage</a>
45<ul> 67<ul>
46<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 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>
47<li><a href="Firefox-share.html">Firefox share</a></li> 70<li><a href="Firefox-share.html">Firefox share</a></li>
48<li><a href="RSS-feeds.html">RSS feeds</a></li> 71<li><a href="RSS-feeds.html">RSS feeds</a></li>
49</ul></li> 72</ul></li>
50<li>How To 73<li>How To
51<ul> 74<ul>
52<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
53<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> 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>
54<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 79<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
55<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 80<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
56</ul></li> 81</ul></li>
@@ -62,6 +87,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
62<li><a href="Directory-structure.html">Directory structure</a></li> 87<li><a href="Directory-structure.html">Directory structure</a></li>
63<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
64<li><a href="Plugin-System.html">Plugin System</a></li> 89<li><a href="Plugin-System.html">Plugin System</a></li>
90<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
65<li><a href="Security.html">Security</a></li> 91<li><a href="Security.html">Security</a></li>
66<li><a href="Static-analysis.html">Static analysis</a></li> 92<li><a href="Static-analysis.html">Static analysis</a></li>
67<li><a href="Theming.html">Theming</a></li> 93<li><a href="Theming.html">Theming</a></li>
@@ -79,7 +105,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
79<h2 id="backup-and-restore-the-datastore-file">Backup and restore the datastore file</h2> 105<h2 id="backup-and-restore-the-datastore-file">Backup and restore the datastore file</h2>
80<p>Backup the file <code>data/datastore.php</code> (by FTP or SSH). Restore by putting the file back in place.</p> 106<p>Backup the file <code>data/datastore.php</code> (by FTP or SSH). Restore by putting the file back in place.</p>
81<p>Example command:</p> 107<p>Example command:</p>
82<pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">rsync</span> -avzP my.server.com:/var/www/shaarli/data/datastore.php datastore-<span class="ot">$(</span><span class="kw">date</span> +%Y-%m-%d_%H%M<span class="ot">)</span>.php</code></pre> 108<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">rsync</span> -avzP my.server.com:/var/www/shaarli/data/datastore.php datastore-<span class="ot">$(</span><span class="kw">date</span> +%Y-%m-%d_%H%M<span class="ot">)</span>.php</code></pre></div>
83<h2 id="export-links-as...">Export links as...</h2> 109<h2 id="export-links-as...">Export links as...</h2>
84<p>To export links as an HTML file, under <em>Tools &gt; Export</em>, choose:</p> 110<p>To export links as an HTML file, under <em>Tools &gt; Export</em>, choose:</p>
85<ul> 111<ul>
@@ -92,7 +118,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
92<li>This can be done using the <a href="https://github.com/nodiscc/shaarchiver">shaarchiver</a> tool.<a href=".html"></a></li> 118<li>This can be done using the <a href="https://github.com/nodiscc/shaarchiver">shaarchiver</a> tool.<a href=".html"></a></li>
93</ul> 119</ul>
94<p>Example command:</p> 120<p>Example command:</p>
95<pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">./export-bookmarks.py</span> --url=https://my.server.com/shaarli --username=myusername --password=mysupersecretpassword --download-dir=./ --type=all</code></pre> 121<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">./export-bookmarks.py</span> --url=https://my.server.com/shaarli --username=myusername --password=mysupersecretpassword --download-dir=./ --type=all</code></pre></div>
96<h2 id="import-links-from...">Import links from...</h2> 122<h2 id="import-links-from...">Import links from...</h2>
97<h3 id="diigo">Diigo</h3> 123<h3 id="diigo">Diigo</h3>
98<p>If you export your bookmark from Diigo, make sure you use the Delicious export, not the Netscape export. (Their Netscape export is broken, and they don't seem to be interested in fixing it.)</p> 124<p>If you export your bookmark from Diigo, make sure you use the Delicious export, not the Netscape export. (Their Netscape export is broken, and they don't seem to be interested in fixing it.)</p>
diff --git a/doc/Browsing-and-searching.html b/doc/Browsing-and-searching.html
new file mode 100644
index 00000000..39806128
--- /dev/null
+++ b/doc/Browsing-and-searching.html
@@ -0,0 +1,83 @@
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli – Browsing and searching</title>
8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
10 <!--[if lt IE 9]>
11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
12 <![endif]-->
13</head>
14<body>
15<div id="local-sidebar">
16<ul>
17<li><a href="Home.html">Home</a></li>
18<li>Installation
19<ul>
20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
29<li><a href="Usage.html">Usage</a>
30<ul>
31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
33<li><a href="Firefox-share.html">Firefox share</a></li>
34<li><a href="RSS-feeds.html">RSS feeds</a></li>
35</ul></li>
36<li>How To
37<ul>
38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
44</ul></li>
45<li><a href="Troubleshooting.html">Troubleshooting</a></li>
46<li><a href="Development.html">Development</a>
47<ul>
48<li><a href="GnuPG-signature.html">GnuPG signature</a></li>
49<li><a href="Coding-guidelines.html">Coding guidelines</a></li>
50<li><a href="Directory-structure.html">Directory structure</a></li>
51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
54<li><a href="Security.html">Security</a></li>
55<li><a href="Static-analysis.html">Static analysis</a></li>
56<li><a href="Theming.html">Theming</a></li>
57<li><a href="Unit-tests.html">Unit tests</a></li>
58</ul></li>
59<li>About
60<ul>
61<li><a href="FAQ.html">FAQ</a></li>
62<li><a href="Community-&amp;-Related-software.html">Community &amp; Related software</a></li>
63<li><a href="TODO.html">TODO</a></li>
64</ul></li>
65</ul>
66</div>
67<h1 id="browsing-and-searching">Browsing and searching</h1>
68<h1 id="browsing-and-searching-1">Browsing and Searching</h1>
69<p>Status: DRAFT</p>
70<p><embed src="(http://pix.toile-libre.org/upload/original/1455571378.png).html" /></p>
71<h2 id="plain-text-search">Plain text search</h2>
72<p>Use the <code>Search text</code> field to search in <em>any</em> of the fields of all links (Title, URL, Description...)</p>
73<p><strong>Exclude text/tags:</strong> Use the <code>-</code> operator before a word or tag (example <code>-uninteresting</code>) to prevent entries containing (or tagged) <code>uninteresting</code> from showing up in the search results.</p>
74<p><strong>Exact text search:</strong> Use double-quotes (example <code>&quot;exact search&quot;</code>) to search for the exact expression.</p>
75<p>Both exclude patterns and exact searches can be combined with normal searches (example <code>&quot;exact search&quot; term otherterm -notthis &quot;very exact&quot; stuff -notagain</code>)</p>
76<h2 id="tags-search">Tags search</h2>
77<p>Use the <code>Filter by tags</code> field to restrict displayed links to entries tagged with one or multiple tags (use space to separate tags).</p>
78<p><strong>Hidden tags:</strong> Tags starting with a dot <code>.</code> (example <code>.secret</code>) are private. They can only be seen and searched when logged in.</p>
79<p>Alternatively you can use the <code>Tag cloud</code> to discover all tags and click on any of them to display related links.</p>
80<h2 id="filtering-rss-feedspicture-wall">Filtering RSS feeds/Picture wall</h2>
81<p>RSS feeds can also be restricted to only return items matching a text/tag search: see <a href="RSS-feeds.html">RSS feeds</a>.</p>
82</body>
83</html>
diff --git a/doc/Browsing-and-searching.md b/doc/Browsing-and-searching.md
new file mode 100644
index 00000000..187fe447
--- /dev/null
+++ b/doc/Browsing-and-searching.md
@@ -0,0 +1,28 @@
1#Browsing and searching
2# Browsing and Searching
3
4Status: DRAFT
5
6![(http://pix.toile-libre.org/upload/original/1455571378.png)]((http://pix.toile-libre.org/upload/original/1455571378.png).html)
7
8## Plain text search
9
10Use the `Search text` field to search in _any_ of the fields of all links (Title, URL, Description...)
11
12**Exclude text/tags:** Use the `-` operator before a word or tag (example `-uninteresting`) to prevent entries containing (or tagged) `uninteresting` from showing up in the search results.
13
14**Exact text search:** Use double-quotes (example `"exact search"`) to search for the exact expression.
15
16Both exclude patterns and exact searches can be combined with normal searches (example `"exact search" term otherterm -notthis "very exact" stuff -notagain`)
17
18## Tags search
19
20Use the `Filter by tags` field to restrict displayed links to entries tagged with one or multiple tags (use space to separate tags).
21
22**Hidden tags:** Tags starting with a dot `.` (example `.secret`) are private. They can only be seen and searched when logged in.
23
24Alternatively you can use the `Tag cloud` to discover all tags and click on any of them to display related links.
25
26## Filtering RSS feeds/Picture wall
27
28RSS feeds can also be restricted to only return items matching a text/tag search: see [RSS feeds](RSS-feeds.html).
diff --git a/doc/Coding-guidelines.html b/doc/Coding-guidelines.html
index 40d17912..add69631 100644
--- a/doc/Coding-guidelines.html
+++ b/doc/Coding-guidelines.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Coding guidelines</title> 7 <title>Shaarli – Coding guidelines</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
diff --git a/doc/Community-&-Related-software.html b/doc/Community-&-Related-software.html
index 34bc6157..77b9793f 100644
--- a/doc/Community-&-Related-software.html
+++ b/doc/Community-&-Related-software.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Community & Related software</title> 7 <title>Shaarli – Community & Related software</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
@@ -70,7 +78,14 @@
70<li><a href="http://sebsauvage.net/wiki/doku.php?id=php:shaarli:discussion">Original discussion page</a> (fr)<a href=".html"></a></li> 78<li><a href="http://sebsauvage.net/wiki/doku.php?id=php:shaarli:discussion">Original discussion page</a> (fr)<a href=".html"></a></li>
71<li><a href="http://sebsauvage.net/wiki/doku.php?id=php:shaarli:history">Original revisions history</a><a href=".html"></a></li> 79<li><a href="http://sebsauvage.net/wiki/doku.php?id=php:shaarli:history">Original revisions history</a><a href=".html"></a></li>
72<li><a href="https://www.shaarli.fr/my.php">Shaarli.fr/my</a> - Unofficial, unsupported (old fork) hosted Shaarlis provider, courtesy of <a href="https://github.com/DMeloni">DMeloni</a><a href=".html"></a></li> 80<li><a href="https://www.shaarli.fr/my.php">Shaarli.fr/my</a> - Unofficial, unsupported (old fork) hosted Shaarlis provider, courtesy of <a href="https://github.com/DMeloni">DMeloni</a><a href=".html"></a></li>
73<li><a href="http://shaarferme.etudiant-libre.fr.nf/index.php">Shaarli Community</a> - Unknown Shaarli hoster (unsupported, old fork)<a href=".html"></a></li> 81</ul>
82<h3 id="third-party-plugins">Third party plugins</h3>
83<ul>
84<li><a href="https://github.com/kalvn/shaarli-plugin-autosave">autosave</a> by <a href="https://github.com/kalvn">@kalvn</a>: Automatically saves data when editing a link to avoid any loss in case of crash or unexpected shutdown.<a href=".html"></a></li>
85<li><a href="https://github.com/ArthurHoaro/code-coloration">Code Coloration</a> by <a href="https://github.com/ArthurHoaro">@ArthurHoaro</a>: client side code syntax highlighter.<a href=".html"></a></li>
86<li><a href="https://github.com/alexisju/social">social</a> by <a href="https://github.com/alexisju">@alexisju</a>: share links to social networks.<a href=".html"></a></li>
87<li><a href="https://github.com/NerosTie/emojione">emojione</a> by <a href="https://github.com/NerosTie/emojione">@NerosTie</a>: Add colorful emojis to your Shaarli.<a href=".html"></a></li>
88<li><a href="https://github.com/ArthurHoaro/launch-plugin">launch</a> - Launch Plugin is a plugin designed to enhance and customize Launch Theme for Shaarli.<a href=".html"></a></li>
74</ul> 89</ul>
75<h3 id="themes">Themes</h3> 90<h3 id="themes">Themes</h3>
76<p>See <a href="Theming.html">Theming</a> for the list of community-contributed themes, and an installation guide.</p> 91<p>See <a href="Theming.html">Theming</a> for the list of community-contributed themes, and an installation guide.</p>
@@ -85,7 +100,7 @@
85</ul> 100</ul>
86<h3 id="mobile-apps">Mobile Apps</h3> 101<h3 id="mobile-apps">Mobile Apps</h3>
87<ul> 102<ul>
88<li><a href="https://github.com/mro/ShaarliOS#the-missing-ios-8-share-extension-to-shaarli">github.com/mro/ShaarliOS</a> iOS share extension - see <a href="https://github.com/shaarli/Shaarli/issues/308#issuecomment-132303709">#308</a> for some promo codes,<a href=".html"></a></li> 103<li><a href="http://app.mro.name/Shaarli💫">Shaarli💫</a> iOS share extension - see <a href="https://github.com/shaarli/Shaarli/issues/308#issuecomment-184592070">#308</a> for some promo codes,<a href=".html"></a></li>
89<li><a href="http://sebsauvage.net/links/?ZAyDzg">Shaarli for Android</a> - Android application that adds Shaarli as a sharing provider<a href=".html"></a></li> 104<li><a href="http://sebsauvage.net/links/?ZAyDzg">Shaarli for Android</a> - Android application that adds Shaarli as a sharing provider<a href=".html"></a></li>
90<li><a href="https://github.com/dimtion/Shaarlier">Shaarlier for Android</a> - Android application to simply add links directly into your Shaarli<a href=".html"></a></li> 105<li><a href="https://github.com/dimtion/Shaarlier">Shaarlier for Android</a> - Android application to simply add links directly into your Shaarli<a href=".html"></a></li>
91</ul> 106</ul>
diff --git a/doc/Community-&-Related-software.md b/doc/Community-&-Related-software.md
index 77ea2420..03a3dea9 100644
--- a/doc/Community-&-Related-software.md
+++ b/doc/Community-&-Related-software.md
@@ -13,7 +13,17 @@ _TODO: contact repos owners to see if they'd like to standardize their work with
13- [Original discussion page](http://sebsauvage.net/wiki/doku.php?id=php:shaarli:discussion) (fr)[](.html) 13- [Original discussion page](http://sebsauvage.net/wiki/doku.php?id=php:shaarli:discussion) (fr)[](.html)
14- [Original revisions history](http://sebsauvage.net/wiki/doku.php?id=php:shaarli:history)[](.html) 14- [Original revisions history](http://sebsauvage.net/wiki/doku.php?id=php:shaarli:history)[](.html)
15- [Shaarli.fr/my](https://www.shaarli.fr/my.php) - Unofficial, unsupported (old fork) hosted Shaarlis provider, courtesy of [DMeloni](https://github.com/DMeloni)[](.html) 15- [Shaarli.fr/my](https://www.shaarli.fr/my.php) - Unofficial, unsupported (old fork) hosted Shaarlis provider, courtesy of [DMeloni](https://github.com/DMeloni)[](.html)
16- [Shaarli Community](http://shaarferme.etudiant-libre.fr.nf/index.php) - Unknown Shaarli hoster (unsupported, old fork)[](.html) 16
17
18### Third party plugins
19
20
21 * [autosave](https://github.com/kalvn/shaarli-plugin-autosave) by [@kalvn](https://github.com/kalvn): Automatically saves data when editing a link to avoid any loss in case of crash or unexpected shutdown.[](.html)
22 * [Code Coloration](https://github.com/ArthurHoaro/code-coloration) by [@ArthurHoaro](https://github.com/ArthurHoaro): client side code syntax highlighter.[](.html)
23 * [social](https://github.com/alexisju/social) by [@alexisju](https://github.com/alexisju): share links to social networks.[](.html)
24 * [emojione](https://github.com/NerosTie/emojione) by [@NerosTie](https://github.com/NerosTie/emojione): Add colorful emojis to your Shaarli.[](.html)
25 * [launch](https://github.com/ArthurHoaro/launch-plugin) - Launch Plugin is a plugin designed to enhance and customize Launch Theme for Shaarli.[](.html)
26
17 27
18### Themes 28### Themes
19See [Theming](Theming.html) for the list of community-contributed themes, and an installation guide. 29See [Theming](Theming.html) for the list of community-contributed themes, and an installation guide.
@@ -27,7 +37,7 @@ See [Theming](Theming.html) for the list of community-contributed themes, and an
27- [Self dead link](https://github.com/qwertygc/shaarli-dev-code/blob/master/self-dead-link.php) - Detect dead links on shaarli. This version use the database of shaarli. An [another version](https://github.com/qwertygc/shaarli-dev-code/blob/master/dead-link.php), can be used for others shaarli (but use most ressources).[](.html) 37- [Self dead link](https://github.com/qwertygc/shaarli-dev-code/blob/master/self-dead-link.php) - Detect dead links on shaarli. This version use the database of shaarli. An [another version](https://github.com/qwertygc/shaarli-dev-code/blob/master/dead-link.php), can be used for others shaarli (but use most ressources).[](.html)
28 38
29### Mobile Apps 39### Mobile Apps
30- [github.com/mro/ShaarliOS](https://github.com/mro/ShaarliOS#the-missing-ios-8-share-extension-to-shaarli) iOS share extension - see [#308](https://github.com/shaarli/Shaarli/issues/308#issuecomment-132303709) for some promo codes,[](.html) 40- [Shaarli💫](http://app.mro.name/Shaarli💫) iOS share extension - see [#308](https://github.com/shaarli/Shaarli/issues/308#issuecomment-184592070) for some promo codes,[](.html)
31- [Shaarli for Android](http://sebsauvage.net/links/?ZAyDzg) - Android application that adds Shaarli as a sharing provider[](.html) 41- [Shaarli for Android](http://sebsauvage.net/links/?ZAyDzg) - Android application that adds Shaarli as a sharing provider[](.html)
32- [Shaarlier for Android](https://github.com/dimtion/Shaarlier) - Android application to simply add links directly into your Shaarli[](.html) 42- [Shaarlier for Android](https://github.com/dimtion/Shaarlier) - Android application to simply add links directly into your Shaarli[](.html)
33 43
diff --git a/doc/Copy-an-existing-installation-over-SSH-and-serve-it-locally.html b/doc/Copy-an-existing-installation-over-SSH-and-serve-it-locally.html
index e27b1134..edb1555f 100644
--- a/doc/Copy-an-existing-installation-over-SSH-and-serve-it-locally.html
+++ b/doc/Copy-an-existing-installation-over-SSH-and-serve-it-locally.html
@@ -4,31 +4,49 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Copy an existing installation over SSH and serve it locally</title> 7 <title>Shaarli – Copy an existing installation over SSH and serve it locally</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <style type="text/css"> 9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
13table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
14 margin: 0; padding: 0; vertical-align: baseline; border: none; } 12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
15table.sourceCode { width: 100%; line-height: 100%; } 13table.sourceCode { width: 100%; line-height: 100%; }
16td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } 14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
17td.sourceCode { padding-left: 5px; } 15td.sourceCode { padding-left: 5px; }
18code > span.kw { color: #007020; font-weight: bold; } 16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
19code > span.dt { color: #902000; } 17code > span.dt { color: #902000; } /* DataType */
20code > span.dv { color: #40a070; } 18code > span.dv { color: #40a070; } /* DecVal */
21code > span.bn { color: #40a070; } 19code > span.bn { color: #40a070; } /* BaseN */
22code > span.fl { color: #40a070; } 20code > span.fl { color: #40a070; } /* Float */
23code > span.ch { color: #4070a0; } 21code > span.ch { color: #4070a0; } /* Char */
24code > span.st { color: #4070a0; } 22code > span.st { color: #4070a0; } /* String */
25code > span.co { color: #60a0b0; font-style: italic; } 23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
26code > span.ot { color: #007020; } 24code > span.ot { color: #007020; } /* Other */
27code > span.al { color: #ff0000; font-weight: bold; } 25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
28code > span.fu { color: #06287e; } 26code > span.fu { color: #06287e; } /* Function */
29code > span.er { color: #ff0000; font-weight: bold; } 27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
30 </style> 45 </style>
31 <link rel="stylesheet" href="github-markdown.css"> 46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
32</head> 50</head>
33<body> 51<body>
34<div id="local-sidebar"> 52<div id="local-sidebar">
@@ -39,18 +57,25 @@ code > span.er { color: #ff0000; font-weight: bold; }
39<li><a href="Download.html">Download</a></li> 57<li><a href="Download.html">Download</a></li>
40<li><a href="Server-requirements.html">Server requirements</a></li> 58<li><a href="Server-requirements.html">Server requirements</a></li>
41<li><a href="Server-configuration.html">Server configuration</a></li> 59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
42<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
43</ul></li> 64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
44<li><a href="Usage.html">Usage</a> 66<li><a href="Usage.html">Usage</a>
45<ul> 67<ul>
46<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 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>
47<li><a href="Firefox-share.html">Firefox share</a></li> 70<li><a href="Firefox-share.html">Firefox share</a></li>
48<li><a href="RSS-feeds.html">RSS feeds</a></li> 71<li><a href="RSS-feeds.html">RSS feeds</a></li>
49</ul></li> 72</ul></li>
50<li>How To 73<li>How To
51<ul> 74<ul>
52<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
53<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> 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>
54<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 79<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
55<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 80<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
56</ul></li> 81</ul></li>
@@ -62,6 +87,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
62<li><a href="Directory-structure.html">Directory structure</a></li> 87<li><a href="Directory-structure.html">Directory structure</a></li>
63<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
64<li><a href="Plugin-System.html">Plugin System</a></li> 89<li><a href="Plugin-System.html">Plugin System</a></li>
90<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
65<li><a href="Security.html">Security</a></li> 91<li><a href="Security.html">Security</a></li>
66<li><a href="Static-analysis.html">Static analysis</a></li> 92<li><a href="Static-analysis.html">Static analysis</a></li>
67<li><a href="Theming.html">Theming</a></li> 93<li><a href="Theming.html">Theming</a></li>
@@ -77,7 +103,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
77</div> 103</div>
78<h1 id="copy-an-existing-installation-over-ssh-and-serve-it-locally">Copy an existing installation over SSH and serve it locally</h1> 104<h1 id="copy-an-existing-installation-over-ssh-and-serve-it-locally">Copy an existing installation over SSH and serve it locally</h1>
79<p>Example bash script:</p> 105<p>Example bash script:</p>
80<pre class="sourceCode bash"><code class="sourceCode bash"><span class="co">#!/bin/bash</span> 106<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="co">#!/bin/bash</span>
81<span class="co">#Description: Copy a Shaarli installation over SSH/SCP, serve it locally with php-cli</span> 107<span class="co">#Description: Copy a Shaarli installation over SSH/SCP, serve it locally with php-cli</span>
82<span class="co">#Will create a local-shaarli/ directory when you run it, backup your Shaarli there, and serve it locally.</span> 108<span class="co">#Will create a local-shaarli/ directory when you run it, backup your Shaarli there, and serve it locally.</span>
83<span class="co">#Will NOT download linked pages. It&#39;s just a directly usable backup/copy/mirror of your Shaarli</span> 109<span class="co">#Will NOT download linked pages. It&#39;s just a directly usable backup/copy/mirror of your Shaarli</span>
@@ -124,9 +150,9 @@ code > span.er { color: #ff0000; font-weight: bold; }
124 150
125<span class="co">##### MAIN #################</span> 151<span class="co">##### MAIN #################</span>
126 152
127<span class="kw">_main</span></code></pre> 153<span class="kw">_main</span></code></pre></div>
128<p>This outputs:</p> 154<p>This outputs:</p>
129<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">./local-shaarli.sh</span> 155<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">./local-shaarli.sh</span>
130<span class="kw">PHP</span> 5.6.0RC4 Development Server started at Mon Sep 1 21:56:19 2014 156<span class="kw">PHP</span> 5.6.0RC4 Development Server started at Mon Sep 1 21:56:19 2014
131<span class="kw">Listening</span> on http://localhost:7431 157<span class="kw">Listening</span> on http://localhost:7431
132<span class="kw">Document</span> root is /home/user/local-shaarli/shaarli 158<span class="kw">Document</span> root is /home/user/local-shaarli/shaarli
@@ -134,6 +160,6 @@ code > span.er { color: #ff0000; font-weight: bold; }
134 160
135[<span class="kw">Mon</span> Sep 1 21:56:27 2014] ::1:57868 [200]: /[](.html) 161[<span class="kw">Mon</span> Sep 1 21:56:27 2014] ::1:57868 [200]: /[](.html)
136[<span class="kw">Mon</span> Sep 1 21:56:27 2014] ::1:57869 [200]: /index.html[](.html) 162[<span class="kw">Mon</span> Sep 1 21:56:27 2014] ::1:57869 [200]: /index.html[](.html)
137[<span class="kw">Mon</span> Sep 1 21:56:37 2014] ::1:57881 [200]: /...[](.html)</code></pre> 163[<span class="kw">Mon</span> Sep 1 21:56:37 2014] ::1:57881 [200]: /...[](.html)</code></pre></div>
138</body> 164</body>
139</html> 165</html>
diff --git a/doc/Create-and-serve-multiple-Shaarlis-(farm).html b/doc/Create-and-serve-multiple-Shaarlis-(farm).html
new file mode 100644
index 00000000..933144e4
--- /dev/null
+++ b/doc/Create-and-serve-multiple-Shaarlis-(farm).html
@@ -0,0 +1,159 @@
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli – Create and serve multiple Shaarlis (farm)</title>
8 <style type="text/css">code{white-space: pre;}</style>
9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
13table.sourceCode { width: 100%; line-height: 100%; }
14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
15td.sourceCode { padding-left: 5px; }
16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
17code > span.dt { color: #902000; } /* DataType */
18code > span.dv { color: #40a070; } /* DecVal */
19code > span.bn { color: #40a070; } /* BaseN */
20code > span.fl { color: #40a070; } /* Float */
21code > span.ch { color: #4070a0; } /* Char */
22code > span.st { color: #4070a0; } /* String */
23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
24code > span.ot { color: #007020; } /* Other */
25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
26code > span.fu { color: #06287e; } /* Function */
27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
45 </style>
46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
50</head>
51<body>
52<div id="local-sidebar">
53<ul>
54<li><a href="Home.html">Home</a></li>
55<li>Installation
56<ul>
57<li><a href="Download.html">Download</a></li>
58<li><a href="Server-requirements.html">Server requirements</a></li>
59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
66<li><a href="Usage.html">Usage</a>
67<ul>
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</ul></li>
73<li>How To
74<ul>
75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</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>
81</ul></li>
82<li><a href="Troubleshooting.html">Troubleshooting</a></li>
83<li><a href="Development.html">Development</a>
84<ul>
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="Security.html">Security</a></li>
92<li><a href="Static-analysis.html">Static analysis</a></li>
93<li><a href="Theming.html">Theming</a></li>
94<li><a href="Unit-tests.html">Unit tests</a></li>
95</ul></li>
96<li>About
97<ul>
98<li><a href="FAQ.html">FAQ</a></li>
99<li><a href="Community-&amp;-Related-software.html">Community &amp; Related software</a></li>
100<li><a href="TODO.html">TODO</a></li>
101</ul></li>
102</ul>
103</div>
104<h1 id="create-and-serve-multiple-shaarlis-farm">Create and serve multiple Shaarlis (farm)</h1>
105<p>Example bash script (creates multiple shaarli instances and generates an HTML index of them)</p>
106<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="co">#!/bin/bash</span>
107<span class="kw">set</span> <span class="kw">-o</span> errexit
108<span class="kw">set</span> <span class="kw">-o</span> nounset
109
110<span class="co">#config</span>
111<span class="ot">shaarli_base_dir=</span><span class="st">&#39;/var/www/shaarli&#39;</span>
112<span class="ot">accounts=</span><span class="st">&#39;bob john whatever username&#39;</span>
113<span class="ot">shaarli_repo_url=</span><span class="st">&#39;https://github.com/shaarli/Shaarli&#39;</span>
114<span class="ot">ref=</span><span class="st">&quot;master&quot;</span>
115
116<span class="co">#clone multiple shaarli instances</span>
117<span class="kw">if [</span> <span class="ot">!</span> <span class="ot">-d</span> <span class="st">&quot;</span><span class="ot">$shaarli_base_dir</span><span class="st">&quot;</span><span class="kw"> ]</span>; <span class="kw">then</span> <span class="kw">mkdir</span> <span class="st">&quot;</span><span class="ot">$shaarli_base_dir</span><span class="st">&quot;</span><span class="kw">;</span> <span class="kw">fi</span>[]<span class="kw">(.html)</span>
118
119<span class="kw">for</span> <span class="kw">account</span> in <span class="ot">$accounts</span><span class="kw">;</span> <span class="kw">do</span>
120 <span class="kw">if [</span> <span class="ot">-d</span> <span class="st">&quot;</span><span class="ot">$shaarli_base_dir</span><span class="st">/</span><span class="ot">$account</span><span class="st">&quot;</span><span class="kw"> ]</span>;[]<span class="kw">(.html)</span>
121 <span class="kw">then</span> <span class="kw">echo</span> <span class="st">&quot;[info] account </span><span class="ot">$account</span><span class="st"> already exists, skipping&quot;</span><span class="kw">;</span>[]<span class="kw">(.html)</span>
122 <span class="kw">else</span> <span class="kw">echo</span> <span class="st">&quot;[info] creating new account </span><span class="ot">$account</span><span class="st"> ...&quot;</span><span class="kw">;</span> <span class="kw">git</span> clone --quiet <span class="st">&quot;</span><span class="ot">$shaarli_repo_url</span><span class="st">&quot;</span> -b <span class="st">&quot;</span><span class="ot">$ref</span><span class="st">&quot;</span> <span class="st">&quot;</span><span class="ot">$shaarli_base_dir</span><span class="st">/</span><span class="ot">$account</span><span class="st">&quot;</span><span class="kw">;</span> <span class="kw">fi</span>[]<span class="kw">(.html)</span>
123<span class="kw">done</span>
124
125<span class="co">#generate html index of shaarlis</span>
126<span class="ot">htmlhead=</span><span class="st">&#39;&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 4.01//EN&quot; &quot;http://www.w3.org/TR/html4/strict.dtd&quot;&gt;</span>
127<span class="st">&lt;!-- Minimal html template thanks to http://www.sitepoint.com/a-minimal-html-document/ --&gt;</span>
128<span class="st">&lt;html lang=&quot;en&quot;&gt;</span>
129<span class="st"> &lt;head&gt;</span>
130<span class="st"> &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;</span>
131<span class="st"> &lt;title&gt;My Shaarli farm&lt;/title&gt;</span>
132<span class="st"> &lt;style&gt;body {font-family: &quot;Open Sans&quot;}&lt;/style&gt;</span>
133<span class="st"> &lt;/head&gt;</span>
134<span class="st"> &lt;body&gt;</span>
135<span class="st"> &lt;div&gt;</span>
136<span class="st"> &lt;h1&gt;My Shaarli farm&lt;/h1&gt;</span>
137<span class="st"> &lt;ul style=&quot;list-style-type: none;&quot;&gt;&#39;</span>
138
139<span class="ot">accountlinks=</span><span class="st">&#39;&#39;</span>
140
141<span class="ot">htmlfooter=</span><span class="st">&#39;</span>
142<span class="st"> &lt;/ul&gt;</span>
143<span class="st"> &lt;/div&gt;</span>
144<span class="st"> &lt;/body&gt;</span>
145<span class="st">&lt;/html&gt;&#39;</span>
146
147
148
149<span class="kw">for</span> <span class="kw">account</span> in <span class="ot">$accounts</span><span class="kw">;</span> <span class="kw">do</span> <span class="ot">accountlinks=</span><span class="st">&quot;</span><span class="ot">$accountlinks</span><span class="st">\n&lt;li&gt;&lt;a href=</span><span class="dt">\&quot;</span><span class="ot">$account</span><span class="dt">\&quot;</span><span class="st">&gt;</span><span class="ot">$account</span><span class="st">&lt;/a&gt;&lt;/li&gt;&quot;</span>; <span class="kw">done</span>
150<span class="kw">if [</span> <span class="ot">-d</span> <span class="st">&quot;</span><span class="ot">$shaarli_base_dir</span><span class="st">/index.html&quot;</span><span class="kw"> ]</span>; <span class="kw">then</span> <span class="kw">echo</span> <span class="st">&quot;[removing old index.html]&quot;</span><span class="kw">;</span> <span class="kw">rm</span> <span class="st">&quot;</span><span class="ot">$shaarli_base_dir</span><span class="st">/index.html&quot;</span> ]<span class="kw">;</span> <span class="kw">fi</span>[]<span class="kw">(.html)</span>
151<span class="kw">echo</span> <span class="st">&quot;[info] generating new index of shaarlis&quot;</span>[](.html)
152<span class="kw">echo</span> -e <span class="st">&quot;</span><span class="ot">$htmlhead</span><span class="st"> </span><span class="ot">$accountlinks</span><span class="st"> </span><span class="ot">$htmlfooter</span><span class="st">&quot;</span> <span class="kw">&gt;</span> <span class="st">&quot;</span><span class="ot">$shaarli_base_dir</span><span class="st">/index.html&quot;</span>
153<span class="kw">echo</span> <span class="st">&#39;[info] done.&#39;</span>[](.html)
154<span class="kw">echo</span> <span class="st">&quot;[info] list of accounts: </span><span class="ot">$accounts</span><span class="st">&quot;</span>[](.html)
155<span class="kw">echo</span> <span class="st">&quot;[info] contents of </span><span class="ot">$shaarli_base_dir</span><span class="st">:&quot;</span>[](.html)
156<span class="kw">tree</span> -a -L 1 <span class="st">&quot;</span><span class="ot">$shaarli_base_dir</span><span class="st">&quot;</span></code></pre></div>
157<p>This script just serves as an example. More precise or complex (applying custom configuration, etc) automation is possible using configuration management software like <a href="https://www.ansible.com/">Ansible</a><a href=".html"></a></p>
158</body>
159</html>
diff --git a/doc/Create-and-serve-multiple-Shaarlis-(farm).md b/doc/Create-and-serve-multiple-Shaarlis-(farm).md
new file mode 100644
index 00000000..a71f6520
--- /dev/null
+++ b/doc/Create-and-serve-multiple-Shaarlis-(farm).md
@@ -0,0 +1,58 @@
1#Create and serve multiple Shaarlis (farm)
2Example bash script (creates multiple shaarli instances and generates an HTML index of them)
3
4```bash
5#!/bin/bash
6set -o errexit
7set -o nounset
8
9#config
10shaarli_base_dir='/var/www/shaarli'
11accounts='bob john whatever username'
12shaarli_repo_url='https://github.com/shaarli/Shaarli'
13ref="master"
14
15#clone multiple shaarli instances
16if [ ! -d "$shaarli_base_dir" ]; then mkdir "$shaarli_base_dir"; fi[](.html)
17
18for account in $accounts; do
19 if [ -d "$shaarli_base_dir/$account" ];[](.html)
20 then echo "[info] account $account already exists, skipping";[](.html)
21 else echo "[info] creating new account $account ..."; git clone --quiet "$shaarli_repo_url" -b "$ref" "$shaarli_base_dir/$account"; fi[](.html)
22done
23
24#generate html index of shaarlis
25htmlhead='<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
26<!-- Minimal html template thanks to http://www.sitepoint.com/a-minimal-html-document/ -->
27<html lang="en">
28 <head>
29 <meta http-equiv="content-type" content="text/html; charset=utf-8">
30 <title>My Shaarli farm</title>
31 <style>body {font-family: "Open Sans"}</style>
32 </head>
33 <body>
34 <div>
35 <h1>My Shaarli farm</h1>
36 <ul style="list-style-type: none;">'
37
38accountlinks=''
39
40htmlfooter='
41 </ul>
42 </div>
43 </body>
44</html>'
45
46
47
48for account in $accounts; do accountlinks="$accountlinks\n<li><a href=\"$account\">$account</a></li>"; done
49if [ -d "$shaarli_base_dir/index.html" ]; then echo "[removing old index.html]"; rm "$shaarli_base_dir/index.html" ]; fi[](.html)
50echo "[info] generating new index of shaarlis"[](.html)
51echo -e "$htmlhead $accountlinks $htmlfooter" > "$shaarli_base_dir/index.html"
52echo '[info] done.'[](.html)
53echo "[info] list of accounts: $accounts"[](.html)
54echo "[info] contents of $shaarli_base_dir:"[](.html)
55tree -a -L 1 "$shaarli_base_dir"
56```
57
58This script just serves as an example. More precise or complex (applying custom configuration, etc) automation is possible using configuration management software like [Ansible](https://www.ansible.com/)[](.html)
diff --git a/doc/Datastore-hacks.html b/doc/Datastore-hacks.html
index 0bf2a493..88639402 100644
--- a/doc/Datastore-hacks.html
+++ b/doc/Datastore-hacks.html
@@ -4,31 +4,49 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Datastore hacks</title> 7 <title>Shaarli – Datastore hacks</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <style type="text/css"> 9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
13table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
14 margin: 0; padding: 0; vertical-align: baseline; border: none; } 12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
15table.sourceCode { width: 100%; line-height: 100%; } 13table.sourceCode { width: 100%; line-height: 100%; }
16td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } 14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
17td.sourceCode { padding-left: 5px; } 15td.sourceCode { padding-left: 5px; }
18code > span.kw { color: #007020; font-weight: bold; } 16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
19code > span.dt { color: #902000; } 17code > span.dt { color: #902000; } /* DataType */
20code > span.dv { color: #40a070; } 18code > span.dv { color: #40a070; } /* DecVal */
21code > span.bn { color: #40a070; } 19code > span.bn { color: #40a070; } /* BaseN */
22code > span.fl { color: #40a070; } 20code > span.fl { color: #40a070; } /* Float */
23code > span.ch { color: #4070a0; } 21code > span.ch { color: #4070a0; } /* Char */
24code > span.st { color: #4070a0; } 22code > span.st { color: #4070a0; } /* String */
25code > span.co { color: #60a0b0; font-style: italic; } 23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
26code > span.ot { color: #007020; } 24code > span.ot { color: #007020; } /* Other */
27code > span.al { color: #ff0000; font-weight: bold; } 25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
28code > span.fu { color: #06287e; } 26code > span.fu { color: #06287e; } /* Function */
29code > span.er { color: #ff0000; font-weight: bold; } 27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
30 </style> 45 </style>
31 <link rel="stylesheet" href="github-markdown.css"> 46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
32</head> 50</head>
33<body> 51<body>
34<div id="local-sidebar"> 52<div id="local-sidebar">
@@ -39,18 +57,25 @@ code > span.er { color: #ff0000; font-weight: bold; }
39<li><a href="Download.html">Download</a></li> 57<li><a href="Download.html">Download</a></li>
40<li><a href="Server-requirements.html">Server requirements</a></li> 58<li><a href="Server-requirements.html">Server requirements</a></li>
41<li><a href="Server-configuration.html">Server configuration</a></li> 59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
42<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
43</ul></li> 64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
44<li><a href="Usage.html">Usage</a> 66<li><a href="Usage.html">Usage</a>
45<ul> 67<ul>
46<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 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>
47<li><a href="Firefox-share.html">Firefox share</a></li> 70<li><a href="Firefox-share.html">Firefox share</a></li>
48<li><a href="RSS-feeds.html">RSS feeds</a></li> 71<li><a href="RSS-feeds.html">RSS feeds</a></li>
49</ul></li> 72</ul></li>
50<li>How To 73<li>How To
51<ul> 74<ul>
52<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
53<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> 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>
54<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 79<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
55<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 80<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
56</ul></li> 81</ul></li>
@@ -62,6 +87,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
62<li><a href="Directory-structure.html">Directory structure</a></li> 87<li><a href="Directory-structure.html">Directory structure</a></li>
63<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
64<li><a href="Plugin-System.html">Plugin System</a></li> 89<li><a href="Plugin-System.html">Plugin System</a></li>
90<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
65<li><a href="Security.html">Security</a></li> 91<li><a href="Security.html">Security</a></li>
66<li><a href="Static-analysis.html">Static analysis</a></li> 92<li><a href="Static-analysis.html">Static analysis</a></li>
67<li><a href="Theming.html">Theming</a></li> 93<li><a href="Theming.html">Theming</a></li>
@@ -78,17 +104,19 @@ code > span.er { color: #ff0000; font-weight: bold; }
78<h1 id="datastore-hacks">Datastore hacks</h1> 104<h1 id="datastore-hacks">Datastore hacks</h1>
79<h3 id="decode-datastore-content">Decode datastore content</h3> 105<h3 id="decode-datastore-content">Decode datastore content</h3>
80<p>To display the array representing the data saved in <code>data/datastore.php</code>, use the following snippet:</p> 106<p>To display the array representing the data saved in <code>data/datastore.php</code>, use the following snippet:</p>
81<pre class="sourceCode php"><code class="sourceCode php"><span class="kw">$data</span> = <span class="st">&quot;tZNdb9MwFIb... &lt;Commented content inside datastore.php&gt;&quot;</span><span class="ot">;</span> 107<div class="sourceCode"><pre class="sourceCode php"><code class="sourceCode php"><span class="kw">$data</span> = <span class="st">&quot;tZNdb9MwFIb... &lt;Commented content inside datastore.php&gt;&quot;</span><span class="ot">;</span>
82<span class="kw">$out</span> = <span class="fu">unserialize</span><span class="ot">(</span><span class="fu">gzinflate</span><span class="ot">(</span><span class="fu">base64_decode</span><span class="ot">(</span><span class="kw">$data</span><span class="ot">)));</span> 108<span class="kw">$out</span> = <span class="fu">unserialize</span><span class="ot">(</span><span class="fu">gzinflate</span><span class="ot">(</span><span class="fu">base64_decode</span><span class="ot">(</span><span class="kw">$data</span><span class="ot">)));</span>
83<span class="fu">echo</span> <span class="st">&quot;&lt;pre&gt;&quot;</span><span class="ot">;</span> <span class="co">// Pretty printing is love, pretty printing is life</span> 109<span class="fu">echo</span> <span class="st">&quot;&lt;pre&gt;&quot;</span><span class="ot">;</span> <span class="co">// Pretty printing is love, pretty printing is life</span>
84<span class="fu">print_r</span><span class="ot">(</span><span class="kw">$out</span><span class="ot">);</span> 110<span class="fu">print_r</span><span class="ot">(</span><span class="kw">$out</span><span class="ot">);</span>
85<span class="fu">echo</span> <span class="st">&quot;&lt;/pre&gt;&quot;</span><span class="ot">;</span> 111<span class="fu">echo</span> <span class="st">&quot;&lt;/pre&gt;&quot;</span><span class="ot">;</span>
86<span class="fu">exit</span><span class="ot">;</span></code></pre> 112<span class="fu">exit</span><span class="ot">;</span></code></pre></div>
87<p>This will output the internal representation of the datastore, &quot;unobfuscated&quot; (if this can really be considered obfuscation).</p> 113<p>This will output the internal representation of the datastore, &quot;unobfuscated&quot; (if this can really be considered obfuscation).</p>
114<p>Alternatively, you can transform to JSON format (and pretty-print if you have <code>jq</code> installed):</p>
115<pre><code>php -r &#39;print(json_encode(unserialize(gzinflate(base64_decode(preg_replace(&quot;!.*/\* (.+) \*/.*!&quot;, &quot;$1&quot;, file_get_contents(&quot;data/datastore.php&quot;)))))));&#39; | jq .</code></pre>
88<h3 id="changing-the-timestamp-for-a-link">Changing the timestamp for a link</h3> 116<h3 id="changing-the-timestamp-for-a-link">Changing the timestamp for a link</h3>
89<ul> 117<ul>
90<li>Look for <code>&lt;input type=&quot;hidden&quot; name=&quot;lf_linkdate&quot; value=&quot;{$link.linkdate}&quot;&gt;</code> in <code>tpl/editlink.tpl</code> (line 14)</li> 118<li>Look for <code>&lt;input type=&quot;hidden&quot; name=&quot;lf_linkdate&quot; value=&quot;{$link.linkdate}&quot;&gt;</code> in <code>tpl/editlink.tpl</code> (line 14)</li>
91<li>Remove <code>type=&quot;hidden&quot;</code> from this line</li> 119<li>Replace <code>type=&quot;hidden&quot;</code> with <code>type=&quot;text&quot;</code> from this line</li>
92<li>A new date/time field becomes available in the edit/new link dialog.</li> 120<li>A new date/time field becomes available in the edit/new link dialog.</li>
93<li>You can set the timestamp manually by entering it in the format <code>YYYMMDD_HHMMS</code>.</li> 121<li>You can set the timestamp manually by entering it in the format <code>YYYMMDD_HHMMS</code>.</li>
94</ul> 122</ul>
diff --git a/doc/Datastore-hacks.md b/doc/Datastore-hacks.md
index 33aa2223..ef6f6d50 100644
--- a/doc/Datastore-hacks.md
+++ b/doc/Datastore-hacks.md
@@ -12,8 +12,13 @@ exit;
12``` 12```
13This will output the internal representation of the datastore, "unobfuscated" (if this can really be considered obfuscation). 13This will output the internal representation of the datastore, "unobfuscated" (if this can really be considered obfuscation).
14 14
15Alternatively, you can transform to JSON format (and pretty-print if you have `jq` installed):
16```
17php -r 'print(json_encode(unserialize(gzinflate(base64_decode(preg_replace("!.*/\* (.+) \*/.*!", "$1", file_get_contents("data/datastore.php")))))));' | jq .
18```
19
15### Changing the timestamp for a link 20### Changing the timestamp for a link
16* Look for `<input type="hidden" name="lf_linkdate" value="{$link.linkdate}">` in `tpl/editlink.tpl` (line 14) 21* Look for `<input type="hidden" name="lf_linkdate" value="{$link.linkdate}">` in `tpl/editlink.tpl` (line 14)
17* Remove `type="hidden"` from this line 22* Replace `type="hidden"` with `type="text"` from this line
18* A new date/time field becomes available in the edit/new link dialog. 23* A new date/time field becomes available in the edit/new link dialog.
19* You can set the timestamp manually by entering it in the format `YYYMMDD_HHMMS`. 24* You can set the timestamp manually by entering it in the format `YYYMMDD_HHMMS`.
diff --git a/doc/Development.html b/doc/Development.html
index 88cf5854..2eacff94 100644
--- a/doc/Development.html
+++ b/doc/Development.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Development</title> 7 <title>Shaarli – Development</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
@@ -92,7 +100,7 @@
92</ul> 100</ul>
93<p>After all jobs have finished, Travis returns the results to GitHub:</p> 101<p>After all jobs have finished, Travis returns the results to GitHub:</p>
94<ul> 102<ul>
95<li>a status icon represents the result for the <code>master</code> branch: <a href="(https://api.travis-ci.org/shaarli/Shaarli.svg)](https://travis-ci.org/shaarli/Shaarli).html"><img src="https://travis-ci.org/shaarli/Shaarli" alt="(https://api.travis-ci.org/shaarli/Shaarli.svg)" /></a></li> 103<li>a status icon represents the result for the <code>master</code> branch: <a href="(https://api.travis-ci.org/shaarli/Shaarli.svg)%5D(https://travis-ci.org/shaarli/Shaarli).html"><img src="https://travis-ci.org/shaarli/Shaarli" alt="(https://api.travis-ci.org/shaarli/Shaarli.svg)" /></a></li>
96<li>Pull Requests are updated with the Travis result 104<li>Pull Requests are updated with the Travis result
97<ul> 105<ul>
98<li>Green: all tests have passed</li> 106<li>Green: all tests have passed</li>
diff --git a/doc/Directory-structure.html b/doc/Directory-structure.html
index 7015923c..003d4d94 100644
--- a/doc/Directory-structure.html
+++ b/doc/Directory-structure.html
@@ -4,31 +4,49 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Directory structure</title> 7 <title>Shaarli – Directory structure</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <style type="text/css"> 9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
13table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
14 margin: 0; padding: 0; vertical-align: baseline; border: none; } 12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
15table.sourceCode { width: 100%; line-height: 100%; } 13table.sourceCode { width: 100%; line-height: 100%; }
16td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } 14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
17td.sourceCode { padding-left: 5px; } 15td.sourceCode { padding-left: 5px; }
18code > span.kw { color: #007020; font-weight: bold; } 16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
19code > span.dt { color: #902000; } 17code > span.dt { color: #902000; } /* DataType */
20code > span.dv { color: #40a070; } 18code > span.dv { color: #40a070; } /* DecVal */
21code > span.bn { color: #40a070; } 19code > span.bn { color: #40a070; } /* BaseN */
22code > span.fl { color: #40a070; } 20code > span.fl { color: #40a070; } /* Float */
23code > span.ch { color: #4070a0; } 21code > span.ch { color: #4070a0; } /* Char */
24code > span.st { color: #4070a0; } 22code > span.st { color: #4070a0; } /* String */
25code > span.co { color: #60a0b0; font-style: italic; } 23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
26code > span.ot { color: #007020; } 24code > span.ot { color: #007020; } /* Other */
27code > span.al { color: #ff0000; font-weight: bold; } 25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
28code > span.fu { color: #06287e; } 26code > span.fu { color: #06287e; } /* Function */
29code > span.er { color: #ff0000; font-weight: bold; } 27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
30 </style> 45 </style>
31 <link rel="stylesheet" href="github-markdown.css"> 46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
32</head> 50</head>
33<body> 51<body>
34<div id="local-sidebar"> 52<div id="local-sidebar">
@@ -39,18 +57,25 @@ code > span.er { color: #ff0000; font-weight: bold; }
39<li><a href="Download.html">Download</a></li> 57<li><a href="Download.html">Download</a></li>
40<li><a href="Server-requirements.html">Server requirements</a></li> 58<li><a href="Server-requirements.html">Server requirements</a></li>
41<li><a href="Server-configuration.html">Server configuration</a></li> 59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
42<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
43</ul></li> 64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
44<li><a href="Usage.html">Usage</a> 66<li><a href="Usage.html">Usage</a>
45<ul> 67<ul>
46<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 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>
47<li><a href="Firefox-share.html">Firefox share</a></li> 70<li><a href="Firefox-share.html">Firefox share</a></li>
48<li><a href="RSS-feeds.html">RSS feeds</a></li> 71<li><a href="RSS-feeds.html">RSS feeds</a></li>
49</ul></li> 72</ul></li>
50<li>How To 73<li>How To
51<ul> 74<ul>
52<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
53<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> 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>
54<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 79<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
55<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 80<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
56</ul></li> 81</ul></li>
@@ -62,6 +87,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
62<li><a href="Directory-structure.html">Directory structure</a></li> 87<li><a href="Directory-structure.html">Directory structure</a></li>
63<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
64<li><a href="Plugin-System.html">Plugin System</a></li> 89<li><a href="Plugin-System.html">Plugin System</a></li>
90<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
65<li><a href="Security.html">Security</a></li> 91<li><a href="Security.html">Security</a></li>
66<li><a href="Static-analysis.html">Static analysis</a></li> 92<li><a href="Static-analysis.html">Static analysis</a></li>
67<li><a href="Theming.html">Theming</a></li> 93<li><a href="Theming.html">Theming</a></li>
@@ -77,7 +103,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
77</div> 103</div>
78<h1 id="directory-structure">Directory structure</h1> 104<h1 id="directory-structure">Directory structure</h1>
79<p>Here is the directory structure of Shaarli and the purpose of the different files:</p> 105<p>Here is the directory structure of Shaarli and the purpose of the different files:</p>
80<pre class="sourceCode bash"><code class="sourceCode bash"> <span class="kw">index.php</span> <span class="co"># Main program</span> 106<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"> <span class="kw">index.php</span> <span class="co"># Main program</span>
81 <span class="kw">application/</span> <span class="co"># Shaarli classes</span> 107 <span class="kw">application/</span> <span class="co"># Shaarli classes</span>
82 ├── <span class="kw">LinkDB.php</span> 108 ├── <span class="kw">LinkDB.php</span>
83 └── <span class="kw">Utils.php</span> 109 └── <span class="kw">Utils.php</span>
@@ -104,6 +130,6 @@ code > span.er { color: #ff0000; font-weight: bold; }
104 <span class="kw">cache/</span> <span class="co"># thumbnails cache</span> 130 <span class="kw">cache/</span> <span class="co"># thumbnails cache</span>
105 <span class="co"># This directory is automatically created. You can erase it anytime you want.</span> 131 <span class="co"># This directory is automatically created. You can erase it anytime you want.</span>
106 <span class="kw">tmp/</span> <span class="co"># Temporary directory for compiled RainTPL templates.</span> 132 <span class="kw">tmp/</span> <span class="co"># Temporary directory for compiled RainTPL templates.</span>
107 <span class="co"># This directory is automatically created. You can erase it anytime you want.</span></code></pre> 133 <span class="co"># This directory is automatically created. You can erase it anytime you want.</span></code></pre></div>
108</body> 134</body>
109</html> 135</html>
diff --git a/doc/Docker.html b/doc/Docker.html
new file mode 100644
index 00000000..a443d100
--- /dev/null
+++ b/doc/Docker.html
@@ -0,0 +1,244 @@
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli – Docker</title>
8 <style type="text/css">code{white-space: pre;}</style>
9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
13table.sourceCode { width: 100%; line-height: 100%; }
14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
15td.sourceCode { padding-left: 5px; }
16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
17code > span.dt { color: #902000; } /* DataType */
18code > span.dv { color: #40a070; } /* DecVal */
19code > span.bn { color: #40a070; } /* BaseN */
20code > span.fl { color: #40a070; } /* Float */
21code > span.ch { color: #4070a0; } /* Char */
22code > span.st { color: #4070a0; } /* String */
23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
24code > span.ot { color: #007020; } /* Other */
25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
26code > span.fu { color: #06287e; } /* Function */
27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
45 </style>
46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
50</head>
51<body>
52<div id="local-sidebar">
53<ul>
54<li><a href="Home.html">Home</a></li>
55<li>Installation
56<ul>
57<li><a href="Download.html">Download</a></li>
58<li><a href="Server-requirements.html">Server requirements</a></li>
59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
66<li><a href="Usage.html">Usage</a>
67<ul>
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</ul></li>
73<li>How To
74<ul>
75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</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>
81</ul></li>
82<li><a href="Troubleshooting.html">Troubleshooting</a></li>
83<li><a href="Development.html">Development</a>
84<ul>
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="Security.html">Security</a></li>
92<li><a href="Static-analysis.html">Static analysis</a></li>
93<li><a href="Theming.html">Theming</a></li>
94<li><a href="Unit-tests.html">Unit tests</a></li>
95</ul></li>
96<li>About
97<ul>
98<li><a href="FAQ.html">FAQ</a></li>
99<li><a href="Community-&amp;-Related-software.html">Community &amp; Related software</a></li>
100<li><a href="TODO.html">TODO</a></li>
101</ul></li>
102</ul>
103</div>
104<h1 id="docker">Docker</h1>
105<ul>
106<li><a href="#docker-usage">Docker usage</a><a href=".html"></a></li>
107<li><a href="#get-and-run-a-shaarli-image">Get and run a Shaarli image</a><a href=".html"></a></li>
108<li><a href="#resources">Resources</a><a href=".html"></a></li>
109</ul>
110<h2 id="docker-usage">Docker usage</h2>
111<h3 id="basics">Basics</h3>
112<p>Install <a href="https://www.docker.com/">Docker</a>, by following the instructions relevant<a href=".html"></a><br />
113to your OS / distribution, and start the service.</p>
114<h4 id="search-an-image-on-dockerhub">Search an image on <a href="https://hub.docker.com/">DockerHub</a><a href=".html"></a></h4>
115<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">docker</span> search debian
116
117<span class="kw">NAME</span> DESCRIPTION STARS OFFICIAL AUTOMATED
118<span class="kw">ubuntu</span> Ubuntu is a Debian-based Linux operating s... 2065 [OK][](.html)
119<span class="kw">debian</span> Debian is a Linux distribution that<span class="st">&#39;s comp... 603 [OK][](.html)</span>
120<span class="st">google/debian 47 [OK][](.html)</span></code></pre></div>
121<h4 id="show-available-tags-for-a-repository">Show available tags for a repository</h4>
122<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">curl</span> https://index.docker.io/v1/repositories/debian/tags <span class="kw">|</span> <span class="kw">python</span> -m json.tool
123
124<span class="kw">%</span> Total % Received % Xferd Average Speed Time Time Time Current
125<span class="kw">Dload</span> Upload Total Spent Left Speed
126<span class="kw">100</span> 1283 0 1283 0 0 433 0 --:--:-- 0:00:02 --:--:-- 433</code></pre></div>
127<p>Sample output:</p>
128<div class="sourceCode"><pre class="sourceCode json"><code class="sourceCode json"><span class="ot">[[]</span><span class="er">(.html)</span>
129 <span class="fu">{</span>
130 <span class="dt">&quot;layer&quot;</span><span class="fu">:</span> <span class="st">&quot;85a02782&quot;</span><span class="fu">,</span>
131 <span class="dt">&quot;name&quot;</span><span class="fu">:</span> <span class="st">&quot;stretch&quot;</span>
132 <span class="fu">}</span><span class="ot">,</span>
133 <span class="fu">{</span>
134 <span class="dt">&quot;layer&quot;</span><span class="fu">:</span> <span class="st">&quot;59abecbc&quot;</span><span class="fu">,</span>
135 <span class="dt">&quot;name&quot;</span><span class="fu">:</span> <span class="st">&quot;testing&quot;</span>
136 <span class="fu">}</span><span class="ot">,</span>
137 <span class="fu">{</span>
138 <span class="dt">&quot;layer&quot;</span><span class="fu">:</span> <span class="st">&quot;bf0fd686&quot;</span><span class="fu">,</span>
139 <span class="dt">&quot;name&quot;</span><span class="fu">:</span> <span class="st">&quot;unstable&quot;</span>
140 <span class="fu">}</span><span class="ot">,</span>
141 <span class="fu">{</span>
142 <span class="dt">&quot;layer&quot;</span><span class="fu">:</span> <span class="st">&quot;60c52dbe&quot;</span><span class="fu">,</span>
143 <span class="dt">&quot;name&quot;</span><span class="fu">:</span> <span class="st">&quot;wheezy&quot;</span>
144 <span class="fu">}</span><span class="ot">,</span>
145 <span class="fu">{</span>
146 <span class="dt">&quot;layer&quot;</span><span class="fu">:</span> <span class="st">&quot;c5b806fe&quot;</span><span class="fu">,</span>
147 <span class="dt">&quot;name&quot;</span><span class="fu">:</span> <span class="st">&quot;wheezy-backports&quot;</span>
148 <span class="fu">}</span>
149<span class="ot">]</span></code></pre></div>
150<h4 id="pull-an-image-from-dockerhub">Pull an image from DockerHub</h4>
151<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">docker</span> pull repository[:tag][](.html)
152
153$ <span class="kw">docker</span> pull debian:wheezy
154<span class="kw">wheezy</span>: Pulling from debian
155<span class="kw">4c8cbfd2973e</span>: Pull complete
156<span class="kw">60c52dbe9d91</span>: Pull complete
157<span class="kw">Digest</span>: sha256:c584131da2ac1948aa3e66468a4424b6aea2f33acba7cec0b631bdb56254c4fe
158<span class="kw">Status</span>: Downloaded newer image for debian:wheezy</code></pre></div>
159<h2 id="get-and-run-a-shaarli-image">Get and run a Shaarli image</h2>
160<h3 id="dockerhub-repository">DockerHub repository</h3>
161<p>The images can be found in the <a href="https://hub.docker.com/r/shaarli/shaarli/"><code>shaarli/shaarli</code></a><a href=".html"></a><br />
162repository.</p>
163<h3 id="available-image-tags">Available image tags</h3>
164<ul>
165<li><code>latest</code>: master branch (tarball release)</li>
166<li><code>stable</code>: stable branch (tarball release)</li>
167<li><code>dev</code>: master branch (Git clone)</li>
168</ul>
169<p>All images rely on:</p>
170<ul>
171<li><a href="https://hub.docker.com/_/debian/">Debian 8 Jessie</a><a href=".html"></a></li>
172<li><a href="http://php-fpm.org/">PHP5-FPM</a><a href=".html"></a></li>
173<li><a href="http://nginx.org/">Nginx</a><a href=".html"></a></li>
174</ul>
175<h3 id="download-from-dockerhub">Download from DockerHub</h3>
176<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">docker</span> pull shaarli/shaarli
177<span class="kw">latest</span>: Pulling from shaarli/shaarli
178<span class="kw">32716d9fcddb</span>: Pull complete
179<span class="kw">84899d045435</span>: Pull complete
180<span class="kw">4b6ad7444763</span>: Pull complete
181<span class="kw">e0345ef7a3e0</span>: Pull complete
182<span class="kw">5c1dd344094f</span>: Pull complete
183<span class="kw">6422305a200b</span>: Pull complete
184<span class="kw">7d63f861dbef</span>: Pull complete
185<span class="kw">3eb97210645c</span>: Pull complete
186<span class="kw">869319d746ff</span>: Already exists
187<span class="kw">869319d746ff</span>: Pulling fs layer
188<span class="kw">902b87aaaec9</span>: Already exists
189<span class="kw">Digest</span>: sha256:f836b4627b958b3f83f59c332f22f02fcd495ace3056f2be2c4912bd8704cc98
190<span class="kw">Status</span>: Downloaded newer image for shaarli/shaarli:latest</code></pre></div>
191<h3 id="create-and-start-a-new-container-from-the-image">Create and start a new container from the image</h3>
192<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="co"># map the host&#39;s :8000 port to the container&#39;s :80 port</span>
193$ <span class="kw">docker</span> create -p 8000:80 shaarli/shaarli
194<span class="kw">d40b7af693d678958adedfb88f87d6ea0237186c23de5c4102a55a8fcb499101</span>
195
196<span class="co"># launch the container in the background</span>
197$ <span class="kw">docker</span> start d40b7af693d678958adedfb88f87d6ea0237186c23de5c4102a55a8fcb499101
198<span class="kw">d40b7af693d678958adedfb88f87d6ea0237186c23de5c4102a55a8fcb499101</span>
199
200<span class="co"># list active containers</span>
201$ <span class="kw">docker</span> ps
202<span class="kw">CONTAINER</span> ID IMAGE COMMAND CREATED STATUS PORTS NAMES
203<span class="kw">d40b7af693d6</span> shaarli/shaarli /usr/bin/supervisor 15 seconds ago Up 4 seconds 0.0.0.0:8000-<span class="kw">&gt;</span>80/tcp backstabbing_galileo</code></pre></div>
204<h3 id="stop-and-destroy-a-container">Stop and destroy a container</h3>
205<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">docker</span> stop backstabbing_galileo <span class="co"># those docker guys are really rude to physicists!</span>
206<span class="kw">backstabbing_galileo</span>
207
208<span class="co"># check the container is stopped</span>
209$ <span class="kw">docker</span> ps
210<span class="kw">CONTAINER</span> ID IMAGE COMMAND CREATED STATUS PORTS NAMES
211
212<span class="co"># list ALL containers</span>
213$ <span class="kw">docker</span> ps -a
214<span class="kw">CONTAINER</span> ID IMAGE COMMAND CREATED STATUS PORTS NAMES
215<span class="kw">d40b7af693d6</span> shaarli/shaarli /usr/bin/supervisor 5 minutes ago Exited (0) <span class="kw">48</span> seconds ago backstabbing_galileo
216
217<span class="co"># destroy the container</span>
218$ <span class="kw">docker</span> rm backstabbing_galileo <span class="co"># let&#39;s put an end to these barbarian practices</span>
219<span class="kw">backstabbing_galileo</span>
220
221$ <span class="kw">docker</span> ps -a
222<span class="kw">CONTAINER</span> ID IMAGE COMMAND CREATED STATUS PORTS NAMES</code></pre></div>
223<h2 id="resources">Resources</h2>
224<h3 id="docker-1">Docker</h3>
225<ul>
226<li><a href="http://blog.thoward37.me/articles/where-are-docker-images-stored/">Where are Docker images stored?</a><a href=".html"></a></li>
227<li><a href="https://docs.docker.com/reference/builder/">Dockerfile reference</a><a href=".html"></a></li>
228<li><a href="https://docs.docker.com/articles/dockerfile_best-practices/">Dockerfile best practices</a><a href=".html"></a></li>
229<li><a href="https://docs.docker.com/userguide/dockervolumes/">Volumes</a><a href=".html"></a></li>
230</ul>
231<h3 id="dockerhub">DockerHub</h3>
232<ul>
233<li><a href="https://docs.docker.com/userguide/dockerrepos/">Repositories</a><a href=".html"></a></li>
234<li><a href="https://docs.docker.com/docker-hub/orgs/">Teams and organizations</a><a href=".html"></a></li>
235<li><a href="https://docs.docker.com/docker-hub/github/">GitHub automated build</a><a href=".html"></a></li>
236</ul>
237<h3 id="service-management">Service management</h3>
238<ul>
239<li><a href="https://docs.docker.com/articles/using_supervisord/">Using supervisord</a><a href=".html"></a></li>
240<li><a href="http://nginx.org/en/docs/ngx_core_module.html#daemon">Nginx in the foreground</a><a href=".html"></a></li>
241<li><a href="http://supervisord.org/">supervisord</a><a href=".html"></a></li>
242</ul>
243</body>
244</html>
diff --git a/doc/Docker.md b/doc/Docker.md
new file mode 100644
index 00000000..1faa7904
--- /dev/null
+++ b/doc/Docker.md
@@ -0,0 +1,157 @@
1#Docker
2- [Docker usage](#docker-usage)[](.html)
3- [Get and run a Shaarli image](#get-and-run-a-shaarli-image)[](.html)
4- [Resources](#resources)[](.html)
5
6## Docker usage
7### Basics
8Install [Docker](https://www.docker.com/), by following the instructions relevant[](.html)
9to your OS / distribution, and start the service.
10
11#### Search an image on [DockerHub](https://hub.docker.com/)[](.html)
12
13```bash
14$ docker search debian
15
16NAME DESCRIPTION STARS OFFICIAL AUTOMATED
17ubuntu Ubuntu is a Debian-based Linux operating s... 2065 [OK][](.html)
18debian Debian is a Linux distribution that's comp... 603 [OK][](.html)
19google/debian 47 [OK][](.html)
20```
21
22#### Show available tags for a repository
23```bash
24$ curl https://index.docker.io/v1/repositories/debian/tags | python -m json.tool
25
26% Total % Received % Xferd Average Speed Time Time Time Current
27Dload Upload Total Spent Left Speed
28100 1283 0 1283 0 0 433 0 --:--:-- 0:00:02 --:--:-- 433
29```
30
31Sample output:
32```json
33[[](.html)
34 {
35 "layer": "85a02782",
36 "name": "stretch"
37 },
38 {
39 "layer": "59abecbc",
40 "name": "testing"
41 },
42 {
43 "layer": "bf0fd686",
44 "name": "unstable"
45 },
46 {
47 "layer": "60c52dbe",
48 "name": "wheezy"
49 },
50 {
51 "layer": "c5b806fe",
52 "name": "wheezy-backports"
53 }
54]
55
56```
57
58#### Pull an image from DockerHub
59```bash
60$ docker pull repository[:tag][](.html)
61
62$ docker pull debian:wheezy
63wheezy: Pulling from debian
644c8cbfd2973e: Pull complete
6560c52dbe9d91: Pull complete
66Digest: sha256:c584131da2ac1948aa3e66468a4424b6aea2f33acba7cec0b631bdb56254c4fe
67Status: Downloaded newer image for debian:wheezy
68```
69
70## Get and run a Shaarli image
71### DockerHub repository
72The images can be found in the [`shaarli/shaarli`](https://hub.docker.com/r/shaarli/shaarli/)[](.html)
73repository.
74
75### Available image tags
76- `latest`: master branch (tarball release)
77- `stable`: stable branch (tarball release)
78- `dev`: master branch (Git clone)
79
80All images rely on:
81- [Debian 8 Jessie](https://hub.docker.com/_/debian/)[](.html)
82- [PHP5-FPM](http://php-fpm.org/)[](.html)
83- [Nginx](http://nginx.org/)[](.html)
84
85### Download from DockerHub
86```bash
87$ docker pull shaarli/shaarli
88latest: Pulling from shaarli/shaarli
8932716d9fcddb: Pull complete
9084899d045435: Pull complete
914b6ad7444763: Pull complete
92e0345ef7a3e0: Pull complete
935c1dd344094f: Pull complete
946422305a200b: Pull complete
957d63f861dbef: Pull complete
963eb97210645c: Pull complete
97869319d746ff: Already exists
98869319d746ff: Pulling fs layer
99902b87aaaec9: Already exists
100Digest: sha256:f836b4627b958b3f83f59c332f22f02fcd495ace3056f2be2c4912bd8704cc98
101Status: Downloaded newer image for shaarli/shaarli:latest
102```
103
104### Create and start a new container from the image
105```bash
106# map the host's :8000 port to the container's :80 port
107$ docker create -p 8000:80 shaarli/shaarli
108d40b7af693d678958adedfb88f87d6ea0237186c23de5c4102a55a8fcb499101
109
110# launch the container in the background
111$ docker start d40b7af693d678958adedfb88f87d6ea0237186c23de5c4102a55a8fcb499101
112d40b7af693d678958adedfb88f87d6ea0237186c23de5c4102a55a8fcb499101
113
114# list active containers
115$ docker ps
116CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
117d40b7af693d6 shaarli/shaarli /usr/bin/supervisor 15 seconds ago Up 4 seconds 0.0.0.0:8000->80/tcp backstabbing_galileo
118```
119
120### Stop and destroy a container
121```bash
122$ docker stop backstabbing_galileo # those docker guys are really rude to physicists!
123backstabbing_galileo
124
125# check the container is stopped
126$ docker ps
127CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
128
129# list ALL containers
130$ docker ps -a
131CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
132d40b7af693d6 shaarli/shaarli /usr/bin/supervisor 5 minutes ago Exited (0) 48 seconds ago backstabbing_galileo
133
134# destroy the container
135$ docker rm backstabbing_galileo # let's put an end to these barbarian practices
136backstabbing_galileo
137
138$ docker ps -a
139CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
140```
141
142## Resources
143### Docker
144- [Where are Docker images stored?](http://blog.thoward37.me/articles/where-are-docker-images-stored/)[](.html)
145- [Dockerfile reference](https://docs.docker.com/reference/builder/)[](.html)
146- [Dockerfile best practices](https://docs.docker.com/articles/dockerfile_best-practices/)[](.html)
147- [Volumes](https://docs.docker.com/userguide/dockervolumes/)[](.html)
148
149### DockerHub
150- [Repositories](https://docs.docker.com/userguide/dockerrepos/)[](.html)
151- [Teams and organizations](https://docs.docker.com/docker-hub/orgs/)[](.html)
152- [GitHub automated build](https://docs.docker.com/docker-hub/github/)[](.html)
153
154### Service management
155- [Using supervisord](https://docs.docker.com/articles/using_supervisord/)[](.html)
156- [Nginx in the foreground](http://nginx.org/en/docs/ngx_core_module.html#daemon)[](.html)
157- [supervisord](http://supervisord.org/)[](.html)
diff --git a/doc/Download-CSS-styles-from-an-OPML-list.html b/doc/Download-CSS-styles-from-an-OPML-list.html
index 7d7fe968..22771502 100644
--- a/doc/Download-CSS-styles-from-an-OPML-list.html
+++ b/doc/Download-CSS-styles-from-an-OPML-list.html
@@ -4,31 +4,49 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Download CSS styles from an OPML list</title> 7 <title>Shaarli – Download CSS styles from an OPML list</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <style type="text/css"> 9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
13table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
14 margin: 0; padding: 0; vertical-align: baseline; border: none; } 12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
15table.sourceCode { width: 100%; line-height: 100%; } 13table.sourceCode { width: 100%; line-height: 100%; }
16td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } 14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
17td.sourceCode { padding-left: 5px; } 15td.sourceCode { padding-left: 5px; }
18code > span.kw { color: #007020; font-weight: bold; } 16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
19code > span.dt { color: #902000; } 17code > span.dt { color: #902000; } /* DataType */
20code > span.dv { color: #40a070; } 18code > span.dv { color: #40a070; } /* DecVal */
21code > span.bn { color: #40a070; } 19code > span.bn { color: #40a070; } /* BaseN */
22code > span.fl { color: #40a070; } 20code > span.fl { color: #40a070; } /* Float */
23code > span.ch { color: #4070a0; } 21code > span.ch { color: #4070a0; } /* Char */
24code > span.st { color: #4070a0; } 22code > span.st { color: #4070a0; } /* String */
25code > span.co { color: #60a0b0; font-style: italic; } 23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
26code > span.ot { color: #007020; } 24code > span.ot { color: #007020; } /* Other */
27code > span.al { color: #ff0000; font-weight: bold; } 25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
28code > span.fu { color: #06287e; } 26code > span.fu { color: #06287e; } /* Function */
29code > span.er { color: #ff0000; font-weight: bold; } 27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
30 </style> 45 </style>
31 <link rel="stylesheet" href="github-markdown.css"> 46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
32</head> 50</head>
33<body> 51<body>
34<div id="local-sidebar"> 52<div id="local-sidebar">
@@ -39,18 +57,25 @@ code > span.er { color: #ff0000; font-weight: bold; }
39<li><a href="Download.html">Download</a></li> 57<li><a href="Download.html">Download</a></li>
40<li><a href="Server-requirements.html">Server requirements</a></li> 58<li><a href="Server-requirements.html">Server requirements</a></li>
41<li><a href="Server-configuration.html">Server configuration</a></li> 59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
42<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
43</ul></li> 64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
44<li><a href="Usage.html">Usage</a> 66<li><a href="Usage.html">Usage</a>
45<ul> 67<ul>
46<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 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>
47<li><a href="Firefox-share.html">Firefox share</a></li> 70<li><a href="Firefox-share.html">Firefox share</a></li>
48<li><a href="RSS-feeds.html">RSS feeds</a></li> 71<li><a href="RSS-feeds.html">RSS feeds</a></li>
49</ul></li> 72</ul></li>
50<li>How To 73<li>How To
51<ul> 74<ul>
52<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
53<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> 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>
54<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 79<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
55<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 80<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
56</ul></li> 81</ul></li>
@@ -62,6 +87,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
62<li><a href="Directory-structure.html">Directory structure</a></li> 87<li><a href="Directory-structure.html">Directory structure</a></li>
63<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
64<li><a href="Plugin-System.html">Plugin System</a></li> 89<li><a href="Plugin-System.html">Plugin System</a></li>
90<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
65<li><a href="Security.html">Security</a></li> 91<li><a href="Security.html">Security</a></li>
66<li><a href="Static-analysis.html">Static analysis</a></li> 92<li><a href="Static-analysis.html">Static analysis</a></li>
67<li><a href="Theming.html">Theming</a></li> 93<li><a href="Theming.html">Theming</a></li>
@@ -78,7 +104,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
78<h1 id="download-css-styles-from-an-opml-list">Download CSS styles from an OPML list</h1> 104<h1 id="download-css-styles-from-an-opml-list">Download CSS styles from an OPML list</h1>
79<h3 id="download-css-styles-for-shaarlis-listed-in-an-opml-file">Download CSS styles for shaarlis listed in an opml file</h3> 105<h3 id="download-css-styles-for-shaarlis-listed-in-an-opml-file">Download CSS styles for shaarlis listed in an opml file</h3>
80<p>Example php script:</p> 106<p>Example php script:</p>
81<pre class="sourceCode php"><code class="sourceCode php">&lt;!---- <span class="ot">?</span>php --&gt; 107<div class="sourceCode"><pre class="sourceCode php"><code class="sourceCode php">&lt;!---- <span class="ot">?</span>php --&gt;
82&lt;!---- Copyright <span class="ot">(</span>c<span class="ot">)</span> <span class="dv">2014</span> Nicolas Delsaux <span class="ot">(</span>https<span class="ot">:</span><span class="co">//github.com/Riduidel) --&gt;</span> 108&lt;!---- Copyright <span class="ot">(</span>c<span class="ot">)</span> <span class="dv">2014</span> Nicolas Delsaux <span class="ot">(</span>https<span class="ot">:</span><span class="co">//github.com/Riduidel) --&gt;</span>
83&lt;!---- License: zlib <span class="ot">(</span>http:<span class="co">//www.gzip.org/zlib/zlib_license.html) --&gt;</span> 109&lt;!---- License: zlib <span class="ot">(</span>http:<span class="co">//www.gzip.org/zlib/zlib_license.html) --&gt;</span>
84 110
@@ -226,6 +252,6 @@ code > span.er { color: #ff0000; font-weight: bold; }
226<span class="kw">$knownStyles</span> = findKnownStyles<span class="ot">();</span> 252<span class="kw">$knownStyles</span> = findKnownStyles<span class="ot">();</span>
227copyUserStylesFrom<span class="ot">(</span>createShaarliHashFromOPMLL<span class="ot">(</span><span class="kw">SHAARLI_RSS_OPML</span><span class="ot">),</span> <span class="kw">$knownStyles</span><span class="ot">);</span> 253copyUserStylesFrom<span class="ot">(</span>createShaarliHashFromOPMLL<span class="ot">(</span><span class="kw">SHAARLI_RSS_OPML</span><span class="ot">),</span> <span class="kw">$knownStyles</span><span class="ot">);</span>
228 254
229&lt;!--- <span class="ot">?</span> ----&gt;</code></pre> 255&lt;!--- <span class="ot">?</span> ----&gt;</code></pre></div>
230</body> 256</body>
231</html> 257</html>
diff --git a/doc/Download.html b/doc/Download.html
index 5f39c70f..9f9f5117 100644
--- a/doc/Download.html
+++ b/doc/Download.html
@@ -4,31 +4,49 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Download</title> 7 <title>Shaarli – Download</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <style type="text/css"> 9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
13table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
14 margin: 0; padding: 0; vertical-align: baseline; border: none; } 12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
15table.sourceCode { width: 100%; line-height: 100%; } 13table.sourceCode { width: 100%; line-height: 100%; }
16td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } 14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
17td.sourceCode { padding-left: 5px; } 15td.sourceCode { padding-left: 5px; }
18code > span.kw { color: #007020; font-weight: bold; } 16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
19code > span.dt { color: #902000; } 17code > span.dt { color: #902000; } /* DataType */
20code > span.dv { color: #40a070; } 18code > span.dv { color: #40a070; } /* DecVal */
21code > span.bn { color: #40a070; } 19code > span.bn { color: #40a070; } /* BaseN */
22code > span.fl { color: #40a070; } 20code > span.fl { color: #40a070; } /* Float */
23code > span.ch { color: #4070a0; } 21code > span.ch { color: #4070a0; } /* Char */
24code > span.st { color: #4070a0; } 22code > span.st { color: #4070a0; } /* String */
25code > span.co { color: #60a0b0; font-style: italic; } 23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
26code > span.ot { color: #007020; } 24code > span.ot { color: #007020; } /* Other */
27code > span.al { color: #ff0000; font-weight: bold; } 25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
28code > span.fu { color: #06287e; } 26code > span.fu { color: #06287e; } /* Function */
29code > span.er { color: #ff0000; font-weight: bold; } 27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
30 </style> 45 </style>
31 <link rel="stylesheet" href="github-markdown.css"> 46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
32</head> 50</head>
33<body> 51<body>
34<div id="local-sidebar"> 52<div id="local-sidebar">
@@ -39,18 +57,25 @@ code > span.er { color: #ff0000; font-weight: bold; }
39<li><a href="Download.html">Download</a></li> 57<li><a href="Download.html">Download</a></li>
40<li><a href="Server-requirements.html">Server requirements</a></li> 58<li><a href="Server-requirements.html">Server requirements</a></li>
41<li><a href="Server-configuration.html">Server configuration</a></li> 59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
42<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
43</ul></li> 64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
44<li><a href="Usage.html">Usage</a> 66<li><a href="Usage.html">Usage</a>
45<ul> 67<ul>
46<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 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>
47<li><a href="Firefox-share.html">Firefox share</a></li> 70<li><a href="Firefox-share.html">Firefox share</a></li>
48<li><a href="RSS-feeds.html">RSS feeds</a></li> 71<li><a href="RSS-feeds.html">RSS feeds</a></li>
49</ul></li> 72</ul></li>
50<li>How To 73<li>How To
51<ul> 74<ul>
52<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
53<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> 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>
54<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 79<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
55<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 80<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
56</ul></li> 81</ul></li>
@@ -62,6 +87,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
62<li><a href="Directory-structure.html">Directory structure</a></li> 87<li><a href="Directory-structure.html">Directory structure</a></li>
63<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
64<li><a href="Plugin-System.html">Plugin System</a></li> 89<li><a href="Plugin-System.html">Plugin System</a></li>
90<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
65<li><a href="Security.html">Security</a></li> 91<li><a href="Security.html">Security</a></li>
66<li><a href="Static-analysis.html">Static analysis</a></li> 92<li><a href="Static-analysis.html">Static analysis</a></li>
67<li><a href="Theming.html">Theming</a></li> 93<li><a href="Theming.html">Theming</a></li>
@@ -80,18 +106,18 @@ code > span.er { color: #ff0000; font-weight: bold; }
80<h3 id="latest-stable-revision">Latest stable revision</h3> 106<h3 id="latest-stable-revision">Latest stable revision</h3>
81<p>This revision has been <a href="https://github.com/shaarli/Shaarli/releases">released</a> and tested.<a href=".html"></a></p> 107<p>This revision has been <a href="https://github.com/shaarli/Shaarli/releases">released</a> and tested.<a href=".html"></a></p>
82<h4 id="clone-with-git-recommended">Clone with Git (recommended)</h4> 108<h4 id="clone-with-git-recommended">Clone with Git (recommended)</h4>
83<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> clone https://github.com/shaarli/Shaarli.git -b stable shaarli</code></pre> 109<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> clone https://github.com/shaarli/Shaarli.git -b stable shaarli</code></pre></div>
84<h4 id="download-as-an-archive">Download as an archive</h4> 110<h4 id="download-as-an-archive">Download as an archive</h4>
85<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">wget</span> https://github.com/shaarli/Shaarli/archive/stable.zip 111<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">wget</span> https://github.com/shaarli/Shaarli/archive/stable.zip
86$ <span class="kw">unzip</span> stable.zip 112$ <span class="kw">unzip</span> stable.zip
87$ <span class="kw">mv</span> Shaarli-stable shaarli</code></pre> 113$ <span class="kw">mv</span> Shaarli-stable shaarli</code></pre></div>
88<p>Tarballs are also available:</p> 114<p>Tarballs are also available:</p>
89<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">wget</span> https://github.com/shaarli/Shaarli/archive/stable.tar.gz 115<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">wget</span> https://github.com/shaarli/Shaarli/archive/stable.tar.gz
90$ <span class="kw">tar</span> xvf stable.tar.gz 116$ <span class="kw">tar</span> xvf stable.tar.gz
91$ <span class="kw">mv</span> Shaarli-stable shaarli</code></pre> 117$ <span class="kw">mv</span> Shaarli-stable shaarli</code></pre></div>
92<h3 id="development-mainline">Development (mainline)</h3> 118<h3 id="development-mainline">Development (mainline)</h3>
93<p><em>Use at your own risk!</em></p> 119<p><em>Use at your own risk!</em></p>
94<p>To get the latest changes:</p> 120<p>To get the latest changes:</p>
95<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> clone https://github.com/shaarli/Shaarli.git shaarli</code></pre> 121<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">git</span> clone https://github.com/shaarli/Shaarli.git shaarli</code></pre></div>
96</body> 122</body>
97</html> 123</html>
diff --git a/doc/Example-patch---add-new-via-field-for-links.html b/doc/Example-patch---add-new-via-field-for-links.html
index 388ff963..7db43107 100644
--- a/doc/Example-patch---add-new-via-field-for-links.html
+++ b/doc/Example-patch---add-new-via-field-for-links.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Example patch add new via field for links</title> 7 <title>Shaarli – Example patch add new via field for links</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
diff --git a/doc/FAQ.html b/doc/FAQ.html
index 33eb7c60..3b6b956d 100644
--- a/doc/FAQ.html
+++ b/doc/FAQ.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - FAQ</title> 7 <title>Shaarli – FAQ</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
diff --git a/doc/Firefox-share.html b/doc/Firefox-share.html
index 2943a86d..add6d4e8 100644
--- a/doc/Firefox-share.html
+++ b/doc/Firefox-share.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Firefox share</title> 7 <title>Shaarli – Firefox share</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
@@ -69,6 +77,19 @@
69<li>When you are visiting a webpage you would like to share with Shaarli, click the Firefox <em>Share</em> button <a href="images/firefoxshare.png.html">images/firefoxshare.png</a></li> 77<li>When you are visiting a webpage you would like to share with Shaarli, click the Firefox <em>Share</em> button <a href="images/firefoxshare.png.html">images/firefoxshare.png</a></li>
70<li>You can edit your link before and after saving, just like the bookmarklet above.</li> 78<li>You can edit your link before and after saving, just like the bookmarklet above.</li>
71</ul> 79</ul>
72<p>| ïª | Your Shaarli instance must be hosted on an HTTPS (SSL/TLS secure connection) enabled server for Firefox Share to work. Firefox Share will not work over plain HTTP connections. |<br />|------|-------------------------------------------------------------------------------|</p> 80<table style="width:100%;">
81<colgroup>
82<col style="width: 8%" />
83<col style="width: 91%" />
84</colgroup>
85<thead>
86<tr class="header">
87<th>ïª</th>
88<th>Your Shaarli instance must be hosted on an HTTPS (SSL/TLS secure connection) enabled server for Firefox Share to work. Firefox Share will not work over plain HTTP connections.</th>
89</tr>
90</thead>
91<tbody>
92</tbody>
93</table>
73</body> 94</body>
74</html> 95</html>
diff --git a/doc/GnuPG-signature.html b/doc/GnuPG-signature.html
index a1210b75..c431f9ad 100644
--- a/doc/GnuPG-signature.html
+++ b/doc/GnuPG-signature.html
@@ -4,31 +4,49 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - GnuPG signature</title> 7 <title>Shaarli – GnuPG signature</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <style type="text/css"> 9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
13table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
14 margin: 0; padding: 0; vertical-align: baseline; border: none; } 12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
15table.sourceCode { width: 100%; line-height: 100%; } 13table.sourceCode { width: 100%; line-height: 100%; }
16td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } 14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
17td.sourceCode { padding-left: 5px; } 15td.sourceCode { padding-left: 5px; }
18code > span.kw { color: #007020; font-weight: bold; } 16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
19code > span.dt { color: #902000; } 17code > span.dt { color: #902000; } /* DataType */
20code > span.dv { color: #40a070; } 18code > span.dv { color: #40a070; } /* DecVal */
21code > span.bn { color: #40a070; } 19code > span.bn { color: #40a070; } /* BaseN */
22code > span.fl { color: #40a070; } 20code > span.fl { color: #40a070; } /* Float */
23code > span.ch { color: #4070a0; } 21code > span.ch { color: #4070a0; } /* Char */
24code > span.st { color: #4070a0; } 22code > span.st { color: #4070a0; } /* String */
25code > span.co { color: #60a0b0; font-style: italic; } 23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
26code > span.ot { color: #007020; } 24code > span.ot { color: #007020; } /* Other */
27code > span.al { color: #ff0000; font-weight: bold; } 25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
28code > span.fu { color: #06287e; } 26code > span.fu { color: #06287e; } /* Function */
29code > span.er { color: #ff0000; font-weight: bold; } 27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
30 </style> 45 </style>
31 <link rel="stylesheet" href="github-markdown.css"> 46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
32</head> 50</head>
33<body> 51<body>
34<div id="local-sidebar"> 52<div id="local-sidebar">
@@ -39,18 +57,25 @@ code > span.er { color: #ff0000; font-weight: bold; }
39<li><a href="Download.html">Download</a></li> 57<li><a href="Download.html">Download</a></li>
40<li><a href="Server-requirements.html">Server requirements</a></li> 58<li><a href="Server-requirements.html">Server requirements</a></li>
41<li><a href="Server-configuration.html">Server configuration</a></li> 59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
42<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
43</ul></li> 64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
44<li><a href="Usage.html">Usage</a> 66<li><a href="Usage.html">Usage</a>
45<ul> 67<ul>
46<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 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>
47<li><a href="Firefox-share.html">Firefox share</a></li> 70<li><a href="Firefox-share.html">Firefox share</a></li>
48<li><a href="RSS-feeds.html">RSS feeds</a></li> 71<li><a href="RSS-feeds.html">RSS feeds</a></li>
49</ul></li> 72</ul></li>
50<li>How To 73<li>How To
51<ul> 74<ul>
52<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
53<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> 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>
54<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 79<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
55<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 80<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
56</ul></li> 81</ul></li>
@@ -62,6 +87,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
62<li><a href="Directory-structure.html">Directory structure</a></li> 87<li><a href="Directory-structure.html">Directory structure</a></li>
63<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
64<li><a href="Plugin-System.html">Plugin System</a></li> 89<li><a href="Plugin-System.html">Plugin System</a></li>
90<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
65<li><a href="Security.html">Security</a></li> 91<li><a href="Security.html">Security</a></li>
66<li><a href="Static-analysis.html">Static analysis</a></li> 92<li><a href="Static-analysis.html">Static analysis</a></li>
67<li><a href="Theming.html">Theming</a></li> 93<li><a href="Theming.html">Theming</a></li>
@@ -78,10 +104,13 @@ code > span.er { color: #ff0000; font-weight: bold; }
78<h1 id="gnupg-signature">GnuPG signature</h1> 104<h1 id="gnupg-signature">GnuPG signature</h1>
79<h2 id="introduction">Introduction</h2> 105<h2 id="introduction">Introduction</h2>
80<h3 id="pgp-and-gpg">PGP and GPG</h3> 106<h3 id="pgp-and-gpg">PGP and GPG</h3>
81<p><a href="https://gnupg.org/">Gnu Privacy Guard</a> (GnuPG) is an Open Source implementation of the <a href="https://en.wikipedia.org/wiki/Pretty_Good_Privacy#OpenPGP">Pretty Good [](.html)<br />Privacy</a> (OpenPGP) specification. Its main purposes are digital authentication,<br />signature and encryption.</p> 107<p><a href="https://gnupg.org/">Gnu Privacy Guard</a> (GnuPG) is an Open Source implementation of the <a href="https://en.wikipedia.org/wiki/Pretty_Good_Privacy#OpenPGP">Pretty Good [](.html)<br />
108Privacy</a> (OpenPGP) specification. Its main purposes are digital authentication,<br />
109signature and encryption.</p>
82<p>It is often used by the <a href="https://en.wikipedia.org/wiki/Free_and_open-source_software">FLOSS</a> community to verify:<a href=".html"></a></p> 110<p>It is often used by the <a href="https://en.wikipedia.org/wiki/Free_and_open-source_software">FLOSS</a> community to verify:<a href=".html"></a></p>
83<ul> 111<ul>
84<li>Linux package signatures: Debian <a href="https://wiki.debian.org/SecureApt">SecureApt</a>, ArchLinux <a href="https://www.archlinux.org/master-keys/">Master [](.html)<br />Keys</a></li> 112<li>Linux package signatures: Debian <a href="https://wiki.debian.org/SecureApt">SecureApt</a>, ArchLinux <a href="https://www.archlinux.org/master-keys/">Master [](.html)<br />
113Keys</a></li>
85<li><a href="https://en.wikipedia.org/wiki/Revision_control">SCM</a> releases &amp; maintainer identity<a href=".html"></a></li> 114<li><a href="https://en.wikipedia.org/wiki/Revision_control">SCM</a> releases &amp; maintainer identity<a href=".html"></a></li>
86</ul> 115</ul>
87<h3 id="trust">Trust</h3> 116<h3 id="trust">Trust</h3>
@@ -95,9 +124,12 @@ code > span.er { color: #ff0000; font-weight: bold; }
95<li><a href="https://en.wikipedia.org/wiki/Web_of_trust">Web of trust</a><a href=".html"></a></li> 124<li><a href="https://en.wikipedia.org/wiki/Web_of_trust">Web of trust</a><a href=".html"></a></li>
96</ul> 125</ul>
97<h2 id="generate-a-gpg-key">Generate a GPG key</h2> 126<h2 id="generate-a-gpg-key">Generate a GPG key</h2>
98<p>See <a href="http://stackoverflow.com/a/16725717">Generating a GPG key for Git tagging</a>.<a href=".html"></a></p> 127<ul>
128<li><a href="http://stackoverflow.com/a/16725717">Generating a GPG key for Git tagging</a> (StackOverflow)<a href=".html"></a></li>
129<li><a href="https://help.github.com/articles/generating-a-gpg-key/">Generating a GPG key</a> (GitHub)<a href=".html"></a></li>
130</ul>
99<h3 id="gpg---provide-identity-information">gpg - provide identity information</h3> 131<h3 id="gpg---provide-identity-information">gpg - provide identity information</h3>
100<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">gpg</span> --gen-key 132<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">gpg</span> --gen-key
101 133
102<span class="kw">gpg</span> (GnuPG) <span class="kw">2.1.6;</span> <span class="kw">Copyright</span> (C) <span class="kw">2015</span> Free Software Foundation, Inc. 134<span class="kw">gpg</span> (GnuPG) <span class="kw">2.1.6;</span> <span class="kw">Copyright</span> (C) <span class="kw">2015</span> Free Software Foundation, Inc.
103<span class="kw">This</span> is free software: you are free to change and redistribute it. 135<span class="kw">This</span> is free software: you are free to change and redistribute it.
@@ -116,7 +148,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
116<span class="kw">We</span> need to generate a lot of random bytes. It is a good idea to perform 148<span class="kw">We</span> need to generate a lot of random bytes. It is a good idea to perform
117<span class="kw">some</span> other action (type on the keyboard, move the mouse, utilize the 149<span class="kw">some</span> other action (type on the keyboard, move the mouse, utilize the
118<span class="kw">disks</span>) <span class="kw">during</span> the prime generation<span class="kw">;</span> <span class="kw">this</span> gives the random number 150<span class="kw">disks</span>) <span class="kw">during</span> the prime generation<span class="kw">;</span> <span class="kw">this</span> gives the random number
119<span class="kw">generator</span> a better chance to gain enough entropy.</code></pre> 151<span class="kw">generator</span> a better chance to gain enough entropy.</code></pre></div>
120<h3 id="gpg---entropy-interlude">gpg - entropy interlude</h3> 152<h3 id="gpg---entropy-interlude">gpg - entropy interlude</h3>
121<p>At this point, you will:</p> 153<p>At this point, you will:</p>
122<ul> 154<ul>
@@ -124,7 +156,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
124<li>be asked to use your machine's input devices (mouse, keyboard, etc.) to generate random entropy; this step <em>may take some time</em></li> 156<li>be asked to use your machine's input devices (mouse, keyboard, etc.) to generate random entropy; this step <em>may take some time</em></li>
125</ul> 157</ul>
126<h3 id="gpg---key-creation-confirmation">gpg - key creation confirmation</h3> 158<h3 id="gpg---key-creation-confirmation">gpg - key creation confirmation</h3>
127<pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">gpg</span>: key A9D53A3E marked as ultimately trusted 159<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">gpg</span>: key A9D53A3E marked as ultimately trusted
128<span class="kw">public</span> and secret key created and signed. 160<span class="kw">public</span> and secret key created and signed.
129 161
130<span class="kw">gpg</span>: checking the trustdb 162<span class="kw">gpg</span>: checking the trustdb
@@ -133,69 +165,11 @@ code > span.er { color: #ff0000; font-weight: bold; }
133<span class="kw">pub</span> rsa2048/A9D53A3E 2015-07-31 165<span class="kw">pub</span> rsa2048/A9D53A3E 2015-07-31
134 <span class="kw">Key</span> fingerprint = AF2A 5381 E54B 2FD2 14C4 A9A3 0E35 ACA4 A9D5 3A3E 166 <span class="kw">Key</span> fingerprint = AF2A 5381 E54B 2FD2 14C4 A9A3 0E35 ACA4 A9D5 3A3E
135<span class="kw">uid</span> [ultimate] Marvin the Paranoid Android <span class="kw">&lt;</span>marvin@h2g2.net<span class="kw">&gt;</span>[](.html) 167<span class="kw">uid</span> [ultimate] Marvin the Paranoid Android <span class="kw">&lt;</span>marvin@h2g2.net<span class="kw">&gt;</span>[](.html)
136<span class="kw">sub</span> rsa2048/8C0EACF1 2015-07-31</code></pre> 168<span class="kw">sub</span> rsa2048/8C0EACF1 2015-07-31</code></pre></div>
137<h3 id="gpg---submit-your-public-key-to-a-pgp-server-optional">gpg - submit your public key to a PGP server (Optional)</h3> 169<h3 id="gpg---submit-your-public-key-to-a-pgp-server-optional">gpg - submit your public key to a PGP server (Optional)</h3>
138<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">gpg</span> --keyserver pgp.mit.edu --send-keys A9D53A3E 170<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">gpg</span> --keyserver pgp.mit.edu --send-keys A9D53A3E
139<span class="kw">gpg</span>: sending key A9D53A3E to hkp server pgp.mit.edu</code></pre> 171<span class="kw">gpg</span>: sending key A9D53A3E to hkp server pgp.mit.edu</code></pre></div>
140<h2 id="create-and-push-a-gpg-signed-tag">Create and push a GPG-signed tag</h2> 172<h2 id="create-and-push-a-gpg-signed-tag">Create and push a GPG-signed tag</h2>
141<p>See <a href="http://git-scm.com/book/en/v2/Distributed-Git-Maintaining-a-Project#Tagging-Your-Releases">Git - Maintaining a project - Tagging your [](.html)<br />releases</a>.</p> 173<p>See <a href="Release-Shaarli.html">Release Shaarli</a>.</p>
142<h3 id="prerequisites">Prerequisites</h3>
143<p>This guide assumes that you have:</p>
144<ul>
145<li>a GPG key matching your GitHub authentication credentials
146<ul>
147<li>i.e., the email address identified by the GPG key is the same as the one in your <code>~/.gitconfig</code></li>
148</ul></li>
149<li>a GitHub fork of Shaarli</li>
150<li>a local clone of your Shaarli fork, with the following remotes:
151<ul>
152<li><code>origin</code> pointing to your GitHub fork</li>
153<li><code>upstream</code> pointing to the main Shaarli repository</li>
154</ul></li>
155<li>maintainer permissions on the main Shaarli repository (to push the signed tag)</li>
156</ul>
157<h3 id="bump-shaarlis-version">Bump Shaarli's version</h3>
158<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">cd</span> /path/to/shaarli
159
160<span class="co"># create a new branch</span>
161$ <span class="kw">git</span> fetch upstream
162$ <span class="kw">git</span> checkout upstream/master -b v0.5.0
163
164<span class="co"># bump the version number</span>
165$ <span class="kw">vim</span> index.php shaarli_version.php
166
167<span class="co"># commit the changes</span>
168$ <span class="kw">git</span> add index.php shaarli_version.php
169$ <span class="kw">git</span> commit -s -m <span class="st">&quot;Bump version to v0.5.0&quot;</span>
170
171<span class="co"># push the commit on your GitHub fork</span>
172$ <span class="kw">git</span> push origin v0.5.0</code></pre>
173<h3 id="create-and-merge-a-pull-request">Create and merge a Pull Request</h3>
174<p>This one is pretty straightforward ;-)</p>
175<h3 id="create-and-push-a-signed-tag">Create and push a signed tag</h3>
176<pre class="sourceCode bash"><code class="sourceCode bash"><span class="co"># update your local copy</span>
177$ <span class="kw">git</span> checkout master
178$ <span class="kw">git</span> fetch upstream
179$ <span class="kw">git</span> pull upstream master
180
181<span class="co"># create a signed tag</span>
182$ <span class="kw">git</span> tag -s -m <span class="st">&quot;Release v0.5.0&quot;</span> v0.5.0
183
184<span class="co"># push it to &quot;upstream&quot;</span>
185$ <span class="kw">git</span> push --tags upstream</code></pre>
186<h3 id="verify-a-signed-tag">Verify a signed tag</h3>
187<p><a href="https://github.com/shaarli/Shaarli/releases/tag/v0.5.0"><code>v0.5.0</code></a> is the first GPG-signed tag pushed on the Community Shaarli.<a href=".html"></a></p>
188<p>Let's have a look at its signature!</p>
189<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">cd</span> /path/to/shaarli
190$ <span class="kw">git</span> fetch upstream
191
192<span class="co"># get the SHA1 reference of the tag</span>
193$ <span class="kw">git</span> show-ref tags/v0.5.0
194<span class="kw">f7762cf803f03f5caf4b8078359a63783d0090c1</span> refs/tags/v0.5.0
195
196<span class="co"># verify the tag signature information</span>
197$ <span class="kw">git</span> verify-tag f7762cf803f03f5caf4b8078359a63783d0090c1
198<span class="kw">gpg</span>: Signature made Thu 30 Jul 2015 11:46:34 CEST using RSA key ID 4100DF6F
199<span class="kw">gpg</span>: Good signature from <span class="st">&quot;VirtualTam &lt;virtualtam@flibidi.net&gt;&quot;</span> [ultimate][](.html)</code></pre>
200</body> 174</body>
201</html> 175</html>
diff --git a/doc/GnuPG-signature.md b/doc/GnuPG-signature.md
index e8dbdb11..b0028d55 100644
--- a/doc/GnuPG-signature.md
+++ b/doc/GnuPG-signature.md
@@ -20,7 +20,8 @@ Trust can be gained by having your key signed by other people (and signing their
20- [Web of trust](https://en.wikipedia.org/wiki/Web_of_trust)[](.html) 20- [Web of trust](https://en.wikipedia.org/wiki/Web_of_trust)[](.html)
21 21
22## Generate a GPG key 22## Generate a GPG key
23See [Generating a GPG key for Git tagging](http://stackoverflow.com/a/16725717).[](.html) 23- [Generating a GPG key for Git tagging](http://stackoverflow.com/a/16725717) (StackOverflow)[](.html)
24- [Generating a GPG key](https://help.github.com/articles/generating-a-gpg-key/) (GitHub)[](.html)
24 25
25### gpg - provide identity information 26### gpg - provide identity information
26```bash 27```bash
@@ -72,70 +73,5 @@ gpg: sending key A9D53A3E to hkp server pgp.mit.edu
72``` 73```
73 74
74## Create and push a GPG-signed tag 75## Create and push a GPG-signed tag
75See [Git - Maintaining a project - Tagging your [](.html)
76releases](http://git-scm.com/book/en/v2/Distributed-Git-Maintaining-a-Project#Tagging-Your-Releases).
77
78### Prerequisites
79This guide assumes that you have:
80- a GPG key matching your GitHub authentication credentials
81 - i.e., the email address identified by the GPG key is the same as the one in your `~/.gitconfig`
82- a GitHub fork of Shaarli
83- a local clone of your Shaarli fork, with the following remotes:
84 - `origin` pointing to your GitHub fork
85 - `upstream` pointing to the main Shaarli repository
86- maintainer permissions on the main Shaarli repository (to push the signed tag)
87
88### Bump Shaarli's version
89```bash
90$ cd /path/to/shaarli
91
92# create a new branch
93$ git fetch upstream
94$ git checkout upstream/master -b v0.5.0
95
96# bump the version number
97$ vim index.php shaarli_version.php
98
99# commit the changes
100$ git add index.php shaarli_version.php
101$ git commit -s -m "Bump version to v0.5.0"
102
103# push the commit on your GitHub fork
104$ git push origin v0.5.0
105```
106
107### Create and merge a Pull Request
108This one is pretty straightforward ;-)
109
110### Create and push a signed tag
111```bash
112# update your local copy
113$ git checkout master
114$ git fetch upstream
115$ git pull upstream master
116 76
117# create a signed tag 77See [Release Shaarli](Release-Shaarli.html).
118$ git tag -s -m "Release v0.5.0" v0.5.0
119
120# push it to "upstream"
121$ git push --tags upstream
122```
123
124### Verify a signed tag
125[`v0.5.0`](https://github.com/shaarli/Shaarli/releases/tag/v0.5.0) is the first GPG-signed tag pushed on the Community Shaarli.[](.html)
126
127Let's have a look at its signature!
128
129```bash
130$ cd /path/to/shaarli
131$ git fetch upstream
132
133# get the SHA1 reference of the tag
134$ git show-ref tags/v0.5.0
135f7762cf803f03f5caf4b8078359a63783d0090c1 refs/tags/v0.5.0
136
137# verify the tag signature information
138$ git verify-tag f7762cf803f03f5caf4b8078359a63783d0090c1
139gpg: Signature made Thu 30 Jul 2015 11:46:34 CEST using RSA key ID 4100DF6F
140gpg: Good signature from "VirtualTam <virtualtam@flibidi.net>" [ultimate][](.html)
141```
diff --git a/doc/Home.html b/doc/Home.html
index 39d951c8..442503c5 100644
--- a/doc/Home.html
+++ b/doc/Home.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Home</title> 7 <title>Shaarli – Home</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
@@ -61,7 +69,7 @@
61<p>Welcome to the <a href="https://github.com/shaarli/Shaarli/">Shaarli</a> wiki<embed src=".html" /></p> 69<p>Welcome to the <a href="https://github.com/shaarli/Shaarli/">Shaarli</a> wiki<embed src=".html" /></p>
62<p>Here you can find some info on how to use, configure, tweak and solve problems with your Shaarli.</p> 70<p>Here you can find some info on how to use, configure, tweak and solve problems with your Shaarli.</p>
63<p>For general info, read the <a href="https://github.com/shaarli/Shaarli/blob/master/README.md">README</a>.<a href=".html"></a></p> 71<p>For general info, read the <a href="https://github.com/shaarli/Shaarli/blob/master/README.md">README</a>.<a href=".html"></a></p>
64<p>If you have any questions or ideas, please join the <a href="https://gitter.im/shaarli/Shaarli">chat</a> (also reachable via <a href="https://irc.gitter.im/">IRC</a>), post them in our <a href="https://github.com/shaarli/Shaarli/issues/44">general discussion</a> or read the current <a href="https://github.com/shaarli/Shaarli/issues">issues</a>. If you've found a bug, please create a <a href="https://github.com/shaarli/Shaarli/issues/new">new issue</a>.<a href=".html"></a></p> 72<p>If you have any questions or ideas, please join the <a href="https://gitter.im/shaarli/Shaarli">chat</a> (also reachable via <a href="https://irc.gitter.im/">IRC</a>), post them in our <a href="https://github.com/shaarli/Shaarli/issues/308">general discussion</a> (<a href="https://github.com/shaarli/Shaarli/issues/44">archive</a>) or read the current <a href="https://github.com/shaarli/Shaarli/issues">issues</a>. If you've found a bug, please create a <a href="https://github.com/shaarli/Shaarli/issues/new">new issue</a>.<a href=".html"></a></p>
65<p>If you would like a feature added to Shaarli, check the issues labeled <a href="https://github.com/shaarli/Shaarli/labels/feature"><code>feature</code></a>, <a href="https://github.com/shaarli/Shaarli/labels/enhancement"><code>enhancement</code></a>, and <a href="https://github.com/shaarli/Shaarli/labels/plugin"><code>plugin</code></a>.<a href=".html"></a></p> 73<p>If you would like a feature added to Shaarli, check the issues labeled <a href="https://github.com/shaarli/Shaarli/labels/feature"><code>feature</code></a>, <a href="https://github.com/shaarli/Shaarli/labels/enhancement"><code>enhancement</code></a>, and <a href="https://github.com/shaarli/Shaarli/labels/plugin"><code>plugin</code></a>.<a href=".html"></a></p>
66<p><em>Note: This documentation is available online at <a href="https://github.com/shaarli/Shaarli/wiki" class="uri">https://github.com/shaarli/Shaarli/wiki</a>, and locally in the <code>doc/</code> directory of your Shaarli installation.</em></p> 74<p><em>Note: This documentation is available online at <a href="https://github.com/shaarli/Shaarli/wiki" class="uri">https://github.com/shaarli/Shaarli/wiki</a>, and locally in the <code>doc/</code> directory of your Shaarli installation.</em></p>
67</body> 75</body>
diff --git a/doc/Home.md b/doc/Home.md
index a824d983..38413f24 100644
--- a/doc/Home.md
+++ b/doc/Home.md
@@ -7,7 +7,7 @@ Here you can find some info on how to use, configure, tweak and solve problems w
7 7
8For general info, read the [README](https://github.com/shaarli/Shaarli/blob/master/README.md).[](.html) 8For general info, read the [README](https://github.com/shaarli/Shaarli/blob/master/README.md).[](.html)
9 9
10If you have any questions or ideas, please join the [chat](https://gitter.im/shaarli/Shaarli) (also reachable via [IRC](https://irc.gitter.im/)), post them in our [general discussion](https://github.com/shaarli/Shaarli/issues/44) or read the current [issues](https://github.com/shaarli/Shaarli/issues). If you've found a bug, please create a [new issue](https://github.com/shaarli/Shaarli/issues/new).[](.html) 10If you have any questions or ideas, please join the [chat](https://gitter.im/shaarli/Shaarli) (also reachable via [IRC](https://irc.gitter.im/)), post them in our [general discussion](https://github.com/shaarli/Shaarli/issues/308) ([archive](https://github.com/shaarli/Shaarli/issues/44)) or read the current [issues](https://github.com/shaarli/Shaarli/issues). If you've found a bug, please create a [new issue](https://github.com/shaarli/Shaarli/issues/new).[](.html)
11 11
12If you would like a feature added to Shaarli, check the issues labeled [`feature`](https://github.com/shaarli/Shaarli/labels/feature), [`enhancement`](https://github.com/shaarli/Shaarli/labels/enhancement), and [`plugin`](https://github.com/shaarli/Shaarli/labels/plugin).[](.html) 12If you would like a feature added to Shaarli, check the issues labeled [`feature`](https://github.com/shaarli/Shaarli/labels/feature), [`enhancement`](https://github.com/shaarli/Shaarli/labels/enhancement), and [`plugin`](https://github.com/shaarli/Shaarli/labels/plugin).[](.html)
13 13
diff --git a/doc/Plugin-System.html b/doc/Plugin-System.html
index cb1cb746..37b26152 100644
--- a/doc/Plugin-System.html
+++ b/doc/Plugin-System.html
@@ -4,31 +4,49 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Plugin System</title> 7 <title>Shaarli – Plugin System</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <style type="text/css"> 9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
13table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
14 margin: 0; padding: 0; vertical-align: baseline; border: none; } 12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
15table.sourceCode { width: 100%; line-height: 100%; } 13table.sourceCode { width: 100%; line-height: 100%; }
16td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } 14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
17td.sourceCode { padding-left: 5px; } 15td.sourceCode { padding-left: 5px; }
18code > span.kw { color: #007020; font-weight: bold; } 16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
19code > span.dt { color: #902000; } 17code > span.dt { color: #902000; } /* DataType */
20code > span.dv { color: #40a070; } 18code > span.dv { color: #40a070; } /* DecVal */
21code > span.bn { color: #40a070; } 19code > span.bn { color: #40a070; } /* BaseN */
22code > span.fl { color: #40a070; } 20code > span.fl { color: #40a070; } /* Float */
23code > span.ch { color: #4070a0; } 21code > span.ch { color: #4070a0; } /* Char */
24code > span.st { color: #4070a0; } 22code > span.st { color: #4070a0; } /* String */
25code > span.co { color: #60a0b0; font-style: italic; } 23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
26code > span.ot { color: #007020; } 24code > span.ot { color: #007020; } /* Other */
27code > span.al { color: #ff0000; font-weight: bold; } 25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
28code > span.fu { color: #06287e; } 26code > span.fu { color: #06287e; } /* Function */
29code > span.er { color: #ff0000; font-weight: bold; } 27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
30 </style> 45 </style>
31 <link rel="stylesheet" href="github-markdown.css"> 46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
32</head> 50</head>
33<body> 51<body>
34<div id="local-sidebar"> 52<div id="local-sidebar">
@@ -39,18 +57,25 @@ code > span.er { color: #ff0000; font-weight: bold; }
39<li><a href="Download.html">Download</a></li> 57<li><a href="Download.html">Download</a></li>
40<li><a href="Server-requirements.html">Server requirements</a></li> 58<li><a href="Server-requirements.html">Server requirements</a></li>
41<li><a href="Server-configuration.html">Server configuration</a></li> 59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
42<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
43</ul></li> 64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
44<li><a href="Usage.html">Usage</a> 66<li><a href="Usage.html">Usage</a>
45<ul> 67<ul>
46<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 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>
47<li><a href="Firefox-share.html">Firefox share</a></li> 70<li><a href="Firefox-share.html">Firefox share</a></li>
48<li><a href="RSS-feeds.html">RSS feeds</a></li> 71<li><a href="RSS-feeds.html">RSS feeds</a></li>
49</ul></li> 72</ul></li>
50<li>How To 73<li>How To
51<ul> 74<ul>
52<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
53<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> 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>
54<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 79<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
55<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 80<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
56</ul></li> 81</ul></li>
@@ -62,6 +87,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
62<li><a href="Directory-structure.html">Directory structure</a></li> 87<li><a href="Directory-structure.html">Directory structure</a></li>
63<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
64<li><a href="Plugin-System.html">Plugin System</a></li> 89<li><a href="Plugin-System.html">Plugin System</a></li>
90<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
65<li><a href="Security.html">Security</a></li> 91<li><a href="Security.html">Security</a></li>
66<li><a href="Static-analysis.html">Static analysis</a></li> 92<li><a href="Static-analysis.html">Static analysis</a></li>
67<li><a href="Theming.html">Theming</a></li> 93<li><a href="Theming.html">Theming</a></li>
@@ -77,32 +103,11 @@ code > span.er { color: #ff0000; font-weight: bold; }
77</div> 103</div>
78<h1 id="plugin-system">Plugin System</h1> 104<h1 id="plugin-system">Plugin System</h1>
79<blockquote> 105<blockquote>
80<p>Note: Plugin current status - in developpement (not merged into master).</p> 106<p>Note: Plugin current status - in development (not merged into master).</p>
81</blockquote> 107</blockquote>
82<p><a href="#plugin-user-guide"><strong>I am a user.</strong> Plugin User Guide.</a><a href=".html"></a></p> 108<p><a href="#developer-api"><strong>I am a developer.</strong> Developer API.</a><a href=".html"></a></p>
83<p><a href="#developper-api"><strong>I am a developper.</strong> Developper API.</a><a href=".html"></a></p>
84<p><a href="#guide-for-template-designer"><strong>I am a template designer.</strong> Guide for template designer.</a><a href=".html"></a></p> 109<p><a href="#guide-for-template-designer"><strong>I am a template designer.</strong> Guide for template designer.</a><a href=".html"></a></p>
85<h2 id="plugin-user-guide">Plugin User Guide</h2> 110<h2 id="developer-api">Developer API</h2>
86<h3 id="manage-plugins">Manage plugins</h3>
87<p>In <code>config.php</code>, change $GLOBALS<a href="&#39;ENABLED_PLUGINS&#39;]-array:.html">'config'['ENABLED_PLUGINS'] array:</a></p>
88<pre class="sourceCode php"><code class="sourceCode php"><span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;config&#39;</span><span class="ot">[</span><span class="st">&#39;ENABLED_PLUGINS&#39;</span><span class="ot">]](</span><span class="st">&#39;ENABLED_PLUGINS&#39;</span><span class="ot">]</span>.html<span class="ot">)</span></code></pre>
89<p>Full list:</p>
90<pre class="sourceCode php"><code class="sourceCode php"><span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;config&#39;</span><span class="ot">[</span><span class="st">&#39;ENABLED_PLUGINS&#39;</span><span class="ot">]</span> = <span class="fu">array</span><span class="ot">(](</span><span class="st">&#39;ENABLED_PLUGINS&#39;</span><span class="ot">]</span>-=-<span class="fu">array</span><span class="ot">(</span>.html<span class="ot">)</span>
91 <span class="st">&#39;qrcode&#39;</span><span class="ot">,</span> <span class="st">&#39;archiveorg&#39;</span><span class="ot">,</span> <span class="st">&#39;readityourself&#39;</span><span class="ot">,</span> <span class="st">&#39;playvideos&#39;</span><span class="ot">,</span>
92 <span class="st">&#39;wallabag&#39;</span><span class="ot">,</span> <span class="st">&#39;markdown&#39;</span><span class="ot">,</span> <span class="st">&#39;addlink_toolbar&#39;</span><span class="ot">,</span>
93<span class="ot">);</span></code></pre>
94<h3 id="list-of-plugins">List of plugins</h3>
95<p>Plugin maintained by the community:</p>
96<ul>
97<li>Archive.org - add a clickable icon to every link to archive.org.</li>
98<li>Addlink in toolbar - add a field to paste new links URL in toolbar.</li>
99<li>Markdown - write and display Shaare in Markdown.</li>
100<li>Play videos - popup to play all videos displayed in linklist.</li>
101<li>QRCode - add a clickable icon generating a QRCode for every link.</li>
102<li>ReadItYourself - add a clickable icon for ReadItYourself.</li>
103<li>Wallabag - add a clickable icon for Wallabag.</li>
104</ul>
105<h2 id="developper-api">Developper API</h2>
106<h3 id="what-can-i-do-with-plugins">What can I do with plugins?</h3> 111<h3 id="what-can-i-do-with-plugins">What can I do with plugins?</h3>
107<p>The plugin system let you:</p> 112<p>The plugin system let you:</p>
108<ul> 113<ul>
@@ -134,72 +139,86 @@ code > span.er { color: #ff0000; font-weight: bold; }
134<p>Template placeholders are displayed in template in specific places.</p> 139<p>Template placeholders are displayed in template in specific places.</p>
135<p>RainTPL displays every element contained in the placeholder's array. These element can be added by plugins.</p> 140<p>RainTPL displays every element contained in the placeholder's array. These element can be added by plugins.</p>
136<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> 141<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>
137<pre class="sourceCode php"><code class="sourceCode php"><span class="kw">$data</span><span class="ot">[</span><span class="st">&#39;top_placeholder&#39;</span><span class="ot">[]</span> = <span class="st">&#39;My content&#39;</span><span class="ot">;](]</span>-=-<span class="st">&#39;My-content&#39;</span><span class="ot">;</span>.html<span class="ot">)</span> 142<div class="sourceCode"><pre class="sourceCode php"><code class="sourceCode php"><span class="kw">$data</span><span class="ot">[</span><span class="st">&#39;top_placeholder&#39;</span><span class="ot">[]</span> = <span class="st">&#39;My content&#39;</span><span class="ot">;](]</span>-=-<span class="st">&#39;My-content&#39;</span><span class="ot">;</span>.html<span class="ot">)</span>
138<span class="co"># OR</span> 143<span class="co"># OR</span>
139<span class="fu">array_push</span><span class="ot">(</span><span class="kw">$data</span><span class="ot">[</span><span class="st">&#39;top_placeholder&#39;</span><span class="ot">],</span> <span class="st">&#39;My&#39;</span><span class="ot">,</span> <span class="st">&#39;content&#39;</span><span class="ot">);[](</span>.html<span class="ot">)</span> 144<span class="fu">array_push</span><span class="ot">(</span><span class="kw">$data</span><span class="ot">[</span><span class="st">&#39;top_placeholder&#39;</span><span class="ot">],</span> <span class="st">&#39;My&#39;</span><span class="ot">,</span> <span class="st">&#39;content&#39;</span><span class="ot">);[](</span>.html<span class="ot">)</span>
140 145
141<span class="kw">return</span> <span class="kw">$data</span><span class="ot">;</span></code></pre> 146<span class="kw">return</span> <span class="kw">$data</span><span class="ot">;</span></code></pre></div>
142<h4 id="data-manipulation">Data manipulation</h4> 147<h4 id="data-manipulation">Data manipulation</h4>
143<p>When a page is displayed, every variable send to the template engine is passed to plugins before that in <code>$data</code>.</p> 148<p>When a page is displayed, every variable send to the template engine is passed to plugins before that in <code>$data</code>.</p>
144<p>The data contained by this array can be altered before template rendering.</p> 149<p>The data contained by this array can be altered before template rendering.</p>
145<p>For exemple, in linklist, it is possible to alter every title:</p> 150<p>For exemple, in linklist, it is possible to alter every title:</p>
146<pre class="sourceCode php"><code class="sourceCode php"><span class="co">// mind the reference if you want $data to be altered</span> 151<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>
147<span class="kw">foreach</span> <span class="ot">(</span><span class="kw">$data</span><span class="ot">[</span><span class="st">&#39;links&#39;</span><span class="ot">]</span> <span class="kw">as</span> &amp;<span class="kw">$value</span><span class="ot">)</span> {<span class="ot">[](</span>.html<span class="ot">)</span> 152<span class="kw">foreach</span> <span class="ot">(</span><span class="kw">$data</span><span class="ot">[</span><span class="st">&#39;links&#39;</span><span class="ot">]</span> <span class="kw">as</span> &amp;<span class="kw">$value</span><span class="ot">)</span> {<span class="ot">[](</span>.html<span class="ot">)</span>
148 <span class="co">// String reverse every title.</span> 153 <span class="co">// String reverse every title.</span>
149 <span class="kw">$value</span><span class="ot">[</span><span class="st">&#39;title&#39;</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">&#39;title&#39;</span><span class="ot">]);[](</span>.html<span class="ot">)</span> 154 <span class="kw">$value</span><span class="ot">[</span><span class="st">&#39;title&#39;</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">&#39;title&#39;</span><span class="ot">]);[](</span>.html<span class="ot">)</span>
150} 155}
151 156
152<span class="kw">return</span> <span class="kw">$data</span><span class="ot">;</span></code></pre> 157<span class="kw">return</span> <span class="kw">$data</span><span class="ot">;</span></code></pre></div>
158<h3 id="metadata">Metadata</h3>
159<p>Every plugin needs a <code>&lt;plugin_name&gt;.meta</code> file, which is in fact an <code>.ini</code> file (<code>KEY=&quot;VALUE&quot;</code>), to be listed in plugin administration.</p>
160<p>Each file contain two keys:</p>
161<ul>
162<li><code>description</code>: plugin description</li>
163<li><code>parameters</code>: user parameter names, separated by a <code>;</code>.</li>
164</ul>
165<blockquote>
166<p>Note: In PHP, <code>parse_ini_file()</code> seems to want strings to be between by quotes <code>&quot;</code> in the ini file.</p>
167</blockquote>
153<h3 id="its-not-working">It's not working!</h3> 168<h3 id="its-not-working">It's not working!</h3>
154<p>Use <code>demo_plugin</code> as a functional example. It covers most of the plugin system features.</p> 169<p>Use <code>demo_plugin</code> as a functional example. It covers most of the plugin system features.</p>
155<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> 170<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>
156<h3 id="hooks">Hooks</h3> 171<h3 id="hooks">Hooks</h3>
157<table> 172<table style="width:42%;">
173<colgroup>
174<col style="width: 19%" />
175<col style="width: 22%" />
176</colgroup>
158<thead> 177<thead>
159<tr class="header"> 178<tr class="header">
160<th style="text-align: left;">Hooks</th> 179<th>Hooks</th>
161<th style="text-align: center;">Description</th> 180<th style="text-align: center;">Description</th>
162</tr> 181</tr>
163</thead> 182</thead>
164<tbody> 183<tbody>
165<tr class="odd"> 184<tr class="odd">
166<td style="text-align: left;"><a href="#render_header">render_header</a></td> 185<td><a href="#render_header">render_header</a></td>
167<td style="text-align: center;">Allow plugin to add content in page headers.</td> 186<td style="text-align: center;">Allow plugin to add content in page headers.</td>
168</tr> 187</tr>
169<tr class="even"> 188<tr class="even">
170<td style="text-align: left;"><a href="#render_includes">render_includes</a></td> 189<td><a href="#render_includes">render_includes</a></td>
171<td style="text-align: center;">Allow plugin to include their own CSS files.</td> 190<td style="text-align: center;">Allow plugin to include their own CSS files.</td>
172</tr> 191</tr>
173<tr class="odd"> 192<tr class="odd">
174<td style="text-align: left;"><a href="#render_footer">render_footer</a></td> 193<td><a href="#render_footer">render_footer</a></td>
175<td style="text-align: center;">Allow plugin to add content in page footer and include their own JS files.</td> 194<td style="text-align: center;">Allow plugin to add content in page footer and include their own JS files.</td>
176</tr> 195</tr>
177<tr class="even"> 196<tr class="even">
178<td style="text-align: left;"><a href="#render_linklist">render_linklist</a></td> 197<td><a href="#render_linklist">render_linklist</a></td>
179<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> 198<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>
180</tr> 199</tr>
181<tr class="odd"> 200<tr class="odd">
182<td style="text-align: left;"><a href="#render_editlink">render_editlink</a></td> 201<td><a href="#render_editlink">render_editlink</a></td>
183<td style="text-align: center;">Allow to add fields in the form, or display elements.</td> 202<td style="text-align: center;">Allow to add fields in the form, or display elements.</td>
184</tr> 203</tr>
185<tr class="even"> 204<tr class="even">
186<td style="text-align: left;"><a href="#render_tools">render_tools</a></td> 205<td><a href="#render_tools">render_tools</a></td>
187<td style="text-align: center;">Allow to add content at the end of the page.</td> 206<td style="text-align: center;">Allow to add content at the end of the page.</td>
188</tr> 207</tr>
189<tr class="odd"> 208<tr class="odd">
190<td style="text-align: left;"><a href="#render_picwall">render_picwall</a></td> 209<td><a href="#render_picwall">render_picwall</a></td>
191<td style="text-align: center;">Allow to add content at the top and bottom of the page.</td> 210<td style="text-align: center;">Allow to add content at the top and bottom of the page.</td>
192</tr> 211</tr>
193<tr class="even"> 212<tr class="even">
194<td style="text-align: left;"><a href="#render_tagcloud">render_tagcloud</a></td> 213<td><a href="#render_tagcloud">render_tagcloud</a></td>
195<td style="text-align: center;">Allow to add content at the top and bottom of the page.</td> 214<td style="text-align: center;">Allow to add content at the top and bottom of the page.</td>
196</tr> 215</tr>
197<tr class="odd"> 216<tr class="odd">
198<td style="text-align: left;"><a href="#render_daily">render_daily</a></td> 217<td><a href="#render_daily">render_daily</a></td>
199<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> 218<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>
200</tr> 219</tr>
201<tr class="even"> 220<tr class="even">
202<td style="text-align: left;"><a href="#savelink">savelink</a></td> 221<td><a href="#savelink">savelink</a></td>
203<td style="text-align: center;">Allow to alter the link being saved in the datastore.</td> 222<td style="text-align: center;">Allow to alter the link being saved in the datastore.</td>
204</tr> 223</tr>
205</tbody> 224</tbody>
@@ -259,6 +278,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
259<p>List of placeholders:</p> 278<p>List of placeholders:</p>
260<ul> 279<ul>
261<li><code>text</code>: called after the end of the footer text.</li> 280<li><code>text</code>: called after the end of the footer text.</li>
281<li><code>endofpage</code>: called at the end of the page.</li>
262</ul> 282</ul>
263<p><img src="http://i.imgur.com/L5S2YEH.png" alt="text_example" /><a href=".html"></a></p> 283<p><img src="http://i.imgur.com/L5S2YEH.png" alt="text_example" /><a href=".html"></a></p>
264<ul> 284<ul>
@@ -393,6 +413,20 @@ code > span.er { color: #ff0000; font-weight: bold; }
393<li>tags</li> 413<li>tags</li>
394</ul> 414</ul>
395<h2 id="guide-for-template-designer">Guide for template designer</h2> 415<h2 id="guide-for-template-designer">Guide for template designer</h2>
416<h3 id="plugin-administration">Plugin administration</h3>
417<p>Your theme must include a plugin administration page: <code>pluginsadmin.html</code>.</p>
418<blockquote>
419<p>Note: repo's template link needs to be added when the PR is merged.</p>
420</blockquote>
421<p>Use the default one as an example.</p>
422<p>Aside from classic RainTPL loops, plugins order is handle by JavaScript. You can just include <code>plugin_admin.js</code>, only if:</p>
423<ul>
424<li>you're using a table.</li>
425<li>you call orderUp() and orderUp() onclick on arrows.</li>
426<li>you add data-line and data-order to your rows.</li>
427</ul>
428<p>Otherwise, you can use your own JS as long as this field is send by the form:</p>
429<p><input type="hidden" name="order_{$key}" value="{$counter}"></p>
396<h3 id="placeholder-system">Placeholder system</h3> 430<h3 id="placeholder-system">Placeholder system</h3>
397<p>In order to make plugins work with every custom themes, you need to add variable placeholder in your templates.</p> 431<p>In order to make plugins work with every custom themes, you need to add variable placeholder in your templates.</p>
398<p>It's a RainTPL loop like this:</p> 432<p>It's a RainTPL loop like this:</p>
@@ -406,96 +440,104 @@ code > span.er { color: #ff0000; font-weight: bold; }
406<pre><code>{loop=&quot;$plugins_header.buttons_toolbar&quot;} 440<pre><code>{loop=&quot;$plugins_header.buttons_toolbar&quot;}
407 {$value} 441 {$value}
408{/loop}</code></pre> 442{/loop}</code></pre>
443<p>At the end of file, before clearing floating blocks:</p>
444<pre><code>{if=&quot;!empty($plugin_errors) &amp;&amp; isLoggedIn()&quot;}
445 &lt;ul class=&quot;errors&quot;&gt;
446 {loop=&quot;plugin_errors&quot;}
447 &lt;li&gt;{$value}&lt;/li&gt;
448 {/loop}
449 &lt;/ul&gt;
450{/if}</code></pre>
409<p><strong>includes.html</strong></p> 451<p><strong>includes.html</strong></p>
410<p>At the end of the file:</p> 452<p>At the end of the file:</p>
411<pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$plugins_includes.css_files&quot;} 453<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$plugins_includes.css_files&quot;}
412<span class="kw">&lt;link</span><span class="ot"> type=</span><span class="st">&quot;text/css&quot;</span><span class="ot"> rel=</span><span class="st">&quot;stylesheet&quot;</span><span class="ot"> href=</span><span class="st">&quot;{$value}#&quot;</span><span class="kw">/&gt;</span> 454<span class="kw">&lt;link</span><span class="ot"> type=</span><span class="st">&quot;text/css&quot;</span><span class="ot"> rel=</span><span class="st">&quot;stylesheet&quot;</span><span class="ot"> href=</span><span class="st">&quot;{$value}#&quot;</span><span class="kw">/&gt;</span>
413{/loop}</code></pre> 455{/loop}</code></pre></div>
414<p><strong>page.footer.html</strong></p> 456<p><strong>page.footer.html</strong></p>
415<p>At the end of your footer notes:</p> 457<p>At the end of your footer notes:</p>
416<pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$plugins_footer.text&quot;} 458<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$plugins_footer.text&quot;}
417 {$value} 459 {$value}
418{/loop}</code></pre> 460{/loop}</code></pre></div>
419<p>At the end of file:</p> 461<p>At the end of file:</p>
420<pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$plugins_footer.js_files&quot;} 462<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$plugins_footer.js_files&quot;}
421 <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;{$value}#&quot;</span><span class="kw">&gt;&lt;/script&gt;</span> 463 <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;{$value}#&quot;</span><span class="kw">&gt;&lt;/script&gt;</span>
422{/loop}</code></pre> 464{/loop}</code></pre></div>
423<p><strong>linklist.html</strong></p> 465<p><strong>linklist.html</strong></p>
424<p>After search fields:</p> 466<p>After search fields:</p>
425<pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$plugins_header.fields_toolbar&quot;} 467<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$plugins_header.fields_toolbar&quot;}
426 {$value} 468 {$value}
427{/loop}</code></pre> 469{/loop}</code></pre></div>
428<p>Before displaying the link list (after paging):</p> 470<p>Before displaying the link list (after paging):</p>
429<pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$plugin_start_zone&quot;} 471<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$plugin_start_zone&quot;}
430 {$value} 472 {$value}
431{/loop}</code></pre> 473{/loop}</code></pre></div>
432<p>For every links (icons):</p> 474<p>For every links (icons):</p>
433<pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$value.link_plugin&quot;} 475<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$value.link_plugin&quot;}
434 <span class="kw">&lt;span&gt;</span>{$value}<span class="kw">&lt;/span&gt;</span> 476 <span class="kw">&lt;span&gt;</span>{$value}<span class="kw">&lt;/span&gt;</span>
435{/loop}</code></pre> 477{/loop}</code></pre></div>
436<p>Before end paging:</p> 478<p>Before end paging:</p>
437<pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$plugin_end_zone&quot;} 479<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$plugin_end_zone&quot;}
438 {$value} 480 {$value}
439{/loop}</code></pre> 481{/loop}</code></pre></div>
440<p><strong>linklist.paging.html</strong></p> 482<p><strong>linklist.paging.html</strong></p>
441<p>After the &quot;private only&quot; icon:</p> 483<p>After the &quot;private only&quot; icon:</p>
442<pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$action_plugin&quot;} 484<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$action_plugin&quot;}
443 {$value} 485 {$value}
444{/loop}</code></pre> 486{/loop}</code></pre></div>
445<p><strong>editlink.html</strong></p> 487<p><strong>editlink.html</strong></p>
446<p>After tags field:</p> 488<p>After tags field:</p>
447<pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$edit_link_plugin&quot;} 489<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$edit_link_plugin&quot;}
448 {$value} 490 {$value}
449{/loop}</code></pre> 491{/loop}</code></pre></div>
450<p><strong>tools.html</strong></p> 492<p><strong>tools.html</strong></p>
451<p>After the last tool:</p> 493<p>After the last tool:</p>
452<pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$tools_plugin&quot;} 494<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html">{loop=&quot;$tools_plugin&quot;}
453 {$value} 495 {$value}
454{/loop}</code></pre> 496{/loop}</code></pre></div>
455<p><strong>picwall.html</strong></p> 497<p><strong>picwall.html</strong></p>
456<p>Top:</p> 498<p>Top:</p>
457<pre class="sourceCode html"><code class="sourceCode html"><span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;plugin_zone_start_picwall&quot;</span><span class="ot"> class=</span><span class="st">&quot;plugin_zone&quot;</span><span class="kw">&gt;</span> 499<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html"><span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;plugin_zone_start_picwall&quot;</span><span class="ot"> class=</span><span class="st">&quot;plugin_zone&quot;</span><span class="kw">&gt;</span>
458 {loop=&quot;$plugin_start_zone&quot;} 500 {loop=&quot;$plugin_start_zone&quot;}
459 {$value} 501 {$value}
460 {/loop} 502 {/loop}
461<span class="kw">&lt;/div&gt;</span></code></pre> 503<span class="kw">&lt;/div&gt;</span></code></pre></div>
462<p>Bottom:</p> 504<p>Bottom:</p>
463<pre class="sourceCode html"><code class="sourceCode html"><span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;plugin_zone_end_picwall&quot;</span><span class="ot"> class=</span><span class="st">&quot;plugin_zone&quot;</span><span class="kw">&gt;</span> 505<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html"><span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;plugin_zone_end_picwall&quot;</span><span class="ot"> class=</span><span class="st">&quot;plugin_zone&quot;</span><span class="kw">&gt;</span>
464 {loop=&quot;$plugin_end_zone&quot;} 506 {loop=&quot;$plugin_end_zone&quot;}
465 {$value} 507 {$value}
466 {/loop} 508 {/loop}
467<span class="kw">&lt;/div&gt;</span></code></pre> 509<span class="kw">&lt;/div&gt;</span></code></pre></div>
468<p><strong>tagcloud.html</strong></p> 510<p><strong>tagcloud.html</strong></p>
469<p>Top:</p> 511<p>Top:</p>
470<pre class="sourceCode html"><code class="sourceCode html"> <span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;plugin_zone_start_tagcloud&quot;</span><span class="ot"> class=</span><span class="st">&quot;plugin_zone&quot;</span><span class="kw">&gt;</span> 512<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html"> <span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;plugin_zone_start_tagcloud&quot;</span><span class="ot"> class=</span><span class="st">&quot;plugin_zone&quot;</span><span class="kw">&gt;</span>
471 {loop=&quot;$plugin_start_zone&quot;} 513 {loop=&quot;$plugin_start_zone&quot;}
472 {$value} 514 {$value}
473 {/loop} 515 {/loop}
474 <span class="kw">&lt;/div&gt;</span></code></pre> 516 <span class="kw">&lt;/div&gt;</span></code></pre></div>
475<p>Bottom:</p> 517<p>Bottom:</p>
476<pre class="sourceCode html"><code class="sourceCode html"> <span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;plugin_zone_end_tagcloud&quot;</span><span class="ot"> class=</span><span class="st">&quot;plugin_zone&quot;</span><span class="kw">&gt;</span> 518<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html"> <span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;plugin_zone_end_tagcloud&quot;</span><span class="ot"> class=</span><span class="st">&quot;plugin_zone&quot;</span><span class="kw">&gt;</span>
477 {loop=&quot;$plugin_end_zone&quot;} 519 {loop=&quot;$plugin_end_zone&quot;}
478 {$value} 520 {$value}
479 {/loop} 521 {/loop}
480 <span class="kw">&lt;/div&gt;</span></code></pre> 522 <span class="kw">&lt;/div&gt;</span></code></pre></div>
481<p><strong>daily.html</strong></p> 523<p><strong>daily.html</strong></p>
482<p>Top:</p> 524<p>Top:</p>
483<pre class="sourceCode html"><code class="sourceCode html"><span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;plugin_zone_start_picwall&quot;</span><span class="ot"> class=</span><span class="st">&quot;plugin_zone&quot;</span><span class="kw">&gt;</span> 525<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html"><span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;plugin_zone_start_picwall&quot;</span><span class="ot"> class=</span><span class="st">&quot;plugin_zone&quot;</span><span class="kw">&gt;</span>
484 {loop=&quot;$plugin_start_zone&quot;} 526 {loop=&quot;$plugin_start_zone&quot;}
485 {$value} 527 {$value}
486 {/loop} 528 {/loop}
487<span class="kw">&lt;/div&gt;</span></code></pre> 529<span class="kw">&lt;/div&gt;</span></code></pre></div>
488<p>After every link:</p> 530<p>After every link:</p>
489<pre class="sourceCode html"><code class="sourceCode html"><span class="kw">&lt;div</span><span class="ot"> class=</span><span class="st">&quot;dailyEntryFooter&quot;</span><span class="kw">&gt;</span> 531<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html"><span class="kw">&lt;div</span><span class="ot"> class=</span><span class="st">&quot;dailyEntryFooter&quot;</span><span class="kw">&gt;</span>
490 {loop=&quot;$link.link_plugin&quot;} 532 {loop=&quot;$link.link_plugin&quot;}
491 {$value} 533 {$value}
492 {/loop} 534 {/loop}
493<span class="kw">&lt;/div&gt;</span></code></pre> 535<span class="kw">&lt;/div&gt;</span></code></pre></div>
494<p>Bottom:</p> 536<p>Bottom:</p>
495<pre class="sourceCode html"><code class="sourceCode html"><span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;plugin_zone_end_picwall&quot;</span><span class="ot"> class=</span><span class="st">&quot;plugin_zone&quot;</span><span class="kw">&gt;</span> 537<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html"><span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;plugin_zone_end_picwall&quot;</span><span class="ot"> class=</span><span class="st">&quot;plugin_zone&quot;</span><span class="kw">&gt;</span>
496 {loop=&quot;$plugin_end_zone&quot;} 538 {loop=&quot;$plugin_end_zone&quot;}
497 {$value} 539 {$value}
498 {/loop} 540 {/loop}
499<span class="kw">&lt;/div&gt;</span></code></pre> 541<span class="kw">&lt;/div&gt;</span></code></pre></div>
500</body> 542</body>
501</html> 543</html>
diff --git a/doc/Plugin-System.md b/doc/Plugin-System.md
index 8cba6664..623627dd 100644
--- a/doc/Plugin-System.md
+++ b/doc/Plugin-System.md
@@ -1,44 +1,11 @@
1#Plugin System 1#Plugin System
2> Note: Plugin current status - in developpement (not merged into master). 2> Note: Plugin current status - in development (not merged into master).
3 3
4[**I am a user.** Plugin User Guide.](#plugin-user-guide)[](.html) 4[**I am a developer.** Developer API.](#developer-api)[](.html)
5
6[**I am a developper.** Developper API.](#developper-api)[](.html)
7 5
8[**I am a template designer.** Guide for template designer.](#guide-for-template-designer)[](.html) 6[**I am a template designer.** Guide for template designer.](#guide-for-template-designer)[](.html)
9 7
10## Plugin User Guide 8## Developer API
11
12### Manage plugins
13
14In `config.php`, change $GLOBALS['config'['ENABLED_PLUGINS'] array:]('ENABLED_PLUGINS']-array:.html)
15
16```php
17$GLOBALS['config'['ENABLED_PLUGINS']]('ENABLED_PLUGINS'].html)
18```
19
20Full list:
21
22```php
23$GLOBALS['config'['ENABLED_PLUGINS'] = array(]('ENABLED_PLUGINS']-=-array(.html)
24 'qrcode', 'archiveorg', 'readityourself', 'playvideos',
25 'wallabag', 'markdown', 'addlink_toolbar',
26);
27```
28
29### List of plugins
30
31Plugin maintained by the community:
32
33 * Archive.org - add a clickable icon to every link to archive.org.
34 * Addlink in toolbar - add a field to paste new links URL in toolbar.
35 * Markdown - write and display Shaare in Markdown.
36 * Play videos - popup to play all videos displayed in linklist.
37 * QRCode - add a clickable icon generating a QRCode for every link.
38 * ReadItYourself - add a clickable icon for ReadItYourself.
39 * Wallabag - add a clickable icon for Wallabag.
40
41## Developper API
42 9
43### What can I do with plugins? 10### What can I do with plugins?
44 11
@@ -123,6 +90,17 @@ foreach ($data['links'] as &$value) {[](.html)
123return $data; 90return $data;
124``` 91```
125 92
93### Metadata
94
95Every plugin needs a `<plugin_name>.meta` file, which is in fact an `.ini` file (`KEY="VALUE"`), to be listed in plugin administration.
96
97Each file contain two keys:
98
99 * `description`: plugin description
100 * `parameters`: user parameter names, separated by a `;`.
101
102> Note: In PHP, `parse_ini_file()` seems to want strings to be between by quotes `"` in the ini file.
103
126### It's not working! 104### It's not working!
127 105
128Use `demo_plugin` as a functional example. It covers most of the plugin system features. 106Use `demo_plugin` as a functional example. It covers most of the plugin system features.
@@ -217,6 +195,7 @@ Items can be displayed in templates by adding an entry in `$data['<placeholder>'
217List of placeholders: 195List of placeholders:
218 196
219 * `text`: called after the end of the footer text. 197 * `text`: called after the end of the footer text.
198 * `endofpage`: called at the end of the page.
220 199
221![text_example](http://i.imgur.com/L5S2YEH.png)[](.html) 200![text_example](http://i.imgur.com/L5S2YEH.png)[](.html)
222 201
@@ -399,6 +378,24 @@ Allow to alter the link being saved in the datastore.
399 378
400## Guide for template designer 379## Guide for template designer
401 380
381### Plugin administration
382
383Your theme must include a plugin administration page: `pluginsadmin.html`.
384
385> Note: repo's template link needs to be added when the PR is merged.
386
387Use the default one as an example.
388
389Aside from classic RainTPL loops, plugins order is handle by JavaScript. You can just include `plugin_admin.js`, only if:
390
391 * you're using a table.
392 * you call orderUp() and orderUp() onclick on arrows.
393 * you add data-line and data-order to your rows.
394
395Otherwise, you can use your own JS as long as this field is send by the form:
396
397<input type="hidden" name="order_{$key}" value="{$counter}">
398
402### Placeholder system 399### Placeholder system
403 400
404In order to make plugins work with every custom themes, you need to add variable placeholder in your templates. 401In order to make plugins work with every custom themes, you need to add variable placeholder in your templates.
@@ -421,6 +418,16 @@ At the end of the menu:
421 {$value} 418 {$value}
422 {/loop} 419 {/loop}
423 420
421At the end of file, before clearing floating blocks:
422
423 {if="!empty($plugin_errors) && isLoggedIn()"}
424 <ul class="errors">
425 {loop="plugin_errors"}
426 <li>{$value}</li>
427 {/loop}
428 </ul>
429 {/if}
430
424**includes.html** 431**includes.html**
425 432
426At the end of the file: 433At the end of the file:
diff --git a/doc/Plugins.html b/doc/Plugins.html
new file mode 100644
index 00000000..e7df6aed
--- /dev/null
+++ b/doc/Plugins.html
@@ -0,0 +1,156 @@
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli – Plugins</title>
8 <style type="text/css">code{white-space: pre;}</style>
9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
13table.sourceCode { width: 100%; line-height: 100%; }
14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
15td.sourceCode { padding-left: 5px; }
16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
17code > span.dt { color: #902000; } /* DataType */
18code > span.dv { color: #40a070; } /* DecVal */
19code > span.bn { color: #40a070; } /* BaseN */
20code > span.fl { color: #40a070; } /* Float */
21code > span.ch { color: #4070a0; } /* Char */
22code > span.st { color: #4070a0; } /* String */
23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
24code > span.ot { color: #007020; } /* Other */
25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
26code > span.fu { color: #06287e; } /* Function */
27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
45 </style>
46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
50</head>
51<body>
52<div id="local-sidebar">
53<ul>
54<li><a href="Home.html">Home</a></li>
55<li>Installation
56<ul>
57<li><a href="Download.html">Download</a></li>
58<li><a href="Server-requirements.html">Server requirements</a></li>
59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
66<li><a href="Usage.html">Usage</a>
67<ul>
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</ul></li>
73<li>How To
74<ul>
75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</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>
81</ul></li>
82<li><a href="Troubleshooting.html">Troubleshooting</a></li>
83<li><a href="Development.html">Development</a>
84<ul>
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="Security.html">Security</a></li>
92<li><a href="Static-analysis.html">Static analysis</a></li>
93<li><a href="Theming.html">Theming</a></li>
94<li><a href="Unit-tests.html">Unit tests</a></li>
95</ul></li>
96<li>About
97<ul>
98<li><a href="FAQ.html">FAQ</a></li>
99<li><a href="Community-&amp;-Related-software.html">Community &amp; Related software</a></li>
100<li><a href="TODO.html">TODO</a></li>
101</ul></li>
102</ul>
103</div>
104<h1 id="plugins">Plugins</h1>
105<h2 id="plugin-installation">Plugin installation</h2>
106<p>There is a bunch of plugins shipped with Shaarli, where there is nothing to do to install them.</p>
107<p>If you want to install a third party plugin:</p>
108<ul>
109<li>Download it.</li>
110<li>Put it in the <code>plugins</code> directory in Shaarli's installation folder.</li>
111<li>Make sure you put it correctly:</li>
112</ul>
113<pre><code>| index.php
114| plugins/
115|---| custom_plugin/
116| |---| custom_plugin.php
117| |---| ...
118</code></pre>
119<ul>
120<li>Make sure your webserver can read and write the files in your plugin folder.</li>
121</ul>
122<h2 id="plugin-configuration">Plugin configuration</h2>
123<p>In Shaarli's administration page (<code>Tools</code> link), go to <code>Plugin administration</code>.</p>
124<p>Here you can enable and disable all plugins available, and configure them.</p>
125<p><img src="https://camo.githubusercontent.com/5da68e191969007492ca0fbeb25f3b2357b748cc/687474703a2f2f692e696d6775722e636f6d2f766837544643712e706e67" alt="administration screenshot" /><a href=".html"></a></p>
126<h2 id="plugin-order">Plugin order</h2>
127<p>In the plugin administration page, you can move enabled plugins to the top or bottom of the list. The first plugins in the list will be processed first.</p>
128<p>This is important in case plugins are depending on each other. Read plugins README details for more information.</p>
129<p><strong>Use case</strong>: The (non existent) plugin <code>shaares_footer</code> adds a footer to every shaare in Markdown syntax. It needs to be processed <em>before</em> (higher in the list) the Markdown plugin. Otherwise its syntax won't be translated in HTML.</p>
130<h2 id="file-mode">File mode</h2>
131<p>Enabled plugin are stored in your <code>config.php</code> parameters file, under the <code>array</code>:</p>
132<div class="sourceCode"><pre class="sourceCode php"><code class="sourceCode php"><span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;config&#39;</span><span class="ot">[</span><span class="st">&#39;ENABLED_PLUGINS&#39;</span><span class="ot">]](</span><span class="st">&#39;ENABLED_PLUGINS&#39;</span><span class="ot">]</span>.html<span class="ot">)</span></code></pre></div>
133<p>You can edit them manually here.<br />
134Example:</p>
135<div class="sourceCode"><pre class="sourceCode php"><code class="sourceCode php"><span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;config&#39;</span><span class="ot">[</span><span class="st">&#39;ENABLED_PLUGINS&#39;</span><span class="ot">]</span> = <span class="fu">array</span><span class="ot">(](</span><span class="st">&#39;ENABLED_PLUGINS&#39;</span><span class="ot">]</span>-=-<span class="fu">array</span><span class="ot">(</span>.html<span class="ot">)</span>
136 <span class="st">&#39;qrcode&#39;</span><span class="ot">,</span>
137 <span class="st">&#39;archiveorg&#39;</span><span class="ot">,</span>
138 <span class="st">&#39;wallabag&#39;</span><span class="ot">,</span>
139 <span class="st">&#39;markdown&#39;</span><span class="ot">,</span>
140<span class="ot">);</span></code></pre></div>
141<h3 id="plugin-usage">Plugin usage</h3>
142<h4 id="official-plugins">Official plugins</h4>
143<p>Usage of each plugin is documented in it's README file:</p>
144<ul>
145<li><code>addlink-toolbar</code>: Adds the addlink input on the linklist page</li>
146<li><code>archiveorg</code>: For each link, add an Archive.org icon</li>
147<li><a href="https://github.com/shaarli/Shaarli/blob/master/plugins/markdown/README.md"><code>markdown</code></a>: Render shaare description with Markdown syntax.<a href=".html"></a></li>
148<li><a href="https://github.com/shaarli/Shaarli/blob/master/plugins/playvideos/README.md"><code>playvideos</code></a>: Add a button in the toolbar allowing to watch all videos.<a href=".html"></a></li>
149<li><code>qrcode</code>: For each link, add a QRCode icon.</li>
150<li><code>readityourself</code>: For each link, add a ReadItYourself icon to save the shaared URL</li>
151<li><a href="https://github.com/shaarli/Shaarli/blob/master/plugins/wallabag/README.md"><code>wallabag</code></a>: For each link, add a Wallabag icon to save it in your instance.<a href=".html"></a></li>
152</ul>
153<h4 id="third-party-plugins">Third party plugins</h4>
154<p>See <a href="https://github.com/shaarli/Shaarli/wiki/Community-%26-Related-software#third-party-plugins">Community &amp; related software</a><a href=".html"></a></p>
155</body>
156</html>
diff --git a/doc/Plugins.md b/doc/Plugins.md
new file mode 100644
index 00000000..81167fcf
--- /dev/null
+++ b/doc/Plugins.md
@@ -0,0 +1,77 @@
1#Plugins
2## Plugin installation
3
4There is a bunch of plugins shipped with Shaarli, where there is nothing to do to install them.
5
6If you want to install a third party plugin:
7
8 * Download it.
9 * Put it in the `plugins` directory in Shaarli's installation folder.
10 * Make sure you put it correctly:
11
12```
13| index.php
14| plugins/
15|---| custom_plugin/
16| |---| custom_plugin.php
17| |---| ...
18
19```
20
21 * Make sure your webserver can read and write the files in your plugin folder.
22
23## Plugin configuration
24
25In Shaarli's administration page (`Tools` link), go to `Plugin administration`.
26
27Here you can enable and disable all plugins available, and configure them.
28
29![administration screenshot](https://camo.githubusercontent.com/5da68e191969007492ca0fbeb25f3b2357b748cc/687474703a2f2f692e696d6775722e636f6d2f766837544643712e706e67)[](.html)
30
31## Plugin order
32
33In the plugin administration page, you can move enabled plugins to the top or bottom of the list. The first plugins in the list will be processed first.
34
35This is important in case plugins are depending on each other. Read plugins README details for more information.
36
37**Use case**: The (non existent) plugin `shaares_footer` adds a footer to every shaare in Markdown syntax. It needs to be processed *before* (higher in the list) the Markdown plugin. Otherwise its syntax won't be translated in HTML.
38
39## File mode
40
41Enabled plugin are stored in your `config.php` parameters file, under the `array`:
42
43```php
44$GLOBALS['config'['ENABLED_PLUGINS']]('ENABLED_PLUGINS'].html)
45```
46
47You can edit them manually here.
48Example:
49
50```php
51$GLOBALS['config'['ENABLED_PLUGINS'] = array(]('ENABLED_PLUGINS']-=-array(.html)
52 'qrcode',
53 'archiveorg',
54 'wallabag',
55 'markdown',
56);
57```
58
59### Plugin usage
60
61#### Official plugins
62
63Usage of each plugin is documented in it's README file:
64
65 * `addlink-toolbar`: Adds the addlink input on the linklist page
66 * `archiveorg`: For each link, add an Archive.org icon
67 * [`markdown`](https://github.com/shaarli/Shaarli/blob/master/plugins/markdown/README.md): Render shaare description with Markdown syntax.[](.html)
68 * [`playvideos`](https://github.com/shaarli/Shaarli/blob/master/plugins/playvideos/README.md): Add a button in the toolbar allowing to watch all videos.[](.html)
69 * `qrcode`: For each link, add a QRCode icon.
70 * `readityourself`: For each link, add a ReadItYourself icon to save the shaared URL
71 * [`wallabag`](https://github.com/shaarli/Shaarli/blob/master/plugins/wallabag/README.md): For each link, add a Wallabag icon to save it in your instance.[](.html)
72
73
74
75#### Third party plugins
76
77See [Community & related software](https://github.com/shaarli/Shaarli/wiki/Community-%26-Related-software#third-party-plugins)[](.html)
diff --git a/doc/RSS-feeds.html b/doc/RSS-feeds.html
index 859869bf..1b38e4e8 100644
--- a/doc/RSS-feeds.html
+++ b/doc/RSS-feeds.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - RSS feeds</title> 7 <title>Shaarli – RSS feeds</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
@@ -57,6 +65,20 @@
57</ul> 65</ul>
58</div> 66</div>
59<h1 id="rss-feeds">RSS feeds</h1> 67<h1 id="rss-feeds">RSS feeds</h1>
68<h3 id="feeds-options">Feeds options</h3>
69<p>Feeds are available in ATOM with <code>?do=atom</code> and RSS with <code>do=RSS</code>.</p>
70<p>Options:</p>
71<ul>
72<li>You can use <code>permalinks</code> in the feed URL to get permalink to Shaares instead of direct link to shaared URL.
73<ul>
74<li>E.G. <code>https://my.shaarli.domain/?do=atom&amp;permalinks</code>.</li>
75</ul></li>
76<li>You can use <code>nb</code> parameter in the feed URL to specify the number of Shaares you want in a feed (default if not specified: <code>50</code>). The keyword <code>all</code> is available if you want everything.
77<ul>
78<li><code>https://my.shaarli.domain/?do=atom&amp;permalinks&amp;nb=42</code></li>
79<li><code>https://my.shaarli.domain/?do=atom&amp;permalinks&amp;nb=all</code></li>
80</ul></li>
81</ul>
60<h3 id="rss-feeds-or-picture-wall-for-a-specific-searchtag">RSS Feeds or Picture Wall for a specific search/tag</h3> 82<h3 id="rss-feeds-or-picture-wall-for-a-specific-searchtag">RSS Feeds or Picture Wall for a specific search/tag</h3>
61<p>It is possible to filter RSS/ATOM feeds and Picture Wall on a Shaarli to <strong>only display results of a specific search, or for a specific tag</strong>.</p> 83<p>It is possible to filter RSS/ATOM feeds and Picture Wall on a Shaarli to <strong>only display results of a specific search, or for a specific tag</strong>.</p>
62<p>For example, if you want to subscribe only to links tagged <code>photography</code>:</p> 84<p>For example, if you want to subscribe only to links tagged <code>photography</code>:</p>
diff --git a/doc/RSS-feeds.md b/doc/RSS-feeds.md
index 764b3a49..757bed9a 100644
--- a/doc/RSS-feeds.md
+++ b/doc/RSS-feeds.md
@@ -1,5 +1,17 @@
1#RSS feeds 1#RSS feeds
2### Feeds options
3
4Feeds are available in ATOM with `?do=atom` and RSS with `do=RSS`.
5
6Options:
7- You can use `permalinks` in the feed URL to get permalink to Shaares instead of direct link to shaared URL.
8 - E.G. `https://my.shaarli.domain/?do=atom&permalinks`.
9- You can use `nb` parameter in the feed URL to specify the number of Shaares you want in a feed (default if not specified: `50`). The keyword `all` is available if you want everything.
10 - `https://my.shaarli.domain/?do=atom&permalinks&nb=42`
11 - `https://my.shaarli.domain/?do=atom&permalinks&nb=all`
12
2### RSS Feeds or Picture Wall for a specific search/tag 13### RSS Feeds or Picture Wall for a specific search/tag
14
3It is possible to filter RSS/ATOM feeds and Picture Wall on a Shaarli to **only display results of a specific search, or for a specific tag**. 15It is possible to filter RSS/ATOM feeds and Picture Wall on a Shaarli to **only display results of a specific search, or for a specific tag**.
4 16
5For example, if you want to subscribe only to links tagged `photography`: 17For example, if you want to subscribe only to links tagged `photography`:
diff --git a/doc/Release-Shaarli.html b/doc/Release-Shaarli.html
new file mode 100644
index 00000000..cfaa663b
--- /dev/null
+++ b/doc/Release-Shaarli.html
@@ -0,0 +1,170 @@
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli – Release Shaarli</title>
8 <style type="text/css">code{white-space: pre;}</style>
9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
13table.sourceCode { width: 100%; line-height: 100%; }
14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
15td.sourceCode { padding-left: 5px; }
16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
17code > span.dt { color: #902000; } /* DataType */
18code > span.dv { color: #40a070; } /* DecVal */
19code > span.bn { color: #40a070; } /* BaseN */
20code > span.fl { color: #40a070; } /* Float */
21code > span.ch { color: #4070a0; } /* Char */
22code > span.st { color: #4070a0; } /* String */
23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
24code > span.ot { color: #007020; } /* Other */
25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
26code > span.fu { color: #06287e; } /* Function */
27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
45 </style>
46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
50</head>
51<body>
52<div id="local-sidebar">
53<ul>
54<li><a href="Home.html">Home</a></li>
55<li>Installation
56<ul>
57<li><a href="Download.html">Download</a></li>
58<li><a href="Server-requirements.html">Server requirements</a></li>
59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
66<li><a href="Usage.html">Usage</a>
67<ul>
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</ul></li>
73<li>How To
74<ul>
75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</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>
81</ul></li>
82<li><a href="Troubleshooting.html">Troubleshooting</a></li>
83<li><a href="Development.html">Development</a>
84<ul>
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="Security.html">Security</a></li>
92<li><a href="Static-analysis.html">Static analysis</a></li>
93<li><a href="Theming.html">Theming</a></li>
94<li><a href="Unit-tests.html">Unit tests</a></li>
95</ul></li>
96<li>About
97<ul>
98<li><a href="FAQ.html">FAQ</a></li>
99<li><a href="Community-&amp;-Related-software.html">Community &amp; Related software</a></li>
100<li><a href="TODO.html">TODO</a></li>
101</ul></li>
102</ul>
103</div>
104<h1 id="release-shaarli">Release Shaarli</h1>
105<p>See <a href="http://git-scm.com/book/en/v2/Distributed-Git-Maintaining-a-Project#Tagging-Your-Releases">Git - Maintaining a project - Tagging your [](.html)<br />
106releases</a>.</p>
107<h3 id="prerequisites">Prerequisites</h3>
108<p>This guide assumes that you have:</p>
109<ul>
110<li>a GPG key matching your GitHub authentication credentials
111<ul>
112<li>i.e., the email address identified by the GPG key is the same as the one in your <code>~/.gitconfig</code></li>
113</ul></li>
114<li>a GitHub fork of Shaarli</li>
115<li>a local clone of your Shaarli fork, with the following remotes:
116<ul>
117<li><code>origin</code> pointing to your GitHub fork</li>
118<li><code>upstream</code> pointing to the main Shaarli repository</li>
119</ul></li>
120<li>maintainer permissions on the main Shaarli repository (to push the signed tag)</li>
121<li><a href="http://pandoc.org/">Pandoc</a> needs to be installed.<a href=".html"></a></li>
122</ul>
123<h3 id="bump-shaarlis-version">Bump Shaarli's version</h3>
124<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">cd</span> /path/to/shaarli
125
126<span class="co"># create a new branch</span>
127$ <span class="kw">git</span> fetch upstream
128$ <span class="kw">git</span> checkout upstream/master -b v0.5.0
129
130<span class="co"># bump the version number</span>
131$ <span class="kw">vim</span> index.php shaarli_version.php
132
133<span class="co"># rebuild the documentation from the wiki</span>
134$ <span class="kw">make</span> htmldoc
135
136<span class="co"># commit the changes</span>
137$ <span class="kw">git</span> add index.php shaarli_version.php doc
138$ <span class="kw">git</span> commit -s -m <span class="st">&quot;Bump version to v0.5.0&quot;</span>
139
140<span class="co"># push the commit on your GitHub fork</span>
141$ <span class="kw">git</span> push origin v0.5.0</code></pre></div>
142<h3 id="create-and-merge-a-pull-request">Create and merge a Pull Request</h3>
143<p>This one is pretty straightforward ;-)</p>
144<h3 id="create-and-push-a-signed-tag">Create and push a signed tag</h3>
145<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="co"># update your local copy</span>
146$ <span class="kw">git</span> checkout master
147$ <span class="kw">git</span> fetch upstream
148$ <span class="kw">git</span> pull upstream master
149
150<span class="co"># create a signed tag</span>
151$ <span class="kw">git</span> tag -s -m <span class="st">&quot;Release v0.5.0&quot;</span> v0.5.0
152
153<span class="co"># push it to &quot;upstream&quot;</span>
154$ <span class="kw">git</span> push --tags upstream</code></pre></div>
155<h3 id="verify-a-signed-tag">Verify a signed tag</h3>
156<p><a href="https://github.com/shaarli/Shaarli/releases/tag/v0.5.0"><code>v0.5.0</code></a> is the first GPG-signed tag pushed on the Community Shaarli.<a href=".html"></a></p>
157<p>Let's have a look at its signature!</p>
158<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">cd</span> /path/to/shaarli
159$ <span class="kw">git</span> fetch upstream
160
161<span class="co"># get the SHA1 reference of the tag</span>
162$ <span class="kw">git</span> show-ref tags/v0.5.0
163<span class="kw">f7762cf803f03f5caf4b8078359a63783d0090c1</span> refs/tags/v0.5.0
164
165<span class="co"># verify the tag signature information</span>
166$ <span class="kw">git</span> verify-tag f7762cf803f03f5caf4b8078359a63783d0090c1
167<span class="kw">gpg</span>: Signature made Thu 30 Jul 2015 11:46:34 CEST using RSA key ID 4100DF6F
168<span class="kw">gpg</span>: Good signature from <span class="st">&quot;VirtualTam &lt;virtualtam@flibidi.net&gt;&quot;</span> [ultimate][](.html)</code></pre></div>
169</body>
170</html>
diff --git a/doc/Release-Shaarli.md b/doc/Release-Shaarli.md
new file mode 100644
index 00000000..d5044fe9
--- /dev/null
+++ b/doc/Release-Shaarli.md
@@ -0,0 +1,72 @@
1#Release Shaarli
2See [Git - Maintaining a project - Tagging your [](.html)
3releases](http://git-scm.com/book/en/v2/Distributed-Git-Maintaining-a-Project#Tagging-Your-Releases).
4
5### Prerequisites
6This guide assumes that you have:
7- a GPG key matching your GitHub authentication credentials
8 - i.e., the email address identified by the GPG key is the same as the one in your `~/.gitconfig`
9- a GitHub fork of Shaarli
10- a local clone of your Shaarli fork, with the following remotes:
11 - `origin` pointing to your GitHub fork
12 - `upstream` pointing to the main Shaarli repository
13- maintainer permissions on the main Shaarli repository (to push the signed tag)
14- [Pandoc](http://pandoc.org/) needs to be installed.[](.html)
15
16### Bump Shaarli's version
17```bash
18$ cd /path/to/shaarli
19
20# create a new branch
21$ git fetch upstream
22$ git checkout upstream/master -b v0.5.0
23
24# bump the version number
25$ vim index.php shaarli_version.php
26
27# rebuild the documentation from the wiki
28$ make htmldoc
29
30# commit the changes
31$ git add index.php shaarli_version.php doc
32$ git commit -s -m "Bump version to v0.5.0"
33
34# push the commit on your GitHub fork
35$ git push origin v0.5.0
36```
37
38### Create and merge a Pull Request
39This one is pretty straightforward ;-)
40
41### Create and push a signed tag
42```bash
43# update your local copy
44$ git checkout master
45$ git fetch upstream
46$ git pull upstream master
47
48# create a signed tag
49$ git tag -s -m "Release v0.5.0" v0.5.0
50
51# push it to "upstream"
52$ git push --tags upstream
53```
54
55### Verify a signed tag
56[`v0.5.0`](https://github.com/shaarli/Shaarli/releases/tag/v0.5.0) is the first GPG-signed tag pushed on the Community Shaarli.[](.html)
57
58Let's have a look at its signature!
59
60```bash
61$ cd /path/to/shaarli
62$ git fetch upstream
63
64# get the SHA1 reference of the tag
65$ git show-ref tags/v0.5.0
66f7762cf803f03f5caf4b8078359a63783d0090c1 refs/tags/v0.5.0
67
68# verify the tag signature information
69$ git verify-tag f7762cf803f03f5caf4b8078359a63783d0090c1
70gpg: Signature made Thu 30 Jul 2015 11:46:34 CEST using RSA key ID 4100DF6F
71gpg: Good signature from "VirtualTam <virtualtam@flibidi.net>" [ultimate][](.html)
72```
diff --git a/doc/Security.html b/doc/Security.html
index 914fa507..b1969a4c 100644
--- a/doc/Security.html
+++ b/doc/Security.html
@@ -4,31 +4,49 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Security</title> 7 <title>Shaarli – Security</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <style type="text/css"> 9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
13table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
14 margin: 0; padding: 0; vertical-align: baseline; border: none; } 12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
15table.sourceCode { width: 100%; line-height: 100%; } 13table.sourceCode { width: 100%; line-height: 100%; }
16td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } 14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
17td.sourceCode { padding-left: 5px; } 15td.sourceCode { padding-left: 5px; }
18code > span.kw { color: #007020; font-weight: bold; } 16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
19code > span.dt { color: #902000; } 17code > span.dt { color: #902000; } /* DataType */
20code > span.dv { color: #40a070; } 18code > span.dv { color: #40a070; } /* DecVal */
21code > span.bn { color: #40a070; } 19code > span.bn { color: #40a070; } /* BaseN */
22code > span.fl { color: #40a070; } 20code > span.fl { color: #40a070; } /* Float */
23code > span.ch { color: #4070a0; } 21code > span.ch { color: #4070a0; } /* Char */
24code > span.st { color: #4070a0; } 22code > span.st { color: #4070a0; } /* String */
25code > span.co { color: #60a0b0; font-style: italic; } 23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
26code > span.ot { color: #007020; } 24code > span.ot { color: #007020; } /* Other */
27code > span.al { color: #ff0000; font-weight: bold; } 25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
28code > span.fu { color: #06287e; } 26code > span.fu { color: #06287e; } /* Function */
29code > span.er { color: #ff0000; font-weight: bold; } 27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
30 </style> 45 </style>
31 <link rel="stylesheet" href="github-markdown.css"> 46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
32</head> 50</head>
33<body> 51<body>
34<div id="local-sidebar"> 52<div id="local-sidebar">
@@ -39,18 +57,25 @@ code > span.er { color: #ff0000; font-weight: bold; }
39<li><a href="Download.html">Download</a></li> 57<li><a href="Download.html">Download</a></li>
40<li><a href="Server-requirements.html">Server requirements</a></li> 58<li><a href="Server-requirements.html">Server requirements</a></li>
41<li><a href="Server-configuration.html">Server configuration</a></li> 59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
42<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
43</ul></li> 64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
44<li><a href="Usage.html">Usage</a> 66<li><a href="Usage.html">Usage</a>
45<ul> 67<ul>
46<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 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>
47<li><a href="Firefox-share.html">Firefox share</a></li> 70<li><a href="Firefox-share.html">Firefox share</a></li>
48<li><a href="RSS-feeds.html">RSS feeds</a></li> 71<li><a href="RSS-feeds.html">RSS feeds</a></li>
49</ul></li> 72</ul></li>
50<li>How To 73<li>How To
51<ul> 74<ul>
52<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
53<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> 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>
54<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 79<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
55<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 80<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
56</ul></li> 81</ul></li>
@@ -62,6 +87,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
62<li><a href="Directory-structure.html">Directory structure</a></li> 87<li><a href="Directory-structure.html">Directory structure</a></li>
63<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
64<li><a href="Plugin-System.html">Plugin System</a></li> 89<li><a href="Plugin-System.html">Plugin System</a></li>
90<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
65<li><a href="Security.html">Security</a></li> 91<li><a href="Security.html">Security</a></li>
66<li><a href="Static-analysis.html">Static analysis</a></li> 92<li><a href="Static-analysis.html">Static analysis</a></li>
67<li><a href="Theming.html">Theming</a></li> 93<li><a href="Theming.html">Theming</a></li>
@@ -101,8 +127,8 @@ code > span.er { color: #ff0000; font-weight: bold; }
101<li>Links are stored as an associative array which is serialized, compressed (with deflate), base64-encoded and saved as a comment in a <code>.php</code> file.</li> 127<li>Links are stored as an associative array which is serialized, compressed (with deflate), base64-encoded and saved as a comment in a <code>.php</code> file.</li>
102<li>Even if the server does not support <code>.htaccess</code> files, the data file will still not be readable by URL.</li> 128<li>Even if the server does not support <code>.htaccess</code> files, the data file will still not be readable by URL.</li>
103<li><p>The database looks like this:</p> 129<li><p>The database looks like this:</p>
104<pre class="sourceCode php"><code class="sourceCode php"><span class="kw">&lt;?php</span> <span class="co">/* zP1ZjxxJtiYIvvevEPJ2lDOaLrZv7o...</span> 130<div class="sourceCode"><pre class="sourceCode php"><code class="sourceCode php"><span class="kw">&lt;?php</span> <span class="co">/* zP1ZjxxJtiYIvvevEPJ2lDOaLrZv7o...</span>
105<span class="co">...ka7gaco/Z+TFXM2i7BlfMf8qxpaSSYfKlvqv/x8= */</span> <span class="kw">?&gt;</span></code></pre></li> 131<span class="co">...ka7gaco/Z+TFXM2i7BlfMf8qxpaSSYfKlvqv/x8= */</span> <span class="kw">?&gt;</span></code></pre></div></li>
106<li><p>Small hashes are used to make a link to an entry in Shaarli. They are unique. In fact, the date of the items (eg. <code>20110923_150523</code>) is hashed with CRC32, then converted to base64 and some characters are replaced. They are always 6 characters longs and use only <code>A-Z a-z 0-9 - _</code> and <code>@</code>.</p></li> 132<li><p>Small hashes are used to make a link to an entry in Shaarli. They are unique. In fact, the date of the items (eg. <code>20110923_150523</code>) is hashed with CRC32, then converted to base64 and some characters are replaced. They are always 6 characters longs and use only <code>A-Z a-z 0-9 - _</code> and <code>@</code>.</p></li>
107</ul> 133</ul>
108</body> 134</body>
diff --git a/doc/Server-configuration.html b/doc/Server-configuration.html
index 3aa89722..1d2276df 100644
--- a/doc/Server-configuration.html
+++ b/doc/Server-configuration.html
@@ -4,31 +4,49 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Server configuration</title> 7 <title>Shaarli – Server configuration</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <style type="text/css"> 9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
13table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
14 margin: 0; padding: 0; vertical-align: baseline; border: none; } 12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
15table.sourceCode { width: 100%; line-height: 100%; } 13table.sourceCode { width: 100%; line-height: 100%; }
16td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } 14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
17td.sourceCode { padding-left: 5px; } 15td.sourceCode { padding-left: 5px; }
18code > span.kw { color: #007020; font-weight: bold; } 16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
19code > span.dt { color: #902000; } 17code > span.dt { color: #902000; } /* DataType */
20code > span.dv { color: #40a070; } 18code > span.dv { color: #40a070; } /* DecVal */
21code > span.bn { color: #40a070; } 19code > span.bn { color: #40a070; } /* BaseN */
22code > span.fl { color: #40a070; } 20code > span.fl { color: #40a070; } /* Float */
23code > span.ch { color: #4070a0; } 21code > span.ch { color: #4070a0; } /* Char */
24code > span.st { color: #4070a0; } 22code > span.st { color: #4070a0; } /* String */
25code > span.co { color: #60a0b0; font-style: italic; } 23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
26code > span.ot { color: #007020; } 24code > span.ot { color: #007020; } /* Other */
27code > span.al { color: #ff0000; font-weight: bold; } 25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
28code > span.fu { color: #06287e; } 26code > span.fu { color: #06287e; } /* Function */
29code > span.er { color: #ff0000; font-weight: bold; } 27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
30 </style> 45 </style>
31 <link rel="stylesheet" href="github-markdown.css"> 46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
32</head> 50</head>
33<body> 51<body>
34<div id="local-sidebar"> 52<div id="local-sidebar">
@@ -39,18 +57,25 @@ code > span.er { color: #ff0000; font-weight: bold; }
39<li><a href="Download.html">Download</a></li> 57<li><a href="Download.html">Download</a></li>
40<li><a href="Server-requirements.html">Server requirements</a></li> 58<li><a href="Server-requirements.html">Server requirements</a></li>
41<li><a href="Server-configuration.html">Server configuration</a></li> 59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
42<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
43</ul></li> 64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
44<li><a href="Usage.html">Usage</a> 66<li><a href="Usage.html">Usage</a>
45<ul> 67<ul>
46<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 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>
47<li><a href="Firefox-share.html">Firefox share</a></li> 70<li><a href="Firefox-share.html">Firefox share</a></li>
48<li><a href="RSS-feeds.html">RSS feeds</a></li> 71<li><a href="RSS-feeds.html">RSS feeds</a></li>
49</ul></li> 72</ul></li>
50<li>How To 73<li>How To
51<ul> 74<ul>
52<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
53<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> 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>
54<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 79<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
55<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 80<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
56</ul></li> 81</ul></li>
@@ -62,6 +87,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
62<li><a href="Directory-structure.html">Directory structure</a></li> 87<li><a href="Directory-structure.html">Directory structure</a></li>
63<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
64<li><a href="Plugin-System.html">Plugin System</a></li> 89<li><a href="Plugin-System.html">Plugin System</a></li>
90<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
65<li><a href="Security.html">Security</a></li> 91<li><a href="Security.html">Security</a></li>
66<li><a href="Static-analysis.html">Static analysis</a></li> 92<li><a href="Static-analysis.html">Static analysis</a></li>
67<li><a href="Theming.html">Theming</a></li> 93<li><a href="Theming.html">Theming</a></li>
@@ -79,10 +105,10 @@ code > span.er { color: #ff0000; font-weight: bold; }
79<p><em>Example virtual host configurations for popular web servers</em></p> 105<p><em>Example virtual host configurations for popular web servers</em></p>
80<ul> 106<ul>
81<li><a href="#apache">Apache</a><a href=".html"></a></li> 107<li><a href="#apache">Apache</a><a href=".html"></a></li>
82<li><a href="#lighthttpd">LightHttpd</a> (empty)<a href=".html"></a></li>
83<li><a href="#nginx">Nginx</a><a href=".html"></a></li> 108<li><a href="#nginx">Nginx</a><a href=".html"></a></li>
84</ul> 109</ul>
85<h2 id="prerequisites">Prerequisites</h2> 110<h2 id="prerequisites">Prerequisites</h2>
111<h3 id="shaarli">Shaarli</h3>
86<ul> 112<ul>
87<li>Shaarli is installed in a directory readable/writeable by the user</li> 113<li>Shaarli is installed in a directory readable/writeable by the user</li>
88<li>the correct read/write permissions have been granted to the web server <em>user and/or group</em></li> 114<li>the correct read/write permissions have been granted to the web server <em>user and/or group</em></li>
@@ -90,25 +116,35 @@ code > span.er { color: #ff0000; font-weight: bold; }
90<li>a key pair (public, private) and a certificate have been generated</li> 116<li>a key pair (public, private) and a certificate have been generated</li>
91<li>the appropriate server SSL extension is installed and active</li> 117<li>the appropriate server SSL extension is installed and active</li>
92</ul> 118</ul>
119<h3 id="https-tls-and-self-signed-certificates">HTTPS, TLS and self-signed certificates</h3>
93<p>Related guides:</p> 120<p>Related guides:</p>
94<ul> 121<ul>
95<li><a href="http://www.xenocafe.com/tutorials/linux/centos/openssl/self_signed_certificates/index.php">How to Create Self-Signed SSL Certificates with OpenSSL</a><a href=".html"></a></li> 122<li><a href="http://www.xenocafe.com/tutorials/linux/centos/openssl/self_signed_certificates/index.php">How to Create Self-Signed SSL Certificates with OpenSSL</a><a href=".html"></a></li>
96<li><a href="https://workaround.org/certificate-authority">How do I create my own Certificate Authority?</a><a href=".html"></a></li> 123<li><a href="https://workaround.org/certificate-authority">How do I create my own Certificate Authority?</a><a href=".html"></a></li>
124<li>Generate a self-signed certificate (will trigger browser warnings) with apache2: <code>make-ssl-cert generate-default-snakeoil --force-overwrite</code> will create <code>/etc/ssl/certs/ssl-cert-snakeoil.pem</code> and <code>/etc/ssl/private/ssl-cert-snakeoil.key</code></li>
125</ul>
126<h3 id="proxies">Proxies</h3>
127<p>If Shaarli is served behind a proxy (i.e. there is a proxy server between clients and the web server hosting Shaarli), please refer to the proxy server documentation for proper configuration. In particular, you have to ensure that the following server variables are properly set:</p>
128<ul>
129<li><code>X-Forwarded-Proto</code>;</li>
130<li><code>X-Forwarded-Host</code>;</li>
131<li><code>X-Forwarded-For</code>.</li>
97</ul> 132</ul>
133<p>See also <a href="https://github.com/shaarli/Shaarli/issues?utf8=%E2%9C%93&amp;q=label%3Aproxy+">proxy-related</a> issues.<a href=".html"></a></p>
98<h2 id="apache">Apache</h2> 134<h2 id="apache">Apache</h2>
99<h3 id="minimal">Minimal</h3> 135<h3 id="minimal">Minimal</h3>
100<pre class="sourceCode apache"><code class="sourceCode apache"><span class="fu">&lt;VirtualHost</span><span class="ot"> *:80</span><span class="fu">&gt;</span> 136<div class="sourceCode"><pre class="sourceCode apache"><code class="sourceCode apache"><span class="fu">&lt;VirtualHost</span><span class="ot"> *:80</span><span class="fu">&gt;</span>
101 ServerName<span class="st"> shaarli.my-domain.org</span> 137 ServerName<span class="st"> shaarli.my-domain.org</span>
102 DocumentRoot<span class="st"> /absolute/path/to/shaarli/</span> 138 DocumentRoot<span class="st"> /absolute/path/to/shaarli/</span>
103<span class="fu">&lt;/VirtualHost&gt;</span></code></pre> 139<span class="fu">&lt;/VirtualHost&gt;</span></code></pre></div>
104<h3 id="debug---log-all-the-things">Debug - Log all the things!</h3> 140<h3 id="debug---log-all-the-things">Debug - Log all the things!</h3>
105<p>This configuration will log both Apache and PHP errors, which may prove useful to identify server configuration errors.</p> 141<p>This configuration will log both Apache and PHP errors, which may prove useful to identify server configuration errors.</p>
106<p>See:</p> 142<p>See:</p>
107<ul> 143<ul>
108<li><a href="http://stackoverflow.com/q/176">Apache/PHP - error log per VirtualHost</a> (StackOverflow)<a href=".html"></a></li> 144<li><a href="http://stackoverflow.com/q/176">Apache/PHP - error log per VirtualHost</a> (StackOverflow)<a href=".html"></a></li>
109<li><a href="PHP:%20php_value%20vs%20php_admin_value%20and%20the%20use%20of%20php_flag%20explained">PHP: php_value vs php_admin_value and the use of php_flag explained</a><a href=".html"></a></li> 145<li><a href="https://ma.ttias.be/php-php_value-vs-php_admin_value-and-the-use-of-php_flag-explained/">PHP: php_value vs php_admin_value and the use of php_flag explained</a><a href=".html"></a></li>
110</ul> 146</ul>
111<pre class="sourceCode apache"><code class="sourceCode apache"><span class="fu">&lt;VirtualHost</span><span class="ot"> *:80</span><span class="fu">&gt;</span> 147<div class="sourceCode"><pre class="sourceCode apache"><code class="sourceCode apache"><span class="fu">&lt;VirtualHost</span><span class="ot"> *:80</span><span class="fu">&gt;</span>
112 ServerName<span class="st"> shaarli.my-domain.org</span> 148 ServerName<span class="st"> shaarli.my-domain.org</span>
113 DocumentRoot<span class="st"> /absolute/path/to/shaarli/</span> 149 DocumentRoot<span class="st"> /absolute/path/to/shaarli/</span>
114 150
@@ -120,24 +156,24 @@ code > span.er { color: #ff0000; font-weight: bold; }
120 php_flag display_errors on 156 php_flag display_errors on
121 php_value error_reporting 2147483647 157 php_value error_reporting 2147483647
122 php_value error_log /var/log/apache2/shaarli-php-error.log 158 php_value error_log /var/log/apache2/shaarli-php-error.log
123<span class="fu">&lt;/VirtualHost&gt;</span></code></pre> 159<span class="fu">&lt;/VirtualHost&gt;</span></code></pre></div>
124<h3 id="standard---keep-access-and-error-logs">Standard - Keep access and error logs</h3> 160<h3 id="standard---keep-access-and-error-logs">Standard - Keep access and error logs</h3>
125<pre class="sourceCode apache"><code class="sourceCode apache"><span class="fu">&lt;VirtualHost</span><span class="ot"> *:80</span><span class="fu">&gt;</span> 161<div class="sourceCode"><pre class="sourceCode apache"><code class="sourceCode apache"><span class="fu">&lt;VirtualHost</span><span class="ot"> *:80</span><span class="fu">&gt;</span>
126 ServerName<span class="st"> shaarli.my-domain.org</span> 162 ServerName<span class="st"> shaarli.my-domain.org</span>
127 DocumentRoot<span class="st"> /absolute/path/to/shaarli/</span> 163 DocumentRoot<span class="st"> /absolute/path/to/shaarli/</span>
128 164
129 <span class="ot">LogLevel</span><span class="ch"> </span><span class="kw">warn</span> 165 <span class="ot">LogLevel</span><span class="ch"> </span><span class="kw">warn</span>
130 ErrorLog<span class="st"> /var/log/apache2/shaarli-error.log</span> 166 ErrorLog<span class="st"> /var/log/apache2/shaarli-error.log</span>
131 CustomLog<span class="st"> /var/log/apache2/shaarli-access.log combined</span> 167 CustomLog<span class="st"> /var/log/apache2/shaarli-access.log combined</span>
132<span class="fu">&lt;/VirtualHost&gt;</span></code></pre> 168<span class="fu">&lt;/VirtualHost&gt;</span></code></pre></div>
133<h3 id="paranoid---redirect-http-80-to-https-443">Paranoid - Redirect HTTP (:80) to HTTPS (:443)</h3> 169<h3 id="paranoid---redirect-http-80-to-https-443">Paranoid - Redirect HTTP (:80) to HTTPS (:443)</h3>
134<p>See <a href="https://wiki.mozilla.org/Security/Server_Side_TLS#Apache">Server-side TLS</a> (Mozilla).<a href=".html"></a></p> 170<p>See <a href="https://wiki.mozilla.org/Security/Server_Side_TLS#Apache">Server-side TLS</a> (Mozilla).<a href=".html"></a></p>
135<pre class="sourceCode apache"><code class="sourceCode apache"><span class="fu">&lt;VirtualHost</span><span class="ot"> *:443</span><span class="fu">&gt;</span> 171<div class="sourceCode"><pre class="sourceCode apache"><code class="sourceCode apache"><span class="fu">&lt;VirtualHost</span><span class="ot"> *:443</span><span class="fu">&gt;</span>
136 ServerName<span class="st"> shaarli.my-domain.org</span> 172 ServerName<span class="st"> shaarli.my-domain.org</span>
137 DocumentRoot<span class="st"> /absolute/path/to/shaarli/</span> 173 DocumentRoot<span class="st"> /absolute/path/to/shaarli/</span>
138 174
139 <span class="ot">SSLEngine</span><span class="ch"> </span><span class="kw">on</span> 175 <span class="ot">SSLEngine</span><span class="ch"> </span><span class="kw">on</span>
140 SSLCertificateFile<span class="st"> /absolute/path/to/the/website/certificate.crt</span> 176 SSLCertificateFile<span class="st"> /absolute/path/to/the/website/certificate.pem</span>
141 SSLCertificateKeyFile<span class="st"> /absolute/path/to/the/website/key.key</span> 177 SSLCertificateKeyFile<span class="st"> /absolute/path/to/the/website/key.key</span>
142 178
143 <span class="fu">&lt;Directory</span><span class="ot"> /absolute/path/to/shaarli/</span><span class="fu">&gt;</span> 179 <span class="fu">&lt;Directory</span><span class="ot"> /absolute/path/to/shaarli/</span><span class="fu">&gt;</span>
@@ -158,7 +194,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
158 <span class="ot">LogLevel</span><span class="ch"> </span><span class="kw">warn</span> 194 <span class="ot">LogLevel</span><span class="ch"> </span><span class="kw">warn</span>
159 ErrorLog<span class="st"> /var/log/apache2/shaarli-error.log</span> 195 ErrorLog<span class="st"> /var/log/apache2/shaarli-error.log</span>
160 CustomLog<span class="st"> /var/log/apache2/shaarli-access.log combined</span> 196 CustomLog<span class="st"> /var/log/apache2/shaarli-access.log combined</span>
161<span class="fu">&lt;/VirtualHost&gt;</span></code></pre> 197<span class="fu">&lt;/VirtualHost&gt;</span></code></pre></div>
162<h2 id="lighthttpd">LightHttpd</h2> 198<h2 id="lighthttpd">LightHttpd</h2>
163<h2 id="nginx">Nginx</h2> 199<h2 id="nginx">Nginx</h2>
164<h3 id="foreword">Foreword</h3> 200<h3 id="foreword">Foreword</h3>
@@ -204,13 +240,13 @@ code > span.er { color: #ff0000; font-weight: bold; }
204<li><code>user:group = john:users</code>,</li> 240<li><code>user:group = john:users</code>,</li>
205</ul> 241</ul>
206<p>which corresponds to the following service configuration:</p> 242<p>which corresponds to the following service configuration:</p>
207<pre class="sourceCode ini"><code class="sourceCode ini"><span class="co">; /etc/php/php-fpm.conf</span> 243<div class="sourceCode"><pre class="sourceCode ini"><code class="sourceCode ini"><span class="co">; /etc/php/php-fpm.conf</span>
208<span class="dt">user </span><span class="ot">=</span><span class="st"> john</span> 244<span class="dt">user </span><span class="ot">=</span><span class="st"> john</span>
209<span class="dt">group </span><span class="ot">=</span><span class="st"> users</span> 245<span class="dt">group </span><span class="ot">=</span><span class="st"> users</span>
210 246
211<span class="kw">[...][]</span><span class="dt">(.html)</span> 247<span class="kw">[...][]</span><span class="dt">(.html)</span>
212<span class="dt">listen.owner </span><span class="ot">=</span><span class="st"> john</span> 248<span class="dt">listen.owner </span><span class="ot">=</span><span class="st"> john</span>
213<span class="dt">listen.group </span><span class="ot">=</span><span class="st"> users</span></code></pre> 249<span class="dt">listen.group </span><span class="ot">=</span><span class="st"> users</span></code></pre></div>
214<pre class="nginx"><code># /etc/nginx/nginx.conf 250<pre class="nginx"><code># /etc/nginx/nginx.conf
215user john users; 251user john users;
216 252
@@ -374,5 +410,10 @@ http {
374 include php.conf; 410 include php.conf;
375 } 411 }
376}</code></pre> 412}</code></pre>
413<h2 id="restricting-search-engines-and-web-crawler-traffic">Restricting search engines and web crawler traffic</h2>
414<p>Creating a <code>robots.txt</code> witht he following contents at the root of your Shaarli installation will prevent &quot;honest&quot; web crawlers from indexing each and every link and Daily page from a Shaarli instance, thus getting rid of a certain amount of unsollicited network traffic.</p>
415<pre><code>User-agent: *
416Disallow: /</code></pre>
417<p>See: <a href="http://www.robotstxt.org/" class="uri">http://www.robotstxt.org/</a>, <a href="http://www.robotstxt.org/robotstxt.html" class="uri">http://www.robotstxt.org/robotstxt.html</a>, <a href="http://www.robotstxt.org/meta.html" class="uri">http://www.robotstxt.org/meta.html</a></p>
377</body> 418</body>
378</html> 419</html>
diff --git a/doc/Server-configuration.md b/doc/Server-configuration.md
index c7b17c5a..fd98a608 100644
--- a/doc/Server-configuration.md
+++ b/doc/Server-configuration.md
@@ -2,19 +2,29 @@
2*Example virtual host configurations for popular web servers* 2*Example virtual host configurations for popular web servers*
3 3
4- [Apache](#apache)[](.html) 4- [Apache](#apache)[](.html)
5- [LightHttpd](#lighthttpd) (empty)[](.html)
6- [Nginx](#nginx)[](.html) 5- [Nginx](#nginx)[](.html)
7 6
8## Prerequisites 7## Prerequisites
8### Shaarli
9* Shaarli is installed in a directory readable/writeable by the user 9* Shaarli is installed in a directory readable/writeable by the user
10* the correct read/write permissions have been granted to the web server _user and/or group_ 10* the correct read/write permissions have been granted to the web server _user and/or group_
11* for HTTPS / SSL: 11* for HTTPS / SSL:
12 * a key pair (public, private) and a certificate have been generated 12 * a key pair (public, private) and a certificate have been generated
13 * the appropriate server SSL extension is installed and active 13 * the appropriate server SSL extension is installed and active
14 14
15### HTTPS, TLS and self-signed certificates
15Related guides: 16Related guides:
16* [How to Create Self-Signed SSL Certificates with OpenSSL](http://www.xenocafe.com/tutorials/linux/centos/openssl/self_signed_certificates/index.php)[](.html) 17* [How to Create Self-Signed SSL Certificates with OpenSSL](http://www.xenocafe.com/tutorials/linux/centos/openssl/self_signed_certificates/index.php)[](.html)
17* [How do I create my own Certificate Authority?](https://workaround.org/certificate-authority)[](.html) 18* [How do I create my own Certificate Authority?](https://workaround.org/certificate-authority)[](.html)
19* Generate a self-signed certificate (will trigger browser warnings) with apache2: `make-ssl-cert generate-default-snakeoil --force-overwrite` will create `/etc/ssl/certs/ssl-cert-snakeoil.pem` and `/etc/ssl/private/ssl-cert-snakeoil.key`
20
21### Proxies
22If Shaarli is served behind a proxy (i.e. there is a proxy server between clients and the web server hosting Shaarli), please refer to the proxy server documentation for proper configuration. In particular, you have to ensure that the following server variables are properly set:
23- `X-Forwarded-Proto`;
24- `X-Forwarded-Host`;
25- `X-Forwarded-For`.
26
27See also [proxy-related](https://github.com/shaarli/Shaarli/issues?utf8=%E2%9C%93&q=label%3Aproxy+) issues.[](.html)
18 28
19## Apache 29## Apache
20### Minimal 30### Minimal
@@ -29,7 +39,7 @@ This configuration will log both Apache and PHP errors, which may prove useful t
29 39
30See: 40See:
31* [Apache/PHP - error log per VirtualHost](http://stackoverflow.com/q/176) (StackOverflow)[](.html) 41* [Apache/PHP - error log per VirtualHost](http://stackoverflow.com/q/176) (StackOverflow)[](.html)
32* [PHP: php_value vs php_admin_value and the use of php_flag explained](PHP: php_value vs php_admin_value and the use of php_flag explained)[](.html) 42* [PHP: php_value vs php_admin_value and the use of php_flag explained](https://ma.ttias.be/php-php_value-vs-php_admin_value-and-the-use-of-php_flag-explained/)[](.html)
33 43
34```apache 44```apache
35<VirtualHost *:80> 45<VirtualHost *:80>
@@ -68,7 +78,7 @@ See [Server-side TLS](https://wiki.mozilla.org/Security/Server_Side_TLS#Apache)
68 DocumentRoot /absolute/path/to/shaarli/ 78 DocumentRoot /absolute/path/to/shaarli/
69 79
70 SSLEngine on 80 SSLEngine on
71 SSLCertificateFile /absolute/path/to/the/website/certificate.crt 81 SSLCertificateFile /absolute/path/to/the/website/certificate.pem
72 SSLCertificateKeyFile /absolute/path/to/the/website/key.key 82 SSLCertificateKeyFile /absolute/path/to/the/website/key.key
73 83
74 <Directory /absolute/path/to/shaarli/> 84 <Directory /absolute/path/to/shaarli/>
@@ -324,3 +334,15 @@ http {
324 } 334 }
325} 335}
326``` 336```
337
338## Restricting search engines and web crawler traffic
339
340Creating a `robots.txt` witht he following contents at the root of your Shaarli installation will prevent "honest" web crawlers from indexing each and every link and Daily page from a Shaarli instance, thus getting rid of a certain amount of unsollicited network traffic.
341
342```
343User-agent: *
344Disallow: /
345```
346
347See: http://www.robotstxt.org/, http://www.robotstxt.org/robotstxt.html, http://www.robotstxt.org/meta.html
348
diff --git a/doc/Server-requirements.html b/doc/Server-requirements.html
index f34f589b..8e4deeb8 100644
--- a/doc/Server-requirements.html
+++ b/doc/Server-requirements.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Server requirements</title> 7 <title>Shaarli – Server requirements</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
@@ -62,6 +70,7 @@
62<ul> 70<ul>
63<li><a href="http://php.net/supported-versions.php">PHP: Supported versions</a><a href=".html"></a></li> 71<li><a href="http://php.net/supported-versions.php">PHP: Supported versions</a><a href=".html"></a></li>
64<li><a href="http://php.net/eol.php">PHP: Unsupported versions</a> <em>(EOL - End Of Life)</em><a href=".html"></a></li> 72<li><a href="http://php.net/eol.php">PHP: Unsupported versions</a> <em>(EOL - End Of Life)</em><a href=".html"></a></li>
73<li><a href="http://php.net/ChangeLog-7.php">PHP 7 Changelog</a><a href=".html"></a></li>
65<li><a href="http://php.net/ChangeLog-5.php">PHP 5 Changelog</a><a href=".html"></a></li> 74<li><a href="http://php.net/ChangeLog-5.php">PHP 5 Changelog</a><a href=".html"></a></li>
66<li><a href="https://bugs.php.net/">PHP: Bugs</a><a href=".html"></a></li> 75<li><a href="https://bugs.php.net/">PHP: Bugs</a><a href=".html"></a></li>
67</ul> 76</ul>
@@ -76,29 +85,29 @@
76</thead> 85</thead>
77<tbody> 86<tbody>
78<tr class="odd"> 87<tr class="odd">
79<td style="text-align: center;">7</td> 88<td style="text-align: center;">7.0</td>
80<td style="text-align: center;">RC2</td> 89<td style="text-align: center;">Supported</td>
81<td style="text-align: center;">planned</td> 90<td style="text-align: center;">✅</td>
82</tr> 91</tr>
83<tr class="even"> 92<tr class="even">
84<td style="text-align: center;">5.6</td> 93<td style="text-align: center;">5.6</td>
85<td style="text-align: center;">Supported</td> 94<td style="text-align: center;">Supported</td>
86<td style="text-align: center;">:white_check_mark:</td> 95<td style="text-align: center;">✅</td>
87</tr> 96</tr>
88<tr class="odd"> 97<tr class="odd">
89<td style="text-align: center;">5.5</td> 98<td style="text-align: center;">5.5</td>
90<td style="text-align: center;">Supported</td> 99<td style="text-align: center;">Supported</td>
91<td style="text-align: center;">:white_check_mark:</td> 100<td style="text-align: center;">✅</td>
92</tr> 101</tr>
93<tr class="even"> 102<tr class="even">
94<td style="text-align: center;">5.4</td> 103<td style="text-align: center;">5.4</td>
95<td style="text-align: center;">EOL: 2015-09-14</td> 104<td style="text-align: center;">EOL: 2015-09-14</td>
96<td style="text-align: center;">:white_check_mark:</td> 105<td style="text-align: center;">✅</td>
97</tr> 106</tr>
98<tr class="odd"> 107<tr class="odd">
99<td style="text-align: center;">5.3</td> 108<td style="text-align: center;">5.3</td>
100<td style="text-align: center;">EOL: 2014-08-14</td> 109<td style="text-align: center;">EOL: 2014-08-14</td>
101<td style="text-align: center;">:white_check_mark:</td> 110<td style="text-align: center;">✅</td>
102</tr> 111</tr>
103</tbody> 112</tbody>
104</table> 113</table>
@@ -106,32 +115,40 @@
106<ul> 115<ul>
107<li><a href="https://github.com/shaarli/Shaarli/blob/master/.travis.yml">Travis configuration</a><a href=".html"></a></li> 116<li><a href="https://github.com/shaarli/Shaarli/blob/master/.travis.yml">Travis configuration</a><a href=".html"></a></li>
108</ul> 117</ul>
109<p>PHP 7 information:</p>
110<ul>
111<li>Announcements: <a href="http://php.net/archive/2015.php#id2015-07-10-4">Beta1</a>, <a href="http://php.net/archive/2015.php#id2015-08-21-1">RC1</a>, <a href="http://php.net/archive/2015.php#id2015-09-04-1">RC2</a><a href=".html"></a></li>
112<li><a href="https://wiki.php.net/todo/php70">TODOLIST</a><a href=".html"></a></li>
113<li><a href="https://bugs.php.net/search.php?limit=30&amp;order_by=id&amp;direction=DESC&amp;cmd=display&amp;status=Open&amp;bug_type=All&amp;phpver=7.0">Recent bugs</a><a href=".html"></a></li>
114<li><a href="http://git.php.net/?p=php-src.git;a=shortlog;h=refs/heads/PHP-7.0.0">Git repository</a><a href=".html"></a></li>
115</ul>
116<h3 id="extensions">Extensions</h3> 118<h3 id="extensions">Extensions</h3>
117<table> 119<table style="width:19%;">
120<colgroup>
121<col style="width: 5%" />
122<col style="width: 8%" />
123<col style="width: 5%" />
124</colgroup>
118<thead> 125<thead>
119<tr class="header"> 126<tr class="header">
120<th style="text-align: left;">Extension</th> 127<th>Extension</th>
121<th style="text-align: center;">Required?</th> 128<th style="text-align: center;">Required?</th>
122<th style="text-align: left;">Usage</th> 129<th>Usage</th>
123</tr> 130</tr>
124</thead> 131</thead>
125<tbody> 132<tbody>
126<tr class="odd"> 133<tr class="odd">
127<td style="text-align: left;"><a href="http://php.net/manual/en/book.mbstring.php"><code>php-mbstring</code></a></td> 134<td><a href="http://php.net/manual/en/book.openssl.php"><code>openssl</code></a></td>
128<td style="text-align: center;">CentOS, Fedora, RHEL, Windows</td> 135<td style="text-align: center;">All</td>
129<td style="text-align: left;">multibyte (Unicode) string support<a href=".html"></a></td> 136<td>OpenSSL, HTTPS<a href=".html"></a></td>
130</tr> 137</tr>
131<tr class="even"> 138<tr class="even">
132<td style="text-align: left;"><a href="http://php.net/manual/en/book.image.php"><code>php-gd</code></a></td> 139<td><a href="http://php.net/manual/en/book.mbstring.php"><code>php-mbstring</code></a></td>
140<td style="text-align: center;">CentOS, Fedora, RHEL, Windows</td>
141<td>multibyte (Unicode) string support<a href=".html"></a></td>
142</tr>
143<tr class="odd">
144<td><a href="http://php.net/manual/en/book.image.php"><code>php-gd</code></a></td>
133<td style="text-align: center;">-</td> 145<td style="text-align: center;">-</td>
134<td style="text-align: left;">thumbnail resizing<a href=".html"></a></td> 146<td>thumbnail resizing<a href=".html"></a></td>
147</tr>
148<tr class="even">
149<td><a href="http://php.net/manual/fr/book.intl.php"><code>php-intl</code></a></td>
150<td style="text-align: center;">Optional</td>
151<td>Tag cloud intelligent sorting (eg. <code>e-&gt;è-&gt;f</code>)<a href=".html"></a></td>
135</tr> 152</tr>
136</tbody> 153</tbody>
137</table> 154</table>
diff --git a/doc/Server-requirements.md b/doc/Server-requirements.md
index 8f44d606..7955fddf 100644
--- a/doc/Server-requirements.md
+++ b/doc/Server-requirements.md
@@ -3,13 +3,14 @@
3### Release information 3### Release information
4- [PHP: Supported versions](http://php.net/supported-versions.php)[](.html) 4- [PHP: Supported versions](http://php.net/supported-versions.php)[](.html)
5- [PHP: Unsupported versions](http://php.net/eol.php) _(EOL - End Of Life)_[](.html) 5- [PHP: Unsupported versions](http://php.net/eol.php) _(EOL - End Of Life)_[](.html)
6- [PHP 7 Changelog](http://php.net/ChangeLog-7.php)[](.html)
6- [PHP 5 Changelog](http://php.net/ChangeLog-5.php)[](.html) 7- [PHP 5 Changelog](http://php.net/ChangeLog-5.php)[](.html)
7- [PHP: Bugs](https://bugs.php.net/)[](.html) 8- [PHP: Bugs](https://bugs.php.net/)[](.html)
8 9
9### Supported versions 10### Supported versions
10Version | Status | Shaarli compatibility 11Version | Status | Shaarli compatibility
11:---:|:---:|:---: 12:---:|:---:|:---:
127 | RC2 | planned 137.0 | Supported | :white_check_mark:
135.6 | Supported | :white_check_mark: 145.6 | Supported | :white_check_mark:
145.5 | Supported | :white_check_mark: 155.5 | Supported | :white_check_mark:
155.4 | EOL: 2015-09-14 | :white_check_mark: 165.4 | EOL: 2015-09-14 | :white_check_mark:
@@ -18,14 +19,10 @@ Version | Status | Shaarli compatibility
18See also: 19See also:
19- [Travis configuration](https://github.com/shaarli/Shaarli/blob/master/.travis.yml)[](.html) 20- [Travis configuration](https://github.com/shaarli/Shaarli/blob/master/.travis.yml)[](.html)
20 21
21PHP 7 information:
22- Announcements: [Beta1](http://php.net/archive/2015.php#id2015-07-10-4), [RC1](http://php.net/archive/2015.php#id2015-08-21-1), [RC2](http://php.net/archive/2015.php#id2015-09-04-1)[](.html)
23- [TODOLIST](https://wiki.php.net/todo/php70)[](.html)
24- [Recent bugs](https://bugs.php.net/search.php?limit=30&order_by=id&direction=DESC&cmd=display&status=Open&bug_type=All&phpver=7.0)[](.html)
25- [Git repository](http://git.php.net/?p=php-src.git;a=shortlog;h=refs/heads/PHP-7.0.0)[](.html)
26
27### Extensions 22### Extensions
28Extension | Required? | Usage 23Extension | Required? | Usage
29---|:---:|--- 24---|:---:|---
25[`openssl`](http://php.net/manual/en/book.openssl.php) | All | OpenSSL, HTTPS[](.html)
30[`php-mbstring`](http://php.net/manual/en/book.mbstring.php) | CentOS, Fedora, RHEL, Windows | multibyte (Unicode) string support[](.html) 26[`php-mbstring`](http://php.net/manual/en/book.mbstring.php) | CentOS, Fedora, RHEL, Windows | multibyte (Unicode) string support[](.html)
31[`php-gd`](http://php.net/manual/en/book.image.php) | - | thumbnail resizing[](.html) 27[`php-gd`](http://php.net/manual/en/book.image.php) | - | thumbnail resizing[](.html)
28[`php-intl`](http://php.net/manual/fr/book.intl.php) | Optional | Tag cloud intelligent sorting (eg. `e->è->f`)[](.html)
diff --git a/doc/Server-security.html b/doc/Server-security.html
new file mode 100644
index 00000000..6b44a133
--- /dev/null
+++ b/doc/Server-security.html
@@ -0,0 +1,165 @@
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli – Server security</title>
8 <style type="text/css">code{white-space: pre;}</style>
9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
13table.sourceCode { width: 100%; line-height: 100%; }
14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
15td.sourceCode { padding-left: 5px; }
16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
17code > span.dt { color: #902000; } /* DataType */
18code > span.dv { color: #40a070; } /* DecVal */
19code > span.bn { color: #40a070; } /* BaseN */
20code > span.fl { color: #40a070; } /* Float */
21code > span.ch { color: #4070a0; } /* Char */
22code > span.st { color: #4070a0; } /* String */
23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
24code > span.ot { color: #007020; } /* Other */
25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
26code > span.fu { color: #06287e; } /* Function */
27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
45 </style>
46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
50</head>
51<body>
52<div id="local-sidebar">
53<ul>
54<li><a href="Home.html">Home</a></li>
55<li>Installation
56<ul>
57<li><a href="Download.html">Download</a></li>
58<li><a href="Server-requirements.html">Server requirements</a></li>
59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
66<li><a href="Usage.html">Usage</a>
67<ul>
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</ul></li>
73<li>How To
74<ul>
75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</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>
81</ul></li>
82<li><a href="Troubleshooting.html">Troubleshooting</a></li>
83<li><a href="Development.html">Development</a>
84<ul>
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="Security.html">Security</a></li>
92<li><a href="Static-analysis.html">Static analysis</a></li>
93<li><a href="Theming.html">Theming</a></li>
94<li><a href="Unit-tests.html">Unit tests</a></li>
95</ul></li>
96<li>About
97<ul>
98<li><a href="FAQ.html">FAQ</a></li>
99<li><a href="Community-&amp;-Related-software.html">Community &amp; Related software</a></li>
100<li><a href="TODO.html">TODO</a></li>
101</ul></li>
102</ul>
103</div>
104<h1 id="server-security">Server security</h1>
105<h2 id="php.ini">php.ini</h2>
106<p>PHP settings are defined in:</p>
107<ul>
108<li>a main configuration file, usually found under <code>/etc/php5/php.ini</code>; some distributions provide different configuration environments, e.g.
109<ul>
110<li><code>/etc/php5/php.ini</code> - used when running console scripts</li>
111<li><code>/etc/php5/apache2/php.ini</code> - used when a client requests PHP resources from Apache</li>
112<li><code>/etc/php5/php-fpm.conf</code> - used when PHP requests are proxied to PHP-FPM</li>
113</ul></li>
114<li>additional configuration files/entries, depending on the installed/enabled extensions:
115<ul>
116<li><code>/etc/php/conf.d/xdebug.ini</code></li>
117</ul></li>
118</ul>
119<h3 id="locate-.ini-files">Locate .ini files</h3>
120<h4 id="console-environment">Console environment</h4>
121<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">php</span> --ini
122<span class="kw">Configuration</span> File (php.ini) <span class="kw">Path</span>: /etc/php
123<span class="kw">Loaded</span> Configuration File: /etc/php/php.ini
124<span class="kw">Scan</span> for additional .ini files in: /etc/php/conf.d
125<span class="kw">Additional</span> .ini files parsed: /etc/php/conf.d/xdebug.ini</code></pre></div>
126<h4 id="server-environment">Server environment</h4>
127<ul>
128<li>create a <code>phpinfo.php</code> script located in a path supported by the web server, e.g.
129<ul>
130<li>Apache (with user dirs enabled): <code>/home/myself/public_html/phpinfo.php</code></li>
131<li><code>/var/www/test/phpinfo.php</code></li>
132</ul></li>
133<li>make sure the script is readable by the web server user/group (usually, <code>www</code>, <code>www-data</code> or <code>httpd</code>)</li>
134<li>access the script from a web browser</li>
135<li><p>look at the <em>Loaded Configuration File</em> and <em>Scan this dir for additional .ini files</em> entries</p>
136<div class="sourceCode"><pre class="sourceCode php"><code class="sourceCode php"><span class="kw">&lt;?php</span> <span class="fu">phpinfo</span><span class="ot">();</span> <span class="kw">?&gt;</span></code></pre></div></li>
137</ul>
138<h2 id="fail2ban">fail2ban</h2>
139<p><code>fail2ban</code> is an intrusion prevention framework that reads server (Apache, SSH, etc.) and uses <code>iptables</code> profiles to block brute-force attempts:</p>
140<ul>
141<li><a href="http://www.fail2ban.org/wiki/index.php/Main_Page">Official website</a><a href=".html"></a></li>
142<li><a href="https://github.com/fail2ban/fail2ban">Source code</a><a href=".html"></a></li>
143</ul>
144<h3 id="read-shaarli-logs-to-ban-ips">Read Shaarli logs to ban IPs</h3>
145<p>Example configuration:</p>
146<ul>
147<li>allow 3 login attempts per IP address</li>
148<li>after 3 failures, permanently ban the corresponding IP adddress</li>
149</ul>
150<p><code>/etc/fail2ban/jail.local</code></p>
151<div class="sourceCode"><pre class="sourceCode ini"><code class="sourceCode ini"><span class="kw">[shaarli-auth][]</span><span class="dt">(.html)</span>
152<span class="dt">enabled </span><span class="ot">=</span><span class="st"> </span><span class="kw">true</span>
153<span class="dt">port </span><span class="ot">=</span><span class="st"> https,http</span>
154<span class="dt">filter </span><span class="ot">=</span><span class="st"> shaarli-auth</span>
155<span class="dt">logpath </span><span class="ot">=</span><span class="st"> /var/www/path/to/shaarli/data/log.txt</span>
156<span class="dt">maxretry </span><span class="ot">=</span><span class="st"> </span><span class="dv">3</span>
157<span class="dt">bantime </span><span class="ot">=</span><span class="st"> -</span><span class="dv">1</span></code></pre></div>
158<p><code>/etc/fail2ban/filter.d/shaarli-auth.conf</code></p>
159<div class="sourceCode"><pre class="sourceCode ini"><code class="sourceCode ini"><span class="kw">[INCLUDES][]</span><span class="dt">(.html)</span>
160<span class="dt">before </span><span class="ot">=</span><span class="st"> common.conf</span>
161<span class="kw">[Definition][]</span><span class="dt">(.html)</span>
162<span class="dt">failregex </span><span class="ot">=</span><span class="st"> \s-\s&lt;HOST&gt;\s-\sLogin failed for user.*$</span>
163<span class="dt">ignoreregex </span><span class="ot">=</span><span class="st"> </span></code></pre></div>
164</body>
165</html>
diff --git a/doc/Server-security.md b/doc/Server-security.md
new file mode 100644
index 00000000..0d16e284
--- /dev/null
+++ b/doc/Server-security.md
@@ -0,0 +1,60 @@
1#Server security
2## php.ini
3PHP settings are defined in:
4- a main configuration file, usually found under `/etc/php5/php.ini`; some distributions provide different configuration environments, e.g.
5 - `/etc/php5/php.ini` - used when running console scripts
6 - `/etc/php5/apache2/php.ini` - used when a client requests PHP resources from Apache
7 - `/etc/php5/php-fpm.conf` - used when PHP requests are proxied to PHP-FPM
8- additional configuration files/entries, depending on the installed/enabled extensions:
9 - `/etc/php/conf.d/xdebug.ini`
10
11### Locate .ini files
12#### Console environment
13```bash
14$ php --ini
15Configuration File (php.ini) Path: /etc/php
16Loaded Configuration File: /etc/php/php.ini
17Scan for additional .ini files in: /etc/php/conf.d
18Additional .ini files parsed: /etc/php/conf.d/xdebug.ini
19```
20
21#### Server environment
22- create a `phpinfo.php` script located in a path supported by the web server, e.g.
23 - Apache (with user dirs enabled): `/home/myself/public_html/phpinfo.php`
24 - `/var/www/test/phpinfo.php`
25- make sure the script is readable by the web server user/group (usually, `www`, `www-data` or `httpd`)
26- access the script from a web browser
27- look at the _Loaded Configuration File_ and _Scan this dir for additional .ini files_ entries
28```php
29<?php phpinfo(); ?>
30```
31
32## fail2ban
33`fail2ban` is an intrusion prevention framework that reads server (Apache, SSH, etc.) and uses `iptables` profiles to block brute-force attempts:
34- [Official website](http://www.fail2ban.org/wiki/index.php/Main_Page)[](.html)
35- [Source code](https://github.com/fail2ban/fail2ban)[](.html)
36
37### Read Shaarli logs to ban IPs
38Example configuration:
39- allow 3 login attempts per IP address
40- after 3 failures, permanently ban the corresponding IP adddress
41
42`/etc/fail2ban/jail.local`
43```ini
44[shaarli-auth][](.html)
45enabled = true
46port = https,http
47filter = shaarli-auth
48logpath = /var/www/path/to/shaarli/data/log.txt
49maxretry = 3
50bantime = -1
51```
52
53`/etc/fail2ban/filter.d/shaarli-auth.conf`
54```ini
55[INCLUDES][](.html)
56before = common.conf
57[Definition][](.html)
58failregex = \s-\s<HOST>\s-\sLogin failed for user.*$
59ignoreregex =
60```
diff --git a/doc/Shaarli-configuration.html b/doc/Shaarli-configuration.html
index b7e29cb3..74947578 100644
--- a/doc/Shaarli-configuration.html
+++ b/doc/Shaarli-configuration.html
@@ -4,31 +4,49 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Shaarli configuration</title> 7 <title>Shaarli – Shaarli configuration</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <style type="text/css"> 9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
13table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
14 margin: 0; padding: 0; vertical-align: baseline; border: none; } 12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
15table.sourceCode { width: 100%; line-height: 100%; } 13table.sourceCode { width: 100%; line-height: 100%; }
16td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } 14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
17td.sourceCode { padding-left: 5px; } 15td.sourceCode { padding-left: 5px; }
18code > span.kw { color: #007020; font-weight: bold; } 16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
19code > span.dt { color: #902000; } 17code > span.dt { color: #902000; } /* DataType */
20code > span.dv { color: #40a070; } 18code > span.dv { color: #40a070; } /* DecVal */
21code > span.bn { color: #40a070; } 19code > span.bn { color: #40a070; } /* BaseN */
22code > span.fl { color: #40a070; } 20code > span.fl { color: #40a070; } /* Float */
23code > span.ch { color: #4070a0; } 21code > span.ch { color: #4070a0; } /* Char */
24code > span.st { color: #4070a0; } 22code > span.st { color: #4070a0; } /* String */
25code > span.co { color: #60a0b0; font-style: italic; } 23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
26code > span.ot { color: #007020; } 24code > span.ot { color: #007020; } /* Other */
27code > span.al { color: #ff0000; font-weight: bold; } 25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
28code > span.fu { color: #06287e; } 26code > span.fu { color: #06287e; } /* Function */
29code > span.er { color: #ff0000; font-weight: bold; } 27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
30 </style> 45 </style>
31 <link rel="stylesheet" href="github-markdown.css"> 46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
32</head> 50</head>
33<body> 51<body>
34<div id="local-sidebar"> 52<div id="local-sidebar">
@@ -39,18 +57,25 @@ code > span.er { color: #ff0000; font-weight: bold; }
39<li><a href="Download.html">Download</a></li> 57<li><a href="Download.html">Download</a></li>
40<li><a href="Server-requirements.html">Server requirements</a></li> 58<li><a href="Server-requirements.html">Server requirements</a></li>
41<li><a href="Server-configuration.html">Server configuration</a></li> 59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
42<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
43</ul></li> 64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
44<li><a href="Usage.html">Usage</a> 66<li><a href="Usage.html">Usage</a>
45<ul> 67<ul>
46<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 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>
47<li><a href="Firefox-share.html">Firefox share</a></li> 70<li><a href="Firefox-share.html">Firefox share</a></li>
48<li><a href="RSS-feeds.html">RSS feeds</a></li> 71<li><a href="RSS-feeds.html">RSS feeds</a></li>
49</ul></li> 72</ul></li>
50<li>How To 73<li>How To
51<ul> 74<ul>
52<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
53<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> 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>
54<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 79<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
55<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 80<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
56</ul></li> 81</ul></li>
@@ -62,6 +87,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
62<li><a href="Directory-structure.html">Directory structure</a></li> 87<li><a href="Directory-structure.html">Directory structure</a></li>
63<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
64<li><a href="Plugin-System.html">Plugin System</a></li> 89<li><a href="Plugin-System.html">Plugin System</a></li>
90<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
65<li><a href="Security.html">Security</a></li> 91<li><a href="Security.html">Security</a></li>
66<li><a href="Static-analysis.html">Static analysis</a></li> 92<li><a href="Static-analysis.html">Static analysis</a></li>
67<li><a href="Theming.html">Theming</a></li> 93<li><a href="Theming.html">Theming</a></li>
@@ -81,6 +107,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
81<p>Once your Shaarli instance is installed, the file <code>data/config.php</code> is generated:</p> 107<p>Once your Shaarli instance is installed, the file <code>data/config.php</code> is generated:</p>
82<ul> 108<ul>
83<li>it contains all settings, and can be edited to customize values</li> 109<li>it contains all settings, and can be edited to customize values</li>
110<li>it defines which <a href="Plugin-System">plugins</a> are enabled<a href=".html"></a></li>
84<li>its values override those defined in <code>index.php</code></li> 111<li>its values override those defined in <code>index.php</code></li>
85</ul> 112</ul>
86<h2 id="file-and-directory-permissions">File and directory permissions</h2> 113<h2 id="file-and-directory-permissions">File and directory permissions</h2>
@@ -88,14 +115,14 @@ code > span.er { color: #ff0000; font-weight: bold; }
88<ul> 115<ul>
89<li><code>read</code> access to the following resources: 116<li><code>read</code> access to the following resources:
90<ul> 117<ul>
91<li>PHP scripts: <code>index.php</code>, <code>application/*.php</code></li> 118<li>PHP scripts: <code>index.php</code>, <code>application/*.php</code>, <code>plugins/*.php</code></li>
92<li>3rd party PHP and Javascript libraries: <code>inc/*.php</code>, <code>inc\*.js</code></li> 119<li>3rd party PHP and Javascript libraries: <code>inc/*.php</code>, <code>inc/*.js</code></li>
93<li>static assets: 120<li>static assets:
94<ul> 121<ul>
95<li>CSS stylesheets: <code>inc\*.css</code></li> 122<li>CSS stylesheets: <code>inc/*.css</code></li>
96<li><code>images\*</code></li> 123<li><code>images/*</code></li>
97</ul></li> 124</ul></li>
98<li>RainTPL templates: <code>tpl\*.html</code></li> 125<li>RainTPL templates: <code>tpl/*.html</code></li>
99</ul></li> 126</ul></li>
100<li><code>read</code>, <code>write</code> and <code>execution</code> access to the following directories: 127<li><code>read</code>, <code>write</code> and <code>execution</code> access to the following directories:
101<ul> 128<ul>
@@ -117,7 +144,8 @@ code > span.er { color: #ff0000; font-weight: bold; }
117<li>if you have a domain / subdomain to serve Shaarli, <a href="Server-configuration">configure the server</a> accordingly<a href=".html"></a></li> 144<li>if you have a domain / subdomain to serve Shaarli, <a href="Server-configuration">configure the server</a> accordingly<a href=".html"></a></li>
118</ul> 145</ul>
119<h2 id="example-dataconfig.php">Example <code>data/config.php</code></h2> 146<h2 id="example-dataconfig.php">Example <code>data/config.php</code></h2>
120<pre class="sourceCode php"><code class="sourceCode php"><span class="kw">&lt;?php</span> 147<p>See also <a href="Plugin-System.html">Plugin System</a>.</p>
148<div class="sourceCode"><pre class="sourceCode php"><code class="sourceCode php"><span class="kw">&lt;?php</span>
121<span class="co">// User login</span> 149<span class="co">// User login</span>
122<span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;login&#39;</span><span class="ot">]</span> = <span class="st">&#39;&lt;login&gt;&#39;</span><span class="ot">;[](</span>.html<span class="ot">)</span> 150<span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;login&#39;</span><span class="ot">]</span> = <span class="st">&#39;&lt;login&gt;&#39;</span><span class="ot">;[](</span>.html<span class="ot">)</span>
123 151
@@ -146,6 +174,10 @@ code > span.er { color: #ff0000; font-weight: bold; }
146<span class="co">// Whether new links are private by default</span> 174<span class="co">// Whether new links are private by default</span>
147<span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;privateLinkByDefault&#39;</span><span class="ot">]</span> = <span class="kw">false</span><span class="ot">;[](</span>.html<span class="ot">)</span> 175<span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;privateLinkByDefault&#39;</span><span class="ot">]</span> = <span class="kw">false</span><span class="ot">;[](</span>.html<span class="ot">)</span>
148 176
177<span class="co">// Enabled plugins</span>
178<span class="co">// Note: each plugin may provide further settings through its own &quot;config.php&quot;</span>
179<span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;config&#39;</span><span class="ot">[</span><span class="st">&#39;ENABLED_PLUGINS&#39;</span><span class="ot">]</span> = <span class="fu">array</span><span class="ot">(</span><span class="st">&#39;addlink_toolbar&#39;</span><span class="ot">,</span> <span class="st">&#39;qrcode&#39;</span><span class="ot">);](</span><span class="st">&#39;ENABLED_PLUGINS&#39;</span><span class="ot">]</span>-=-<span class="fu">array</span><span class="ot">(</span><span class="st">&#39;addlink_toolbar&#39;</span><span class="ot">,</span>-<span class="st">&#39;qrcode&#39;</span><span class="ot">);</span>.html<span class="ot">)</span>
180
149<span class="co">// Subdirectory where Shaarli stores its data files.</span> 181<span class="co">// Subdirectory where Shaarli stores its data files.</span>
150<span class="co">// You can change it for better security.</span> 182<span class="co">// You can change it for better security.</span>
151<span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;config&#39;</span><span class="ot">[</span><span class="st">&#39;DATADIR&#39;</span><span class="ot">]</span> = <span class="st">&#39;data&#39;</span><span class="ot">;](</span><span class="st">&#39;DATADIR&#39;</span><span class="ot">]</span>-=-<span class="st">&#39;data&#39;</span><span class="ot">;</span>.html<span class="ot">)</span> 183<span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;config&#39;</span><span class="ot">[</span><span class="st">&#39;DATADIR&#39;</span><span class="ot">]</span> = <span class="st">&#39;data&#39;</span><span class="ot">;](</span><span class="st">&#39;DATADIR&#39;</span><span class="ot">]</span>-=-<span class="st">&#39;data&#39;</span><span class="ot">;</span>.html<span class="ot">)</span>
@@ -218,6 +250,11 @@ code > span.er { color: #ff0000; font-weight: bold; }
218<span class="co">// Show an ATOM Feed button next to the Subscribe (RSS) button.</span> 250<span class="co">// Show an ATOM Feed button next to the Subscribe (RSS) button.</span>
219<span class="co">// ATOM feeds are available at the address ?do=atom regardless of this option.</span> 251<span class="co">// ATOM feeds are available at the address ?do=atom regardless of this option.</span>
220<span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;config&#39;</span><span class="ot">[</span><span class="st">&#39;SHOW_ATOM&#39;</span><span class="ot">]</span> = <span class="kw">false</span><span class="ot">;](</span><span class="st">&#39;SHOW_ATOM&#39;</span><span class="ot">]</span>-=-<span class="kw">false</span><span class="ot">;</span>.html<span class="ot">)</span> 252<span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;config&#39;</span><span class="ot">[</span><span class="st">&#39;SHOW_ATOM&#39;</span><span class="ot">]</span> = <span class="kw">false</span><span class="ot">;](</span><span class="st">&#39;SHOW_ATOM&#39;</span><span class="ot">]</span>-=-<span class="kw">false</span><span class="ot">;</span>.html<span class="ot">)</span>
221<span class="kw">?&gt;</span></code></pre> 253
254<span class="co">// Set this to true if the redirector requires encoded URL, false otherwise.</span>
255<span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;config&#39;</span><span class="ot">[</span><span class="st">&#39;REDIRECTOR_URLENCODE&#39;</span><span class="ot">]</span> = <span class="kw">true</span><span class="ot">;](</span><span class="st">&#39;REDIRECTOR_URLENCODE&#39;</span><span class="ot">]</span>-=-<span class="kw">true</span><span class="ot">;</span>.html<span class="ot">)</span>
256<span class="kw">?&gt;</span></code></pre></div>
257<h2 id="additional-configuration">Additional configuration</h2>
258<p>The playvideos plugin may require that you adapt your server's <a href="https://github.com/shaarli/Shaarli/blob/master/plugins/playvideos/README.md#troubleshooting">Content Security Policy</a> configuration to work properly.<a href=".html"></a></p>
222</body> 259</body>
223</html> 260</html>
diff --git a/doc/Shaarli-configuration.md b/doc/Shaarli-configuration.md
index 5bf70a62..d0560d79 100644
--- a/doc/Shaarli-configuration.md
+++ b/doc/Shaarli-configuration.md
@@ -5,17 +5,18 @@
5 5
6Once your Shaarli instance is installed, the file `data/config.php` is generated: 6Once your Shaarli instance is installed, the file `data/config.php` is generated:
7* it contains all settings, and can be edited to customize values 7* it contains all settings, and can be edited to customize values
8* it defines which [plugins](Plugin-System) are enabled[](.html)
8* its values override those defined in `index.php` 9* its values override those defined in `index.php`
9 10
10## File and directory permissions 11## File and directory permissions
11The server process running Shaarli must have: 12The server process running Shaarli must have:
12- `read` access to the following resources: 13- `read` access to the following resources:
13 - PHP scripts: `index.php`, `application/*.php` 14 - PHP scripts: `index.php`, `application/*.php`, `plugins/*.php`
14 - 3rd party PHP and Javascript libraries: `inc/*.php`, `inc\*.js` 15 - 3rd party PHP and Javascript libraries: `inc/*.php`, `inc/*.js`
15 - static assets: 16 - static assets:
16 - CSS stylesheets: `inc\*.css` 17 - CSS stylesheets: `inc/*.css`
17 - `images\*` 18 - `images/*`
18 - RainTPL templates: `tpl\*.html` 19 - RainTPL templates: `tpl/*.html`
19- `read`, `write` and `execution` access to the following directories: 20- `read`, `write` and `execution` access to the following directories:
20 - `cache` - thumbnail cache 21 - `cache` - thumbnail cache
21 - `data` - link data store, configuration options 22 - `data` - link data store, configuration options
@@ -31,6 +32,8 @@ On a Linux distribution:
31- if you have a domain / subdomain to serve Shaarli, [configure the server](Server-configuration) accordingly[](.html) 32- if you have a domain / subdomain to serve Shaarli, [configure the server](Server-configuration) accordingly[](.html)
32 33
33## Example `data/config.php` 34## Example `data/config.php`
35See also [Plugin System](Plugin-System.html).
36
34```php 37```php
35<?php 38<?php
36// User login 39// User login
@@ -61,6 +64,10 @@ $GLOBALS['disablesessionprotection'] = false; [](.html)
61// Whether new links are private by default 64// Whether new links are private by default
62$GLOBALS['privateLinkByDefault'] = false;[](.html) 65$GLOBALS['privateLinkByDefault'] = false;[](.html)
63 66
67// Enabled plugins
68// Note: each plugin may provide further settings through its own "config.php"
69$GLOBALS['config'['ENABLED_PLUGINS'] = array('addlink_toolbar', 'qrcode');]('ENABLED_PLUGINS']-=-array('addlink_toolbar',-'qrcode');.html)
70
64// Subdirectory where Shaarli stores its data files. 71// Subdirectory where Shaarli stores its data files.
65// You can change it for better security. 72// You can change it for better security.
66$GLOBALS['config'['DATADIR'] = 'data';]('DATADIR']-=-'data';.html) 73$GLOBALS['config'['DATADIR'] = 'data';]('DATADIR']-=-'data';.html)
@@ -133,5 +140,12 @@ $GLOBALS['config'['PUBSUBHUB_URL'] = '';]('PUBSUBHUB_URL']-=-'';.html)
133// Show an ATOM Feed button next to the Subscribe (RSS) button. 140// Show an ATOM Feed button next to the Subscribe (RSS) button.
134// ATOM feeds are available at the address ?do=atom regardless of this option. 141// ATOM feeds are available at the address ?do=atom regardless of this option.
135$GLOBALS['config'['SHOW_ATOM'] = false;]('SHOW_ATOM']-=-false;.html) 142$GLOBALS['config'['SHOW_ATOM'] = false;]('SHOW_ATOM']-=-false;.html)
143
144// Set this to true if the redirector requires encoded URL, false otherwise.
145$GLOBALS['config'['REDIRECTOR_URLENCODE'] = true;]('REDIRECTOR_URLENCODE']-=-true;.html)
136?> 146?>
137``` 147```
148
149## Additional configuration
150
151The playvideos plugin may require that you adapt your server's [Content Security Policy](https://github.com/shaarli/Shaarli/blob/master/plugins/playvideos/README.md#troubleshooting) configuration to work properly.[](.html)
diff --git a/doc/Shaarli-installation.html b/doc/Shaarli-installation.html
new file mode 100644
index 00000000..487ec1db
--- /dev/null
+++ b/doc/Shaarli-installation.html
@@ -0,0 +1,72 @@
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli – Shaarli installation</title>
8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
10 <!--[if lt IE 9]>
11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
12 <![endif]-->
13</head>
14<body>
15<div id="local-sidebar">
16<ul>
17<li><a href="Home.html">Home</a></li>
18<li>Installation
19<ul>
20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
29<li><a href="Usage.html">Usage</a>
30<ul>
31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
33<li><a href="Firefox-share.html">Firefox share</a></li>
34<li><a href="RSS-feeds.html">RSS feeds</a></li>
35</ul></li>
36<li>How To
37<ul>
38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
44</ul></li>
45<li><a href="Troubleshooting.html">Troubleshooting</a></li>
46<li><a href="Development.html">Development</a>
47<ul>
48<li><a href="GnuPG-signature.html">GnuPG signature</a></li>
49<li><a href="Coding-guidelines.html">Coding guidelines</a></li>
50<li><a href="Directory-structure.html">Directory structure</a></li>
51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
54<li><a href="Security.html">Security</a></li>
55<li><a href="Static-analysis.html">Static analysis</a></li>
56<li><a href="Theming.html">Theming</a></li>
57<li><a href="Unit-tests.html">Unit tests</a></li>
58</ul></li>
59<li>About
60<ul>
61<li><a href="FAQ.html">FAQ</a></li>
62<li><a href="Community-&amp;-Related-software.html">Community &amp; Related software</a></li>
63<li><a href="TODO.html">TODO</a></li>
64</ul></li>
65</ul>
66</div>
67<h1 id="shaarli-installation">Shaarli installation</h1>
68<p>Once Shaarli is downloaded and installed behind a web server, open it in your favorite browser.</p>
69<p><img src="http://i.imgur.com/wuMpDSN.png" alt="install screenshot" /><a href=".html"></a></p>
70<p>Setup your Shaarli installation, and it's ready to use!</p>
71</body>
72</html>
diff --git a/doc/Shaarli-installation.md b/doc/Shaarli-installation.md
new file mode 100644
index 00000000..be9726e0
--- /dev/null
+++ b/doc/Shaarli-installation.md
@@ -0,0 +1,6 @@
1#Shaarli installation
2Once Shaarli is downloaded and installed behind a web server, open it in your favorite browser.
3
4![install screenshot](http://i.imgur.com/wuMpDSN.png)[](.html)
5
6Setup your Shaarli installation, and it's ready to use!
diff --git a/doc/Sharing-button.html b/doc/Sharing-button.html
index 6fa5e77a..3770d8ad 100644
--- a/doc/Sharing-button.html
+++ b/doc/Sharing-button.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Sharing button</title> 7 <title>Shaarli – Sharing button</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
@@ -74,5 +82,13 @@
74<li>You can also check the “Private†box so that the link is saved but only visible to you.</li> 82<li>You can also check the “Private†box so that the link is saved but only visible to you.</li>
75<li>Click <code>Save</code>.<strong>Voilà! Your link is now shared.</strong></li> 83<li>Click <code>Save</code>.<strong>Voilà! Your link is now shared.</strong></li>
76</ul> 84</ul>
85<h3 id="troubleshooting-the-bookmarklet-doesnt-work-with-a-few-website-e.g.-github.com">Troubleshooting: The bookmarklet doesn't work with a few website (e.g. Github.com)</h3>
86<p>Websites which enforce Content Security Policy (CSP), such as github.com, disallow usage of bookmarklets. Unfortunatly, there is nothing Shaarli can do about it.</p>
87<p>See <a href="https://github.com/shaarli/Shaarli#196">#196</a>.<a href=".html"></a></p>
88<p>There is an open bug for both Firefox and Chromium:</p>
89<ul>
90<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=866522" class="uri">https://bugzilla.mozilla.org/show_bug.cgi?id=866522</a></li>
91<li><a href="https://code.google.com/p/chromium/issues/detail?id=233903" class="uri">https://code.google.com/p/chromium/issues/detail?id=233903</a></li>
92</ul>
77</body> 93</body>
78</html> 94</html>
diff --git a/doc/Sharing-button.md b/doc/Sharing-button.md
index fe576a77..e4388863 100644
--- a/doc/Sharing-button.md
+++ b/doc/Sharing-button.md
@@ -17,3 +17,15 @@ _This bookmarklet button is compatible with Firefox, Opera, Chrome and Safari. U
17 * You will be able to edit this link later using the ![(https://raw.githubusercontent.com/shaarli/Shaarli/master/images/edit_icon.png) edit button.]((https://raw.githubusercontent.com/shaarli/Shaarli/master/images/edit_icon.png)-edit-button..html) 17 * You will be able to edit this link later using the ![(https://raw.githubusercontent.com/shaarli/Shaarli/master/images/edit_icon.png) edit button.]((https://raw.githubusercontent.com/shaarli/Shaarli/master/images/edit_icon.png)-edit-button..html)
18 * You can also check the “Private†box so that the link is saved but only visible to you. 18 * You can also check the “Private†box so that the link is saved but only visible to you.
19 * Click `Save`.**Voilà! Your link is now shared.** 19 * Click `Save`.**Voilà! Your link is now shared.**
20
21### Troubleshooting: The bookmarklet doesn't work with a few website (e.g. Github.com)
22
23Websites which enforce Content Security Policy (CSP), such as github.com, disallow usage of bookmarklets. Unfortunatly, there is nothing Shaarli can do about it.
24
25See [#196](https://github.com/shaarli/Shaarli#196).[](.html)
26
27There is an open bug for both Firefox and Chromium:
28
29 * https://bugzilla.mozilla.org/show_bug.cgi?id=866522
30 * https://code.google.com/p/chromium/issues/detail?id=233903
31
diff --git a/doc/Static-analysis.html b/doc/Static-analysis.html
index e95893a8..86cb4696 100644
--- a/doc/Static-analysis.html
+++ b/doc/Static-analysis.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Static analysis</title> 7 <title>Shaarli – Static analysis</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
diff --git a/doc/TODO.html b/doc/TODO.html
index 7a6a4bf6..04224dbf 100644
--- a/doc/TODO.html
+++ b/doc/TODO.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - TODO</title> 7 <title>Shaarli – TODO</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
diff --git a/doc/Theming.html b/doc/Theming.html
index a751eb98..27c5d863 100644
--- a/doc/Theming.html
+++ b/doc/Theming.html
@@ -4,31 +4,49 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Theming</title> 7 <title>Shaarli – Theming</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <style type="text/css"> 9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
13table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
14 margin: 0; padding: 0; vertical-align: baseline; border: none; } 12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
15table.sourceCode { width: 100%; line-height: 100%; } 13table.sourceCode { width: 100%; line-height: 100%; }
16td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } 14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
17td.sourceCode { padding-left: 5px; } 15td.sourceCode { padding-left: 5px; }
18code > span.kw { color: #007020; font-weight: bold; } 16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
19code > span.dt { color: #902000; } 17code > span.dt { color: #902000; } /* DataType */
20code > span.dv { color: #40a070; } 18code > span.dv { color: #40a070; } /* DecVal */
21code > span.bn { color: #40a070; } 19code > span.bn { color: #40a070; } /* BaseN */
22code > span.fl { color: #40a070; } 20code > span.fl { color: #40a070; } /* Float */
23code > span.ch { color: #4070a0; } 21code > span.ch { color: #4070a0; } /* Char */
24code > span.st { color: #4070a0; } 22code > span.st { color: #4070a0; } /* String */
25code > span.co { color: #60a0b0; font-style: italic; } 23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
26code > span.ot { color: #007020; } 24code > span.ot { color: #007020; } /* Other */
27code > span.al { color: #ff0000; font-weight: bold; } 25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
28code > span.fu { color: #06287e; } 26code > span.fu { color: #06287e; } /* Function */
29code > span.er { color: #ff0000; font-weight: bold; } 27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
30 </style> 45 </style>
31 <link rel="stylesheet" href="github-markdown.css"> 46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
32</head> 50</head>
33<body> 51<body>
34<div id="local-sidebar"> 52<div id="local-sidebar">
@@ -39,18 +57,25 @@ code > span.er { color: #ff0000; font-weight: bold; }
39<li><a href="Download.html">Download</a></li> 57<li><a href="Download.html">Download</a></li>
40<li><a href="Server-requirements.html">Server requirements</a></li> 58<li><a href="Server-requirements.html">Server requirements</a></li>
41<li><a href="Server-configuration.html">Server configuration</a></li> 59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
42<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
43</ul></li> 64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
44<li><a href="Usage.html">Usage</a> 66<li><a href="Usage.html">Usage</a>
45<ul> 67<ul>
46<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 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>
47<li><a href="Firefox-share.html">Firefox share</a></li> 70<li><a href="Firefox-share.html">Firefox share</a></li>
48<li><a href="RSS-feeds.html">RSS feeds</a></li> 71<li><a href="RSS-feeds.html">RSS feeds</a></li>
49</ul></li> 72</ul></li>
50<li>How To 73<li>How To
51<ul> 74<ul>
52<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
53<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> 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>
54<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 79<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
55<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 80<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
56</ul></li> 81</ul></li>
@@ -62,6 +87,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
62<li><a href="Directory-structure.html">Directory structure</a></li> 87<li><a href="Directory-structure.html">Directory structure</a></li>
63<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
64<li><a href="Plugin-System.html">Plugin System</a></li> 89<li><a href="Plugin-System.html">Plugin System</a></li>
90<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
65<li><a href="Security.html">Security</a></li> 91<li><a href="Security.html">Security</a></li>
66<li><a href="Static-analysis.html">Static analysis</a></li> 92<li><a href="Static-analysis.html">Static analysis</a></li>
67<li><a href="Theming.html">Theming</a></li> 93<li><a href="Theming.html">Theming</a></li>
@@ -89,14 +115,14 @@ code > span.er { color: #ff0000; font-weight: bold; }
89<h2 id="raintpl-template">RainTPL template</h2> 115<h2 id="raintpl-template">RainTPL template</h2>
90<p><em>WARNING - This feature is currently being worked on and will be improved in the next releases. Experimental.</em></p> 116<p><em>WARNING - This feature is currently being worked on and will be improved in the next releases. Experimental.</em></p>
91<ul> 117<ul>
92<li>Find the template you'd like to install (see the list of <a href="available-templates|Theming#community-themes--templates.html">available templates|Theming#community-themes--templates</a>)</li> 118<li>Find the template you'd like to install (see the list of <a href="available-templates%7CTheming#community-themes--templates.html">available templates|Theming#community-themes--templates</a>)</li>
93<li>Find it's git clone URL or download the zip archive for the template.</li> 119<li>Find it's git clone URL or download the zip archive for the template.</li>
94<li>In your Shaarli <code>tpl/</code> directory, run <code>git clone https://url/of/my-template/</code> or unpack the zip archive. 120<li>In your Shaarli <code>tpl/</code> directory, run <code>git clone https://url/of/my-template/</code> or unpack the zip archive.
95<ul> 121<ul>
96<li>There should now be a <code>my-template/</code> directory under the <code>tpl/</code> dir, containing directly all the template files.</li> 122<li>There should now be a <code>my-template/</code> directory under the <code>tpl/</code> dir, containing directly all the template files.</li>
97</ul></li> 123</ul></li>
98<li><p>Edit <code>data/config.php</code> to have Shaarli use this template, e.g.</p> 124<li><p>Edit <code>data/config.php</code> to have Shaarli use this template, e.g.</p>
99<pre class="sourceCode php"><code class="sourceCode php"><span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;config&#39;</span><span class="ot">[</span><span class="st">&#39;RAINTPL_TPL&#39;</span><span class="ot">]</span> = <span class="st">&#39;tpl/my-template/&#39;</span><span class="ot">;](</span><span class="st">&#39;RAINTPL_TPL&#39;</span><span class="ot">]</span>-=-<span class="st">&#39;tpl/my-template/&#39;</span><span class="ot">;</span>.html<span class="ot">)</span></code></pre></li> 125<div class="sourceCode"><pre class="sourceCode php"><code class="sourceCode php"><span class="kw">$GLOBALS</span><span class="ot">[</span><span class="st">&#39;config&#39;</span><span class="ot">[</span><span class="st">&#39;RAINTPL_TPL&#39;</span><span class="ot">]</span> = <span class="st">&#39;tpl/my-template/&#39;</span><span class="ot">;](</span><span class="st">&#39;RAINTPL_TPL&#39;</span><span class="ot">]</span>-=-<span class="st">&#39;tpl/my-template/&#39;</span><span class="ot">;</span>.html<span class="ot">)</span></code></pre></div></li>
100</ul> 126</ul>
101<h2 id="community-themes-templates">Community themes &amp; templates</h2> 127<h2 id="community-themes-templates">Community themes &amp; templates</h2>
102<ul> 128<ul>
@@ -116,7 +142,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
116<li>user sites are enabled, e.g. <code>/home/user/public_html/somedir</code> is served as <code>http://localhost/~user/somedir</code></li> 142<li>user sites are enabled, e.g. <code>/home/user/public_html/somedir</code> is served as <code>http://localhost/~user/somedir</code></li>
117<li><code>http</code> is the name of the Apache user</li> 143<li><code>http</code> is the name of the Apache user</li>
118</ul> 144</ul>
119<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">cd</span> ~/public_html 145<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">cd</span> ~/public_html
120 146
121<span class="co"># clone repositories</span> 147<span class="co"># clone repositories</span>
122$ <span class="kw">git</span> clone https://github.com/shaarli/Shaarli.git shaarli 148$ <span class="kw">git</span> clone https://github.com/shaarli/Shaarli.git shaarli
@@ -126,15 +152,15 @@ $ <span class="kw">popd</span>
126 152
127<span class="co"># set access rights for Apache</span> 153<span class="co"># set access rights for Apache</span>
128$ <span class="kw">chgrp</span> -R http shaarli 154$ <span class="kw">chgrp</span> -R http shaarli
129$ <span class="kw">chmod</span> g+rwx shaarli shaarli/cache shaarli/data shaarli/pagecache shaarli/tmp</code></pre> 155$ <span class="kw">chmod</span> g+rwx shaarli shaarli/cache shaarli/data shaarli/pagecache shaarli/tmp</code></pre></div>
130<p>Get config written:</p> 156<p>Get config written:</p>
131<ul> 157<ul>
132<li>go to the freshly installed site</li> 158<li>go to the freshly installed site</li>
133<li>fill the install form</li> 159<li>fill the install form</li>
134<li>log in to Shaarli</li> 160<li>log in to Shaarli</li>
135</ul> 161</ul>
136<p>Edit Shaarli's <a href="configuration|Shaarli-configuration.html">configuration|Shaarli configuration</a>:</p> 162<p>Edit Shaarli's <a href="configuration%7CShaarli-configuration.html">configuration|Shaarli configuration</a>:</p>
137<pre class="sourceCode bash"><code class="sourceCode bash"><span class="co"># the file should be owned by Apache, thus not writeable =&gt; sudo</span> 163<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="co"># the file should be owned by Apache, thus not writeable =&gt; sudo</span>
138$ <span class="kw">sudo</span> sed -i s=tpl=tpl/albinomouse-template=g shaarli/data/config.php</code></pre> 164$ <span class="kw">sudo</span> sed -i s=tpl=tpl/albinomouse-template=g shaarli/data/config.php</code></pre></div>
139</body> 165</body>
140</html> 166</html>
diff --git a/doc/Troubleshooting.html b/doc/Troubleshooting.html
index 98fd5354..3de8ad1e 100644
--- a/doc/Troubleshooting.html
+++ b/doc/Troubleshooting.html
@@ -4,31 +4,49 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Troubleshooting</title> 7 <title>Shaarli – Troubleshooting</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <style type="text/css"> 9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
13table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
14 margin: 0; padding: 0; vertical-align: baseline; border: none; } 12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
15table.sourceCode { width: 100%; line-height: 100%; } 13table.sourceCode { width: 100%; line-height: 100%; }
16td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } 14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
17td.sourceCode { padding-left: 5px; } 15td.sourceCode { padding-left: 5px; }
18code > span.kw { color: #007020; font-weight: bold; } 16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
19code > span.dt { color: #902000; } 17code > span.dt { color: #902000; } /* DataType */
20code > span.dv { color: #40a070; } 18code > span.dv { color: #40a070; } /* DecVal */
21code > span.bn { color: #40a070; } 19code > span.bn { color: #40a070; } /* BaseN */
22code > span.fl { color: #40a070; } 20code > span.fl { color: #40a070; } /* Float */
23code > span.ch { color: #4070a0; } 21code > span.ch { color: #4070a0; } /* Char */
24code > span.st { color: #4070a0; } 22code > span.st { color: #4070a0; } /* String */
25code > span.co { color: #60a0b0; font-style: italic; } 23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
26code > span.ot { color: #007020; } 24code > span.ot { color: #007020; } /* Other */
27code > span.al { color: #ff0000; font-weight: bold; } 25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
28code > span.fu { color: #06287e; } 26code > span.fu { color: #06287e; } /* Function */
29code > span.er { color: #ff0000; font-weight: bold; } 27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
30 </style> 45 </style>
31 <link rel="stylesheet" href="github-markdown.css"> 46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
32</head> 50</head>
33<body> 51<body>
34<div id="local-sidebar"> 52<div id="local-sidebar">
@@ -39,18 +57,25 @@ code > span.er { color: #ff0000; font-weight: bold; }
39<li><a href="Download.html">Download</a></li> 57<li><a href="Download.html">Download</a></li>
40<li><a href="Server-requirements.html">Server requirements</a></li> 58<li><a href="Server-requirements.html">Server requirements</a></li>
41<li><a href="Server-configuration.html">Server configuration</a></li> 59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
42<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
43</ul></li> 64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
44<li><a href="Usage.html">Usage</a> 66<li><a href="Usage.html">Usage</a>
45<ul> 67<ul>
46<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 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>
47<li><a href="Firefox-share.html">Firefox share</a></li> 70<li><a href="Firefox-share.html">Firefox share</a></li>
48<li><a href="RSS-feeds.html">RSS feeds</a></li> 71<li><a href="RSS-feeds.html">RSS feeds</a></li>
49</ul></li> 72</ul></li>
50<li>How To 73<li>How To
51<ul> 74<ul>
52<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
53<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> 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>
54<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 79<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
55<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 80<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
56</ul></li> 81</ul></li>
@@ -62,6 +87,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
62<li><a href="Directory-structure.html">Directory structure</a></li> 87<li><a href="Directory-structure.html">Directory structure</a></li>
63<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
64<li><a href="Plugin-System.html">Plugin System</a></li> 89<li><a href="Plugin-System.html">Plugin System</a></li>
90<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
65<li><a href="Security.html">Security</a></li> 91<li><a href="Security.html">Security</a></li>
66<li><a href="Static-analysis.html">Static analysis</a></li> 92<li><a href="Static-analysis.html">Static analysis</a></li>
67<li><a href="Theming.html">Theming</a></li> 93<li><a href="Theming.html">Theming</a></li>
@@ -131,23 +157,24 @@ code > span.er { color: #ff0000; font-weight: bold; }
131<p>Login form is protected against brute force attacks: 4 failed logins will ban the IP address from login for 30 minutes. Banned IPs can still browse links.</p> 157<p>Login form is protected against brute force attacks: 4 failed logins will ban the IP address from login for 30 minutes. Banned IPs can still browse links.</p>
132<p>To remove the current IP bans, delete the file <code>data/ipbans.php</code></p> 158<p>To remove the current IP bans, delete the file <code>data/ipbans.php</code></p>
133<h3 id="list-of-all-login-attempts">List of all login attempts</h3> 159<h3 id="list-of-all-login-attempts">List of all login attempts</h3>
134<p>The file <code>data/log.txt</code> shows all logins (successful or failed) and bans/lifted bans.<br />Search for <code>failed</code> in this file to look for unauthorized login attempts.</p> 160<p>The file <code>data/log.txt</code> shows all logins (successful or failed) and bans/lifted bans.<br />
161Search for <code>failed</code> in this file to look for unauthorized login attempts.</p>
135<h2 id="hosting-problems">Hosting problems</h2> 162<h2 id="hosting-problems">Hosting problems</h2>
136<h3 id="old-php-versions">Old PHP versions</h3> 163<h3 id="old-php-versions">Old PHP versions</h3>
137<ul> 164<ul>
138<li>On <strong>free.fr</strong> : free.fr now support php 5.6.x(<a href="http://les.pages.perso.chez.free.fr/migrations/php5v6.io">link</a>)and so support now the tag autocompletion but you have to do the following : At the root of your webspace create a <code>sessions</code> directory and a <code>.htaccess</code> file containing:<a href=".html"></a></li> 165<li>On <strong>free.fr</strong> : free.fr now support php 5.6.x(<a href="http://les.pages.perso.chez.free.fr/migrations/php5v6.io">link</a>)and so support now the tag autocompletion but you have to do the following : At the root of your webspace create a <code>sessions</code> directory and a <code>.htaccess</code> file containing:<a href=".html"></a></li>
139</ul> 166</ul>
140<pre class="sourceCode ini"><code class="sourceCode ini"><span class="dt">&lt;IfDefine Free&gt;</span> 167<div class="sourceCode"><pre class="sourceCode ini"><code class="sourceCode ini"><span class="dt">&lt;IfDefine Free&gt;</span>
141<span class="dt">php56 1</span> 168<span class="dt">php56 1</span>
142<span class="dt">&lt;/IfDefine&gt;</span></code></pre> 169<span class="dt">&lt;/IfDefine&gt;</span></code></pre></div>
143<ul> 170<ul>
144<li>If you have an error such as: <code>Parse error: syntax error, unexpected '=', expecting '(' in /links/index.php on line xxx</code>, it means that your host is using php4, not php5. Shaarli requires php 5.1. Try changing the file extension to <code>.php5</code></li> 171<li>If you have an error such as: <code>Parse error: syntax error, unexpected '=', expecting '(' in /links/index.php on line xxx</code>, it means that your host is using php4, not php5. Shaarli requires php 5.1. Try changing the file extension to <code>.php5</code></li>
145<li>On <strong>1and1</strong> : If you add the link from the page (and not from the bookmarklet), Shaarli will no be able to get the title of the page. You will have to enter it manually. (Because they have disabled the ability to download a file through HTTP).</li> 172<li>On <strong>1and1</strong> : If you add the link from the page (and not from the bookmarklet), Shaarli will no be able to get the title of the page. You will have to enter it manually. (Because they have disabled the ability to download a file through HTTP).</li>
146<li>If you have the error <code>Warning: file_get_contents() [function.file-get-contents]: URL file-access is disabled in the server configuration in /…/index.php on line xxx</code>, it means that your host has disabled the ability to fetch a file by HTTP in the php config (Typically in 1and1 hosting). Bad host. Change host. Or comment the following lines:<a href=".html"></a></li> 173<li>If you have the error <code>Warning: file_get_contents() [function.file-get-contents]: URL file-access is disabled in the server configuration in /…/index.php on line xxx</code>, it means that your host has disabled the ability to fetch a file by HTTP in the php config (Typically in 1and1 hosting). Bad host. Change host. Or comment the following lines:<a href=".html"></a></li>
147</ul> 174</ul>
148<pre class="sourceCode php"><code class="sourceCode php"><span class="co">//list($status,$headers,$data) = getHTTP($url,4); // Short timeout to keep the application responsive.</span> 175<div class="sourceCode"><pre class="sourceCode php"><code class="sourceCode php"><span class="co">//list($status,$headers,$data) = getHTTP($url,4); // Short timeout to keep the application responsive.</span>
149<span class="co">// FIXME: Decode charset according to charset specified in either 1) HTTP response headers or 2) &lt;head&gt; in html </span> 176<span class="co">// FIXME: Decode charset according to charset specified in either 1) HTTP response headers or 2) &lt;head&gt; in html </span>
150<span class="co">//if (strpos($status,&#39;200 OK&#39;)) $title=html_extract_title($data);</span></code></pre> 177<span class="co">//if (strpos($status,&#39;200 OK&#39;)) $title=html_extract_title($data);</span></code></pre></div>
151<ul> 178<ul>
152<li>On hosts which forbid outgoing HTTP requests (such as free.fr), some thumbnails will not work.</li> 179<li>On hosts which forbid outgoing HTTP requests (such as free.fr), some thumbnails will not work.</li>
153<li>On <strong>lost-oasis</strong>, RSS doesn't work correctly, because of this message at the begining of the RSS/ATOM feed : <code>&lt;? // tout ce qui est charge ici (generalement des includes et require) est charge en permanence. ?&gt;</code>. To fix this, remove this message from <code>php-include/prepend.php</code></li> 180<li>On <strong>lost-oasis</strong>, RSS doesn't work correctly, because of this message at the begining of the RSS/ATOM feed : <code>&lt;? // tout ce qui est charge ici (generalement des includes et require) est charge en permanence. ?&gt;</code>. To fix this, remove this message from <code>php-include/prepend.php</code></li>
diff --git a/doc/Unit-tests.html b/doc/Unit-tests.html
index 6d760771..7934e346 100644
--- a/doc/Unit-tests.html
+++ b/doc/Unit-tests.html
@@ -4,31 +4,49 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Unit tests</title> 7 <title>Shaarli – Unit tests</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <style type="text/css"> 9 <style type="text/css">
10div.sourceCode { overflow-x: auto; }
13table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 11table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
14 margin: 0; padding: 0; vertical-align: baseline; border: none; } 12 margin: 0; padding: 0; vertical-align: baseline; border: none; }
15table.sourceCode { width: 100%; line-height: 100%; } 13table.sourceCode { width: 100%; line-height: 100%; }
16td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } 14td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
17td.sourceCode { padding-left: 5px; } 15td.sourceCode { padding-left: 5px; }
18code > span.kw { color: #007020; font-weight: bold; } 16code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
19code > span.dt { color: #902000; } 17code > span.dt { color: #902000; } /* DataType */
20code > span.dv { color: #40a070; } 18code > span.dv { color: #40a070; } /* DecVal */
21code > span.bn { color: #40a070; } 19code > span.bn { color: #40a070; } /* BaseN */
22code > span.fl { color: #40a070; } 20code > span.fl { color: #40a070; } /* Float */
23code > span.ch { color: #4070a0; } 21code > span.ch { color: #4070a0; } /* Char */
24code > span.st { color: #4070a0; } 22code > span.st { color: #4070a0; } /* String */
25code > span.co { color: #60a0b0; font-style: italic; } 23code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
26code > span.ot { color: #007020; } 24code > span.ot { color: #007020; } /* Other */
27code > span.al { color: #ff0000; font-weight: bold; } 25code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
28code > span.fu { color: #06287e; } 26code > span.fu { color: #06287e; } /* Function */
29code > span.er { color: #ff0000; font-weight: bold; } 27code > span.er { color: #ff0000; font-weight: bold; } /* Error */
28code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
29code > span.cn { color: #880000; } /* Constant */
30code > span.sc { color: #4070a0; } /* SpecialChar */
31code > span.vs { color: #4070a0; } /* VerbatimString */
32code > span.ss { color: #bb6688; } /* SpecialString */
33code > span.im { } /* Import */
34code > span.va { color: #19177c; } /* Variable */
35code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
36code > span.op { color: #666666; } /* Operator */
37code > span.bu { } /* BuiltIn */
38code > span.ex { } /* Extension */
39code > span.pp { color: #bc7a00; } /* Preprocessor */
40code > span.at { color: #7d9029; } /* Attribute */
41code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
42code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
43code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
44code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
30 </style> 45 </style>
31 <link rel="stylesheet" href="github-markdown.css"> 46 <link rel="stylesheet" href="github-markdown.css">
47 <!--[if lt IE 9]>
48 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
49 <![endif]-->
32</head> 50</head>
33<body> 51<body>
34<div id="local-sidebar"> 52<div id="local-sidebar">
@@ -39,18 +57,25 @@ code > span.er { color: #ff0000; font-weight: bold; }
39<li><a href="Download.html">Download</a></li> 57<li><a href="Download.html">Download</a></li>
40<li><a href="Server-requirements.html">Server requirements</a></li> 58<li><a href="Server-requirements.html">Server requirements</a></li>
41<li><a href="Server-configuration.html">Server configuration</a></li> 59<li><a href="Server-configuration.html">Server configuration</a></li>
60<li><a href="Server-security.html">Server security</a></li>
61<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
42<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 62<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
63<li><a href="Plugins.html">Plugins</a></li>
43</ul></li> 64</ul></li>
65<li><a href="Docker.html">Docker</a></li>
44<li><a href="Usage.html">Usage</a> 66<li><a href="Usage.html">Usage</a>
45<ul> 67<ul>
46<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 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>
47<li><a href="Firefox-share.html">Firefox share</a></li> 70<li><a href="Firefox-share.html">Firefox share</a></li>
48<li><a href="RSS-feeds.html">RSS feeds</a></li> 71<li><a href="RSS-feeds.html">RSS feeds</a></li>
49</ul></li> 72</ul></li>
50<li>How To 73<li>How To
51<ul> 74<ul>
52<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 75<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
76<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
53<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> 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>
54<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 79<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
55<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 80<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
56</ul></li> 81</ul></li>
@@ -62,6 +87,7 @@ code > span.er { color: #ff0000; font-weight: bold; }
62<li><a href="Directory-structure.html">Directory structure</a></li> 87<li><a href="Directory-structure.html">Directory structure</a></li>
63<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
64<li><a href="Plugin-System.html">Plugin System</a></li> 89<li><a href="Plugin-System.html">Plugin System</a></li>
90<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
65<li><a href="Security.html">Security</a></li> 91<li><a href="Security.html">Security</a></li>
66<li><a href="Static-analysis.html">Static analysis</a></li> 92<li><a href="Static-analysis.html">Static analysis</a></li>
67<li><a href="Theming.html">Theming</a></li> 93<li><a href="Theming.html">Theming</a></li>
@@ -84,27 +110,27 @@ code > span.er { color: #ff0000; font-weight: bold; }
84<li>a local version, downloadable <a href="https://getcomposer.org/download/">here</a><a href=".html"></a></li> 110<li>a local version, downloadable <a href="https://getcomposer.org/download/">here</a><a href=".html"></a></li>
85</ul> 111</ul>
86<h4 id="sample-usage">Sample usage</h4> 112<h4 id="sample-usage">Sample usage</h4>
87<pre class="sourceCode bash"><code class="sourceCode bash"><span class="co"># system-wide version</span> 113<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="co"># system-wide version</span>
88$ <span class="kw">composer</span> install 114$ <span class="kw">composer</span> install
89$ <span class="kw">composer</span> update 115$ <span class="kw">composer</span> update
90 116
91<span class="co"># local version</span> 117<span class="co"># local version</span>
92$ <span class="kw">php</span> composer.phar self-update 118$ <span class="kw">php</span> composer.phar self-update
93$ <span class="kw">php</span> composer.phar install 119$ <span class="kw">php</span> composer.phar install
94$ <span class="kw">php</span> composer.phar update</code></pre> 120$ <span class="kw">php</span> composer.phar update</code></pre></div>
95<h4 id="install-shaarli-dev-dependencies">Install Shaarli dev dependencies</h4> 121<h4 id="install-shaarli-dev-dependencies">Install Shaarli dev dependencies</h4>
96<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">cd</span> /path/to/shaarli 122<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">cd</span> /path/to/shaarli
97$ <span class="kw">composer</span> update</code></pre> 123$ <span class="kw">composer</span> update</code></pre></div>
98<h4 id="install-and-enable-xdebug-to-generate-phpunit-coverage-reports">Install and enable Xdebug to generate PHPUnit coverage reports</h4> 124<h4 id="install-and-enable-xdebug-to-generate-phpunit-coverage-reports">Install and enable Xdebug to generate PHPUnit coverage reports</h4>
99<p>For Debian-based distros:</p> 125<p>For Debian-based distros:</p>
100<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">aptitude</span> install php5-xdebug</code></pre> 126<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">aptitude</span> install php5-xdebug</code></pre></div>
101<p>For ArchLinux:</p> 127<p>For ArchLinux:</p>
102<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">pacman</span> -S xdebug</code></pre> 128<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">pacman</span> -S xdebug</code></pre></div>
103<p>Then add the following line to <code>/etc/php/php.ini</code>:</p> 129<p>Then add the following line to <code>/etc/php/php.ini</code>:</p>
104<pre class="sourceCode ini"><code class="sourceCode ini"><span class="dt">zend_extension</span><span class="ot">=</span><span class="st">xdebug.so</span></code></pre> 130<div class="sourceCode"><pre class="sourceCode ini"><code class="sourceCode ini"><span class="dt">zend_extension</span><span class="ot">=</span><span class="st">xdebug.so</span></code></pre></div>
105<h4 id="run-unit-tests">Run unit tests</h4> 131<h4 id="run-unit-tests">Run unit tests</h4>
106<p>Successful test suite:</p> 132<p>Successful test suite:</p>
107<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">make</span> test 133<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">make</span> test
108 134
109<span class="kw">-------</span> 135<span class="kw">-------</span>
110<span class="kw">PHPUNIT</span> 136<span class="kw">PHPUNIT</span>
@@ -117,9 +143,9 @@ $ <span class="kw">composer</span> update</code></pre>
117 143
118<span class="kw">Time</span>: 759 ms, Memory: 8.25Mb 144<span class="kw">Time</span>: 759 ms, Memory: 8.25Mb
119 145
120<span class="kw">OK</span> (36 tests, 65 assertions)</code></pre> 146<span class="kw">OK</span> (36 tests, 65 assertions)</code></pre></div>
121<p>Test suite with failures and errors:</p> 147<p>Test suite with failures and errors:</p>
122<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">make</span> test 148<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">make</span> test
123<span class="kw">-------</span> 149<span class="kw">-------</span>
124<span class="kw">PHPUNIT</span> 150<span class="kw">PHPUNIT</span>
125<span class="kw">-------</span> 151<span class="kw">-------</span>
@@ -165,7 +191,7 @@ DBTest.php on line 79 and defined
165<span class="kw">/home/virtualtam/public_html/shaarli/tests</span>/LinkDBTest.php:<span class="kw">133</span> 191<span class="kw">/home/virtualtam/public_html/shaarli/tests</span>/LinkDBTest.php:<span class="kw">133</span>
166 192
167<span class="kw">FAILURES</span>! 193<span class="kw">FAILURES</span>!
168<span class="kw">Tests</span>: 36, Assertions: 63, Errors: 1, Failures: 2.</code></pre> 194<span class="kw">Tests</span>: 36, Assertions: 63, Errors: 1, Failures: 2.</code></pre></div>
169<h4 id="test-results-and-coverage">Test results and coverage</h4> 195<h4 id="test-results-and-coverage">Test results and coverage</h4>
170<p>By default, PHPUnit will run all suitable tests found under the <code>tests</code> directory.</p> 196<p>By default, PHPUnit will run all suitable tests found under the <code>tests</code> directory.</p>
171<p>Each test has 3 possible outcomes:</p> 197<p>Each test has 3 possible outcomes:</p>
diff --git a/doc/Upgrade-from-original-sebsauvage-Shaarli.html b/doc/Upgrade-from-original-sebsauvage-Shaarli.html
new file mode 100644
index 00000000..db69a0ed
--- /dev/null
+++ b/doc/Upgrade-from-original-sebsauvage-Shaarli.html
@@ -0,0 +1,74 @@
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli – Upgrade from original sebsauvage Shaarli</title>
8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
10 <!--[if lt IE 9]>
11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
12 <![endif]-->
13</head>
14<body>
15<div id="local-sidebar">
16<ul>
17<li><a href="Home.html">Home</a></li>
18<li>Installation
19<ul>
20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
29<li><a href="Usage.html">Usage</a>
30<ul>
31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
33<li><a href="Firefox-share.html">Firefox share</a></li>
34<li><a href="RSS-feeds.html">RSS feeds</a></li>
35</ul></li>
36<li>How To
37<ul>
38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
44</ul></li>
45<li><a href="Troubleshooting.html">Troubleshooting</a></li>
46<li><a href="Development.html">Development</a>
47<ul>
48<li><a href="GnuPG-signature.html">GnuPG signature</a></li>
49<li><a href="Coding-guidelines.html">Coding guidelines</a></li>
50<li><a href="Directory-structure.html">Directory structure</a></li>
51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
54<li><a href="Security.html">Security</a></li>
55<li><a href="Static-analysis.html">Static analysis</a></li>
56<li><a href="Theming.html">Theming</a></li>
57<li><a href="Unit-tests.html">Unit tests</a></li>
58</ul></li>
59<li>About
60<ul>
61<li><a href="FAQ.html">FAQ</a></li>
62<li><a href="Community-&amp;-Related-software.html">Community &amp; Related software</a></li>
63<li><a href="TODO.html">TODO</a></li>
64</ul></li>
65</ul>
66</div>
67<h1 id="upgrade-from-original-sebsauvage-shaarli">Upgrade from original sebsauvage Shaarli</h1>
68<ul>
69<li>Backup your original <code>data/</code> directory.</li>
70<li><a href="https://github.com/shaarli/Shaarli#installation--upgrade">Install</a> and setup the Shaarli community fork.<a href=".html"></a></li>
71<li>Copy your original <code>data</code> directory over the new installation.</li>
72</ul>
73</body>
74</html>
diff --git a/doc/Upgrade-from-original-sebsauvage-Shaarli.md b/doc/Upgrade-from-original-sebsauvage-Shaarli.md
new file mode 100644
index 00000000..6ae0c67b
--- /dev/null
+++ b/doc/Upgrade-from-original-sebsauvage-Shaarli.md
@@ -0,0 +1,4 @@
1#Upgrade from original sebsauvage Shaarli
2 * Backup your original `data/` directory.
3 * [Install](https://github.com/shaarli/Shaarli#installation--upgrade) and setup the Shaarli community fork.[](.html)
4 * Copy your original `data` directory over the new installation.
diff --git a/doc/Usage.html b/doc/Usage.html
index 0ba457f6..2befaa02 100644
--- a/doc/Usage.html
+++ b/doc/Usage.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - Usage</title> 7 <title>Shaarli – Usage</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
diff --git a/doc/_Footer.html b/doc/_Footer.html
index 98032386..a054cc53 100644
--- a/doc/_Footer.html
+++ b/doc/_Footer.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - _Footer</title> 7 <title>Shaarli – _Footer</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
@@ -56,6 +64,7 @@
56</ul></li> 64</ul></li>
57</ul> 65</ul>
58</div> 66</div>
59<h1 id="footer-shaarli-the-personal-minimalist-super-fast-no-database-delicious-clone">_Footer<br /><em>Shaarli, the personal, minimalist, super-fast, no-database delicious clone</em></h1> 67<h1 id="footer-shaarli-the-personal-minimalist-super-fast-no-database-delicious-clone">_Footer<br />
68<em>Shaarli, the personal, minimalist, super-fast, no-database delicious clone</em></h1>
60</body> 69</body>
61</html> 70</html>
diff --git a/doc/_Sidebar.html b/doc/_Sidebar.html
index fbf6dffd..89c2cf8a 100644
--- a/doc/_Sidebar.html
+++ b/doc/_Sidebar.html
@@ -4,12 +4,12 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc"> 5 <meta name="generator" content="pandoc">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>Shaarli - _Sidebar</title> 7 <title>Shaarli – _Sidebar</title>
8 <style type="text/css">code{white-space: pre;}</style> 8 <style type="text/css">code{white-space: pre;}</style>
9 <link rel="stylesheet" href="github-markdown.css">
9 <!--[if lt IE 9]> 10 <!--[if lt IE 9]>
10 <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 11 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
11 <![endif]--> 12 <![endif]-->
12 <link rel="stylesheet" href="github-markdown.css">
13</head> 13</head>
14<body> 14<body>
15<div id="local-sidebar"> 15<div id="local-sidebar">
@@ -20,18 +20,25 @@
20<li><a href="Download.html">Download</a></li> 20<li><a href="Download.html">Download</a></li>
21<li><a href="Server-requirements.html">Server requirements</a></li> 21<li><a href="Server-requirements.html">Server requirements</a></li>
22<li><a href="Server-configuration.html">Server configuration</a></li> 22<li><a href="Server-configuration.html">Server configuration</a></li>
23<li><a href="Server-security.html">Server security</a></li>
24<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
23<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 25<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
26<li><a href="Plugins.html">Plugins</a></li>
24</ul></li> 27</ul></li>
28<li><a href="Docker.html">Docker</a></li>
25<li><a href="Usage.html">Usage</a> 29<li><a href="Usage.html">Usage</a>
26<ul> 30<ul>
27<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 31<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
32<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
28<li><a href="Firefox-share.html">Firefox share</a></li> 33<li><a href="Firefox-share.html">Firefox share</a></li>
29<li><a href="RSS-feeds.html">RSS feeds</a></li> 34<li><a href="RSS-feeds.html">RSS feeds</a></li>
30</ul></li> 35</ul></li>
31<li>How To 36<li>How To
32<ul> 37<ul>
33<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 38<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
39<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
34<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> 40<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>
41<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
35<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 42<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
36<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 43<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
37</ul></li> 44</ul></li>
@@ -43,6 +50,7 @@
43<li><a href="Directory-structure.html">Directory structure</a></li> 50<li><a href="Directory-structure.html">Directory structure</a></li>
44<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 51<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
45<li><a href="Plugin-System.html">Plugin System</a></li> 52<li><a href="Plugin-System.html">Plugin System</a></li>
53<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
46<li><a href="Security.html">Security</a></li> 54<li><a href="Security.html">Security</a></li>
47<li><a href="Static-analysis.html">Static analysis</a></li> 55<li><a href="Static-analysis.html">Static analysis</a></li>
48<li><a href="Theming.html">Theming</a></li> 56<li><a href="Theming.html">Theming</a></li>
@@ -64,18 +72,25 @@
64<li><a href="Download.html">Download</a></li> 72<li><a href="Download.html">Download</a></li>
65<li><a href="Server-requirements.html">Server requirements</a></li> 73<li><a href="Server-requirements.html">Server requirements</a></li>
66<li><a href="Server-configuration.html">Server configuration</a></li> 74<li><a href="Server-configuration.html">Server configuration</a></li>
75<li><a href="Server-security.html">Server security</a></li>
76<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
67<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 77<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
78<li><a href="Plugins.html">Plugins</a></li>
68</ul></li> 79</ul></li>
80<li><a href="Docker.html">Docker</a></li>
69<li><a href="Usage.html">Usage</a> 81<li><a href="Usage.html">Usage</a>
70<ul> 82<ul>
71<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 83<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
84<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
72<li><a href="Firefox-share.html">Firefox share</a></li> 85<li><a href="Firefox-share.html">Firefox share</a></li>
73<li><a href="RSS-feeds.html">RSS feeds</a></li> 86<li><a href="RSS-feeds.html">RSS feeds</a></li>
74</ul></li> 87</ul></li>
75<li>How To 88<li>How To
76<ul> 89<ul>
77<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 90<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
91<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
78<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> 92<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>
93<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> 94<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> 95<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
81</ul></li> 96</ul></li>
@@ -87,6 +102,7 @@
87<li><a href="Directory-structure.html">Directory structure</a></li> 102<li><a href="Directory-structure.html">Directory structure</a></li>
88<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 103<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
89<li><a href="Plugin-System.html">Plugin System</a></li> 104<li><a href="Plugin-System.html">Plugin System</a></li>
105<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
90<li><a href="Security.html">Security</a></li> 106<li><a href="Security.html">Security</a></li>
91<li><a href="Static-analysis.html">Static analysis</a></li> 107<li><a href="Static-analysis.html">Static analysis</a></li>
92<li><a href="Theming.html">Theming</a></li> 108<li><a href="Theming.html">Theming</a></li>
diff --git a/doc/_Sidebar.md b/doc/_Sidebar.md
index 68e3b9f3..7c71f462 100644
--- a/doc/_Sidebar.md
+++ b/doc/_Sidebar.md
@@ -4,14 +4,21 @@
4 - [Download](Download.html) 4 - [Download](Download.html)
5 - [Server requirements](Server-requirements.html) 5 - [Server requirements](Server-requirements.html)
6 - [Server configuration](Server-configuration.html) 6 - [Server configuration](Server-configuration.html)
7 - [Server security](Server-security.html)
8 - [Shaarli installation](Shaarli-installation.html)
7 - [Shaarli configuration](Shaarli-configuration.html) 9 - [Shaarli configuration](Shaarli-configuration.html)
10 - [Plugins](Plugins.html)
11- [Docker](Docker.html)
8- [Usage](Usage.html) 12- [Usage](Usage.html)
9 - [Sharing button](Sharing-button.html) (bookmarklet) 13 - [Sharing button](Sharing-button.html) (bookmarklet)
14 - [Browsing and Searching](Browsing-and-Searching.html)
10 - [Firefox share](Firefox-share.html) 15 - [Firefox share](Firefox-share.html)
11 - [RSS feeds](RSS-feeds.html) 16 - [RSS feeds](RSS-feeds.html)
12- How To 17- How To
13 - [Backup, restore, import and export](Backup,-restore,-import-and-export.html) 18 - [Backup, restore, import and export](Backup,-restore,-import-and-export.html)
19 - [Upgrade from original sebsauvage/Shaarli](Upgrade-from-original-sebsauvage/Shaarli.html)
14 - [Copy an existing installation over SSH and serve it locally](Copy-an-existing-installation-over-SSH-and-serve-it-locally.html) 20 - [Copy an existing installation over SSH and serve it locally](Copy-an-existing-installation-over-SSH-and-serve-it-locally.html)
21 - [Create and serve multiple Shaarlis (farm)](Create-and-serve-multiple-Shaarlis-(farm).html)
15 - [Download CSS styles from an OPML list](Download-CSS-styles-from-an-OPML-list.html) 22 - [Download CSS styles from an OPML list](Download-CSS-styles-from-an-OPML-list.html)
16 - [Datastore hacks](Datastore-hacks.html) 23 - [Datastore hacks](Datastore-hacks.html)
17- [Troubleshooting](Troubleshooting.html) 24- [Troubleshooting](Troubleshooting.html)
@@ -21,6 +28,7 @@
21 - [Directory structure](Directory-structure.html) 28 - [Directory structure](Directory-structure.html)
22 - [3rd party libraries](3rd-party-libraries.html) 29 - [3rd party libraries](3rd-party-libraries.html)
23 - [Plugin System](Plugin-System.html) 30 - [Plugin System](Plugin-System.html)
31 - [Release Shaarli](Release-Shaarli.html)
24 - [Security](Security.html) 32 - [Security](Security.html)
25 - [Static analysis](Static-analysis.html) 33 - [Static analysis](Static-analysis.html)
26 - [Theming](Theming.html) 34 - [Theming](Theming.html)
diff --git a/doc/images/doc-logo.svg b/doc/images/doc-logo.svg
new file mode 100644
index 00000000..37fc6658
--- /dev/null
+++ b/doc/images/doc-logo.svg
@@ -0,0 +1,522 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<svg
3 xmlns:dc="http://purl.org/dc/elements/1.1/"
4 xmlns:cc="http://creativecommons.org/ns#"
5 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
6 xmlns:svg="http://www.w3.org/2000/svg"
7 xmlns="http://www.w3.org/2000/svg"
8 xmlns:xlink="http://www.w3.org/1999/xlink"
9 width="600"
10 height="240"
11 id="svg2"
12 version="1.1">
13 <title
14 id="title6384">Shaarli Logo</title>
15 <defs
16 id="defs4">
17 <linearGradient
18 id="linearGradient4405">
19 <stop
20 style="stop-color:#000000;stop-opacity:1;"
21 offset="0"
22 id="stop4407" />
23 <stop
24 style="stop-color:#ffffff;stop-opacity:1;"
25 offset="1"
26 id="stop4409" />
27 </linearGradient>
28 <linearGradient
29 id="linearGradient3780">
30 <stop
31 style="stop-color:#8aea00;stop-opacity:1;"
32 offset="0"
33 id="stop3782" />
34 <stop
35 style="stop-color:#ebff36;stop-opacity:1;"
36 offset="1"
37 id="stop3784" />
38 </linearGradient>
39 <linearGradient
40 id="linearGradient4333-6-7">
41 <stop
42 style="stop-color:#ffffff;stop-opacity:1;"
43 offset="0"
44 id="stop4335-0-4" />
45 <stop
46 style="stop-color:#e1e1e1;stop-opacity:1;"
47 offset="1"
48 id="stop4337-49-0" />
49 </linearGradient>
50 <linearGradient
51 xlink:href="#linearGradient4333-6-7"
52 id="linearGradient4435"
53 gradientUnits="userSpaceOnUse"
54 gradientTransform="translate(-606.51586,-487.01655)"
55 x1="845.7998"
56 y1="637.30005"
57 x2="845.7998"
58 y2="509.84348" />
59 <linearGradient
60 xlink:href="#linearGradient3780"
61 id="linearGradient4437"
62 gradientUnits="userSpaceOnUse"
63 gradientTransform="translate(-1434.0326,365.55395)"
64 x1="1984.2427"
65 y1="-348.63434"
66 x2="1984.2427"
67 y2="-293.69879" />
68 <linearGradient
69 xlink:href="#linearGradient4333-6-7"
70 id="linearGradient4439"
71 gradientUnits="userSpaceOnUse"
72 gradientTransform="translate(-699.19746,-487.01655)"
73 x1="845.7998"
74 y1="637.30005"
75 x2="845.7998"
76 y2="509.84348" />
77 <linearGradient
78 xlink:href="#linearGradient4333-6-7"
79 id="linearGradient4441"
80 gradientUnits="userSpaceOnUse"
81 gradientTransform="translate(-699.87915,-487.01655)"
82 x1="845.7998"
83 y1="637.30005"
84 x2="845.7998"
85 y2="509.84348" />
86 <linearGradient
87 xlink:href="#linearGradient4333-6-7"
88 id="linearGradient4443"
89 gradientUnits="userSpaceOnUse"
90 gradientTransform="translate(-703.2869,-487.01655)"
91 x1="845.7998"
92 y1="637.30005"
93 x2="845.7998"
94 y2="509.84348" />
95 <linearGradient
96 xlink:href="#linearGradient4333-6-7"
97 id="linearGradient4445"
98 gradientUnits="userSpaceOnUse"
99 gradientTransform="translate(-701.24225,-487.01655)"
100 x1="845.7998"
101 y1="637.30005"
102 x2="845.7998"
103 y2="509.84348" />
104 <linearGradient
105 xlink:href="#linearGradient4333-6-7"
106 id="linearGradient4447"
107 gradientUnits="userSpaceOnUse"
108 gradientTransform="translate(-699.1976,-487.01655)"
109 x1="845.7998"
110 y1="637.30005"
111 x2="845.7998"
112 y2="509.84348" />
113 <linearGradient
114 xlink:href="#linearGradient4333-6-7"
115 id="linearGradient4449"
116 gradientUnits="userSpaceOnUse"
117 gradientTransform="translate(-701.24225,-487.01655)"
118 x1="845.7998"
119 y1="637.30005"
120 x2="845.7998"
121 y2="509.84348" />
122 <linearGradient
123 xlink:href="#linearGradient4333-6-7"
124 id="linearGradient4451"
125 gradientUnits="userSpaceOnUse"
126 gradientTransform="translate(-701.24225,-487.01655)"
127 x1="845.7998"
128 y1="637.30005"
129 x2="845.7998"
130 y2="509.84348" />
131 <linearGradient
132 xlink:href="#linearGradient4333-6-7"
133 id="linearGradient4453"
134 gradientUnits="userSpaceOnUse"
135 gradientTransform="translate(-701.24225,-487.01655)"
136 x1="845.7998"
137 y1="637.30005"
138 x2="845.7998"
139 y2="509.84348" />
140 <linearGradient
141 y2="509.84348"
142 x2="845.7998"
143 y1="637.30005"
144 x1="845.7998"
145 gradientTransform="translate(-701.24225,-487.01655)"
146 gradientUnits="userSpaceOnUse"
147 id="linearGradient6071"
148 xlink:href="#linearGradient4333-6-7" />
149 <linearGradient
150 y2="509.84348"
151 x2="845.7998"
152 y1="637.30005"
153 x1="845.7998"
154 gradientTransform="translate(-701.24225,-487.01655)"
155 gradientUnits="userSpaceOnUse"
156 id="linearGradient6073"
157 xlink:href="#linearGradient4333-6-7" />
158 <linearGradient
159 y2="509.84348"
160 x2="845.7998"
161 y1="637.30005"
162 x1="845.7998"
163 gradientTransform="translate(-701.24225,-487.01655)"
164 gradientUnits="userSpaceOnUse"
165 id="linearGradient6075"
166 xlink:href="#linearGradient4333-6-7" />
167 <linearGradient
168 y2="509.84348"
169 x2="845.7998"
170 y1="637.30005"
171 x1="845.7998"
172 gradientTransform="translate(-699.1976,-487.01655)"
173 gradientUnits="userSpaceOnUse"
174 id="linearGradient6077"
175 xlink:href="#linearGradient4333-6-7" />
176 <linearGradient
177 y2="509.84348"
178 x2="845.7998"
179 y1="637.30005"
180 x1="845.7998"
181 gradientTransform="translate(-701.24225,-487.01655)"
182 gradientUnits="userSpaceOnUse"
183 id="linearGradient6079"
184 xlink:href="#linearGradient4333-6-7" />
185 <linearGradient
186 y2="509.84348"
187 x2="845.7998"
188 y1="637.30005"
189 x1="845.7998"
190 gradientTransform="translate(-703.2869,-487.01655)"
191 gradientUnits="userSpaceOnUse"
192 id="linearGradient6081"
193 xlink:href="#linearGradient4333-6-7" />
194 <linearGradient
195 y2="509.84348"
196 x2="845.7998"
197 y1="637.30005"
198 x1="845.7998"
199 gradientTransform="translate(-699.87915,-487.01655)"
200 gradientUnits="userSpaceOnUse"
201 id="linearGradient6083"
202 xlink:href="#linearGradient4333-6-7" />
203 <linearGradient
204 y2="509.84348"
205 x2="845.7998"
206 y1="637.30005"
207 x1="845.7998"
208 gradientTransform="translate(-699.19746,-487.01655)"
209 gradientUnits="userSpaceOnUse"
210 id="linearGradient6085"
211 xlink:href="#linearGradient4333-6-7" />
212 <linearGradient
213 y2="-293.69879"
214 x2="1984.2427"
215 y1="-348.63434"
216 x1="1984.2427"
217 gradientTransform="translate(-1434.0326,365.55395)"
218 gradientUnits="userSpaceOnUse"
219 id="linearGradient6087"
220 xlink:href="#linearGradient3780" />
221 <linearGradient
222 y2="509.84348"
223 x2="845.7998"
224 y1="637.30005"
225 x1="845.7998"
226 gradientTransform="translate(-606.51586,-487.01655)"
227 gradientUnits="userSpaceOnUse"
228 id="linearGradient6089"
229 xlink:href="#linearGradient4333-6-7" />
230 <linearGradient
231 y2="-5.3252554"
232 x2="1795.8763"
233 y1="-116.8399"
234 x1="1795.8763"
235 gradientTransform="translate(-1431.3064,219.11539)"
236 gradientUnits="userSpaceOnUse"
237 id="linearGradient6095"
238 xlink:href="#linearGradient4405" />
239 <mask
240 id="mask6091"
241 maskUnits="userSpaceOnUse">
242 <rect
243 y="11.978719"
244 x="8.1208458"
245 height="153.34807"
246 width="582.72266"
247 id="rect6093"
248 style="color:#000000;fill:url(#linearGradient6095);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0" />
249 </mask>
250 </defs>
251 <metadata
252 id="metadata7">
253 <rdf:RDF>
254 <cc:Work
255 rdf:about="">
256 <dc:format>image/svg+xml</dc:format>
257 <dc:type
258 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
259 <dc:title>Shaarli Logo</dc:title>
260 <dc:creator>
261 <cc:Agent>
262 <dc:title>http://blog.idleman.fr/</dc:title>
263 </cc:Agent>
264 </dc:creator>
265 <dc:date>2012-08-29 22:36:01+02:00</dc:date>
266 <dc:publisher>
267 <cc:Agent>
268 <dc:title>http://sebsauvage.net/</dc:title>
269 </cc:Agent>
270 </dc:publisher>
271 <dc:subject>
272 <rdf:Bag>
273 <rdf:li>Shaarli</rdf:li>
274 <rdf:li>Logo</rdf:li>
275 </rdf:Bag>
276 </dc:subject>
277 <dc:contributor>
278 <cc:Agent>
279 <dc:title>http://thatguynamedandy.com/,
280http://mro.name/me</dc:title>
281 </cc:Agent>
282 </dc:contributor>
283 <cc:license
284 rdf:resource="http://www.opensource.org/licenses/zlib-license.php" />
285 <dc:source>http://sebsauvage.net/files/shaarli_logo.zip</dc:source>
286 <dc:relation>http://sebsauvage.net/wiki/doku.php?id=php:shaarli:discussion#comment_09a1e91bc0abc7db6d186a6abf429877</dc:relation>
287 </cc:Work>
288 </rdf:RDF>
289 </metadata>
290 <g
291 style="display:inline"
292 id="layer9">
293 <g
294 id="g6232">
295 <g
296 style="display:inline"
297 id="g5987"
298 transform="matrix(1,0,0,-1,0,323.7441)"
299 mask="url(#mask6091)">
300 <path
301 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
302 d="m 549.36434,78.11349 c -9.4946,1.99352 -9.7027,14.03504 -9.8352,21.77668 0.1121,11.0831 -0.2095,22.9628 4.1417,33.27264 2.0054,4.85047 9.7812,4.74809 10.3195,-1.06753 4.7624,-15.20498 4.7481,-32.01281 1.4946,-47.50541 -0.983,-2.75668 -3.069,-6.35036 -6.1206,-6.47638 z"
303 id="path5989" />
304 <path
305 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
306 d="m 499.48944,47.6175 c -6.4927,-0.34021 -9.3439,6.60543 -8.1121,12.16941 -0.5858,24.07597 -0.3292,48.31194 0.034,72.30837 1.7508,6.96484 14.895,8.48808 15.0166,-0.0712 1.2169,-13.27189 -0.274,-26.75029 0.6639,-40.10232 0.7817,-11.41478 -0.5568,-23.24296 -0.6994,-34.37618 1.5849,-5.10643 -0.4706,-11.12871 -6.9034,-9.92811 z"
307 id="path5991" />
308 <path
309 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
310 d="m 132.42293,35.23407 c -7.6945,2.17125 -5.9206,12.79289 -6.2273,19.00216 1.6106,23.24538 0.8475,46.57408 2.1706,69.81693 0.068,7.09423 3.2021,16.90233 11.8853,16.22657 7.5709,-1.76417 5.7778,-11.8325 5.6557,-17.71589 -0.047,-7.84014 -4.5559,-19.23884 3.9165,-24.30949 7.6405,-5.37547 19.848,0.64078 18.6463,10.39069 -0.3251,8.83089 -2.0837,22.16882 7.8287,26.47493 6.4024,2.92649 10.6176,-5.21693 9.3943,-10.71096 -0.3749,-13.55442 1.2727,-30.22607 -10.711,-39.6768 -7.9735,-4.05845 -18.9828,-5.54515 -26.8307,-0.21351 -1.0372,2.42576 -6.9951,6.95054 -6.4053,1.24546 -1.6949,-15.3749 2.056,-31.45755 -2.3485,-46.40228 -1.2024,-2.63946 -4.0324,-4.45898 -6.9746,-4.12781 z"
311 id="path5993" />
312 <path
313 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
314 d="m 442.14024,64.05759 c -10.165,-0.2579 -20.6562,1.86137 -28.1474,9.18081 -2.8958,2.05591 -1.2663,-4.94966 -4.8395,-5.01742 -5.4074,-2.93338 -11.5829,2.98762 -9.5367,8.75381 0.099,20.06919 -1.977,40.97889 3.8787,60.387 3.1796,4.95849 13.7562,4.09337 12.7037,-2.9891 1.546,-15.53942 -2.968,-32.10549 3.167,-46.86488 4.3319,-8.66318 18.41,-14.13659 25.3718,-5.90704 3.521,6.12624 -0.9752,16.78774 6.8323,20.31879 7.6504,1.3481 9.6041,-9.08157 8.825,-14.7676 -1.6539,-6.72434 -2.1565,-14.5353 -6.6544,-19.99852 -3.1376,-2.78799 -7.564,-3.22067 -11.6005,-3.09585 z"
315 id="path5995" />
316 <path
317 style="color:#000000;fill:url(#linearGradient6071);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
318 d="m 442.38294,54.04595 c -0.1827,-0.005 -0.3789,0.0345 -0.5625,0.0312 -8.6942,-0.15632 -18.301,1.16995 -26.7813,5.96876 -0.368,-0.21564 -0.7676,-0.37654 -1.1562,-0.5625 l 0.031,-0.0625 c -0.2019,-0.10958 -0.4204,-0.1194 -0.625,-0.21875 -0.5569,-0.23563 -1.1103,-0.37966 -1.6874,-0.53125 -6.0741,-2.10894 -12.7994,-0.4336 -16.8438,3.34375 -3.8577,3.60298 -6.0063,9.29062 -5.1562,15.125 0.085,19.31578 -2.292,41.23535 4.3124,63.12499 l 0.4063,1.3125 0.75,1.1875 c 4.4521,6.94297 11.5862,8.53059 18,7.46875 3.2069,-0.53092 6.701,-1.89897 9.5,-5.03125 2.2725,-2.54317 3.5121,-6.27514 3.5937,-9.84375 0,-0.0435 0,-0.0816 0,-0.125 1.7478,-17.81793 -1.8544,-32.72457 2.2813,-43.375 0.6976,-1.23208 3.1856,-3.39065 5.4063,-4.03125 1.1119,-0.32077 1.7363,-0.44325 2.1874,-0.40625 0.051,0.8996 0.2789,2.71568 0.5313,6.0625 0.1821,2.41445 0.4732,5.42185 2.0313,8.8125 1.558,3.39065 4.8419,6.94014 8.8437,8.75 l 1.1563,0.5 1.2187,0.21875 c 4.1545,0.73208 8.9361,-0.28467 12.2187,-2.59375 3.2827,-2.30908 5.1358,-5.31163 6.3126,-8.0625 2.3534,-5.50175 2.5912,-10.54096 1.9374,-15.3125 l -0.062,-0.53125 -0.125,-0.5 c -1.3372,-5.43656 -1.418,-15.17693 -8.6563,-23.96874 l -0.4687,-0.59375 -0.5938,-0.53125 c -6.0316,-5.35952 -13.0425,-5.71213 -18,-5.59376 l 0,-0.0312 z m -20.9688,14.62501 c 0.3103,0.61975 0.1924,0.76755 0.063,0.28125 -0.016,-0.0599 -0.046,-0.21107 -0.063,-0.28125 z m -11.8437,14.15624 c 0.271,0.10418 0.5347,0.22752 0.8125,0.3125 l -0.125,0.21875 -0.125,0.3125 c -0.2313,0.55649 -0.3535,1.10135 -0.5625,1.65625 0.01,-0.84699 -0.01,-1.64903 0,-2.5 z"
319 id="path5997" />
320 <path
321 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:38"
322 d="m 334.93614,43.42895 -1.125,0.0625 c -11.4541,0.68757 -31.1299,2.13948 -42.5313,20.5 l -0.6875,1.15625 -0.5312,1.21875 c -4.0155,9.09454 -1.1737,19.34928 5,25.5 -7.1006,9.03999 -10.5361,20.69833 -9.25,32.65625 -0.7932,13.71238 8.5163,26.58972 21.5624,30.34375 l -0.031,0.0625 c 14.5936,5.02387 28.3345,3.89176 40,1.875 1.1383,0.61027 2.377,1.24208 3.8438,1.84375 3.1932,1.30991 7.6804,2.60895 13.1874,1.96875 5.5071,-0.6402 11.3463,-3.71585 15.0626,-7.53125 l 0.6562,-0.6875 0.5938,-0.75 c 7.375,-9.27994 7.6766,-20.19393 7.1874,-26.8125 -0.4891,-6.61857 -1.0653,-10.99648 -1.0312,-11.375 l 0.125,-1.46875 -0.094,-1.5 c -0.9045,-13.69999 -0.4438,-31.50909 -8.6874,-49.71875 -0.8869,-3.14352 -2.6183,-4.60975 -5,-6.625 -14.193,-12.04738 -29.8012,-10.22761 -37.125,-10.65625 z m -5,69.25 c -0.6975,0.25422 -0.096,-0.059 3.5937,0.375 3.1757,0.3735 8.4922,1.29071 15.3437,0.34375 -0.042,1.60674 -0.047,3.10046 0.031,4.46875 l -1.2187,0.25 c -9.4296,1.92946 -17.7526,2.70557 -24.0626,1.71875 0.3089,-2.61777 2.5558,-6.11412 4.2813,-6.53125 l 1.0313,-0.25 1,-0.375 z"
323 id="path5999" />
324 <path
325 id="path6001"
326 d="m 242.86794,62.94328 c -9.8451,0.59098 -21.9234,2.57343 -27.5069,11.56498 -1.5225,3.44827 2.5155,7.16458 5.8003,4.55483 11.6876,-3.18405 25.8772,-8.64334 36.9368,-1.03196 3.4255,4.6575 3.2712,13.73214 -2.1351,16.8315 -8.1137,1.83399 -16.456,-2.50178 -24.589,0.4626 -12.7407,3.08001 -20.924,16.83116 -18.6463,29.53519 -1.221,6.03853 2.7535,11.58045 8.7182,12.59694 12.2603,4.22059 25.7141,2.25842 37.9688,-0.24909 3.9671,2.72001 9.7011,7.85911 14.3406,3.09585 6.2596,-7.87653 1.273,-19.02318 2.088,-28.06851 -0.9577,-14.50429 -1.0481,-29.91302 -7.0343,-43.1362 -7.0905,-6.01862 -17.2216,-5.6458 -25.9411,-6.15613 z"
327 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
328 <path
329 style="color:#000000;fill:url(#linearGradient6073);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
330 d="m 132.71733,24.19589 c -0.5004,0.0152 -1.0205,0.0363 -1.5312,0.0937 l -0.9063,0.0937 -0.8437,0.25 c -4.2861,1.20943 -8.1936,4.24904 -10.375,7.56249 -2.1816,3.31346 -2.9841,6.56659 -3.4063,9.375 -0.8444,5.61682 -0.3823,10.37282 -0.4687,12.125 l -0.031,0.65625 0.062,0.625 c 1.548,22.34205 0.8033,45.46456 2.125,69.1875 5e-4,0.0505 0.031,0.10568 0.031,0.15625 0.01,0.1151 -0.01,0.22862 0,0.34375 l 0.031,0 c 0.099,4.98929 0.9665,10.43113 4.125,15.90625 3.2605,5.65198 11.0145,11.32149 19.5625,10.65625 l 0.8438,-0.0625 0.8124,-0.1875 c 4.2384,-0.98762 8.3269,-3.79564 10.625,-7.09375 2.1728,-3.63384 4.3342,-6.89183 5.1872,-10.22818 3.8402,7.13335 5.9507,8.04619 13.1566,11.44693 l 0,0.0312 c 0.059,0.0269 0.1281,0.0362 0.1875,0.0625 3.7423,1.65403 8.4312,1.97661 12.2813,0.65625 3.91101,-1.34132 6.71761,-3.90092 8.59371,-6.5 3.336,-4.62154 4.6441,-9.64143 3.9063,-15.25 -0.1718,-6.20746 0.2238,-14.23226 -1.1563,-22.8125 -1.3801,-8.58024 -5.0962,-18.36284 -13.75001,-25.1875 l -0.8437,-0.6875 -0.9688,-0.5 c -7.7653,-3.95251 -17.7087,-6.355 -27.4062,-4.09375 0.4086,-10.28331 1.089,-21.96033 -2.625,-34.5625 l -0.2188,-0.75 -0.3125,-0.71875 c -2.9167,-6.40275 -9.181,-10.82231 -16.6875,-10.59374 z m 6.0625,53.99999 c 0,0.0101 0.05,0.0315 0.062,0.0625 l -0.6245,1.46875 c 0.3311,-0.86163 0.5542,-1.56647 0.5625,-1.53125 z m 36.0625,48.28125 c 0.012,-0.004 0.019,0.005 0.031,0 l 0.063,0.3125 c -0.043,-0.19086 -0.061,-0.25465 -0.094,-0.3125 z"
331 id="path6003" />
332 <path
333 style="fill:#484848;fill-opacity:1;stroke:none"
334 id="path6005"
335 d="m 133.3461,36.09636 c -1.692,0.49428 -2.8155,1.39846 -3.625,2.625 -0.8214,1.24442 -1.3243,2.85069 -1.5938,4.625 -0.5342,3.51732 -0.1953,7.61208 -0.3438,10.8125 0,0.0285 0,0.0654 0,0.0937 1.6063,23.27388 0.8692,46.5905 2.1876,69.75 a 0.88388823,0.88388823 0 0 1 0,0.0625 c 0.033,3.4213 0.83,7.53419 2.5937,10.59375 1.7438,3.02495 4.2922,5.00636 8.2187,4.75 0.011,-7.3e-4 0.02,7.7e-4 0.031,0 1.6857,-0.39978 2.7542,-1.19719 3.5313,-2.3125 0.7819,-1.12237 1.2391,-2.59827 1.4687,-4.25 0.4593,-3.30346 2e-4,-7.22907 -0.062,-10.25 a 0.88388823,0.88388823 0 0 1 0,-0.0312 c -0.023,-3.75401 -1.179,-8.58343 -1.25,-13.1875 -0.071,-4.59014 1.0512,-9.12033 5.5625,-11.84375 0.012,-0.008 0.019,-0.023 0.031,-0.0312 8.2411,-5.75335 21.2001,0.72746 19.9687,11.1875 0,0.011 0,0.0202 0,0.0312 -4e-4,0.01 4e-4,0.0216 0,0.0312 -0.1662,4.44678 -0.6416,9.92071 0.094,14.71875 0.7386,4.81878 2.5857,8.83105 7.2188,10.84375 a 0.88388823,0.88388823 0 0 1 0.031,0 c 1.4264,0.65196 2.625,0.67804 3.6876,0.3125 1.0625,-0.36554 2.0152,-1.15367 2.7812,-2.21875 1.532,-2.13016 2.2012,-5.36524 1.6562,-7.8125 a 0.88388823,0.88388823 0 0 1 0,-0.15625 c -0.1887,-6.82351 0.1073,-14.35845 -1,-21.28125 -1.1026,-6.89383 -3.5864,-13.13587 -9.3124,-17.6875 -7.7294,-3.90433 -18.3437,-5.25802 -25.7813,-0.25 -0.7734,1.48479 -2.3237,3.00623 -4,3.78125 -0.9043,0.41808 -1.982,0.65336 -2.875,0.0312 -0.8519,-0.59346 -1.0866,-1.72753 -0.9687,-3.1875 0.01,-0.0705 -0.01,-0.11538 0,-0.1875 -1.6634,-15.48034 1.9617,-31.38045 -2.2813,-45.9375 -1.0363,-2.2749 -3.4784,-3.85945 -5.9687,-3.625 z" />
336 <path
337 style="color:#000000;fill:url(#linearGradient6075);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
338 d="m 500.00794,37.6397 c -0.47,-0.0246 -0.9099,0.13839 -1.375,0.15625 -0.3182,0.036 -0.6564,-0.0583 -0.9688,0 l 0,0.0937 c -5.9486,0.59666 -11.3199,4.27914 -13.8124,8.625 -2.5191,4.39212 -3.1643,9.07388 -2.4688,13.75001 -0.5691,24.07161 -0.3288,48.17845 0.031,71.96874 l 0.031,1.1875 0.2813,1.125 c 2.2758,9.05358 10.1204,12.94327 17.2812,13.3125 3.5804,0.18461 7.6057,-0.50128 11.25,-3.21875 3.4431,-2.56742 5.753,-7.21537 6.0625,-11.6875 l 0.062,0 c 0.024,-0.26477 0.01,-0.51719 0.031,-0.78125 1.2169,-14.32127 -0.1813,-27.63851 0.6563,-39.5625 0.8412,-12.28307 -0.4559,-23.97948 -0.6563,-34.18749 0.9168,-4.19732 0.7514,-8.64033 -1.75,-13.09376 -2.5398,-4.52202 -8.6787,-7.57722 -14.4374,-7.5625 -0.073,1.9e-4 -0.1457,-0.001 -0.2188,0 l 0,-0.125 z m -0.4375,10.46875 1.5625,8.375 c -0.089,0.0884 -0.5399,0.26586 -0.9688,0.50001 -0.4433,-0.17558 -0.588,-0.31717 -1.125,-0.59376 l 0.5313,-8.28125 z m 1.625,8.6875 0.125,0.65626 c 0,-5.2e-4 -0.146,-0.0578 -0.1563,-0.0625 0.013,-0.26164 0.01,-0.41632 0.031,-0.59376 z"
339 id="path6007" />
340 <path
341 style="fill:#484848;fill-opacity:1;stroke:none"
342 d="m 499.48944,47.6175 c -6.4927,-0.34021 -9.3439,6.60543 -8.1121,12.16941 -0.5858,24.07597 -0.3292,48.31194 0.034,72.30837 1.7508,6.96484 14.895,8.48808 15.0166,-0.0712 1.2169,-13.27189 -0.274,-26.75029 0.6639,-40.10232 0.7817,-11.41478 -0.5568,-23.24296 -0.6994,-34.37618 1.5849,-5.10643 -0.4706,-11.12871 -6.9034,-9.92811 z"
343 id="path6009" />
344 <path
345 style="fill:#000000;fill-opacity:1;stroke:none"
346 d="m 544.51954,53.6313 c -7.5784,-0.46784 -10.6755,10.08558 -4.626,14.19825 6.4831,5.13984 16.9776,-2.57743 12.9884,-10.24836 -1.4384,-3.20261 -5.1136,-4.25984 -8.3624,-3.94989 z"
347 id="path6011" />
348 <path
349 style="fill:#484848;fill-opacity:1;stroke:#484848;stroke-width:38;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
350 d="m 66.312222,57.93009 c -17.370703,0.62829 -30.0641,20.09681 -26.023403,36.39781 2.1928,10.05075 13.8541,12.09708 22.635103,11.4922 7.1377,-0.5151 17.6041,2.45346 16.7319,11.49222 -1.8676,6.29718 -10.9897,4.97438 -16.0667,5.21679 -7.019003,0.3042 -14.551803,-2.83467 -21.309203,-1.0251 -5.546297,3.71601 -0.7698,11.63178 4.4362,13.09902 11.6204,3.85396 24.776703,2.98561 36.677203,0.52396 8.494404,-1.78465 13.976704,-9.66183 14.007304,-18.12905 0.5362,-8.45978 -0.1252,-18.85777 -9.082,-22.63511 -7.833304,-4.5437 -17.524404,-2.59996 -25.744004,-4.64578 -6.504303,-3.75215 -4.590203,-15.08325 3.2137,-15.54417 8.376,-2.645 16.5844,3.54335 24.730904,1.74653 6.8027,-2.75685 5.6777,-13.26551 -1.2924,-15.19486 C 82.177322,57.19274 73.972122,57.9802 66.312222,57.93009 Z"
351 id="path6013" />
352 <path
353 style="color:#000000;fill:url(#linearGradient6077);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
354 d="m 66.146122,46.92095 -0.2187,0.0312 c -25.268203,0.91394 -41.9786,26.29641 -36.375,49.71875 0,0.01 0,0.0214 0,0.0312 0.023,0.0937 0.039,0.18758 0.062,0.28125 l 0.062,0 c 1.4158,6.03031 5.2241,10.72981 9.5937,13.9375 l -1.5937,0.4375 -1.5313,1 c -3.4934,2.34058 -6.2461,6.40677 -7.0312,10.4375 -0.7852,4.03073 0.016,7.64447 1.2812,10.53125 2.4625,5.61698 6.4364,9.72109 12.843797,11.6875 l 0,0.0312 c 0.1235,0.0409 0.2514,0.0537 0.375,0.0937 0.044,0.0142 0.081,0.0484 0.125,0.0625 14.2876,4.59699 29.052403,3.33987 41.875007,0.6875 l 0.031,0 c 13.703,-2.87897 22.354804,-15.23519 22.687504,-28.1875 l 0.031,0 c 0.01,-0.1043 -0.01,-0.23849 0,-0.34375 0,-0.10511 0.031,-0.20733 0.031,-0.3125 l -0.031,0 c 0.275,-4.68022 0.3633,-10.21921 -1.4063,-16.21875 -1.6128,-5.46789 -5.6186,-11.40935 -11.718704,-15.03125 C 110.28983,79.05558 108.57813,56.15757 93.550926,50.6395 83.076822,45.62854 73.121622,46.96476 66.394622,46.92075 l -0.25,0 z M 49.927419,124.0772 c 0.4736,0.11312 0.7429,0.17483 0.6875,0.1875 -0.1379,-0.0437 -0.3009,-0.0484 -0.4375,-0.0937 l -0.25,-0.0937 z"
355 id="path6015" />
356 <path
357 style="fill:#484848;fill-opacity:1;stroke:none"
358 id="path6017"
359 d="M 67.047,59.37761 C 50.7565,60.01346 38.6203,78.63489 42.422,93.97136 a 1.4420115,1.4420115 0 0 1 0,0.0312 c 0.9874,4.52574 3.9833,7.14275 7.9688,8.71875 3.9854,1.576 8.921,1.948 13.1562,1.65625 3.8182,-0.27555 8.4163,0.35581 12.1562,2.34375 3.74,1.98794 6.6157,5.6345 6.125,10.71875 a 1.4420115,1.4420115 0 0 1 -0.062,0.28125 c -0.5618,1.89409 -1.746,3.32797 -3.1876,4.25 -1.4415,0.92203 -3.0867,1.39395 -4.7812,1.65625 -3.3889,0.5246 -7.0334,0.23046 -9.4062,0.34375 -7.4077,0.32104 -14.726,-2.60314 -20.7813,-1.09375 -0.9228,0.69289 -1.3969,1.4625 -1.5625,2.3125 -0.1806,0.92739 -0.017,2.01851 0.4688,3.125 0.9708,2.21298 3.281,4.32492 5.3437,4.90625 a 1.4420115,1.4420115 0 0 1 0.062,0 c 11.2515,3.73156 24.1465,2.93253 35.9062,0.5 7.7821,-1.63499 12.8466,-8.87337 12.875,-16.71875 a 1.4420115,1.4420115 0 0 1 0,-0.0937 c 0.2634,-4.15469 0.2008,-8.71518 -0.9374,-12.5625 -1.1383,-3.84732 -3.227,-6.9152 -7.2813,-8.625 a 1.4420115,1.4420115 0 0 1 -0.1563,-0.0937 c -7.233,-4.1955 -16.6908,-2.33856 -25.375,-4.5 a 1.4420115,1.4420115 0 0 1 -0.375,-0.15625 c -7.593,-4.38022 -5.364,-17.27483 3.5,-18.15625 l 0,-0.0312 c 0.1153,-0.0364 0.2288,-0.0291 0.3438,-0.0625 4.5012,-1.3064 8.8395,-0.37995 12.875,0.59375 4.0804,0.98454 7.88,1.92841 11.4688,1.1875 5.4755,-2.31046 4.4951,-10.8333 -1.1876,-12.40625 a 1.4420115,1.4420115 0 0 1 -0.2812,-0.0937 c -6.5535,-3.28332 -14.4405,-2.57842 -22.1875,-2.625 -0.021,-1.3e-4 -0.042,1.4e-4 -0.062,0 z" />
360 <path
361 style="color:#000000;fill:url(#linearGradient6079);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
362 d="m 334.91414,52.45217 -0.5624,0.0312 c -10.692,0.64182 -26.7608,2.35866 -35.4063,16.28126 l -0.375,0.59375 -0.2813,0.625 c -2.6168,5.92672 -0.4865,12.63582 3.8126,16.24999 2.47,2.0766 6.1544,2.97511 9.8124,2.75 -12.1731,7.16212 -18.9579,21.29295 -17.0937,35.5 -0.9321,10.0329 5.7963,19.42583 15.4375,21.90625 l 0,0.0312 c 13.5839,4.67628 27.0449,3.11875 38.7812,0.90625 1.4491,0.98507 3.2876,2.06677 5.5626,3 2.2748,0.93323 5.2583,1.74964 8.75,1.34375 3.4915,-0.40589 7.1195,-2.30283 9.625,-4.875 l 0.375,-0.34375 0.3124,-0.40625 c 5.3642,-6.74967 5.6479,-14.75709 5.2188,-20.5625 -0.4291,-5.80541 -1.211,-10.50221 -1,-12.84375 l 0.062,-0.78125 -0.062,-0.75 c -0.9297,-14.08097 -0.732,-30.77734 -7.9062,-46.62499 -0.4593,-1.65783 -1.3753,-2.43205 -2.625,-3.4999 -10.8288,-9.19166 -23.8588,-8.03267 -31.8438,-8.50001 l -0.5938,-0.0312 z m 22.0626,47.46875 c 0.2983,4.01025 0.663,7.89337 0.9374,12.09375 -0.3619,6.15055 0.7536,11.18085 1.0313,14.9375 0.091,1.23358 -3e-4,1.89681 -0.031,2.71875 -0.7261,-0.49389 -0.8804,-0.56988 -1.7812,-1.1875 l -3.5,-2.40625 -4.1562,0.84375 c -11.8502,2.42474 -23.4896,3.77093 -32.7188,0.59375 l -0.75,-0.25 -0.8125,-0.15625 c -0.7563,-0.12889 -0.7437,-0.008 -0.5937,-0.75 l 0.375,-1.875 -0.3438,-1.875 c -1.3223,-7.37497 4.0726,-16.31882 11.1562,-18.03125 l 0.5626,-0.15625 0.5312,-0.1875 c 1.5591,-0.56829 3.7957,-0.58273 7.6875,-0.125 3.8918,0.45773 9.2275,1.48444 15.6563,0.0312 l 1.4687,-0.34375 1.3125,-0.75 c 1.5458,-0.8862 2.8481,-1.95265 3.9688,-3.125 z"
363 id="path6019" />
364 <path
365 style="fill:#484848;fill-opacity:1;stroke:none"
366 id="path6021"
367 d="m 442.8461,65.50261 c -9.9417,-0.25223 -20.0112,1.83054 -27.125,8.78125 a 1.4249747,1.4249747 0 0 1 -0.1876,0.125 c -0.4923,0.34955 -1.0141,0.64308 -1.6874,0.65625 -0.6734,0.0132 -1.3402,-0.39879 -1.6876,-0.8125 -0.6947,-0.82743 -0.7686,-1.5945 -0.9687,-2.34375 -0.2001,-0.74925 -0.4246,-1.47139 -0.6563,-1.84375 -0.2316,-0.37236 -0.2624,-0.39819 -0.6874,-0.40625 a 1.4249747,1.4249747 0 0 1 -0.6563,-0.1875 c -2.1511,-1.16691 -4.3134,-0.58174 -5.9063,0.90625 -1.5928,1.48799 -2.4145,3.81205 -1.5937,6.125 a 1.4249747,1.4249747 0 0 1 0.094,0.46875 c 0.099,20.08519 -1.9054,40.73856 3.75,59.71875 1.2377,1.74956 4.0539,2.66609 6.4063,2.28125 1.2075,-0.19755 2.2216,-0.71247 2.8437,-1.40625 0.6222,-0.69378 0.9615,-1.54589 0.75,-2.96875 a 1.4249747,1.4249747 0 0 1 0,-0.375 c 1.5091,-15.16756 -3.1254,-31.94343 3.25,-47.28125 a 1.4249747,1.4249747 0 0 1 0.031,-0.0625 c 2.3884,-4.77662 7.2847,-8.50018 12.5937,-10.03125 5.3091,-1.53107 11.2689,-0.75156 15.1563,3.84375 a 1.4249747,1.4249747 0 0 1 0.1563,0.1875 c 2.0694,3.60071 1.6918,8.0153 1.9687,11.75 0.1385,1.86735 0.4194,3.54061 1.0313,4.875 0.5916,1.2904 1.4751,2.25734 3.0312,3 1.4606,0.20734 2.5297,-0.051 3.4375,-0.6875 0.9587,-0.67214 1.771,-1.81376 2.375,-3.21875 1.2079,-2.80999 1.508,-6.6831 1.1563,-9.25 -1.6601,-6.82503 -2.269,-14.23556 -6.2813,-19.1875 -2.6943,-2.32961 -6.6692,-2.77567 -10.5313,-2.65625 a 1.4249747,1.4249747 0 0 1 -0.062,0 z" />
368 <path
369 style="color:#000000;fill:url(#linearGradient6081);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
370 d="m 548.52594,68.07721 -1.2187,0.25 c -8.6956,1.82574 -14.1425,9.53796 -15.9688,15.68749 -1.8263,6.14954 -1.7462,11.84707 -1.8125,15.71875 l 0,0.125 0,0.125 c 0.1092,10.79916 -0.5536,24.0134 4.9063,37 0.01,0.0225 0.022,0.0401 0.031,0.0625 2.7726,6.62078 9.3817,9.9621 15.5625,9.5625 5.6001,-0.36206 11.8353,-5.2195 13.5,-11.53125 5.3924,-17.21633 5.3013,-35.62075 1.75,-52.53125 l -0.1563,-0.6875 -0.2187,-0.62499 c -0.7814,-2.19128 -1.853,-4.62969 -3.9375,-7.1875 -2.0845,-2.55781 -5.8401,-5.71667 -11.1875,-5.9375 l -1.25,-0.0312 z"
371 id="path6023" />
372 <path
373 style="fill:#484848;fill-opacity:1;stroke:none"
374 id="path6025"
375 d="m 550.1139,78.59636 c -4.5226,0.97522 -6.7823,4.26272 -8,8.375 -1.2232,4.13111 -1.3087,9.03503 -1.375,12.90625 0.1123,11.09592 -0.2043,22.90976 4.0938,33.09375 0.9213,2.22841 3.1731,3.32073 5.25,3.1875 2.0769,-0.13323 3.906,-1.39 4.1562,-4.09375 a 0.46475483,0.46475483 0 0 1 0.031,-0.0937 c 4.7332,-15.11164 4.7084,-31.85462 1.4687,-47.28125 -0.4788,-1.32581 -1.2248,-2.85305 -2.1874,-4.03125 -0.9629,-1.17844 -2.1146,-1.98485 -3.4376,-2.0625 z" />
376 <path
377 style="color:#000000;fill:url(#linearGradient6083);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
378 d="m 242.87094,52.92092 -0.5938,0.0312 c -10.6919,0.64192 -26.7607,2.35873 -35.4062,16.28131 l -0.375,0.59375 -0.2813,0.65625 c -2.6168,5.92671 -0.4864,12.60456 3.8125,16.21874 2.4771,2.0825 6.1757,2.98309 9.8438,2.75 -12.176,7.14722 -18.9659,21.26849 -17.125,35.46875 -0.9665,10.0609 5.7999,19.48906 15.4687,21.96875 l -0.031,0.0312 c 13.5891,4.67806 27.073,3.12012 38.8125,0.90625 1.4445,0.97996 3.2715,2.07302 5.5313,3 2.2749,0.93323 5.2585,1.71839 8.75,1.3125 3.4915,-0.40589 7.1509,-2.27156 9.6562,-4.84375 l 0.3438,-0.375 0.3125,-0.40625 c 5.3641,-6.74969 5.6478,-14.72585 5.2187,-20.53125 -0.4291,-5.8054 -1.2109,-10.50221 -1,-12.84375 l 0.062,-0.78125 -0.062,-0.78125 c -0.9297,-14.081 -0.7006,-30.74608 -7.875,-46.59374 l -0.9375,-2.0625 -1.7187,-1.4375 c -10.8287,-9.19167 -23.8276,-8.06392 -31.8125,-8.53126 l -0.5938,-0.0312 z m 22.0312,47.5 c 0.2974,4.00059 0.6637,7.87292 0.9375,12.0625 -0.3619,6.15055 0.7536,11.2121 1.0313,14.96875 0.091,1.22812 0,1.86766 -0.031,2.6875 -0.7261,-0.49388 -0.8805,-0.56989 -1.7813,-1.1875 l -3.5,-2.40625 -4.1562,0.875 c -11.8502,2.42475 -23.4582,3.77094 -32.6875,0.59375 l -0.7813,-0.28125 -0.8125,-0.125 c -0.7563,-0.12888 -0.7437,-0.0396 -0.5938,-0.78125 l 0.375,-1.84375 -0.3437,-1.875 c -1.3223,-7.37494 4.0726,-16.35008 11.1562,-18.0625 l 0.5625,-0.125 0.5313,-0.1875 c 1.5591,-0.56828 3.7957,-0.58273 7.6875,-0.125 3.8918,0.45773 9.2275,1.45313 15.6562,0 l 1.4688,-0.3125 1.3125,-0.75 c 1.5458,-0.8862 2.8482,-1.95265 3.9687,-3.125 z"
379 id="path6027" />
380 <path
381 style="fill:#484848;fill-opacity:1;stroke:#484848;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
382 id="path6029"
383 d="m 243.6361,64.63031 c -9.6363,0.58398 -20.9336,2.59484 -26.0312,10.625 -0.4035,0.99026 -0.045,1.9107 0.6562,2.5 0.717,0.60234 1.4896,0.85243 2.5626,0 a 1.684398,1.684398 0 0 1 0.625,-0.3125 c 5.775,-1.5733 12.3167,-3.78461 18.9374,-4.625 6.6208,-0.84039 13.4444,-0.25925 19.4063,3.84375 a 1.684398,1.684398 0 0 1 0.375,0.375 c 2.0281,2.75755 2.9112,6.50666 2.5937,10.125 -0.3174,3.61834 -1.9072,7.25777 -5.2187,9.15625 a 1.684398,1.684398 0 0 1 -0.4687,0.1875 c -4.4561,1.00721 -8.7953,0.29068 -12.875,-0.1875 -4.0798,-0.47818 -7.8868,-0.73461 -11.5313,0.59375 a 1.684398,1.684398 0 0 1 -0.1563,0.0312 c -11.7884,2.8498 -19.5228,15.78804 -17.4062,27.59375 a 1.684398,1.684398 0 0 1 0,0.65625 c -1.0407,5.14641 2.2557,9.72666 7.3438,10.59375 a 1.684398,1.684398 0 0 1 0.2812,0.0625 c 11.7498,4.04484 24.8758,2.18109 37.0625,-0.3125 a 1.684398,1.684398 0 0 1 1.2813,0.28125 c 2.0816,1.42722 4.4575,3.29235 6.625,4.1875 1.0837,0.44757 2.0633,0.63094 2.9374,0.53125 0.8627,-0.0984 1.6764,-0.44585 2.5938,-1.375 0.01,-0.0118 0.022,-0.0195 0.031,-0.0312 2.6608,-3.43997 2.9705,-7.61463 2.625,-12.3125 -0.3431,-4.66636 -1.3766,-9.66321 -1,-14.46875 -0.9524,-14.4251 -1.1073,-29.45823 -6.7187,-42.15625 -6.4124,-5.22259 -15.7954,-5.06556 -24.4687,-5.5625 -0.021,-10e-4 -0.042,0.001 -0.063,0 z" />
384 <path
385 style="color:#000000;fill:url(#linearGradient6085);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
386 id="path6031"
387 d="m 252.9376,106.30395 c -3.4993,0.0307 -6.9607,-0.0581 -10.375,0.0312 -4.1004,0.36044 -9.0376,1.69024 -12.625,4.09375 -3.614,2.42133 -5.8704,5.68864 -5.2813,10.4375 0.4935,4.61527 3.5645,7.56447 7.6876,9.21875 4.123,1.65428 9.2633,1.8209 13.1562,0.65625 a 1.3611835,1.3611835 0 0 1 0.1562,-0.0312 c 2.8688,-0.49834 6.5939,-1.2529 9.2813,-2.71875 1.3437,-0.73292 2.3836,-1.63683 3.0313,-2.6875 0.6476,-1.05067 0.9604,-2.26047 0.6874,-3.96875 a 1.3611835,1.3611835 0 0 1 0,-0.28125 c 0.1564,-2.76724 0.3451,-6.68524 -0.375,-9.71875 -0.36,-1.51676 -0.9264,-2.77474 -1.75,-3.625 -0.8176,-0.8442 -1.8698,-1.36151 -3.5624,-1.40625 -0.012,-3.2e-4 -0.019,2.7e-4 -0.031,0 z" />
388 <path
389 style="color:#000000;fill:#305f00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10"
390 d="m 550.24144,11.97714 c -4.7431,8e-5 -9.3884,1.94508 -12.1562,5.65625 -2.3938,3.20927 -3.2655,7.28209 -3.5,11.84374 -5.2417,0.10768 -9.658,0.71067 -13.2813,2.53125 -3.7519,1.88519 -6.5576,5.75636 -6.9063,9.9375 l -0.062,0 c -0.013,0.1027 0.011,0.20947 0,0.3125 0,0.043 -0.03,0.0819 -0.031,0.125 l 0.031,0 c -0.383,3.94189 0.8037,8.08581 3.625,10.84375 1.7434,1.70445 3.9242,2.79035 6.3124,3.59375 l -0.875,2.4375 -0.062,0.125 -0.031,0.125 c -1.0239,3.32791 -0.9882,7.09444 0.8437,10.15625 1.8322,3.06181 4.9132,4.85334 8.3438,5.90625 l 0.7188,0.21875 0.75,0 2.2812,0 c 4.1038,5e-5 8.0184,-1.11288 11.1562,-3.5 1.388,-1.05587 2.5677,-2.38102 3.5938,-3.8125 2.738,2.5559 6.0541,4.80834 10,6.78125 l 0.5,0.25 0.5312,0.15625 c 3.235,0.79227 6.3972,0.95306 9.4063,-0.1875 2.9956,-1.13542 5.3523,-3.78973 6.4375,-6.71875 l 0.031,0 0,-0.0312 c 1.3188,-3.58119 1.0754,-7.65809 -0.4687,-11.1875 -0.3593,-0.82136 -0.9637,-1.56048 -1.4375,-2.34375 0.7988,-0.35352 1.5774,-0.75006 2.3125,-1.28125 3.1456,-2.2731 4.4669,-6.43958 4.1563,-10.25 l 0.031,0 c 0,-0.12851 -0.061,-0.24691 -0.062,-0.375 -0.017,-0.15367 0.023,-0.31671 0,-0.46875 l -0.062,0 c -0.2506,-3.85862 -2.6242,-7.47641 -5.875,-9.5625 -3.1968,-2.05143 -7.2278,-3.19745 -12.0625,-4.03124 -0.5947,-4.02941 -1.4462,-7.64148 -3.125,-10.53125 -2.2702,-3.9078 -6.5646,-6.71865 -11.0625,-6.71875 z m 18.3125,50.62499 c 0.2654,0.97712 0.2969,1.7705 -0.031,2.65625 l 0,0.0312 c -0.3181,0.86918 -0.3036,0.72198 -0.625,0.84375 -0.2585,0.098 -1.2073,0.14918 -2.5624,-0.0625 0.3313,-0.1475 0.7366,-0.14338 1.0312,-0.34375 l 0.4375,-0.28125 0.375,-0.40625 c 0.5814,-0.62017 0.9776,-1.55372 1.375,-2.4375 z"
391 id="path6033" />
392 <g
393 id="text6035"
394 style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:165.01513672px;line-height:125%;font-family:'comic andy';-inkscape-font-specification:'comic andy';letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient4437);fill-opacity:1;stroke:none">
395 <path
396 id="path98"
397 style="fill:url(#linearGradient6087);fill-opacity:1"
398 d="m 550.24549,16.984496 q 8.54083,0 9.83001,16.920498 l 2.33664,0 q 15.22844,2.33664 15.0673,9.668855 1.28918,8.621397 -11.03861,7.976806 9.42713,8.299101 6.7682,15.470169 -2.09492,5.72074 -9.99116,3.786969 -8.70197,-4.350985 -12.32779,-9.991151 l -1.5309,0 q -3.3841,9.991151 -13.13353,9.991151 l -2.25606,0 q -8.13796,-2.497788 -5.88189,-9.830003 l 2.82008,-7.815659 -0.80574,0 q -11.92492,-1.692049 -10.79688,-10.555167 0.32229,-8.137954 16.35648,-8.218527 4.43155,-0.483443 3.70639,-2.820083 0,-14.583858 10.87746,-14.583858 z m -4.5927,16.034186 -0.16115,4.512133 q -0.24172,3.384099 -2.17549,3.384099 l -12.73066,0.725164 q -2.98123,0.08057 -2.98123,2.417214 0,2.256067 3.22295,2.417214 11.19976,-0.564016 10.47459,1.530902 l -2.25606,4.834428 q -5.72074,8.621396 -2.82009,10.152299 3.86754,2.33664 10.95804,-12.08607 1.69205,-1.530902 2.82008,0 4.99558,5.317871 8.21853,8.70197 3.30353,3.3841 5.31787,2.014345 2.41721,-2.578361 -1.28918,-5.559592 -3.62582,-3.061804 -8.2991,-8.379675 -0.48344,-1.772623 0.24172,-1.772623 15.79246,1.047459 15.14787,-2.014345 0.48345,-3.3841 -13.69754,-3.3841 -2.17549,0.402869 -3.54525,-1.047459 l 0,-7.896232 q 0,-6.607052 -3.14238,-6.526478 -3.3841,-0.805738 -3.30352,7.976806 z" />
399 </g>
400 <path
401 d="m 335.7911,64.63031 c -9.6363,0.58398 -20.9336,2.59484 -26.0312,10.625 -0.4035,0.99026 -0.045,1.9107 0.6562,2.5 0.717,0.60234 1.4896,0.85243 2.5626,0 a 1.684398,1.684398 0 0 1 0.625,-0.3125 c 5.775,-1.5733 12.3167,-3.78461 18.9374,-4.625 6.6208,-0.84039 13.4444,-0.25925 19.4063,3.84375 a 1.684398,1.684398 0 0 1 0.375,0.375 c 2.0281,2.75755 2.9112,6.50666 2.5937,10.125 -0.3174,3.61834 -1.9072,7.25777 -5.2187,9.15625 a 1.684398,1.684398 0 0 1 -0.4687,0.1875 c -4.4561,1.00721 -8.7953,0.29068 -12.875,-0.1875 -4.0798,-0.47818 -7.8868,-0.73461 -11.5313,0.59375 a 1.684398,1.684398 0 0 1 -0.1563,0.0312 c -11.7884,2.8498 -19.5228,15.78804 -17.4062,27.59375 a 1.684398,1.684398 0 0 1 0,0.65625 c -1.0407,5.14641 2.2557,9.72666 7.3438,10.59375 a 1.684398,1.684398 0 0 1 0.2812,0.0625 c 11.7498,4.04484 24.8758,2.18109 37.0625,-0.3125 a 1.684398,1.684398 0 0 1 1.2813,0.28125 c 2.0816,1.42722 4.4575,3.29235 6.625,4.1875 1.0837,0.44757 2.0633,0.63094 2.9374,0.53125 0.8627,-0.0984 1.6764,-0.44585 2.5938,-1.375 0.01,-0.0118 0.022,-0.0195 0.031,-0.0312 2.6608,-3.43997 2.9705,-7.61463 2.625,-12.3125 -0.3431,-4.66636 -1.3766,-9.66321 -1,-14.46875 -0.9524,-14.4251 -1.1073,-29.45823 -6.7187,-42.15625 -6.4124,-5.22259 -15.7954,-5.06556 -24.4687,-5.5625 -0.021,-10e-4 -0.042,0.001 -0.063,0 z"
402 id="path6039"
403 style="fill:#484848;fill-opacity:1;stroke:#484848;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
404 <path
405 d="m 345.6192,106.30395 c -3.4993,0.0307 -6.9607,-0.0581 -10.375,0.0312 -4.1004,0.36044 -9.0376,1.69024 -12.625,4.09375 -3.614,2.42133 -5.8704,5.68864 -5.2813,10.4375 0.4935,4.61527 3.5645,7.56447 7.6876,9.21875 4.123,1.65428 9.2633,1.8209 13.1562,0.65625 a 1.3611835,1.3611835 0 0 1 0.1562,-0.0312 c 2.8688,-0.49834 6.5939,-1.2529 9.2813,-2.71875 1.3437,-0.73292 2.3836,-1.63683 3.0313,-2.6875 0.6476,-1.05067 0.9604,-2.26047 0.6874,-3.96875 a 1.3611835,1.3611835 0 0 1 0,-0.28125 c 0.1564,-2.76724 0.3451,-6.68524 -0.375,-9.71875 -0.36,-1.51676 -0.9264,-2.77474 -1.75,-3.625 -0.8176,-0.8442 -1.8698,-1.36151 -3.5624,-1.40625 -0.012,-3.2e-4 -0.019,2.7e-4 -0.031,0 z"
406 id="path6041"
407 style="color:#000000;fill:url(#linearGradient6089);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
408 </g>
409 <g
410 id="g5958">
411 <path
412 id="path4188"
413 d="m 549.36434,78.11349 c -9.4946,1.99352 -9.7027,14.03504 -9.8352,21.77668 0.1121,11.0831 -0.2095,22.9628 4.1417,33.27264 2.0054,4.85047 9.7812,4.74809 10.3195,-1.06753 4.7624,-15.20498 4.7481,-32.01281 1.4946,-47.50541 -0.983,-2.75668 -3.069,-6.35036 -6.1206,-6.47638 z"
414 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
415 <path
416 id="path4190"
417 d="m 499.48944,47.6175 c -6.4927,-0.34021 -9.3439,6.60543 -8.1121,12.16941 -0.5858,24.07597 -0.3292,48.31194 0.034,72.30837 1.7508,6.96484 14.895,8.48808 15.0166,-0.0712 1.2169,-13.27189 -0.274,-26.75029 0.6639,-40.10232 0.7817,-11.41478 -0.5568,-23.24296 -0.6994,-34.37618 1.5849,-5.10643 -0.4706,-11.12871 -6.9034,-9.92811 z"
418 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
419 <path
420 id="path4192"
421 d="m 132.42293,35.23407 c -7.6945,2.17125 -5.9206,12.79289 -6.2273,19.00216 1.6106,23.24538 0.8475,46.57408 2.1706,69.81693 0.068,7.09423 3.2021,16.90233 11.8853,16.22657 7.5709,-1.76417 5.7778,-11.8325 5.6557,-17.71589 -0.047,-7.84014 -4.5559,-19.23884 3.9165,-24.30949 7.6405,-5.37547 19.848,0.64078 18.6463,10.39069 -0.3251,8.83089 -2.0837,22.16882 7.8287,26.47493 6.4024,2.92649 10.6176,-5.21693 9.3943,-10.71096 -0.3749,-13.55442 1.2727,-30.22607 -10.711,-39.6768 -7.9735,-4.05845 -18.9828,-5.54515 -26.8307,-0.21351 -1.0372,2.42576 -6.9951,6.95054 -6.4053,1.24546 -1.6949,-15.3749 2.056,-31.45755 -2.3485,-46.40228 -1.2024,-2.63946 -4.0324,-4.45898 -6.9746,-4.12781 z"
422 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
423 <path
424 id="path4194"
425 d="m 442.14024,64.05759 c -10.165,-0.2579 -20.6562,1.86137 -28.1474,9.18081 -2.8958,2.05591 -1.2663,-4.94966 -4.8395,-5.01742 -5.4074,-2.93338 -11.5829,2.98762 -9.5367,8.75381 0.099,20.06919 -1.977,40.97889 3.8787,60.387 3.1796,4.95849 13.7562,4.09337 12.7037,-2.9891 1.546,-15.53942 -2.968,-32.10549 3.167,-46.86488 4.3319,-8.66318 18.41,-14.13659 25.3718,-5.90704 3.521,6.12624 -0.9752,16.78774 6.8323,20.31879 7.6504,1.3481 9.6041,-9.08157 8.825,-14.7676 -1.6539,-6.72434 -2.1565,-14.5353 -6.6544,-19.99852 -3.1376,-2.78799 -7.564,-3.22067 -11.6005,-3.09585 z"
426 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
427 <path
428 id="path4196"
429 d="m 442.38294,54.04595 c -0.1827,-0.005 -0.3789,0.0345 -0.5625,0.0312 -8.6942,-0.15632 -18.301,1.16995 -26.7813,5.96876 -0.368,-0.21564 -0.7676,-0.37654 -1.1562,-0.5625 l 0.031,-0.0625 c -0.2019,-0.10958 -0.4204,-0.1194 -0.625,-0.21875 -0.5569,-0.23563 -1.1103,-0.37966 -1.6874,-0.53125 -6.0741,-2.10894 -12.7994,-0.4336 -16.8438,3.34375 -3.8577,3.60298 -6.0063,9.29062 -5.1562,15.125 0.085,19.31578 -2.292,41.23535 4.3124,63.12499 l 0.4063,1.3125 0.75,1.1875 c 4.4521,6.94297 11.5862,8.53059 18,7.46875 3.2069,-0.53092 6.701,-1.89897 9.5,-5.03125 2.2725,-2.54317 3.5121,-6.27514 3.5937,-9.84375 0,-0.0435 0,-0.0816 0,-0.125 1.7478,-17.81793 -1.8544,-32.72457 2.2813,-43.375 0.6976,-1.23208 3.1856,-3.39065 5.4063,-4.03125 1.1119,-0.32077 1.7363,-0.44325 2.1874,-0.40625 0.051,0.8996 0.2789,2.71568 0.5313,6.0625 0.1821,2.41445 0.4732,5.42185 2.0313,8.8125 1.558,3.39065 4.8419,6.94014 8.8437,8.75 l 1.1563,0.5 1.2187,0.21875 c 4.1545,0.73208 8.9361,-0.28467 12.2187,-2.59375 3.2827,-2.30908 5.1358,-5.31163 6.3126,-8.0625 2.3534,-5.50175 2.5912,-10.54096 1.9374,-15.3125 l -0.062,-0.53125 -0.125,-0.5 c -1.3372,-5.43656 -1.418,-15.17693 -8.6563,-23.96874 l -0.4687,-0.59375 -0.5938,-0.53125 c -6.0316,-5.35952 -13.0425,-5.71213 -18,-5.59376 l 0,-0.0312 z m -20.9688,14.62501 c 0.3103,0.61975 0.1924,0.76755 0.063,0.28125 -0.016,-0.0599 -0.046,-0.21107 -0.063,-0.28125 z m -11.8437,14.15624 c 0.271,0.10418 0.5347,0.22752 0.8125,0.3125 l -0.125,0.21875 -0.125,0.3125 c -0.2313,0.55649 -0.3535,1.10135 -0.5625,1.65625 0.01,-0.84699 -0.01,-1.64903 0,-2.5 z"
430 style="color:#000000;fill:url(#linearGradient4453);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
431 <path
432 id="path4198"
433 d="m 334.93614,43.42895 -1.125,0.0625 c -11.4541,0.68757 -31.1299,2.13948 -42.5313,20.5 l -0.6875,1.15625 -0.5312,1.21875 c -4.0155,9.09454 -1.1737,19.34928 5,25.5 -7.1006,9.03999 -10.5361,20.69833 -9.25,32.65625 -0.7932,13.71238 8.5163,26.58972 21.5624,30.34375 l -0.031,0.0625 c 14.5936,5.02387 28.3345,3.89176 40,1.875 1.1383,0.61027 2.377,1.24208 3.8438,1.84375 3.1932,1.30991 7.6804,2.60895 13.1874,1.96875 5.5071,-0.6402 11.3463,-3.71585 15.0626,-7.53125 l 0.6562,-0.6875 0.5938,-0.75 c 7.375,-9.27994 7.6766,-20.19393 7.1874,-26.8125 -0.4891,-6.61857 -1.0653,-10.99648 -1.0312,-11.375 l 0.125,-1.46875 -0.094,-1.5 c -0.9045,-13.69999 -0.4438,-31.50909 -8.6874,-49.71875 -0.8869,-3.14352 -2.6183,-4.60975 -5,-6.625 -14.193,-12.04738 -29.8012,-10.22761 -37.125,-10.65625 z m -5,69.25 c -0.6975,0.25422 -0.096,-0.059 3.5937,0.375 3.1757,0.3735 8.4922,1.29071 15.3437,0.34375 -0.042,1.60674 -0.047,3.10046 0.031,4.46875 l -1.2187,0.25 c -9.4296,1.92946 -17.7526,2.70557 -24.0626,1.71875 0.3089,-2.61777 2.5558,-6.11412 4.2813,-6.53125 l 1.0313,-0.25 1,-0.375 z"
434 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:38" />
435 <path
436 style="color:#000000;fill:#484848;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:38;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
437 d="m 242.86794,62.94328 c -9.8451,0.59098 -21.9234,2.57343 -27.5069,11.56498 -1.5225,3.44827 2.5155,7.16458 5.8003,4.55483 11.6876,-3.18405 25.8772,-8.64334 36.9368,-1.03196 3.4255,4.6575 3.2712,13.73214 -2.1351,16.8315 -8.1137,1.83399 -16.456,-2.50178 -24.589,0.4626 -12.7407,3.08001 -20.924,16.83116 -18.6463,29.53519 -1.221,6.03853 2.7535,11.58045 8.7182,12.59694 12.2603,4.22059 25.7141,2.25842 37.9688,-0.24909 3.9671,2.72001 9.7011,7.85911 14.3406,3.09585 6.2596,-7.87653 1.273,-19.02318 2.088,-28.06851 -0.9577,-14.50429 -1.0481,-29.91302 -7.0343,-43.1362 -7.0905,-6.01862 -17.2216,-5.6458 -25.9411,-6.15613 z"
438 id="path4200" />
439 <path
440 id="path4202"
441 d="m 132.71733,24.19589 c -0.5004,0.0152 -1.0205,0.0363 -1.5312,0.0937 l -0.9063,0.0937 -0.8437,0.25 c -4.2861,1.20943 -8.1936,4.24904 -10.375,7.56249 -2.1816,3.31346 -2.9841,6.56659 -3.4063,9.375 -0.8444,5.61682 -0.3823,10.37282 -0.4687,12.125 l -0.031,0.65625 0.062,0.625 c 1.548,22.34205 0.8033,45.46456 2.125,69.1875 5e-4,0.0505 0.031,0.10568 0.031,0.15625 0.01,0.1151 -0.01,0.22862 0,0.34375 l 0.031,0 c 0.099,4.98929 0.9665,10.43113 4.125,15.90625 3.2605,5.65198 11.0145,11.32149 19.5625,10.65625 l 0.8438,-0.0625 0.8124,-0.1875 c 4.2384,-0.98762 8.3269,-3.79564 10.625,-7.09375 2.1728,-3.63384 4.3342,-6.89183 5.1872,-10.22818 3.8402,7.13335 5.9507,8.04619 13.1566,11.44693 l 0,0.0312 c 0.059,0.0269 0.1281,0.0362 0.1875,0.0625 3.7423,1.65403 8.4312,1.97661 12.2813,0.65625 3.91101,-1.34132 6.71761,-3.90092 8.59371,-6.5 3.336,-4.62154 4.6441,-9.64143 3.9063,-15.25 -0.1718,-6.20746 0.2238,-14.23226 -1.1563,-22.8125 -1.3801,-8.58024 -5.0962,-18.36284 -13.75001,-25.1875 l -0.8437,-0.6875 -0.9688,-0.5 c -7.7653,-3.95251 -17.7087,-6.355 -27.4062,-4.09375 0.4086,-10.28331 1.089,-21.96033 -2.625,-34.5625 l -0.2188,-0.75 -0.3125,-0.71875 c -2.9167,-6.40275 -9.181,-10.82231 -16.6875,-10.59374 z m 6.0625,53.99999 c 0,0.0101 0.05,0.0315 0.062,0.0625 l -0.6245,1.46875 c 0.3311,-0.86163 0.5542,-1.56647 0.5625,-1.53125 z m 36.0625,48.28125 c 0.012,-0.004 0.019,0.005 0.031,0 l 0.063,0.3125 c -0.043,-0.19086 -0.061,-0.25465 -0.094,-0.3125 z"
442 style="color:#000000;fill:url(#linearGradient4451);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
443 <path
444 d="m 133.3461,36.09636 c -1.692,0.49428 -2.8155,1.39846 -3.625,2.625 -0.8214,1.24442 -1.3243,2.85069 -1.5938,4.625 -0.5342,3.51732 -0.1953,7.61208 -0.3438,10.8125 0,0.0285 0,0.0654 0,0.0937 1.6063,23.27388 0.8692,46.5905 2.1876,69.75 a 0.88388823,0.88388823 0 0 1 0,0.0625 c 0.033,3.4213 0.83,7.53419 2.5937,10.59375 1.7438,3.02495 4.2922,5.00636 8.2187,4.75 0.011,-7.3e-4 0.02,7.7e-4 0.031,0 1.6857,-0.39978 2.7542,-1.19719 3.5313,-2.3125 0.7819,-1.12237 1.2391,-2.59827 1.4687,-4.25 0.4593,-3.30346 2e-4,-7.22907 -0.062,-10.25 a 0.88388823,0.88388823 0 0 1 0,-0.0312 c -0.023,-3.75401 -1.179,-8.58343 -1.25,-13.1875 -0.071,-4.59014 1.0512,-9.12033 5.5625,-11.84375 0.012,-0.008 0.019,-0.023 0.031,-0.0312 8.2411,-5.75335 21.2001,0.72746 19.9687,11.1875 0,0.011 0,0.0202 0,0.0312 -4e-4,0.01 4e-4,0.0216 0,0.0312 -0.1662,4.44678 -0.6416,9.92071 0.094,14.71875 0.7386,4.81878 2.5857,8.83105 7.2188,10.84375 a 0.88388823,0.88388823 0 0 1 0.031,0 c 1.4264,0.65196 2.625,0.67804 3.6876,0.3125 1.0625,-0.36554 2.0152,-1.15367 2.7812,-2.21875 1.532,-2.13016 2.2012,-5.36524 1.6562,-7.8125 a 0.88388823,0.88388823 0 0 1 0,-0.15625 c -0.1887,-6.82351 0.1073,-14.35845 -1,-21.28125 -1.1026,-6.89383 -3.5864,-13.13587 -9.3124,-17.6875 -7.7294,-3.90433 -18.3437,-5.25802 -25.7813,-0.25 -0.7734,1.48479 -2.3237,3.00623 -4,3.78125 -0.9043,0.41808 -1.982,0.65336 -2.875,0.0312 -0.8519,-0.59346 -1.0866,-1.72753 -0.9687,-3.1875 0.01,-0.0705 -0.01,-0.11538 0,-0.1875 -1.6634,-15.48034 1.9617,-31.38045 -2.2813,-45.9375 -1.0363,-2.2749 -3.4784,-3.85945 -5.9687,-3.625 z"
445 id="path4440"
446 style="fill:#484848;fill-opacity:1;stroke:none" />
447 <path
448 id="path4206"
449 d="m 500.00794,37.6397 c -0.47,-0.0246 -0.9099,0.13839 -1.375,0.15625 -0.3182,0.036 -0.6564,-0.0583 -0.9688,0 l 0,0.0937 c -5.9486,0.59666 -11.3199,4.27914 -13.8124,8.625 -2.5191,4.39212 -3.1643,9.07388 -2.4688,13.75001 -0.5691,24.07161 -0.3288,48.17845 0.031,71.96874 l 0.031,1.1875 0.2813,1.125 c 2.2758,9.05358 10.1204,12.94327 17.2812,13.3125 3.5804,0.18461 7.6057,-0.50128 11.25,-3.21875 3.4431,-2.56742 5.753,-7.21537 6.0625,-11.6875 l 0.062,0 c 0.024,-0.26477 0.01,-0.51719 0.031,-0.78125 1.2169,-14.32127 -0.1813,-27.63851 0.6563,-39.5625 0.8412,-12.28307 -0.4559,-23.97948 -0.6563,-34.18749 0.9168,-4.19732 0.7514,-8.64033 -1.75,-13.09376 -2.5398,-4.52202 -8.6787,-7.57722 -14.4374,-7.5625 -0.073,1.9e-4 -0.1457,-0.001 -0.2188,0 l 0,-0.125 z m -0.4375,10.46875 1.5625,8.375 c -0.089,0.0884 -0.5399,0.26586 -0.9688,0.50001 -0.4433,-0.17558 -0.588,-0.31717 -1.125,-0.59376 l 0.5313,-8.28125 z m 1.625,8.6875 0.125,0.65626 c 0,-5.2e-4 -0.146,-0.0578 -0.1563,-0.0625 0.013,-0.26164 0.01,-0.41632 0.031,-0.59376 z"
450 style="color:#000000;fill:url(#linearGradient4449);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
451 <path
452 id="path4208"
453 d="m 499.48944,47.6175 c -6.4927,-0.34021 -9.3439,6.60543 -8.1121,12.16941 -0.5858,24.07597 -0.3292,48.31194 0.034,72.30837 1.7508,6.96484 14.895,8.48808 15.0166,-0.0712 1.2169,-13.27189 -0.274,-26.75029 0.6639,-40.10232 0.7817,-11.41478 -0.5568,-23.24296 -0.6994,-34.37618 1.5849,-5.10643 -0.4706,-11.12871 -6.9034,-9.92811 z"
454 style="fill:#484848;fill-opacity:1;stroke:none" />
455 <path
456 id="path4210"
457 d="m 544.51954,53.6313 c -7.5784,-0.46784 -10.6755,10.08558 -4.626,14.19825 6.4831,5.13984 16.9776,-2.57743 12.9884,-10.24836 -1.4384,-3.20261 -5.1136,-4.25984 -8.3624,-3.94989 z"
458 style="fill:#000000;fill-opacity:1;stroke:none" />
459 <path
460 id="path4212"
461 d="m 66.312222,57.93009 c -17.370703,0.62829 -30.0641,20.09681 -26.023403,36.39781 2.1928,10.05075 13.8541,12.09708 22.635103,11.4922 7.1377,-0.5151 17.6041,2.45346 16.7319,11.49222 -1.8676,6.29718 -10.9897,4.97438 -16.0667,5.21679 -7.019003,0.3042 -14.551803,-2.83467 -21.309203,-1.0251 -5.546297,3.71601 -0.7698,11.63178 4.4362,13.09902 11.6204,3.85396 24.776703,2.98561 36.677203,0.52396 8.494404,-1.78465 13.976704,-9.66183 14.007304,-18.12905 0.5362,-8.45978 -0.1252,-18.85777 -9.082,-22.63511 -7.833304,-4.5437 -17.524404,-2.59996 -25.744004,-4.64578 -6.504303,-3.75215 -4.590203,-15.08325 3.2137,-15.54417 8.376,-2.645 16.5844,3.54335 24.730904,1.74653 6.8027,-2.75685 5.6777,-13.26551 -1.2924,-15.19486 C 82.177322,57.19274 73.972122,57.9802 66.312222,57.93009 Z"
462 style="fill:#484848;fill-opacity:1;stroke:#484848;stroke-width:38;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
463 <path
464 id="path4214"
465 d="m 66.146122,46.92095 -0.2187,0.0312 c -25.268203,0.91394 -41.9786,26.29641 -36.375,49.71875 0,0.01 0,0.0214 0,0.0312 0.023,0.0937 0.039,0.18758 0.062,0.28125 l 0.062,0 c 1.4158,6.03031 5.2241,10.72981 9.5937,13.9375 l -1.5937,0.4375 -1.5313,1 c -3.4934,2.34058 -6.2461,6.40677 -7.0312,10.4375 -0.7852,4.03073 0.016,7.64447 1.2812,10.53125 2.4625,5.61698 6.4364,9.72109 12.843797,11.6875 l 0,0.0312 c 0.1235,0.0409 0.2514,0.0537 0.375,0.0937 0.044,0.0142 0.081,0.0484 0.125,0.0625 14.2876,4.59699 29.052403,3.33987 41.875007,0.6875 l 0.031,0 c 13.703,-2.87897 22.354804,-15.23519 22.687504,-28.1875 l 0.031,0 c 0.01,-0.1043 -0.01,-0.23849 0,-0.34375 0,-0.10511 0.031,-0.20733 0.031,-0.3125 l -0.031,0 c 0.275,-4.68022 0.3633,-10.21921 -1.4063,-16.21875 -1.6128,-5.46789 -5.6186,-11.40935 -11.718704,-15.03125 C 110.28983,79.05558 108.57813,56.15757 93.550926,50.6395 83.076822,45.62854 73.121622,46.96476 66.394622,46.92075 l -0.25,0 z M 49.927419,124.0772 c 0.4736,0.11312 0.7429,0.17483 0.6875,0.1875 -0.1379,-0.0437 -0.3009,-0.0484 -0.4375,-0.0937 l -0.25,-0.0937 z"
466 style="color:#000000;fill:url(#linearGradient4447);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
467 <path
468 d="M 67.047,59.37761 C 50.7565,60.01346 38.6203,78.63489 42.422,93.97136 a 1.4420115,1.4420115 0 0 1 0,0.0312 c 0.9874,4.52574 3.9833,7.14275 7.9688,8.71875 3.9854,1.576 8.921,1.948 13.1562,1.65625 3.8182,-0.27555 8.4163,0.35581 12.1562,2.34375 3.74,1.98794 6.6157,5.6345 6.125,10.71875 a 1.4420115,1.4420115 0 0 1 -0.062,0.28125 c -0.5618,1.89409 -1.746,3.32797 -3.1876,4.25 -1.4415,0.92203 -3.0867,1.39395 -4.7812,1.65625 -3.3889,0.5246 -7.0334,0.23046 -9.4062,0.34375 -7.4077,0.32104 -14.726,-2.60314 -20.7813,-1.09375 -0.9228,0.69289 -1.3969,1.4625 -1.5625,2.3125 -0.1806,0.92739 -0.017,2.01851 0.4688,3.125 0.9708,2.21298 3.281,4.32492 5.3437,4.90625 a 1.4420115,1.4420115 0 0 1 0.062,0 c 11.2515,3.73156 24.1465,2.93253 35.9062,0.5 7.7821,-1.63499 12.8466,-8.87337 12.875,-16.71875 a 1.4420115,1.4420115 0 0 1 0,-0.0937 c 0.2634,-4.15469 0.2008,-8.71518 -0.9374,-12.5625 -1.1383,-3.84732 -3.227,-6.9152 -7.2813,-8.625 a 1.4420115,1.4420115 0 0 1 -0.1563,-0.0937 c -7.233,-4.1955 -16.6908,-2.33856 -25.375,-4.5 a 1.4420115,1.4420115 0 0 1 -0.375,-0.15625 c -7.593,-4.38022 -5.364,-17.27483 3.5,-18.15625 l 0,-0.0312 c 0.1153,-0.0364 0.2288,-0.0291 0.3438,-0.0625 4.5012,-1.3064 8.8395,-0.37995 12.875,0.59375 4.0804,0.98454 7.88,1.92841 11.4688,1.1875 5.4755,-2.31046 4.4951,-10.8333 -1.1876,-12.40625 a 1.4420115,1.4420115 0 0 1 -0.2812,-0.0937 c -6.5535,-3.28332 -14.4405,-2.57842 -22.1875,-2.625 -0.021,-1.3e-4 -0.042,1.4e-4 -0.062,0 z"
469 id="path4442"
470 style="fill:#484848;fill-opacity:1;stroke:none" />
471 <path
472 id="path4218"
473 d="m 334.91414,52.45217 -0.5624,0.0312 c -10.692,0.64182 -26.7608,2.35866 -35.4063,16.28126 l -0.375,0.59375 -0.2813,0.625 c -2.6168,5.92672 -0.4865,12.63582 3.8126,16.24999 2.47,2.0766 6.1544,2.97511 9.8124,2.75 -12.1731,7.16212 -18.9579,21.29295 -17.0937,35.5 -0.9321,10.0329 5.7963,19.42583 15.4375,21.90625 l 0,0.0312 c 13.5839,4.67628 27.0449,3.11875 38.7812,0.90625 1.4491,0.98507 3.2876,2.06677 5.5626,3 2.2748,0.93323 5.2583,1.74964 8.75,1.34375 3.4915,-0.40589 7.1195,-2.30283 9.625,-4.875 l 0.375,-0.34375 0.3124,-0.40625 c 5.3642,-6.74967 5.6479,-14.75709 5.2188,-20.5625 -0.4291,-5.80541 -1.211,-10.50221 -1,-12.84375 l 0.062,-0.78125 -0.062,-0.75 c -0.9297,-14.08097 -0.732,-30.77734 -7.9062,-46.62499 -0.4593,-1.65783 -1.3753,-2.43205 -2.625,-3.4999 -10.8288,-9.19166 -23.8588,-8.03267 -31.8438,-8.50001 l -0.5938,-0.0312 z m 22.0626,47.46875 c 0.2983,4.01025 0.663,7.89337 0.9374,12.09375 -0.3619,6.15055 0.7536,11.18085 1.0313,14.9375 0.091,1.23358 -3e-4,1.89681 -0.031,2.71875 -0.7261,-0.49389 -0.8804,-0.56988 -1.7812,-1.1875 l -3.5,-2.40625 -4.1562,0.84375 c -11.8502,2.42474 -23.4896,3.77093 -32.7188,0.59375 l -0.75,-0.25 -0.8125,-0.15625 c -0.7563,-0.12889 -0.7437,-0.008 -0.5937,-0.75 l 0.375,-1.875 -0.3438,-1.875 c -1.3223,-7.37497 4.0726,-16.31882 11.1562,-18.03125 l 0.5626,-0.15625 0.5312,-0.1875 c 1.5591,-0.56829 3.7957,-0.58273 7.6875,-0.125 3.8918,0.45773 9.2275,1.48444 15.6563,0.0312 l 1.4687,-0.34375 1.3125,-0.75 c 1.5458,-0.8862 2.8481,-1.95265 3.9688,-3.125 z"
474 style="color:#000000;fill:url(#linearGradient4445);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
475 <path
476 d="m 442.8461,65.50261 c -9.9417,-0.25223 -20.0112,1.83054 -27.125,8.78125 a 1.4249747,1.4249747 0 0 1 -0.1876,0.125 c -0.4923,0.34955 -1.0141,0.64308 -1.6874,0.65625 -0.6734,0.0132 -1.3402,-0.39879 -1.6876,-0.8125 -0.6947,-0.82743 -0.7686,-1.5945 -0.9687,-2.34375 -0.2001,-0.74925 -0.4246,-1.47139 -0.6563,-1.84375 -0.2316,-0.37236 -0.2624,-0.39819 -0.6874,-0.40625 a 1.4249747,1.4249747 0 0 1 -0.6563,-0.1875 c -2.1511,-1.16691 -4.3134,-0.58174 -5.9063,0.90625 -1.5928,1.48799 -2.4145,3.81205 -1.5937,6.125 a 1.4249747,1.4249747 0 0 1 0.094,0.46875 c 0.099,20.08519 -1.9054,40.73856 3.75,59.71875 1.2377,1.74956 4.0539,2.66609 6.4063,2.28125 1.2075,-0.19755 2.2216,-0.71247 2.8437,-1.40625 0.6222,-0.69378 0.9615,-1.54589 0.75,-2.96875 a 1.4249747,1.4249747 0 0 1 0,-0.375 c 1.5091,-15.16756 -3.1254,-31.94343 3.25,-47.28125 a 1.4249747,1.4249747 0 0 1 0.031,-0.0625 c 2.3884,-4.77662 7.2847,-8.50018 12.5937,-10.03125 5.3091,-1.53107 11.2689,-0.75156 15.1563,3.84375 a 1.4249747,1.4249747 0 0 1 0.1563,0.1875 c 2.0694,3.60071 1.6918,8.0153 1.9687,11.75 0.1385,1.86735 0.4194,3.54061 1.0313,4.875 0.5916,1.2904 1.4751,2.25734 3.0312,3 1.4606,0.20734 2.5297,-0.051 3.4375,-0.6875 0.9587,-0.67214 1.771,-1.81376 2.375,-3.21875 1.2079,-2.80999 1.508,-6.6831 1.1563,-9.25 -1.6601,-6.82503 -2.269,-14.23556 -6.2813,-19.1875 -2.6943,-2.32961 -6.6692,-2.77567 -10.5313,-2.65625 a 1.4249747,1.4249747 0 0 1 -0.062,0 z"
477 id="path4436"
478 style="fill:#484848;fill-opacity:1;stroke:none" />
479 <path
480 id="path4224"
481 d="m 548.52594,68.07721 -1.2187,0.25 c -8.6956,1.82574 -14.1425,9.53796 -15.9688,15.68749 -1.8263,6.14954 -1.7462,11.84707 -1.8125,15.71875 l 0,0.125 0,0.125 c 0.1092,10.79916 -0.5536,24.0134 4.9063,37 0.01,0.0225 0.022,0.0401 0.031,0.0625 2.7726,6.62078 9.3817,9.9621 15.5625,9.5625 5.6001,-0.36206 11.8353,-5.2195 13.5,-11.53125 5.3924,-17.21633 5.3013,-35.62075 1.75,-52.53125 l -0.1563,-0.6875 -0.2187,-0.62499 c -0.7814,-2.19128 -1.853,-4.62969 -3.9375,-7.1875 -2.0845,-2.55781 -5.8401,-5.71667 -11.1875,-5.9375 l -1.25,-0.0312 z"
482 style="color:#000000;fill:url(#linearGradient4443);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
483 <path
484 d="m 550.1139,78.59636 c -4.5226,0.97522 -6.7823,4.26272 -8,8.375 -1.2232,4.13111 -1.3087,9.03503 -1.375,12.90625 0.1123,11.09592 -0.2043,22.90976 4.0938,33.09375 0.9213,2.22841 3.1731,3.32073 5.25,3.1875 2.0769,-0.13323 3.906,-1.39 4.1562,-4.09375 a 0.46475483,0.46475483 0 0 1 0.031,-0.0937 c 4.7332,-15.11164 4.7084,-31.85462 1.4687,-47.28125 -0.4788,-1.32581 -1.2248,-2.85305 -2.1874,-4.03125 -0.9629,-1.17844 -2.1146,-1.98485 -3.4376,-2.0625 z"
485 id="path4438"
486 style="fill:#484848;fill-opacity:1;stroke:none" />
487 <path
488 id="path4229"
489 d="m 242.87094,52.92092 -0.5938,0.0312 c -10.6919,0.64192 -26.7607,2.35873 -35.4062,16.28131 l -0.375,0.59375 -0.2813,0.65625 c -2.6168,5.92671 -0.4864,12.60456 3.8125,16.21874 2.4771,2.0825 6.1757,2.98309 9.8438,2.75 -12.176,7.14722 -18.9659,21.26849 -17.125,35.46875 -0.9665,10.0609 5.7999,19.48906 15.4687,21.96875 l -0.031,0.0312 c 13.5891,4.67806 27.073,3.12012 38.8125,0.90625 1.4445,0.97996 3.2715,2.07302 5.5313,3 2.2749,0.93323 5.2585,1.71839 8.75,1.3125 3.4915,-0.40589 7.1509,-2.27156 9.6562,-4.84375 l 0.3438,-0.375 0.3125,-0.40625 c 5.3641,-6.74969 5.6478,-14.72585 5.2187,-20.53125 -0.4291,-5.8054 -1.2109,-10.50221 -1,-12.84375 l 0.062,-0.78125 -0.062,-0.78125 c -0.9297,-14.081 -0.7006,-30.74608 -7.875,-46.59374 l -0.9375,-2.0625 -1.7187,-1.4375 c -10.8287,-9.19167 -23.8276,-8.06392 -31.8125,-8.53126 l -0.5938,-0.0312 z m 22.0312,47.5 c 0.2974,4.00059 0.6637,7.87292 0.9375,12.0625 -0.3619,6.15055 0.7536,11.2121 1.0313,14.96875 0.091,1.22812 0,1.86766 -0.031,2.6875 -0.7261,-0.49388 -0.8805,-0.56989 -1.7813,-1.1875 l -3.5,-2.40625 -4.1562,0.875 c -11.8502,2.42475 -23.4582,3.77094 -32.6875,0.59375 l -0.7813,-0.28125 -0.8125,-0.125 c -0.7563,-0.12888 -0.7437,-0.0396 -0.5938,-0.78125 l 0.375,-1.84375 -0.3437,-1.875 c -1.3223,-7.37494 4.0726,-16.35008 11.1562,-18.0625 l 0.5625,-0.125 0.5313,-0.1875 c 1.5591,-0.56828 3.7957,-0.58273 7.6875,-0.125 3.8918,0.45773 9.2275,1.45313 15.6562,0 l 1.4688,-0.3125 1.3125,-0.75 c 1.5458,-0.8862 2.8482,-1.95265 3.9687,-3.125 z"
490 style="color:#000000;fill:url(#linearGradient4441);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
491 <path
492 d="m 243.6361,64.63031 c -9.6363,0.58398 -20.9336,2.59484 -26.0312,10.625 -0.4035,0.99026 -0.045,1.9107 0.6562,2.5 0.717,0.60234 1.4896,0.85243 2.5626,0 a 1.684398,1.684398 0 0 1 0.625,-0.3125 c 5.775,-1.5733 12.3167,-3.78461 18.9374,-4.625 6.6208,-0.84039 13.4444,-0.25925 19.4063,3.84375 a 1.684398,1.684398 0 0 1 0.375,0.375 c 2.0281,2.75755 2.9112,6.50666 2.5937,10.125 -0.3174,3.61834 -1.9072,7.25777 -5.2187,9.15625 a 1.684398,1.684398 0 0 1 -0.4687,0.1875 c -4.4561,1.00721 -8.7953,0.29068 -12.875,-0.1875 -4.0798,-0.47818 -7.8868,-0.73461 -11.5313,0.59375 a 1.684398,1.684398 0 0 1 -0.1563,0.0312 c -11.7884,2.8498 -19.5228,15.78804 -17.4062,27.59375 a 1.684398,1.684398 0 0 1 0,0.65625 c -1.0407,5.14641 2.2557,9.72666 7.3438,10.59375 a 1.684398,1.684398 0 0 1 0.2812,0.0625 c 11.7498,4.04484 24.8758,2.18109 37.0625,-0.3125 a 1.684398,1.684398 0 0 1 1.2813,0.28125 c 2.0816,1.42722 4.4575,3.29235 6.625,4.1875 1.0837,0.44757 2.0633,0.63094 2.9374,0.53125 0.8627,-0.0984 1.6764,-0.44585 2.5938,-1.375 0.01,-0.0118 0.022,-0.0195 0.031,-0.0312 2.6608,-3.43997 2.9705,-7.61463 2.625,-12.3125 -0.3431,-4.66636 -1.3766,-9.66321 -1,-14.46875 -0.9524,-14.4251 -1.1073,-29.45823 -6.7187,-42.15625 -6.4124,-5.22259 -15.7954,-5.06556 -24.4687,-5.5625 -0.021,-10e-4 -0.042,0.001 -0.063,0 z"
493 id="path4426"
494 style="fill:#484848;fill-opacity:1;stroke:#484848;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
495 <path
496 d="m 252.9376,106.30395 c -3.4993,0.0307 -6.9607,-0.0581 -10.375,0.0312 -4.1004,0.36044 -9.0376,1.69024 -12.625,4.09375 -3.614,2.42133 -5.8704,5.68864 -5.2813,10.4375 0.4935,4.61527 3.5645,7.56447 7.6876,9.21875 4.123,1.65428 9.2633,1.8209 13.1562,0.65625 a 1.3611835,1.3611835 0 0 1 0.1562,-0.0312 c 2.8688,-0.49834 6.5939,-1.2529 9.2813,-2.71875 1.3437,-0.73292 2.3836,-1.63683 3.0313,-2.6875 0.6476,-1.05067 0.9604,-2.26047 0.6874,-3.96875 a 1.3611835,1.3611835 0 0 1 0,-0.28125 c 0.1564,-2.76724 0.3451,-6.68524 -0.375,-9.71875 -0.36,-1.51676 -0.9264,-2.77474 -1.75,-3.625 -0.8176,-0.8442 -1.8698,-1.36151 -3.5624,-1.40625 -0.012,-3.2e-4 -0.019,2.7e-4 -0.031,0 z"
497 id="path5306"
498 style="color:#000000;fill:url(#linearGradient4439);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22" />
499 <path
500 id="text4338"
501 d="m 550.24144,11.97714 c -4.7431,8e-5 -9.3884,1.94508 -12.1562,5.65625 -2.3938,3.20927 -3.2655,7.28209 -3.5,11.84374 -5.2417,0.10768 -9.658,0.71067 -13.2813,2.53125 -3.7519,1.88519 -6.5576,5.75636 -6.9063,9.9375 l -0.062,0 c -0.013,0.1027 0.011,0.20947 0,0.3125 0,0.043 -0.03,0.0819 -0.031,0.125 l 0.031,0 c -0.383,3.94189 0.8037,8.08581 3.625,10.84375 1.7434,1.70445 3.9242,2.79035 6.3124,3.59375 l -0.875,2.4375 -0.062,0.125 -0.031,0.125 c -1.0239,3.32791 -0.9882,7.09444 0.8437,10.15625 1.8322,3.06181 4.9132,4.85334 8.3438,5.90625 l 0.7188,0.21875 0.75,0 2.2812,0 c 4.1038,5e-5 8.0184,-1.11288 11.1562,-3.5 1.388,-1.05587 2.5677,-2.38102 3.5938,-3.8125 2.738,2.5559 6.0541,4.80834 10,6.78125 l 0.5,0.25 0.5312,0.15625 c 3.235,0.79227 6.3972,0.95306 9.4063,-0.1875 2.9956,-1.13542 5.3523,-3.78973 6.4375,-6.71875 l 0.031,0 0,-0.0312 c 1.3188,-3.58119 1.0754,-7.65809 -0.4687,-11.1875 -0.3593,-0.82136 -0.9637,-1.56048 -1.4375,-2.34375 0.7988,-0.35352 1.5774,-0.75006 2.3125,-1.28125 3.1456,-2.2731 4.4669,-6.43958 4.1563,-10.25 l 0.031,0 c 0,-0.12851 -0.061,-0.24691 -0.062,-0.375 -0.017,-0.15367 0.023,-0.31671 0,-0.46875 l -0.062,0 c -0.2506,-3.85862 -2.6242,-7.47641 -5.875,-9.5625 -3.1968,-2.05143 -7.2278,-3.19745 -12.0625,-4.03124 -0.5947,-4.02941 -1.4462,-7.64148 -3.125,-10.53125 -2.2702,-3.9078 -6.5646,-6.71865 -11.0625,-6.71875 z m 18.3125,50.62499 c 0.2654,0.97712 0.2969,1.7705 -0.031,2.65625 l 0,0.0312 c -0.3181,0.86918 -0.3036,0.72198 -0.625,0.84375 -0.2585,0.098 -1.2073,0.14918 -2.5624,-0.0625 0.3313,-0.1475 0.7366,-0.14338 1.0312,-0.34375 l 0.4375,-0.28125 0.375,-0.40625 c 0.5814,-0.62017 0.9776,-1.55372 1.375,-2.4375 z"
502 style="color:#000000;fill:#305f00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10" />
503 <g
504 id="text4342"
505 style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:165.01513672px;line-height:125%;font-family:'comic andy';-inkscape-font-specification:'comic andy';letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient4437);fill-opacity:1;stroke:none">
506 <path
507 id="path101"
508 style="fill:url(#linearGradient4437);fill-opacity:1"
509 d="m 550.24549,16.984496 q 8.54083,0 9.83001,16.920498 l 2.33664,0 q 15.22844,2.33664 15.0673,9.668855 1.28918,8.621397 -11.03861,7.976806 9.42713,8.299101 6.7682,15.470169 -2.09492,5.72074 -9.99116,3.786969 -8.70197,-4.350985 -12.32779,-9.991151 l -1.5309,0 q -3.3841,9.991151 -13.13353,9.991151 l -2.25606,0 q -8.13796,-2.497788 -5.88189,-9.830003 l 2.82008,-7.815659 -0.80574,0 q -11.92492,-1.692049 -10.79688,-10.555167 0.32229,-8.137954 16.35648,-8.218527 4.43155,-0.483443 3.70639,-2.820083 0,-14.583858 10.87746,-14.583858 z m -4.5927,16.034186 -0.16115,4.512133 q -0.24172,3.384099 -2.17549,3.384099 l -12.73066,0.725164 q -2.98123,0.08057 -2.98123,2.417214 0,2.256067 3.22295,2.417214 11.19976,-0.564016 10.47459,1.530902 l -2.25606,4.834428 q -5.72074,8.621396 -2.82009,10.152299 3.86754,2.33664 10.95804,-12.08607 1.69205,-1.530902 2.82008,0 4.99558,5.317871 8.21853,8.70197 3.30353,3.3841 5.31787,2.014345 2.41721,-2.578361 -1.28918,-5.559592 -3.62582,-3.061804 -8.2991,-8.379675 -0.48344,-1.772623 0.24172,-1.772623 15.79246,1.047459 15.14787,-2.014345 0.48345,-3.3841 -13.69754,-3.3841 -2.17549,0.402869 -3.54525,-1.047459 l 0,-7.896232 q 0,-6.607052 -3.14238,-6.526478 -3.3841,-0.805738 -3.30352,7.976806 z" />
510 </g>
511 <path
512 style="fill:#484848;fill-opacity:1;stroke:#484848;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
513 id="path4714"
514 d="m 335.7911,64.63031 c -9.6363,0.58398 -20.9336,2.59484 -26.0312,10.625 -0.4035,0.99026 -0.045,1.9107 0.6562,2.5 0.717,0.60234 1.4896,0.85243 2.5626,0 a 1.684398,1.684398 0 0 1 0.625,-0.3125 c 5.775,-1.5733 12.3167,-3.78461 18.9374,-4.625 6.6208,-0.84039 13.4444,-0.25925 19.4063,3.84375 a 1.684398,1.684398 0 0 1 0.375,0.375 c 2.0281,2.75755 2.9112,6.50666 2.5937,10.125 -0.3174,3.61834 -1.9072,7.25777 -5.2187,9.15625 a 1.684398,1.684398 0 0 1 -0.4687,0.1875 c -4.4561,1.00721 -8.7953,0.29068 -12.875,-0.1875 -4.0798,-0.47818 -7.8868,-0.73461 -11.5313,0.59375 a 1.684398,1.684398 0 0 1 -0.1563,0.0312 c -11.7884,2.8498 -19.5228,15.78804 -17.4062,27.59375 a 1.684398,1.684398 0 0 1 0,0.65625 c -1.0407,5.14641 2.2557,9.72666 7.3438,10.59375 a 1.684398,1.684398 0 0 1 0.2812,0.0625 c 11.7498,4.04484 24.8758,2.18109 37.0625,-0.3125 a 1.684398,1.684398 0 0 1 1.2813,0.28125 c 2.0816,1.42722 4.4575,3.29235 6.625,4.1875 1.0837,0.44757 2.0633,0.63094 2.9374,0.53125 0.8627,-0.0984 1.6764,-0.44585 2.5938,-1.375 0.01,-0.0118 0.022,-0.0195 0.031,-0.0312 2.6608,-3.43997 2.9705,-7.61463 2.625,-12.3125 -0.3431,-4.66636 -1.3766,-9.66321 -1,-14.46875 -0.9524,-14.4251 -1.1073,-29.45823 -6.7187,-42.15625 -6.4124,-5.22259 -15.7954,-5.06556 -24.4687,-5.5625 -0.021,-10e-4 -0.042,0.001 -0.063,0 z" />
515 <path
516 style="color:#000000;fill:url(#linearGradient4435);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:22"
517 id="path5310"
518 d="m 345.6192,106.30395 c -3.4993,0.0307 -6.9607,-0.0581 -10.375,0.0312 -4.1004,0.36044 -9.0376,1.69024 -12.625,4.09375 -3.614,2.42133 -5.8704,5.68864 -5.2813,10.4375 0.4935,4.61527 3.5645,7.56447 7.6876,9.21875 4.123,1.65428 9.2633,1.8209 13.1562,0.65625 a 1.3611835,1.3611835 0 0 1 0.1562,-0.0312 c 2.8688,-0.49834 6.5939,-1.2529 9.2813,-2.71875 1.3437,-0.73292 2.3836,-1.63683 3.0313,-2.6875 0.6476,-1.05067 0.9604,-2.26047 0.6874,-3.96875 a 1.3611835,1.3611835 0 0 1 0,-0.28125 c 0.1564,-2.76724 0.3451,-6.68524 -0.375,-9.71875 -0.36,-1.51676 -0.9264,-2.77474 -1.75,-3.625 -0.8176,-0.8442 -1.8698,-1.36151 -3.5624,-1.40625 -0.012,-3.2e-4 -0.019,2.7e-4 -0.031,0 z" />
519 </g>
520 </g>
521 </g>
522</svg>
diff --git a/doc/sidebar.html b/doc/sidebar.html
index 826e4cb2..62844581 100644
--- a/doc/sidebar.html
+++ b/doc/sidebar.html
@@ -6,18 +6,25 @@
6<li><a href="Download.html">Download</a></li> 6<li><a href="Download.html">Download</a></li>
7<li><a href="Server-requirements.html">Server requirements</a></li> 7<li><a href="Server-requirements.html">Server requirements</a></li>
8<li><a href="Server-configuration.html">Server configuration</a></li> 8<li><a href="Server-configuration.html">Server configuration</a></li>
9<li><a href="Server-security.html">Server security</a></li>
10<li><a href="Shaarli-installation.html">Shaarli installation</a></li>
9<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li> 11<li><a href="Shaarli-configuration.html">Shaarli configuration</a></li>
12<li><a href="Plugins.html">Plugins</a></li>
10</ul></li> 13</ul></li>
14<li><a href="Docker.html">Docker</a></li>
11<li><a href="Usage.html">Usage</a> 15<li><a href="Usage.html">Usage</a>
12<ul> 16<ul>
13<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li> 17<li><a href="Sharing-button.html">Sharing button</a> (bookmarklet)</li>
18<li><a href="Browsing-and-Searching.html">Browsing and Searching</a></li>
14<li><a href="Firefox-share.html">Firefox share</a></li> 19<li><a href="Firefox-share.html">Firefox share</a></li>
15<li><a href="RSS-feeds.html">RSS feeds</a></li> 20<li><a href="RSS-feeds.html">RSS feeds</a></li>
16</ul></li> 21</ul></li>
17<li>How To 22<li>How To
18<ul> 23<ul>
19<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li> 24<li><a href="Backup,-restore,-import-and-export.html">Backup, restore, import and export</a></li>
25<li><a href="Upgrade-from-original-sebsauvage/Shaarli.html">Upgrade from original sebsauvage/Shaarli</a></li>
20<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> 26<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>
27<li><a href="Create-and-serve-multiple-Shaarlis-(farm).html">Create and serve multiple Shaarlis (farm)</a></li>
21<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li> 28<li><a href="Download-CSS-styles-from-an-OPML-list.html">Download CSS styles from an OPML list</a></li>
22<li><a href="Datastore-hacks.html">Datastore hacks</a></li> 29<li><a href="Datastore-hacks.html">Datastore hacks</a></li>
23</ul></li> 30</ul></li>
@@ -29,6 +36,7 @@
29<li><a href="Directory-structure.html">Directory structure</a></li> 36<li><a href="Directory-structure.html">Directory structure</a></li>
30<li><a href="3rd-party-libraries.html">3rd party libraries</a></li> 37<li><a href="3rd-party-libraries.html">3rd party libraries</a></li>
31<li><a href="Plugin-System.html">Plugin System</a></li> 38<li><a href="Plugin-System.html">Plugin System</a></li>
39<li><a href="Release-Shaarli.html">Release Shaarli</a></li>
32<li><a href="Security.html">Security</a></li> 40<li><a href="Security.html">Security</a></li>
33<li><a href="Static-analysis.html">Static analysis</a></li> 41<li><a href="Static-analysis.html">Static analysis</a></li>
34<li><a href="Theming.html">Theming</a></li> 42<li><a href="Theming.html">Theming</a></li>
diff --git a/inc/awesomplete-multiple-tags.js b/inc/awesomplete-multiple-tags.js
index e0f889b1..4cc8429f 100644
--- a/inc/awesomplete-multiple-tags.js
+++ b/inc/awesomplete-multiple-tags.js
@@ -1,5 +1,5 @@
1$ = Awesomplete.$; 1var awp = Awesomplete.$;
2awesomplete = new Awesomplete($('input[data-multiple]'), { 2awesomplete = new Awesomplete(awp('input[data-multiple]'), {
3 filter: function(text, input) { 3 filter: function(text, input) {
4 return Awesomplete.FILTER_CONTAINS(text, input.match(/[^ ]*$/)[0]); 4 return Awesomplete.FILTER_CONTAINS(text, input.match(/[^ ]*$/)[0]);
5 }, 5 },
diff --git a/index.php b/index.php
index 850b350e..7465c41f 100644
--- a/index.php
+++ b/index.php
@@ -1,6 +1,6 @@
1<?php 1<?php
2/** 2/**
3 * Shaarli v0.6.5 - Shaare your links... 3 * Shaarli v0.7.0 - Shaare your links...
4 * 4 *
5 * The personal, minimalist, super-fast, no-database Delicious clone. 5 * The personal, minimalist, super-fast, no-database Delicious clone.
6 * 6 *
@@ -100,6 +100,7 @@ $GLOBALS['config']['ENABLE_LOCALCACHE'] = true;
100$GLOBALS['config']['UPDATECHECK_BRANCH'] = 'stable'; 100$GLOBALS['config']['UPDATECHECK_BRANCH'] = 'stable';
101$GLOBALS['config']['UPDATECHECK_INTERVAL'] = 86400; 101$GLOBALS['config']['UPDATECHECK_INTERVAL'] = 86400;
102 102
103$GLOBALS['config']['REDIRECTOR_URLENCODE'] = true;
103 104
104/* 105/*
105 * Plugin configuration 106 * Plugin configuration
@@ -125,7 +126,7 @@ $GLOBALS['config']['PUBSUBHUB_URL'] = '';
125/* 126/*
126 * PHP configuration 127 * PHP configuration
127 */ 128 */
128define('shaarli_version', '0.6.5'); 129define('shaarli_version', '0.7.0');
129 130
130// http://server.com/x/shaarli --> /shaarli/ 131// http://server.com/x/shaarli --> /shaarli/
131define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0))); 132define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0)));
@@ -154,11 +155,14 @@ if (is_file($GLOBALS['config']['CONFIG_FILE'])) {
154require_once 'application/ApplicationUtils.php'; 155require_once 'application/ApplicationUtils.php';
155require_once 'application/Cache.php'; 156require_once 'application/Cache.php';
156require_once 'application/CachedPage.php'; 157require_once 'application/CachedPage.php';
158require_once 'application/FeedBuilder.php';
157require_once 'application/FileUtils.php'; 159require_once 'application/FileUtils.php';
158require_once 'application/HttpUtils.php'; 160require_once 'application/HttpUtils.php';
159require_once 'application/LinkDB.php'; 161require_once 'application/LinkDB.php';
160require_once 'application/LinkFilter.php'; 162require_once 'application/LinkFilter.php';
161require_once 'application/LinkUtils.php'; 163require_once 'application/LinkUtils.php';
164require_once 'application/NetscapeBookmarkUtils.php';
165require_once 'application/PageBuilder.php';
162require_once 'application/TimeZone.php'; 166require_once 'application/TimeZone.php';
163require_once 'application/Url.php'; 167require_once 'application/Url.php';
164require_once 'application/Utils.php'; 168require_once 'application/Utils.php';
@@ -483,7 +487,7 @@ if (isset($_POST['login']))
483 if (isset($_POST['returnurl'])) { 487 if (isset($_POST['returnurl'])) {
484 // Prevent loops over login screen. 488 // Prevent loops over login screen.
485 if (strpos($_POST['returnurl'], 'do=login') === false) { 489 if (strpos($_POST['returnurl'], 'do=login') === false) {
486 header('Location: '. escape($_POST['returnurl'])); 490 header('Location: '. generateLocation($_POST['returnurl'], $_SERVER['HTTP_HOST']));
487 exit; 491 exit;
488 } 492 }
489 } 493 }
@@ -492,9 +496,9 @@ if (isset($_POST['login']))
492 else 496 else
493 { 497 {
494 ban_loginFailed(); 498 ban_loginFailed();
495 $redir = ''; 499 $redir = '&username='. $_POST['login'];
496 if (isset($_GET['post'])) { 500 if (isset($_GET['post'])) {
497 $redir = '?post=' . urlencode($_GET['post']); 501 $redir .= '&post=' . urlencode($_GET['post']);
498 foreach (array('description', 'source', 'title') as $param) { 502 foreach (array('description', 'source', 'title') as $param) {
499 if (!empty($_GET[$param])) { 503 if (!empty($_GET[$param])) {
500 $redir .= '&' . $param . '=' . urlencode($_GET[$param]); 504 $redir .= '&' . $param . '=' . urlencode($_GET[$param]);
@@ -560,337 +564,12 @@ function tokenOk($token)
560} 564}
561 565
562// ------------------------------------------------------------------------------------------ 566// ------------------------------------------------------------------------------------------
563/* This class is in charge of building the final page.
564 (This is basically a wrapper around RainTPL which pre-fills some fields.)
565 p = new pageBuilder;
566 p.assign('myfield','myvalue');
567 p.renderPage('mytemplate');
568
569*/
570class pageBuilder
571{
572 private $tpl; // RainTPL template
573
574 function __construct()
575 {
576 $this->tpl = false;
577 }
578
579 /**
580 * Initialize all default tpl tags.
581 */
582 private function initialize()
583 {
584 $this->tpl = new RainTPL;
585
586 try {
587 $version = ApplicationUtils::checkUpdate(
588 shaarli_version,
589 $GLOBALS['config']['UPDATECHECK_FILENAME'],
590 $GLOBALS['config']['UPDATECHECK_INTERVAL'],
591 $GLOBALS['config']['ENABLE_UPDATECHECK'],
592 isLoggedIn(),
593 $GLOBALS['config']['UPDATECHECK_BRANCH']
594 );
595 $this->tpl->assign('newVersion', escape($version));
596 $this->tpl->assign('versionError', '');
597
598 } catch (Exception $exc) {
599 logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], $exc->getMessage());
600 $this->tpl->assign('newVersion', '');
601 $this->tpl->assign('versionError', escape($exc->getMessage()));
602 }
603
604 $this->tpl->assign('feedurl', escape(index_url($_SERVER)));
605 $searchcrits = ''; // Search criteria
606 if (!empty($_GET['searchtags'])) {
607 $searchcrits .= '&searchtags=' . urlencode($_GET['searchtags']);
608 }
609 if (!empty($_GET['searchterm'])) {
610 $searchcrits .= '&searchterm=' . urlencode($_GET['searchterm']);
611 }
612 $this->tpl->assign('searchcrits', $searchcrits);
613 $this->tpl->assign('source', index_url($_SERVER));
614 $this->tpl->assign('version', shaarli_version);
615 $this->tpl->assign('scripturl', index_url($_SERVER));
616 $this->tpl->assign('pagetitle', 'Shaarli');
617 $this->tpl->assign('privateonly', !empty($_SESSION['privateonly'])); // Show only private links?
618 if (!empty($GLOBALS['title'])) {
619 $this->tpl->assign('pagetitle', $GLOBALS['title']);
620 }
621 if (!empty($GLOBALS['titleLink'])) {
622 $this->tpl->assign('titleLink', $GLOBALS['titleLink']);
623 }
624 if (!empty($GLOBALS['pagetitle'])) {
625 $this->tpl->assign('pagetitle', $GLOBALS['pagetitle']);
626 }
627 $this->tpl->assign('shaarlititle', empty($GLOBALS['title']) ? 'Shaarli': $GLOBALS['title']);
628 if (!empty($GLOBALS['plugin_errors'])) {
629 $this->tpl->assign('plugin_errors', $GLOBALS['plugin_errors']);
630 }
631 }
632
633 // The following assign() method is basically the same as RainTPL (except that it's lazy)
634 public function assign($what,$where)
635 {
636 if ($this->tpl===false) $this->initialize(); // Lazy initialization
637 $this->tpl->assign($what,$where);
638 }
639
640 // Render a specific page (using a template).
641 // e.g. pb.renderPage('picwall')
642 public function renderPage($page)
643 {
644 if ($this->tpl===false) $this->initialize(); // Lazy initialization
645 $this->tpl->draw($page);
646 }
647
648 /**
649 * Render a 404 page (uses the template : tpl/404.tpl)
650 *
651 * usage : $PAGE->render404('The link was deleted')
652 * @param string $message A messate to display what is not found
653 */
654 public function render404($message='The page you are trying to reach does not exist or has been deleted.') {
655 header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
656 $this->tpl->assign('error_message', $message);
657 $this->renderPage('404');
658 }
659}
660
661// ------------------------------------------------------------------------------------------
662// Output the last N links in RSS 2.0 format.
663function showRSS()
664{
665 header('Content-Type: application/rss+xml; charset=utf-8');
666
667 // $usepermalink : If true, use permalink instead of final link.
668 // User just has to add 'permalink' in URL parameters. e.g. http://mysite.com/shaarli/?do=rss&permalinks
669 // Also enabled through a config option
670 $usepermalinks = isset($_GET['permalinks']) || !$GLOBALS['config']['ENABLE_RSS_PERMALINKS'];
671
672 // Cache system
673 $query = $_SERVER["QUERY_STRING"];
674 $cache = new CachedPage(
675 $GLOBALS['config']['PAGECACHE'],
676 page_url($_SERVER),
677 startsWith($query,'do=rss') && !isLoggedIn()
678 );
679 $cached = $cache->cachedVersion();
680 if (! empty($cached)) {
681 echo $cached;
682 exit;
683 }
684
685 // If cached was not found (or not usable), then read the database and build the response:
686 $LINKSDB = new LinkDB(
687 $GLOBALS['config']['DATASTORE'],
688 isLoggedIn(),
689 $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
690 $GLOBALS['redirector']
691 );
692 // Read links from database (and filter private links if user it not logged in).
693
694 // Optionally filter the results:
695 $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : '';
696 $searchterm = !empty($_GET['searchterm']) ? escape($_GET['searchterm']) : '';
697 if (! empty($searchtags) && ! empty($searchterm)) {
698 $linksToDisplay = $LINKSDB->filter(
699 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
700 array($searchtags, $searchterm)
701 );
702 }
703 elseif ($searchtags) {
704 $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $searchtags);
705 }
706 elseif ($searchterm) {
707 $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $searchterm);
708 }
709 else {
710 $linksToDisplay = $LINKSDB;
711 }
712
713 $nblinksToDisplay = 50; // Number of links to display.
714 // In URL, you can specificy the number of links. Example: nb=200 or nb=all for all links.
715 if (!empty($_GET['nb'])) {
716 $nblinksToDisplay = $_GET['nb'] == 'all' ? count($linksToDisplay) : max(intval($_GET['nb']), 1);
717 }
718
719 $pageaddr = escape(index_url($_SERVER));
720 echo '<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">';
721 echo '<channel><title>'.$GLOBALS['title'].'</title><link>'.$pageaddr.'</link>';
722 echo '<description>Shared links</description><language>en-en</language><copyright>'.$pageaddr.'</copyright>'."\n\n";
723 if (!empty($GLOBALS['config']['PUBSUBHUB_URL']))
724 {
725 echo '<!-- PubSubHubbub Discovery -->';
726 echo '<link rel="hub" href="'.escape($GLOBALS['config']['PUBSUBHUB_URL']).'" xmlns="http://www.w3.org/2005/Atom" />';
727 echo '<link rel="self" href="'.$pageaddr.'?do=rss" xmlns="http://www.w3.org/2005/Atom" />';
728 echo '<!-- End Of PubSubHubbub Discovery -->';
729 }
730 $i=0;
731 $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys().
732 while ($i<$nblinksToDisplay && $i<count($keys))
733 {
734 $link = $linksToDisplay[$keys[$i]];
735 $guid = $pageaddr.'?'.smallHash($link['linkdate']);
736 $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']);
737 $absurl = $link['url'];
738 if (startsWith($absurl,'?')) $absurl=$pageaddr.$absurl; // make permalink URL absolute
739 if ($usepermalinks===true)
740 echo '<item><title>'.$link['title'].'</title><guid isPermaLink="true">'.$guid.'</guid><link>'.$guid.'</link>';
741 else
742 echo '<item><title>'.$link['title'].'</title><guid isPermaLink="false">'.$guid.'</guid><link>'.$absurl.'</link>';
743 if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) {
744 echo '<pubDate>'.escape($date->format(DateTime::RSS))."</pubDate>\n";
745 }
746 if ($link['tags']!='') // Adding tags to each RSS entry (as mentioned in RSS specification)
747 {
748 foreach(explode(' ',$link['tags']) as $tag) { echo '<category domain="'.$pageaddr.'">'.$tag.'</category>'."\n"; }
749 }
750
751 // Add permalink in description
752 $descriptionlink = '(<a href="'.$guid.'">Permalink</a>)';
753 // If user wants permalinks first, put the final link in description
754 if ($usepermalinks===true) $descriptionlink = '(<a href="'.$absurl.'">Link</a>)';
755 if (strlen($link['description'])>0) $descriptionlink = '<br>'.$descriptionlink;
756 echo '<description><![CDATA['.
757 format_description($link['description'], $GLOBALS['redirector']) .
758 $descriptionlink . ']]></description>' . "\n</item>\n";
759 $i++;
760 }
761 echo '</channel></rss><!-- Cached version of '.escape(page_url($_SERVER)).' -->';
762
763 $cache->cache(ob_get_contents());
764 ob_end_flush();
765 exit;
766}
767
768// ------------------------------------------------------------------------------------------
769// Output the last N links in ATOM format.
770function showATOM()
771{
772 header('Content-Type: application/atom+xml; charset=utf-8');
773
774 // $usepermalink : If true, use permalink instead of final link.
775 // User just has to add 'permalink' in URL parameters. e.g. http://mysite.com/shaarli/?do=atom&permalinks
776 $usepermalinks = isset($_GET['permalinks']) || !$GLOBALS['config']['ENABLE_RSS_PERMALINKS'];
777
778 // Cache system
779 $query = $_SERVER["QUERY_STRING"];
780 $cache = new CachedPage(
781 $GLOBALS['config']['PAGECACHE'],
782 page_url($_SERVER),
783 startsWith($query,'do=atom') && !isLoggedIn()
784 );
785 $cached = $cache->cachedVersion();
786 if (!empty($cached)) {
787 echo $cached;
788 exit;
789 }
790
791 // If cached was not found (or not usable), then read the database and build the response:
792 // Read links from database (and filter private links if used it not logged in).
793 $LINKSDB = new LinkDB(
794 $GLOBALS['config']['DATASTORE'],
795 isLoggedIn(),
796 $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
797 $GLOBALS['redirector']
798 );
799
800 // Optionally filter the results:
801 $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : '';
802 $searchterm = !empty($_GET['searchterm']) ? escape($_GET['searchterm']) : '';
803 if (! empty($searchtags) && ! empty($searchterm)) {
804 $linksToDisplay = $LINKSDB->filter(
805 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
806 array($searchtags, $searchterm)
807 );
808 }
809 elseif ($searchtags) {
810 $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $searchtags);
811 }
812 elseif ($searchterm) {
813 $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $searchterm);
814 }
815 else {
816 $linksToDisplay = $LINKSDB;
817 }
818
819 $nblinksToDisplay = 50; // Number of links to display.
820 // In URL, you can specificy the number of links. Example: nb=200 or nb=all for all links.
821 if (!empty($_GET['nb'])) {
822 $nblinksToDisplay = $_GET['nb']=='all' ? count($linksToDisplay) : max(intval($_GET['nb']), 1);
823 }
824
825 $pageaddr=escape(index_url($_SERVER));
826 $latestDate = '';
827 $entries='';
828 $i=0;
829 $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys().
830 while ($i<$nblinksToDisplay && $i<count($keys))
831 {
832 $link = $linksToDisplay[$keys[$i]];
833 $guid = $pageaddr.'?'.smallHash($link['linkdate']);
834 $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']);
835 $iso8601date = $date->format(DateTime::ISO8601);
836 $latestDate = max($latestDate, $iso8601date);
837 $absurl = $link['url'];
838 if (startsWith($absurl,'?')) $absurl=$pageaddr.$absurl; // make permalink URL absolute
839 $entries.='<entry><title>'.$link['title'].'</title>';
840 if ($usepermalinks===true)
841 $entries.='<link href="'.$guid.'" /><id>'.$guid.'</id>';
842 else
843 $entries.='<link href="'.$absurl.'" /><id>'.$guid.'</id>';
844
845 if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) {
846 $entries.='<updated>'.escape($iso8601date).'</updated>';
847 }
848
849 // Add permalink in description
850 $descriptionlink = '(<a href="'.$guid.'">Permalink</a>)';
851 // If user wants permalinks first, put the final link in description
852 if ($usepermalinks===true) $descriptionlink = '(<a href="'.$absurl.'">Link</a>)';
853 if (strlen($link['description'])>0) $descriptionlink = '<br>'.$descriptionlink;
854
855 $entries .= '<content type="html"><![CDATA['.
856 format_description($link['description'], $GLOBALS['redirector']) .
857 $descriptionlink . "]]></content>\n";
858 if ($link['tags']!='') // Adding tags to each ATOM entry (as mentioned in ATOM specification)
859 {
860 foreach(explode(' ',$link['tags']) as $tag)
861 { $entries.='<category scheme="'.$pageaddr.'" term="'.$tag.'" />'."\n"; }
862 }
863 $entries.="</entry>\n";
864 $i++;
865 }
866 $feed='<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom">';
867 $feed.='<title>'.$GLOBALS['title'].'</title>';
868 if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) $feed.='<updated>'.escape($latestDate).'</updated>';
869 $feed.='<link rel="self" href="'.escape(server_url($_SERVER).$_SERVER["REQUEST_URI"]).'" />';
870 if (!empty($GLOBALS['config']['PUBSUBHUB_URL']))
871 {
872 $feed.='<!-- PubSubHubbub Discovery -->';
873 $feed.='<link rel="hub" href="'.escape($GLOBALS['config']['PUBSUBHUB_URL']).'" />';
874 $feed.='<!-- End Of PubSubHubbub Discovery -->';
875 }
876 $feed.='<author><name>'.$pageaddr.'</name><uri>'.$pageaddr.'</uri></author>';
877 $feed.='<id>'.$pageaddr.'</id>'."\n\n"; // Yes, I know I should use a real IRI (RFC3987), but the site URL will do.
878 $feed.=$entries;
879 $feed.='</feed><!-- Cached version of '.escape(page_url($_SERVER)).' -->';
880 echo $feed;
881
882 $cache->cache(ob_get_contents());
883 ob_end_flush();
884 exit;
885}
886
887// ------------------------------------------------------------------------------------------
888// Daily RSS feed: 1 RSS entry per day giving all the links on that day. 567// Daily RSS feed: 1 RSS entry per day giving all the links on that day.
889// Gives the last 7 days (which have links). 568// Gives the last 7 days (which have links).
890// This RSS feed cannot be filtered. 569// This RSS feed cannot be filtered.
891function showDailyRSS() { 570function showDailyRSS() {
892 // Cache system 571 // Cache system
893 $query = $_SERVER["QUERY_STRING"]; 572 $query = $_SERVER['QUERY_STRING'];
894 $cache = new CachedPage( 573 $cache = new CachedPage(
895 $GLOBALS['config']['PAGECACHE'], 574 $GLOBALS['config']['PAGECACHE'],
896 page_url($_SERVER), 575 page_url($_SERVER),
@@ -908,7 +587,8 @@ function showDailyRSS() {
908 $GLOBALS['config']['DATASTORE'], 587 $GLOBALS['config']['DATASTORE'],
909 isLoggedIn(), 588 isLoggedIn(),
910 $GLOBALS['config']['HIDE_PUBLIC_LINKS'], 589 $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
911 $GLOBALS['redirector'] 590 $GLOBALS['redirector'],
591 $GLOBALS['config']['REDIRECTOR_URLENCODE']
912 ); 592 );
913 593
914 /* Some Shaarlies may have very few links, so we need to look 594 /* Some Shaarlies may have very few links, so we need to look
@@ -993,16 +673,10 @@ function showDailyRSS() {
993 * Show the 'Daily' page. 673 * Show the 'Daily' page.
994 * 674 *
995 * @param PageBuilder $pageBuilder Template engine wrapper. 675 * @param PageBuilder $pageBuilder Template engine wrapper.
676 * @param LinkDB $LINKSDB LinkDB instance.
996 */ 677 */
997function showDaily($pageBuilder) 678function showDaily($pageBuilder, $LINKSDB)
998{ 679{
999 $LINKSDB = new LinkDB(
1000 $GLOBALS['config']['DATASTORE'],
1001 isLoggedIn(),
1002 $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
1003 $GLOBALS['redirector']
1004 );
1005
1006 $day=Date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD. 680 $day=Date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD.
1007 if (isset($_GET['day'])) $day=$_GET['day']; 681 if (isset($_GET['day'])) $day=$_GET['day'];
1008 682
@@ -1018,7 +692,7 @@ function showDaily($pageBuilder)
1018 } 692 }
1019 693
1020 try { 694 try {
1021 $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_DAY, $day); 695 $linksToDisplay = $LINKSDB->filterDay($day);
1022 } catch (Exception $exc) { 696 } catch (Exception $exc) {
1023 error_log($exc); 697 error_log($exc);
1024 $linksToDisplay = array(); 698 $linksToDisplay = array();
@@ -1062,7 +736,6 @@ function showDaily($pageBuilder)
1062 $dayDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $day.'_000000'); 736 $dayDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $day.'_000000');
1063 $data = array( 737 $data = array(
1064 'linksToDisplay' => $linksToDisplay, 738 'linksToDisplay' => $linksToDisplay,
1065 'linkcount' => count($LINKSDB),
1066 'cols' => $columns, 739 'cols' => $columns,
1067 'day' => $dayDate->getTimestamp(), 740 'day' => $dayDate->getTimestamp(),
1068 'previousday' => $previousday, 741 'previousday' => $previousday,
@@ -1094,7 +767,8 @@ function renderPage()
1094 $GLOBALS['config']['DATASTORE'], 767 $GLOBALS['config']['DATASTORE'],
1095 isLoggedIn(), 768 isLoggedIn(),
1096 $GLOBALS['config']['HIDE_PUBLIC_LINKS'], 769 $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
1097 $GLOBALS['redirector'] 770 $GLOBALS['redirector'],
771 $GLOBALS['config']['REDIRECTOR_URLENCODE']
1098 ); 772 );
1099 773
1100 $updater = new Updater( 774 $updater = new Updater(
@@ -1116,7 +790,9 @@ function renderPage()
1116 die($e->getMessage()); 790 die($e->getMessage());
1117 } 791 }
1118 792
1119 $PAGE = new pageBuilder; 793 $PAGE = new PageBuilder();
794 $PAGE->assign('linkcount', count($LINKSDB));
795 $PAGE->assign('privateLinkcount', count_private($LINKSDB));
1120 796
1121 // Determine which page will be rendered. 797 // Determine which page will be rendered.
1122 $query = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : ''; 798 $query = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : '';
@@ -1147,12 +823,15 @@ function renderPage()
1147 if ($GLOBALS['config']['OPEN_SHAARLI']) { header('Location: ?'); exit; } // No need to login for open Shaarli 823 if ($GLOBALS['config']['OPEN_SHAARLI']) { header('Location: ?'); exit; } // No need to login for open Shaarli
1148 $token=''; if (ban_canLogin()) $token=getToken(); // Do not waste token generation if not useful. 824 $token=''; if (ban_canLogin()) $token=getToken(); // Do not waste token generation if not useful.
1149 $PAGE->assign('token',$token); 825 $PAGE->assign('token',$token);
826 if (isset($_GET['username'])) {
827 $PAGE->assign('username', escape($_GET['username']));
828 }
1150 $PAGE->assign('returnurl',(isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']):'')); 829 $PAGE->assign('returnurl',(isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']):''));
1151 $PAGE->renderPage('loginform'); 830 $PAGE->renderPage('loginform');
1152 exit; 831 exit;
1153 } 832 }
1154 // -------- User wants to logout. 833 // -------- User wants to logout.
1155 if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=logout')) 834 if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=logout'))
1156 { 835 {
1157 invalidateCaches($GLOBALS['config']['PAGECACHE']); 836 invalidateCaches($GLOBALS['config']['PAGECACHE']);
1158 logout(); 837 logout();
@@ -1164,24 +843,7 @@ function renderPage()
1164 if ($targetPage == Router::$PAGE_PICWALL) 843 if ($targetPage == Router::$PAGE_PICWALL)
1165 { 844 {
1166 // Optionally filter the results: 845 // Optionally filter the results:
1167 $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : ''; 846 $links = $LINKSDB->filterSearch($_GET);
1168 $searchterm = !empty($_GET['searchterm']) ? escape($_GET['searchterm']) : '';
1169 if (! empty($searchtags) && ! empty($searchterm)) {
1170 $links = $LINKSDB->filter(
1171 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
1172 array($searchtags, $searchterm)
1173 );
1174 }
1175 elseif ($searchtags) {
1176 $links = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $searchtags);
1177 }
1178 elseif ($searchterm) {
1179 $links = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $searchterm);
1180 }
1181 else {
1182 $links = $LINKSDB;
1183 }
1184
1185 $linksToDisplay = array(); 847 $linksToDisplay = array();
1186 848
1187 // Get only links which have a thumbnail. 849 // Get only links which have a thumbnail.
@@ -1197,7 +859,6 @@ function renderPage()
1197 } 859 }
1198 860
1199 $data = array( 861 $data = array(
1200 'linkcount' => count($LINKSDB),
1201 'linksToDisplay' => $linksToDisplay, 862 'linksToDisplay' => $linksToDisplay,
1202 ); 863 );
1203 $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => isLoggedIn())); 864 $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => isLoggedIn()));
@@ -1234,15 +895,19 @@ function renderPage()
1234 return strcasecmp($a, $b); 895 return strcasecmp($a, $b);
1235 }); 896 });
1236 897
1237 $tagList=array(); 898 $tagList = array();
1238 foreach($tags as $key=>$value) 899 foreach($tags as $key => $value) {
1239 // Tag font size scaling: default 15 and 30 logarithm bases affect scaling, 22 and 6 are arbitrary font sizes for max and min sizes. 900 // Tag font size scaling:
1240 { 901 // default 15 and 30 logarithm bases affect scaling,
1241 $tagList[$key] = array('count'=>$value,'size'=>log($value, 15) / log($maxcount, 30) * (22-6) + 6); 902 // 22 and 6 are arbitrary font sizes for max and min sizes.
903 $size = log($value, 15) / log($maxcount, 30) * 2.2 + 0.8;
904 $tagList[$key] = array(
905 'count' => $value,
906 'size' => number_format($size, 2, '.', ''),
907 );
1242 } 908 }
1243 909
1244 $data = array( 910 $data = array(
1245 'linkcount' => count($LINKSDB),
1246 'tags' => $tagList, 911 'tags' => $tagList,
1247 ); 912 );
1248 $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => isLoggedIn())); 913 $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => isLoggedIn()));
@@ -1257,7 +922,50 @@ function renderPage()
1257 922
1258 // Daily page. 923 // Daily page.
1259 if ($targetPage == Router::$PAGE_DAILY) { 924 if ($targetPage == Router::$PAGE_DAILY) {
1260 showDaily($PAGE); 925 showDaily($PAGE, $LINKSDB);
926 }
927
928 // ATOM and RSS feed.
929 if ($targetPage == Router::$PAGE_FEED_ATOM || $targetPage == Router::$PAGE_FEED_RSS) {
930 $feedType = $targetPage == Router::$PAGE_FEED_RSS ? FeedBuilder::$FEED_RSS : FeedBuilder::$FEED_ATOM;
931 header('Content-Type: application/'. $feedType .'+xml; charset=utf-8');
932
933 // Cache system
934 $query = $_SERVER['QUERY_STRING'];
935 $cache = new CachedPage(
936 $GLOBALS['config']['PAGECACHE'],
937 page_url($_SERVER),
938 startsWith($query,'do='. $targetPage) && !isLoggedIn()
939 );
940 $cached = $cache->cachedVersion();
941 if (!empty($cached)) {
942 echo $cached;
943 exit;
944 }
945
946 // Generate data.
947 $feedGenerator = new FeedBuilder($LINKSDB, $feedType, $_SERVER, $_GET, isLoggedIn());
948 $feedGenerator->setLocale(strtolower(setlocale(LC_COLLATE, 0)));
949 $feedGenerator->setHideDates($GLOBALS['config']['HIDE_TIMESTAMPS'] && !isLoggedIn());
950 $feedGenerator->setUsePermalinks(isset($_GET['permalinks']) || !$GLOBALS['config']['ENABLE_RSS_PERMALINKS']);
951 if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) {
952 $feedGenerator->setPubsubhubUrl($GLOBALS['config']['PUBSUBHUB_URL']);
953 }
954 $data = $feedGenerator->buildData();
955
956 // Process plugin hook.
957 $pluginManager = PluginManager::getInstance();
958 $pluginManager->executeHooks('render_feed', $data, array(
959 'loggedin' => isLoggedIn(),
960 'target' => $targetPage,
961 ));
962
963 // Render the template.
964 $PAGE->assignAll($data);
965 $PAGE->renderPage('feed.'. $feedType);
966 $cache->cache(ob_get_contents());
967 ob_end_flush();
968 exit;
1261 } 969 }
1262 970
1263 // Display openseach plugin (XML) 971 // Display openseach plugin (XML)
@@ -1372,12 +1080,6 @@ function renderPage()
1372 exit; 1080 exit;
1373 } 1081 }
1374 1082
1375 // Same case as above except that user tried to access ?do=addlink without being logged in
1376 // Note: passing empty parameters makes Shaarli generate default URLs and descriptions.
1377 if (isset($_GET['do']) && $_GET['do'] === 'addlink') {
1378 header('Location: ?do=login&post=');
1379 exit;
1380 }
1381 showLinkList($PAGE, $LINKSDB); 1083 showLinkList($PAGE, $LINKSDB);
1382 if (isset($_GET['edit_link'])) { 1084 if (isset($_GET['edit_link'])) {
1383 header('Location: ?do=login&edit_link='. escape($_GET['edit_link'])); 1085 header('Location: ?do=login&edit_link='. escape($_GET['edit_link']));
@@ -1393,7 +1095,6 @@ function renderPage()
1393 if ($targetPage == Router::$PAGE_TOOLS) 1095 if ($targetPage == Router::$PAGE_TOOLS)
1394 { 1096 {
1395 $data = array( 1097 $data = array(
1396 'linkcount' => count($LINKSDB),
1397 'pageabsaddr' => index_url($_SERVER), 1098 'pageabsaddr' => index_url($_SERVER),
1398 ); 1099 );
1399 $pluginManager->executeHooks('render_tools', $data); 1100 $pluginManager->executeHooks('render_tools', $data);
@@ -1438,7 +1139,6 @@ function renderPage()
1438 } 1139 }
1439 else // show the change password form. 1140 else // show the change password form.
1440 { 1141 {
1441 $PAGE->assign('linkcount',count($LINKSDB));
1442 $PAGE->assign('token',getToken()); 1142 $PAGE->assign('token',getToken());
1443 $PAGE->renderPage('changepassword'); 1143 $PAGE->renderPage('changepassword');
1444 exit; 1144 exit;
@@ -1450,11 +1150,15 @@ function renderPage()
1450 { 1150 {
1451 if (!empty($_POST['title']) ) 1151 if (!empty($_POST['title']) )
1452 { 1152 {
1453 if (!tokenOk($_POST['token'])) die('Wrong token.'); // Go away! 1153 if (!tokenOk($_POST['token'])) {
1154 die('Wrong token.'); // Go away!
1155 }
1454 $tz = 'UTC'; 1156 $tz = 'UTC';
1455 if (!empty($_POST['continent']) && !empty($_POST['city'])) 1157 if (!empty($_POST['continent']) && !empty($_POST['city'])
1456 if (isTimeZoneValid($_POST['continent'],$_POST['city'])) 1158 && isTimeZoneValid($_POST['continent'], $_POST['city'])
1457 $tz = $_POST['continent'].'/'.$_POST['city']; 1159 ) {
1160 $tz = $_POST['continent'] . '/' . $_POST['city'];
1161 }
1458 $GLOBALS['timezone'] = $tz; 1162 $GLOBALS['timezone'] = $tz;
1459 $GLOBALS['title']=$_POST['title']; 1163 $GLOBALS['title']=$_POST['title'];
1460 $GLOBALS['titleLink']=$_POST['titleLink']; 1164 $GLOBALS['titleLink']=$_POST['titleLink'];
@@ -1482,7 +1186,6 @@ function renderPage()
1482 } 1186 }
1483 else // Show the configuration form. 1187 else // Show the configuration form.
1484 { 1188 {
1485 $PAGE->assign('linkcount',count($LINKSDB));
1486 $PAGE->assign('token',getToken()); 1189 $PAGE->assign('token',getToken());
1487 $PAGE->assign('title', empty($GLOBALS['title']) ? '' : $GLOBALS['title'] ); 1190 $PAGE->assign('title', empty($GLOBALS['title']) ? '' : $GLOBALS['title'] );
1488 $PAGE->assign('redirector', empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'] ); 1191 $PAGE->assign('redirector', empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'] );
@@ -1498,7 +1201,6 @@ function renderPage()
1498 if ($targetPage == Router::$PAGE_CHANGETAG) 1201 if ($targetPage == Router::$PAGE_CHANGETAG)
1499 { 1202 {
1500 if (empty($_POST['fromtag']) || (empty($_POST['totag']) && isset($_POST['renametag']))) { 1203 if (empty($_POST['fromtag']) || (empty($_POST['totag']) && isset($_POST['renametag']))) {
1501 $PAGE->assign('linkcount', count($LINKSDB));
1502 $PAGE->assign('token', getToken()); 1204 $PAGE->assign('token', getToken());
1503 $PAGE->assign('tags', $LINKSDB->allTags()); 1205 $PAGE->assign('tags', $LINKSDB->allTags());
1504 $PAGE->renderPage('changetag'); 1206 $PAGE->renderPage('changetag');
@@ -1511,9 +1213,9 @@ function renderPage()
1511 1213
1512 // Delete a tag: 1214 // Delete a tag:
1513 if (isset($_POST['deletetag']) && !empty($_POST['fromtag'])) { 1215 if (isset($_POST['deletetag']) && !empty($_POST['fromtag'])) {
1514 $needle=trim($_POST['fromtag']); 1216 $needle = trim($_POST['fromtag']);
1515 // True for case-sensitive tag search. 1217 // True for case-sensitive tag search.
1516 $linksToAlter = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $needle, true); 1218 $linksToAlter = $LINKSDB->filterSearch(array('searchtags' => $needle), true);
1517 foreach($linksToAlter as $key=>$value) 1219 foreach($linksToAlter as $key=>$value)
1518 { 1220 {
1519 $tags = explode(' ',trim($value['tags'])); 1221 $tags = explode(' ',trim($value['tags']));
@@ -1528,9 +1230,9 @@ function renderPage()
1528 1230
1529 // Rename a tag: 1231 // Rename a tag:
1530 if (isset($_POST['renametag']) && !empty($_POST['fromtag']) && !empty($_POST['totag'])) { 1232 if (isset($_POST['renametag']) && !empty($_POST['fromtag']) && !empty($_POST['totag'])) {
1531 $needle=trim($_POST['fromtag']); 1233 $needle = trim($_POST['fromtag']);
1532 // True for case-sensitive tag search. 1234 // True for case-sensitive tag search.
1533 $linksToAlter = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $needle, true); 1235 $linksToAlter = $LINKSDB->filterSearch(array('searchtags' => $needle), true);
1534 foreach($linksToAlter as $key=>$value) 1236 foreach($linksToAlter as $key=>$value)
1535 { 1237 {
1536 $tags = explode(' ',trim($value['tags'])); 1238 $tags = explode(' ',trim($value['tags']));
@@ -1547,7 +1249,6 @@ function renderPage()
1547 // -------- User wants to add a link without using the bookmarklet: Show form. 1249 // -------- User wants to add a link without using the bookmarklet: Show form.
1548 if ($targetPage == Router::$PAGE_ADDLINK) 1250 if ($targetPage == Router::$PAGE_ADDLINK)
1549 { 1251 {
1550 $PAGE->assign('linkcount',count($LINKSDB));
1551 $PAGE->renderPage('addlink'); 1252 $PAGE->renderPage('addlink');
1552 exit; 1253 exit;
1553 } 1254 }
@@ -1673,7 +1374,6 @@ function renderPage()
1673 $link = $LINKSDB[$_GET['edit_link']]; // Read database 1374 $link = $LINKSDB[$_GET['edit_link']]; // Read database
1674 if (!$link) { header('Location: ?'); exit; } // Link not found in database. 1375 if (!$link) { header('Location: ?'); exit; } // Link not found in database.
1675 $data = array( 1376 $data = array(
1676 'linkcount' => count($LINKSDB),
1677 'link' => $link, 1377 'link' => $link,
1678 'link_is_new' => false, 1378 'link_is_new' => false,
1679 'token' => getToken(), 1379 'token' => getToken(),
@@ -1692,7 +1392,7 @@ function renderPage()
1692 1392
1693 // -------- User want to post a new link: Display link edit form. 1393 // -------- User want to post a new link: Display link edit form.
1694 if (isset($_GET['post'])) { 1394 if (isset($_GET['post'])) {
1695 $url = cleanup_url(escape($_GET['post'])); 1395 $url = cleanup_url($_GET['post']);
1696 1396
1697 $link_is_new = false; 1397 $link_is_new = false;
1698 // Check if URL is not already in database (in this case, we will edit the existing link) 1398 // Check if URL is not already in database (in this case, we will edit the existing link)
@@ -1717,8 +1417,8 @@ function renderPage()
1717 // Extract title. 1417 // Extract title.
1718 $title = html_extract_title($content); 1418 $title = html_extract_title($content);
1719 // Re-encode title in utf-8 if necessary. 1419 // Re-encode title in utf-8 if necessary.
1720 if (! empty($title) && $charset != 'utf-8') { 1420 if (! empty($title) && strtolower($charset) != 'utf-8') {
1721 $title = mb_convert_encoding($title, $charset, 'utf-8'); 1421 $title = mb_convert_encoding($title, 'utf-8', $charset);
1722 } 1422 }
1723 } 1423 }
1724 } 1424 }
@@ -1727,6 +1427,8 @@ function renderPage()
1727 $url = '?' . smallHash($linkdate); 1427 $url = '?' . smallHash($linkdate);
1728 $title = 'Note: '; 1428 $title = 'Note: ';
1729 } 1429 }
1430 $url = escape($url);
1431 $title = escape($title);
1730 1432
1731 $link = array( 1433 $link = array(
1732 'linkdate' => $linkdate, 1434 'linkdate' => $linkdate,
@@ -1739,7 +1441,6 @@ function renderPage()
1739 } 1441 }
1740 1442
1741 $data = array( 1443 $data = array(
1742 'linkcount' => count($LINKSDB),
1743 'link' => $link, 1444 'link' => $link,
1744 'link_is_new' => $link_is_new, 1445 'link_is_new' => $link_is_new,
1745 'token' => getToken(), // XSRF protection. 1446 'token' => getToken(), // XSRF protection.
@@ -1757,49 +1458,52 @@ function renderPage()
1757 exit; 1458 exit;
1758 } 1459 }
1759 1460
1760 // -------- Export as Netscape Bookmarks HTML file. 1461 if ($targetPage == Router::$PAGE_EXPORT) {
1761 if ($targetPage == Router::$PAGE_EXPORT) 1462 // Export links as a Netscape Bookmarks file
1762 { 1463
1763 if (empty($_GET['what'])) 1464 if (empty($_GET['selection'])) {
1764 {
1765 $PAGE->assign('linkcount',count($LINKSDB));
1766 $PAGE->renderPage('export'); 1465 $PAGE->renderPage('export');
1767 exit; 1466 exit;
1768 } 1467 }
1769 $exportWhat=$_GET['what'];
1770 if (!array_intersect(array('all','public','private'),array($exportWhat))) die('What are you trying to export???');
1771 1468
1772 header('Content-Type: text/html; charset=utf-8'); 1469 // export as bookmarks_(all|private|public)_YYYYmmdd_HHMMSS.html
1773 header('Content-disposition: attachment; filename=bookmarks_'.$exportWhat.'_'.strval(date('Ymd_His')).'.html'); 1470 $selection = $_GET['selection'];
1774 $currentdate=date('Y/m/d H:i:s'); 1471 if (isset($_GET['prepend_note_url'])) {
1775 echo <<<HTML 1472 $prependNoteUrl = $_GET['prepend_note_url'];
1776<!DOCTYPE NETSCAPE-Bookmark-file-1> 1473 } else {
1777<!-- This is an automatically generated file. 1474 $prependNoteUrl = false;
1778 It will be read and overwritten.
1779 DO NOT EDIT! -->
1780<!-- Shaarli {$exportWhat} bookmarks export on {$currentdate} -->
1781<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
1782<TITLE>Bookmarks</TITLE>
1783<H1>Bookmarks</H1>
1784HTML;
1785 foreach($LINKSDB as $link)
1786 {
1787 if ($exportWhat=='all' ||
1788 ($exportWhat=='private' && $link['private']!=0) ||
1789 ($exportWhat=='public' && $link['private']==0))
1790 {
1791 $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']);
1792 echo '<DT><A HREF="'.$link['url'].'" ADD_DATE="'.$date->getTimestamp().'" PRIVATE="'.$link['private'].'"';
1793 if ($link['tags']!='') echo ' TAGS="'.str_replace(' ',',',$link['tags']).'"';
1794 echo '>'.$link['title']."</A>\n";
1795 if ($link['description']!='') echo '<DD>'.$link['description']."\n";
1796 }
1797 } 1475 }
1798 exit; 1476
1477 try {
1478 $PAGE->assign(
1479 'links',
1480 NetscapeBookmarkUtils::filterAndFormat(
1481 $LINKSDB,
1482 $selection,
1483 $prependNoteUrl,
1484 index_url($_SERVER)
1485 )
1486 );
1487 } catch (Exception $exc) {
1488 header('Content-Type: text/plain; charset=utf-8');
1489 echo $exc->getMessage();
1490 exit;
1491 }
1492 $now = new DateTime();
1493 header('Content-Type: text/html; charset=utf-8');
1494 header(
1495 'Content-disposition: attachment; filename=bookmarks_'
1496 .$selection.'_'.$now->format(LinkDB::LINK_DATE_FORMAT).'.html'
1497 );
1498 $PAGE->assign('date', $now->format(DateTime::RFC822));
1499 $PAGE->assign('eol', PHP_EOL);
1500 $PAGE->assign('selection', $selection);
1501 $PAGE->renderPage('export.bookmarks');
1502 exit;
1799 } 1503 }
1800 1504
1801 // -------- User is uploading a file for import 1505 // -------- User is uploading a file for import
1802 if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=upload')) 1506 if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=upload'))
1803 { 1507 {
1804 // If file is too big, some form field may be missing. 1508 // If file is too big, some form field may be missing.
1805 if (!isset($_POST['token']) || (!isset($_FILES)) || (isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size']==0)) 1509 if (!isset($_POST['token']) || (!isset($_FILES)) || (isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size']==0))
@@ -1809,14 +1513,13 @@ HTML;
1809 exit; 1513 exit;
1810 } 1514 }
1811 if (!tokenOk($_POST['token'])) die('Wrong token.'); 1515 if (!tokenOk($_POST['token'])) die('Wrong token.');
1812 importFile(); 1516 importFile($LINKSDB);
1813 exit; 1517 exit;
1814 } 1518 }
1815 1519
1816 // -------- Show upload/import dialog: 1520 // -------- Show upload/import dialog:
1817 if ($targetPage == Router::$PAGE_IMPORT) 1521 if ($targetPage == Router::$PAGE_IMPORT)
1818 { 1522 {
1819 $PAGE->assign('linkcount',count($LINKSDB));
1820 $PAGE->assign('token',getToken()); 1523 $PAGE->assign('token',getToken());
1821 $PAGE->assign('maxfilesize',getMaxFileSize()); 1524 $PAGE->assign('maxfilesize',getMaxFileSize());
1822 $PAGE->renderPage('import'); 1525 $PAGE->renderPage('import');
@@ -1878,15 +1581,10 @@ HTML;
1878 1581
1879// ----------------------------------------------------------------------------------------------- 1582// -----------------------------------------------------------------------------------------------
1880// Process the import file form. 1583// Process the import file form.
1881function importFile() 1584function importFile($LINKSDB)
1882{ 1585{
1883 if (!isLoggedIn()) { die('Not allowed.'); } 1586 if (!isLoggedIn()) { die('Not allowed.'); }
1884 $LINKSDB = new LinkDB( 1587
1885 $GLOBALS['config']['DATASTORE'],
1886 isLoggedIn(),
1887 $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
1888 $GLOBALS['redirector']
1889 );
1890 $filename=$_FILES['filetoupload']['name']; 1588 $filename=$_FILES['filetoupload']['name'];
1891 $filesize=$_FILES['filetoupload']['size']; 1589 $filesize=$_FILES['filetoupload']['size'];
1892 $data=file_get_contents($_FILES['filetoupload']['tmp_name']); 1590 $data=file_get_contents($_FILES['filetoupload']['tmp_name']);
@@ -1907,7 +1605,7 @@ function importFile()
1907 { 1605 {
1908 $link = array('linkdate'=>'','title'=>'','url'=>'','description'=>'','tags'=>'','private'=>0); 1606 $link = array('linkdate'=>'','title'=>'','url'=>'','description'=>'','tags'=>'','private'=>0);
1909 $d = explode('<DD>',$html); 1607 $d = explode('<DD>',$html);
1910 if (startswith($d[0],'<A ')) 1608 if (startsWith($d[0], '<A '))
1911 { 1609 {
1912 $link['description'] = (isset($d[1]) ? html_entity_decode(trim($d[1]),ENT_QUOTES,'UTF-8') : ''); // Get description (optional) 1610 $link['description'] = (isset($d[1]) ? html_entity_decode(trim($d[1]),ENT_QUOTES,'UTF-8') : ''); // Get description (optional)
1913 preg_match('!<A .*?>(.*?)</A>!i',$d[0],$matches); $link['title'] = (isset($matches[1]) ? trim($matches[1]) : ''); // Get title 1611 preg_match('!<A .*?>(.*?)</A>!i',$d[0],$matches); $link['title'] = (isset($matches[1]) ? trim($matches[1]) : ''); // Get title
@@ -1966,60 +1664,32 @@ function importFile()
1966 } 1664 }
1967} 1665}
1968 1666
1969// ----------------------------------------------------------------------------------------------- 1667/**
1970// Template for the list of links (<div id="linklist">) 1668 * Template for the list of links (<div id="linklist">)
1971// This function fills all the necessary fields in the $PAGE for the template 'linklist.html' 1669 * This function fills all the necessary fields in the $PAGE for the template 'linklist.html'
1670 *
1671 * @param pageBuilder $PAGE pageBuilder instance.
1672 * @param LinkDB $LINKSDB LinkDB instance.
1673 */
1972function buildLinkList($PAGE,$LINKSDB) 1674function buildLinkList($PAGE,$LINKSDB)
1973{ 1675{
1974 // Filter link database according to parameters. 1676 // Used in templates
1975 $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : ''; 1677 $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : '';
1976 $searchterm = !empty($_GET['searchterm']) ? escape(trim($_GET['searchterm'])) : ''; 1678 $searchterm = !empty($_GET['searchterm']) ? escape($_GET['searchterm']) : '';
1977 $privateonly = !empty($_SESSION['privateonly']) ? true : false;
1978
1979 // Search tags + fullsearch.
1980 if (! empty($searchtags) && ! empty($searchterm)) {
1981 $linksToDisplay = $LINKSDB->filter(
1982 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
1983 array($searchtags, $searchterm),
1984 false,
1985 $privateonly
1986 );
1987 }
1988 // Search by tags.
1989 elseif (! empty($searchtags)) {
1990 $linksToDisplay = $LINKSDB->filter(
1991 LinkFilter::$FILTER_TAG,
1992 $searchtags,
1993 false,
1994 $privateonly
1995 );
1996 }
1997 // Fulltext search.
1998 elseif (! empty($searchterm)) {
1999 $linksToDisplay = $LINKSDB->filter(
2000 LinkFilter::$FILTER_TEXT,
2001 $searchterm,
2002 false,
2003 $privateonly
2004 );
2005 }
2006 // Detect smallHashes in URL.
2007 elseif (! empty($_SERVER['QUERY_STRING'])
2008 && preg_match('/[a-zA-Z0-9-_@]{6}(&.+?)?/', $_SERVER['QUERY_STRING'])
2009 ) {
2010 $linksToDisplay = $LINKSDB->filter(
2011 LinkFilter::$FILTER_HASH,
2012 substr(trim($_SERVER["QUERY_STRING"], '/'), 0, 6)
2013 );
2014 1679
2015 if (count($linksToDisplay) == 0) { 1680 // Smallhash filter
2016 $PAGE->render404('The link you are trying to reach does not exist or has been deleted.'); 1681 if (! empty($_SERVER['QUERY_STRING'])
1682 && preg_match('/^[a-zA-Z0-9-_@]{6}($|&|#)/', $_SERVER['QUERY_STRING'])) {
1683 try {
1684 $linksToDisplay = $LINKSDB->filterHash($_SERVER['QUERY_STRING']);
1685 } catch (LinkNotFoundException $e) {
1686 $PAGE->render404($e->getMessage());
2017 exit; 1687 exit;
2018 } 1688 }
2019 } 1689 } else {
2020 // Otherwise, display without filtering. 1690 // Filter links according search parameters.
2021 else { 1691 $privateonly = !empty($_SESSION['privateonly']);
2022 $linksToDisplay = $LINKSDB->filter('', '', false, $privateonly); 1692 $linksToDisplay = $LINKSDB->filterSearch($_GET, false, $privateonly);
2023 } 1693 }
2024 1694
2025 // ---- Handle paging. 1695 // ---- Handle paging.
@@ -2081,7 +1751,6 @@ function buildLinkList($PAGE,$LINKSDB)
2081 1751
2082 // Fill all template fields. 1752 // Fill all template fields.
2083 $data = array( 1753 $data = array(
2084 'linkcount' => count($LINKSDB),
2085 'previous_page_url' => $previous_page_url, 1754 'previous_page_url' => $previous_page_url,
2086 'next_page_url' => $next_page_url, 1755 'next_page_url' => $next_page_url,
2087 'page_current' => $page, 1756 'page_current' => $page,
@@ -2320,10 +1989,10 @@ function install()
2320 if (!empty($_POST['setlogin']) && !empty($_POST['setpassword'])) 1989 if (!empty($_POST['setlogin']) && !empty($_POST['setpassword']))
2321 { 1990 {
2322 $tz = 'UTC'; 1991 $tz = 'UTC';
2323 if (!empty($_POST['continent']) && !empty($_POST['city'])) { 1992 if (!empty($_POST['continent']) && !empty($_POST['city'])
2324 if (isTimeZoneValid($_POST['continent'], $_POST['city'])) { 1993 && isTimeZoneValid($_POST['continent'], $_POST['city'])
2325 $tz = $_POST['continent'].'/'.$_POST['city']; 1994 ) {
2326 } 1995 $tz = $_POST['continent'].'/'.$_POST['city'];
2327 } 1996 }
2328 $GLOBALS['timezone'] = $tz; 1997 $GLOBALS['timezone'] = $tz;
2329 // Everything is ok, let's create config file. 1998 // Everything is ok, let's create config file.
@@ -2356,7 +2025,7 @@ function install()
2356 $timezone_html = '<tr><td><b>Timezone:</b></td><td>'.$timezone_form.'</td></tr>'; 2025 $timezone_html = '<tr><td><b>Timezone:</b></td><td>'.$timezone_form.'</td></tr>';
2357 } 2026 }
2358 2027
2359 $PAGE = new pageBuilder; 2028 $PAGE = new PageBuilder();
2360 $PAGE->assign('timezone_html',$timezone_html); 2029 $PAGE->assign('timezone_html',$timezone_html);
2361 $PAGE->assign('timezone_js',$timezone_js); 2030 $PAGE->assign('timezone_js',$timezone_js);
2362 $PAGE->renderPage('install'); 2031 $PAGE->renderPage('install');
@@ -2406,7 +2075,7 @@ function genThumbnail()
2406 2075
2407 // Is this a link to an image, or to a flickr page ? 2076 // Is this a link to an image, or to a flickr page ?
2408 $imageurl=''; 2077 $imageurl='';
2409 if (endswith(parse_url($url,PHP_URL_PATH),'.jpg')) 2078 if (endsWith(parse_url($url, PHP_URL_PATH), '.jpg'))
2410 { // This is a direct link to an image. e.g. http://farm1.staticflickr.com/5/5921913_ac83ed27bd_o.jpg 2079 { // This is a direct link to an image. e.g. http://farm1.staticflickr.com/5/5921913_ac83ed27bd_o.jpg
2411 preg_match('!(http://farm\d+\.staticflickr\.com/\d+/\d+_\w+_)\w.jpg!',$url,$matches); 2080 preg_match('!(http://farm\d+\.staticflickr\.com/\d+/\d+_\w+_)\w.jpg!',$url,$matches);
2412 if (!empty($matches[1])) $imageurl=$matches[1].'m.jpg'; 2081 if (!empty($matches[1])) $imageurl=$matches[1].'m.jpg';
@@ -2583,10 +2252,8 @@ function resizeImage($filepath)
2583 return true; 2252 return true;
2584} 2253}
2585 2254
2586if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=genthumbnail')) { genThumbnail(); exit; } // Thumbnail generation/cache does not need the link database. 2255if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=genthumbnail')) { genThumbnail(); exit; } // Thumbnail generation/cache does not need the link database.
2587if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=rss')) { showRSS(); exit; } 2256if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=dailyrss')) { showDailyRSS(); exit; }
2588if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=atom')) { showATOM(); exit; }
2589if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=dailyrss')) { showDailyRSS(); exit; }
2590if (!isset($_SESSION['LINKS_PER_PAGE'])) $_SESSION['LINKS_PER_PAGE']=$GLOBALS['config']['LINKS_PER_PAGE']; 2257if (!isset($_SESSION['LINKS_PER_PAGE'])) $_SESSION['LINKS_PER_PAGE']=$GLOBALS['config']['LINKS_PER_PAGE'];
2591renderPage(); 2258renderPage();
2592?> 2259?>
diff --git a/plugins/demo_plugin/demo_plugin.php b/plugins/demo_plugin/demo_plugin.php
index f5f028e0..18834e53 100644
--- a/plugins/demo_plugin/demo_plugin.php
+++ b/plugins/demo_plugin/demo_plugin.php
@@ -322,4 +322,29 @@ function hook_demo_plugin_delete_link($data)
322 if (strpos($data['url'], 'youtube.com') !== false) { 322 if (strpos($data['url'], 'youtube.com') !== false) {
323 exit('You can not delete a YouTube link. Don\'t ask.'); 323 exit('You can not delete a YouTube link. Don\'t ask.');
324 } 324 }
325} \ No newline at end of file 325}
326
327/**
328 * Execute render_feed hook.
329 * Called with ATOM and RSS feed.
330 *
331 * Special data keys:
332 * - _PAGE_: current page
333 * - _LOGGEDIN_: true/false
334 *
335 * @param array $data data passed to plugin
336 *
337 * @return array altered $data.
338 */
339function hook_demo_plugin_render_feed($data)
340{
341 foreach ($data['links'] as &$link) {
342 if ($data['_PAGE_'] == Router::$PAGE_FEED_ATOM) {
343 $link['description'] .= ' - ATOM Feed' ;
344 }
345 elseif ($data['_PAGE_'] == Router::$PAGE_FEED_RSS) {
346 $link['description'] .= ' - RSS Feed';
347 }
348 }
349 return $data;
350}
diff --git a/plugins/markdown/README.md b/plugins/markdown/README.md
index defaacd1..4f021871 100644
--- a/plugins/markdown/README.md
+++ b/plugins/markdown/README.md
@@ -2,25 +2,31 @@
2 2
3Convert all your shaares description to HTML formatted Markdown. 3Convert all your shaares description to HTML formatted Markdown.
4 4
5Read more about Markdown syntax here. 5[Read more about Markdown syntax](http://daringfireball.net/projects/markdown/syntax).
6
7Markdown processing is done with [Parsedown library](https://github.com/erusev/parsedown).
6 8
7### Installation 9### Installation
8 10
9Clone this repository inside your `tpl/plugins/` directory, or download the archive and unpack it there. 11As a default plugin, it should already be in `tpl/plugins/` directory.
12If not, download and unpack it there.
13
10The directory structure should look like: 14The directory structure should look like:
11 15
12``` 16```
13??? plugins 17--- plugins
14    ??? markdown 18 |--- markdown
15 ??? help.html 19 |--- help.html
16 ??? markdown.css 20 |--- markdown.css
17 ??? markdown.meta 21 |--- markdown.meta
18 ??? markdown.php 22 |--- markdown.php
19 ??? Parsedown.php 23 |--- Parsedown.php
20    ??? README.md 24 |--- README.md
21``` 25```
22 26
23To enable the plugin, add `markdown` to your list of enabled plugins in `data/config.php` 27To enable the plugin, just check it in the plugin administration page.
28
29You can also add `markdown` to your list of enabled plugins in `data/config.php`
24(`ENABLED_PLUGINS` array). 30(`ENABLED_PLUGINS` array).
25 31
26This should look like: 32This should look like:
@@ -29,6 +35,12 @@ This should look like:
29$GLOBALS['config']['ENABLED_PLUGINS'] = array('qrcode', 'any_other_plugin', 'markdown') 35$GLOBALS['config']['ENABLED_PLUGINS'] = array('qrcode', 'any_other_plugin', 'markdown')
30``` 36```
31 37
38### No Markdown tag
39
40If the tag `.nomarkdown` is set for a shaare, it won't be converted to Markdown syntax.
41
42> Note: it's a private tag (leading dot), so it won't be displayed to visitors.
43
32### Known issue 44### Known issue
33 45
34#### Redirector 46#### Redirector
diff --git a/plugins/markdown/markdown.css b/plugins/markdown/markdown.css
index 3c1b2aeb..6789ce84 100644
--- a/plugins/markdown/markdown.css
+++ b/plugins/markdown/markdown.css
@@ -143,6 +143,13 @@
143 hyphens: none; 143 hyphens: none;
144} 144}
145 145
146.markdown :not(pre) code {
147 background-color: #eee;
148 padding: 1px 3px;
149 border-radius: 1px;
150 box-shadow: 0 -1px 0 #e5e5e5,0 0 1px rgba(0,0,0,0.12),0 1px 1px rgba(0,0,0,0.24);
151}
152
146.md_help { 153.md_help {
147 color: white; 154 color: white;
148} 155}
diff --git a/plugins/markdown/markdown.php b/plugins/markdown/markdown.php
index 5a702c7b..57fcce32 100644
--- a/plugins/markdown/markdown.php
+++ b/plugins/markdown/markdown.php
@@ -8,6 +8,12 @@
8 8
9require_once 'Parsedown.php'; 9require_once 'Parsedown.php';
10 10
11/*
12 * If this tag is used on a shaare, the description won't be processed by Parsedown.
13 * Using a private tag so it won't appear for visitors.
14 */
15define('NO_MD_TAG', '.nomarkdown');
16
11/** 17/**
12 * Parse linklist descriptions. 18 * Parse linklist descriptions.
13 * 19 *
@@ -18,6 +24,28 @@ require_once 'Parsedown.php';
18function hook_markdown_render_linklist($data) 24function hook_markdown_render_linklist($data)
19{ 25{
20 foreach ($data['links'] as &$value) { 26 foreach ($data['links'] as &$value) {
27 if (!empty($value['tags']) && noMarkdownTag($value['tags'])) {
28 continue;
29 }
30 $value['description'] = process_markdown($value['description']);
31 }
32
33 return $data;
34}
35
36/**
37 * Parse feed linklist descriptions.
38 *
39 * @param array $data linklist data.
40 *
41 * @return mixed linklist data parsed in markdown (and converted to HTML).
42 */
43function hook_markdown_render_feed($data)
44{
45 foreach ($data['links'] as &$value) {
46 if (!empty($value['tags']) && noMarkdownTag($value['tags'])) {
47 continue;
48 }
21 $value['description'] = process_markdown($value['description']); 49 $value['description'] = process_markdown($value['description']);
22 } 50 }
23 51
@@ -36,6 +64,9 @@ function hook_markdown_render_daily($data)
36 // Manipulate columns data 64 // Manipulate columns data
37 foreach ($data['cols'] as &$value) { 65 foreach ($data['cols'] as &$value) {
38 foreach ($value as &$value2) { 66 foreach ($value as &$value2) {
67 if (!empty($value2['tags']) && noMarkdownTag($value2['tags'])) {
68 continue;
69 }
39 $value2['formatedDescription'] = process_markdown($value2['formatedDescription']); 70 $value2['formatedDescription'] = process_markdown($value2['formatedDescription']);
40 } 71 }
41 } 72 }
@@ -44,6 +75,18 @@ function hook_markdown_render_daily($data)
44} 75}
45 76
46/** 77/**
78 * Check if noMarkdown is set in tags.
79 *
80 * @param string $tags tag list
81 *
82 * @return bool true if markdown should be disabled on this link.
83 */
84function noMarkdownTag($tags)
85{
86 return strpos($tags, NO_MD_TAG) !== false;
87}
88
89/**
47 * When link list is displayed, include markdown CSS. 90 * When link list is displayed, include markdown CSS.
48 * 91 *
49 * @param array $data includes data. 92 * @param array $data includes data.
@@ -75,6 +118,12 @@ function hook_markdown_render_editlink($data)
75{ 118{
76 // Load help HTML into a string 119 // Load help HTML into a string
77 $data['edit_link_plugin'][] = file_get_contents(PluginManager::$PLUGINS_PATH .'/markdown/help.html'); 120 $data['edit_link_plugin'][] = file_get_contents(PluginManager::$PLUGINS_PATH .'/markdown/help.html');
121
122 // Add no markdown 'meta-tag' in tag list if it was never used, for autocompletion.
123 if (! in_array(NO_MD_TAG, $data['tags'])) {
124 $data['tags'][NO_MD_TAG] = 0;
125 }
126
78 return $data; 127 return $data;
79} 128}
80 129
diff --git a/shaarli_version.php b/shaarli_version.php
index 5e293321..184e5220 100644
--- a/shaarli_version.php
+++ b/shaarli_version.php
@@ -1 +1 @@
<?php /* 0.6.5 */ ?> <?php /* 0.7.0 */
diff --git a/tests/FeedBuilderTest.php b/tests/FeedBuilderTest.php
new file mode 100644
index 00000000..069b1581
--- /dev/null
+++ b/tests/FeedBuilderTest.php
@@ -0,0 +1,212 @@
1<?php
2
3require_once 'application/FeedBuilder.php';
4require_once 'application/LinkDB.php';
5
6/**
7 * FeedBuilderTest class.
8 *
9 * Unit tests for FeedBuilder.
10 */
11class FeedBuilderTest extends PHPUnit_Framework_TestCase
12{
13 /**
14 * @var string locale Basque (Spain).
15 */
16 public static $LOCALE = 'eu_ES';
17
18 /**
19 * @var string language in RSS format.
20 */
21 public static $RSS_LANGUAGE = 'eu-es';
22
23 /**
24 * @var string language in ATOM format.
25 */
26 public static $ATOM_LANGUAGUE = 'eu';
27
28 protected static $testDatastore = 'sandbox/datastore.php';
29
30 public static $linkDB;
31
32 public static $serverInfo;
33
34 /**
35 * Called before every test method.
36 */
37 public static function setUpBeforeClass()
38 {
39 $refLinkDB = new ReferenceLinkDB();
40 $refLinkDB->write(self::$testDatastore);
41 self::$linkDB = new LinkDB(self::$testDatastore, true, false);
42 self::$serverInfo = array(
43 'HTTPS' => 'Off',
44 'SERVER_NAME' => 'host.tld',
45 'SERVER_PORT' => '80',
46 'SCRIPT_NAME' => '/index.php',
47 'REQUEST_URI' => '/index.php?do=feed',
48 );
49 }
50
51 /**
52 * Test GetTypeLanguage().
53 */
54 public function testGetTypeLanguage()
55 {
56 $feedBuilder = new FeedBuilder(null, FeedBuilder::$FEED_ATOM, null, null, false);
57 $feedBuilder->setLocale(self::$LOCALE);
58 $this->assertEquals(self::$ATOM_LANGUAGUE, $feedBuilder->getTypeLanguage());
59 $feedBuilder = new FeedBuilder(null, FeedBuilder::$FEED_RSS, null, null, false);
60 $feedBuilder->setLocale(self::$LOCALE);
61 $this->assertEquals(self::$RSS_LANGUAGE, $feedBuilder->getTypeLanguage());
62 $feedBuilder = new FeedBuilder(null, FeedBuilder::$FEED_ATOM, null, null, false);
63 $this->assertEquals('en', $feedBuilder->getTypeLanguage());
64 $feedBuilder = new FeedBuilder(null, FeedBuilder::$FEED_RSS, null, null, false);
65 $this->assertEquals('en-en', $feedBuilder->getTypeLanguage());
66 }
67
68 /**
69 * Test buildData with RSS feed.
70 */
71 public function testRSSBuildData()
72 {
73 $feedBuilder = new FeedBuilder(self::$linkDB, FeedBuilder::$FEED_RSS, self::$serverInfo, null, false);
74 $feedBuilder->setLocale(self::$LOCALE);
75 $data = $feedBuilder->buildData();
76 // Test headers (RSS)
77 $this->assertEquals(self::$RSS_LANGUAGE, $data['language']);
78 $this->assertEmpty($data['pubsubhub_url']);
79 $this->assertEquals('Tue, 10 Mar 2015 11:46:51 +0100', $data['last_update']);
80 $this->assertEquals(true, $data['show_dates']);
81 $this->assertEquals('http://host.tld/index.php?do=feed', $data['self_link']);
82 $this->assertEquals('http://host.tld/', $data['index_url']);
83 $this->assertFalse($data['usepermalinks']);
84 $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
85
86 // Test first link (note link)
87 $link = array_shift($data['links']);
88 $this->assertEquals('20150310_114651', $link['linkdate']);
89 $this->assertEquals('http://host.tld/?WDWyig', $link['guid']);
90 $this->assertEquals('http://host.tld/?WDWyig', $link['url']);
91 $this->assertEquals('Tue, 10 Mar 2015 11:46:51 +0100', $link['iso_date']);
92 $this->assertContains('Stallman has a beard', $link['description']);
93 $this->assertContains('Permalink', $link['description']);
94 $this->assertContains('http://host.tld/?WDWyig', $link['description']);
95 $this->assertEquals(1, count($link['taglist']));
96 $this->assertEquals('stuff', $link['taglist'][0]);
97
98 // Test URL with external link.
99 $this->assertEquals('https://static.fsf.org/nosvn/faif-2.0.pdf', $data['links']['20150310_114633']['url']);
100
101 // Test multitags.
102 $this->assertEquals(5, count($data['links']['20141125_084734']['taglist']));
103 $this->assertEquals('css', $data['links']['20141125_084734']['taglist'][0]);
104 }
105
106 /**
107 * Test buildData with ATOM feed (test only specific to ATOM).
108 */
109 public function testAtomBuildData()
110 {
111 $feedBuilder = new FeedBuilder(self::$linkDB, FeedBuilder::$FEED_ATOM, self::$serverInfo, null, false);
112 $feedBuilder->setLocale(self::$LOCALE);
113 $data = $feedBuilder->buildData();
114 $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
115 $link = array_shift($data['links']);
116 $this->assertEquals('2015-03-10T11:46:51+01:00', $link['iso_date']);
117 }
118
119 /**
120 * Test buildData with search criteria.
121 */
122 public function testBuildDataFiltered()
123 {
124 $criteria = array(
125 'searchtags' => 'stuff',
126 'searchterm' => 'beard',
127 );
128 $feedBuilder = new FeedBuilder(self::$linkDB, FeedBuilder::$FEED_ATOM, self::$serverInfo, $criteria, false);
129 $feedBuilder->setLocale(self::$LOCALE);
130 $data = $feedBuilder->buildData();
131 $this->assertEquals(1, count($data['links']));
132 $link = array_shift($data['links']);
133 $this->assertEquals('20150310_114651', $link['linkdate']);
134 }
135
136 /**
137 * Test buildData with nb limit.
138 */
139 public function testBuildDataCount()
140 {
141 $criteria = array(
142 'nb' => '1',
143 );
144 $feedBuilder = new FeedBuilder(self::$linkDB, FeedBuilder::$FEED_ATOM, self::$serverInfo, $criteria, false);
145 $feedBuilder->setLocale(self::$LOCALE);
146 $data = $feedBuilder->buildData();
147 $this->assertEquals(1, count($data['links']));
148 $link = array_shift($data['links']);
149 $this->assertEquals('20150310_114651', $link['linkdate']);
150 }
151
152 /**
153 * Test buildData with permalinks on.
154 */
155 public function testBuildDataPermalinks()
156 {
157 $feedBuilder = new FeedBuilder(self::$linkDB, FeedBuilder::$FEED_ATOM, self::$serverInfo, null, false);
158 $feedBuilder->setLocale(self::$LOCALE);
159 $feedBuilder->setUsePermalinks(true);
160 $data = $feedBuilder->buildData();
161 $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
162 $this->assertTrue($data['usepermalinks']);
163 // First link is a permalink
164 $link = array_shift($data['links']);
165 $this->assertEquals('20150310_114651', $link['linkdate']);
166 $this->assertEquals('http://host.tld/?WDWyig', $link['guid']);
167 $this->assertEquals('http://host.tld/?WDWyig', $link['url']);
168 $this->assertContains('Direct link', $link['description']);
169 $this->assertContains('http://host.tld/?WDWyig', $link['description']);
170 // Second link is a direct link
171 $link = array_shift($data['links']);
172 $this->assertEquals('20150310_114633', $link['linkdate']);
173 $this->assertEquals('http://host.tld/?kLHmZg', $link['guid']);
174 $this->assertEquals('https://static.fsf.org/nosvn/faif-2.0.pdf', $link['url']);
175 $this->assertContains('Direct link', $link['description']);
176 $this->assertContains('https://static.fsf.org/nosvn/faif-2.0.pdf', $link['description']);
177 }
178
179 /**
180 * Test buildData with hide dates settings.
181 */
182 public function testBuildDataHideDates()
183 {
184 $feedBuilder = new FeedBuilder(self::$linkDB, FeedBuilder::$FEED_ATOM, self::$serverInfo, null, false);
185 $feedBuilder->setLocale(self::$LOCALE);
186 $feedBuilder->setHideDates(true);
187 $data = $feedBuilder->buildData();
188 $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
189 $this->assertFalse($data['show_dates']);
190
191 // Show dates while logged in
192 $feedBuilder = new FeedBuilder(self::$linkDB, FeedBuilder::$FEED_ATOM, self::$serverInfo, null, true);
193 $feedBuilder->setLocale(self::$LOCALE);
194 $feedBuilder->setHideDates(true);
195 $data = $feedBuilder->buildData();
196 $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
197 $this->assertTrue($data['show_dates']);
198 }
199
200 /**
201 * Test buildData with hide dates settings.
202 */
203 public function testBuildDataPubsubhub()
204 {
205 $feedBuilder = new FeedBuilder(self::$linkDB, FeedBuilder::$FEED_ATOM, self::$serverInfo, null, false);
206 $feedBuilder->setLocale(self::$LOCALE);
207 $feedBuilder->setPubsubhubUrl('http://pubsubhub.io');
208 $data = $feedBuilder->buildData();
209 $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
210 $this->assertEquals('http://pubsubhub.io', $data['pubsubhub_url']);
211 }
212}
diff --git a/tests/HttpUtils/GetHttpUrlTest.php b/tests/HttpUtils/GetHttpUrlTest.php
index fd293505..ea53de5f 100644
--- a/tests/HttpUtils/GetHttpUrlTest.php
+++ b/tests/HttpUtils/GetHttpUrlTest.php
@@ -35,4 +35,31 @@ class GetHttpUrlTest extends PHPUnit_Framework_TestCase
35 $this->assertFalse($headers); 35 $this->assertFalse($headers);
36 $this->assertFalse($content); 36 $this->assertFalse($content);
37 } 37 }
38
39 /**
40 * Test getAbsoluteUrl with relative target URL.
41 */
42 public function testGetAbsoluteUrlWithRelative()
43 {
44 $origin = 'http://non.existent/blabla/?test';
45 $target = '/stuff.php';
46
47 $expected = 'http://non.existent/stuff.php';
48 $this->assertEquals($expected, getAbsoluteUrl($origin, $target));
49
50 $target = 'stuff.php';
51 $expected = 'http://non.existent/blabla/stuff.php';
52 $this->assertEquals($expected, getAbsoluteUrl($origin, $target));
53 }
54
55 /**
56 * Test getAbsoluteUrl with absolute target URL.
57 */
58 public function testGetAbsoluteUrlWithAbsolute()
59 {
60 $origin = 'http://non.existent/blabla/?test';
61 $target = 'http://other.url/stuff.php';
62
63 $this->assertEquals($target, getAbsoluteUrl($origin, $target));
64 }
38} 65}
diff --git a/tests/LinkDBTest.php b/tests/LinkDBTest.php
index b6a273b3..b055fe91 100644
--- a/tests/LinkDBTest.php
+++ b/tests/LinkDBTest.php
@@ -17,8 +17,20 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
17{ 17{
18 // datastore to test write operations 18 // datastore to test write operations
19 protected static $testDatastore = 'sandbox/datastore.php'; 19 protected static $testDatastore = 'sandbox/datastore.php';
20
21 /**
22 * @var ReferenceLinkDB instance.
23 */
20 protected static $refDB = null; 24 protected static $refDB = null;
25
26 /**
27 * @var LinkDB public LinkDB instance.
28 */
21 protected static $publicLinkDB = null; 29 protected static $publicLinkDB = null;
30
31 /**
32 * @var LinkDB private LinkDB instance.
33 */
22 protected static $privateLinkDB = null; 34 protected static $privateLinkDB = null;
23 35
24 /** 36 /**
@@ -326,6 +338,13 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
326 $db = new LinkDB(self::$testDatastore, false, false, $redirector); 338 $db = new LinkDB(self::$testDatastore, false, false, $redirector);
327 foreach($db as $link) { 339 foreach($db as $link) {
328 $this->assertStringStartsWith($redirector, $link['real_url']); 340 $this->assertStringStartsWith($redirector, $link['real_url']);
341 $this->assertNotFalse(strpos($link['real_url'], urlencode('://')));
342 }
343
344 $db = new LinkDB(self::$testDatastore, false, false, $redirector, false);
345 foreach($db as $link) {
346 $this->assertStringStartsWith($redirector, $link['real_url']);
347 $this->assertFalse(strpos($link['real_url'], urlencode('://')));
329 } 348 }
330 } 349 }
331 350
@@ -335,9 +354,10 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
335 public function testFilterString() 354 public function testFilterString()
336 { 355 {
337 $tags = 'dev cartoon'; 356 $tags = 'dev cartoon';
357 $request = array('searchtags' => $tags);
338 $this->assertEquals( 358 $this->assertEquals(
339 2, 359 2,
340 count(self::$privateLinkDB->filter(LinkFilter::$FILTER_TAG, $tags, true, false)) 360 count(self::$privateLinkDB->filterSearch($request, true, false))
341 ); 361 );
342 } 362 }
343 363
@@ -347,9 +367,10 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
347 public function testFilterArray() 367 public function testFilterArray()
348 { 368 {
349 $tags = array('dev', 'cartoon'); 369 $tags = array('dev', 'cartoon');
370 $request = array('searchtags' => $tags);
350 $this->assertEquals( 371 $this->assertEquals(
351 2, 372 2,
352 count(self::$privateLinkDB->filter(LinkFilter::$FILTER_TAG, $tags, true, false)) 373 count(self::$privateLinkDB->filterSearch($request, true, false))
353 ); 374 );
354 } 375 }
355 376
@@ -360,14 +381,48 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
360 public function testHiddenTags() 381 public function testHiddenTags()
361 { 382 {
362 $tags = '.hidden'; 383 $tags = '.hidden';
384 $request = array('searchtags' => $tags);
363 $this->assertEquals( 385 $this->assertEquals(
364 1, 386 1,
365 count(self::$privateLinkDB->filter(LinkFilter::$FILTER_TAG, $tags, true, false)) 387 count(self::$privateLinkDB->filterSearch($request, true, false))
366 ); 388 );
367 389
368 $this->assertEquals( 390 $this->assertEquals(
369 0, 391 0,
370 count(self::$publicLinkDB->filter(LinkFilter::$FILTER_TAG, $tags, true, false)) 392 count(self::$publicLinkDB->filterSearch($request, true, false))
371 ); 393 );
372 } 394 }
395
396 /**
397 * Test filterHash() with a valid smallhash.
398 */
399 public function testFilterHashValid()
400 {
401 $request = smallHash('20150310_114651');
402 $this->assertEquals(
403 1,
404 count(self::$publicLinkDB->filterHash($request))
405 );
406 }
407
408 /**
409 * Test filterHash() with an invalid smallhash.
410 *
411 * @expectedException LinkNotFoundException
412 */
413 public function testFilterHashInValid1()
414 {
415 $request = 'blabla';
416 self::$publicLinkDB->filterHash($request);
417 }
418
419 /**
420 * Test filterHash() with an empty smallhash.
421 *
422 * @expectedException LinkNotFoundException
423 */
424 public function testFilterHashInValid()
425 {
426 self::$publicLinkDB->filterHash('');
427 }
373} 428}
diff --git a/tests/LinkFilterTest.php b/tests/LinkFilterTest.php
index ef1cc10a..1620bb78 100644
--- a/tests/LinkFilterTest.php
+++ b/tests/LinkFilterTest.php
@@ -12,8 +12,6 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
12 */ 12 */
13 protected static $linkFilter; 13 protected static $linkFilter;
14 14
15 protected static $NB_LINKS_REFDB = 7;
16
17 /** 15 /**
18 * Instanciate linkFilter with ReferenceLinkDB data. 16 * Instanciate linkFilter with ReferenceLinkDB data.
19 */ 17 */
@@ -29,7 +27,7 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
29 public function testFilter() 27 public function testFilter()
30 { 28 {
31 $this->assertEquals( 29 $this->assertEquals(
32 self::$NB_LINKS_REFDB, 30 ReferenceLinkDB::$NB_LINKS_TOTAL,
33 count(self::$linkFilter->filter('', '')) 31 count(self::$linkFilter->filter('', ''))
34 ); 32 );
35 33
@@ -40,12 +38,12 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
40 ); 38 );
41 39
42 $this->assertEquals( 40 $this->assertEquals(
43 self::$NB_LINKS_REFDB, 41 ReferenceLinkDB::$NB_LINKS_TOTAL,
44 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, '')) 42 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, ''))
45 ); 43 );
46 44
47 $this->assertEquals( 45 $this->assertEquals(
48 self::$NB_LINKS_REFDB, 46 ReferenceLinkDB::$NB_LINKS_TOTAL,
49 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '')) 47 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, ''))
50 ); 48 );
51 } 49 }
@@ -167,13 +165,12 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
167 165
168 /** 166 /**
169 * No link for this hash 167 * No link for this hash
168 *
169 * @expectedException LinkNotFoundException
170 */ 170 */
171 public function testFilterUnknownSmallHash() 171 public function testFilterUnknownSmallHash()
172 { 172 {
173 $this->assertEquals( 173 self::$linkFilter->filter(LinkFilter::$FILTER_HASH, 'Iblaah');
174 0,
175 count(self::$linkFilter->filter(LinkFilter::$FILTER_HASH, 'Iblaah'))
176 );
177 } 174 }
178 175
179 /** 176 /**
@@ -383,7 +380,7 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
383 )) 380 ))
384 ); 381 );
385 $this->assertEquals( 382 $this->assertEquals(
386 self::$NB_LINKS_REFDB, 383 ReferenceLinkDB::$NB_LINKS_TOTAL,
387 count(self::$linkFilter->filter( 384 count(self::$linkFilter->filter(
388 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT, 385 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
389 '' 386 ''
diff --git a/tests/LinkUtilsTest.php b/tests/LinkUtilsTest.php
index c2257590..d1b022fd 100644
--- a/tests/LinkUtilsTest.php
+++ b/tests/LinkUtilsTest.php
@@ -15,6 +15,8 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
15 $title = 'Read me please.'; 15 $title = 'Read me please.';
16 $html = '<html><meta>stuff</meta><title>'. $title .'</title></html>'; 16 $html = '<html><meta>stuff</meta><title>'. $title .'</title></html>';
17 $this->assertEquals($title, html_extract_title($html)); 17 $this->assertEquals($title, html_extract_title($html));
18 $html = '<html><title>'. $title .'</title>blabla<title>another</title></html>';
19 $this->assertEquals($title, html_extract_title($html));
18 } 20 }
19 21
20 /** 22 /**
@@ -82,4 +84,13 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
82 $html = '<html><meta>stuff</meta><meta charset=""/></html>'; 84 $html = '<html><meta>stuff</meta><meta charset=""/></html>';
83 $this->assertFalse(html_extract_charset($html)); 85 $this->assertFalse(html_extract_charset($html));
84 } 86 }
87
88 /**
89 * Test count_private.
90 */
91 public function testCountPrivateLinks()
92 {
93 $refDB = new ReferenceLinkDB();
94 $this->assertEquals($refDB->countPrivateLinks(), count_private($refDB->getLinks()));
95 }
85} 96}
diff --git a/tests/NetscapeBookmarkUtilsTest.php b/tests/NetscapeBookmarkUtilsTest.php
new file mode 100644
index 00000000..41e6d84c
--- /dev/null
+++ b/tests/NetscapeBookmarkUtilsTest.php
@@ -0,0 +1,134 @@
1<?php
2
3require_once 'application/NetscapeBookmarkUtils.php';
4
5/**
6 * Netscape bookmark import and export
7 */
8class NetscapeBookmarkUtilsTest extends PHPUnit_Framework_TestCase
9{
10 /**
11 * @var string datastore to test write operations
12 */
13 protected static $testDatastore = 'sandbox/datastore.php';
14
15 /**
16 * @var ReferenceLinkDB instance.
17 */
18 protected static $refDb = null;
19
20 /**
21 * @var LinkDB private LinkDB instance.
22 */
23 protected static $linkDb = null;
24
25 /**
26 * Instantiate reference data
27 */
28 public static function setUpBeforeClass()
29 {
30 self::$refDb = new ReferenceLinkDB();
31 self::$refDb->write(self::$testDatastore);
32 self::$linkDb = new LinkDB(self::$testDatastore, true, false);
33 }
34
35 /**
36 * Attempt to export an invalid link selection
37 * @expectedException Exception
38 * @expectedExceptionMessageRegExp /Invalid export selection/
39 */
40 public function testFilterAndFormatInvalid()
41 {
42 NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'derp', false, '');
43 }
44
45 /**
46 * Prepare all links for export
47 */
48 public function testFilterAndFormatAll()
49 {
50 $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'all', false, '');
51 $this->assertEquals(self::$refDb->countLinks(), sizeof($links));
52 foreach ($links as $link) {
53 $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']);
54 $this->assertEquals(
55 $date->getTimestamp(),
56 $link['timestamp']
57 );
58 $this->assertEquals(
59 str_replace(' ', ',', $link['tags']),
60 $link['taglist']
61 );
62 }
63 }
64
65 /**
66 * Prepare private links for export
67 */
68 public function testFilterAndFormatPrivate()
69 {
70 $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'private', false, '');
71 $this->assertEquals(self::$refDb->countPrivateLinks(), sizeof($links));
72 foreach ($links as $link) {
73 $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']);
74 $this->assertEquals(
75 $date->getTimestamp(),
76 $link['timestamp']
77 );
78 $this->assertEquals(
79 str_replace(' ', ',', $link['tags']),
80 $link['taglist']
81 );
82 }
83 }
84
85 /**
86 * Prepare public links for export
87 */
88 public function testFilterAndFormatPublic()
89 {
90 $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'public', false, '');
91 $this->assertEquals(self::$refDb->countPublicLinks(), sizeof($links));
92 foreach ($links as $link) {
93 $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']);
94 $this->assertEquals(
95 $date->getTimestamp(),
96 $link['timestamp']
97 );
98 $this->assertEquals(
99 str_replace(' ', ',', $link['tags']),
100 $link['taglist']
101 );
102 }
103 }
104
105 /**
106 * Do not prepend notes with the Shaarli index's URL
107 */
108 public function testFilterAndFormatDoNotPrependNoteUrl()
109 {
110 $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'public', false, '');
111 $this->assertEquals(
112 '?WDWyig',
113 $links[0]['url']
114 );
115 }
116
117 /**
118 * Prepend notes with the Shaarli index's URL
119 */
120 public function testFilterAndFormatPrependNoteUrl()
121 {
122 $indexUrl = 'http://localhost:7469/shaarli/';
123 $links = NetscapeBookmarkUtils::filterAndFormat(
124 self::$linkDb,
125 'public',
126 true,
127 $indexUrl
128 );
129 $this->assertEquals(
130 $indexUrl . '?WDWyig',
131 $links[0]['url']
132 );
133 }
134}
diff --git a/tests/TimeZoneTest.php b/tests/TimeZoneTest.php
index b219030a..2976d116 100644
--- a/tests/TimeZoneTest.php
+++ b/tests/TimeZoneTest.php
@@ -67,7 +67,6 @@ class TimeZoneTest extends PHPUnit_Framework_TestCase
67 { 67 {
68 $this->assertTrue(isTimeZoneValid('America', 'Argentina/Ushuaia')); 68 $this->assertTrue(isTimeZoneValid('America', 'Argentina/Ushuaia'));
69 $this->assertTrue(isTimeZoneValid('Europe', 'Oslo')); 69 $this->assertTrue(isTimeZoneValid('Europe', 'Oslo'));
70 $this->assertTrue(isTimeZoneValid('UTC', 'UTC'));
71 } 70 }
72 71
73 /** 72 /**
@@ -78,5 +77,6 @@ class TimeZoneTest extends PHPUnit_Framework_TestCase
78 $this->assertFalse(isTimeZoneValid('CEST', 'CEST')); 77 $this->assertFalse(isTimeZoneValid('CEST', 'CEST'));
79 $this->assertFalse(isTimeZoneValid('Europe', 'Atlantis')); 78 $this->assertFalse(isTimeZoneValid('Europe', 'Atlantis'));
80 $this->assertFalse(isTimeZoneValid('Middle_Earth', 'Moria')); 79 $this->assertFalse(isTimeZoneValid('Middle_Earth', 'Moria'));
80 $this->assertFalse(isTimeZoneValid('UTC', 'UTC'));
81 } 81 }
82} 82}
diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php
index d865066b..a29d9067 100644
--- a/tests/Updater/UpdaterTest.php
+++ b/tests/Updater/UpdaterTest.php
@@ -236,9 +236,9 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
236 $refDB = new ReferenceLinkDB(); 236 $refDB = new ReferenceLinkDB();
237 $refDB->write(self::$testDatastore); 237 $refDB->write(self::$testDatastore);
238 $linkDB = new LinkDB(self::$testDatastore, true, false); 238 $linkDB = new LinkDB(self::$testDatastore, true, false);
239 $this->assertEmpty($linkDB->filter(LinkFilter::$FILTER_TAG, 'exclude')); 239 $this->assertEmpty($linkDB->filterSearch(array('searchtags' => 'exclude')));
240 $updater = new Updater(array(), self::$configFields, $linkDB, true); 240 $updater = new Updater(array(), self::$configFields, $linkDB, true);
241 $updater->updateMethodRenameDashTags(); 241 $updater->updateMethodRenameDashTags();
242 $this->assertNotEmpty($linkDB->filter(LinkFilter::$FILTER_TAG, 'exclude')); 242 $this->assertNotEmpty($linkDB->filterSearch(array('searchtags' => 'exclude')));
243 } 243 }
244} 244}
diff --git a/tests/Url/UrlTest.php b/tests/Url/UrlTest.php
index 425327ed..ce82265e 100644
--- a/tests/Url/UrlTest.php
+++ b/tests/Url/UrlTest.php
@@ -128,6 +128,13 @@ class UrlTest extends PHPUnit_Framework_TestCase
128 self::$baseUrl.'?my=stuff&is=kept#again', 128 self::$baseUrl.'?my=stuff&is=kept#again',
129 $url->cleanup() 129 $url->cleanup()
130 ); 130 );
131
132 // test firefox reader url
133 $url = new Url(
134 'about://reader?url=' . urlencode(self::$baseUrl .'?my=stuff&is=kept')
135 );
136 $this->assertEquals(self::$baseUrl.'?my=stuff&is=kept', $url->cleanup());
137
131 } 138 }
132 139
133 /** 140 /**
@@ -174,4 +181,19 @@ class UrlTest extends PHPUnit_Framework_TestCase
174 $url = new Url('ftp://save.tld/mysave'); 181 $url = new Url('ftp://save.tld/mysave');
175 $this->assertFalse($url->isHttp()); 182 $this->assertFalse($url->isHttp());
176 } 183 }
184
185 /**
186 * Test IndToAscii.
187 */
188 function testIndToAscii()
189 {
190 $ind = 'http://www.académie-française.fr/';
191 $expected = 'http://www.xn--acadmie-franaise-npb1a.fr/';
192 $url = new Url($ind);
193 $this->assertEquals($expected, $url->idnToAscii());
194
195 $notInd = 'http://www.academie-francaise.fr/';
196 $url = new Url($notInd);
197 $this->assertEquals($notInd, $url->idnToAscii());
198 }
177} 199}
diff --git a/tests/plugins/PluginMarkdownTest.php b/tests/plugins/PluginMarkdownTest.php
index 8e1a128a..fa7e1d52 100644
--- a/tests/plugins/PluginMarkdownTest.php
+++ b/tests/plugins/PluginMarkdownTest.php
@@ -102,7 +102,8 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase
102 /** 102 /**
103 * Test sanitize_html(). 103 * Test sanitize_html().
104 */ 104 */
105 function testSanitizeHtml() { 105 function testSanitizeHtml()
106 {
106 $input = '< script src="js.js"/>'; 107 $input = '< script src="js.js"/>';
107 $input .= '< script attr>alert(\'xss\');</script>'; 108 $input .= '< script attr>alert(\'xss\');</script>';
108 $input .= '<style> * { display: none }</style>'; 109 $input .= '<style> * { display: none }</style>';
@@ -114,4 +115,38 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase
114 $input = escape($input); 115 $input = escape($input);
115 $this->assertEquals($input, sanitize_html($input)); 116 $this->assertEquals($input, sanitize_html($input));
116 } 117 }
118
119 /**
120 * Test the no markdown tag.
121 */
122 function testNoMarkdownTag()
123 {
124 $str = 'All _work_ and `no play` makes Jack a *dull* boy.';
125 $data = array(
126 'links' => array(array(
127 'description' => $str,
128 'tags' => NO_MD_TAG
129 ))
130 );
131
132 $data = hook_markdown_render_linklist($data);
133 $this->assertEquals($str, $data['links'][0]['description']);
134
135 $data = array(
136 // Columns data
137 'cols' => array(
138 // First, second, third.
139 0 => array(
140 // nth link
141 0 => array(
142 'formatedDescription' => $str,
143 'tags' => NO_MD_TAG
144 ),
145 ),
146 ),
147 );
148
149 $data = hook_markdown_render_daily($data);
150 $this->assertEquals($str, $data['cols'][0][0]['formatedDescription']);
151 }
117} 152}
diff --git a/tests/utils/ReferenceLinkDB.php b/tests/utils/ReferenceLinkDB.php
index 61faef05..dc4f5dfa 100644
--- a/tests/utils/ReferenceLinkDB.php
+++ b/tests/utils/ReferenceLinkDB.php
@@ -4,6 +4,8 @@
4 */ 4 */
5class ReferenceLinkDB 5class ReferenceLinkDB
6{ 6{
7 public static $NB_LINKS_TOTAL = 7;
8
7 private $_links = array(); 9 private $_links = array();
8 private $_publicCount = 0; 10 private $_publicCount = 0;
9 private $_privateCount = 0; 11 private $_privateCount = 0;
@@ -14,6 +16,15 @@ class ReferenceLinkDB
14 function __construct() 16 function __construct()
15 { 17 {
16 $this->addLink( 18 $this->addLink(
19 'Link title: @website',
20 '?WDWyig',
21 'Stallman has a beard and is part of the Free Software Foundation (or not). Seriously, read this.',
22 0,
23 '20150310_114651',
24 'stuff'
25 );
26
27 $this->addLink(
17 'Free as in Freedom 2.0 @website', 28 'Free as in Freedom 2.0 @website',
18 'https://static.fsf.org/nosvn/faif-2.0.pdf', 29 'https://static.fsf.org/nosvn/faif-2.0.pdf',
19 'Richard Stallman and the Free Software Revolution. Read this.', 30 'Richard Stallman and the Free Software Revolution. Read this.',
@@ -23,15 +34,6 @@ class ReferenceLinkDB
23 ); 34 );
24 35
25 $this->addLink( 36 $this->addLink(
26 'Link title: @website',
27 'local',
28 'Stallman has a beard and is part of the Free Software Foundation (or not). Seriously, read this.',
29 0,
30 '20150310_114651',
31 'stuff'
32 );
33
34 $this->addLink(
35 'MediaGoblin', 37 'MediaGoblin',
36 'http://mediagoblin.org/', 38 'http://mediagoblin.org/',
37 'A free software media publishing platform', 39 'A free software media publishing platform',
diff --git a/tpl/configure.html b/tpl/configure.html
index 9c725a51..77c8b7d9 100644
--- a/tpl/configure.html
+++ b/tpl/configure.html
@@ -22,9 +22,12 @@
22 <input type="checkbox" name="privateLinkByDefault" id="privateLinkByDefault" {if="!empty($GLOBALS['privateLinkByDefault'])"}checked{/if}/><label for="privateLinkByDefault">&nbsp;All new links are private by default</label></td> 22 <input type="checkbox" name="privateLinkByDefault" id="privateLinkByDefault" {if="!empty($GLOBALS['privateLinkByDefault'])"}checked{/if}/><label for="privateLinkByDefault">&nbsp;All new links are private by default</label></td>
23 </tr> 23 </tr>
24 <tr> 24 <tr>
25 <td valign="top"><b>Enable RSS Permalinks</b></td> 25 <td valign="top"><b>RSS direct links</b></td>
26 <td> 26 <td>
27 <input type="checkbox" name="enableRssPermalinks" id="enableRssPermalinks" {if="!empty($GLOBALS['config']['ENABLE_RSS_PERMALINKS'])"}checked{/if}/><label for="enableRssPermalinks">&nbsp;Switches the RSS feed URLs between full URLs and shortlinks. Enabling it will show a permalink in the description, and the feed item will be linked to the absolute URL. Disabling it swaps this behaviour around (permalink in title and link in description). RSS Permalinks are currently <b>{if="$GLOBALS['config']['ENABLE_RSS_PERMALINKS']"}enabled{else}disabled{/if}</b></label> 27 <input type="checkbox" name="enableRssPermalinks" id="enableRssPermalinks" {if="!empty($GLOBALS['config']['ENABLE_RSS_PERMALINKS'])"}checked{/if}/>
28 <label for="enableRssPermalinks">
29 &nbsp;Disable it to use permalinks in RSS feed instead of direct links to your shaared links. Currently <b>{if="$GLOBALS['config']['ENABLE_RSS_PERMALINKS']"}enabled{else}disabled{/if}.</b>
30 </label>
28 </td> 31 </td>
29 </tr> 32 </tr>
30 <tr> 33 <tr>
diff --git a/tpl/export.bookmarks.html b/tpl/export.bookmarks.html
new file mode 100644
index 00000000..da733257
--- /dev/null
+++ b/tpl/export.bookmarks.html
@@ -0,0 +1,10 @@
1<!DOCTYPE NETSCAPE-Bookmark-file-1>
2<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
3<!-- This is an automatically generated file.
4 It will be read and overwritten.
5 Do Not Edit! -->{ignore}The RainTPL loop is formatted to avoid generating extra newlines{/ignore}
6<TITLE>{$pagetitle}</TITLE>
7<H1>Shaarli export of {$selection} bookmarks on {$date}</H1>
8<DL><p>{loop="links"}
9<DT><A HREF="{$value.url}" ADD_DATE="{$value.timestamp}" PRIVATE="{$value.private}" TAGS="{$value.taglist}">{$value.title}</A>{if="$value.description"}{$eol}<DD>{$value.description}{/if}{/loop}
10</DL><p>
diff --git a/tpl/export.html b/tpl/export.html
index 9d101db4..67c3d05f 100644
--- a/tpl/export.html
+++ b/tpl/export.html
@@ -2,15 +2,27 @@
2<html> 2<html>
3<head>{include="includes"}</head> 3<head>{include="includes"}</head>
4<body> 4<body>
5<div id="pageheader"> 5 <div id="pageheader">
6 {include="page.header"} 6 {include="page.header"}
7 <div id="toolsdiv"> 7 <div id="toolsdiv">
8 <a href="?do=export&amp;what=all"><b>Export all</b> <span>: Export all links</span></a><br><br> 8 <form method="GET">
9 <a href="?do=export&amp;what=public"><b>Export public</b> <span>: Export public links only</span></a><br><br> 9 <input type="hidden" name="do" value="export">
10 <a href="?do=export&amp;what=private"><b>Export private</b> <span>: Export private links only</span></a> 10 Selection:<br>
11 <div class="clear"></div> 11 <input type="radio" name="selection" value="all" checked="true"> All<br>
12 </div> 12 <input type="radio" name="selection" value="private"> Private<br>
13</div> 13 <input type="radio" name="selection" value="public"> Public<br>
14{include="page.footer"} 14 <br>
15 <input type="checkbox" name="prepend_note_url" id="prepend_note_url">
16 <label for="prepend_note_url">
17 Prepend note permalinks with this Shaarli instance's URL
18 <em>(useful to import bookmarks in a web browser)</em>
19 </label>
20 <br><br>
21 <input class="bigbutton" type="submit" value="Export">
22 </form>
23 <div class="clear"></div>
24 </div>
25 </div>
26 {include="page.footer"}
15</body> 27</body>
16</html> 28</html>
diff --git a/tpl/feed.atom.html b/tpl/feed.atom.html
new file mode 100644
index 00000000..2ebb162a
--- /dev/null
+++ b/tpl/feed.atom.html
@@ -0,0 +1,40 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<feed xmlns="http://www.w3.org/2005/Atom">
3 <title>{$pagetitle}</title>
4 <subtitle>Shaared links</subtitle>
5 {if="$show_dates"}
6 <updated>{$last_update}</updated>
7 {/if}
8 <link rel="self" href="{$self_link}#" />
9 {if="!empty($pubsubhub_url)"}
10 <!-- PubSubHubbub Discovery -->
11 <link rel="hub" href="{$pubsubhub_url}#" />
12 <!-- End Of PubSubHubbub Discovery -->
13 {/if}
14 <author>
15 <name>{$index_url}</name>
16 <uri>{$index_url}</uri>
17 </author>
18 <id>{$index_url}</id>
19 <generator>Shaarli</generator>
20 {loop="links"}
21 <entry>
22 <title>{$value.title}</title>
23 {if="$usepermalinks"}
24 <link href="{$value.guid}#" />
25 {else}
26 <link href="{$value.url}#" />
27 {/if}
28 <id>{$value.guid}</id>
29 {if="$show_dates"}
30 <updated>{$value.iso_date}</updated>
31 {/if}
32 <content type="html" xml:lang="{$language}">
33 <![CDATA[{$value.description}]]>
34 </content>
35 {loop="$value.taglist"}
36 <category scheme="{$index_url}?searchtags=" term="{$value|strtolower}" label="{$value}" />
37 {/loop}
38 </entry>
39 {/loop}
40</feed>
diff --git a/tpl/feed.rss.html b/tpl/feed.rss.html
new file mode 100644
index 00000000..26de7f19
--- /dev/null
+++ b/tpl/feed.rss.html
@@ -0,0 +1,34 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
3 <channel>
4 <title>{$pagetitle}</title>
5 <link>{$index_url}</link>
6 <description>Shaared links</description>
7 <language>{$language}</language>
8 <copyright>{$index_url}</copyright>
9 <generator>Shaarli</generator>
10 <atom:link rel="self" href="{$self_link}" />
11 {if="!empty($pubsubhub_url)"}
12 <!-- PubSubHubbub Discovery -->
13 <atom:link rel="hub" href="{$pubsubhub_url}" />
14 {/if}
15 {loop="links"}
16 <item>
17 <title>{$value.title}</title>
18 <guid isPermaLink="{if="$usepermalinks"}true{else}false{/if}">{$value.guid}</guid>
19 {if="$usepermalinks"}
20 <link>{$value.guid}</link>
21 {else}
22 <link>{$value.url}</link>
23 {/if}
24 {if="$show_dates"}
25 <pubDate>{$value.iso_date}</pubDate>
26 {/if}
27 <description><![CDATA[{$value.description}]]></description>
28 {loop="$value.taglist"}
29 <category domain="{$index_url}?searchtags=">{$value}</category>
30 {/loop}
31 </item>
32 {/loop}
33 </channel>
34</rss>
diff --git a/tpl/loginform.html b/tpl/loginform.html
index 678375fd..a49b42d3 100644
--- a/tpl/loginform.html
+++ b/tpl/loginform.html
@@ -1,26 +1,36 @@
1<!DOCTYPE html> 1<!DOCTYPE html>
2<html> 2<html>
3<head>{include="includes"}</head> 3<head>{include="includes"}</head>
4<body{if="ban_canLogin()"} onload="document.loginform.login.focus();"{/if}> 4<body
5{if="ban_canLogin()"}
6 {if="empty($username)"}
7 onload="document.loginform.login.focus();"
8 {else}
9 onload="document.loginform.password.focus();"
10 {/if}
11{/if}>
5<div id="pageheader"> 12<div id="pageheader">
6 {include="page.header"} 13 {include="page.header"}
7 14
8 <div id="headerform"> 15 <div id="headerform">
9{if="!ban_canLogin()"} 16 {if="!ban_canLogin()"}
10 You have been banned from login after too many failed attempts. Try later. 17 You have been banned from login after too many failed attempts. Try later.
11{else} 18 {else}
12 <form method="post" name="loginform"> 19 <form method="post" name="loginform">
13 <label for="login">Login: <input type="text" id="login" name="login" tabindex="1"></label> 20 <label for="login">Login: <input type="text" id="login" name="login" tabindex="1"
14 <label for="password">Password: <input type="password" id="password" name="password" tabindex="2"></label> 21 {if="!empty($username)"}value="{$username}"{/if}>
15 <input type="submit" value="Login" class="bigbutton" tabindex="4"> 22 </label>
16 <label for="longlastingsession"> 23 <label for="password">Password: <input type="password" id="password" name="password" tabindex="2">
17 <input type="checkbox" name="longlastingsession" id="longlastingsession" tabindex="3"> 24 </label>
18 Stay signed in (Do not check on public computers)</label> 25 <input type="submit" value="Login" class="bigbutton" tabindex="4">
19 <input type="hidden" name="token" value="{$token}"> 26 <label for="longlastingsession">
20 {if="$returnurl"}<input type="hidden" name="returnurl" value="{$returnurl}">{/if} 27 <input type="checkbox" name="longlastingsession" id="longlastingsession" tabindex="3">
21 </form> 28 Stay signed in (Do not check on public computers)</label>
22{/if} 29 <input type="hidden" name="token" value="{$token}">
23 </div> 30 {if="$returnurl"}<input type="hidden" name="returnurl" value="{$returnurl}">{/if}
31 </form>
32 {/if}
33 </div>
24</div> 34</div>
25 35
26{include="page.footer"} 36{include="page.footer"}
diff --git a/tpl/page.footer.html b/tpl/page.footer.html
index 195dada0..006d1d68 100644
--- a/tpl/page.footer.html
+++ b/tpl/page.footer.html
@@ -1,5 +1,7 @@
1<div id="footer"> 1<div id="footer">
2 <b><a href="https://github.com/shaarli/Shaarli">Shaarli</a></b> - The personal, minimalist, super-fast, no-database delicious clone by the <a href="https://github.com/shaarli/Shaarli">Shaarli</a> community - <a href="doc/Home.html">Help/documentation</a> 2 <strong><a href="https://github.com/shaarli/Shaarli">Shaarli</a></strong>
3 - The personal, minimalist, super-fast, database free, bookmarking service by the Shaarli community
4 - <a href="doc/Home.html" rel="nofollow">Help/documentation</a>
3 {loop="$plugins_footer.text"} 5 {loop="$plugins_footer.text"}
4 {$value} 6 {$value}
5 {/loop} 7 {/loop}
diff --git a/tpl/page.header.html b/tpl/page.header.html
index 52429f23..3a09ecd9 100644
--- a/tpl/page.header.html
+++ b/tpl/page.header.html
@@ -2,7 +2,8 @@
2<div id="logo" title="Share your links !" onclick="document.location='?';"></div> 2<div id="logo" title="Share your links !" onclick="document.location='?';"></div>
3 3
4<div id="linkcount" class="nomobile"> 4<div id="linkcount" class="nomobile">
5 {if="!empty($linkcount)"}{$linkcount} links{/if} 5 {if="!empty($linkcount)"}{$linkcount} links{/if}<br>
6 {if="!empty($privateLinkcount)"}{$privateLinkcount} private links{/if}
6</div> 7</div>
7 8
8<div id="menu"> 9<div id="menu">
diff --git a/tpl/tagcloud.html b/tpl/tagcloud.html
index 5891cd25..e449f293 100644
--- a/tpl/tagcloud.html
+++ b/tpl/tagcloud.html
@@ -12,8 +12,8 @@
12 12
13 <div id="cloudtag"> 13 <div id="cloudtag">
14 {loop="tags"} 14 {loop="tags"}
15 <span class="count">{$value.count}</span> 15 <span class="count">{$value.count}</span><a
16 <a href="?searchtags={$key|urlencode}" style="font-size:{$value.size}pt;">{$key}</a> 16 href="?searchtags={$key|urlencode}" style="font-size:{$value.size}em;">{$key}</a>
17 {loop="$value.tag_plugin"} 17 {loop="$value.tag_plugin"}
18 {$value} 18 {$value}
19 {/loop} 19 {/loop}