Merge pull request #732 from ArthurHoaro/feature/theme-manager
Theme manager: improvements
4
.gitignore
vendored
|
@ -28,3 +28,7 @@ phpmd.html
|
||||||
|
|
||||||
# User plugin configuration
|
# User plugin configuration
|
||||||
plugins/*/config.php
|
plugins/*/config.php
|
||||||
|
|
||||||
|
# 3rd party themes
|
||||||
|
tpl/*
|
||||||
|
!tpl/default
|
||||||
|
|
|
@ -12,9 +12,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- REST API: see [Shaarli API documentation](http://shaarli.github.io/api-documentation/)
|
- REST API: see [Shaarli API documentation](http://shaarli.github.io/api-documentation/)
|
||||||
|
- The theme can now be selected in the administration page.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- Default template files are moved to a subfolder (`default`).
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
||||||
|
|
2
COPYING
|
@ -43,7 +43,7 @@ License: CC-BY (http://creativecommons.org/licenses/by/3.0/)
|
||||||
Copyright: (c) 2014 Designmodo
|
Copyright: (c) 2014 Designmodo
|
||||||
Source: http://designmodo.com/linecons-free/
|
Source: http://designmodo.com/linecons-free/
|
||||||
|
|
||||||
Files: images/floral_left.png, images/floral_right.png, images/squiggle.png, images/squiggle2.png, images/squiggle_closing.png
|
Files: images/floral_left.png, images/floral_right.png, images/squiggle.png, images/squiggle_closing.png
|
||||||
Licence: Public Domain
|
Licence: Public Domain
|
||||||
Source: https://openclipart.org/people/j4p4n/j4p4n_ornimental_bookend_-_left.svg
|
Source: https://openclipart.org/people/j4p4n/j4p4n_ornimental_bookend_-_left.svg
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,7 @@ public static function checkResourcePermissions($conf)
|
||||||
'inc',
|
'inc',
|
||||||
'plugins',
|
'plugins',
|
||||||
$conf->get('resource.raintpl_tpl'),
|
$conf->get('resource.raintpl_tpl'),
|
||||||
|
$conf->get('resource.raintpl_tpl').'/'.$conf->get('resource.theme'),
|
||||||
) as $path) {
|
) as $path) {
|
||||||
if (! is_readable(realpath($path))) {
|
if (! is_readable(realpath($path))) {
|
||||||
$errors[] = '"'.$path.'" directory is not readable';
|
$errors[] = '"'.$path.'" directory is not readable';
|
||||||
|
|
33
application/ThemeUtils.php
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Shaarli;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ThemeUtils
|
||||||
|
*
|
||||||
|
* Utility functions related to theme management.
|
||||||
|
*
|
||||||
|
* @package Shaarli
|
||||||
|
*/
|
||||||
|
class ThemeUtils
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get a list of available themes.
|
||||||
|
*
|
||||||
|
* It will return the name of any directory present in the template folder.
|
||||||
|
*
|
||||||
|
* @param string $tplDir Templates main directory.
|
||||||
|
*
|
||||||
|
* @return array List of theme names.
|
||||||
|
*/
|
||||||
|
public static function getThemes($tplDir)
|
||||||
|
{
|
||||||
|
$allTheme = glob($tplDir.'/*', GLOB_ONLYDIR);
|
||||||
|
$themes = [];
|
||||||
|
foreach ($allTheme as $value) {
|
||||||
|
$themes[] = str_replace($tplDir.'/', '', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $themes;
|
||||||
|
}
|
||||||
|
}
|
|
@ -279,6 +279,35 @@ public function updateMethodApiSettings()
|
||||||
$this->conf->write($this->isLoggedIn);
|
$this->conf->write($this->isLoggedIn);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New setting: theme name. If the default theme is used, nothing to do.
|
||||||
|
*
|
||||||
|
* If the user uses a custom theme, raintpl_tpl dir is updated to the parent directory,
|
||||||
|
* and the current theme is set as default in the theme setting.
|
||||||
|
*
|
||||||
|
* @return bool true if the update is successful, false otherwise.
|
||||||
|
*/
|
||||||
|
public function updateMethodDefaultTheme()
|
||||||
|
{
|
||||||
|
// raintpl_tpl isn't the root template directory anymore.
|
||||||
|
// We run the update only if this folder still contains the template files.
|
||||||
|
$tplDir = $this->conf->get('resource.raintpl_tpl');
|
||||||
|
$tplFile = $tplDir . '/linklist.html';
|
||||||
|
if (! file_exists($tplFile)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parent = dirname($tplDir);
|
||||||
|
$this->conf->set('resource.raintpl_tpl', $parent);
|
||||||
|
$this->conf->set('resource.theme', trim(str_replace($parent, '', $tplDir), '/'));
|
||||||
|
$this->conf->write($this->isLoggedIn);
|
||||||
|
|
||||||
|
// Dependency injection gore
|
||||||
|
RainTPL::$tpl_dir = $tplDir;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -299,6 +299,7 @@ protected function setDefaultValues()
|
||||||
$this->setEmpty('resource.log', 'data/log.txt');
|
$this->setEmpty('resource.log', 'data/log.txt');
|
||||||
$this->setEmpty('resource.update_check', 'data/lastupdatecheck.txt');
|
$this->setEmpty('resource.update_check', 'data/lastupdatecheck.txt');
|
||||||
$this->setEmpty('resource.raintpl_tpl', 'tpl/');
|
$this->setEmpty('resource.raintpl_tpl', 'tpl/');
|
||||||
|
$this->setEmpty('resource.theme', 'default');
|
||||||
$this->setEmpty('resource.raintpl_tmp', 'tmp/');
|
$this->setEmpty('resource.raintpl_tmp', 'tmp/');
|
||||||
$this->setEmpty('resource.thumbnails_cache', 'cache');
|
$this->setEmpty('resource.thumbnails_cache', 'cache');
|
||||||
$this->setEmpty('resource.page_cache', 'pagecache');
|
$this->setEmpty('resource.page_cache', 'pagecache');
|
||||||
|
|
|
@ -41,6 +41,7 @@ class ConfigPhp implements ConfigIO
|
||||||
'resource.log' => 'config.LOG_FILE',
|
'resource.log' => 'config.LOG_FILE',
|
||||||
'resource.update_check' => 'config.UPDATECHECK_FILENAME',
|
'resource.update_check' => 'config.UPDATECHECK_FILENAME',
|
||||||
'resource.raintpl_tpl' => 'config.RAINTPL_TPL',
|
'resource.raintpl_tpl' => 'config.RAINTPL_TPL',
|
||||||
|
'resource.theme' => 'config.theme',
|
||||||
'resource.raintpl_tmp' => 'config.RAINTPL_TMP',
|
'resource.raintpl_tmp' => 'config.RAINTPL_TMP',
|
||||||
'resource.thumbnails_cache' => 'config.CACHEDIR',
|
'resource.thumbnails_cache' => 'config.CACHEDIR',
|
||||||
'resource.page_cache' => 'config.PAGECACHE',
|
'resource.page_cache' => 'config.PAGECACHE',
|
||||||
|
|
Before Width: | Height: | Size: 684 B |
|
@ -79,6 +79,7 @@
|
||||||
require_once 'application/PluginManager.php';
|
require_once 'application/PluginManager.php';
|
||||||
require_once 'application/Router.php';
|
require_once 'application/Router.php';
|
||||||
require_once 'application/Updater.php';
|
require_once 'application/Updater.php';
|
||||||
|
use \Shaarli\ThemeUtils;
|
||||||
|
|
||||||
// Ensure the PHP version is supported
|
// Ensure the PHP version is supported
|
||||||
try {
|
try {
|
||||||
|
@ -122,7 +123,7 @@
|
||||||
$conf = new ConfigManager();
|
$conf = new ConfigManager();
|
||||||
$conf->setEmpty('general.timezone', date_default_timezone_get());
|
$conf->setEmpty('general.timezone', date_default_timezone_get());
|
||||||
$conf->setEmpty('general.title', 'Shared links on '. escape(index_url($_SERVER)));
|
$conf->setEmpty('general.title', 'Shared links on '. escape(index_url($_SERVER)));
|
||||||
RainTPL::$tpl_dir = $conf->get('resource.raintpl_tpl'); // template directory
|
RainTPL::$tpl_dir = $conf->get('resource.raintpl_tpl').'/'.$conf->get('resource.theme').'/'; // template directory
|
||||||
RainTPL::$cache_dir = $conf->get('resource.raintpl_tmp'); // cache directory
|
RainTPL::$cache_dir = $conf->get('resource.raintpl_tmp'); // cache directory
|
||||||
|
|
||||||
$pluginManager = new PluginManager($conf);
|
$pluginManager = new PluginManager($conf);
|
||||||
|
@ -1124,6 +1125,7 @@ function renderPage($conf, $pluginManager, $LINKSDB)
|
||||||
$conf->set('general.timezone', $tz);
|
$conf->set('general.timezone', $tz);
|
||||||
$conf->set('general.title', escape($_POST['title']));
|
$conf->set('general.title', escape($_POST['title']));
|
||||||
$conf->set('general.header_link', escape($_POST['titleLink']));
|
$conf->set('general.header_link', escape($_POST['titleLink']));
|
||||||
|
$conf->set('resource.theme', escape($_POST['theme']));
|
||||||
$conf->set('redirector.url', escape($_POST['redirector']));
|
$conf->set('redirector.url', escape($_POST['redirector']));
|
||||||
$conf->set('security.session_protection_disabled', !empty($_POST['disablesessionprotection']));
|
$conf->set('security.session_protection_disabled', !empty($_POST['disablesessionprotection']));
|
||||||
$conf->set('privacy.default_private_links', !empty($_POST['privateLinkByDefault']));
|
$conf->set('privacy.default_private_links', !empty($_POST['privateLinkByDefault']));
|
||||||
|
@ -1134,6 +1136,7 @@ function renderPage($conf, $pluginManager, $LINKSDB)
|
||||||
$conf->set('api.secret', escape($_POST['apiSecret']));
|
$conf->set('api.secret', escape($_POST['apiSecret']));
|
||||||
try {
|
try {
|
||||||
$conf->write(isLoggedIn());
|
$conf->write(isLoggedIn());
|
||||||
|
invalidateCaches($conf->get('resource.page_cache'));
|
||||||
}
|
}
|
||||||
catch(Exception $e) {
|
catch(Exception $e) {
|
||||||
error_log(
|
error_log(
|
||||||
|
@ -1151,6 +1154,8 @@ function renderPage($conf, $pluginManager, $LINKSDB)
|
||||||
else // Show the configuration form.
|
else // Show the configuration form.
|
||||||
{
|
{
|
||||||
$PAGE->assign('title', $conf->get('general.title'));
|
$PAGE->assign('title', $conf->get('general.title'));
|
||||||
|
$PAGE->assign('theme', $conf->get('resource.theme'));
|
||||||
|
$PAGE->assign('theme_available', ThemeUtils::getThemes($conf->get('resource.raintpl_tpl')));
|
||||||
$PAGE->assign('redirector', $conf->get('redirector.url'));
|
$PAGE->assign('redirector', $conf->get('redirector.url'));
|
||||||
list($timezone_form, $timezone_js) = generateTimeZoneForm($conf->get('general.timezone'));
|
list($timezone_form, $timezone_js) = generateTimeZoneForm($conf->get('general.timezone'));
|
||||||
$PAGE->assign('timezone_form', $timezone_form);
|
$PAGE->assign('timezone_form', $timezone_form);
|
||||||
|
|
|
@ -289,6 +289,7 @@ public function testCheckCurrentResourcePermissions()
|
||||||
$conf->set('resource.page_cache', 'pagecache');
|
$conf->set('resource.page_cache', 'pagecache');
|
||||||
$conf->set('resource.raintpl_tmp', 'tmp');
|
$conf->set('resource.raintpl_tmp', 'tmp');
|
||||||
$conf->set('resource.raintpl_tpl', 'tpl');
|
$conf->set('resource.raintpl_tpl', 'tpl');
|
||||||
|
$conf->set('resource.theme', 'default');
|
||||||
$conf->set('resource.update_check', 'data/lastupdatecheck.txt');
|
$conf->set('resource.update_check', 'data/lastupdatecheck.txt');
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
|
@ -312,10 +313,12 @@ public function testCheckCurrentResourcePermissionsErrors()
|
||||||
$conf->set('resource.page_cache', 'null/pagecache');
|
$conf->set('resource.page_cache', 'null/pagecache');
|
||||||
$conf->set('resource.raintpl_tmp', 'null/tmp');
|
$conf->set('resource.raintpl_tmp', 'null/tmp');
|
||||||
$conf->set('resource.raintpl_tpl', 'null/tpl');
|
$conf->set('resource.raintpl_tpl', 'null/tpl');
|
||||||
|
$conf->set('resource.raintpl_theme', 'null/tpl/default');
|
||||||
$conf->set('resource.update_check', 'null/data/lastupdatecheck.txt');
|
$conf->set('resource.update_check', 'null/data/lastupdatecheck.txt');
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
array(
|
array(
|
||||||
'"null/tpl" directory is not readable',
|
'"null/tpl" directory is not readable',
|
||||||
|
'"null/tpl/default" directory is not readable',
|
||||||
'"null/cache" directory is not readable',
|
'"null/cache" directory is not readable',
|
||||||
'"null/cache" directory is not writable',
|
'"null/cache" directory is not writable',
|
||||||
'"null/data" directory is not readable',
|
'"null/data" directory is not readable',
|
||||||
|
|
55
tests/ThemeUtilsTest.php
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Shaarli;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ThemeUtilsTest
|
||||||
|
*
|
||||||
|
* @package Shaarli
|
||||||
|
*/
|
||||||
|
class ThemeUtilsTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Test getThemes() with existing theme directories.
|
||||||
|
*/
|
||||||
|
public function testGetThemes()
|
||||||
|
{
|
||||||
|
$themes = ['theme1', 'default', 'Bl1p_- bL0p'];
|
||||||
|
foreach ($themes as $theme) {
|
||||||
|
mkdir('sandbox/tpl/'. $theme, 0755, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// include a file which should be ignored
|
||||||
|
touch('sandbox/tpl/supertheme');
|
||||||
|
|
||||||
|
$res = ThemeUtils::getThemes('sandbox/tpl/');
|
||||||
|
foreach ($res as $theme) {
|
||||||
|
$this->assertTrue(in_array($theme, $themes));
|
||||||
|
}
|
||||||
|
$this->assertFalse(in_array('supertheme', $res));
|
||||||
|
|
||||||
|
foreach ($themes as $theme) {
|
||||||
|
rmdir('sandbox/tpl/'. $theme);
|
||||||
|
}
|
||||||
|
unlink('sandbox/tpl/supertheme');
|
||||||
|
rmdir('sandbox/tpl');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test getThemes() without any theme dir.
|
||||||
|
*/
|
||||||
|
public function testGetThemesEmpty()
|
||||||
|
{
|
||||||
|
mkdir('sandbox/tpl/', 0755, true);
|
||||||
|
$this->assertEquals([], ThemeUtils::getThemes('sandbox/tpl/'));
|
||||||
|
rmdir('sandbox/tpl/');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test getThemes() with an invalid path.
|
||||||
|
*/
|
||||||
|
public function testGetThemesInvalid()
|
||||||
|
{
|
||||||
|
$this->assertEquals([], ThemeUtils::getThemes('nope'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
require_once 'application/config/ConfigManager.php';
|
require_once 'application/config/ConfigManager.php';
|
||||||
require_once 'tests/Updater/DummyUpdater.php';
|
require_once 'tests/Updater/DummyUpdater.php';
|
||||||
|
require_once 'inc/rain.tpl.class.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class UpdaterTest.
|
* Class UpdaterTest.
|
||||||
|
@ -421,4 +422,48 @@ public function testDatastoreIdsNothingToDo()
|
||||||
$this->assertTrue($updater->updateMethodDatastoreIds());
|
$this->assertTrue($updater->updateMethodDatastoreIds());
|
||||||
$this->assertEquals($checksum, hash_file('sha1', self::$testDatastore));
|
$this->assertEquals($checksum, hash_file('sha1', self::$testDatastore));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test defaultTheme update with default settings: nothing to do.
|
||||||
|
*/
|
||||||
|
public function testDefaultThemeWithDefaultSettings()
|
||||||
|
{
|
||||||
|
$sandbox = 'sandbox/config';
|
||||||
|
copy(self::$configFile . '.json.php', $sandbox . '.json.php');
|
||||||
|
$this->conf = new ConfigManager($sandbox);
|
||||||
|
$updater = new Updater([], [], $this->conf, true);
|
||||||
|
$this->assertTrue($updater->updateMethodDefaultTheme());
|
||||||
|
|
||||||
|
$this->assertEquals('tpl/', $this->conf->get('resource.raintpl_tpl'));
|
||||||
|
$this->assertEquals('default', $this->conf->get('resource.theme'));
|
||||||
|
$this->conf = new ConfigManager($sandbox);
|
||||||
|
$this->assertEquals('tpl/', $this->conf->get('resource.raintpl_tpl'));
|
||||||
|
$this->assertEquals('default', $this->conf->get('resource.theme'));
|
||||||
|
unlink($sandbox . '.json.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test defaultTheme update with a custom theme in a subfolder
|
||||||
|
*/
|
||||||
|
public function testDefaultThemeWithCustomTheme()
|
||||||
|
{
|
||||||
|
$theme = 'iamanartist';
|
||||||
|
$sandbox = 'sandbox/config';
|
||||||
|
copy(self::$configFile . '.json.php', $sandbox . '.json.php');
|
||||||
|
$this->conf = new ConfigManager($sandbox);
|
||||||
|
mkdir('sandbox/'. $theme);
|
||||||
|
touch('sandbox/'. $theme .'/linklist.html');
|
||||||
|
$this->conf->set('resource.raintpl_tpl', 'sandbox/'. $theme .'/');
|
||||||
|
$updater = new Updater([], [], $this->conf, true);
|
||||||
|
$this->assertTrue($updater->updateMethodDefaultTheme());
|
||||||
|
|
||||||
|
$this->assertEquals('sandbox', $this->conf->get('resource.raintpl_tpl'));
|
||||||
|
$this->assertEquals($theme, $this->conf->get('resource.theme'));
|
||||||
|
$this->conf = new ConfigManager($sandbox);
|
||||||
|
$this->assertEquals('sandbox', $this->conf->get('resource.raintpl_tpl'));
|
||||||
|
$this->assertEquals($theme, $this->conf->get('resource.theme'));
|
||||||
|
unlink($sandbox . '.json.php');
|
||||||
|
unlink('sandbox/'. $theme .'/linklist.html');
|
||||||
|
rmdir('sandbox/'. $theme);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"datastore": "tests\/utils\/config\/datastore.php",
|
"datastore": "tests\/utils\/config\/datastore.php",
|
||||||
"data_dir": "tests\/utils\/config"
|
"data_dir": "tests\/utils\/config",
|
||||||
|
"raintpl_tpl": "tpl/"
|
||||||
},
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"WALLABAG_VERSION": 1
|
"WALLABAG_VERSION": 1
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>{include="includes"}
|
<head>{include="includes"}
|
||||||
<link type="text/css" rel="stylesheet" href="../inc/awesomplete.css" />
|
<link type="text/css" rel="stylesheet" href="inc/awesomplete.css#" />
|
||||||
<script src="inc/awesomplete.min.js#"></script>
|
<script src="inc/awesomplete.min.js#"></script>
|
||||||
</head>
|
</head>
|
||||||
<body onload="document.changetag.fromtag.focus();">
|
<body onload="document.changetag.fromtag.focus();">
|
|
@ -19,6 +19,20 @@
|
||||||
<td><input type="text" name="titleLink" id="titleLink" size="50" value="{$titleLink}"><br/><label
|
<td><input type="text" name="titleLink" id="titleLink" size="50" value="{$titleLink}"><br/><label
|
||||||
for="titleLink">(default value is: ?)</label></td>
|
for="titleLink">(default value is: ?)</label></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><b>Theme:</b></td>
|
||||||
|
<td>
|
||||||
|
<select name="theme" id="theme">
|
||||||
|
{loop="$theme_available"}
|
||||||
|
<option value="{$value}" {if="$value===$theme"}selected{/if}>
|
||||||
|
{$value|ucfirst}
|
||||||
|
</option>
|
||||||
|
{/loop}
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td><b>Timezone:</b></td>
|
<td><b>Timezone:</b></td>
|
||||||
<td>{$timezone_form}</td>
|
<td>{$timezone_form}</td>
|
|
@ -103,7 +103,7 @@ strong {
|
||||||
}
|
}
|
||||||
|
|
||||||
#pageheader #logo {
|
#pageheader #logo {
|
||||||
background-image: url('../images/logo.png');
|
background-image: url('../../../images/logo.png');
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
float: left;
|
float: left;
|
||||||
margin: 0 10px 0 10px;
|
margin: 0 10px 0 10px;
|
||||||
|
@ -803,6 +803,10 @@ div.dailyAbout img {
|
||||||
height: 14px;
|
height: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.dailyEntryPermalink {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
div.dailyTitle {
|
div.dailyTitle {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 44pt;
|
font-size: 44pt;
|
|
@ -28,9 +28,9 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="dailyTitle">
|
<div class="dailyTitle">
|
||||||
<img src="../images/floral_left.png" width="51" height="50" class="nomobile" alt="floral_left">
|
<img src="images/floral_left.png" width="51" height="50" class="nomobile" alt="floral_left">
|
||||||
The Daily Shaarli
|
The Daily Shaarli
|
||||||
<img src="../images/floral_right.png" width="51" height="50" class="nomobile" alt="floral_right">
|
<img src="images/floral_right.png" width="51" height="50" class="nomobile" alt="floral_right">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="dailyDate">
|
<div class="dailyDate">
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
<div class="dailyEntry">
|
<div class="dailyEntry">
|
||||||
<div class="dailyEntryPermalink">
|
<div class="dailyEntryPermalink">
|
||||||
<a href="?{$value.shorturl}">
|
<a href="?{$value.shorturl}">
|
||||||
<img src="../images/squiggle2.png" width="25" height="26" title="permalink" alt="permalink">
|
<img src="images/squiggle.png" width="25" height="26" title="permalink" alt="permalink">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{if="!$hide_timestamps || isLoggedIn()"}
|
{if="!$hide_timestamps || isLoggedIn()"}
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
{$value}
|
{$value}
|
||||||
{/loop}
|
{/loop}
|
||||||
</div>
|
</div>
|
||||||
<div id="closing"><img src="../images/squiggle_closing.png" width="66" height="61" alt="-"></div>
|
<div id="closing"><img src="images/squiggle_closing.png" width="66" height="61" alt="-"></div>
|
||||||
</div>
|
</div>
|
||||||
{include="page.footer"}
|
{include="page.footer"}
|
||||||
</body>
|
</body>
|
|
@ -1,7 +1,7 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>{include="includes"}
|
<head>{include="includes"}
|
||||||
<link type="text/css" rel="stylesheet" href="../inc/awesomplete.css" />
|
<link type="text/css" rel="stylesheet" href="inc/awesomplete.css#" />
|
||||||
</head>
|
</head>
|
||||||
<body
|
<body
|
||||||
{if="$link.title==''"}onload="document.linkform.lf_title.focus();"
|
{if="$link.title==''"}onload="document.linkform.lf_title.focus();"
|
Before Width: | Height: | Size: 599 B After Width: | Height: | Size: 599 B |
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 124 KiB |
Before Width: | Height: | Size: 650 B After Width: | Height: | Size: 650 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 813 B After Width: | Height: | Size: 813 B |
Before Width: | Height: | Size: 720 B After Width: | Height: | Size: 720 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 714 B After Width: | Height: | Size: 714 B |
|
@ -6,9 +6,9 @@
|
||||||
<link rel="alternate" type="application/rss+xml" href="{$feedurl}?do=rss{$searchcrits}#" title="RSS Feed" />
|
<link rel="alternate" type="application/rss+xml" href="{$feedurl}?do=rss{$searchcrits}#" title="RSS Feed" />
|
||||||
<link rel="alternate" type="application/atom+xml" href="{$feedurl}?do=atom{$searchcrits}#" title="ATOM Feed" />
|
<link rel="alternate" type="application/atom+xml" href="{$feedurl}?do=atom{$searchcrits}#" title="ATOM Feed" />
|
||||||
<link href="images/favicon.ico#" rel="shortcut icon" type="image/x-icon" />
|
<link href="images/favicon.ico#" rel="shortcut icon" type="image/x-icon" />
|
||||||
<link type="text/css" rel="stylesheet" href="../inc/reset.css" />
|
<link type="text/css" rel="stylesheet" href="css/reset.css" />
|
||||||
<link type="text/css" rel="stylesheet" href="../inc/shaarli.css" />
|
<link type="text/css" rel="stylesheet" href="css/shaarli.css" />
|
||||||
{if="is_file('inc/user.css')"}<link type="text/css" rel="stylesheet" href="../inc/user.css" />{/if}
|
{if="is_file('inc/user.css')"}<link type="text/css" rel="stylesheet" href="inc/user.css#" />{/if}
|
||||||
{loop="$plugins_includes.css_files"}
|
{loop="$plugins_includes.css_files"}
|
||||||
<link type="text/css" rel="stylesheet" href="{$value}#"/>
|
<link type="text/css" rel="stylesheet" href="{$value}#"/>
|
||||||
{/loop}
|
{/loop}
|
|
@ -1,7 +1,7 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link type="text/css" rel="stylesheet" href="../inc/awesomplete.css" />
|
<link type="text/css" rel="stylesheet" href="inc/awesomplete.css#" />
|
||||||
{include="includes"}
|
{include="includes"}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|