diff --git a/README.markdown b/README.markdown index 6ef4f70..53a194a 100644 --- a/README.markdown +++ b/README.markdown @@ -171,4 +171,30 @@ Actually, the following constants can be overrided: - `APP_VERSION` => default value is master - `DB_FILENAME` => default value is `data/db.sqlite` - `DEBUG` => default is false (enable logs dump of picoFeed) -- `DEBUG_DIRECTORY` => default is /tmp (place to store log files) \ No newline at end of file +- `DEBUG_DIRECTORY` => default is /tmp (place to store log files) +- `THEME_DIRECTORY` => default is themes + +### How to create a theme for Miniflux? + +It's very easy to write a custom theme for Miniflux. + +A theme is just a CSS file, images and fonts. +A theme doesn't change the behaviour of the application but only the page design. + +The first step is to create a new directory structure for your theme: + + mkdir -p themes/mysuperskin/{css,img,fonts} + +The name of your theme should be only alphanumeric. +There is the following directories inside your theme: + +- `css`: Your stylesheet, the file must be named `app.css` (required) +- `img`: Theme images (not required) +- `fonts`: Theme fonts (not required) + +For a very basic theme example, have a look to the directory `examples\mytheme`. + +Miniflux use responsive design, so it's better if your theme can handle mobile devices. + +If you write a very cool theme for Miniflux, **send me your code to be available in the default installation!** +It would be awesome for everybody :) \ No newline at end of file diff --git a/common.php b/common.php index 3ef3f31..aee4c6c 100644 --- a/common.php +++ b/common.php @@ -16,6 +16,7 @@ defined('HTTP_TIMEOUT') or define('HTTP_TIMEOUT', 10); defined('DB_FILENAME') or define('DB_FILENAME', 'data/db.sqlite'); defined('DEBUG') or define('DEBUG', false); defined('DEBUG_DIRECTORY') or define('DEBUG_DIRECTORY', '/tmp'); +defined('THEME_DIRECTORY') or define('THEME_DIRECTORY', 'themes'); PicoTools\container('db', function() { diff --git a/examples/mytheme/css/app.css b/examples/mytheme/css/app.css new file mode 100644 index 0000000..00abd51 --- /dev/null +++ b/examples/mytheme/css/app.css @@ -0,0 +1,11 @@ +@font-face { + font-family: Inconsolata; + src: url(../fonts/Inconsolata-Regular.ttf); +} + +body { + margin-left: 300px; + padding-left: 10px; + border-left: 5px solid #000; + font-family: 'Inconsolata', sans-serif; +} diff --git a/examples/mytheme/fonts/Inconsolata-Bold.ttf b/examples/mytheme/fonts/Inconsolata-Bold.ttf new file mode 100755 index 0000000..15eb599 Binary files /dev/null and b/examples/mytheme/fonts/Inconsolata-Bold.ttf differ diff --git a/examples/mytheme/fonts/Inconsolata-Regular.ttf b/examples/mytheme/fonts/Inconsolata-Regular.ttf new file mode 100755 index 0000000..4ea3681 Binary files /dev/null and b/examples/mytheme/fonts/Inconsolata-Regular.ttf differ diff --git a/helpers.php b/helpers.php new file mode 100644 index 0000000..a0a0229 --- /dev/null +++ b/helpers.php @@ -0,0 +1,20 @@ + Model\get_languages(), 'autoflush_options' => Model\get_autoflush_options(), 'paging_options' => Model\get_paging_options(), + 'theme_options' => Model\get_themes(), 'menu' => 'config', 'title' => t('Preferences') ))); @@ -525,6 +527,7 @@ Router\post_action('config', function() { 'languages' => Model\get_languages(), 'autoflush_options' => Model\get_autoflush_options(), 'paging_options' => Model\get_paging_options(), + 'theme_options' => Model\get_themes(), 'menu' => 'config', 'title' => t('Preferences') ))); diff --git a/locales/fr_FR/translations.php b/locales/fr_FR/translations.php index 94bc247..4e6e5a4 100644 --- a/locales/fr_FR/translations.php +++ b/locales/fr_FR/translations.php @@ -1,6 +1,7 @@ 'Thème', 'No item' => 'Aucun élément', 'items' => 'éléments', 'There is %d empty feeds, there is maybe an error: %s...' => diff --git a/model.php b/model.php index 8121ca4..2436dc7 100644 --- a/model.php +++ b/model.php @@ -22,7 +22,7 @@ use PicoFeed\Reader; use PicoFeed\Export; -const DB_VERSION = 9; +const DB_VERSION = 10; const HTTP_USERAGENT = 'Miniflux - http://miniflux.net'; const LIMIT_ALL = -1; @@ -40,6 +40,28 @@ function get_languages() } +function get_themes() +{ + $themes = array( + 'original' => t('Original') + ); + + if (file_exists(THEME_DIRECTORY)) { + + $dir = new \DirectoryIterator(THEME_DIRECTORY); + + foreach ($dir as $fileinfo) { + + if (! $fileinfo->isDot() && $fileinfo->isDir()) { + $themes[$dir->getFilename()] = ucfirst($dir->getFilename()); + } + } + } + + return $themes; +} + + function get_autoflush_options() { return array( @@ -622,7 +644,7 @@ function get_config() { return \PicoTools\singleton('db') ->table('config') - ->columns('username', 'language', 'autoflush', 'nocontent', 'items_per_page') + ->columns('username', 'language', 'autoflush', 'nocontent', 'items_per_page', 'theme') ->findOne(); } @@ -687,6 +709,7 @@ function validate_config_update(array $values) new Validators\Required('autoflush', t('Value required')), new Validators\Required('items_per_page', t('Value required')), new Validators\Integer('items_per_page', t('Must be an integer')), + new Validators\Required('theme', t('Value required')), )); } else { @@ -710,8 +733,8 @@ function save_config(array $values) if (! empty($values['password'])) { $values['password'] = \password_hash($values['password'], PASSWORD_BCRYPT); - } - else { + + } else { unset($values['password']); } diff --git a/schema.php b/schema.php index bbe0a0e..30e1e20 100644 --- a/schema.php +++ b/schema.php @@ -3,6 +3,12 @@ namespace Schema; +function version_10($pdo) +{ + $pdo->exec('ALTER TABLE config ADD COLUMN theme TEXT DEFAULT "original"'); +} + + function version_9($pdo) { $pdo->exec('ALTER TABLE config ADD COLUMN items_per_page INTEGER DEFAULT 100'); diff --git a/templates/app_header.php b/templates/app_header.php index e29b16a..9c14526 100644 --- a/templates/app_header.php +++ b/templates/app_header.php @@ -10,7 +10,7 @@ <?= isset($title) ? Helper\escape($title) : 'miniflux' ?> - + diff --git a/templates/config.php b/templates/config.php index 9401408..a1c9aec 100644 --- a/templates/config.php +++ b/templates/config.php @@ -22,6 +22,9 @@
+ +
+