Use .yml files to configure Pico

Instead of using `*.config.php` files, use `*.yml` files to configure Pico. YAML is much easier to understand, more user friendly and (at least a bit) more error-tolerant, but still very powerful. Don't break BC by letting `PicoDeprecated` still read `config/config.php`.
This commit is contained in:
Daniel Rudolf 2017-02-05 16:52:18 +01:00
parent 0a080c8965
commit 9b7523b9e8
No known key found for this signature in database
GPG key ID: A061F02CD8DE4538
6 changed files with 121 additions and 91 deletions

2
.gitignore vendored
View file

@ -21,7 +21,7 @@ desktop.ini
/_build/deploy-*.git
# User config
/config/config.php
/config/config.yml
# User themes
/themes/*

View file

@ -1,61 +0,0 @@
<?php
/**
* Pico configuration
*
* This is the configuration file for {@link Pico}. It comes loaded with the
* default values, which can be found in {@link Pico::getConfig()} (see
* {@path "lib/Pico.php"}).
*
* To override any of the default settings below, copy this file to
* {@path "config/config.php"}, uncomment the line, then make and
* save your changes.
*
* @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License
* @version 2.0
*/
/*
* BASIC
*/
// $config['site_title'] = 'Pico'; // Site title
// $config['base_url'] = ''; // Override base URL (e.g. http://example.com/pico/)
// $config['rewrite_url'] = null; // A boolean indicating forced URL rewriting
/*
* THEME
*/
// $config['theme'] = 'default'; // Set the theme (defaults to "default")
// $config['theme_url'] = ''; // Override the base URL of the themes folder (e.g. http://example.com/pico/themes/)
// $config['theme_config'] = array( // Settings of the theme; depends on the theme used
// 'widescreen' => false // Default theme: Allocate more horicontal space (i.e. make the site container wider)
// );
// $config['twig_config'] = array( // Twig settings
// 'cache' => false, // To enable Twig caching change this to a path to a writable directory
// 'autoescape' => false, // Auto-escape Twig vars
// 'debug' => false // Enable Twig debug
// );
/*
* CONTENT
*/
// $config['date_format'] = '%D %T'; // Set the PHP date format as described here: http://php.net/manual/en/function.strftime.php
// $config['pages_order_by'] = 'alpha'; // Order pages by "alpha" or "date"
// $config['pages_order'] = 'asc'; // Order pages "asc" or "desc"
// $config['content_dir'] = 'content-sample/'; // Content directory
// $config['content_ext'] = '.md'; // File extension of content files to serve
/*
* TIMEZONE
*/
// $config['timezone'] = 'UTC'; // Timezone may be required by your php install
/*
* PLUGINS
*/
// $config['DummyPlugin.enabled'] = false; // Force DummyPlugin to be disabled
/*
* CUSTOM
*/
// $config['custom_setting'] = 'Hello'; // Can be accessed by {{ config.custom_setting }} in a theme

View file

@ -0,0 +1,41 @@
##
# Basic
#
site_title: Pico # The title of your website
base_url: ~ # Pico will try to guess its base URL, if this fails, override it here
# Example: http://example.com/pico/
rewrite_url: ~ # A boolean (true or false) indicating whether URL rewriting is forced
timezone: UTC # Your PHP installation might require you to manually specify a timezone
##
# Theme
#
theme: default # The name of your custom theme
theme_url: ~ # Pico will try to guess the URL to the themes dir of your installation
# If this fails, override it here. Example: http://example.com/pico/themes/
theme_config:
widescreen: false # Default theme: Use more horicontal space (i.e. make the site container wider)
twig_config:
cache: false # Enable Twig template caching by specifying a path to a writable directory
autoescape: false # Let Twig escape variables by default
debug: false # Enable Twig's debugging mode
##
# Content
#
date_format: %D %T # Pico's default date format
# List of available variables: http://php.net/manual/en/function.strftime.php
pages_order_by: alpha # Change how Pico sorts pages ("alpha" for alphabetical order, or "date")
pages_order: asc # Sort pages in ascending ("asc") or descending ("desc") order
content_dir: content/ # The path to Pico's content directory
content_ext: .md # The file extension of your Markdown files
##
# Plugins
#
DummyPlugin.enabled: false # Force the plugin "DummyPlugin" to be disabled
##
# Custom
#
my_custom_setting: Hello World! # You can access custom settings in themes using {{ config.my_custom_setting }}

View file

@ -263,10 +263,12 @@ to the brand new plugin system introduced with Pico 1.0. Please refer to the
## Config
You can override the default Pico settings (and add your own custom settings)
by editing `config/config.php` in the Pico directory. For a brief overview of
the available settings and their defaults see `config/config.php.template`. To
override a setting, copy `config/config.php.template` to `config/config.php`,
uncomment the setting and set your custom value.
by editing `config/config.yml` in the Pico directory. For a brief overview of
the available settings and their defaults see `config/config.yml.template`. To
override a setting, simply copy the line from `config/config.yml.template`
to `config/config.yml` and set your custom value. Pico will read all `*.yml`
files in the `config/` dir, thus you can even use a distinct settings file to
configure your custom theme (e.g. `config/my_theme.yml`).
### URL Rewriting

View file

@ -670,25 +670,26 @@ class Pico
*/
protected function loadConfig()
{
// scope isolated require()
$includeClosure = function ($configFile) {
require($configFile);
return (isset($config) && is_array($config)) ? $config : array();
// load config closure
$yamlParser = $this->getYamlParser();
$loadConfigClosure = function ($configFile) use ($yamlParser) {
$yaml = file_get_contents($configFile);
$config = $yamlParser->parse($yaml);
return is_array($config) ? $config : array();
};
if (PHP_VERSION_ID >= 50400) {
$includeClosure = $includeClosure->bindTo(null);
}
// load main config file (config/config.php)
// load main config file (config/config.yml)
$this->config = is_array($this->config) ? $this->config : array();
if (file_exists($this->getConfigDir() . 'config.php')) {
$this->config += $includeClosure($this->getConfigDir() . 'config.php');
if (file_exists($this->getConfigDir() . 'config.yml')) {
$this->config += $loadConfigClosure($this->getConfigDir() . 'config.yml');
}
// merge $config of config/*.config.php files
$configFiles = $this->getFilesGlob($this->getConfigDir() . '?*.config.php');
// merge $config of config/*.yml files
$configFiles = $this->getFilesGlob($this->getConfigDir() . '*.yml');
foreach ($configFiles as $configFile) {
$this->config += $includeClosure($configFile);
if ($configFile !== 'config.yml') {
$this->config += $loadConfigClosure($configFile);
}
}
// merge default config
@ -697,14 +698,14 @@ class Pico
'base_url' => '',
'rewrite_url' => null,
'theme' => 'default',
'theme_url' => '',
'theme_url' => null,
'date_format' => '%D %T',
'twig_config' => array('cache' => false, 'autoescape' => false, 'debug' => false),
'pages_order_by' => 'alpha',
'pages_order' => 'asc',
'content_dir' => null,
'content_ext' => '.md',
'timezone' => ''
'timezone' => null
);
if (!$this->config['base_url']) {
@ -1333,8 +1334,8 @@ class Pico
protected function sortPages()
{
// sort pages
$order = $this->getConfig('pages_order');
$orderBy = $this->getConfig('pages_order_by');
$order = strtolower($this->getConfig('pages_order'));
$orderBy = strtolower($this->getConfig('pages_order_by'));
if (($orderBy !== 'date') && ($orderBy !== 'alpha')) {
return;

View file

@ -4,11 +4,9 @@
* Maintain backward compatibility to older Pico releases
*
* This plugin exists for backward compatibility and is disabled by default.
* It gets automatically enabled when a plugin which doesn't implement
* {@link PicoPluginInterface} is loaded. This plugin triggers deprecated
* events and automatically enables {@link PicoParsePagesContent} and
* {@link PicoExcerpt}. These plugins heavily impact Pico's performance! You
* can disable this plugin by calling {@link PicoDeprecated::setEnabled()}.
* It gets automatically enabled when a plugin which either doesn't implement
* {@link PicoPluginInterface} (plugins for Pico 0.X) or define the
* {@link PicoDeprecated::API_VERSION} (plugins for Pico 1.0) is loaded.
*
* The following deprecated events are triggered by this plugin:
*
@ -32,9 +30,10 @@
* | onPageRendering | before_render($twigVariables, $twig, $templateName) |
* | onPageRendered | after_render($output) |
*
* Since Pico 1.0 the config is stored in {@path "config/config.php"}. This
* plugin tries to read {@path "config.php"} in Pico's root dir and overwrites
* all settings previously specified in {@path "config/config.php"}.
* Since Pico 2.0 the config is stored in `config/*.yml` files. This plugin
* also tries to read {@path "config/config.php"} (Pico 1.0) and
* {@path "config.php"} in Pico's root dir (Pico 0.X) and overwrites all
* previously specified settings.
*
* @author Daniel Rudolf
* @link http://picocms.org
@ -110,6 +109,7 @@ class PicoDeprecated extends AbstractPicoPlugin
public function onConfigLoaded(array &$config)
{
$this->defineConstants();
$this->loadScriptedConfig($config);
$this->loadRootDirConfig($config);
$this->enablePlugins();
$GLOBALS['config'] = &$config;
@ -154,6 +154,53 @@ class PicoDeprecated extends AbstractPicoPlugin
}
}
/**
* Read config.php in Pico's config dir (i.e. config/config.php)
*
* @see PicoDeprecated::onConfigLoaded()
* @see Pico::loadConfig()
* @param array &$realConfig array of config variables
* @return void
*/
protected function loadScriptedConfig(array &$realConfig)
{
if (file_exists($this->getConfigDir() . 'config.php')) {
// scope isolated require()
$includeClosure = function ($configFile) {
require($configFile);
return (isset($config) && is_array($config)) ? $config : array();
};
if (PHP_VERSION_ID >= 50400) {
$includeClosure = $includeClosure->bindTo(null);
}
// config.php in Pico::$configDir (i.e. config/config.php) is deprecated
// use *.yml files in Pico::$configDir instead
$config = $includeClosure($this->getConfigDir() . 'config.php');
if ($config) {
if (!empty($config['base_url'])) {
$config['base_url'] = rtrim($config['base_url'], '/') . '/';
}
if (!empty($config['content_dir'])) {
$config['content_dir'] = $this->getAbsolutePath($config['content_dir']);
}
if (!empty($config['theme_url'])) {
if (preg_match('#^[A-Za-z][A-Za-z0-9+\-.]*://#', $config['theme_url'])) {
$config['theme_url'] = rtrim($config['theme_url'], '/') . '/';
} else {
$config['theme_url'] = $this->getBaseUrl() . rtrim($config['theme_url'], '/') . '/';
}
}
if (!empty($config['timezone'])) {
date_default_timezone_set($config['timezone']);
}
$realConfig = $config + $realConfig;
}
}
}
/**
* Read config.php in Pico's root dir
*