diff options
51 files changed, 2252 insertions, 246 deletions
@@ -135,7 +135,7 @@ test: | |||
135 | @echo "PHPUNIT" | 135 | @echo "PHPUNIT" |
136 | @echo "-------" | 136 | @echo "-------" |
137 | @mkdir -p sandbox coverage | 137 | @mkdir -p sandbox coverage |
138 | @$(BIN)/phpunit --coverage-php coverage/main.cov --testsuite unit-tests | 138 | @$(BIN)/phpunit --coverage-php coverage/main.cov --bootstrap tests/bootstrap.php --testsuite unit-tests |
139 | 139 | ||
140 | locale_test_%: | 140 | locale_test_%: |
141 | @UT_LOCALE=$*.utf8 \ | 141 | @UT_LOCALE=$*.utf8 \ |
diff --git a/application/ApplicationUtils.php b/application/ApplicationUtils.php index 5643f4a0..911873a0 100644 --- a/application/ApplicationUtils.php +++ b/application/ApplicationUtils.php | |||
@@ -149,12 +149,13 @@ class ApplicationUtils | |||
149 | public static function checkPHPVersion($minVersion, $curVersion) | 149 | public static function checkPHPVersion($minVersion, $curVersion) |
150 | { | 150 | { |
151 | if (version_compare($curVersion, $minVersion) < 0) { | 151 | if (version_compare($curVersion, $minVersion) < 0) { |
152 | throw new Exception( | 152 | $msg = t( |
153 | 'Your PHP version is obsolete!' | 153 | 'Your PHP version is obsolete!' |
154 | .' Shaarli requires at least PHP '.$minVersion.', and thus cannot run.' | 154 | . ' Shaarli requires at least PHP %s, and thus cannot run.' |
155 | .' Your PHP version has known security vulnerabilities and should be' | 155 | . ' Your PHP version has known security vulnerabilities and should be' |
156 | .' updated as soon as possible.' | 156 | . ' updated as soon as possible.' |
157 | ); | 157 | ); |
158 | throw new Exception(sprintf($msg, $minVersion)); | ||
158 | } | 159 | } |
159 | } | 160 | } |
160 | 161 | ||
@@ -179,7 +180,7 @@ class ApplicationUtils | |||
179 | $rainTplDir.'/'.$conf->get('resource.theme'), | 180 | $rainTplDir.'/'.$conf->get('resource.theme'), |
180 | ) as $path) { | 181 | ) as $path) { |
181 | if (! is_readable(realpath($path))) { | 182 | if (! is_readable(realpath($path))) { |
182 | $errors[] = '"'.$path.'" directory is not readable'; | 183 | $errors[] = '"'.$path.'" '. t('directory is not readable'); |
183 | } | 184 | } |
184 | } | 185 | } |
185 | 186 | ||
@@ -191,10 +192,10 @@ class ApplicationUtils | |||
191 | $conf->get('resource.raintpl_tmp'), | 192 | $conf->get('resource.raintpl_tmp'), |
192 | ) as $path) { | 193 | ) as $path) { |
193 | if (! is_readable(realpath($path))) { | 194 | if (! is_readable(realpath($path))) { |
194 | $errors[] = '"'.$path.'" directory is not readable'; | 195 | $errors[] = '"'.$path.'" '. t('directory is not readable'); |
195 | } | 196 | } |
196 | if (! is_writable(realpath($path))) { | 197 | if (! is_writable(realpath($path))) { |
197 | $errors[] = '"'.$path.'" directory is not writable'; | 198 | $errors[] = '"'.$path.'" '. t('directory is not writable'); |
198 | } | 199 | } |
199 | } | 200 | } |
200 | 201 | ||
@@ -212,10 +213,10 @@ class ApplicationUtils | |||
212 | } | 213 | } |
213 | 214 | ||
214 | if (! is_readable(realpath($path))) { | 215 | if (! is_readable(realpath($path))) { |
215 | $errors[] = '"'.$path.'" file is not readable'; | 216 | $errors[] = '"'.$path.'" '. t('file is not readable'); |
216 | } | 217 | } |
217 | if (! is_writable(realpath($path))) { | 218 | if (! is_writable(realpath($path))) { |
218 | $errors[] = '"'.$path.'" file is not writable'; | 219 | $errors[] = '"'.$path.'" '. t('file is not writable'); |
219 | } | 220 | } |
220 | } | 221 | } |
221 | 222 | ||
diff --git a/application/Cache.php b/application/Cache.php index 5d050165..e5d43e61 100644 --- a/application/Cache.php +++ b/application/Cache.php | |||
@@ -13,7 +13,7 @@ | |||
13 | function purgeCachedPages($pageCacheDir) | 13 | function purgeCachedPages($pageCacheDir) |
14 | { | 14 | { |
15 | if (! is_dir($pageCacheDir)) { | 15 | if (! is_dir($pageCacheDir)) { |
16 | $error = 'Cannot purge '.$pageCacheDir.': no directory'; | 16 | $error = sprintf(t('Cannot purge %s: no directory'), $pageCacheDir); |
17 | error_log($error); | 17 | error_log($error); |
18 | return $error; | 18 | return $error; |
19 | } | 19 | } |
diff --git a/application/FeedBuilder.php b/application/FeedBuilder.php index 7377bcec..3cfaafb4 100644 --- a/application/FeedBuilder.php +++ b/application/FeedBuilder.php | |||
@@ -148,9 +148,9 @@ class FeedBuilder | |||
148 | $link['url'] = $pageaddr . $link['url']; | 148 | $link['url'] = $pageaddr . $link['url']; |
149 | } | 149 | } |
150 | if ($this->usePermalinks === true) { | 150 | if ($this->usePermalinks === true) { |
151 | $permalink = '<a href="'. $link['url'] .'" title="Direct link">Direct link</a>'; | 151 | $permalink = '<a href="'. $link['url'] .'" title="'. t('Direct link') .'">'. t('Direct link') .'</a>'; |
152 | } else { | 152 | } else { |
153 | $permalink = '<a href="'. $link['guid'] .'" title="Permalink">Permalink</a>'; | 153 | $permalink = '<a href="'. $link['guid'] .'" title="'. t('Permalink') .'">'. t('Permalink') .'</a>'; |
154 | } | 154 | } |
155 | $link['description'] = format_description($link['description'], '', $pageaddr); | 155 | $link['description'] = format_description($link['description'], '', $pageaddr); |
156 | $link['description'] .= PHP_EOL .'<br>— '. $permalink; | 156 | $link['description'] .= PHP_EOL .'<br>— '. $permalink; |
diff --git a/application/History.php b/application/History.php index 5e3b1b72..35ec016a 100644 --- a/application/History.php +++ b/application/History.php | |||
@@ -171,7 +171,7 @@ class History | |||
171 | } | 171 | } |
172 | 172 | ||
173 | if (! is_writable($this->historyFilePath)) { | 173 | if (! is_writable($this->historyFilePath)) { |
174 | throw new Exception('History file isn\'t readable or writable'); | 174 | throw new Exception(t('History file isn\'t readable or writable')); |
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
@@ -182,7 +182,7 @@ class History | |||
182 | { | 182 | { |
183 | $this->history = FileUtils::readFlatDB($this->historyFilePath, []); | 183 | $this->history = FileUtils::readFlatDB($this->historyFilePath, []); |
184 | if ($this->history === false) { | 184 | if ($this->history === false) { |
185 | throw new Exception('Could not parse history file'); | 185 | throw new Exception(t('Could not parse history file')); |
186 | } | 186 | } |
187 | } | 187 | } |
188 | 188 | ||
diff --git a/application/Languages.php b/application/Languages.php index c8b0a25a..4ba32f29 100644 --- a/application/Languages.php +++ b/application/Languages.php | |||
@@ -1,21 +1,150 @@ | |||
1 | <?php | 1 | <?php |
2 | 2 | ||
3 | namespace Shaarli; | ||
4 | |||
5 | use Gettext\GettextTranslator; | ||
6 | use Gettext\Merge; | ||
7 | use Gettext\Translations; | ||
8 | use Gettext\Translator; | ||
9 | use Gettext\TranslatorInterface; | ||
10 | use Shaarli\Config\ConfigManager; | ||
11 | |||
3 | /** | 12 | /** |
4 | * Wrapper function for translation which match the API | 13 | * Class Languages |
5 | * of gettext()/_() and ngettext(). | 14 | * |
15 | * Load Shaarli translations using 'gettext/gettext'. | ||
16 | * This class allows to either use PHP gettext extension, or a PHP implementation of gettext, | ||
17 | * with a fixed language, or dynamically using autoLocale(). | ||
6 | * | 18 | * |
7 | * Not doing translation for now. | 19 | * Translation files PO/MO files follow gettext standard and must be placed under: |
20 | * <translation path>/<language>/LC_MESSAGES/<domain>.[po|mo] | ||
8 | * | 21 | * |
9 | * @param string $text Text to translate. | 22 | * Pros/cons: |
10 | * @param string $nText The plural message ID. | 23 | * - gettext extension is faster |
11 | * @param int $nb The number of items for plural forms. | 24 | * - gettext is very system dependent (PHP extension, the locale must be installed, and web server reloaded) |
12 | * | 25 | * |
13 | * @return String Text translated. | 26 | * Settings: |
27 | * - translation.mode: | ||
28 | * - auto: use default setting (PHP implementation) | ||
29 | * - php: use PHP implementation | ||
30 | * - gettext: use gettext wrapper | ||
31 | * - translation.language: | ||
32 | * - auto: use autoLocale() and the language change according to user HTTP headers | ||
33 | * - fixed language: e.g. 'fr' | ||
34 | * - translation.extensions: | ||
35 | * - domain => translation_path: allow plugins and themes to extend the defaut extension | ||
36 | * The domain must be unique, and translation path must be relative, and contains the tree mentioned above. | ||
37 | * | ||
38 | * @package Shaarli | ||
14 | */ | 39 | */ |
15 | function t($text, $nText = '', $nb = 0) { | 40 | class Languages |
16 | if (empty($nText)) { | 41 | { |
17 | return $text; | 42 | /** |
43 | * Core translations domain | ||
44 | */ | ||
45 | const DEFAULT_DOMAIN = 'shaarli'; | ||
46 | |||
47 | /** | ||
48 | * @var TranslatorInterface | ||
49 | */ | ||
50 | protected $translator; | ||
51 | |||
52 | /** | ||
53 | * @var string | ||
54 | */ | ||
55 | protected $language; | ||
56 | |||
57 | /** | ||
58 | * @var ConfigManager | ||
59 | */ | ||
60 | protected $conf; | ||
61 | |||
62 | /** | ||
63 | * Languages constructor. | ||
64 | * | ||
65 | * @param string $language lang determined by autoLocale(), can be override. | ||
66 | * @param ConfigManager $conf instance. | ||
67 | */ | ||
68 | public function __construct($language, $conf) | ||
69 | { | ||
70 | $this->conf = $conf; | ||
71 | $confLanguage = $this->conf->get('translation.language', 'auto'); | ||
72 | if ($confLanguage === 'auto' || ! $this->isValidLanguage($confLanguage)) { | ||
73 | $this->language = substr($language, 0, 5); | ||
74 | } else { | ||
75 | $this->language = $confLanguage; | ||
76 | } | ||
77 | |||
78 | if (! extension_loaded('gettext') | ||
79 | || in_array($this->conf->get('translation.mode', 'auto'), ['auto', 'php']) | ||
80 | ) { | ||
81 | $this->initPhpTranslator(); | ||
82 | } else { | ||
83 | $this->initGettextTranslator(); | ||
84 | } | ||
85 | |||
86 | // Register default functions (e.g. '__()') to use our Translator | ||
87 | $this->translator->register(); | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * Initialize the translator using php gettext extension (gettext dependency act as a wrapper). | ||
92 | */ | ||
93 | protected function initGettextTranslator () | ||
94 | { | ||
95 | $this->translator = new GettextTranslator(); | ||
96 | $this->translator->setLanguage($this->language); | ||
97 | $this->translator->loadDomain(self::DEFAULT_DOMAIN, 'inc/languages'); | ||
98 | |||
99 | foreach ($this->conf->get('translation.extensions', []) as $domain => $translationPath) { | ||
100 | if ($domain !== self::DEFAULT_DOMAIN) { | ||
101 | $this->translator->loadDomain($domain, $translationPath, false); | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | |||
106 | /** | ||
107 | * Initialize the translator using a PHP implementation of gettext. | ||
108 | * | ||
109 | * Note that if language po file doesn't exist, errors are ignored (e.g. not installed language). | ||
110 | */ | ||
111 | protected function initPhpTranslator() | ||
112 | { | ||
113 | $this->translator = new Translator(); | ||
114 | $translations = new Translations(); | ||
115 | // Core translations | ||
116 | try { | ||
117 | /** @var Translations $translations */ | ||
118 | $translations = $translations->addFromPoFile('inc/languages/'. $this->language .'/LC_MESSAGES/shaarli.po'); | ||
119 | $translations->setDomain('shaarli'); | ||
120 | $this->translator->loadTranslations($translations); | ||
121 | } catch (\InvalidArgumentException $e) {} | ||
122 | |||
123 | |||
124 | // Extension translations (plugins, themes, etc.). | ||
125 | foreach ($this->conf->get('translation.extensions', []) as $domain => $translationPath) { | ||
126 | if ($domain === self::DEFAULT_DOMAIN) { | ||
127 | continue; | ||
128 | } | ||
129 | |||
130 | try { | ||
131 | /** @var Translations $extension */ | ||
132 | $extension = Translations::fromPoFile($translationPath . $this->language .'/LC_MESSAGES/'. $domain .'.po'); | ||
133 | $extension->setDomain($domain); | ||
134 | $this->translator->loadTranslations($extension); | ||
135 | } catch (\InvalidArgumentException $e) {} | ||
136 | } | ||
137 | } | ||
138 | |||
139 | /** | ||
140 | * Checks if a language string is valid. | ||
141 | * | ||
142 | * @param string $language e.g. 'fr' or 'en_US' | ||
143 | * | ||
144 | * @return bool true if valid, false otherwise | ||
145 | */ | ||
146 | protected function isValidLanguage($language) | ||
147 | { | ||
148 | return preg_match('/^[a-z]{2}(_[A-Z]{2})?/', $language) === 1; | ||
18 | } | 149 | } |
19 | $actualForm = $nb > 1 ? $nText : $text; | ||
20 | return sprintf($actualForm, $nb); | ||
21 | } | 150 | } |
diff --git a/application/LinkDB.php b/application/LinkDB.php index 22c1f0ab..f026a041 100644 --- a/application/LinkDB.php +++ b/application/LinkDB.php | |||
@@ -133,16 +133,16 @@ class LinkDB implements Iterator, Countable, ArrayAccess | |||
133 | { | 133 | { |
134 | // TODO: use exceptions instead of "die" | 134 | // TODO: use exceptions instead of "die" |
135 | if (!$this->loggedIn) { | 135 | if (!$this->loggedIn) { |
136 | die('You are not authorized to add a link.'); | 136 | die(t('You are not authorized to add a link.')); |
137 | } | 137 | } |
138 | if (!isset($value['id']) || empty($value['url'])) { | 138 | if (!isset($value['id']) || empty($value['url'])) { |
139 | die('Internal Error: A link should always have an id and URL.'); | 139 | die(t('Internal Error: A link should always have an id and URL.')); |
140 | } | 140 | } |
141 | if (($offset !== null && ! is_int($offset)) || ! is_int($value['id'])) { | 141 | if (($offset !== null && ! is_int($offset)) || ! is_int($value['id'])) { |
142 | die('You must specify an integer as a key.'); | 142 | die(t('You must specify an integer as a key.')); |
143 | } | 143 | } |
144 | if ($offset !== null && $offset !== $value['id']) { | 144 | if ($offset !== null && $offset !== $value['id']) { |
145 | die('Array offset and link ID must be equal.'); | 145 | die(t('Array offset and link ID must be equal.')); |
146 | } | 146 | } |
147 | 147 | ||
148 | // If the link exists, we reuse the real offset, otherwise new entry | 148 | // If the link exists, we reuse the real offset, otherwise new entry |
@@ -248,13 +248,13 @@ class LinkDB implements Iterator, Countable, ArrayAccess | |||
248 | $this->links = array(); | 248 | $this->links = array(); |
249 | $link = array( | 249 | $link = array( |
250 | 'id' => 1, | 250 | 'id' => 1, |
251 | 'title'=>' Shaarli: the personal, minimalist, super-fast, no-database delicious clone', | 251 | 'title'=> t('The personal, minimalist, super-fast, database free, bookmarking service'), |
252 | 'url'=>'https://shaarli.readthedocs.io', | 252 | 'url'=>'https://shaarli.readthedocs.io', |
253 | 'description'=>'Welcome to Shaarli! This is your first public bookmark. To edit or delete me, you must first login. | 253 | 'description'=>t('Welcome to Shaarli! This is your first public bookmark. To edit or delete me, you must first login. |
254 | 254 | ||
255 | To learn how to use Shaarli, consult the link "Help/documentation" at the bottom of this page. | 255 | To learn how to use Shaarli, consult the link "Documentation" at the bottom of this page. |
256 | 256 | ||
257 | You use the community supported version of the original Shaarli project, by Sebastien Sauvage.', | 257 | You use the community supported version of the original Shaarli project, by Sebastien Sauvage.'), |
258 | 'private'=>0, | 258 | 'private'=>0, |
259 | 'created'=> new DateTime(), | 259 | 'created'=> new DateTime(), |
260 | 'tags'=>'opensource software' | 260 | 'tags'=>'opensource software' |
@@ -264,9 +264,9 @@ You use the community supported version of the original Shaarli project, by Seba | |||
264 | 264 | ||
265 | $link = array( | 265 | $link = array( |
266 | 'id' => 0, | 266 | 'id' => 0, |
267 | 'title'=>'My secret stuff... - Pastebin.com', | 267 | 'title'=> t('My secret stuff... - Pastebin.com'), |
268 | 'url'=>'http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8=', | 268 | 'url'=>'http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8=', |
269 | 'description'=>'Shhhh! I\'m a private link only YOU can see. You can delete me too.', | 269 | 'description'=> t('Shhhh! I\'m a private link only YOU can see. You can delete me too.'), |
270 | 'private'=>1, | 270 | 'private'=>1, |
271 | 'created'=> new DateTime('1 minute ago'), | 271 | 'created'=> new DateTime('1 minute ago'), |
272 | 'tags'=>'secretstuff', | 272 | 'tags'=>'secretstuff', |
diff --git a/application/LinkFilter.php b/application/LinkFilter.php index 99ecd1e2..12376e27 100644 --- a/application/LinkFilter.php +++ b/application/LinkFilter.php | |||
@@ -444,5 +444,11 @@ class LinkFilter | |||
444 | 444 | ||
445 | class LinkNotFoundException extends Exception | 445 | class LinkNotFoundException extends Exception |
446 | { | 446 | { |
447 | protected $message = 'The link you are trying to reach does not exist or has been deleted.'; | 447 | /** |
448 | * LinkNotFoundException constructor. | ||
449 | */ | ||
450 | public function __construct() | ||
451 | { | ||
452 | $this->message = t('The link you are trying to reach does not exist or has been deleted.'); | ||
453 | } | ||
448 | } | 454 | } |
diff --git a/application/NetscapeBookmarkUtils.php b/application/NetscapeBookmarkUtils.php index 31796367..31a14537 100644 --- a/application/NetscapeBookmarkUtils.php +++ b/application/NetscapeBookmarkUtils.php | |||
@@ -32,11 +32,11 @@ class NetscapeBookmarkUtils | |||
32 | { | 32 | { |
33 | // see tpl/export.html for possible values | 33 | // see tpl/export.html for possible values |
34 | if (! in_array($selection, array('all', 'public', 'private'))) { | 34 | if (! in_array($selection, array('all', 'public', 'private'))) { |
35 | throw new Exception('Invalid export selection: "'.$selection.'"'); | 35 | throw new Exception(t('Invalid export selection:') .' "'.$selection.'"'); |
36 | } | 36 | } |
37 | 37 | ||
38 | $bookmarkLinks = array(); | 38 | $bookmarkLinks = array(); |
39 | 39 | 7 | |
40 | foreach ($linkDb as $link) { | 40 | foreach ($linkDb as $link) { |
41 | if ($link['private'] != 0 && $selection == 'public') { | 41 | if ($link['private'] != 0 && $selection == 'public') { |
42 | continue; | 42 | continue; |
@@ -79,14 +79,14 @@ class NetscapeBookmarkUtils | |||
79 | $duration=0 | 79 | $duration=0 |
80 | ) | 80 | ) |
81 | { | 81 | { |
82 | $status = 'File '.$filename.' ('.$filesize.' bytes) '; | 82 | $status = sprintf(t('File %s (%d bytes) '), $filename, $filesize); |
83 | if ($importCount == 0 && $overwriteCount == 0 && $skipCount == 0) { | 83 | if ($importCount == 0 && $overwriteCount == 0 && $skipCount == 0) { |
84 | $status .= 'has an unknown file format. Nothing was imported.'; | 84 | $status .= t('has an unknown file format. Nothing was imported.'); |
85 | } else { | 85 | } else { |
86 | $status .= 'was successfully processed in '. $duration .' seconds: '; | 86 | $status .= vsprintf( |
87 | $status .= $importCount.' links imported, '; | 87 | t('was successfully processed in %d seconds: %d links imported, %d links overwritten, %d links skipped.'), |
88 | $status .= $overwriteCount.' links overwritten, '; | 88 | [$duration, $importCount, $overwriteCount, $skipCount] |
89 | $status .= $skipCount.' links skipped.'; | 89 | ); |
90 | } | 90 | } |
91 | return $status; | 91 | return $status; |
92 | } | 92 | } |
diff --git a/application/PageBuilder.php b/application/PageBuilder.php index 291860ad..af290671 100644 --- a/application/PageBuilder.php +++ b/application/PageBuilder.php | |||
@@ -159,9 +159,12 @@ class PageBuilder | |||
159 | * | 159 | * |
160 | * @param string $message A messate to display what is not found | 160 | * @param string $message A messate to display what is not found |
161 | */ | 161 | */ |
162 | public function render404($message = 'The page you are trying to reach does not exist or has been deleted.') | 162 | public function render404($message = '') |
163 | { | 163 | { |
164 | header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); | 164 | if (empty($message)) { |
165 | $message = t('The page you are trying to reach does not exist or has been deleted.'); | ||
166 | } | ||
167 | header($_SERVER['SERVER_PROTOCOL'] .' '. t('404 Not Found')); | ||
165 | $this->tpl->assign('error_message', $message); | 168 | $this->tpl->assign('error_message', $message); |
166 | $this->renderPage('404'); | 169 | $this->renderPage('404'); |
167 | } | 170 | } |
diff --git a/application/PluginManager.php b/application/PluginManager.php index 59ece4fa..cf603845 100644 --- a/application/PluginManager.php +++ b/application/PluginManager.php | |||
@@ -188,6 +188,9 @@ class PluginManager | |||
188 | $metaData[$plugin] = parse_ini_file($metaFile); | 188 | $metaData[$plugin] = parse_ini_file($metaFile); |
189 | $metaData[$plugin]['order'] = array_search($plugin, $this->authorizedPlugins); | 189 | $metaData[$plugin]['order'] = array_search($plugin, $this->authorizedPlugins); |
190 | 190 | ||
191 | if (isset($metaData[$plugin]['description'])) { | ||
192 | $metaData[$plugin]['description'] = t($metaData[$plugin]['description']); | ||
193 | } | ||
191 | // Read parameters and format them into an array. | 194 | // Read parameters and format them into an array. |
192 | if (isset($metaData[$plugin]['parameters'])) { | 195 | if (isset($metaData[$plugin]['parameters'])) { |
193 | $params = explode(';', $metaData[$plugin]['parameters']); | 196 | $params = explode(';', $metaData[$plugin]['parameters']); |
@@ -203,7 +206,7 @@ class PluginManager | |||
203 | $metaData[$plugin]['parameters'][$param]['value'] = ''; | 206 | $metaData[$plugin]['parameters'][$param]['value'] = ''; |
204 | // Optional parameter description in parameter.PARAM_NAME= | 207 | // Optional parameter description in parameter.PARAM_NAME= |
205 | if (isset($metaData[$plugin]['parameter.'. $param])) { | 208 | if (isset($metaData[$plugin]['parameter.'. $param])) { |
206 | $metaData[$plugin]['parameters'][$param]['desc'] = $metaData[$plugin]['parameter.'. $param]; | 209 | $metaData[$plugin]['parameters'][$param]['desc'] = t($metaData[$plugin]['parameter.'. $param]); |
207 | } | 210 | } |
208 | } | 211 | } |
209 | } | 212 | } |
@@ -237,6 +240,6 @@ class PluginFileNotFoundException extends Exception | |||
237 | */ | 240 | */ |
238 | public function __construct($pluginName) | 241 | public function __construct($pluginName) |
239 | { | 242 | { |
240 | $this->message = 'Plugin "'. $pluginName .'" files not found.'; | 243 | $this->message = sprintf(t('Plugin "%s" files not found.'), $pluginName); |
241 | } | 244 | } |
242 | } | 245 | } |
diff --git a/application/Updater.php b/application/Updater.php index 72b2def0..723a7a81 100644 --- a/application/Updater.php +++ b/application/Updater.php | |||
@@ -73,7 +73,7 @@ class Updater | |||
73 | } | 73 | } |
74 | 74 | ||
75 | if ($this->methods === null) { | 75 | if ($this->methods === null) { |
76 | throw new UpdaterException('Couldn\'t retrieve Updater class methods.'); | 76 | throw new UpdaterException(t('Couldn\'t retrieve Updater class methods.')); |
77 | } | 77 | } |
78 | 78 | ||
79 | foreach ($this->methods as $method) { | 79 | foreach ($this->methods as $method) { |
@@ -482,7 +482,7 @@ class UpdaterException extends Exception | |||
482 | } | 482 | } |
483 | 483 | ||
484 | if (! empty($this->method)) { | 484 | if (! empty($this->method)) { |
485 | $out .= 'An error occurred while running the update '. $this->method . PHP_EOL; | 485 | $out .= t('An error occurred while running the update ') . $this->method . PHP_EOL; |
486 | } | 486 | } |
487 | 487 | ||
488 | if (! empty($this->previous)) { | 488 | if (! empty($this->previous)) { |
@@ -522,11 +522,11 @@ function read_updates_file($updatesFilepath) | |||
522 | function write_updates_file($updatesFilepath, $updates) | 522 | function write_updates_file($updatesFilepath, $updates) |
523 | { | 523 | { |
524 | if (empty($updatesFilepath)) { | 524 | if (empty($updatesFilepath)) { |
525 | throw new Exception('Updates file path is not set, can\'t write updates.'); | 525 | throw new Exception(t('Updates file path is not set, can\'t write updates.')); |
526 | } | 526 | } |
527 | 527 | ||
528 | $res = file_put_contents($updatesFilepath, implode(';', $updates)); | 528 | $res = file_put_contents($updatesFilepath, implode(';', $updates)); |
529 | if ($res === false) { | 529 | if ($res === false) { |
530 | throw new Exception('Unable to write updates in '. $updatesFilepath . '.'); | 530 | throw new Exception(t('Unable to write updates in '. $updatesFilepath . '.')); |
531 | } | 531 | } |
532 | } | 532 | } |
diff --git a/application/Utils.php b/application/Utils.php index 4a2f5561..27eaafc5 100644 --- a/application/Utils.php +++ b/application/Utils.php | |||
@@ -452,7 +452,7 @@ function get_max_upload_size($limitPost, $limitUpload, $format = true) | |||
452 | */ | 452 | */ |
453 | function alphabetical_sort(&$data, $reverse = false, $byKeys = false) | 453 | function alphabetical_sort(&$data, $reverse = false, $byKeys = false) |
454 | { | 454 | { |
455 | $callback = function($a, $b) use ($reverse) { | 455 | $callback = function ($a, $b) use ($reverse) { |
456 | // Collator is part of PHP intl. | 456 | // Collator is part of PHP intl. |
457 | if (class_exists('Collator')) { | 457 | if (class_exists('Collator')) { |
458 | $collator = new Collator(setlocale(LC_COLLATE, 0)); | 458 | $collator = new Collator(setlocale(LC_COLLATE, 0)); |
@@ -470,3 +470,18 @@ function alphabetical_sort(&$data, $reverse = false, $byKeys = false) | |||
470 | usort($data, $callback); | 470 | usort($data, $callback); |
471 | } | 471 | } |
472 | } | 472 | } |
473 | |||
474 | /** | ||
475 | * Wrapper function for translation which match the API | ||
476 | * of gettext()/_() and ngettext(). | ||
477 | * | ||
478 | * @param string $text Text to translate. | ||
479 | * @param string $nText The plural message ID. | ||
480 | * @param int $nb The number of items for plural forms. | ||
481 | * @param string $domain The domain where the translation is stored (default: shaarli). | ||
482 | * | ||
483 | * @return String Text translated. | ||
484 | */ | ||
485 | function t($text, $nText = '', $nb = 1, $domain = 'shaarli') { | ||
486 | return dn__($domain, $text, $nText, $nb); | ||
487 | } | ||
diff --git a/application/config/ConfigJson.php b/application/config/ConfigJson.php index 9ef2ef56..8c8d5610 100644 --- a/application/config/ConfigJson.php +++ b/application/config/ConfigJson.php | |||
@@ -22,10 +22,15 @@ class ConfigJson implements ConfigIO | |||
22 | $data = json_decode($data, true); | 22 | $data = json_decode($data, true); |
23 | if ($data === null) { | 23 | if ($data === null) { |
24 | $errorCode = json_last_error(); | 24 | $errorCode = json_last_error(); |
25 | $error = 'An error occurred while parsing JSON configuration file ('. $filepath .'): error code #'; | 25 | $error = sprintf( |
26 | $error .= $errorCode. '<br>➜ <code>' . json_last_error_msg() .'</code>'; | 26 | 'An error occurred while parsing JSON configuration file (%s): error code #%d', |
27 | $filepath, | ||
28 | $errorCode | ||
29 | ); | ||
30 | $error .= '<br>➜ <code>' . json_last_error_msg() .'</code>'; | ||
27 | if ($errorCode === JSON_ERROR_SYNTAX) { | 31 | if ($errorCode === JSON_ERROR_SYNTAX) { |
28 | $error .= '<br>Please check your JSON syntax (without PHP comment tags) using a JSON lint tool such as '; | 32 | $error .= '<br>'; |
33 | $error .= 'Please check your JSON syntax (without PHP comment tags) using a JSON lint tool such as '; | ||
29 | $error .= '<a href="http://jsonlint.com/">jsonlint.com</a>.'; | 34 | $error .= '<a href="http://jsonlint.com/">jsonlint.com</a>.'; |
30 | } | 35 | } |
31 | throw new \Exception($error); | 36 | throw new \Exception($error); |
@@ -44,8 +49,8 @@ class ConfigJson implements ConfigIO | |||
44 | if (!file_put_contents($filepath, $data)) { | 49 | if (!file_put_contents($filepath, $data)) { |
45 | throw new \IOException( | 50 | throw new \IOException( |
46 | $filepath, | 51 | $filepath, |
47 | 'Shaarli could not create the config file. | 52 | t('Shaarli could not create the config file. '. |
48 | Please make sure Shaarli has the right to write in the folder is it installed in.' | 53 | 'Please make sure Shaarli has the right to write in the folder is it installed in.') |
49 | ); | 54 | ); |
50 | } | 55 | } |
51 | } | 56 | } |
diff --git a/application/config/ConfigManager.php b/application/config/ConfigManager.php index 7ff2fe67..9e4c9f63 100644 --- a/application/config/ConfigManager.php +++ b/application/config/ConfigManager.php | |||
@@ -132,7 +132,7 @@ class ConfigManager | |||
132 | public function set($setting, $value, $write = false, $isLoggedIn = false) | 132 | public function set($setting, $value, $write = false, $isLoggedIn = false) |
133 | { | 133 | { |
134 | if (empty($setting) || ! is_string($setting)) { | 134 | if (empty($setting) || ! is_string($setting)) { |
135 | throw new \Exception('Invalid setting key parameter. String expected, got: '. gettype($setting)); | 135 | throw new \Exception(t('Invalid setting key parameter. String expected, got: '). gettype($setting)); |
136 | } | 136 | } |
137 | 137 | ||
138 | // During the ConfigIO transition, map legacy settings to the new ones. | 138 | // During the ConfigIO transition, map legacy settings to the new ones. |
@@ -339,6 +339,10 @@ class ConfigManager | |||
339 | $this->setEmpty('redirector.url', ''); | 339 | $this->setEmpty('redirector.url', ''); |
340 | $this->setEmpty('redirector.encode_url', true); | 340 | $this->setEmpty('redirector.encode_url', true); |
341 | 341 | ||
342 | $this->setEmpty('translation.language', 'auto'); | ||
343 | $this->setEmpty('translation.mode', 'php'); | ||
344 | $this->setEmpty('translation.extensions', []); | ||
345 | |||
342 | $this->setEmpty('plugins', array()); | 346 | $this->setEmpty('plugins', array()); |
343 | } | 347 | } |
344 | 348 | ||
diff --git a/application/config/ConfigPhp.php b/application/config/ConfigPhp.php index 2633824d..2f66e8e0 100644 --- a/application/config/ConfigPhp.php +++ b/application/config/ConfigPhp.php | |||
@@ -118,8 +118,8 @@ class ConfigPhp implements ConfigIO | |||
118 | ) { | 118 | ) { |
119 | throw new \IOException( | 119 | throw new \IOException( |
120 | $filepath, | 120 | $filepath, |
121 | 'Shaarli could not create the config file. | 121 | t('Shaarli could not create the config file. '. |
122 | Please make sure Shaarli has the right to write in the folder is it installed in.' | 122 | 'Please make sure Shaarli has the right to write in the folder is it installed in.') |
123 | ); | 123 | ); |
124 | } | 124 | } |
125 | } | 125 | } |
diff --git a/application/config/exception/MissingFieldConfigException.php b/application/config/exception/MissingFieldConfigException.php index 6346c6a9..9e0a9359 100644 --- a/application/config/exception/MissingFieldConfigException.php +++ b/application/config/exception/MissingFieldConfigException.php | |||
@@ -18,6 +18,6 @@ class MissingFieldConfigException extends \Exception | |||
18 | public function __construct($field) | 18 | public function __construct($field) |
19 | { | 19 | { |
20 | $this->field = $field; | 20 | $this->field = $field; |
21 | $this->message = 'Configuration value is required for '. $this->field; | 21 | $this->message = sprintf(t('Configuration value is required for %s'), $this->field); |
22 | } | 22 | } |
23 | } | 23 | } |
diff --git a/application/config/exception/PluginConfigOrderException.php b/application/config/exception/PluginConfigOrderException.php index f9d68750..f82ec26e 100644 --- a/application/config/exception/PluginConfigOrderException.php +++ b/application/config/exception/PluginConfigOrderException.php | |||
@@ -12,6 +12,6 @@ class PluginConfigOrderException extends \Exception | |||
12 | */ | 12 | */ |
13 | public function __construct() | 13 | public function __construct() |
14 | { | 14 | { |
15 | $this->message = 'An error occurred while trying to save plugins loading order.'; | 15 | $this->message = t('An error occurred while trying to save plugins loading order.'); |
16 | } | 16 | } |
17 | } | 17 | } |
diff --git a/application/config/exception/UnauthorizedConfigException.php b/application/config/exception/UnauthorizedConfigException.php index 79672c1b..72311fae 100644 --- a/application/config/exception/UnauthorizedConfigException.php +++ b/application/config/exception/UnauthorizedConfigException.php | |||
@@ -13,6 +13,6 @@ class UnauthorizedConfigException extends \Exception | |||
13 | */ | 13 | */ |
14 | public function __construct() | 14 | public function __construct() |
15 | { | 15 | { |
16 | $this->message = 'You are not authorized to alter config.'; | 16 | $this->message = t('You are not authorized to alter config.'); |
17 | } | 17 | } |
18 | } | 18 | } |
diff --git a/application/exceptions/IOException.php b/application/exceptions/IOException.php index b563b23d..18e46b77 100644 --- a/application/exceptions/IOException.php +++ b/application/exceptions/IOException.php | |||
@@ -16,7 +16,7 @@ class IOException extends Exception | |||
16 | public function __construct($path, $message = '') | 16 | public function __construct($path, $message = '') |
17 | { | 17 | { |
18 | $this->path = $path; | 18 | $this->path = $path; |
19 | $this->message = empty($message) ? 'Error accessing' : $message; | 19 | $this->message = empty($message) ? t('Error accessing') : $message; |
20 | $this->message .= ' "' . $this->path .'"'; | 20 | $this->message .= ' "' . $this->path .'"'; |
21 | } | 21 | } |
22 | } | 22 | } |
diff --git a/composer.json b/composer.json index afb8aca4..f331d6ca 100644 --- a/composer.json +++ b/composer.json | |||
@@ -19,7 +19,8 @@ | |||
19 | "shaarli/netscape-bookmark-parser": "^2.0", | 19 | "shaarli/netscape-bookmark-parser": "^2.0", |
20 | "erusev/parsedown": "1.6", | 20 | "erusev/parsedown": "1.6", |
21 | "slim/slim": "^3.0", | 21 | "slim/slim": "^3.0", |
22 | "pubsubhubbub/publisher": "dev-master" | 22 | "pubsubhubbub/publisher": "dev-master", |
23 | "gettext/gettext": "^4.4" | ||
23 | }, | 24 | }, |
24 | "require-dev": { | 25 | "require-dev": { |
25 | "phpmd/phpmd" : "@stable", | 26 | "phpmd/phpmd" : "@stable", |
diff --git a/composer.lock b/composer.lock index 435d6a88..ea20025d 100644 --- a/composer.lock +++ b/composer.lock | |||
@@ -4,7 +4,7 @@ | |||
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", | 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", |
5 | "This file is @generated automatically" | 5 | "This file is @generated automatically" |
6 | ], | 6 | ], |
7 | "content-hash": "68beedbfa104c788029b079800cfd6e8", | 7 | "content-hash": "13b7e1e474fe9264b098ba86face0feb", |
8 | "packages": [ | 8 | "packages": [ |
9 | { | 9 | { |
10 | "name": "container-interop/container-interop", | 10 | "name": "container-interop/container-interop", |
@@ -77,6 +77,129 @@ | |||
77 | "time": "2015-10-04T16:44:32+00:00" | 77 | "time": "2015-10-04T16:44:32+00:00" |
78 | }, | 78 | }, |
79 | { | 79 | { |
80 | "name": "gettext/gettext", | ||
81 | "version": "v4.4.3", | ||
82 | "source": { | ||
83 | "type": "git", | ||
84 | "url": "https://github.com/oscarotero/Gettext.git", | ||
85 | "reference": "4f57f004635cc6311a20815ebfdc0757cb337113" | ||
86 | }, | ||
87 | "dist": { | ||
88 | "type": "zip", | ||
89 | "url": "https://api.github.com/repos/oscarotero/Gettext/zipball/4f57f004635cc6311a20815ebfdc0757cb337113", | ||
90 | "reference": "4f57f004635cc6311a20815ebfdc0757cb337113", | ||
91 | "shasum": "" | ||
92 | }, | ||
93 | "require": { | ||
94 | "gettext/languages": "^2.3", | ||
95 | "php": ">=5.4.0" | ||
96 | }, | ||
97 | "require-dev": { | ||
98 | "illuminate/view": "*", | ||
99 | "phpunit/phpunit": "^4.8|^5.7", | ||
100 | "squizlabs/php_codesniffer": "^3.0", | ||
101 | "symfony/yaml": "~2", | ||
102 | "twig/extensions": "*", | ||
103 | "twig/twig": "^1.31|^2.0" | ||
104 | }, | ||
105 | "suggest": { | ||
106 | "illuminate/view": "Is necessary if you want to use the Blade extractor", | ||
107 | "symfony/yaml": "Is necessary if you want to use the Yaml extractor/generator", | ||
108 | "twig/extensions": "Is necessary if you want to use the Twig extractor", | ||
109 | "twig/twig": "Is necessary if you want to use the Twig extractor" | ||
110 | }, | ||
111 | "type": "library", | ||
112 | "autoload": { | ||
113 | "psr-4": { | ||
114 | "Gettext\\": "src" | ||
115 | } | ||
116 | }, | ||
117 | "notification-url": "https://packagist.org/downloads/", | ||
118 | "license": [ | ||
119 | "MIT" | ||
120 | ], | ||
121 | "authors": [ | ||
122 | { | ||
123 | "name": "Oscar Otero", | ||
124 | "email": "oom@oscarotero.com", | ||
125 | "homepage": "http://oscarotero.com", | ||
126 | "role": "Developer" | ||
127 | } | ||
128 | ], | ||
129 | "description": "PHP gettext manager", | ||
130 | "homepage": "https://github.com/oscarotero/Gettext", | ||
131 | "keywords": [ | ||
132 | "JS", | ||
133 | "gettext", | ||
134 | "i18n", | ||
135 | "mo", | ||
136 | "po", | ||
137 | "translation" | ||
138 | ], | ||
139 | "time": "2017-08-09T16:59:46+00:00" | ||
140 | }, | ||
141 | { | ||
142 | "name": "gettext/languages", | ||
143 | "version": "2.3.0", | ||
144 | "source": { | ||
145 | "type": "git", | ||
146 | "url": "https://github.com/mlocati/cldr-to-gettext-plural-rules.git", | ||
147 | "reference": "49c39e51569963cc917a924b489e7025bfb9d8c7" | ||
148 | }, | ||
149 | "dist": { | ||
150 | "type": "zip", | ||
151 | "url": "https://api.github.com/repos/mlocati/cldr-to-gettext-plural-rules/zipball/49c39e51569963cc917a924b489e7025bfb9d8c7", | ||
152 | "reference": "49c39e51569963cc917a924b489e7025bfb9d8c7", | ||
153 | "shasum": "" | ||
154 | }, | ||
155 | "require": { | ||
156 | "php": ">=5.3" | ||
157 | }, | ||
158 | "require-dev": { | ||
159 | "phpunit/phpunit": "^4" | ||
160 | }, | ||
161 | "bin": [ | ||
162 | "bin/export-plural-rules", | ||
163 | "bin/export-plural-rules.php" | ||
164 | ], | ||
165 | "type": "library", | ||
166 | "autoload": { | ||
167 | "psr-4": { | ||
168 | "Gettext\\Languages\\": "src/" | ||
169 | } | ||
170 | }, | ||
171 | "notification-url": "https://packagist.org/downloads/", | ||
172 | "license": [ | ||
173 | "MIT" | ||
174 | ], | ||
175 | "authors": [ | ||
176 | { | ||
177 | "name": "Michele Locati", | ||
178 | "email": "mlocati@gmail.com", | ||
179 | "role": "Developer" | ||
180 | } | ||
181 | ], | ||
182 | "description": "gettext languages with plural rules", | ||
183 | "homepage": "https://github.com/mlocati/cldr-to-gettext-plural-rules", | ||
184 | "keywords": [ | ||
185 | "cldr", | ||
186 | "i18n", | ||
187 | "internationalization", | ||
188 | "l10n", | ||
189 | "language", | ||
190 | "languages", | ||
191 | "localization", | ||
192 | "php", | ||
193 | "plural", | ||
194 | "plural rules", | ||
195 | "plurals", | ||
196 | "translate", | ||
197 | "translations", | ||
198 | "unicode" | ||
199 | ], | ||
200 | "time": "2017-03-23T17:02:28+00:00" | ||
201 | }, | ||
202 | { | ||
80 | "name": "katzgrau/klogger", | 203 | "name": "katzgrau/klogger", |
81 | "version": "1.2.1", | 204 | "version": "1.2.1", |
82 | "source": { | 205 | "source": { |
@@ -686,16 +809,16 @@ | |||
686 | }, | 809 | }, |
687 | { | 810 | { |
688 | "name": "phpdocumentor/reflection-docblock", | 811 | "name": "phpdocumentor/reflection-docblock", |
689 | "version": "3.2.1", | 812 | "version": "3.2.2", |
690 | "source": { | 813 | "source": { |
691 | "type": "git", | 814 | "type": "git", |
692 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", | 815 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", |
693 | "reference": "183824db76118b9dddffc7e522b91fa175f75119" | 816 | "reference": "4aada1f93c72c35e22fb1383b47fee43b8f1d157" |
694 | }, | 817 | }, |
695 | "dist": { | 818 | "dist": { |
696 | "type": "zip", | 819 | "type": "zip", |
697 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/183824db76118b9dddffc7e522b91fa175f75119", | 820 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/4aada1f93c72c35e22fb1383b47fee43b8f1d157", |
698 | "reference": "183824db76118b9dddffc7e522b91fa175f75119", | 821 | "reference": "4aada1f93c72c35e22fb1383b47fee43b8f1d157", |
699 | "shasum": "" | 822 | "shasum": "" |
700 | }, | 823 | }, |
701 | "require": { | 824 | "require": { |
@@ -727,7 +850,7 @@ | |||
727 | } | 850 | } |
728 | ], | 851 | ], |
729 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", | 852 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", |
730 | "time": "2017-08-04T20:55:59+00:00" | 853 | "time": "2017-08-08T06:39:58+00:00" |
731 | }, | 854 | }, |
732 | { | 855 | { |
733 | "name": "phpdocumentor/type-resolver", | 856 | "name": "phpdocumentor/type-resolver", |
@@ -1875,20 +1998,20 @@ | |||
1875 | }, | 1998 | }, |
1876 | { | 1999 | { |
1877 | "name": "symfony/config", | 2000 | "name": "symfony/config", |
1878 | "version": "v3.3.6", | 2001 | "version": "v3.3.8", |
1879 | "source": { | 2002 | "source": { |
1880 | "type": "git", | 2003 | "type": "git", |
1881 | "url": "https://github.com/symfony/config.git", | 2004 | "url": "https://github.com/symfony/config.git", |
1882 | "reference": "54ee12b0dd60f294132cabae6f5da9573d2e5297" | 2005 | "reference": "6ac0cc1f047c1dbc058fc25b7a4d91b068ed4488" |
1883 | }, | 2006 | }, |
1884 | "dist": { | 2007 | "dist": { |
1885 | "type": "zip", | 2008 | "type": "zip", |
1886 | "url": "https://api.github.com/repos/symfony/config/zipball/54ee12b0dd60f294132cabae6f5da9573d2e5297", | 2009 | "url": "https://api.github.com/repos/symfony/config/zipball/6ac0cc1f047c1dbc058fc25b7a4d91b068ed4488", |
1887 | "reference": "54ee12b0dd60f294132cabae6f5da9573d2e5297", | 2010 | "reference": "6ac0cc1f047c1dbc058fc25b7a4d91b068ed4488", |
1888 | "shasum": "" | 2011 | "shasum": "" |
1889 | }, | 2012 | }, |
1890 | "require": { | 2013 | "require": { |
1891 | "php": ">=5.5.9", | 2014 | "php": "^5.5.9|>=7.0.8", |
1892 | "symfony/filesystem": "~2.8|~3.0" | 2015 | "symfony/filesystem": "~2.8|~3.0" |
1893 | }, | 2016 | }, |
1894 | "conflict": { | 2017 | "conflict": { |
@@ -1933,20 +2056,20 @@ | |||
1933 | ], | 2056 | ], |
1934 | "description": "Symfony Config Component", | 2057 | "description": "Symfony Config Component", |
1935 | "homepage": "https://symfony.com", | 2058 | "homepage": "https://symfony.com", |
1936 | "time": "2017-07-19T07:37:29+00:00" | 2059 | "time": "2017-08-03T08:59:45+00:00" |
1937 | }, | 2060 | }, |
1938 | { | 2061 | { |
1939 | "name": "symfony/console", | 2062 | "name": "symfony/console", |
1940 | "version": "v2.8.26", | 2063 | "version": "v2.8.27", |
1941 | "source": { | 2064 | "source": { |
1942 | "type": "git", | 2065 | "type": "git", |
1943 | "url": "https://github.com/symfony/console.git", | 2066 | "url": "https://github.com/symfony/console.git", |
1944 | "reference": "32a3c6b3398de5db8ed381f4ef92970c59c2fcdd" | 2067 | "reference": "c0807a2ca978e64d8945d373a9221a5c35d1a253" |
1945 | }, | 2068 | }, |
1946 | "dist": { | 2069 | "dist": { |
1947 | "type": "zip", | 2070 | "type": "zip", |
1948 | "url": "https://api.github.com/repos/symfony/console/zipball/32a3c6b3398de5db8ed381f4ef92970c59c2fcdd", | 2071 | "url": "https://api.github.com/repos/symfony/console/zipball/c0807a2ca978e64d8945d373a9221a5c35d1a253", |
1949 | "reference": "32a3c6b3398de5db8ed381f4ef92970c59c2fcdd", | 2072 | "reference": "c0807a2ca978e64d8945d373a9221a5c35d1a253", |
1950 | "shasum": "" | 2073 | "shasum": "" |
1951 | }, | 2074 | }, |
1952 | "require": { | 2075 | "require": { |
@@ -1994,7 +2117,7 @@ | |||
1994 | ], | 2117 | ], |
1995 | "description": "Symfony Console Component", | 2118 | "description": "Symfony Console Component", |
1996 | "homepage": "https://symfony.com", | 2119 | "homepage": "https://symfony.com", |
1997 | "time": "2017-07-29T21:26:04+00:00" | 2120 | "time": "2017-08-27T14:29:03+00:00" |
1998 | }, | 2121 | }, |
1999 | { | 2122 | { |
2000 | "name": "symfony/debug", | 2123 | "name": "symfony/debug", |
@@ -2055,20 +2178,20 @@ | |||
2055 | }, | 2178 | }, |
2056 | { | 2179 | { |
2057 | "name": "symfony/dependency-injection", | 2180 | "name": "symfony/dependency-injection", |
2058 | "version": "v3.3.6", | 2181 | "version": "v3.3.8", |
2059 | "source": { | 2182 | "source": { |
2060 | "type": "git", | 2183 | "type": "git", |
2061 | "url": "https://github.com/symfony/dependency-injection.git", | 2184 | "url": "https://github.com/symfony/dependency-injection.git", |
2062 | "reference": "8d70987f991481e809c63681ffe8ce3f3fde68a0" | 2185 | "reference": "2ac658972626c75cbde7b0067c84b988170a6907" |
2063 | }, | 2186 | }, |
2064 | "dist": { | 2187 | "dist": { |
2065 | "type": "zip", | 2188 | "type": "zip", |
2066 | "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/8d70987f991481e809c63681ffe8ce3f3fde68a0", | 2189 | "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2ac658972626c75cbde7b0067c84b988170a6907", |
2067 | "reference": "8d70987f991481e809c63681ffe8ce3f3fde68a0", | 2190 | "reference": "2ac658972626c75cbde7b0067c84b988170a6907", |
2068 | "shasum": "" | 2191 | "shasum": "" |
2069 | }, | 2192 | }, |
2070 | "require": { | 2193 | "require": { |
2071 | "php": ">=5.5.9", | 2194 | "php": "^5.5.9|>=7.0.8", |
2072 | "psr/container": "^1.0" | 2195 | "psr/container": "^1.0" |
2073 | }, | 2196 | }, |
2074 | "conflict": { | 2197 | "conflict": { |
@@ -2121,24 +2244,24 @@ | |||
2121 | ], | 2244 | ], |
2122 | "description": "Symfony DependencyInjection Component", | 2245 | "description": "Symfony DependencyInjection Component", |
2123 | "homepage": "https://symfony.com", | 2246 | "homepage": "https://symfony.com", |
2124 | "time": "2017-07-28T15:27:31+00:00" | 2247 | "time": "2017-08-28T22:20:37+00:00" |
2125 | }, | 2248 | }, |
2126 | { | 2249 | { |
2127 | "name": "symfony/filesystem", | 2250 | "name": "symfony/filesystem", |
2128 | "version": "v3.3.6", | 2251 | "version": "v3.3.8", |
2129 | "source": { | 2252 | "source": { |
2130 | "type": "git", | 2253 | "type": "git", |
2131 | "url": "https://github.com/symfony/filesystem.git", | 2254 | "url": "https://github.com/symfony/filesystem.git", |
2132 | "reference": "427987eb4eed764c3b6e38d52a0f87989e010676" | 2255 | "reference": "b32a0e5f928d0fa3d1dd03c78d020777e50c10cb" |
2133 | }, | 2256 | }, |
2134 | "dist": { | 2257 | "dist": { |
2135 | "type": "zip", | 2258 | "type": "zip", |
2136 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/427987eb4eed764c3b6e38d52a0f87989e010676", | 2259 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/b32a0e5f928d0fa3d1dd03c78d020777e50c10cb", |
2137 | "reference": "427987eb4eed764c3b6e38d52a0f87989e010676", | 2260 | "reference": "b32a0e5f928d0fa3d1dd03c78d020777e50c10cb", |
2138 | "shasum": "" | 2261 | "shasum": "" |
2139 | }, | 2262 | }, |
2140 | "require": { | 2263 | "require": { |
2141 | "php": ">=5.5.9" | 2264 | "php": "^5.5.9|>=7.0.8" |
2142 | }, | 2265 | }, |
2143 | "type": "library", | 2266 | "type": "library", |
2144 | "extra": { | 2267 | "extra": { |
@@ -2170,24 +2293,24 @@ | |||
2170 | ], | 2293 | ], |
2171 | "description": "Symfony Filesystem Component", | 2294 | "description": "Symfony Filesystem Component", |
2172 | "homepage": "https://symfony.com", | 2295 | "homepage": "https://symfony.com", |
2173 | "time": "2017-07-11T07:17:58+00:00" | 2296 | "time": "2017-07-29T21:54:42+00:00" |
2174 | }, | 2297 | }, |
2175 | { | 2298 | { |
2176 | "name": "symfony/finder", | 2299 | "name": "symfony/finder", |
2177 | "version": "v3.3.6", | 2300 | "version": "v3.3.8", |
2178 | "source": { | 2301 | "source": { |
2179 | "type": "git", | 2302 | "type": "git", |
2180 | "url": "https://github.com/symfony/finder.git", | 2303 | "url": "https://github.com/symfony/finder.git", |
2181 | "reference": "baea7f66d30854ad32988c11a09d7ffd485810c4" | 2304 | "reference": "b2260dbc80f3c4198f903215f91a1ac7fe9fe09e" |
2182 | }, | 2305 | }, |
2183 | "dist": { | 2306 | "dist": { |
2184 | "type": "zip", | 2307 | "type": "zip", |
2185 | "url": "https://api.github.com/repos/symfony/finder/zipball/baea7f66d30854ad32988c11a09d7ffd485810c4", | 2308 | "url": "https://api.github.com/repos/symfony/finder/zipball/b2260dbc80f3c4198f903215f91a1ac7fe9fe09e", |
2186 | "reference": "baea7f66d30854ad32988c11a09d7ffd485810c4", | 2309 | "reference": "b2260dbc80f3c4198f903215f91a1ac7fe9fe09e", |
2187 | "shasum": "" | 2310 | "shasum": "" |
2188 | }, | 2311 | }, |
2189 | "require": { | 2312 | "require": { |
2190 | "php": ">=5.5.9" | 2313 | "php": "^5.5.9|>=7.0.8" |
2191 | }, | 2314 | }, |
2192 | "type": "library", | 2315 | "type": "library", |
2193 | "extra": { | 2316 | "extra": { |
@@ -2219,20 +2342,20 @@ | |||
2219 | ], | 2342 | ], |
2220 | "description": "Symfony Finder Component", | 2343 | "description": "Symfony Finder Component", |
2221 | "homepage": "https://symfony.com", | 2344 | "homepage": "https://symfony.com", |
2222 | "time": "2017-06-01T21:01:25+00:00" | 2345 | "time": "2017-07-29T21:54:42+00:00" |
2223 | }, | 2346 | }, |
2224 | { | 2347 | { |
2225 | "name": "symfony/polyfill-mbstring", | 2348 | "name": "symfony/polyfill-mbstring", |
2226 | "version": "v1.4.0", | 2349 | "version": "v1.5.0", |
2227 | "source": { | 2350 | "source": { |
2228 | "type": "git", | 2351 | "type": "git", |
2229 | "url": "https://github.com/symfony/polyfill-mbstring.git", | 2352 | "url": "https://github.com/symfony/polyfill-mbstring.git", |
2230 | "reference": "f29dca382a6485c3cbe6379f0c61230167681937" | 2353 | "reference": "7c8fae0ac1d216eb54349e6a8baa57d515fe8803" |
2231 | }, | 2354 | }, |
2232 | "dist": { | 2355 | "dist": { |
2233 | "type": "zip", | 2356 | "type": "zip", |
2234 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f29dca382a6485c3cbe6379f0c61230167681937", | 2357 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7c8fae0ac1d216eb54349e6a8baa57d515fe8803", |
2235 | "reference": "f29dca382a6485c3cbe6379f0c61230167681937", | 2358 | "reference": "7c8fae0ac1d216eb54349e6a8baa57d515fe8803", |
2236 | "shasum": "" | 2359 | "shasum": "" |
2237 | }, | 2360 | }, |
2238 | "require": { | 2361 | "require": { |
@@ -2244,7 +2367,7 @@ | |||
2244 | "type": "library", | 2367 | "type": "library", |
2245 | "extra": { | 2368 | "extra": { |
2246 | "branch-alias": { | 2369 | "branch-alias": { |
2247 | "dev-master": "1.4-dev" | 2370 | "dev-master": "1.5-dev" |
2248 | } | 2371 | } |
2249 | }, | 2372 | }, |
2250 | "autoload": { | 2373 | "autoload": { |
@@ -2278,24 +2401,24 @@ | |||
2278 | "portable", | 2401 | "portable", |
2279 | "shim" | 2402 | "shim" |
2280 | ], | 2403 | ], |
2281 | "time": "2017-06-09T14:24:12+00:00" | 2404 | "time": "2017-06-14T15:44:48+00:00" |
2282 | }, | 2405 | }, |
2283 | { | 2406 | { |
2284 | "name": "symfony/yaml", | 2407 | "name": "symfony/yaml", |
2285 | "version": "v3.3.6", | 2408 | "version": "v3.3.8", |
2286 | "source": { | 2409 | "source": { |
2287 | "type": "git", | 2410 | "type": "git", |
2288 | "url": "https://github.com/symfony/yaml.git", | 2411 | "url": "https://github.com/symfony/yaml.git", |
2289 | "reference": "ddc23324e6cfe066f3dd34a37ff494fa80b617ed" | 2412 | "reference": "1d8c2a99c80862bdc3af94c1781bf70f86bccac0" |
2290 | }, | 2413 | }, |
2291 | "dist": { | 2414 | "dist": { |
2292 | "type": "zip", | 2415 | "type": "zip", |
2293 | "url": "https://api.github.com/repos/symfony/yaml/zipball/ddc23324e6cfe066f3dd34a37ff494fa80b617ed", | 2416 | "url": "https://api.github.com/repos/symfony/yaml/zipball/1d8c2a99c80862bdc3af94c1781bf70f86bccac0", |
2294 | "reference": "ddc23324e6cfe066f3dd34a37ff494fa80b617ed", | 2417 | "reference": "1d8c2a99c80862bdc3af94c1781bf70f86bccac0", |
2295 | "shasum": "" | 2418 | "shasum": "" |
2296 | }, | 2419 | }, |
2297 | "require": { | 2420 | "require": { |
2298 | "php": ">=5.5.9" | 2421 | "php": "^5.5.9|>=7.0.8" |
2299 | }, | 2422 | }, |
2300 | "require-dev": { | 2423 | "require-dev": { |
2301 | "symfony/console": "~2.8|~3.0" | 2424 | "symfony/console": "~2.8|~3.0" |
@@ -2333,7 +2456,7 @@ | |||
2333 | ], | 2456 | ], |
2334 | "description": "Symfony Yaml Component", | 2457 | "description": "Symfony Yaml Component", |
2335 | "homepage": "https://symfony.com", | 2458 | "homepage": "https://symfony.com", |
2336 | "time": "2017-07-23T12:43:26+00:00" | 2459 | "time": "2017-07-29T21:54:42+00:00" |
2337 | }, | 2460 | }, |
2338 | { | 2461 | { |
2339 | "name": "theseer/fdomdocument", | 2462 | "name": "theseer/fdomdocument", |
diff --git a/inc/languages/fr/LC_MESSAGES/shaarli.mo b/inc/languages/fr/LC_MESSAGES/shaarli.mo new file mode 100644 index 00000000..d6b195da --- /dev/null +++ b/inc/languages/fr/LC_MESSAGES/shaarli.mo | |||
Binary files differ | |||
diff --git a/inc/languages/fr/LC_MESSAGES/shaarli.po b/inc/languages/fr/LC_MESSAGES/shaarli.po new file mode 100644 index 00000000..8763581b --- /dev/null +++ b/inc/languages/fr/LC_MESSAGES/shaarli.po | |||
@@ -0,0 +1,1243 @@ | |||
1 | msgid "" | ||
2 | msgstr "" | ||
3 | "Project-Id-Version: Shaarli\n" | ||
4 | "POT-Creation-Date: 2017-05-20 13:54+0200\n" | ||
5 | "PO-Revision-Date: 2017-05-20 14:11+0200\n" | ||
6 | "Last-Translator: \n" | ||
7 | "Language-Team: Shaarli\n" | ||
8 | "Language: fr_FR\n" | ||
9 | "MIME-Version: 1.0\n" | ||
10 | "Content-Type: text/plain; charset=UTF-8\n" | ||
11 | "Content-Transfer-Encoding: 8bit\n" | ||
12 | "X-Generator: Poedit 2.0.1\n" | ||
13 | "X-Poedit-Basepath: ../../../..\n" | ||
14 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" | ||
15 | "X-Poedit-SourceCharset: UTF-8\n" | ||
16 | "X-Poedit-KeywordsList: t:1,2;t\n" | ||
17 | "X-Poedit-SearchPath-0: .\n" | ||
18 | |||
19 | #: application/ApplicationUtils.php:152 | ||
20 | #, php-format | ||
21 | msgid "" | ||
22 | "Your PHP version is obsolete! Shaarli requires at least PHP %s, and thus " | ||
23 | "cannot run. Your PHP version has known security vulnerabilities and should " | ||
24 | "be updated as soon as possible." | ||
25 | msgstr "" | ||
26 | "Votre version de PHP est obsolète ! Shaarli nécessite au moins PHP %s, et ne " | ||
27 | "peut donc pas fonctionner. Votre version de PHP a des failles de sécurités " | ||
28 | "connues et devrait être mise à jour au plus tôt." | ||
29 | |||
30 | #: application/ApplicationUtils.php:180 application/ApplicationUtils.php:192 | ||
31 | msgid "directory is not readable" | ||
32 | msgstr "le répertoire n'est pas accessible en lecture" | ||
33 | |||
34 | #: application/ApplicationUtils.php:195 | ||
35 | msgid "directory is not writable" | ||
36 | msgstr "le répertoire n'est pas accessible en écriture" | ||
37 | |||
38 | #: application/ApplicationUtils.php:213 | ||
39 | msgid "file is not readable" | ||
40 | msgstr "le fichier n'est pas accessible en lecture" | ||
41 | |||
42 | #: application/ApplicationUtils.php:216 | ||
43 | msgid "file is not writable" | ||
44 | msgstr "le fichier n'est pas accessible en écriture" | ||
45 | |||
46 | #: application/Cache.php:16 | ||
47 | #, php-format | ||
48 | msgid "Cannot purge %s: no directory" | ||
49 | msgstr "Impossible de purger %s: le répertoire n'existe pas" | ||
50 | |||
51 | #: application/FeedBuilder.php:146 | ||
52 | msgid "Direct link" | ||
53 | msgstr "Liens directs" | ||
54 | |||
55 | #: application/FeedBuilder.php:148 | ||
56 | #: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:88 | ||
57 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:242 | ||
58 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:245 | ||
59 | #: tmp/paper.b91ef64efc3688266305ea9b42e5017e.rtpl.php:88 | ||
60 | msgid "Permalink" | ||
61 | msgstr "Permalien" | ||
62 | |||
63 | #: application/History.php:158 | ||
64 | msgid "History file isn't readable or writable" | ||
65 | msgstr "Le fichier d'historique n'est pas accessible en lecture ou en écriture" | ||
66 | |||
67 | #: application/History.php:169 | ||
68 | msgid "Could not parse history file" | ||
69 | msgstr "Format incorrect pour le fichier d'historique" | ||
70 | |||
71 | #: application/LinkDB.php:136 | ||
72 | msgid "You are not authorized to add a link." | ||
73 | msgstr "Vous n'êtes pas autorisé à ajouter un lien." | ||
74 | |||
75 | #: application/LinkDB.php:139 | ||
76 | msgid "Internal Error: A link should always have an id and URL." | ||
77 | msgstr "Erreur interne : un lien devrait toujours avoir un ID et une URL." | ||
78 | |||
79 | #: application/LinkDB.php:142 | ||
80 | msgid "You must specify an integer as a key." | ||
81 | msgstr "Vous devez utiliser un entier comme clé." | ||
82 | |||
83 | #: application/LinkDB.php:145 | ||
84 | msgid "Array offset and link ID must be equal." | ||
85 | msgstr "La clé du tableau et l'ID du lien doivent être égaux." | ||
86 | |||
87 | #: application/LinkDB.php:251 | ||
88 | #: tmp/page.footer.cedf684561d925457130839629000a81.rtpl.php:14 | ||
89 | msgid "" | ||
90 | "The personal, minimalist, super-fast, database free, bookmarking service" | ||
91 | msgstr "" | ||
92 | "Le gestionnaire de marque-page personnel, minimaliste, et sans base de " | ||
93 | "données" | ||
94 | |||
95 | #: application/LinkDB.php:253 | ||
96 | msgid "" | ||
97 | "Welcome to Shaarli! This is your first public bookmark. To edit or delete " | ||
98 | "me, you must first login.\n" | ||
99 | "\n" | ||
100 | "To learn how to use Shaarli, consult the link \"Documentation\" at the " | ||
101 | "bottom of this page.\n" | ||
102 | "\n" | ||
103 | "You use the community supported version of the original Shaarli project, by " | ||
104 | "Sebastien Sauvage." | ||
105 | msgstr "" | ||
106 | "Bienvenue sur Shaarli ! Ceci est votre premier marque-page public. Pour me " | ||
107 | "modifier ou me supprimer, vous devez d'abord vous connecter.\n" | ||
108 | "\n" | ||
109 | "Pour apprendre comment utiliser Shaarli, consultez le lien « Documentation » " | ||
110 | "en bas de page.\n" | ||
111 | "\n" | ||
112 | "Vous utilisez la version supportée par la communauté du projet original " | ||
113 | "Shaarli, de Sébastien Sauvage." | ||
114 | |||
115 | #: application/LinkDB.php:267 | ||
116 | msgid "My secret stuff... - Pastebin.com" | ||
117 | msgstr "Mes trucs secrets... - Pastebin.com" | ||
118 | |||
119 | #: application/LinkDB.php:269 | ||
120 | msgid "Shhhh! I'm a private link only YOU can see. You can delete me too." | ||
121 | msgstr "" | ||
122 | "Pssst ! Je suis un lien privé que VOUS êtes le seul à voir. Vous pouvez me " | ||
123 | "supprimer aussi." | ||
124 | |||
125 | #: application/LinkFilter.php:376 | ||
126 | msgid "The link you are trying to reach does not exist or has been deleted." | ||
127 | msgstr "Le lien que vous essayez de consulter n'existe pas ou a été supprimé." | ||
128 | |||
129 | #: application/NetscapeBookmarkUtils.php:35 | ||
130 | msgid "Invalid export selection:" | ||
131 | msgstr "Sélection d'export invalide :" | ||
132 | |||
133 | #: application/NetscapeBookmarkUtils.php:80 | ||
134 | #, php-format | ||
135 | msgid "File %s (%d bytes) " | ||
136 | msgstr "Le fichier %s (%d octets) " | ||
137 | |||
138 | #: application/NetscapeBookmarkUtils.php:82 | ||
139 | msgid "has an unknown file format. Nothing was imported." | ||
140 | msgstr "a un format inconnu. Rien n'a été importé." | ||
141 | |||
142 | #: application/NetscapeBookmarkUtils.php:85 | ||
143 | #, php-format | ||
144 | msgid "" | ||
145 | "was successfully processed: %d links imported, %d links overwritten, %d " | ||
146 | "links skipped." | ||
147 | msgstr "" | ||
148 | "a été importé avec succès : %d liens importés, %d liens écrasés, %d liens " | ||
149 | "ignorés." | ||
150 | |||
151 | #: application/PageBuilder.php:159 | ||
152 | msgid "The page you are trying to reach does not exist or has been deleted." | ||
153 | msgstr "La page que vous essayez de consulter n'existe pas ou a été supprimée." | ||
154 | |||
155 | #: application/PageBuilder.php:161 | ||
156 | #, fuzzy | ||
157 | #| msgid " 404 Not Found" | ||
158 | msgid "404 Not Found" | ||
159 | msgstr "404 Introuvable" | ||
160 | |||
161 | #: application/PluginManager.php:243 | ||
162 | #, php-format | ||
163 | msgid "Plugin \"%s\" files not found." | ||
164 | msgstr "Les fichiers de l'extension \"%s\" sont introuvables." | ||
165 | |||
166 | #: application/Updater.php:76 | ||
167 | msgid "Couldn't retrieve Updater class methods." | ||
168 | msgstr "Impossible de récupérer les méthodes de la classe Updater." | ||
169 | |||
170 | #: application/Updater.php:500 | ||
171 | msgid "An error occurred while running the update " | ||
172 | msgstr "Une erreur s'est produite lors de l'exécution de la mise à jour " | ||
173 | |||
174 | #: application/Updater.php:540 | ||
175 | msgid "Updates file path is not set, can't write updates." | ||
176 | msgstr "" | ||
177 | "Le chemin vers le fichier de mise à jour n'est pas défini, impossible " | ||
178 | "d'écrire les mises à jour." | ||
179 | |||
180 | #: application/Updater.php:545 | ||
181 | msgid "Unable to write updates in " | ||
182 | msgstr "Impossible d'écrire les mises à jour dans " | ||
183 | |||
184 | #: application/Utils.php:402 tests/UtilsTest.php:398 | ||
185 | msgid "Setting not set" | ||
186 | msgstr "Paramètre non défini" | ||
187 | |||
188 | #: application/Utils.php:409 tests/UtilsTest.php:396 tests/UtilsTest.php:397 | ||
189 | msgid "Unlimited" | ||
190 | msgstr "Illimité" | ||
191 | |||
192 | #: application/Utils.php:412 tests/UtilsTest.php:393 tests/UtilsTest.php:394 | ||
193 | #: tests/UtilsTest.php:408 | ||
194 | msgid "B" | ||
195 | msgstr "o" | ||
196 | |||
197 | #: application/Utils.php:412 tests/UtilsTest.php:387 tests/UtilsTest.php:388 | ||
198 | #: tests/UtilsTest.php:395 | ||
199 | msgid "kiB" | ||
200 | msgstr "ko" | ||
201 | |||
202 | #: application/Utils.php:412 tests/UtilsTest.php:389 tests/UtilsTest.php:390 | ||
203 | #: tests/UtilsTest.php:406 tests/UtilsTest.php:407 | ||
204 | msgid "MiB" | ||
205 | msgstr "Mo" | ||
206 | |||
207 | #: application/Utils.php:412 tests/UtilsTest.php:391 tests/UtilsTest.php:392 | ||
208 | msgid "GiB" | ||
209 | msgstr "Go" | ||
210 | |||
211 | #: application/config/ConfigJson.php:26 | ||
212 | #, php-format | ||
213 | msgid "" | ||
214 | "An error occurred while parsing JSON configuration file (%s): error code #%d" | ||
215 | msgstr "" | ||
216 | "Une erreur s'est produite lors de la lecture du fichier de configuration " | ||
217 | "JSON (%s) : code d'erreur #%d" | ||
218 | |||
219 | #: application/config/ConfigJson.php:33 | ||
220 | msgid "" | ||
221 | "Please check your JSON syntax (without PHP comment tags) using a JSON lint " | ||
222 | "tool such as " | ||
223 | msgstr "" | ||
224 | "Merci de vérifier la syntaxe JSON (sans les balises de commentaires PHP) en " | ||
225 | "utilisant un validateur de JSON tel que " | ||
226 | |||
227 | #: application/config/ConfigJson.php:52 application/config/ConfigPhp.php:121 | ||
228 | msgid "" | ||
229 | "Shaarli could not create the config file. Please make sure Shaarli has the " | ||
230 | "right to write in the folder is it installed in." | ||
231 | msgstr "" | ||
232 | "Shaarli n'a pas pu créer le fichier de configuration. Merci de vérifier que " | ||
233 | "Shaarli a les droits d'écriture dans le dossier dans lequel il est installé." | ||
234 | |||
235 | #: application/config/ConfigManager.php:135 | ||
236 | msgid "Invalid setting key parameter. String expected, got: " | ||
237 | msgstr "Clé de paramétrage invalide. Chaîne de caractères obtenue, attendu :" | ||
238 | |||
239 | #: application/config/exception/MissingFieldConfigException.php:21 | ||
240 | #, php-format | ||
241 | msgid "Configuration value is required for %s" | ||
242 | msgstr "Le paramètre %s est obligatoire" | ||
243 | |||
244 | #: application/config/exception/PluginConfigOrderException.php:15 | ||
245 | msgid "An error occurred while trying to save plugins loading order." | ||
246 | msgstr "" | ||
247 | "Une erreur s'est produite lors de la sauvegarde de l'ordre des extensions." | ||
248 | |||
249 | #: application/config/exception/UnauthorizedConfigException.php:16 | ||
250 | msgid "You are not authorized to alter config." | ||
251 | msgstr "Vous n'êtes pas autorisé à modifier la configuration." | ||
252 | |||
253 | #: application/exceptions/IOException.php:19 | ||
254 | msgid "Error accessing" | ||
255 | msgstr "Une erreur s'est produite en accédant à " | ||
256 | |||
257 | #: index.php:48 | ||
258 | msgid "" | ||
259 | "Error: missing Composer dependencies\n" | ||
260 | "\n" | ||
261 | "If you installed Shaarli through Git or using the development branch,\n" | ||
262 | "please refer to the installation documentation to install PHP dependencies " | ||
263 | "using Composer:\n" | ||
264 | msgstr "" | ||
265 | "Erreur : les dépendances Composer sont manquantes\n" | ||
266 | "\n" | ||
267 | "Si vous avez installé Shaarli avec Git ou depuis la branche de " | ||
268 | "développement\n" | ||
269 | "merci de consulter la documentation d'installation pour installer les " | ||
270 | "dépendances Composer :\n" | ||
271 | "\n" | ||
272 | |||
273 | #: index.php:137 | ||
274 | msgid "Shared links on " | ||
275 | msgstr "Liens partagés sur " | ||
276 | |||
277 | #: index.php:168 | ||
278 | msgid "Insufficient permissions:" | ||
279 | msgstr "Permissions insuffisantes :" | ||
280 | |||
281 | #: index.php:415 | ||
282 | msgid "I said: NO. You are banned for the moment. Go away." | ||
283 | msgstr "NON. Vous êtes banni pour le moment. Revenez plus tard." | ||
284 | |||
285 | #: index.php:479 | ||
286 | msgid "Wrong login/password." | ||
287 | msgstr "Nom d'utilisateur ou mot de passe incorrects." | ||
288 | |||
289 | #: index.php:1072 | ||
290 | msgid "You are not supposed to change a password on an Open Shaarli." | ||
291 | msgstr "" | ||
292 | "Vous n'êtes pas censé modifier le mot de passe d'un Shaarli en mode ouvert." | ||
293 | |||
294 | #: index.php:1077 index.php:1118 index.php:1189 index.php:1243 index.php:1350 | ||
295 | msgid "Wrong token." | ||
296 | msgstr "Jeton invalide." | ||
297 | |||
298 | #: index.php:1082 | ||
299 | msgid "The old password is not correct." | ||
300 | msgstr "L'ancien mot de passe est incorrect." | ||
301 | |||
302 | #: index.php:1102 | ||
303 | msgid "Your password has been changed" | ||
304 | msgstr "Votre mot de passe a été modifié" | ||
305 | |||
306 | #: index.php:1153 | ||
307 | msgid "Configuration was saved." | ||
308 | msgstr "La configuration a été sauvegardé." | ||
309 | |||
310 | #: index.php:1206 | ||
311 | #, php-format | ||
312 | msgid "Tag was removed from %d links." | ||
313 | msgstr "Le tag a été supprimé de %d liens." | ||
314 | |||
315 | #: index.php:1225 | ||
316 | #, php-format | ||
317 | msgid "Tag was renamed in %d links." | ||
318 | msgstr "Le tag a été renommé dans %d liens." | ||
319 | |||
320 | #: index.php:1544 | ||
321 | #, php-format | ||
322 | msgid "" | ||
323 | "The file you are trying to upload is probably bigger than what this " | ||
324 | "webserver can accept (%s). Please upload in smaller chunks." | ||
325 | msgstr "" | ||
326 | "Le fichier que vous essayer d'envoyer est probablement plus lourd que ce que " | ||
327 | "le serveur web peut accepter (%s). Merci de l'envoyer en parties plus " | ||
328 | "légères." | ||
329 | |||
330 | #: index.php:1941 | ||
331 | #, php-format | ||
332 | msgid "" | ||
333 | "<pre>Sessions do not seem to work correctly on your server.<br>Make sure the " | ||
334 | "variable \"session.save_path\" is set correctly in your PHP config, and that " | ||
335 | "you have write access to it.<br>It currently points to %s.<br>On some " | ||
336 | "browsers, accessing your server via a hostname like 'localhost' or any " | ||
337 | "custom hostname without a dot causes cookie storage to fail. We recommend " | ||
338 | "accessing your server via it's IP address or Fully Qualified Domain Name.<br>" | ||
339 | msgstr "" | ||
340 | "<pre>Les sesssions ne semble pas fonctionner sur ce serveur.<br>Assurez vous " | ||
341 | "que la variable « session.save_path » est correctement définie dans votre " | ||
342 | "fichier de configuration PHP, et que vous y avez les droits d'écriture." | ||
343 | "<br>Ce paramètre pointe actuellement sur %s.<br>Sur certains navigateurs, " | ||
344 | "accéder à votre serveur depuis un nom d'hôte comme « localhost » ou autre " | ||
345 | "nom personnalisé sans point '.' entraine l'échec de la sauvegarde des " | ||
346 | "cookies. Nous vous recommandons d'accéder à votre serveur depuis son adresse " | ||
347 | "IP ou un <em>Fully Qualified Domain Name</em>.<br>" | ||
348 | |||
349 | #: index.php:1951 | ||
350 | msgid "Click to try again." | ||
351 | msgstr "Cliquer ici pour réessayer." | ||
352 | |||
353 | #: plugins/addlink_toolbar/addlink_toolbar.php:29 | ||
354 | msgid "URI" | ||
355 | msgstr "URI" | ||
356 | |||
357 | #: plugins/addlink_toolbar/addlink_toolbar.php:33 | ||
358 | #: tmp/addlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19 | ||
359 | msgid "Add link" | ||
360 | msgstr "Shaare" | ||
361 | |||
362 | #: plugins/addlink_toolbar/addlink_toolbar.php:50 | ||
363 | msgid "Adds the addlink input on the linklist page." | ||
364 | msgstr "Ajout le formulaire d'ajout de liens sur la page principale." | ||
365 | |||
366 | #: plugins/archiveorg/archiveorg.php:23 | ||
367 | msgid "View on archive.org" | ||
368 | msgstr "Voir sur archive.org" | ||
369 | |||
370 | #: plugins/archiveorg/archiveorg.php:36 | ||
371 | msgid "For each link, add an Archive.org icon." | ||
372 | msgstr "Pour chaque lien, ajoute une icône pour Archive.org." | ||
373 | |||
374 | #: plugins/demo_plugin/demo_plugin.php:443 | ||
375 | msgid "" | ||
376 | "A demo plugin covering all use cases for template designers and plugin " | ||
377 | "developers." | ||
378 | msgstr "" | ||
379 | "Une extension de démonstration couvrant tous les cas d'utilisation pour les " | ||
380 | "designers et les développeurs." | ||
381 | |||
382 | #: plugins/isso/isso.php:20 | ||
383 | msgid "" | ||
384 | "Isso plugin error: Please define the \"ISSO_SERVER\" setting in the plugin " | ||
385 | "administration page." | ||
386 | msgstr "" | ||
387 | "Erreur de l'extension Isso : Merci de définir le paramètre « ISSO_SERVER » " | ||
388 | "dans la page d'administration des extensions." | ||
389 | |||
390 | #: plugins/isso/isso.php:63 | ||
391 | msgid "Let visitor comment your shaares on permalinks with Isso." | ||
392 | msgstr "" | ||
393 | "Permet aux visiteurs de commenter vos shaares sur les permaliens avec Isso." | ||
394 | |||
395 | #: plugins/isso/isso.php:64 | ||
396 | msgid "Isso server URL (without 'http://')" | ||
397 | msgstr "URL du serveur Isso (sans 'http://')" | ||
398 | |||
399 | #: plugins/markdown/markdown.php:150 | ||
400 | msgid "Description will be rendered with" | ||
401 | msgstr "La description sera générée avec" | ||
402 | |||
403 | #: plugins/markdown/markdown.php:151 | ||
404 | msgid "Markdown syntax documentation" | ||
405 | msgstr "Documentation sur la syntaxe Markdown" | ||
406 | |||
407 | #: plugins/markdown/markdown.php:152 | ||
408 | msgid "Markdown syntax" | ||
409 | msgstr "la syntaxe Markdown" | ||
410 | |||
411 | #: plugins/markdown/markdown.php:311 | ||
412 | msgid "" | ||
413 | "Render shaare description with Markdown syntax.<br><strong>Warning</" | ||
414 | "strong>:\n" | ||
415 | "If your shaared descriptions contained HTML tags before enabling the " | ||
416 | "markdown plugin,\n" | ||
417 | "enabling it might break your page.\n" | ||
418 | "See the <a href=\"https://github.com/shaarli/Shaarli/tree/master/plugins/" | ||
419 | "markdown#html-rendering\">README</a>." | ||
420 | msgstr "" | ||
421 | "Utilise la syntaxe Markdown pour la description des liens." | ||
422 | "<br><strong>Attention</strong> :\n" | ||
423 | "Si vous aviez des descriptions contenant du HTML avant d'activer cette " | ||
424 | "extension,\n" | ||
425 | "l'activer pourrait déformer vos pages.\n" | ||
426 | "Voir le <a href=\"https://github.com/shaarli/Shaarli/tree/master/plugins/" | ||
427 | "markdown#html-rendering\">README</a>." | ||
428 | |||
429 | #: plugins/piwik/piwik.php:21 | ||
430 | msgid "" | ||
431 | "Piwik plugin error: Please define PIWIK_URL and PIWIK_SITEID in the plugin " | ||
432 | "administration page." | ||
433 | msgstr "" | ||
434 | "Erreur de l'extension Piwik : Merci de définir les paramètres PIWIK_URL et " | ||
435 | "PIWIK_SITEID dans la page d'administration des extensions." | ||
436 | |||
437 | #: plugins/piwik/piwik.php:70 | ||
438 | msgid "A plugin that adds Piwik tracking code to Shaarli pages." | ||
439 | msgstr "Ajoute le code de traçage de Piwik sur les pages de Shaarli." | ||
440 | |||
441 | #: plugins/piwik/piwik.php:71 | ||
442 | msgid "Piwik URL" | ||
443 | msgstr "URL de Piwik" | ||
444 | |||
445 | #: plugins/piwik/piwik.php:72 | ||
446 | msgid "Piwik site ID" | ||
447 | msgstr "Site ID de Piwik" | ||
448 | |||
449 | #: plugins/playvideos/playvideos.php:22 | ||
450 | msgid "Video player" | ||
451 | msgstr "Lecteur vidéo" | ||
452 | |||
453 | #: plugins/playvideos/playvideos.php:25 | ||
454 | msgid "Play Videos" | ||
455 | msgstr "Jouer les vidéos" | ||
456 | |||
457 | #: plugins/playvideos/playvideos.php:56 | ||
458 | msgid "Add a button in the toolbar allowing to watch all videos." | ||
459 | msgstr "" | ||
460 | "Ajoute un bouton dans la barre de menu pour regarder toutes les vidéos." | ||
461 | |||
462 | #: plugins/playvideos/youtube_playlist.js:214 | ||
463 | msgid "plugins/playvideos/jquery-1.11.2.min.js" | ||
464 | msgstr "" | ||
465 | |||
466 | #: plugins/pubsubhubbub/pubsubhubbub.php:69 | ||
467 | #, php-format | ||
468 | msgid "Could not publish to PubSubHubbub: %s" | ||
469 | msgstr "Impossible de publier vers PubSubHubbub : %s" | ||
470 | |||
471 | #: plugins/pubsubhubbub/pubsubhubbub.php:95 | ||
472 | #, php-format | ||
473 | msgid "Could not post to %s" | ||
474 | msgstr "Impossible de publier vers %s" | ||
475 | |||
476 | #: plugins/pubsubhubbub/pubsubhubbub.php:99 | ||
477 | #, php-format | ||
478 | msgid "Bad response from the hub %s" | ||
479 | msgstr "Mauvaise réponse du hub %s" | ||
480 | |||
481 | #: plugins/pubsubhubbub/pubsubhubbub.php:110 | ||
482 | msgid "Enable PubSubHubbub feed publishing." | ||
483 | msgstr "Active la publication de flux vers PubSubHubbub" | ||
484 | |||
485 | #: plugins/qrcode/qrcode.php:69 plugins/wallabag/wallabag.php:68 | ||
486 | msgid "For each link, add a QRCode icon." | ||
487 | msgstr "Pour chaque liens, ajouter une icône de QRCode." | ||
488 | |||
489 | #: plugins/wallabag/wallabag.php:21 | ||
490 | msgid "" | ||
491 | "Wallabag plugin error: Please define the \"WALLABAG_URL\" setting in the " | ||
492 | "plugin administration page." | ||
493 | msgstr "" | ||
494 | "Erreur de l'extension Wallabag : Merci de définir le paramètre « " | ||
495 | "WALLABAG_URL » dans la page d'administration des extensions." | ||
496 | |||
497 | #: plugins/wallabag/wallabag.php:47 | ||
498 | msgid "Save to wallabag" | ||
499 | msgstr "Sauvegarder dans Wallabag" | ||
500 | |||
501 | #: plugins/wallabag/wallabag.php:69 | ||
502 | msgid "Wallabag API URL" | ||
503 | msgstr "URL de l'API Wallabag " | ||
504 | |||
505 | #: plugins/wallabag/wallabag.php:70 | ||
506 | msgid "Wallabag API version (1 or 2)" | ||
507 | msgstr "Version de l'API Wallabag (1 ou 2)" | ||
508 | |||
509 | #: tmp/addlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13 | ||
510 | msgid "Shaare a new link" | ||
511 | msgstr "Partager un nouveau lien" | ||
512 | |||
513 | #: tmp/addlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:16 | ||
514 | msgid "URL or leave empty to post a note" | ||
515 | msgstr "URL ou laisser vide pour créer une note" | ||
516 | |||
517 | #: tmp/changepassword.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13 | ||
518 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29 | ||
519 | msgid "Change password" | ||
520 | msgstr "Modification du mot de passe" | ||
521 | |||
522 | #: tmp/changepassword.b91ef64efc3688266305ea9b42e5017e.rtpl.php:16 | ||
523 | msgid "Current password" | ||
524 | msgstr "Mot de passe actuel" | ||
525 | |||
526 | #: tmp/changepassword.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19 | ||
527 | msgid "New password" | ||
528 | msgstr "Nouveau mot de passe\t" | ||
529 | |||
530 | #: tmp/changepassword.b91ef64efc3688266305ea9b42e5017e.rtpl.php:23 | ||
531 | msgid "Change" | ||
532 | msgstr "Changer" | ||
533 | |||
534 | #: tmp/changetag.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13 | ||
535 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:36 | ||
536 | msgid "Manage tags" | ||
537 | msgstr "Gérer les tags" | ||
538 | |||
539 | #: tmp/changetag.b91ef64efc3688266305ea9b42e5017e.rtpl.php:16 | ||
540 | #: tmp/import.b91ef64efc3688266305ea9b42e5017e.rtpl.php:77 | ||
541 | msgid "Tag" | ||
542 | msgstr "Tag" | ||
543 | |||
544 | #: tmp/changetag.b91ef64efc3688266305ea9b42e5017e.rtpl.php:24 | ||
545 | msgid "New name" | ||
546 | msgstr "Nouveau nom" | ||
547 | |||
548 | #: tmp/changetag.b91ef64efc3688266305ea9b42e5017e.rtpl.php:31 | ||
549 | msgid "Case sensitive" | ||
550 | msgstr "Sensible à la casse" | ||
551 | |||
552 | #: tmp/changetag.b91ef64efc3688266305ea9b42e5017e.rtpl.php:34 | ||
553 | msgid "Rename" | ||
554 | msgstr "Renommer" | ||
555 | |||
556 | #: tmp/changetag.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35 | ||
557 | #: tmp/editlink.90100d2eaf5d3705e14b9b4f78ecddc9.rtpl.php:60 | ||
558 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:71 | ||
559 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:288 | ||
560 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:313 | ||
561 | msgid "Delete" | ||
562 | msgstr "Supprimer" | ||
563 | |||
564 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:24 | ||
565 | msgid "Configure" | ||
566 | msgstr "Configurer" | ||
567 | |||
568 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29 | ||
569 | msgid "title" | ||
570 | msgstr "titre" | ||
571 | |||
572 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:43 | ||
573 | msgid "Home link" | ||
574 | msgstr "Lien vers l'accueil" | ||
575 | |||
576 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:44 | ||
577 | msgid "Default value" | ||
578 | msgstr "Valeur par défaut" | ||
579 | |||
580 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:58 | ||
581 | msgid "Theme" | ||
582 | msgstr "Thème" | ||
583 | |||
584 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:87 | ||
585 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:63 | ||
586 | msgid "Timezone" | ||
587 | msgstr "Fuseau horaire" | ||
588 | |||
589 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:88 | ||
590 | msgid "Continent" | ||
591 | msgstr "Continent" | ||
592 | |||
593 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:88 | ||
594 | msgid "City" | ||
595 | msgstr "Ville" | ||
596 | |||
597 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:134 | ||
598 | msgid "Redirector" | ||
599 | msgstr "Redirecteur" | ||
600 | |||
601 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:135 | ||
602 | msgid "e. g." | ||
603 | msgstr "ex :" | ||
604 | |||
605 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:135 | ||
606 | msgid "will mask the HTTP_REFERER" | ||
607 | msgstr "masque le HTTP_REFERER" | ||
608 | |||
609 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:150 | ||
610 | msgid "Disable session cookie hijacking protection" | ||
611 | msgstr "Désactiver la protection contre le détournement de cookies" | ||
612 | |||
613 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:152 | ||
614 | msgid "Check this if you get disconnected or if your IP address changes often" | ||
615 | msgstr "" | ||
616 | "Cocher cette case si vous êtes souvent déconnecté ou si votre adresse IP " | ||
617 | "change souvent" | ||
618 | |||
619 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:169 | ||
620 | msgid "Private links by default" | ||
621 | msgstr "Liens privés par défaut" | ||
622 | |||
623 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:170 | ||
624 | msgid "All new links are private by default" | ||
625 | msgstr "Tous les nouveaux liens sont privés par défaut" | ||
626 | |||
627 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:185 | ||
628 | msgid "RSS direct links" | ||
629 | msgstr "Liens directs dans le flux RSS" | ||
630 | |||
631 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:186 | ||
632 | msgid "Check this to use direct URL instead of permalink in feeds" | ||
633 | msgstr "" | ||
634 | "Cocher cette case pour utiliser des liens directs au lieu des permaliens " | ||
635 | "dans le flux RSS" | ||
636 | |||
637 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:201 | ||
638 | msgid "Hide public links" | ||
639 | msgstr "Cacher les liens publics" | ||
640 | |||
641 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:202 | ||
642 | msgid "Do not show any links if the user is not logged in" | ||
643 | msgstr "N'afficher aucun lien sans être connecté" | ||
644 | |||
645 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:217 | ||
646 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:95 | ||
647 | msgid "Check updates" | ||
648 | msgstr "Vérifier les mises à jour" | ||
649 | |||
650 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:218 | ||
651 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:97 | ||
652 | msgid "Notify me when a new release is ready" | ||
653 | msgstr "Me notifier lorsqu'une nouvelle version est disponible" | ||
654 | |||
655 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:233 | ||
656 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:114 | ||
657 | msgid "Enable REST API" | ||
658 | msgstr "Activer l'API REST" | ||
659 | |||
660 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:234 | ||
661 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:115 | ||
662 | msgid "Allow third party software to use Shaarli such as mobile application" | ||
663 | msgstr "" | ||
664 | "Permets aux applications tierces d'utiliser Shaarli, par exemple les " | ||
665 | "applications mobiles" | ||
666 | |||
667 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:249 | ||
668 | msgid "API secret" | ||
669 | msgstr "Clé d'API secrète" | ||
670 | |||
671 | #: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:260 | ||
672 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:66 | ||
673 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:139 | ||
674 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:192 | ||
675 | msgid "Save" | ||
676 | msgstr "Enregistrer" | ||
677 | |||
678 | #: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:15 | ||
679 | #: tmp/paper.b91ef64efc3688266305ea9b42e5017e.rtpl.php:15 | ||
680 | msgid "The Daily Shaarli" | ||
681 | msgstr "Le Quotidien Shaarli" | ||
682 | |||
683 | #: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:17 | ||
684 | #: tmp/paper.b91ef64efc3688266305ea9b42e5017e.rtpl.php:17 | ||
685 | msgid "1 RSS entry per day" | ||
686 | msgstr "1 entrée RSS par jour" | ||
687 | |||
688 | #: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:37 | ||
689 | #: tmp/paper.b91ef64efc3688266305ea9b42e5017e.rtpl.php:37 | ||
690 | msgid "Previous day" | ||
691 | msgstr "Jour précédent" | ||
692 | |||
693 | #: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:44 | ||
694 | #: tmp/paper.b91ef64efc3688266305ea9b42e5017e.rtpl.php:44 | ||
695 | msgid "All links of one day in a single page." | ||
696 | msgstr "Tous les liens d'un jour sur une page." | ||
697 | |||
698 | #: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:51 | ||
699 | #: tmp/paper.b91ef64efc3688266305ea9b42e5017e.rtpl.php:51 | ||
700 | msgid "Next day" | ||
701 | msgstr "Jour suivant" | ||
702 | |||
703 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:13 | ||
704 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:26 | ||
705 | msgid "Shaare" | ||
706 | msgstr "Shaare" | ||
707 | |||
708 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:21 | ||
709 | msgid "URL" | ||
710 | msgstr "URL" | ||
711 | |||
712 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:27 | ||
713 | msgid "Title" | ||
714 | msgstr "Titre" | ||
715 | |||
716 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:33 | ||
717 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:42 | ||
718 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:75 | ||
719 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:99 | ||
720 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:124 | ||
721 | msgid "Description" | ||
722 | msgstr "Description" | ||
723 | |||
724 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:39 | ||
725 | msgid "Tags" | ||
726 | msgstr "Tags" | ||
727 | |||
728 | #: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:52 | ||
729 | #: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:36 | ||
730 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:177 | ||
731 | msgid "Private" | ||
732 | msgstr "Privé" | ||
733 | |||
734 | #: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:16 | ||
735 | msgid "Export Database" | ||
736 | msgstr "Exporter les données" | ||
737 | |||
738 | #: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:24 | ||
739 | msgid "Selection" | ||
740 | msgstr "Choisir" | ||
741 | |||
742 | #: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:31 | ||
743 | msgid "All" | ||
744 | msgstr "Tous" | ||
745 | |||
746 | #: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:41 | ||
747 | msgid "Public" | ||
748 | msgstr "Publics" | ||
749 | |||
750 | #: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:52 | ||
751 | msgid "Prepend note permalinks with this Shaarli instance's URL" | ||
752 | msgstr "Préfixer les liens de notes avec l'URL de l'instance de Shaarli" | ||
753 | |||
754 | #: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:53 | ||
755 | msgid "Useful to import bookmarks in a web browser" | ||
756 | msgstr "Utile pour importer les marques-pages dans un navigateur" | ||
757 | |||
758 | #: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:65 | ||
759 | msgid "Export" | ||
760 | msgstr "Exporter" | ||
761 | |||
762 | #: tmp/import.b91ef64efc3688266305ea9b42e5017e.rtpl.php:16 | ||
763 | msgid "Import Database" | ||
764 | msgstr "Importer des données" | ||
765 | |||
766 | #: tmp/import.b91ef64efc3688266305ea9b42e5017e.rtpl.php:23 | ||
767 | msgid "Maximum size allowed:" | ||
768 | msgstr "Taille maximum autorisée :" | ||
769 | |||
770 | #: tmp/import.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29 | ||
771 | msgid "Visibility" | ||
772 | msgstr "Visibilité" | ||
773 | |||
774 | #: tmp/import.b91ef64efc3688266305ea9b42e5017e.rtpl.php:36 | ||
775 | msgid "Use values from the imported file, default to public" | ||
776 | msgstr "" | ||
777 | "Utiliser les valeurs présentes dans le fichier d'import, public par défaut" | ||
778 | |||
779 | #: tmp/import.b91ef64efc3688266305ea9b42e5017e.rtpl.php:41 | ||
780 | msgid "Import all bookmarks as private" | ||
781 | msgstr "Importer tous les liens comme privés" | ||
782 | |||
783 | #: tmp/import.b91ef64efc3688266305ea9b42e5017e.rtpl.php:46 | ||
784 | msgid "Import all bookmarks as public" | ||
785 | msgstr "Importer tous les liens comme publics" | ||
786 | |||
787 | #: tmp/import.b91ef64efc3688266305ea9b42e5017e.rtpl.php:57 | ||
788 | msgid "Overwrite existing bookmarks" | ||
789 | msgstr "Remplacer les liens existants" | ||
790 | |||
791 | #: tmp/import.b91ef64efc3688266305ea9b42e5017e.rtpl.php:58 | ||
792 | msgid "Duplicates based on URL" | ||
793 | msgstr "Les doublons s'appuient sur les URL" | ||
794 | |||
795 | #: tmp/import.b91ef64efc3688266305ea9b42e5017e.rtpl.php:72 | ||
796 | msgid "Add default tags" | ||
797 | msgstr "Ajouter des tags par défaut" | ||
798 | |||
799 | #: tmp/import.b91ef64efc3688266305ea9b42e5017e.rtpl.php:83 | ||
800 | msgid "Import" | ||
801 | msgstr "Importer" | ||
802 | |||
803 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:22 | ||
804 | msgid "Install Shaarli" | ||
805 | msgstr "Installation de Shaarli" | ||
806 | |||
807 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:25 | ||
808 | msgid "It looks like it's the first time you run Shaarli. Please configure it." | ||
809 | msgstr "" | ||
810 | "Il semblerait que ça soit la première fois que vous lancez Shaarli. Merci de " | ||
811 | "le configurer." | ||
812 | |||
813 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:33 | ||
814 | #: tmp/loginform.b91ef64efc3688266305ea9b42e5017e.rtpl.php:30 | ||
815 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:149 | ||
816 | msgid "Username" | ||
817 | msgstr "Nom d'utilisateur" | ||
818 | |||
819 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:48 | ||
820 | #: tmp/loginform.b91ef64efc3688266305ea9b42e5017e.rtpl.php:34 | ||
821 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:150 | ||
822 | msgid "Password" | ||
823 | msgstr "Mot de passe" | ||
824 | |||
825 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:80 | ||
826 | msgid "Shaarli title" | ||
827 | msgstr "Titre du Shaarli" | ||
828 | |||
829 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:86 | ||
830 | msgid "My links" | ||
831 | msgstr "Mes liens" | ||
832 | |||
833 | #: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:127 | ||
834 | msgid "Install" | ||
835 | msgstr "Installer" | ||
836 | |||
837 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14 | ||
838 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:87 | ||
839 | msgid "shaare" | ||
840 | msgid_plural "shaares" | ||
841 | msgstr[0] "shaare" | ||
842 | msgstr[1] "shaares" | ||
843 | |||
844 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:18 | ||
845 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:91 | ||
846 | msgid "private link" | ||
847 | msgid_plural "private links" | ||
848 | msgstr[0] "lien privé" | ||
849 | msgstr[1] "liens privés" | ||
850 | |||
851 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:31 | ||
852 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:119 | ||
853 | msgid "Search text" | ||
854 | msgstr "Recherche texte" | ||
855 | |||
856 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:43 | ||
857 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:131 | ||
858 | msgid "Filter by tag" | ||
859 | msgstr "Filtrer par tag" | ||
860 | |||
861 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:118 | ||
862 | msgid "Nothing found." | ||
863 | msgstr "Aucun résultat." | ||
864 | |||
865 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:126 | ||
866 | #, php-format | ||
867 | msgid "%s result" | ||
868 | msgid_plural "%s results" | ||
869 | msgstr[0] "%s résultat" | ||
870 | msgstr[1] "%s résultats" | ||
871 | |||
872 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:130 | ||
873 | msgid "for" | ||
874 | msgstr "pour" | ||
875 | |||
876 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:137 | ||
877 | msgid "tagged" | ||
878 | msgstr "taggé" | ||
879 | |||
880 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:141 | ||
881 | msgid "Remove tag" | ||
882 | msgstr "Retirer le tag" | ||
883 | |||
884 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:150 | ||
885 | msgid "with status" | ||
886 | msgstr "avec le statut" | ||
887 | |||
888 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:181 | ||
889 | msgid "Edit" | ||
890 | msgstr "Modifier" | ||
891 | |||
892 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:182 | ||
893 | msgid "Fold" | ||
894 | msgstr "Replier" | ||
895 | |||
896 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:245 | ||
897 | msgid "Edited: " | ||
898 | msgstr "Modifié :" | ||
899 | |||
900 | #: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:257 | ||
901 | msgid "permalink" | ||
902 | msgstr "permalien" | ||
903 | |||
904 | #: tmp/linklist.paging.cedf684561d925457130839629000a81.rtpl.php:7 | ||
905 | msgid "Filters" | ||
906 | msgstr "Filtres" | ||
907 | |||
908 | #: tmp/linklist.paging.cedf684561d925457130839629000a81.rtpl.php:12 | ||
909 | msgid "Filter private links" | ||
910 | msgstr "Filtrer par liens privés" | ||
911 | |||
912 | #: tmp/linklist.paging.cedf684561d925457130839629000a81.rtpl.php:63 | ||
913 | msgid "Links per page" | ||
914 | msgstr "Liens par page" | ||
915 | |||
916 | #: tmp/loginform.b91ef64efc3688266305ea9b42e5017e.rtpl.php:15 | ||
917 | msgid "" | ||
918 | "You have been banned after too many failed login attempts. Try again later." | ||
919 | msgstr "" | ||
920 | "Vous avez été banni après trop d'échec d'authentification. Merci de " | ||
921 | "réessayer plus tard." | ||
922 | |||
923 | #: tmp/loginform.b91ef64efc3688266305ea9b42e5017e.rtpl.php:28 | ||
924 | #: tmp/loginform.b91ef64efc3688266305ea9b42e5017e.rtpl.php:42 | ||
925 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:71 | ||
926 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:95 | ||
927 | msgid "Login" | ||
928 | msgstr "Connexion" | ||
929 | |||
930 | #: tmp/loginform.b91ef64efc3688266305ea9b42e5017e.rtpl.php:39 | ||
931 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:153 | ||
932 | msgid "Remember me" | ||
933 | msgstr "Rester connecté" | ||
934 | |||
935 | #: tmp/page.footer.cedf684561d925457130839629000a81.rtpl.php:14 | ||
936 | msgid "by the Shaarli community" | ||
937 | msgstr "par la communauté Shaarli" | ||
938 | |||
939 | #: tmp/page.footer.cedf684561d925457130839629000a81.rtpl.php:15 | ||
940 | msgid "Documentation" | ||
941 | msgstr "Documentation" | ||
942 | |||
943 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:31 | ||
944 | msgid "Tools" | ||
945 | msgstr "Outils" | ||
946 | |||
947 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:36 | ||
948 | #: tmp/tag.cloud.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19 | ||
949 | #: tmp/tagcloud.b91ef64efc3688266305ea9b42e5017e.rtpl.php:16 | ||
950 | msgid "Tag cloud" | ||
951 | msgstr "Nuage de tags" | ||
952 | |||
953 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:39 | ||
954 | msgid "Picture wall" | ||
955 | msgstr "Mur d'images" | ||
956 | |||
957 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:42 | ||
958 | msgid "Daily" | ||
959 | msgstr "Quotidien" | ||
960 | |||
961 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:61 | ||
962 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:86 | ||
963 | msgid "RSS Feed" | ||
964 | msgstr "Flux RSS" | ||
965 | |||
966 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:66 | ||
967 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:102 | ||
968 | msgid "Logout" | ||
969 | msgstr "Déconnexion" | ||
970 | |||
971 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:81 | ||
972 | msgid "Search" | ||
973 | msgstr "Rechercher" | ||
974 | |||
975 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:171 | ||
976 | msgid "is available" | ||
977 | msgstr "est disponible" | ||
978 | |||
979 | #: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:178 | ||
980 | msgid "Error" | ||
981 | msgstr "Erreur" | ||
982 | |||
983 | #: tmp/picwall.b91ef64efc3688266305ea9b42e5017e.rtpl.php:16 | ||
984 | msgid "Picture Wall" | ||
985 | msgstr "Mur d'images" | ||
986 | |||
987 | #: tmp/picwall.b91ef64efc3688266305ea9b42e5017e.rtpl.php:16 | ||
988 | msgid "pics" | ||
989 | msgstr "images" | ||
990 | |||
991 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:15 | ||
992 | msgid "You need to enable Javascript to change plugin loading order." | ||
993 | msgstr "" | ||
994 | "Vous devez activer Javascript pour pouvoir modifier l'ordre des extensions." | ||
995 | |||
996 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:26 | ||
997 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:22 | ||
998 | msgid "Plugin administration" | ||
999 | msgstr "Administration des extensions" | ||
1000 | |||
1001 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29 | ||
1002 | msgid "Enabled Plugins" | ||
1003 | msgstr "Extensions activées" | ||
1004 | |||
1005 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:34 | ||
1006 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:155 | ||
1007 | msgid "No plugin enabled." | ||
1008 | msgstr "Aucune extension activée." | ||
1009 | |||
1010 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:40 | ||
1011 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:73 | ||
1012 | msgid "Disable" | ||
1013 | msgstr "Désactiver" | ||
1014 | |||
1015 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:41 | ||
1016 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:74 | ||
1017 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:98 | ||
1018 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:123 | ||
1019 | msgid "Name" | ||
1020 | msgstr "Nom" | ||
1021 | |||
1022 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:43 | ||
1023 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:76 | ||
1024 | msgid "Order" | ||
1025 | msgstr "Ordre" | ||
1026 | |||
1027 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:86 | ||
1028 | msgid "Disabled Plugins" | ||
1029 | msgstr "Extensions désactivées" | ||
1030 | |||
1031 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:91 | ||
1032 | msgid "No plugin disabled." | ||
1033 | msgstr "Aucune extension désactivée." | ||
1034 | |||
1035 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:97 | ||
1036 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:122 | ||
1037 | msgid "Enable" | ||
1038 | msgstr "Activer" | ||
1039 | |||
1040 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:134 | ||
1041 | msgid "More plugins available" | ||
1042 | msgstr "Plus d'extensions disponibles" | ||
1043 | |||
1044 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:136 | ||
1045 | msgid "in the documentation" | ||
1046 | msgstr "dans la documentation" | ||
1047 | |||
1048 | #: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:150 | ||
1049 | msgid "Plugin configuration" | ||
1050 | msgstr "Configuration des extensions" | ||
1051 | |||
1052 | #: tmp/tag.cloud.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19 | ||
1053 | #: tmp/tag.list.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19 | ||
1054 | #: tmp/tagcloud.b91ef64efc3688266305ea9b42e5017e.rtpl.php:16 | ||
1055 | msgid "tags" | ||
1056 | msgstr "tags" | ||
1057 | |||
1058 | #: tmp/tag.list.b91ef64efc3688266305ea9b42e5017e.rtpl.php:19 | ||
1059 | msgid "Tag list" | ||
1060 | msgstr "List des tags" | ||
1061 | |||
1062 | #: tmp/tag.sort.cedf684561d925457130839629000a81.rtpl.php:3 | ||
1063 | msgid "Sort by:" | ||
1064 | msgstr "Trier par :" | ||
1065 | |||
1066 | #: tmp/tag.sort.cedf684561d925457130839629000a81.rtpl.php:5 | ||
1067 | msgid "Cloud" | ||
1068 | msgstr "Nuage" | ||
1069 | |||
1070 | #: tmp/tag.sort.cedf684561d925457130839629000a81.rtpl.php:6 | ||
1071 | msgid "Most used" | ||
1072 | msgstr "Plus utilisés" | ||
1073 | |||
1074 | #: tmp/tag.sort.cedf684561d925457130839629000a81.rtpl.php:7 | ||
1075 | msgid "Alphabetical" | ||
1076 | msgstr "Alphabétique" | ||
1077 | |||
1078 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14 | ||
1079 | msgid "Settings" | ||
1080 | msgstr "Paramètres" | ||
1081 | |||
1082 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:16 | ||
1083 | msgid "Change Shaarli settings: title, timezone, etc." | ||
1084 | msgstr "Changer les paramètres de Shaarli : titre, fuseau horaire, etc." | ||
1085 | |||
1086 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:17 | ||
1087 | msgid "Configure your Shaarli" | ||
1088 | msgstr "Conguration de Shaarli" | ||
1089 | |||
1090 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:21 | ||
1091 | msgid "Enable, disable and configure plugins" | ||
1092 | msgstr "Activer, désactiver et configurer les extensions" | ||
1093 | |||
1094 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:28 | ||
1095 | msgid "Change your password" | ||
1096 | msgstr "Modification du mot de passe" | ||
1097 | |||
1098 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35 | ||
1099 | msgid "Rename or delete a tag in all links" | ||
1100 | msgstr "Rename or delete a tag in all links" | ||
1101 | |||
1102 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:41 | ||
1103 | msgid "" | ||
1104 | "Import Netscape HTML bookmarks (as exported from Firefox, Chrome, Opera, " | ||
1105 | "delicious...)" | ||
1106 | msgstr "" | ||
1107 | "Importer des marques pages au format Netscape HTML (comme exportés depuis " | ||
1108 | "Firefox, Chrome, Opera, delicious...)" | ||
1109 | |||
1110 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:42 | ||
1111 | msgid "Import links" | ||
1112 | msgstr "Importer des liens" | ||
1113 | |||
1114 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:47 | ||
1115 | msgid "" | ||
1116 | "Export Netscape HTML bookmarks (which can be imported in Firefox, Chrome, " | ||
1117 | "Opera, delicious...)" | ||
1118 | msgstr "" | ||
1119 | "Exporter les marques pages au format Netscape HTML (comme exportés depuis " | ||
1120 | "Firefox, Chrome, Opera, delicious...)" | ||
1121 | |||
1122 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:48 | ||
1123 | msgid "Export database" | ||
1124 | msgstr "Exporter les données" | ||
1125 | |||
1126 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:71 | ||
1127 | msgid "" | ||
1128 | "Drag one of these button to your bookmarks toolbar or right-click it and " | ||
1129 | "\"Bookmark This Link\"" | ||
1130 | msgstr "" | ||
1131 | "Glisser un de ces bouttons dans votre barre de favoris ou cliquer droit " | ||
1132 | "dessus et « Ajouter aux favoris »" | ||
1133 | |||
1134 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:72 | ||
1135 | msgid "then click on the bookmarklet in any page you want to share." | ||
1136 | msgstr "" | ||
1137 | "puis cliquer sur le marque page depuis un site que vous souhaitez partager." | ||
1138 | |||
1139 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:76 | ||
1140 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:95 | ||
1141 | msgid "" | ||
1142 | "Drag this link to your bookmarks toolbar or right-click it and Bookmark This " | ||
1143 | "Link" | ||
1144 | msgstr "" | ||
1145 | "Glisser ce lien dans votre barre de favoris ou cliquer droit dessus et « " | ||
1146 | "Ajouter aux favoris »" | ||
1147 | |||
1148 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:77 | ||
1149 | msgid "then click ✚Shaare link button in any page you want to share" | ||
1150 | msgstr "puis cliquer sur ✚Shaare depuis un site que vous souhaitez partager" | ||
1151 | |||
1152 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:91 | ||
1153 | msgid "Shaare link" | ||
1154 | msgstr "Shaare" | ||
1155 | |||
1156 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:96 | ||
1157 | msgid "" | ||
1158 | "Then click ✚Add Note button anytime to start composing a private Note (text " | ||
1159 | "post) to your Shaarli" | ||
1160 | msgstr "" | ||
1161 | "Puis cliquer sur ✚Add Note pour commencer à rédiger une Note sur Shaarli" | ||
1162 | |||
1163 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:99 | ||
1164 | msgid "Add Note" | ||
1165 | msgstr "Ajouter une Note" | ||
1166 | |||
1167 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:111 | ||
1168 | msgid "" | ||
1169 | "You need to browse your Shaarli over <strong>HTTPS</strong> to use this " | ||
1170 | "functionality." | ||
1171 | msgstr "" | ||
1172 | "Vous devez utiliser Shaarli en <strong>HTTPS</strong> pour utiliser cette " | ||
1173 | "fonctionalité." | ||
1174 | |||
1175 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:116 | ||
1176 | msgid "Add to" | ||
1177 | msgstr "Ajouter à " | ||
1178 | |||
1179 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:127 | ||
1180 | msgid "3rd party" | ||
1181 | msgstr "Applications tierces" | ||
1182 | |||
1183 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:129 | ||
1184 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:135 | ||
1185 | msgid "Plugin" | ||
1186 | msgstr "Extension" | ||
1187 | |||
1188 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:130 | ||
1189 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:136 | ||
1190 | msgid "plugin" | ||
1191 | msgstr "extension" | ||
1192 | |||
1193 | #: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:157 | ||
1194 | msgid "" | ||
1195 | "Drag this link to your bookmarks toolbar, or right-click it and choose " | ||
1196 | "Bookmark This Link" | ||
1197 | msgstr "" | ||
1198 | "Glisser ce lien dans votre barre de favoris ou cliquer droit dessus et « " | ||
1199 | "Ajouter aux favoris »" | ||
1200 | |||
1201 | #~ msgid "Sessions do not seem to work correctly on your server." | ||
1202 | #~ msgstr "Les sessions ne semblent " | ||
1203 | |||
1204 | #~ msgid "Tag was renamed in " | ||
1205 | #~ msgstr "Le tag a été renommé dans " | ||
1206 | |||
1207 | #, fuzzy | ||
1208 | #~| msgid "My links" | ||
1209 | #~ msgid " links" | ||
1210 | #~ msgstr "Mes liens" | ||
1211 | |||
1212 | #, fuzzy | ||
1213 | #~| msgid "" | ||
1214 | #~| "Error: missing Composer configuration\n" | ||
1215 | #~| "\n" | ||
1216 | #~ msgid "Error: missing Composer configuration" | ||
1217 | #~ msgstr "" | ||
1218 | #~ "Erreur : la configuration Composer est manquante\n" | ||
1219 | #~ "\n" | ||
1220 | |||
1221 | #, fuzzy | ||
1222 | #~| msgid "" | ||
1223 | #~| "Shaarli could not create the config file. Please make sure Shaarli has " | ||
1224 | #~| "the right to write in the folder is it installed in." | ||
1225 | #~ msgid "" | ||
1226 | #~ "Shaarli could not create the config file. \n" | ||
1227 | #~ " Please make sure Shaarli has the right to write in the " | ||
1228 | #~ "folder is it installed in." | ||
1229 | #~ msgstr "" | ||
1230 | #~ "Shaarli n'a pas pu créer le fichier de configuration. Merci de vérifier " | ||
1231 | #~ "que Shaarli a les droits d'écriture dans le dossier dans lequel il est " | ||
1232 | #~ "installé." | ||
1233 | |||
1234 | #, fuzzy | ||
1235 | #~| msgid "Plugin" | ||
1236 | #~ msgid "Plugin \"" | ||
1237 | #~ msgstr "Extension" | ||
1238 | |||
1239 | #~ msgid "Your PHP version is obsolete!" | ||
1240 | #~ msgstr "Votre version de PHP est obsolète !" | ||
1241 | |||
1242 | #~ msgid " Shaarli requires at least PHP " | ||
1243 | #~ msgstr "Shaarli nécessite au moins PHP" | ||
@@ -64,7 +64,6 @@ require_once 'application/FeedBuilder.php'; | |||
64 | require_once 'application/FileUtils.php'; | 64 | require_once 'application/FileUtils.php'; |
65 | require_once 'application/History.php'; | 65 | require_once 'application/History.php'; |
66 | require_once 'application/HttpUtils.php'; | 66 | require_once 'application/HttpUtils.php'; |
67 | require_once 'application/Languages.php'; | ||
68 | require_once 'application/LinkDB.php'; | 67 | require_once 'application/LinkDB.php'; |
69 | require_once 'application/LinkFilter.php'; | 68 | require_once 'application/LinkFilter.php'; |
70 | require_once 'application/LinkUtils.php'; | 69 | require_once 'application/LinkUtils.php'; |
@@ -76,6 +75,7 @@ require_once 'application/Utils.php'; | |||
76 | require_once 'application/PluginManager.php'; | 75 | require_once 'application/PluginManager.php'; |
77 | require_once 'application/Router.php'; | 76 | require_once 'application/Router.php'; |
78 | require_once 'application/Updater.php'; | 77 | require_once 'application/Updater.php'; |
78 | use \Shaarli\Languages; | ||
79 | use \Shaarli\ThemeUtils; | 79 | use \Shaarli\ThemeUtils; |
80 | use \Shaarli\Config\ConfigManager; | 80 | use \Shaarli\Config\ConfigManager; |
81 | 81 | ||
@@ -121,8 +121,16 @@ if (isset($_COOKIE['shaarli']) && !is_session_id_valid($_COOKIE['shaarli'])) { | |||
121 | } | 121 | } |
122 | 122 | ||
123 | $conf = new ConfigManager(); | 123 | $conf = new ConfigManager(); |
124 | |||
125 | // Sniff browser language and set date format accordingly. | ||
126 | if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { | ||
127 | autoLocale($_SERVER['HTTP_ACCEPT_LANGUAGE']); | ||
128 | } | ||
129 | |||
130 | new Languages(setlocale(LC_MESSAGES, 0), $conf); | ||
131 | |||
124 | $conf->setEmpty('general.timezone', date_default_timezone_get()); | 132 | $conf->setEmpty('general.timezone', date_default_timezone_get()); |
125 | $conf->setEmpty('general.title', 'Shared links on '. escape(index_url($_SERVER))); | 133 | $conf->setEmpty('general.title', t('Shared links on '). escape(index_url($_SERVER))); |
126 | RainTPL::$tpl_dir = $conf->get('resource.raintpl_tpl').'/'.$conf->get('resource.theme').'/'; // template directory | 134 | RainTPL::$tpl_dir = $conf->get('resource.raintpl_tpl').'/'.$conf->get('resource.theme').'/'; // template directory |
127 | RainTPL::$cache_dir = $conf->get('resource.raintpl_tmp'); // cache directory | 135 | RainTPL::$cache_dir = $conf->get('resource.raintpl_tmp'); // cache directory |
128 | 136 | ||
@@ -144,7 +152,7 @@ if (! is_file($conf->getConfigFileExt())) { | |||
144 | $errors = ApplicationUtils::checkResourcePermissions($conf); | 152 | $errors = ApplicationUtils::checkResourcePermissions($conf); |
145 | 153 | ||
146 | if ($errors != array()) { | 154 | if ($errors != array()) { |
147 | $message = '<p>Insufficient permissions:</p><ul>'; | 155 | $message = '<p>'. t('Insufficient permissions:') .'</p><ul>'; |
148 | 156 | ||
149 | foreach ($errors as $error) { | 157 | foreach ($errors as $error) { |
150 | $message .= '<li>'.$error.'</li>'; | 158 | $message .= '<li>'.$error.'</li>'; |
@@ -163,11 +171,6 @@ if (! is_file($conf->getConfigFileExt())) { | |||
163 | // a token depending of deployment salt, user password, and the current ip | 171 | // a token depending of deployment salt, user password, and the current ip |
164 | define('STAY_SIGNED_IN_TOKEN', sha1($conf->get('credentials.hash') . $_SERVER['REMOTE_ADDR'] . $conf->get('credentials.salt'))); | 172 | define('STAY_SIGNED_IN_TOKEN', sha1($conf->get('credentials.hash') . $_SERVER['REMOTE_ADDR'] . $conf->get('credentials.salt'))); |
165 | 173 | ||
166 | // Sniff browser language and set date format accordingly. | ||
167 | if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { | ||
168 | autoLocale($_SERVER['HTTP_ACCEPT_LANGUAGE']); | ||
169 | } | ||
170 | |||
171 | /** | 174 | /** |
172 | * Checking session state (i.e. is the user still logged in) | 175 | * Checking session state (i.e. is the user still logged in) |
173 | * | 176 | * |
@@ -376,7 +379,7 @@ function ban_canLogin($conf) | |||
376 | // Process login form: Check if login/password is correct. | 379 | // Process login form: Check if login/password is correct. |
377 | if (isset($_POST['login'])) | 380 | if (isset($_POST['login'])) |
378 | { | 381 | { |
379 | if (!ban_canLogin($conf)) die('I said: NO. You are banned for the moment. Go away.'); | 382 | if (!ban_canLogin($conf)) die(t('I said: NO. You are banned for the moment. Go away.')); |
380 | if (isset($_POST['password']) | 383 | if (isset($_POST['password']) |
381 | && tokenOk($_POST['token']) | 384 | && tokenOk($_POST['token']) |
382 | && (check_auth($_POST['login'], $_POST['password'], $conf)) | 385 | && (check_auth($_POST['login'], $_POST['password'], $conf)) |
@@ -440,7 +443,8 @@ if (isset($_POST['login'])) | |||
440 | } | 443 | } |
441 | } | 444 | } |
442 | } | 445 | } |
443 | echo '<script>alert("Wrong login/password.");document.location=\'?do=login'.$redir.'\';</script>'; // Redirect to login screen. | 446 | // Redirect to login screen. |
447 | echo '<script>alert("'. t("Wrong login/password.") .'");document.location=\'?do=login'.$redir.'\';</script>'; | ||
444 | exit; | 448 | exit; |
445 | } | 449 | } |
446 | } | 450 | } |
@@ -1100,16 +1104,19 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history) | |||
1100 | if ($targetPage == Router::$PAGE_CHANGEPASSWORD) | 1104 | if ($targetPage == Router::$PAGE_CHANGEPASSWORD) |
1101 | { | 1105 | { |
1102 | if ($conf->get('security.open_shaarli')) { | 1106 | if ($conf->get('security.open_shaarli')) { |
1103 | die('You are not supposed to change a password on an Open Shaarli.'); | 1107 | die(t('You are not supposed to change a password on an Open Shaarli.')); |
1104 | } | 1108 | } |
1105 | 1109 | ||
1106 | if (!empty($_POST['setpassword']) && !empty($_POST['oldpassword'])) | 1110 | if (!empty($_POST['setpassword']) && !empty($_POST['oldpassword'])) |
1107 | { | 1111 | { |
1108 | if (!tokenOk($_POST['token'])) die('Wrong token.'); // Go away! | 1112 | if (!tokenOk($_POST['token'])) die(t('Wrong token.')); // Go away! |
1109 | 1113 | ||
1110 | // Make sure old password is correct. | 1114 | // Make sure old password is correct. |
1111 | $oldhash = sha1($_POST['oldpassword'].$conf->get('credentials.login').$conf->get('credentials.salt')); | 1115 | $oldhash = sha1($_POST['oldpassword'].$conf->get('credentials.login').$conf->get('credentials.salt')); |
1112 | if ($oldhash!= $conf->get('credentials.hash')) { echo '<script>alert("The old password is not correct.");document.location=\'?do=changepasswd\';</script>'; exit; } | 1116 | if ($oldhash!= $conf->get('credentials.hash')) { |
1117 | echo '<script>alert("'. t('The old password is not correct.') .'");document.location=\'?do=changepasswd\';</script>'; | ||
1118 | exit; | ||
1119 | } | ||
1113 | // Save new password | 1120 | // Save new password |
1114 | // Salt renders rainbow-tables attacks useless. | 1121 | // Salt renders rainbow-tables attacks useless. |
1115 | $conf->set('credentials.salt', sha1(uniqid('', true) .'_'. mt_rand())); | 1122 | $conf->set('credentials.salt', sha1(uniqid('', true) .'_'. mt_rand())); |
@@ -1127,7 +1134,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history) | |||
1127 | echo '<script>alert("'. $e->getMessage() .'");document.location=\'?do=tools\';</script>'; | 1134 | echo '<script>alert("'. $e->getMessage() .'");document.location=\'?do=tools\';</script>'; |
1128 | exit; | 1135 | exit; |
1129 | } | 1136 | } |
1130 | echo '<script>alert("Your password has been changed.");document.location=\'?do=tools\';</script>'; | 1137 | echo '<script>alert("'. t('Your password has been changed') .'");document.location=\'?do=tools\';</script>'; |
1131 | exit; | 1138 | exit; |
1132 | } | 1139 | } |
1133 | else // show the change password form. | 1140 | else // show the change password form. |
@@ -1143,7 +1150,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history) | |||
1143 | if (!empty($_POST['title']) ) | 1150 | if (!empty($_POST['title']) ) |
1144 | { | 1151 | { |
1145 | if (!tokenOk($_POST['token'])) { | 1152 | if (!tokenOk($_POST['token'])) { |
1146 | die('Wrong token.'); // Go away! | 1153 | die(t('Wrong token.')); // Go away! |
1147 | } | 1154 | } |
1148 | $tz = 'UTC'; | 1155 | $tz = 'UTC'; |
1149 | if (!empty($_POST['continent']) && !empty($_POST['city']) | 1156 | if (!empty($_POST['continent']) && !empty($_POST['city']) |
@@ -1178,7 +1185,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history) | |||
1178 | echo '<script>alert("'. $e->getMessage() .'");document.location=\'?do=configure\';</script>'; | 1185 | echo '<script>alert("'. $e->getMessage() .'");document.location=\'?do=configure\';</script>'; |
1179 | exit; | 1186 | exit; |
1180 | } | 1187 | } |
1181 | echo '<script>alert("Configuration was saved.");document.location=\'?do=configure\';</script>'; | 1188 | echo '<script>alert("'. t('Configuration was saved.') .'");document.location=\'?do=configure\';</script>'; |
1182 | exit; | 1189 | exit; |
1183 | } | 1190 | } |
1184 | else // Show the configuration form. | 1191 | else // Show the configuration form. |
@@ -1215,7 +1222,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history) | |||
1215 | } | 1222 | } |
1216 | 1223 | ||
1217 | if (!tokenOk($_POST['token'])) { | 1224 | if (!tokenOk($_POST['token'])) { |
1218 | die('Wrong token.'); | 1225 | die(t('Wrong token.')); |
1219 | } | 1226 | } |
1220 | 1227 | ||
1221 | $alteredLinks = $LINKSDB->renameTag(escape($_POST['fromtag']), escape($_POST['totag'])); | 1228 | $alteredLinks = $LINKSDB->renameTag(escape($_POST['fromtag']), escape($_POST['totag'])); |
@@ -1244,7 +1251,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history) | |||
1244 | { | 1251 | { |
1245 | // Go away! | 1252 | // Go away! |
1246 | if (! tokenOk($_POST['token'])) { | 1253 | if (! tokenOk($_POST['token'])) { |
1247 | die('Wrong token.'); | 1254 | die(t('Wrong token.')); |
1248 | } | 1255 | } |
1249 | 1256 | ||
1250 | // lf_id should only be present if the link exists. | 1257 | // lf_id should only be present if the link exists. |
@@ -1344,7 +1351,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history) | |||
1344 | if ($targetPage == Router::$PAGE_DELETELINK) | 1351 | if ($targetPage == Router::$PAGE_DELETELINK) |
1345 | { | 1352 | { |
1346 | if (! tokenOk($_GET['token'])) { | 1353 | if (! tokenOk($_GET['token'])) { |
1347 | die('Wrong token.'); | 1354 | die(t('Wrong token.')); |
1348 | } | 1355 | } |
1349 | 1356 | ||
1350 | $ids = trim($_GET['lf_linkdate']); | 1357 | $ids = trim($_GET['lf_linkdate']); |
@@ -1550,11 +1557,14 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history) | |||
1550 | // Import bookmarks from an uploaded file | 1557 | // Import bookmarks from an uploaded file |
1551 | if (isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size'] == 0) { | 1558 | if (isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size'] == 0) { |
1552 | // The file is too big or some form field may be missing. | 1559 | // The file is too big or some form field may be missing. |
1553 | echo '<script>alert("The file you are trying to upload is probably' | 1560 | $msg = sprintf( |
1554 | .' bigger than what this webserver can accept (' | 1561 | t( |
1555 | .get_max_upload_size(ini_get('post_max_size'), ini_get('upload_max_filesize')).').' | 1562 | 'The file you are trying to upload is probably bigger than what this webserver can accept' |
1556 | .' Please upload in smaller chunks.");document.location=\'?do=' | 1563 | .' (%s). Please upload in smaller chunks.' |
1557 | .Router::$PAGE_IMPORT .'\';</script>'; | 1564 | ), |
1565 | get_max_upload_size(ini_get('post_max_size'), ini_get('upload_max_filesize')) | ||
1566 | ); | ||
1567 | echo '<script>alert("'. $msg .'");document.location=\'?do='.Router::$PAGE_IMPORT .'\';</script>'; | ||
1558 | exit; | 1568 | exit; |
1559 | } | 1569 | } |
1560 | if (! tokenOk($_POST['token'])) { | 1570 | if (! tokenOk($_POST['token'])) { |
@@ -1962,12 +1972,20 @@ function install($conf) | |||
1962 | // (Because on some hosts, session.save_path may not be set correctly, | 1972 | // (Because on some hosts, session.save_path may not be set correctly, |
1963 | // or we may not have write access to it.) | 1973 | // or we may not have write access to it.) |
1964 | if (isset($_GET['test_session']) && ( !isset($_SESSION) || !isset($_SESSION['session_tested']) || $_SESSION['session_tested']!='Working')) | 1974 | if (isset($_GET['test_session']) && ( !isset($_SESSION) || !isset($_SESSION['session_tested']) || $_SESSION['session_tested']!='Working')) |
1965 | { // Step 2: Check if data in session is correct. | 1975 | { |
1966 | echo '<pre>Sessions do not seem to work correctly on your server.<br>'; | 1976 | // Step 2: Check if data in session is correct. |
1967 | echo 'Make sure the variable session.save_path is set correctly in your php config, and that you have write access to it.<br>'; | 1977 | $msg = t( |
1968 | echo 'It currently points to '.session_save_path().'<br>'; | 1978 | '<pre>Sessions do not seem to work correctly on your server.<br>'. |
1969 | echo 'Check that the hostname used to access Shaarli contains a dot. On some browsers, accessing your server via a hostname like \'localhost\' or any custom hostname without a dot causes cookie storage to fail. We recommend accessing your server via it\'s IP address or Fully Qualified Domain Name.<br>'; | 1979 | 'Make sure the variable "session.save_path" is set correctly in your PHP config, '. |
1970 | echo '<br><a href="?">Click to try again.</a></pre>'; | 1980 | 'and that you have write access to it.<br>'. |
1981 | 'It currently points to %s.<br>'. | ||
1982 | 'On some browsers, accessing your server via a hostname like \'localhost\' '. | ||
1983 | 'or any custom hostname without a dot causes cookie storage to fail. '. | ||
1984 | 'We recommend accessing your server via it\'s IP address or Fully Qualified Domain Name.<br>' | ||
1985 | ); | ||
1986 | $msg = sprintf($msg, session_save_path()); | ||
1987 | echo $msg; | ||
1988 | echo '<br><a href="?">'. t('Click to try again.') .'</a></pre>'; | ||
1971 | die; | 1989 | die; |
1972 | } | 1990 | } |
1973 | if (!isset($_SESSION['session_tested'])) | 1991 | if (!isset($_SESSION['session_tested'])) |
diff --git a/plugins/TODO.md b/plugins/TODO.md deleted file mode 100644 index e3313d67..00000000 --- a/plugins/TODO.md +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | https://github.com/shaarli/Shaarli/issues/181 - Add Disqus or Isso comments box on a permalink page | ||
2 | |||
3 | * http://posativ.org/isso/ | ||
4 | * install debian package https://packages.debian.org/sid/isso | ||
5 | * configure server http://posativ.org/isso/docs/configuration/server/ | ||
6 | * configure client http://posativ.org/isso/docs/configuration/client/ | ||
7 | * http://posativ.org/isso/docs/quickstart/ and add `<script data-isso="//comments.example.tld/" src="//comments.example.tld/js/embed.min.js"></script>` to includes.html template; then add `<section id="isso-thread"></section>` in the linklist template where you want the comments (in the linklist_plugins loop for example) | ||
8 | |||
9 | |||
10 | Problem: by default, Isso thread ID is guessed from the current url (only one thread per page). | ||
11 | if we want multiple threads on a single page (shaarli linklist), we must use : the `data-isso-id` client config, | ||
12 | with data-isso-id being the permalink of an item. | ||
13 | |||
14 | `<section data-isso-id="aH7klxW" id="isso-thread"></section>` | ||
15 | `data-isso-id: Set a custom thread id, defaults to current URI.` | ||
16 | |||
17 | Problem: feature is currently broken https://github.com/posativ/isso/issues/27 | ||
18 | |||
19 | Another option, only display isso threads when current URL is a permalink (`\?(A-Z|a-z|0-9|-){7}`) (only show thread | ||
20 | when displaying only this link), and just display a "comments" button on each linklist item. Optionally show the comment | ||
21 | count on each item using the API (http://posativ.org/isso/docs/extras/api/#get-comment-count). API requests can be done | ||
22 | by raintpl `{function` or client-side with js. The former should be faster if isso and shaarli are on ther same server. | ||
23 | |||
24 | Showing all full isso threads in the linklist would destroy layout | ||
25 | |||
26 | ----------------------------------------------------------- | ||
27 | |||
28 | http://www.git-attitude.fr/2014/11/04/git-rerere/ for the merge | ||
diff --git a/plugins/addlink_toolbar/addlink_toolbar.php b/plugins/addlink_toolbar/addlink_toolbar.php index ddf50aaf..8c05a231 100644 --- a/plugins/addlink_toolbar/addlink_toolbar.php +++ b/plugins/addlink_toolbar/addlink_toolbar.php | |||
@@ -26,11 +26,11 @@ function hook_addlink_toolbar_render_header($data) | |||
26 | array( | 26 | array( |
27 | 'type' => 'text', | 27 | 'type' => 'text', |
28 | 'name' => 'post', | 28 | 'name' => 'post', |
29 | 'placeholder' => 'URI', | 29 | 'placeholder' => t('URI'), |
30 | ), | 30 | ), |
31 | array( | 31 | array( |
32 | 'type' => 'submit', | 32 | 'type' => 'submit', |
33 | 'value' => 'Add link', | 33 | 'value' => t('Add link'), |
34 | 'class' => 'bigbutton', | 34 | 'class' => 'bigbutton', |
35 | ), | 35 | ), |
36 | ), | 36 | ), |
@@ -40,3 +40,12 @@ function hook_addlink_toolbar_render_header($data) | |||
40 | 40 | ||
41 | return $data; | 41 | return $data; |
42 | } | 42 | } |
43 | |||
44 | /** | ||
45 | * This function is never called, but contains translation calls for GNU gettext extraction. | ||
46 | */ | ||
47 | function addlink_toolbar_dummy_translation() | ||
48 | { | ||
49 | // meta | ||
50 | t('Adds the addlink input on the linklist page.'); | ||
51 | } | ||
diff --git a/plugins/archiveorg/archiveorg.html b/plugins/archiveorg/archiveorg.html index 0781fe35..ad501f47 100644 --- a/plugins/archiveorg/archiveorg.html +++ b/plugins/archiveorg/archiveorg.html | |||
@@ -1 +1,5 @@ | |||
1 | <span><a href="https://web.archive.org/web/%s"><img class="linklist-plugin-icon" src="plugins/archiveorg/internetarchive.png" title="View on archive.org" alt="archive.org" /></a></span> | 1 | <span> |
2 | <a href="https://web.archive.org/web/%s"> | ||
3 | <img class="linklist-plugin-icon" src="plugins/archiveorg/internetarchive.png" title="%s" alt="archive.org" /> | ||
4 | </a> | ||
5 | </span> | ||
diff --git a/plugins/archiveorg/archiveorg.php b/plugins/archiveorg/archiveorg.php index 03d13d0e..cda35751 100644 --- a/plugins/archiveorg/archiveorg.php +++ b/plugins/archiveorg/archiveorg.php | |||
@@ -20,9 +20,18 @@ function hook_archiveorg_render_linklist($data) | |||
20 | if($value['private'] && preg_match('/^\?[a-zA-Z0-9-_@]{6}($|&|#)/', $value['real_url'])) { | 20 | if($value['private'] && preg_match('/^\?[a-zA-Z0-9-_@]{6}($|&|#)/', $value['real_url'])) { |
21 | continue; | 21 | continue; |
22 | } | 22 | } |
23 | $archive = sprintf($archive_html, $value['url']); | 23 | $archive = sprintf($archive_html, $value['url'], t('View on archive.org')); |
24 | $value['link_plugin'][] = $archive; | 24 | $value['link_plugin'][] = $archive; |
25 | } | 25 | } |
26 | 26 | ||
27 | return $data; | 27 | return $data; |
28 | } | 28 | } |
29 | |||
30 | /** | ||
31 | * This function is never called, but contains translation calls for GNU gettext extraction. | ||
32 | */ | ||
33 | function archiveorg_dummy_translation() | ||
34 | { | ||
35 | // meta | ||
36 | t('For each link, add an Archive.org icon.'); | ||
37 | } | ||
diff --git a/plugins/demo_plugin/demo_plugin.php b/plugins/demo_plugin/demo_plugin.php index 8fdbf663..3a90ae6a 100644 --- a/plugins/demo_plugin/demo_plugin.php +++ b/plugins/demo_plugin/demo_plugin.php | |||
@@ -433,3 +433,12 @@ function hook_demo_plugin_render_feed($data) | |||
433 | } | 433 | } |
434 | return $data; | 434 | return $data; |
435 | } | 435 | } |
436 | |||
437 | /** | ||
438 | * This function is never called, but contains translation calls for GNU gettext extraction. | ||
439 | */ | ||
440 | function demo_dummy_translation() | ||
441 | { | ||
442 | // meta | ||
443 | t('A demo plugin covering all use cases for template designers and plugin developers.'); | ||
444 | } | ||
diff --git a/plugins/isso/isso.php b/plugins/isso/isso.php index ce16645f..5bc1cce2 100644 --- a/plugins/isso/isso.php +++ b/plugins/isso/isso.php | |||
@@ -4,10 +4,11 @@ | |||
4 | * Plugin Isso. | 4 | * Plugin Isso. |
5 | */ | 5 | */ |
6 | 6 | ||
7 | use Shaarli\Config\ConfigManager; | ||
8 | |||
7 | /** | 9 | /** |
8 | * Display an error everywhere if the plugin is enabled without configuration. | 10 | * Display an error everywhere if the plugin is enabled without configuration. |
9 | * | 11 | * |
10 | * @param $data array List of links | ||
11 | * @param $conf ConfigManager instance | 12 | * @param $conf ConfigManager instance |
12 | * | 13 | * |
13 | * @return mixed - linklist data with Isso plugin. | 14 | * @return mixed - linklist data with Isso plugin. |
@@ -16,8 +17,8 @@ function isso_init($conf) | |||
16 | { | 17 | { |
17 | $issoUrl = $conf->get('plugins.ISSO_SERVER'); | 18 | $issoUrl = $conf->get('plugins.ISSO_SERVER'); |
18 | if (empty($issoUrl)) { | 19 | if (empty($issoUrl)) { |
19 | $error = 'Isso plugin error: '. | 20 | $error = t('Isso plugin error: '. |
20 | 'Please define the "ISSO_SERVER" setting in the plugin administration page.'; | 21 | 'Please define the "ISSO_SERVER" setting in the plugin administration page.'); |
21 | return array($error); | 22 | return array($error); |
22 | } | 23 | } |
23 | } | 24 | } |
@@ -52,3 +53,13 @@ function hook_isso_render_linklist($data, $conf) | |||
52 | 53 | ||
53 | return $data; | 54 | return $data; |
54 | } | 55 | } |
56 | |||
57 | /** | ||
58 | * This function is never called, but contains translation calls for GNU gettext extraction. | ||
59 | */ | ||
60 | function isso_dummy_translation() | ||
61 | { | ||
62 | // meta | ||
63 | t('Let visitor comment your shaares on permalinks with Isso.'); | ||
64 | t('Isso server URL (without \'http://\')'); | ||
65 | } | ||
diff --git a/plugins/markdown/help.html b/plugins/markdown/help.html index 9c4e5ae0..ded3d347 100644 --- a/plugins/markdown/help.html +++ b/plugins/markdown/help.html | |||
@@ -1,5 +1,5 @@ | |||
1 | <div class="md_help"> | 1 | <div class="md_help"> |
2 | Description will be rendered with | 2 | %s |
3 | <a href="http://daringfireball.net/projects/markdown/syntax" title="Markdown syntax documentation"> | 3 | <a href="http://daringfireball.net/projects/markdown/syntax" title="%s"> |
4 | Markdown syntax</a>. | 4 | %s</a>. |
5 | </div> | 5 | </div> |
diff --git a/plugins/markdown/markdown.php b/plugins/markdown/markdown.php index 772c56e8..1531549d 100644 --- a/plugins/markdown/markdown.php +++ b/plugins/markdown/markdown.php | |||
@@ -154,8 +154,13 @@ function hook_markdown_render_includes($data) | |||
154 | function hook_markdown_render_editlink($data) | 154 | function hook_markdown_render_editlink($data) |
155 | { | 155 | { |
156 | // Load help HTML into a string | 156 | // Load help HTML into a string |
157 | $data['edit_link_plugin'][] = file_get_contents(PluginManager::$PLUGINS_PATH .'/markdown/help.html'); | 157 | $txt = file_get_contents(PluginManager::$PLUGINS_PATH .'/markdown/help.html'); |
158 | 158 | $translations = [ | |
159 | t('Description will be rendered with'), | ||
160 | t('Markdown syntax documentation'), | ||
161 | t('Markdown syntax'), | ||
162 | ]; | ||
163 | $data['edit_link_plugin'][] = vsprintf($txt, $translations); | ||
159 | // Add no markdown 'meta-tag' in tag list if it was never used, for autocompletion. | 164 | // Add no markdown 'meta-tag' in tag list if it was never used, for autocompletion. |
160 | if (! in_array(NO_MD_TAG, $data['tags'])) { | 165 | if (! in_array(NO_MD_TAG, $data['tags'])) { |
161 | $data['tags'][NO_MD_TAG] = 0; | 166 | $data['tags'][NO_MD_TAG] = 0; |
@@ -325,3 +330,15 @@ function process_markdown($description, $escape = true, $allowedProtocols = []) | |||
325 | 330 | ||
326 | return $processedDescription; | 331 | return $processedDescription; |
327 | } | 332 | } |
333 | |||
334 | /** | ||
335 | * This function is never called, but contains translation calls for GNU gettext extraction. | ||
336 | */ | ||
337 | function markdown_dummy_translation() | ||
338 | { | ||
339 | // meta | ||
340 | t('Render shaare description with Markdown syntax.<br><strong>Warning</strong>: | ||
341 | If your shaared descriptions contained HTML tags before enabling the markdown plugin, | ||
342 | enabling it might break your page. | ||
343 | See the <a href="https://github.com/shaarli/Shaarli/tree/master/plugins/markdown#html-rendering">README</a>.'); | ||
344 | } | ||
diff --git a/plugins/piwik/piwik.php b/plugins/piwik/piwik.php index 4a2b48a1..ca00c2be 100644 --- a/plugins/piwik/piwik.php +++ b/plugins/piwik/piwik.php | |||
@@ -18,8 +18,8 @@ function piwik_init($conf) | |||
18 | $piwikUrl = $conf->get('plugins.PIWIK_URL'); | 18 | $piwikUrl = $conf->get('plugins.PIWIK_URL'); |
19 | $piwikSiteid = $conf->get('plugins.PIWIK_SITEID'); | 19 | $piwikSiteid = $conf->get('plugins.PIWIK_SITEID'); |
20 | if (empty($piwikUrl) || empty($piwikSiteid)) { | 20 | if (empty($piwikUrl) || empty($piwikSiteid)) { |
21 | $error = 'Piwik plugin error: ' . | 21 | $error = t('Piwik plugin error: ' . |
22 | 'Please define PIWIK_URL and PIWIK_SITEID in the plugin administration page.'; | 22 | 'Please define PIWIK_URL and PIWIK_SITEID in the plugin administration page.'); |
23 | return array($error); | 23 | return array($error); |
24 | } | 24 | } |
25 | } | 25 | } |
@@ -60,3 +60,14 @@ function hook_piwik_render_footer($data, $conf) | |||
60 | 60 | ||
61 | return $data; | 61 | return $data; |
62 | } | 62 | } |
63 | |||
64 | /** | ||
65 | * This function is never called, but contains translation calls for GNU gettext extraction. | ||
66 | */ | ||
67 | function piwik_dummy_translation() | ||
68 | { | ||
69 | // meta | ||
70 | t('A plugin that adds Piwik tracking code to Shaarli pages.'); | ||
71 | t('Piwik URL'); | ||
72 | t('Piwik site ID'); | ||
73 | } | ||
diff --git a/plugins/playvideos/playvideos.php b/plugins/playvideos/playvideos.php index 64484504..c6d6b0cc 100644 --- a/plugins/playvideos/playvideos.php +++ b/plugins/playvideos/playvideos.php | |||
@@ -19,10 +19,10 @@ function hook_playvideos_render_header($data) | |||
19 | $playvideo = array( | 19 | $playvideo = array( |
20 | 'attr' => array( | 20 | 'attr' => array( |
21 | 'href' => '#', | 21 | 'href' => '#', |
22 | 'title' => 'Video player', | 22 | 'title' => t('Video player'), |
23 | 'id' => 'playvideos', | 23 | 'id' => 'playvideos', |
24 | ), | 24 | ), |
25 | 'html' => 'â–º Play Videos' | 25 | 'html' => 'â–º '. t('Play Videos') |
26 | ); | 26 | ); |
27 | $data['buttons_toolbar'][] = $playvideo; | 27 | $data['buttons_toolbar'][] = $playvideo; |
28 | } | 28 | } |
@@ -46,3 +46,12 @@ function hook_playvideos_render_footer($data) | |||
46 | 46 | ||
47 | return $data; | 47 | return $data; |
48 | } | 48 | } |
49 | |||
50 | /** | ||
51 | * This function is never called, but contains translation calls for GNU gettext extraction. | ||
52 | */ | ||
53 | function playvideos_dummy_translation() | ||
54 | { | ||
55 | // meta | ||
56 | t('Add a button in the toolbar allowing to watch all videos.'); | ||
57 | } | ||
diff --git a/plugins/pubsubhubbub/pubsubhubbub.php b/plugins/pubsubhubbub/pubsubhubbub.php index 03b6757b..184b588b 100644 --- a/plugins/pubsubhubbub/pubsubhubbub.php +++ b/plugins/pubsubhubbub/pubsubhubbub.php | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | use pubsubhubbub\publisher\Publisher; | 12 | use pubsubhubbub\publisher\Publisher; |
13 | use Shaarli\Config\ConfigManager; | ||
13 | 14 | ||
14 | /** | 15 | /** |
15 | * Plugin init function - set the hub to the default appspot one. | 16 | * Plugin init function - set the hub to the default appspot one. |
@@ -65,7 +66,7 @@ function hook_pubsubhubbub_save_link($data, $conf) | |||
65 | $p = new Publisher($conf->get('plugins.PUBSUBHUB_URL')); | 66 | $p = new Publisher($conf->get('plugins.PUBSUBHUB_URL')); |
66 | $p->publish_update($feeds, $httpPost); | 67 | $p->publish_update($feeds, $httpPost); |
67 | } catch (Exception $e) { | 68 | } catch (Exception $e) { |
68 | error_log('Could not publish to PubSubHubbub: ' . $e->getMessage()); | 69 | error_log(sprintf(t('Could not publish to PubSubHubbub: %s'), $e->getMessage())); |
69 | } | 70 | } |
70 | 71 | ||
71 | return $data; | 72 | return $data; |
@@ -91,11 +92,20 @@ function nocurl_http_post($url, $postString) { | |||
91 | $context = stream_context_create($params); | 92 | $context = stream_context_create($params); |
92 | $fp = @fopen($url, 'rb', false, $context); | 93 | $fp = @fopen($url, 'rb', false, $context); |
93 | if (!$fp) { | 94 | if (!$fp) { |
94 | throw new Exception('Could not post to '. $url); | 95 | throw new Exception(sprintf(t('Could not post to %s'), $url)); |
95 | } | 96 | } |
96 | $response = @stream_get_contents($fp); | 97 | $response = @stream_get_contents($fp); |
97 | if ($response === false) { | 98 | if ($response === false) { |
98 | throw new Exception('Bad response from the hub '. $url); | 99 | throw new Exception(sprintf(t('Bad response from the hub %s'), $url)); |
99 | } | 100 | } |
100 | return $response; | 101 | return $response; |
101 | } | 102 | } |
103 | |||
104 | /** | ||
105 | * This function is never called, but contains translation calls for GNU gettext extraction. | ||
106 | */ | ||
107 | function pubsubhubbub_dummy_translation() | ||
108 | { | ||
109 | // meta | ||
110 | t('Enable PubSubHubbub feed publishing.'); | ||
111 | } | ||
diff --git a/plugins/qrcode/qrcode.meta b/plugins/qrcode/qrcode.meta index cbf371ea..1812cd21 100644 --- a/plugins/qrcode/qrcode.meta +++ b/plugins/qrcode/qrcode.meta | |||
@@ -1 +1 @@ | |||
description="For each link, add a QRCode icon ." | description="For each link, add a QRCode icon." | ||
diff --git a/plugins/qrcode/qrcode.php b/plugins/qrcode/qrcode.php index 8bc610d1..0f96a106 100644 --- a/plugins/qrcode/qrcode.php +++ b/plugins/qrcode/qrcode.php | |||
@@ -59,3 +59,12 @@ function hook_qrcode_render_includes($data) | |||
59 | 59 | ||
60 | return $data; | 60 | return $data; |
61 | } | 61 | } |
62 | |||
63 | /** | ||
64 | * This function is never called, but contains translation calls for GNU gettext extraction. | ||
65 | */ | ||
66 | function qrcode_dummy_translation() | ||
67 | { | ||
68 | // meta | ||
69 | t('For each link, add a QRCode icon.'); | ||
70 | } | ||
diff --git a/plugins/wallabag/wallabag.html b/plugins/wallabag/wallabag.html index e861536d..4c57691d 100644 --- a/plugins/wallabag/wallabag.html +++ b/plugins/wallabag/wallabag.html | |||
@@ -1 +1,5 @@ | |||
1 | <span><a href="%s%s" target="_blank"><img class="linklist-plugin-icon" src="%s/wallabag/wallabag.png" title="Save to wallabag" alt="wallabag" /></a></span> | 1 | <span> |
2 | <a href="%s%s" target="_blank"> | ||
3 | <img class="linklist-plugin-icon" src="%s/wallabag/wallabag.png" title="%s" alt="wallabag" /> | ||
4 | </a> | ||
5 | </span> | ||
diff --git a/plugins/wallabag/wallabag.php b/plugins/wallabag/wallabag.php index 641e4cc2..9dfd079e 100644 --- a/plugins/wallabag/wallabag.php +++ b/plugins/wallabag/wallabag.php | |||
@@ -5,6 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | require_once 'WallabagInstance.php'; | 7 | require_once 'WallabagInstance.php'; |
8 | use Shaarli\Config\ConfigManager; | ||
8 | 9 | ||
9 | /** | 10 | /** |
10 | * Init function, return an error if the server is not set. | 11 | * Init function, return an error if the server is not set. |
@@ -17,8 +18,8 @@ function wallabag_init($conf) | |||
17 | { | 18 | { |
18 | $wallabagUrl = $conf->get('plugins.WALLABAG_URL'); | 19 | $wallabagUrl = $conf->get('plugins.WALLABAG_URL'); |
19 | if (empty($wallabagUrl)) { | 20 | if (empty($wallabagUrl)) { |
20 | $error = 'Wallabag plugin error: '. | 21 | $error = t('Wallabag plugin error: '. |
21 | 'Please define the "WALLABAG_URL" setting in the plugin administration page.'; | 22 | 'Please define the "WALLABAG_URL" setting in the plugin administration page.'); |
22 | return array($error); | 23 | return array($error); |
23 | } | 24 | } |
24 | } | 25 | } |
@@ -43,12 +44,14 @@ function hook_wallabag_render_linklist($data, $conf) | |||
43 | 44 | ||
44 | $wallabagHtml = file_get_contents(PluginManager::$PLUGINS_PATH . '/wallabag/wallabag.html'); | 45 | $wallabagHtml = file_get_contents(PluginManager::$PLUGINS_PATH . '/wallabag/wallabag.html'); |
45 | 46 | ||
47 | $linkTitle = t('Save to wallabag'); | ||
46 | foreach ($data['links'] as &$value) { | 48 | foreach ($data['links'] as &$value) { |
47 | $wallabag = sprintf( | 49 | $wallabag = sprintf( |
48 | $wallabagHtml, | 50 | $wallabagHtml, |
49 | $wallabagInstance->getWallabagUrl(), | 51 | $wallabagInstance->getWallabagUrl(), |
50 | urlencode($value['url']), | 52 | urlencode($value['url']), |
51 | PluginManager::$PLUGINS_PATH | 53 | PluginManager::$PLUGINS_PATH, |
54 | $linkTitle | ||
52 | ); | 55 | ); |
53 | $value['link_plugin'][] = $wallabag; | 56 | $value['link_plugin'][] = $wallabag; |
54 | } | 57 | } |
@@ -56,3 +59,14 @@ function hook_wallabag_render_linklist($data, $conf) | |||
56 | return $data; | 59 | return $data; |
57 | } | 60 | } |
58 | 61 | ||
62 | /** | ||
63 | * This function is never called, but contains translation calls for GNU gettext extraction. | ||
64 | */ | ||
65 | function wallabag_dummy_translation() | ||
66 | { | ||
67 | // meta | ||
68 | t('For each link, add a QRCode icon.'); | ||
69 | t('Wallabag API URL'); | ||
70 | t('Wallabag API version (1 or 2)'); | ||
71 | } | ||
72 | |||
diff --git a/tests/LanguagesTest.php b/tests/LanguagesTest.php index 79c136c8..46bfcd72 100644 --- a/tests/LanguagesTest.php +++ b/tests/LanguagesTest.php | |||
@@ -1,41 +1,201 @@ | |||
1 | <?php | 1 | <?php |
2 | 2 | ||
3 | require_once 'application/Languages.php'; | 3 | namespace Shaarli; |
4 | |||
5 | use Shaarli\Config\ConfigManager; | ||
4 | 6 | ||
5 | /** | 7 | /** |
6 | * Class LanguagesTest. | 8 | * Class LanguagesTest. |
7 | */ | 9 | */ |
8 | class LanguagesTest extends PHPUnit_Framework_TestCase | 10 | class LanguagesTest extends \PHPUnit_Framework_TestCase |
9 | { | 11 | { |
10 | /** | 12 | /** |
13 | * @var string Config file path (without extension). | ||
14 | */ | ||
15 | protected static $configFile = 'tests/utils/config/configJson'; | ||
16 | |||
17 | /** | ||
18 | * @var ConfigManager | ||
19 | */ | ||
20 | protected $conf; | ||
21 | |||
22 | /** | ||
23 | * | ||
24 | */ | ||
25 | public function setUp() | ||
26 | { | ||
27 | $this->conf = new ConfigManager(self::$configFile); | ||
28 | } | ||
29 | |||
30 | /** | ||
31 | * Test t() with a simple non identified value. | ||
32 | */ | ||
33 | public function testTranslateSingleNotIDGettext() | ||
34 | { | ||
35 | $this->conf->set('translation.mode', 'gettext'); | ||
36 | new Languages('en', $this->conf); | ||
37 | $text = 'abcdé 564 fgK'; | ||
38 | $this->assertEquals($text, t($text)); | ||
39 | } | ||
40 | |||
41 | /** | ||
42 | * Test t() with a simple identified value in gettext mode. | ||
43 | */ | ||
44 | public function testTranslateSingleIDGettext() | ||
45 | { | ||
46 | $this->conf->set('translation.mode', 'gettext'); | ||
47 | new Languages('en', $this->conf); | ||
48 | $text = 'permalink'; | ||
49 | $this->assertEquals($text, t($text)); | ||
50 | } | ||
51 | |||
52 | /** | ||
53 | * Test t() with a non identified plural form in gettext mode. | ||
54 | */ | ||
55 | public function testTranslatePluralNotIDGettext() | ||
56 | { | ||
57 | $this->conf->set('translation.mode', 'gettext'); | ||
58 | new Languages('en', $this->conf); | ||
59 | $text = 'sandwich'; | ||
60 | $nText = 'sandwiches'; | ||
61 | $this->assertEquals('sandwiches', t($text, $nText, 0)); | ||
62 | $this->assertEquals('sandwich', t($text, $nText, 1)); | ||
63 | $this->assertEquals('sandwiches', t($text, $nText, 2)); | ||
64 | } | ||
65 | |||
66 | /** | ||
67 | * Test t() with an identified plural form in gettext mode. | ||
68 | */ | ||
69 | public function testTranslatePluralIDGettext() | ||
70 | { | ||
71 | $this->conf->set('translation.mode', 'gettext'); | ||
72 | new Languages('en', $this->conf); | ||
73 | $text = 'shaare'; | ||
74 | $nText = 'shaares'; | ||
75 | // In english, zero is followed by plural form | ||
76 | $this->assertEquals('shaares', t($text, $nText, 0)); | ||
77 | $this->assertEquals('shaare', t($text, $nText, 1)); | ||
78 | $this->assertEquals('shaares', t($text, $nText, 2)); | ||
79 | } | ||
80 | |||
81 | /** | ||
11 | * Test t() with a simple non identified value. | 82 | * Test t() with a simple non identified value. |
12 | */ | 83 | */ |
13 | public function testTranslateSingleNotID() | 84 | public function testTranslateSingleNotIDPhp() |
14 | { | 85 | { |
86 | $this->conf->set('translation.mode', 'php'); | ||
87 | new Languages('en', $this->conf); | ||
15 | $text = 'abcdé 564 fgK'; | 88 | $text = 'abcdé 564 fgK'; |
16 | $this->assertEquals($text, t($text)); | 89 | $this->assertEquals($text, t($text)); |
17 | } | 90 | } |
18 | 91 | ||
19 | /** | 92 | /** |
20 | * Test t() with a non identified plural form. | 93 | * Test t() with a simple identified value in PHP mode. |
21 | */ | 94 | */ |
22 | public function testTranslatePluralNotID() | 95 | public function testTranslateSingleIDPhp() |
23 | { | 96 | { |
24 | $text = '%s sandwich'; | 97 | $this->conf->set('translation.mode', 'php'); |
25 | $nText = '%s sandwiches'; | 98 | new Languages('en', $this->conf); |
26 | $this->assertEquals('0 sandwich', t($text, $nText)); | 99 | $text = 'permalink'; |
27 | $this->assertEquals('1 sandwich', t($text, $nText, 1)); | 100 | $this->assertEquals($text, t($text)); |
28 | $this->assertEquals('2 sandwiches', t($text, $nText, 2)); | ||
29 | } | 101 | } |
30 | 102 | ||
31 | /** | 103 | /** |
32 | * Test t() with a non identified invalid plural form. | 104 | * Test t() with a non identified plural form in PHP mode. |
33 | */ | 105 | */ |
34 | public function testTranslatePluralNotIDInvalid() | 106 | public function testTranslatePluralNotIDPhp() |
35 | { | 107 | { |
108 | $this->conf->set('translation.mode', 'php'); | ||
109 | new Languages('en', $this->conf); | ||
36 | $text = 'sandwich'; | 110 | $text = 'sandwich'; |
37 | $nText = 'sandwiches'; | 111 | $nText = 'sandwiches'; |
112 | $this->assertEquals('sandwiches', t($text, $nText, 0)); | ||
38 | $this->assertEquals('sandwich', t($text, $nText, 1)); | 113 | $this->assertEquals('sandwich', t($text, $nText, 1)); |
39 | $this->assertEquals('sandwiches', t($text, $nText, 2)); | 114 | $this->assertEquals('sandwiches', t($text, $nText, 2)); |
40 | } | 115 | } |
116 | |||
117 | /** | ||
118 | * Test t() with an identified plural form in PHP mode. | ||
119 | */ | ||
120 | public function testTranslatePluralIDPhp() | ||
121 | { | ||
122 | $this->conf->set('translation.mode', 'php'); | ||
123 | new Languages('en', $this->conf); | ||
124 | $text = 'shaare'; | ||
125 | $nText = 'shaares'; | ||
126 | // In english, zero is followed by plural form | ||
127 | $this->assertEquals('shaares', t($text, $nText, 0)); | ||
128 | $this->assertEquals('shaare', t($text, $nText, 1)); | ||
129 | $this->assertEquals('shaares', t($text, $nText, 2)); | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * Test t() with an invalid language set in the configuration in gettext mode. | ||
134 | */ | ||
135 | public function testTranslateWithInvalidConfLanguageGettext() | ||
136 | { | ||
137 | $this->conf->set('translation.mode', 'gettext'); | ||
138 | $this->conf->set('translation.language', 'nope'); | ||
139 | new Languages('fr', $this->conf); | ||
140 | $text = 'grumble'; | ||
141 | $this->assertEquals($text, t($text)); | ||
142 | } | ||
143 | |||
144 | /** | ||
145 | * Test t() with an invalid language set in the configuration in PHP mode. | ||
146 | */ | ||
147 | public function testTranslateWithInvalidConfLanguagePhp() | ||
148 | { | ||
149 | $this->conf->set('translation.mode', 'php'); | ||
150 | $this->conf->set('translation.language', 'nope'); | ||
151 | new Languages('fr', $this->conf); | ||
152 | $text = 'grumble'; | ||
153 | $this->assertEquals($text, t($text)); | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * Test t() with an invalid language set with auto language in gettext mode. | ||
158 | */ | ||
159 | public function testTranslateWithInvalidAutoLanguageGettext() | ||
160 | { | ||
161 | $this->conf->set('translation.mode', 'gettext'); | ||
162 | new Languages('nope', $this->conf); | ||
163 | $text = 'grumble'; | ||
164 | $this->assertEquals($text, t($text)); | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * Test t() with an invalid language set with auto language in PHP mode. | ||
169 | */ | ||
170 | public function testTranslateWithInvalidAutoLanguagePhp() | ||
171 | { | ||
172 | $this->conf->set('translation.mode', 'php'); | ||
173 | new Languages('nope', $this->conf); | ||
174 | $text = 'grumble'; | ||
175 | $this->assertEquals($text, t($text)); | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * Test t() with an extension language file in gettext mode | ||
180 | */ | ||
181 | public function testTranslationExtensionGettext() | ||
182 | { | ||
183 | $this->conf->set('translation.mode', 'gettext'); | ||
184 | $this->conf->set('translation.extensions.test', 'tests/utils/languages/'); | ||
185 | new Languages('en', $this->conf); | ||
186 | $this->assertEquals('car', t('car', 'car', 1, 'test')); | ||
187 | $this->assertEquals('Search', t('Search', 'Search', 1, 'test')); | ||
188 | } | ||
189 | |||
190 | /** | ||
191 | * Test t() with an extension language file in PHP mode | ||
192 | */ | ||
193 | public function testTranslationExtensionPhp() | ||
194 | { | ||
195 | $this->conf->set('translation.mode', 'php'); | ||
196 | $this->conf->set('translation.extensions.test', 'tests/utils/languages/'); | ||
197 | new Languages('en', $this->conf); | ||
198 | $this->assertEquals('car', t('car', 'car', 1, 'test')); | ||
199 | $this->assertEquals('Search', t('Search', 'Search', 1, 'test')); | ||
200 | } | ||
41 | } | 201 | } |
diff --git a/tests/UtilsTest.php b/tests/UtilsTest.php index 3d1aa653..840eaf21 100644 --- a/tests/UtilsTest.php +++ b/tests/UtilsTest.php | |||
@@ -384,18 +384,18 @@ class UtilsTest extends PHPUnit_Framework_TestCase | |||
384 | */ | 384 | */ |
385 | public function testHumanBytes() | 385 | public function testHumanBytes() |
386 | { | 386 | { |
387 | $this->assertEquals('2kiB', human_bytes(2 * 1024)); | 387 | $this->assertEquals('2'. t('kiB'), human_bytes(2 * 1024)); |
388 | $this->assertEquals('2kiB', human_bytes(strval(2 * 1024))); | 388 | $this->assertEquals('2'. t('kiB'), human_bytes(strval(2 * 1024))); |
389 | $this->assertEquals('2MiB', human_bytes(2 * (pow(1024, 2)))); | 389 | $this->assertEquals('2'. t('MiB'), human_bytes(2 * (pow(1024, 2)))); |
390 | $this->assertEquals('2MiB', human_bytes(strval(2 * (pow(1024, 2))))); | 390 | $this->assertEquals('2'. t('MiB'), human_bytes(strval(2 * (pow(1024, 2))))); |
391 | $this->assertEquals('2GiB', human_bytes(2 * (pow(1024, 3)))); | 391 | $this->assertEquals('2'. t('GiB'), human_bytes(2 * (pow(1024, 3)))); |
392 | $this->assertEquals('2GiB', human_bytes(strval(2 * (pow(1024, 3))))); | 392 | $this->assertEquals('2'. t('GiB'), human_bytes(strval(2 * (pow(1024, 3))))); |
393 | $this->assertEquals('374B', human_bytes(374)); | 393 | $this->assertEquals('374'. t('B'), human_bytes(374)); |
394 | $this->assertEquals('374B', human_bytes('374')); | 394 | $this->assertEquals('374'. t('B'), human_bytes('374')); |
395 | $this->assertEquals('232kiB', human_bytes(237481)); | 395 | $this->assertEquals('232'. t('kiB'), human_bytes(237481)); |
396 | $this->assertEquals('Unlimited', human_bytes('0')); | 396 | $this->assertEquals(t('Unlimited'), human_bytes('0')); |
397 | $this->assertEquals('Unlimited', human_bytes(0)); | 397 | $this->assertEquals(t('Unlimited'), human_bytes(0)); |
398 | $this->assertEquals('Setting not set', human_bytes('')); | 398 | $this->assertEquals(t('Setting not set'), human_bytes('')); |
399 | } | 399 | } |
400 | 400 | ||
401 | /** | 401 | /** |
@@ -403,9 +403,9 @@ class UtilsTest extends PHPUnit_Framework_TestCase | |||
403 | */ | 403 | */ |
404 | public function testGetMaxUploadSize() | 404 | public function testGetMaxUploadSize() |
405 | { | 405 | { |
406 | $this->assertEquals('1MiB', get_max_upload_size(2097152, '1024k')); | 406 | $this->assertEquals('1'. t('MiB'), get_max_upload_size(2097152, '1024k')); |
407 | $this->assertEquals('1MiB', get_max_upload_size('1m', '2m')); | 407 | $this->assertEquals('1'. t('MiB'), get_max_upload_size('1m', '2m')); |
408 | $this->assertEquals('100B', get_max_upload_size(100, 100)); | 408 | $this->assertEquals('100'. t('B'), get_max_upload_size(100, 100)); |
409 | } | 409 | } |
410 | 410 | ||
411 | /** | 411 | /** |
diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 00000000..d36d73cd --- /dev/null +++ b/tests/bootstrap.php | |||
@@ -0,0 +1,6 @@ | |||
1 | <?php | ||
2 | |||
3 | require_once 'vendor/autoload.php'; | ||
4 | |||
5 | $conf = new \Shaarli\Config\ConfigManager('tests/utils/config/configJson'); | ||
6 | new \Shaarli\Languages('en', $conf); | ||
diff --git a/tests/languages/bootstrap.php b/tests/languages/bootstrap.php index 95609210..da6ac2e4 100644 --- a/tests/languages/bootstrap.php +++ b/tests/languages/bootstrap.php | |||
@@ -1,7 +1,6 @@ | |||
1 | <?php | 1 | <?php |
2 | if (! empty('UT_LOCALE')) { | 2 | require_once 'tests/bootstrap.php'; |
3 | |||
4 | if (! empty(getenv('UT_LOCALE'))) { | ||
3 | setlocale(LC_ALL, getenv('UT_LOCALE')); | 5 | setlocale(LC_ALL, getenv('UT_LOCALE')); |
4 | } | 6 | } |
5 | |||
6 | require_once 'vendor/autoload.php'; | ||
7 | |||
diff --git a/tests/languages/fr/LanguagesFrTest.php b/tests/languages/fr/LanguagesFrTest.php new file mode 100644 index 00000000..c05a0f98 --- /dev/null +++ b/tests/languages/fr/LanguagesFrTest.php | |||
@@ -0,0 +1,173 @@ | |||
1 | <?php | ||
2 | |||
3 | |||
4 | namespace Shaarli; | ||
5 | |||
6 | |||
7 | use Shaarli\Config\ConfigManager; | ||
8 | |||
9 | /** | ||
10 | * Class LanguagesFrTest | ||
11 | * | ||
12 | * Test the translation system in PHP and gettext mode with French language. | ||
13 | * | ||
14 | * @package Shaarli | ||
15 | */ | ||
16 | class LanguagesFrTest extends \PHPUnit_Framework_TestCase | ||
17 | { | ||
18 | /** | ||
19 | * @var string Config file path (without extension). | ||
20 | */ | ||
21 | protected static $configFile = 'tests/utils/config/configJson'; | ||
22 | |||
23 | /** | ||
24 | * @var ConfigManager | ||
25 | */ | ||
26 | protected $conf; | ||
27 | |||
28 | /** | ||
29 | * Init: force French | ||
30 | */ | ||
31 | public function setUp() | ||
32 | { | ||
33 | $this->conf = new ConfigManager(self::$configFile); | ||
34 | $this->conf->set('translation.language', 'fr'); | ||
35 | } | ||
36 | |||
37 | /** | ||
38 | * Reset the locale since gettext seems to mess with it, making it too long | ||
39 | */ | ||
40 | public static function tearDownAfterClass() | ||
41 | { | ||
42 | if (! empty(getenv('UT_LOCALE'))) { | ||
43 | setlocale(LC_ALL, getenv('UT_LOCALE')); | ||
44 | } | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * Test t() with a simple non identified value. | ||
49 | */ | ||
50 | public function testTranslateSingleNotIDGettext() | ||
51 | { | ||
52 | $this->conf->set('translation.mode', 'gettext'); | ||
53 | new Languages('en', $this->conf); | ||
54 | $text = 'abcdé 564 fgK'; | ||
55 | $this->assertEquals($text, t($text)); | ||
56 | } | ||
57 | |||
58 | /** | ||
59 | * Test t() with a simple identified value in gettext mode. | ||
60 | */ | ||
61 | public function testTranslateSingleIDGettext() | ||
62 | { | ||
63 | $this->conf->set('translation.mode', 'gettext'); | ||
64 | new Languages('en', $this->conf); | ||
65 | $text = 'permalink'; | ||
66 | $this->assertEquals('permalien', t($text)); | ||
67 | } | ||
68 | |||
69 | /** | ||
70 | * Test t() with a non identified plural form in gettext mode. | ||
71 | */ | ||
72 | public function testTranslatePluralNotIDGettext() | ||
73 | { | ||
74 | $this->conf->set('translation.mode', 'gettext'); | ||
75 | new Languages('en', $this->conf); | ||
76 | $text = 'sandwich'; | ||
77 | $nText = 'sandwiches'; | ||
78 | // Not ID, so English fallback, and in english, plural 0 | ||
79 | $this->assertEquals('sandwiches', t($text, $nText, 0)); | ||
80 | $this->assertEquals('sandwich', t($text, $nText, 1)); | ||
81 | $this->assertEquals('sandwiches', t($text, $nText, 2)); | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * Test t() with an identified plural form in gettext mode. | ||
86 | */ | ||
87 | public function testTranslatePluralIDGettext() | ||
88 | { | ||
89 | $this->conf->set('translation.mode', 'gettext'); | ||
90 | new Languages('en', $this->conf); | ||
91 | $text = 'shaare'; | ||
92 | $nText = 'shaares'; | ||
93 | $this->assertEquals('shaare', t($text, $nText, 0)); | ||
94 | $this->assertEquals('shaare', t($text, $nText, 1)); | ||
95 | $this->assertEquals('shaares', t($text, $nText, 2)); | ||
96 | } | ||
97 | |||
98 | /** | ||
99 | * Test t() with a simple non identified value. | ||
100 | */ | ||
101 | public function testTranslateSingleNotIDPhp() | ||
102 | { | ||
103 | $this->conf->set('translation.mode', 'php'); | ||
104 | new Languages('en', $this->conf); | ||
105 | $text = 'abcdé 564 fgK'; | ||
106 | $this->assertEquals($text, t($text)); | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * Test t() with a simple identified value in PHP mode. | ||
111 | */ | ||
112 | public function testTranslateSingleIDPhp() | ||
113 | { | ||
114 | $this->conf->set('translation.mode', 'php'); | ||
115 | new Languages('en', $this->conf); | ||
116 | $text = 'permalink'; | ||
117 | $this->assertEquals('permalien', t($text)); | ||
118 | } | ||
119 | |||
120 | /** | ||
121 | * Test t() with a non identified plural form in PHP mode. | ||
122 | */ | ||
123 | public function testTranslatePluralNotIDPhp() | ||
124 | { | ||
125 | $this->conf->set('translation.mode', 'php'); | ||
126 | new Languages('en', $this->conf); | ||
127 | $text = 'sandwich'; | ||
128 | $nText = 'sandwiches'; | ||
129 | // Not ID, so English fallback, and in english, plural 0 | ||
130 | $this->assertEquals('sandwiches', t($text, $nText, 0)); | ||
131 | $this->assertEquals('sandwich', t($text, $nText, 1)); | ||
132 | $this->assertEquals('sandwiches', t($text, $nText, 2)); | ||
133 | } | ||
134 | |||
135 | /** | ||
136 | * Test t() with an identified plural form in PHP mode. | ||
137 | */ | ||
138 | public function testTranslatePluralIDPhp() | ||
139 | { | ||
140 | $this->conf->set('translation.mode', 'php'); | ||
141 | new Languages('en', $this->conf); | ||
142 | $text = 'shaare'; | ||
143 | $nText = 'shaares'; | ||
144 | // In english, zero is followed by plural form | ||
145 | $this->assertEquals('shaare', t($text, $nText, 0)); | ||
146 | $this->assertEquals('shaare', t($text, $nText, 1)); | ||
147 | $this->assertEquals('shaares', t($text, $nText, 2)); | ||
148 | } | ||
149 | |||
150 | /** | ||
151 | * Test t() with an extension language file in gettext mode | ||
152 | */ | ||
153 | public function testTranslationExtensionGettext() | ||
154 | { | ||
155 | $this->conf->set('translation.mode', 'gettext'); | ||
156 | $this->conf->set('translation.extensions.test', 'tests/utils/languages/'); | ||
157 | new Languages('en', $this->conf); | ||
158 | $this->assertEquals('voiture', t('car', 'car', 1, 'test')); | ||
159 | $this->assertEquals('Fouille', t('Search', 'Search', 1, 'test')); | ||
160 | } | ||
161 | |||
162 | /** | ||
163 | * Test t() with an extension language file in PHP mode | ||
164 | */ | ||
165 | public function testTranslationExtensionPhp() | ||
166 | { | ||
167 | $this->conf->set('translation.mode', 'php'); | ||
168 | $this->conf->set('translation.extensions.test', 'tests/utils/languages/'); | ||
169 | new Languages('en', $this->conf); | ||
170 | $this->assertEquals('voiture', t('car', 'car', 1, 'test')); | ||
171 | $this->assertEquals('Fouille', t('Search', 'Search', 1, 'test')); | ||
172 | } | ||
173 | } | ||
diff --git a/tests/utils/languages/fr/LC_MESSAGES/test.mo b/tests/utils/languages/fr/LC_MESSAGES/test.mo new file mode 100644 index 00000000..416c7831 --- /dev/null +++ b/tests/utils/languages/fr/LC_MESSAGES/test.mo | |||
Binary files differ | |||
diff --git a/tests/utils/languages/fr/LC_MESSAGES/test.po b/tests/utils/languages/fr/LC_MESSAGES/test.po new file mode 100644 index 00000000..89a4fd9b --- /dev/null +++ b/tests/utils/languages/fr/LC_MESSAGES/test.po | |||
@@ -0,0 +1,19 @@ | |||
1 | msgid "" | ||
2 | msgstr "" | ||
3 | "Project-Id-Version: Extension test\n" | ||
4 | "POT-Creation-Date: 2017-05-20 13:54+0200\n" | ||
5 | "PO-Revision-Date: 2017-05-20 14:16+0200\n" | ||
6 | "Last-Translator: \n" | ||
7 | "Language-Team: Shaarli\n" | ||
8 | "Language: fr_FR\n" | ||
9 | "MIME-Version: 1.0\n" | ||
10 | "Content-Type: text/plain; charset=UTF-8\n" | ||
11 | "Content-Transfer-Encoding: 8bit\n" | ||
12 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" | ||
13 | "X-Generator: Poedit 2.0.1\n" | ||
14 | |||
15 | msgid "car" | ||
16 | msgstr "voiture" | ||
17 | |||
18 | msgid "Search" | ||
19 | msgstr "Fouille" | ||
diff --git a/tpl/default/import.html b/tpl/default/import.html index 1f040685..000a50ac 100644 --- a/tpl/default/import.html +++ b/tpl/default/import.html | |||
@@ -18,7 +18,7 @@ | |||
18 | <div class="center" id="import-field"> | 18 | <div class="center" id="import-field"> |
19 | <input type="hidden" name="MAX_FILE_SIZE" value="{$maxfilesize}"> | 19 | <input type="hidden" name="MAX_FILE_SIZE" value="{$maxfilesize}"> |
20 | <input type="file" name="filetoupload"> | 20 | <input type="file" name="filetoupload"> |
21 | <p><br>Maximum size allowed: <strong>{$maxfilesizeHuman}</strong></p> | 21 | <p><br>{'Maximum size allowed:'|t} <strong>{$maxfilesizeHuman}</strong></p> |
22 | </div> | 22 | </div> |
23 | 23 | ||
24 | <div class="pure-g"> | 24 | <div class="pure-g"> |
@@ -31,15 +31,15 @@ | |||
31 | <div class="radio-buttons"> | 31 | <div class="radio-buttons"> |
32 | <div> | 32 | <div> |
33 | <input type="radio" name="privacy" value="default" checked="checked"> | 33 | <input type="radio" name="privacy" value="default" checked="checked"> |
34 | Use values from the imported file, default to public | 34 | {'Use values from the imported file, default to public'|t} |
35 | </div> | 35 | </div> |
36 | <div> | 36 | <div> |
37 | <input type="radio" name="privacy" value="private"> | 37 | <input type="radio" name="privacy" value="private"> |
38 | Import all bookmarks as private | 38 | {'Import all bookmarks as private'|t} |
39 | </div> | 39 | </div> |
40 | <div> | 40 | <div> |
41 | <input type="radio" name="privacy" value="public"> | 41 | <input type="radio" name="privacy" value="public"> |
42 | Import all bookmarks as public | 42 | {'Import all bookmarks as public'|t} |
43 | </div> | 43 | </div> |
44 | </div> | 44 | </div> |
45 | </div> | 45 | </div> |
diff --git a/tpl/default/linklist.html b/tpl/default/linklist.html index 685821e3..5dab8e9a 100644 --- a/tpl/default/linklist.html +++ b/tpl/default/linklist.html | |||
@@ -86,7 +86,7 @@ | |||
86 | <div class="pure-g pure-alert pure-alert-success search-result"> | 86 | <div class="pure-g pure-alert pure-alert-success search-result"> |
87 | <div class="pure-u-2-24"></div> | 87 | <div class="pure-u-2-24"></div> |
88 | <div class="pure-u-20-24"> | 88 | <div class="pure-u-20-24"> |
89 | {function="t('%s result', '%s results', $result_count)"} | 89 | {function="sprintf(t('%s result', '%s results', $result_count), $result_count)"} |
90 | {if="!empty($search_term)"} | 90 | {if="!empty($search_term)"} |
91 | {'for'|t} <em><strong>{$search_term}</strong></em> | 91 | {'for'|t} <em><strong>{$search_term}</strong></em> |
92 | {/if} | 92 | {/if} |
@@ -117,6 +117,16 @@ | |||
117 | <div class="pure-g"> | 117 | <div class="pure-g"> |
118 | <div class="pure-u-lg-2-24 pure-u-1-24"></div> | 118 | <div class="pure-u-lg-2-24 pure-u-1-24"></div> |
119 | <div class="pure-u-lg-20-24 pure-u-22-24"> | 119 | <div class="pure-u-lg-20-24 pure-u-22-24"> |
120 | {ignore}Set translation here, for performances{/ignore} | ||
121 | {$strPrivate=t('Private')} | ||
122 | {$strEdit=t('Edit')} | ||
123 | {$strDelete=t('Delete')} | ||
124 | {$strFold=t('Fold')} | ||
125 | {$strEdited=t('Edited: ')} | ||
126 | {$strPermalink=t('Permalink')} | ||
127 | {$strPermalinkLc=t('permalink')} | ||
128 | {$strAddTag=t('Add tag')} | ||
129 | {ignore}End of translations{/ignore} | ||
120 | {loop="links"} | 130 | {loop="links"} |
121 | <div class="anchor" id="{$value.shorturl}"></div> | 131 | <div class="anchor" id="{$value.shorturl}"></div> |
122 | <div class="linklist-item linklist-item{if="$value.class"} {$value.class}{/if}" data-id="{$value.id}"> | 132 | <div class="linklist-item linklist-item{if="$value.class"} {$value.class}{/if}" data-id="{$value.id}"> |
@@ -125,12 +135,12 @@ | |||
125 | {if="isLoggedIn()"} | 135 | {if="isLoggedIn()"} |
126 | <div class="linklist-item-editbuttons"> | 136 | <div class="linklist-item-editbuttons"> |
127 | {if="$value.private"} | 137 | {if="$value.private"} |
128 | <span class="label label-private">{'Private'|t}</span> | 138 | <span class="label label-private">{$strPrivate}</span> |
129 | {/if} | 139 | {/if} |
130 | <input type="checkbox" class="delete-checkbox" value="{$value.id}"> | 140 | <input type="checkbox" class="delete-checkbox" value="{$value.id}"> |
131 | <!-- FIXME! JS translation --> | 141 | <!-- FIXME! JS translation --> |
132 | <a href="?edit_link={$value.id}" title="{'Edit'|t}"><i class="fa fa-pencil-square-o edit-link"></i></a> | 142 | <a href="?edit_link={$value.id}" title="{$strEdit}"><i class="fa fa-pencil-square-o edit-link"></i></a> |
133 | <a href="#" title="{'Fold'|t}" class="fold-button"><i class="fa fa-chevron-up"></i></a> | 143 | <a href="#" title="{$strFold}" class="fold-button"><i class="fa fa-chevron-up"></i></a> |
134 | </div> | 144 | </div> |
135 | {/if} | 145 | {/if} |
136 | 146 | ||
@@ -164,7 +174,7 @@ | |||
164 | <i class="fa fa-tags"></i> | 174 | <i class="fa fa-tags"></i> |
165 | {$tag_counter=count($value.taglist)} | 175 | {$tag_counter=count($value.taglist)} |
166 | {loop="value.taglist"} | 176 | {loop="value.taglist"} |
167 | <span class="label label-tag" title="Add tag"> | 177 | <span class="label label-tag" title="{$strAddTag}"> |
168 | <a href="?addtag={$value|urlencode}">{$value}</a> | 178 | <a href="?addtag={$value|urlencode}">{$value}</a> |
169 | </span> | 179 | </span> |
170 | {if="$tag_counter - 1 != $counter"}·{/if} | 180 | {if="$tag_counter - 1 != $counter"}·{/if} |
@@ -174,9 +184,9 @@ | |||
174 | 184 | ||
175 | <div class="pure-g"> | 185 | <div class="pure-g"> |
176 | <div class="linklist-item-infos-dateblock pure-u-lg-3-8 pure-u-1"> | 186 | <div class="linklist-item-infos-dateblock pure-u-lg-3-8 pure-u-1"> |
177 | <a href="?{$value.shorturl}" title="{'Permalink'|t}"> | 187 | <a href="?{$value.shorturl}" title="{$strPermalink}"> |
178 | {if="!$hide_timestamps || isLoggedIn()"} | 188 | {if="!$hide_timestamps || isLoggedIn()"} |
179 | {$updated=$value.updated_timestamp ? 'Edited: '. format_date($value.updated) : 'Permalink'} | 189 | {$updated=$value.updated_timestamp ? $strEdited. format_date($value.updated) : $strPermalink} |
180 | <span class="linkdate" title="{$updated}"> | 190 | <span class="linkdate" title="{$updated}"> |
181 | <i class="fa fa-clock-o"></i> | 191 | <i class="fa fa-clock-o"></i> |
182 | {$value.created|format_date} | 192 | {$value.created|format_date} |
@@ -184,7 +194,7 @@ | |||
184 | · | 194 | · |
185 | </span> | 195 | </span> |
186 | {/if} | 196 | {/if} |
187 | {'permalink'|t} | 197 | {$strPermalinkLc} |
188 | </a> | 198 | </a> |
189 | 199 | ||
190 | <div class="pure-u-0 pure-u-lg-visible"> | 200 | <div class="pure-u-0 pure-u-lg-visible"> |
@@ -205,7 +215,7 @@ | |||
205 | </a> | 215 | </a> |
206 | {if="isLoggedIn()"} | 216 | {if="isLoggedIn()"} |
207 | <a href="?delete_link&lf_linkdate={$value.id}&token={$token}" | 217 | <a href="?delete_link&lf_linkdate={$value.id}&token={$token}" |
208 | title="{'Delete'|t}" class="delete-link pure-u-0 pure-u-lg-visible confirm-delete"> | 218 | title="{$strDelete}" class="delete-link pure-u-0 pure-u-lg-visible confirm-delete"> |
209 | <i class="fa fa-trash"></i> | 219 | <i class="fa fa-trash"></i> |
210 | </a> | 220 | </a> |
211 | {/if} | 221 | {/if} |
@@ -221,7 +231,7 @@ | |||
221 | {if="isLoggedIn()"} | 231 | {if="isLoggedIn()"} |
222 | · | 232 | · |
223 | <a href="?delete_link&lf_linkdate={$value.id}&token={$token}" | 233 | <a href="?delete_link&lf_linkdate={$value.id}&token={$token}" |
224 | title="{'Delete'|t}" class="delete-link confirm-delete"> | 234 | title="{$strDelete}" class="delete-link confirm-delete"> |
225 | <i class="fa fa-trash"></i> | 235 | <i class="fa fa-trash"></i> |
226 | </a> | 236 | </a> |
227 | {/if} | 237 | {/if} |
diff --git a/tpl/default/page.footer.html b/tpl/default/page.footer.html index 54b16e8a..2c788e2f 100644 --- a/tpl/default/page.footer.html +++ b/tpl/default/page.footer.html | |||
@@ -8,8 +8,8 @@ | |||
8 | {$version} | 8 | {$version} |
9 | {/if} | 9 | {/if} |
10 | · | 10 | · |
11 | The personal, minimalist, super-fast, database free, bookmarking service by the Shaarli community · | 11 | {'The personal, minimalist, super-fast, database free, bookmarking service'|t} {'by the Shaarli community'|t} · |
12 | <a href="doc/html/index.html" rel="nofollow">Documentation</a> | 12 | <a href="doc/html/index.html" rel="nofollow">{'Documentation'|t}</a> |
13 | {loop="$plugins_footer.text"} | 13 | {loop="$plugins_footer.text"} |
14 | {$value} | 14 | {$value} |
15 | {/loop} | 15 | {/loop} |
diff --git a/tpl/default/pluginsadmin.html b/tpl/default/pluginsadmin.html index 5cc1802f..717cb517 100644 --- a/tpl/default/pluginsadmin.html +++ b/tpl/default/pluginsadmin.html | |||
@@ -116,8 +116,8 @@ | |||
116 | </section> | 116 | </section> |
117 | 117 | ||
118 | <div class="center more"> | 118 | <div class="center more"> |
119 | More plugins available | 119 | {"More plugins available"|t} |
120 | <a href="doc/Community-&-Related-software.html#third-party-plugins">in the documentation</a>. | 120 | <a href="doc/Community-&-Related-software.html#third-party-plugins">{"in the documentation"|t}</a>. |
121 | </div> | 121 | </div> |
122 | <div class="center"> | 122 | <div class="center"> |
123 | <input type="submit" value="{'Save'|t}" name="save"> | 123 | <input type="submit" value="{'Save'|t}" name="save"> |