- Introduce a new theme
- Allow selecting themes/templates from the configuration page
- New/Edit link form can be submitted using CTRL+Enter in the textarea
+ - Shaarli version is displayed in the footer when logged in
- Add plugin placeholders to Atom/RSS feed templates
- Add OpenSearch to feed templates
- Add `campaign_` to the URL cleanup pattern list
_Shaarli is a minimalist delicious clone that you can install on your own server._
_It is designed to be personal (single-user), fast and handy._
-[![](https://img.shields.io/travis/shaarli/Shaarli.svg?label=master)](https://travis-ci.org/shaarli/Shaarli)
+[![](https://img.shields.io/badge/stable-v0.7.1-blue.svg)](https://github.com/shaarli/Shaarli/releases/tag/v0.7.1)
[![](https://img.shields.io/travis/shaarli/Shaarli/stable.svg?label=stable)](https://travis-ci.org/shaarli/Shaarli)
-[![](https://img.shields.io/github/release/shaarli/shaarli.svg)](https://github.com/shaarli/Shaarli/releases/latest/)
-[![Docker repository](https://img.shields.io/docker/pulls/shaarli/shaarli.svg)](https://hub.docker.com/r/shaarli/shaarli/)
+•
+[![](https://img.shields.io/badge/latest-v0.8.4-blue.svg)](https://github.com/shaarli/Shaarli/releases/tag/v0.8.4)
+[![](https://img.shields.io/travis/shaarli/Shaarli/latest.svg?label=latest)](https://travis-ci.org/shaarli/Shaarli)
+•
+[![](https://img.shields.io/badge/master-v0.9.x-blue.svg)](https://github.com/shaarli/Shaarli)
+[![](https://img.shields.io/travis/shaarli/Shaarli.svg?label=master)](https://travis-ci.org/shaarli/Shaarli)
[![Join the chat at https://gitter.im/shaarli/Shaarli](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/shaarli/Shaarli)
[![Bountysource](https://www.bountysource.com/badge/team?team_id=19583&style=bounties_received)](https://www.bountysource.com/teams/shaarli/issues)
+[![Docker repository](https://img.shields.io/docker/pulls/shaarli/shaarli.svg)](https://hub.docker.com/r/shaarli/shaarli/)
## Quickstart
- [Wiki/documentation](https://github.com/shaarli/Shaarli/wiki)
}
$this->tpl->assign('shaarlititle', $this->conf->get('general.title', 'Shaarli'));
$this->tpl->assign('openshaarli', $this->conf->get('security.open_shaarli', false));
- $this->tpl->assign('showatom', $this->conf->get('feed.show_atom', false));
+ $this->tpl->assign('showatom', $this->conf->get('feed.show_atom', true));
+ $this->tpl->assign('feed_type', $this->conf->get('feed.show_atom', true) !== false ? 'atom' : 'rss');
$this->tpl->assign('hide_timestamps', $this->conf->get('privacy.hide_timestamps', false));
$this->tpl->assign('token', getToken($this->conf));
// To be removed with a proper theme configuration.
$this->conf->set('plugins.PIWIK_URL', 'http://'. $this->conf->get('plugins.PIWIK_URL'));
$this->conf->write($this->isLoggedIn);
+
+ return true;
+ }
+
+ /**
+ * Use ATOM feed as default.
+ */
+ public function updateMethodAtomDefault()
+ {
+ if (!$this->conf->exists('feed.show_atom') || $this->conf->get('feed.show_atom') === true) {
+ return true;
+ }
+
+ $this->conf->set('feed.show_atom', true);
+ $this->conf->write($this->isLoggedIn);
+
return true;
}
$data = str_replace(self::getPhpSuffix(), '', $data);
$data = json_decode($data, true);
if ($data === null) {
- $error = json_last_error();
- throw new \Exception('An error occurred while parsing JSON file: error code #'. $error);
+ $errorCode = json_last_error();
+ $error = 'An error occurred while parsing JSON configuration file ('. $filepath .'): error code #';
+ $error .= $errorCode. '<br>➜ <code>' . json_last_error_msg() .'</code>';
+ if ($errorCode === JSON_ERROR_SYNTAX) {
+ $error .= '<br>Please check your JSON syntax (without PHP comment tags) using a JSON lint tool such as ';
+ $error .= '<a href="http://jsonlint.com/">jsonlint.com</a>.';
+ }
+ throw new \Exception($error);
}
return $data;
}
*/
protected function load()
{
- $this->loadedConfig = $this->configIO->read($this->getConfigFileExt());
+ try {
+ $this->loadedConfig = $this->configIO->read($this->getConfigFileExt());
+ } catch (\Exception $e) {
+ die($e->getMessage());
+ }
$this->setDefaultValues();
}
$this->setEmpty('updates.check_updates_interval', 86400);
$this->setEmpty('feed.rss_permalinks', true);
- $this->setEmpty('feed.show_atom', false);
+ $this->setEmpty('feed.show_atom', true);
$this->setEmpty('privacy.default_private_links', false);
$this->setEmpty('privacy.hide_public_links', false);
$this->assertTrue($updater->updateMethodPiwikUrl());
$this->assertEquals($url, $this->conf->get('plugins.PIWIK_URL'));
}
+
+ /**
+ * Test updateMethodAtomDefault with show_atom set to false
+ * => update to true.
+ */
+ public function testUpdateMethodAtomDefault()
+ {
+ $sandboxConf = 'sandbox/config';
+ copy(self::$configFile . '.json.php', $sandboxConf . '.json.php');
+ $this->conf = new ConfigManager($sandboxConf);
+ $this->conf->set('feed.show_atom', false);
+ $updater = new Updater([], [], $this->conf, true);
+ $this->assertTrue($updater->updateMethodAtomDefault());
+ $this->assertTrue($this->conf->get('feed.show_atom'));
+ // reload from file
+ $this->conf = new ConfigManager($sandboxConf);
+ $this->assertTrue($this->conf->get('feed.show_atom'));
+ }
+ /**
+ * Test updateMethodAtomDefault with show_atom not set.
+ * => nothing to do
+ */
+ public function testUpdateMethodAtomDefaultNoExist()
+ {
+ $sandboxConf = 'sandbox/config';
+ copy(self::$configFile . '.json.php', $sandboxConf . '.json.php');
+ $this->conf = new ConfigManager($sandboxConf);
+ $updater = new Updater([], [], $this->conf, true);
+ $this->assertTrue($updater->updateMethodAtomDefault());
+ $this->assertTrue($this->conf->get('feed.show_atom'));
+ }
+ /**
+ * Test updateMethodAtomDefault with show_atom set to true.
+ * => nothing to do
+ */
+ public function testUpdateMethodAtomDefaultAlreadyTrue()
+ {
+ $sandboxConf = 'sandbox/config';
+ copy(self::$configFile . '.json.php', $sandboxConf . '.json.php');
+ $this->conf = new ConfigManager($sandboxConf);
+ $this->conf->set('feed.show_atom', true);
+ $updater = new Updater([], [], $this->conf, true);
+ $this->assertTrue($updater->updateMethodAtomDefault());
+ $this->assertTrue($this->conf->get('feed.show_atom'));
+ }
}
* Read a non existent config file -> empty array.
*
* @expectedException \Exception
- * @expectedExceptionMessage An error occurred while parsing JSON file: error code #4
+ * @expectedExceptionMessageRegExp /An error occurred while parsing JSON configuration file \([\w\/\.]+\): error code #4/
*/
public function testReadInvalidJson()
{
<div class="pure-g">
<div class="pure-u-2-24"></div>
<div id="footer" class="pure-u-20-24">
- <strong><a href="https://github.com/shaarli/Shaarli">Shaarli</a></strong> ·
+ <strong><a href="https://github.com/shaarli/Shaarli">Shaarli</a></strong>
+ {if="isLoggedIn()===true"}
+ {$version}
+ {/if}
+ ·
The personal, minimalist, super-fast, database free, bookmarking service by the Shaarli community ·
<a href="doc/Home.html" rel="nofollow">Documentation</a>
{loop="$plugins_footer.text"}
</li>
{/loop}
<li class="pure-menu-item pure-u-lg-0">
- <a href="?do=atom{$searchcrits}" class="pure-menu-link">{'RSS Feed'|t}</a>
+ <a href="?do={$feed_type}{$searchcrits}" class="pure-menu-link">{'RSS Feed'|t}</a>
</li>
{if="isLoggedIn()"}
<li class="pure-menu-item pure-u-lg-0">
</a>
</li>
<li class="pure-menu-item">
- <a href="?do=atom{$searchcrits}" class="pure-menu-link" title="{'RSS Feed'|t}">
+ <a href="?do={$feed_type}{$searchcrits}" class="pure-menu-link" title="{'RSS Feed'|t}">
<i class="fa fa-rss"></i>
</a>
</li>