diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | CHANGELOG.md | 5 | ||||
-rw-r--r-- | COPYING | 2 | ||||
-rw-r--r-- | application/ApplicationUtils.php | 20 | ||||
-rw-r--r-- | application/PageBuilder.php | 2 | ||||
-rw-r--r-- | application/Utils.php | 10 | ||||
-rw-r--r-- | images/squiggle.png | bin | 684 -> 0 bytes | |||
-rw-r--r-- | index.php | 4 | ||||
-rw-r--r-- | tests/ApplicationUtilsTest.php | 44 | ||||
-rw-r--r-- | tests/Updater/UpdaterTest.php | 1 | ||||
-rw-r--r-- | tests/utils/config/configJson.json.php | 3 | ||||
-rw-r--r-- | tpl/default/configure.html | 13 | ||||
-rw-r--r-- | tpl/default/css/reset.css (renamed from tpl/default/inc/reset.css) | 0 | ||||
-rw-r--r-- | tpl/default/css/shaarli.css (renamed from tpl/default/inc/shaarli.css) | 0 | ||||
-rw-r--r-- | tpl/default/daily.html | 8 | ||||
-rw-r--r-- | tpl/default/images/floral_left.png (renamed from images/floral_left.png) | bin | 1284 -> 1284 bytes | |||
-rw-r--r-- | tpl/default/images/floral_right.png (renamed from images/floral_right.png) | bin | 1309 -> 1309 bytes | |||
-rw-r--r-- | tpl/default/images/squiggle.png (renamed from images/squiggle2.png) | bin | 720 -> 720 bytes | |||
-rw-r--r-- | tpl/default/images/squiggle_closing.png (renamed from images/squiggle_closing.png) | bin | 1244 -> 1244 bytes | |||
-rw-r--r-- | tpl/default/includes.html | 4 |
20 files changed, 92 insertions, 28 deletions
@@ -28,3 +28,7 @@ phpmd.html | |||
28 | 28 | ||
29 | # User plugin configuration | 29 | # User plugin configuration |
30 | plugins/*/config.php | 30 | plugins/*/config.php |
31 | |||
32 | # 3rd party themes | ||
33 | tpl/* | ||
34 | !tpl/default | ||
diff --git a/CHANGELOG.md b/CHANGELOG.md index fe775b3e..d3ecc1e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md | |||
@@ -7,14 +7,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/). | |||
7 | 7 | ||
8 | ## [v0.9.0](https://github.com/shaarli/Shaarli/releases/tag/v0.9.0) - UNPUBLISHED | 8 | ## [v0.9.0](https://github.com/shaarli/Shaarli/releases/tag/v0.9.0) - UNPUBLISHED |
9 | 9 | ||
10 | **WARNING**: Shaarli now requires PHP 5.5+. | 10 | **WARNING**: Shaarli now requires PHP 5.5+. |
11 | 11 | ||
12 | ### Added | 12 | ### Added |
13 | 13 | ||
14 | - REST API: see [Shaarli API documentation](http://shaarli.github.io/api-documentation/) | 14 | - REST API: see [Shaarli API documentation](http://shaarli.github.io/api-documentation/) |
15 | - The theme can now be selected in the administration page. | ||
15 | 16 | ||
16 | ### Changed | 17 | ### Changed |
17 | 18 | ||
19 | - Default template files are moved to a subfolder (`default`). | ||
20 | |||
18 | ### Fixed | 21 | ### Fixed |
19 | 22 | ||
20 | 23 | ||
@@ -43,7 +43,7 @@ License: CC-BY (http://creativecommons.org/licenses/by/3.0/) | |||
43 | Copyright: (c) 2014 Designmodo | 43 | Copyright: (c) 2014 Designmodo |
44 | Source: http://designmodo.com/linecons-free/ | 44 | Source: http://designmodo.com/linecons-free/ |
45 | 45 | ||
46 | Files: images/floral_left.png, images/floral_right.png, images/squiggle.png, images/squiggle2.png, images/squiggle_closing.png | 46 | Files: images/floral_left.png, images/floral_right.png, images/squiggle.png, images/squiggle_closing.png |
47 | Licence: Public Domain | 47 | Licence: Public Domain |
48 | Source: https://openclipart.org/people/j4p4n/j4p4n_ornimental_bookend_-_left.svg | 48 | Source: https://openclipart.org/people/j4p4n/j4p4n_ornimental_bookend_-_left.svg |
49 | 49 | ||
diff --git a/application/ApplicationUtils.php b/application/ApplicationUtils.php index a0f482b0..cc009a1d 100644 --- a/application/ApplicationUtils.php +++ b/application/ApplicationUtils.php | |||
@@ -195,4 +195,24 @@ class ApplicationUtils | |||
195 | 195 | ||
196 | return $errors; | 196 | return $errors; |
197 | } | 197 | } |
198 | |||
199 | /** | ||
200 | * Get a list of available themes. | ||
201 | * | ||
202 | * It will return the name of any directory present in the template folder. | ||
203 | * | ||
204 | * @param string $tplDir Templates main directory. | ||
205 | * | ||
206 | * @return array List of theme names. | ||
207 | */ | ||
208 | public static function getThemes($tplDir) | ||
209 | { | ||
210 | $allTheme = glob($tplDir.'/*', GLOB_ONLYDIR); | ||
211 | $themes = []; | ||
212 | foreach ($allTheme as $value) { | ||
213 | $themes[] = str_replace($tplDir.'/', '', $value); | ||
214 | } | ||
215 | |||
216 | return $themes; | ||
217 | } | ||
198 | } | 218 | } |
diff --git a/application/PageBuilder.php b/application/PageBuilder.php index e226a77d..32c7f9f1 100644 --- a/application/PageBuilder.php +++ b/application/PageBuilder.php | |||
@@ -79,7 +79,7 @@ class PageBuilder | |||
79 | $this->tpl->assign('hide_timestamps', $this->conf->get('privacy.hide_timestamps', false)); | 79 | $this->tpl->assign('hide_timestamps', $this->conf->get('privacy.hide_timestamps', false)); |
80 | $this->tpl->assign('token', getToken($this->conf)); | 80 | $this->tpl->assign('token', getToken($this->conf)); |
81 | // To be removed with a proper theme configuration. | 81 | // To be removed with a proper theme configuration. |
82 | $this->tpl->assign('theme', $this->conf->get('resource.theme', 'default')); | 82 | $this->tpl->assign('conf', $this->conf); |
83 | } | 83 | } |
84 | 84 | ||
85 | /** | 85 | /** |
diff --git a/application/Utils.php b/application/Utils.php index 7556d3c9..35d65224 100644 --- a/application/Utils.php +++ b/application/Utils.php | |||
@@ -270,13 +270,3 @@ function normalize_spaces($string) | |||
270 | { | 270 | { |
271 | return preg_replace('/\s{2,}/', ' ', trim($string)); | 271 | return preg_replace('/\s{2,}/', ' ', trim($string)); |
272 | } | 272 | } |
273 | |||
274 | function getAllTheme($raintpl_tpl) | ||
275 | { | ||
276 | $allTheme = glob($raintpl_tpl.'/*', GLOB_ONLYDIR); | ||
277 | foreach ($allTheme as $value) { | ||
278 | $themes[] = str_replace($raintpl_tpl.'/', '', $value); | ||
279 | } | ||
280 | |||
281 | return $themes; | ||
282 | } | ||
diff --git a/images/squiggle.png b/images/squiggle.png deleted file mode 100644 index a6ce218c..00000000 --- a/images/squiggle.png +++ /dev/null | |||
Binary files differ | |||
@@ -79,6 +79,7 @@ require_once 'application/Utils.php'; | |||
79 | require_once 'application/PluginManager.php'; | 79 | require_once 'application/PluginManager.php'; |
80 | require_once 'application/Router.php'; | 80 | require_once 'application/Router.php'; |
81 | require_once 'application/Updater.php'; | 81 | require_once 'application/Updater.php'; |
82 | use \Shaarli\ThemeUtils; | ||
82 | 83 | ||
83 | // Ensure the PHP version is supported | 84 | // Ensure the PHP version is supported |
84 | try { | 85 | try { |
@@ -122,7 +123,6 @@ if (isset($_COOKIE['shaarli']) && !is_session_id_valid($_COOKIE['shaarli'])) { | |||
122 | $conf = new ConfigManager(); | 123 | $conf = new ConfigManager(); |
123 | $conf->setEmpty('general.timezone', date_default_timezone_get()); | 124 | $conf->setEmpty('general.timezone', date_default_timezone_get()); |
124 | $conf->setEmpty('general.title', 'Shared links on '. escape(index_url($_SERVER))); | 125 | $conf->setEmpty('general.title', 'Shared links on '. escape(index_url($_SERVER))); |
125 | $conf->setEmpty('resource.theme', 'default'); | ||
126 | RainTPL::$tpl_dir = $conf->get('resource.raintpl_tpl').'/'.$conf->get('resource.theme').'/'; // template directory | 126 | 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 | 127 | RainTPL::$cache_dir = $conf->get('resource.raintpl_tmp'); // cache directory |
128 | 128 | ||
@@ -1155,7 +1155,7 @@ function renderPage($conf, $pluginManager, $LINKSDB) | |||
1155 | { | 1155 | { |
1156 | $PAGE->assign('title', $conf->get('general.title')); | 1156 | $PAGE->assign('title', $conf->get('general.title')); |
1157 | $PAGE->assign('theme', $conf->get('resource.theme')); | 1157 | $PAGE->assign('theme', $conf->get('resource.theme')); |
1158 | $PAGE->assign('theme_available', getAllTheme($conf->get('resource.raintpl_tpl'))); | 1158 | $PAGE->assign('theme_available', ThemeUtils::getThemes($conf->get('resource.raintpl_tpl'))); |
1159 | $PAGE->assign('redirector', $conf->get('redirector.url')); | 1159 | $PAGE->assign('redirector', $conf->get('redirector.url')); |
1160 | list($timezone_form, $timezone_js) = generateTimeZoneForm($conf->get('general.timezone')); | 1160 | list($timezone_form, $timezone_js) = generateTimeZoneForm($conf->get('general.timezone')); |
1161 | $PAGE->assign('timezone_form', $timezone_form); | 1161 | $PAGE->assign('timezone_form', $timezone_form); |
diff --git a/tests/ApplicationUtilsTest.php b/tests/ApplicationUtilsTest.php index 634bd0ed..c39649e8 100644 --- a/tests/ApplicationUtilsTest.php +++ b/tests/ApplicationUtilsTest.php | |||
@@ -331,4 +331,48 @@ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase | |||
331 | ApplicationUtils::checkResourcePermissions($conf) | 331 | ApplicationUtils::checkResourcePermissions($conf) |
332 | ); | 332 | ); |
333 | } | 333 | } |
334 | |||
335 | /** | ||
336 | * Test getThemes() with existing theme directories. | ||
337 | */ | ||
338 | public function testGetThemes() | ||
339 | { | ||
340 | $themes = ['theme1', 'default', 'Bl1p_- bL0p']; | ||
341 | foreach ($themes as $theme) { | ||
342 | mkdir('sandbox/tpl/'. $theme, 0777, true); | ||
343 | } | ||
344 | |||
345 | // include a file which should be ignored | ||
346 | touch('sandbox/tpl/supertheme'); | ||
347 | |||
348 | $res = ApplicationUtils::getThemes('sandbox/tpl/'); | ||
349 | foreach ($res as $theme) { | ||
350 | $this->assertTrue(in_array($theme, $themes)); | ||
351 | } | ||
352 | $this->assertFalse(in_array('supertheme', $res)); | ||
353 | |||
354 | foreach ($themes as $theme) { | ||
355 | rmdir('sandbox/tpl/'. $theme); | ||
356 | } | ||
357 | unlink('sandbox/tpl/supertheme'); | ||
358 | rmdir('sandbox/tpl'); | ||
359 | } | ||
360 | |||
361 | /** | ||
362 | * Test getThemes() without any theme dir. | ||
363 | */ | ||
364 | public function testGetThemesEmpty() | ||
365 | { | ||
366 | mkdir('sandbox/tpl/', 0777, true); | ||
367 | $this->assertEquals([], ApplicationUtils::getThemes('sandbox/tpl/')); | ||
368 | rmdir('sandbox/tpl/'); | ||
369 | } | ||
370 | |||
371 | /** | ||
372 | * Test getThemes() with an invalid path. | ||
373 | */ | ||
374 | public function testGetThemesInvalid() | ||
375 | { | ||
376 | $this->assertEquals([], ApplicationUtils::getThemes('nope')); | ||
377 | } | ||
334 | } | 378 | } |
diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php index 0171daad..a1530996 100644 --- a/tests/Updater/UpdaterTest.php +++ b/tests/Updater/UpdaterTest.php | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | require_once 'application/config/ConfigManager.php'; | 3 | require_once 'application/config/ConfigManager.php'; |
4 | require_once 'tests/Updater/DummyUpdater.php'; | 4 | require_once 'tests/Updater/DummyUpdater.php'; |
5 | require_once 'inc/rain.tpl.class.php'; | ||
5 | 6 | ||
6 | /** | 7 | /** |
7 | * Class UpdaterTest. | 8 | * Class UpdaterTest. |
diff --git a/tests/utils/config/configJson.json.php b/tests/utils/config/configJson.json.php index 06a302e8..13d38c66 100644 --- a/tests/utils/config/configJson.json.php +++ b/tests/utils/config/configJson.json.php | |||
@@ -24,7 +24,8 @@ | |||
24 | }, | 24 | }, |
25 | "resource": { | 25 | "resource": { |
26 | "datastore": "tests\/utils\/config\/datastore.php", | 26 | "datastore": "tests\/utils\/config\/datastore.php", |
27 | "data_dir": "tests\/utils\/config" | 27 | "data_dir": "tests\/utils\/config", |
28 | "raintpl_tpl": "tpl/" | ||
28 | }, | 29 | }, |
29 | "plugins": { | 30 | "plugins": { |
30 | "WALLABAG_VERSION": 1 | 31 | "WALLABAG_VERSION": 1 |
diff --git a/tpl/default/configure.html b/tpl/default/configure.html index 94f6df69..e71133b4 100644 --- a/tpl/default/configure.html +++ b/tpl/default/configure.html | |||
@@ -25,14 +25,15 @@ | |||
25 | <td> | 25 | <td> |
26 | <select name="theme" id="theme"> | 26 | <select name="theme" id="theme"> |
27 | {loop="$theme_available"} | 27 | {loop="$theme_available"} |
28 | {if="$value===$theme"} | 28 | <option value="{$value}" |
29 | <option selected value="{$value}">{$value|ucfirst}</option> | 29 | {if="$value===$theme"} |
30 | {else} | 30 | selected="selected" |
31 | <option value="{$value}">{$value|ucfirst}</option> | 31 | {/if} |
32 | {/if} | 32 | > |
33 | {$value|ucfirst} | ||
34 | </option> | ||
33 | {/loop} | 35 | {/loop} |
34 | </select> | 36 | </select> |
35 | <label for="theme">(default value is: Default)</label> | ||
36 | </td> | 37 | </td> |
37 | </tr> | 38 | </tr> |
38 | 39 | ||
diff --git a/tpl/default/inc/reset.css b/tpl/default/css/reset.css index e29699e2..e29699e2 100644 --- a/tpl/default/inc/reset.css +++ b/tpl/default/css/reset.css | |||
diff --git a/tpl/default/inc/shaarli.css b/tpl/default/css/shaarli.css index 45890f62..45890f62 100644 --- a/tpl/default/inc/shaarli.css +++ b/tpl/default/css/shaarli.css | |||
diff --git a/tpl/default/daily.html b/tpl/default/daily.html index 024ee32e..e86e90b1 100644 --- a/tpl/default/daily.html +++ b/tpl/default/daily.html | |||
@@ -28,9 +28,9 @@ | |||
28 | </div> | 28 | </div> |
29 | 29 | ||
30 | <div class="dailyTitle"> | 30 | <div class="dailyTitle"> |
31 | <img src="../../images/floral_left.png" width="51" height="50" class="nomobile" alt="floral_left"> | 31 | <img src="images/floral_left.png" width="51" height="50" class="nomobile" alt="floral_left"> |
32 | The Daily Shaarli | 32 | The Daily Shaarli |
33 | <img src="../../images/floral_right.png" width="51" height="50" class="nomobile" alt="floral_right"> | 33 | <img src="images/floral_right.png" width="51" height="50" class="nomobile" alt="floral_right"> |
34 | </div> | 34 | </div> |
35 | 35 | ||
36 | <div class="dailyDate"> | 36 | <div class="dailyDate"> |
@@ -50,7 +50,7 @@ | |||
50 | <div class="dailyEntry"> | 50 | <div class="dailyEntry"> |
51 | <div class="dailyEntryPermalink"> | 51 | <div class="dailyEntryPermalink"> |
52 | <a href="?{$value.shorturl}"> | 52 | <a href="?{$value.shorturl}"> |
53 | <img src="../../images/squiggle2.png" width="25" height="26" title="permalink" alt="permalink"> | 53 | <img src="images/squiggle.png" width="25" height="26" title="permalink" alt="permalink"> |
54 | </a> | 54 | </a> |
55 | </div> | 55 | </div> |
56 | {if="!$hide_timestamps || isLoggedIn()"} | 56 | {if="!$hide_timestamps || isLoggedIn()"} |
@@ -94,7 +94,7 @@ | |||
94 | {$value} | 94 | {$value} |
95 | {/loop} | 95 | {/loop} |
96 | </div> | 96 | </div> |
97 | <div id="closing"><img src="../../images/squiggle_closing.png" width="66" height="61" alt="-"></div> | 97 | <div id="closing"><img src="images/squiggle_closing.png" width="66" height="61" alt="-"></div> |
98 | </div> | 98 | </div> |
99 | {include="page.footer"} | 99 | {include="page.footer"} |
100 | </body> | 100 | </body> |
diff --git a/images/floral_left.png b/tpl/default/images/floral_left.png index f09a861d..f09a861d 100644 --- a/images/floral_left.png +++ b/tpl/default/images/floral_left.png | |||
Binary files differ | |||
diff --git a/images/floral_right.png b/tpl/default/images/floral_right.png index 0dfb6112..0dfb6112 100644 --- a/images/floral_right.png +++ b/tpl/default/images/floral_right.png | |||
Binary files differ | |||
diff --git a/images/squiggle2.png b/tpl/default/images/squiggle.png index c795f0a3..c795f0a3 100644 --- a/images/squiggle2.png +++ b/tpl/default/images/squiggle.png | |||
Binary files differ | |||
diff --git a/images/squiggle_closing.png b/tpl/default/images/squiggle_closing.png index 3f9d02b1..3f9d02b1 100644 --- a/images/squiggle_closing.png +++ b/tpl/default/images/squiggle_closing.png | |||
Binary files differ | |||
diff --git a/tpl/default/includes.html b/tpl/default/includes.html index 2ff5d8df..c3b837f5 100644 --- a/tpl/default/includes.html +++ b/tpl/default/includes.html | |||
@@ -6,8 +6,8 @@ | |||
6 | <link rel="alternate" type="application/rss+xml" href="{$feedurl}?do=rss{$searchcrits}#" title="RSS Feed" /> | 6 | <link rel="alternate" type="application/rss+xml" href="{$feedurl}?do=rss{$searchcrits}#" title="RSS Feed" /> |
7 | <link rel="alternate" type="application/atom+xml" href="{$feedurl}?do=atom{$searchcrits}#" title="ATOM Feed" /> | 7 | <link rel="alternate" type="application/atom+xml" href="{$feedurl}?do=atom{$searchcrits}#" title="ATOM Feed" /> |
8 | <link href="images/favicon.ico#" rel="shortcut icon" type="image/x-icon" /> | 8 | <link href="images/favicon.ico#" rel="shortcut icon" type="image/x-icon" /> |
9 | <link type="text/css" rel="stylesheet" href="inc/reset.css" /> | 9 | <link type="text/css" rel="stylesheet" href="css/reset.css" /> |
10 | <link type="text/css" rel="stylesheet" href="inc/shaarli.css" /> | 10 | <link type="text/css" rel="stylesheet" href="css/shaarli.css" /> |
11 | {if="is_file('inc/user.css')"}<link type="text/css" rel="stylesheet" href="inc/user.css#" />{/if} | 11 | {if="is_file('inc/user.css')"}<link type="text/css" rel="stylesheet" href="inc/user.css#" />{/if} |
12 | {loop="$plugins_includes.css_files"} | 12 | {loop="$plugins_includes.css_files"} |
13 | <link type="text/css" rel="stylesheet" href="{$value}#"/> | 13 | <link type="text/css" rel="stylesheet" href="{$value}#"/> |