Merge pull request #1317 from ArthurHoaro/feature/default-colors

Plugin to override default template colors
This commit is contained in:
ArthurHoaro 2019-07-20 09:36:39 +02:00 committed by GitHub
commit a9633359d1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 439 additions and 39 deletions

View file

@ -2,9 +2,11 @@ options:
max-warnings: 0
rules:
property-sort-order:
- 1
-
order: 'concentric'
- 0
# Sort order rule does not work with CSS variables: https://github.com/sasstools/sass-lint/issues/1161
# - 1
# -
# order: 'concentric'
no-important:
- 0
no-vendor-prefixes:

1
.gitignore vendored
View file

@ -28,6 +28,7 @@ phpdoc.xml
# User plugin configuration
plugins/*/config.php
plugins/default_colors/default_colors.css
# HTML documentation
doc/html/

View file

@ -25,9 +25,15 @@ $warning-text: #97600d;
$form-input-border: #d8d8d8;
$form-input-background: #eee;
:root {
--main-color: #{$main-green};
--background-color: #{$background-color};
--dark-main-color: #{$dark-green};
}
// General
body {
background: $background-color;
background: var(--background-color);
}
.strong {
@ -143,7 +149,7 @@ body,
}
.pure-alert-success {
background-color: $main-green;
background-color: var(--main-color);
}
.pure-alert-warning {
@ -169,7 +175,7 @@ body,
top: 0;
transition: max-height .5s;
z-index: 999;
background: $main-green;
background: var(--main-color);
width: 100%;
// Hack to transition with auto height: http://stackoverflow.com/a/8331169/1484919
max-height: 45px;
@ -322,7 +328,7 @@ body,
button {
border: 0;
border-radius: 2px;
background-color: $main-green;
background-color: var(--main-color);
padding: 4px 8px 6px;
color: $almost-white;
}
@ -358,7 +364,7 @@ body,
.search-tagcloud {
button {
&:hover {
color: $background-color;
color: var(--background-color);
}
}
}
@ -389,7 +395,7 @@ body,
position: fixed;
visibility: hidden;
z-index: 999;
background: $main-green;
background: var(--main-color);
padding: 5px 0;
width: 100%;
height: 30px;
@ -411,7 +417,7 @@ body,
margin: 0 0 5px;
border: 1px solid $almost-white;
border-radius: 2px;
background: $main-green;
background: var(--main-color);
padding: 4px 0;
width: 100px;
height: 28px;
@ -419,7 +425,7 @@ body,
&:hover {
background: $almost-white;
color: $main-green;
color: var(--main-color);
}
}
@ -558,7 +564,7 @@ body,
}
.filter-on {
background: $main-green;
background: var(--main-color);
color: $light-green;
}
@ -697,7 +703,7 @@ body,
&:visited {
.linklist-link {
color: $dark-green;
color: var(--dark-main-color);
}
}
@ -708,7 +714,7 @@ body,
}
.linklist-link {
color: $main-green;
color: var(--main-color);
font-size: 1.1em;
&:hover {
@ -783,14 +789,14 @@ body,
a {
text-decoration: none;
color: $main-green;
color: var(--main-color);
&:hover {
color: $dark-grey;
}
&:visited {
color: $dark-green;
color: var(--dark-main-color);
}
}
}
@ -888,7 +894,7 @@ body,
&::before {
display: block;
margin: 10px auto;
background: linear-gradient(to right, $background-color, $dark-grey, $background-color);
background: linear-gradient(to right, var(--background-color), $dark-grey, var(--background-color));
width: 80%;
height: 1px;
content: '';
@ -917,7 +923,7 @@ body,
margin: 15px 5px;
border: 0;
box-shadow: 1px 1px 1px $form-input-border, -1px -1px 6px $form-input-border, -1px 1px 2px $form-input-border, 1px -1px 2px $form-input-border;
background: $main-green;
background: var(--main-color);
min-width: 150px;
height: 35px;
vertical-align: center;
@ -941,7 +947,7 @@ body,
padding: 10px 0;
width: 100%;
text-align: center;
color: $main-green;
color: var(--main-color);
}
.window-subtitle {
@ -950,7 +956,7 @@ body,
a {
text-decoration: none;
color: $main-green;
color: var(--main-color);
font-weight: bold;
&.button {
@ -1278,7 +1284,7 @@ form {
.pure-button {
&:hover {
background-color: $main-green;
background-color: var(--main-color);
background-image: none;
color: $almost-white;
}
@ -1362,7 +1368,7 @@ form {
}
.validate-rename-tag {
color: $main-green;
color: var(--main-color);
}
}
@ -1458,7 +1464,7 @@ form {
&::after {
display: block;
margin: 10px auto;
background: linear-gradient(to right, $background-color, $dark-grey, $background-color);
background: linear-gradient(to right, var(--background-color), $dark-grey, var(--background-color));
width: 90%;
height: 1px;
content: '';
@ -1508,14 +1514,14 @@ form {
.daily-entry-description {
a {
text-decoration: none;
color: $main-green;
color: var(--main-color);
&:hover {
text-shadow: 1px 1px $background-linklist-info;
}
&:visited {
color: $dark-green;
color: var(--dark-main-color);
}
}
}
@ -1572,12 +1578,12 @@ form {
}
.pure-button-shaarli {
background-color: $main-green;
background-color: var(--main-color);
}
.progressbar {
border-radius: 6px;
background-color: $main-green;
background-color: var(--main-color);
padding: 1px;
> div {
@ -1586,8 +1592,8 @@ form {
-45deg,
$almost-white,
$almost-white 6px,
$background-color 6px,
$background-color 12px
var(--background-color) 6px,
var(--background-color) 12px
);
width: 0%;
height: 10px;

View file

@ -137,6 +137,7 @@ If it's still not working, please [open an issue](https://github.com/shaarli/Sha
| [render_feed](#render_feed) | Allow to do add tags in RSS and ATOM feeds. |
| [save_link](#save_link) | Allow to alter the link being saved in the datastore. |
| [delete_link](#delete_link) | Allow to do an action before a link is deleted from the datastore. |
| [save_plugin_parameters](#save_plugin_parameters) | Allow to manipulate plugin parameters before they're saved. |
@ -471,6 +472,22 @@ Allow to execute any action before the link is actually removed from the datasto
- created
- updated
#### save_plugin_parameters
Triggered when the plugin parameters are saved from the plugin administration page.
Plugins can perform an action every times their settings are updated.
For example it is used to update the CSS file of the `default_colors` plugins.
##### Data
`$data` input contains the `$_POST` array.
So if the plugin has a parameter called `MYPLUGIN_PARAMETER`,
the array will contain an entry with `MYPLUGIN_PARAMETER` as a key.
## Guide for template designer
### Plugin administration

View file

@ -63,8 +63,12 @@ Usage of each plugin is documented in it's README file:
* `addlink-toolbar`: Adds the addlink input on the linklist page
* `archiveorg`: For each link, add an Archive.org icon
* `default_colors`: Override default theme colors.
* `isso`: Let visitor comment your shaares on permalinks with Isso.
* [`markdown`](https://github.com/shaarli/Shaarli/blob/master/plugins/markdown/README.md): Render shaare description with Markdown syntax.
* `piwik`: A plugin that adds Piwik tracking code to Shaarli pages.
* [`playvideos`](https://github.com/shaarli/Shaarli/blob/master/plugins/playvideos/README.md): Add a button in the toolbar allowing to watch all videos.
* `pubsubhubbub`: Enable PubSubHubbub feed publishing
* `qrcode`: For each link, add a QRCode icon.
* [`wallabag`](https://github.com/shaarli/Shaarli/blob/master/plugins/wallabag/README.md): For each link, add a Wallabag icon to save it in your instance.

View file

@ -1,8 +1,8 @@
msgid ""
msgstr ""
"Project-Id-Version: Shaarli\n"
"POT-Creation-Date: 2019-07-06 12:14+0200\n"
"PO-Revision-Date: 2019-07-06 12:17+0200\n"
"POT-Creation-Date: 2019-07-13 10:45+0200\n"
"PO-Revision-Date: 2019-07-13 10:49+0200\n"
"Last-Translator: \n"
"Language-Team: Shaarli\n"
"Language: fr_FR\n"
@ -403,7 +403,7 @@ msgstr "Note : "
#: index.php:1424
msgid "Invalid link ID provided"
msgstr ""
msgstr "ID du lien non valide"
#: index.php:1444 tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:65
msgid "Export"
@ -428,15 +428,15 @@ msgstr ""
msgid "Plugin administration"
msgstr "Administration des plugins"
#: index.php:1615 tmp/thumbnails.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14
#: index.php:1616 tmp/thumbnails.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14
msgid "Thumbnails update"
msgstr "Mise à jour des miniatures"
#: index.php:1781
#: index.php:1782
msgid "Search: "
msgstr "Recherche : "
#: index.php:1824
#: index.php:1825
#, php-format
msgid ""
"<pre>Sessions do not seem to work correctly on your server.<br>Make sure the "
@ -455,7 +455,7 @@ msgstr ""
"des cookies. Nous vous recommandons d'accéder à votre serveur depuis son "
"adresse IP ou un <em>Fully Qualified Domain Name</em>.<br>"
#: index.php:1834
#: index.php:1835
msgid "Click to try again."
msgstr "Cliquer ici pour réessayer."
@ -480,7 +480,33 @@ msgstr "Voir sur archive.org"
msgid "For each link, add an Archive.org icon."
msgstr "Pour chaque lien, ajoute une icône pour Archive.org."
#: plugins/demo_plugin/demo_plugin.php:465
#: plugins/default_colors/default_colors.php:33
msgid ""
"Default colors plugin error: This plugin is active and no custom color is "
"configured."
msgstr ""
"Erreur du plugin default colors : ce plugin est actif et aucune couleur "
"n'est configurée."
#: plugins/default_colors/default_colors.php:107
msgid "Override default theme colors. Use any CSS valid color."
msgstr ""
"Remplacer les couleurs du thème par défaut. Utiliser n'importe quelle "
"couleur CSS valide."
#: plugins/default_colors/default_colors.php:108
msgid "Main color (navbar green)"
msgstr "Couleur principale (vert de la barre de navigation)"
#: plugins/default_colors/default_colors.php:109
msgid "Background color (light grey)"
msgstr "Couleur de fond (gris léger)"
#: plugins/default_colors/default_colors.php:110
msgid "Dark main color (e.g. visited links)"
msgstr "Couleur principale sombre (ex : les liens visités)"
#: plugins/demo_plugin/demo_plugin.php:482
msgid ""
"A demo plugin covering all use cases for template designers and plugin "
"developers."
@ -488,6 +514,14 @@ msgstr ""
"Une extension de démonstration couvrant tous les cas d'utilisation pour les "
"designers de thèmes et les développeurs d'extensions."
#: plugins/demo_plugin/demo_plugin.php:483
msgid "This is a parameter dedicated to the demo plugin. It'll be suffixed."
msgstr "Ceci est un paramètre dédié au plugin de démo. Il sera suffixé."
#: plugins/demo_plugin/demo_plugin.php:484
msgid "Other demo parameter"
msgstr "Un autre paramètre de démo"
#: plugins/isso/isso.php:22
msgid ""
"Isso plugin error: Please define the \"ISSO_SERVER\" setting in the plugin "
@ -703,9 +737,8 @@ msgstr ""
"miniatures."
#: tmp/configure.90100d2eaf5d3705e14b9b4f78ecddc9.rtpl.php:162
#| msgid "Enable thumbnails"
msgid "Synchonize thumbnails"
msgstr ""
msgstr "Synchroniser les miniatures"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29
msgid "title"

View file

@ -1567,6 +1567,7 @@ function ($a, $b) {
if ($targetPage == Router::$PAGE_SAVE_PLUGINSADMIN) {
try {
if (isset($_POST['parameters_form'])) {
$pluginManager->executeHooks('save_plugin_parameters', $_POST);
unset($_POST['parameters_form']);
foreach ($_POST as $param => $value) {
$conf->set('plugins.'. $param, escape($value));

View file

@ -0,0 +1,3 @@
:root {
%s
}

View file

@ -0,0 +1,5 @@
description="Override default theme colors. Use any CSS valid color."
parameters="DEFAULT_COLORS_MAIN;DEFAULT_COLORS_BACKGROUND;DEFAULT_COLORS_DARK_MAIN"
parameter.DEFAULT_COLORS_MAIN="Main color (navbar green)"
parameter.DEFAULT_COLORS_BACKGROUND="Background color (light grey)"
parameter.DEFAULT_COLORS_DARK_MAIN="Dark main color (e.g. visited links)"

View file

@ -0,0 +1,111 @@
<?php
/**
* Plugin default_colors.
*
* Allow users to easily overrides colors of the default theme.
*/
use Shaarli\Config\ConfigManager;
use Shaarli\Plugin\PluginManager;
const DEFAULT_COLORS_PLACEHOLDERS = [
'DEFAULT_COLORS_MAIN',
'DEFAULT_COLORS_BACKGROUND',
'DEFAULT_COLORS_DARK_MAIN',
];
/**
* Display an error if the plugin is active a no color is configured.
*
* @param $conf ConfigManager instance
*
* @return array|null The errors array or null of there is none.
*/
function default_colors_init($conf)
{
$params = '';
foreach (DEFAULT_COLORS_PLACEHOLDERS as $placeholder) {
$params .= trim($conf->get('plugins.'. $placeholder, ''));
}
if (empty($params)) {
$error = t('Default colors plugin error: '.
'This plugin is active and no custom color is configured.');
return array($error);
}
}
/**
* When plugin parameters are saved, we regenerate the custom CSS file with provided settings.
*
* @param array $data $_POST array
*
* @return array Updated $_POST array
*/
function hook_default_colors_save_plugin_parameters($data)
{
$file = PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css';
$template = file_get_contents(PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css.template');
$content = '';
foreach (DEFAULT_COLORS_PLACEHOLDERS as $rule) {
$content .= ! empty($data[$rule])
? default_colors_format_css_rule($data, $rule) .';'. PHP_EOL
: '';
}
if (! empty($content)) {
file_put_contents($file, sprintf($template, $content));
}
return $data;
}
/**
* When linklist is displayed, include default_colors CSS file.
*
* @param array $data - header data.
*
* @return mixed - header data with default_colors CSS file added.
*/
function hook_default_colors_render_includes($data)
{
$file = PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css';
if (file_exists($file )) {
$data['css_files'][] = $file ;
}
return $data;
}
/**
* Create a valid CSS rule from parameters settings and plugin parameter.
*
* @param array $data $_POST array
* @param string $parameter Plugin parameter name
*
* @return string CSS rules for the provided parameter and its matching value.
*/
function default_colors_format_css_rule($data, $parameter)
{
if (empty($data[$parameter])) {
return '';
}
$key = str_replace('DEFAULT_COLORS_', '', $parameter);
$key = str_replace('_', '-', strtolower($key)) .'-color';
return ' --'. $key .': '. $data[$parameter];
}
/**
* This function is never called, but contains translation calls for GNU gettext extraction.
*/
function default_colors_translation()
{
// meta
t('Override default theme colors. Use any CSS valid color.');
t('Main color (navbar green)');
t('Background color (light grey)');
t('Dark main color (e.g. visited links)');
}

View file

@ -1 +1,4 @@
description="A demo plugin covering all use cases for template designers and plugin developers."
parameters="DEMO_PLUGIN_PARAMETER;DEMO_PLUGIN_OTHER_PARAMETER"
parameter.DEMO_PLUGIN_PARAMETER="This is a parameter dedicated to the demo plugin. It'll be suffixed."
parameter.DEMO_PLUGIN_OTHER_PARAMETER="Other demo parameter"

View file

@ -456,6 +456,23 @@ function hook_demo_plugin_render_feed($data)
return $data;
}
/**
* When plugin parameters are saved.
*
* @param array $data $_POST array
*
* @return array Updated $_POST array
*/
function hook_demo_plugin_save_plugin_parameters($data)
{
// Here we edit the provided value, but we can use this to generate config files, etc.
if (! empty($data['DEMO_PLUGIN_PARAMETER']) && ! endsWith($data['DEMO_PLUGIN_PARAMETER'], '_SUFFIX')) {
$data['DEMO_PLUGIN_PARAMETER'] .= '_SUFFIX';
}
return $data;
}
/**
* This function is never called, but contains translation calls for GNU gettext extraction.
*/
@ -463,4 +480,6 @@ function demo_dummy_translation()
{
// meta
t('A demo plugin covering all use cases for template designers and plugin developers.');
t('This is a parameter dedicated to the demo plugin. It\'ll be suffixed.');
t('Other demo parameter');
}

View file

@ -0,0 +1,195 @@
<?php
namespace Shaarli\Plugin\DefaultColors;
use DateTime;
use PHPUnit\Framework\TestCase;
use Shaarli\Bookmark\LinkDB;
use Shaarli\Config\ConfigManager;
use Shaarli\Plugin\PluginManager;
require_once 'plugins/default_colors/default_colors.php';
/**
* Class PluginDefaultColorsTest
*
* Test the DefaultColors plugin (allowing to override default template colors).
*/
class PluginDefaultColorsTest extends TestCase
{
/**
* Reset plugin path
*/
public function setUp()
{
PluginManager::$PLUGINS_PATH = 'sandbox';
mkdir(PluginManager::$PLUGINS_PATH . '/default_colors/');
copy(
'plugins/default_colors/default_colors.css.template',
PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css.template'
);
}
/**
* Remove sandbox files and folder
*/
public function tearDown()
{
if (file_exists('sandbox/default_colors/default_colors.css.template')) {
unlink('sandbox/default_colors/default_colors.css.template');
}
if (file_exists('sandbox/default_colors/default_colors.css')) {
unlink('sandbox/default_colors/default_colors.css');
}
if (is_dir('sandbox/default_colors')) {
rmdir('sandbox/default_colors');
}
}
/**
* Test DefaultColors init without errors.
*/
public function testDefaultColorsInitNoError()
{
$conf = new ConfigManager('');
$conf->set('plugins.DEFAULT_COLORS_BACKGROUND', 'value');
$errors = default_colors_init($conf);
$this->assertEmpty($errors);
}
/**
* Test DefaultColors init with errors.
*/
public function testDefaultColorsInitError()
{
$conf = new ConfigManager('');
$errors = default_colors_init($conf);
$this->assertNotEmpty($errors);
}
/**
* Test the save plugin parameters hook with all colors specified.
*/
public function testSavePluginParametersAll()
{
$post = [
'other1' => true,
'DEFAULT_COLORS_MAIN' => 'blue',
'DEFAULT_COLORS_BACKGROUND' => 'pink',
'other2' => ['yep'],
'DEFAULT_COLORS_DARK_MAIN' => 'green',
];
hook_default_colors_save_plugin_parameters($post);
$this->assertFileExists($file = 'sandbox/default_colors/default_colors.css');
$content = file_get_contents($file);
$expected = ':root {
--main-color: blue;
--background-color: pink;
--dark-main-color: green;
}
';
$this->assertEquals($expected, $content);
}
/**
* Test the save plugin parameters hook with only one color specified.
*/
public function testSavePluginParametersSingle()
{
$post = [
'other1' => true,
'DEFAULT_COLORS_BACKGROUND' => 'pink',
'other2' => ['yep'],
'DEFAULT_COLORS_DARK_MAIN' => '',
];
hook_default_colors_save_plugin_parameters($post);
$this->assertFileExists($file = 'sandbox/default_colors/default_colors.css');
$content = file_get_contents($file);
$expected = ':root {
--background-color: pink;
}
';
$this->assertEquals($expected, $content);
}
/**
* Test the save plugin parameters hook with no color specified.
*/
public function testSavePluginParametersNone()
{
hook_default_colors_save_plugin_parameters([]);
$this->assertFileNotExists($file = 'sandbox/default_colors/default_colors.css');
}
/**
* Make sure that the CSS is properly included by the include hook.
*/
public function testIncludeWithFile()
{
$data = [
'css_files' => ['file1'],
'js_files' => ['file2'],
];
touch($file = 'sandbox/default_colors/default_colors.css');
$processedData = hook_default_colors_render_includes($data);
$this->assertCount(2, $processedData['css_files']);
$this->assertEquals($file, $processedData['css_files'][1]);
$this->assertCount(1, $processedData['js_files']);
}
/**
* Make sure that the CSS is not included by the include hook if the CSS file does not exist.
*/
public function testIncludeWithoutFile()
{
$data = [
'css_files' => ['file1'],
'js_files' => ['file2'],
];
$processedData = hook_default_colors_render_includes($data);
$this->assertEquals($data, $processedData);
}
/**
* Test helper function which generates CSS rules with valid input.
*/
public function testFormatCssRuleValid()
{
$data = [
'other1' => true,
'DEFAULT_COLORS_BLIP_BLOP' => 'shinyColor',
'other2' => ['yep'],
];
$result = default_colors_format_css_rule($data, 'DEFAULT_COLORS_BLIP_BLOP');
$this->assertEquals(' --blip-blop-color: shinyColor', $result);
$data = ['unknown-parameter' => true];
$result = default_colors_format_css_rule($data, 'unknown-parameter');
$this->assertEquals(' --unknown-parameter-color: 1', $result);
}
/**
* Test helper function which generates CSS rules with invalid input.
*/
public function testFormatCssRuleInvalid()
{
$result = default_colors_format_css_rule([], 'DEFAULT_COLORS_BLIP_BLOP');
$this->assertEmpty($result);
$data = [
'other1' => true,
'DEFAULT_COLORS_BLIP_BLOP' => 'shinyColor',
'other2' => ['yep'],
];
$result = default_colors_format_css_rule($data, '');
$this->assertEmpty($result);
}
}