mirror of
https://github.com/getgrav/grav.git
synced 2025-12-05 23:39:58 +01:00
Compare commits
30 Commits
1.0.0-rc.2
...
1.0.0-rc.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e62ff07726 | ||
|
|
c97edb60a5 | ||
|
|
695793b752 | ||
|
|
c953ffb471 | ||
|
|
3d7fa06129 | ||
|
|
49d4fbcf3d | ||
|
|
fc18a40c35 | ||
|
|
1e81d5e38c | ||
|
|
daf8b53c0d | ||
|
|
8de55a745d | ||
|
|
6bf669815d | ||
|
|
8ba49e163d | ||
|
|
26918d90ab | ||
|
|
929b0806dc | ||
|
|
3e32e61db1 | ||
|
|
038693bffb | ||
|
|
9445aa43e6 | ||
|
|
658212e7be | ||
|
|
e91554770c | ||
|
|
7f134e39f4 | ||
|
|
07b2767ac9 | ||
|
|
0ca24a9786 | ||
|
|
c84c1366e7 | ||
|
|
ebf9bb5c18 | ||
|
|
70b67a0805 | ||
|
|
545b97716f | ||
|
|
f7140522f6 | ||
|
|
bd2f7088e9 | ||
|
|
5260c181a1 | ||
|
|
a9538adf2b |
19
CHANGELOG.md
19
CHANGELOG.md
@@ -1,3 +1,22 @@
|
||||
# v1.0.0-rc.4
|
||||
## 10/29/2015
|
||||
|
||||
1. [](#bugfix)
|
||||
* Fixed a fatal error if you have a collection with missing or invalid `@page: /route`
|
||||
|
||||
# v1.0.0-rc.3
|
||||
## 10/29/2015
|
||||
|
||||
1. [](#new)
|
||||
* New Page collection options! `@self.parent, @self.siblings, @self.descendants` + more
|
||||
* Whitelist of file types for fallback route functionality (images by default)
|
||||
1. [](#improved)
|
||||
* Assets switched from defines to streams
|
||||
1. [](#bugfix)
|
||||
* README.md typos fixed
|
||||
* Fixed issue with routes that have lang string in them (`/en/english`)
|
||||
* Trim strings before validation so whitespace is not satisfy 'required'
|
||||
|
||||
# v1.0.0-rc.2
|
||||
## 10/27/2015
|
||||
|
||||
|
||||
@@ -9,10 +9,10 @@ The underlying architecture of Grav is designed to use well-established and _bes
|
||||
* [Twig Templating](http://twig.sensiolabs.org/): for powerful control of the user interface
|
||||
* [Markdown](http://en.wikipedia.org/wiki/Markdown): for easy content creation
|
||||
* [YAML](http://yaml.org): for simple configuration
|
||||
* [Parsedown](http://parsedown.org/): for fast Markdown and Mardown Extra support
|
||||
* [Parsedown](http://parsedown.org/): for fast Markdown and Markdown Extra support
|
||||
* [Doctrine Cache](http://docs.doctrine-project.org/en/2.0.x/reference/caching.html): layer for performance
|
||||
* [Pimple Dependency Injection Container](http://pimple.sensiolabs.org/): for extensibility and maintainability
|
||||
* [Symfony Event Dispacher](http://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling
|
||||
* [Symfony Event Dispatcher](http://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling
|
||||
* [Symfony Console](http://symfony.com/doc/current/components/console/introduction.html): for CLI interface
|
||||
* [Gregwar Image Library](https://github.com/Gregwar/Image): for dynamic image manipulation
|
||||
|
||||
@@ -53,7 +53,7 @@ You can download [plugins](http://getgrav.org/downloads/plugins) or [themes](htt
|
||||
$ bin/gpm index
|
||||
```
|
||||
|
||||
This will display all the available plugins and then you can install one ore more with:
|
||||
This will display all the available plugins and then you can install one or more with:
|
||||
|
||||
```
|
||||
$ bin/gpm install <plugin/theme>
|
||||
@@ -76,7 +76,7 @@ $ bin/gpm update
|
||||
|
||||
# Contributing
|
||||
We appreciate any contribution to Grav, whether it is related to bugs, grammar, or simply a suggestion or improvement.
|
||||
However, we ask that any contribution follow our simple guidelines in order to be properly received.
|
||||
However, we ask that any contributions follow our simple guidelines in order to be properly received.
|
||||
|
||||
All our projects follow the [GitFlow branching model][gitflow-model], from development to release. If you are not familiar with it, there are several guides and tutorials to make you understand what it is about.
|
||||
|
||||
|
||||
@@ -215,6 +215,15 @@ form:
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
pages.fallback_types:
|
||||
type: selectize
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.FALLBACK_TYPES
|
||||
help: PLUGIN_ADMIN.FALLBACK_TYPES_HELP
|
||||
classes: fancy
|
||||
validate:
|
||||
type: commalist
|
||||
|
||||
languages:
|
||||
type: section
|
||||
title: PLUGIN_ADMIN.LANGUAGES
|
||||
@@ -774,6 +783,7 @@ form:
|
||||
|
||||
param_sep:
|
||||
type: select
|
||||
size: medium
|
||||
label: PLUGIN_ADMIN.PARAMETER_SEPARATOR
|
||||
classes: fancy
|
||||
help: PLUGIN_ADMIN.PARAMETER_SEPARATOR_HELP
|
||||
|
||||
@@ -49,11 +49,12 @@ pages:
|
||||
vary_accept_encoding: false # Add `Vary: Accept-Encoding` header
|
||||
redirect_default_route: false # Automatically redirect to a page's default route
|
||||
redirect_default_code: 301 # Default code to use for redirects
|
||||
redirect_trailing_slash: true # Handle automatically or 301 redirect a trailing / URL
|
||||
redirect_trailing_slash: true # Handle automatically or 301 redirect a trailing / URL
|
||||
ignore_files: [.DS_Store] # Files to ignore in Pages
|
||||
ignore_folders: [.git, .idea] # Folders to ignore in Pages
|
||||
ignore_hidden: true # Ignore all Hidden files and folders
|
||||
url_taxonomy_filters: true # Enable auto-magic URL-based taxonomy filters for page collections
|
||||
fallback_types: [png,jpg,jpeg,gif] # Allowed types of files found if accessed via Page route
|
||||
|
||||
cache:
|
||||
enabled: true # Set to true to enable caching
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// Some standard defines
|
||||
define('GRAV', true);
|
||||
define('GRAV_VERSION', '1.0.0-rc.2');
|
||||
define('GRAV_VERSION', '1.0.0-rc.4');
|
||||
define('DS', '/');
|
||||
|
||||
// Directories and Paths
|
||||
@@ -13,14 +13,14 @@ define('ROOT_DIR', GRAV_ROOT . '/');
|
||||
define('USER_PATH', 'user/');
|
||||
define('USER_DIR', ROOT_DIR . USER_PATH);
|
||||
define('SYSTEM_DIR', ROOT_DIR .'system/');
|
||||
define('ASSETS_DIR', ROOT_DIR . 'assets/');
|
||||
define('CACHE_DIR', ROOT_DIR . 'cache/');
|
||||
define('IMAGES_DIR', ROOT_DIR . 'images/');
|
||||
define('LOG_DIR', ROOT_DIR .'logs/');
|
||||
define('ACCOUNTS_DIR', USER_DIR .'accounts/');
|
||||
define('PAGES_DIR', USER_DIR .'pages/');
|
||||
|
||||
// DEPRECATED: Do not use!
|
||||
define('ASSETS_DIR', ROOT_DIR . 'assets/');
|
||||
define('IMAGES_DIR', ROOT_DIR . 'images/');
|
||||
define('ACCOUNTS_DIR', USER_DIR .'accounts/');
|
||||
define('PAGES_DIR', USER_DIR .'pages/');
|
||||
define('DATA_DIR', USER_DIR .'data/');
|
||||
define('LIB_DIR', SYSTEM_DIR .'src/');
|
||||
define('PLUGINS_DIR', USER_DIR .'plugins/');
|
||||
|
||||
@@ -74,6 +74,8 @@ class Assets
|
||||
protected $config;
|
||||
protected $base_url;
|
||||
protected $timestamp = '';
|
||||
protected $assets_dir;
|
||||
protected $assets_url;
|
||||
|
||||
// Default values for pipeline settings
|
||||
protected $css_minify = true;
|
||||
@@ -117,7 +119,7 @@ class Assets
|
||||
}
|
||||
|
||||
// Pipeline requires public dir
|
||||
if (($this->js_pipeline || $this->css_pipeline) && !is_dir(ASSETS_DIR)) {
|
||||
if (($this->js_pipeline || $this->css_pipeline) && !is_dir($this->assets_dir)) {
|
||||
throw new \Exception('Assets: Public dir not found');
|
||||
}
|
||||
|
||||
@@ -175,6 +177,11 @@ class Assets
|
||||
$base_url = self::getGrav()['base_url'];
|
||||
$asset_config = (array)$config->get('system.assets');
|
||||
|
||||
/** @var Locator $locator */
|
||||
$locator = self::$grav['locator'];
|
||||
$this->assets_dir = self::getGrav()['locator']->findResource('asset://') . DS;
|
||||
$this->assets_url = self::getGrav()['locator']->findResource('asset://', false);
|
||||
|
||||
$this->config($asset_config);
|
||||
$this->base_url = $base_url . '/';
|
||||
|
||||
@@ -621,8 +628,8 @@ class Assets
|
||||
|
||||
$file = md5(json_encode($this->css) . $this->css_minify . $this->css_rewrite . $group) . '.css';
|
||||
|
||||
$relative_path = "{$this->base_url}" . basename(ASSETS_DIR) . "/{$file}";
|
||||
$absolute_path = ASSETS_DIR . $file;
|
||||
$relative_path = "{$this->base_url}{$this->assets_url}/{$file}";
|
||||
$absolute_path = $this->assets_dir . $file;
|
||||
|
||||
// If pipeline exist return it
|
||||
if (file_exists($absolute_path)) {
|
||||
@@ -689,8 +696,8 @@ class Assets
|
||||
|
||||
$file = md5(json_encode($this->js) . $this->js_minify . $group) . '.js';
|
||||
|
||||
$relative_path = "{$this->base_url}" . basename(ASSETS_DIR) . "/{$file}";
|
||||
$absolute_path = ASSETS_DIR . $file;
|
||||
$relative_path = "{$this->base_url}{$this->assets_url}/{$file}";
|
||||
$absolute_path = $this->assets_dir . $file;
|
||||
|
||||
// If pipeline exist return it
|
||||
if (file_exists($absolute_path)) {
|
||||
@@ -852,12 +859,12 @@ class Assets
|
||||
public function addDir($directory, $pattern = self::DEFAULT_REGEX)
|
||||
{
|
||||
// Check if public_dir exists
|
||||
if (!is_dir(ASSETS_DIR)) {
|
||||
if (!is_dir($this->assets_dir)) {
|
||||
throw new Exception('Assets: Public dir not found');
|
||||
}
|
||||
|
||||
// Get files
|
||||
$files = $this->rglob(ASSETS_DIR . DIRECTORY_SEPARATOR . $directory, $pattern, ASSETS_DIR);
|
||||
$files = $this->rglob($this->assets_dir . DIRECTORY_SEPARATOR . $directory, $pattern, $this->assets_dir);
|
||||
|
||||
// No luck? Nothing to do
|
||||
if (!$files) {
|
||||
|
||||
@@ -194,7 +194,7 @@ class Config extends Data
|
||||
$checkConfig = $this->get('system.cache.check.config', true);
|
||||
$checkSystem = $this->get('system.cache.check.system', true);
|
||||
|
||||
if (!$checkBlueprints && !!$checkLanguages && $checkConfig && !$checkSystem) {
|
||||
if (!$checkBlueprints && !$checkLanguages && !$checkConfig && !$checkSystem) {
|
||||
$this->messages[] = 'Skip configuration timestamp check.';
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -224,16 +224,6 @@ class Data implements DataInterface
|
||||
return $this->file()->raw();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the data items.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function items()
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or get the data storage.
|
||||
*
|
||||
|
||||
@@ -588,6 +588,10 @@ class Validation
|
||||
|
||||
public static function validateRequired($value, $params)
|
||||
{
|
||||
if (is_string($value)) {
|
||||
$value = trim($value);
|
||||
}
|
||||
|
||||
return (bool) $params !== true || !empty($value);
|
||||
}
|
||||
|
||||
|
||||
@@ -457,6 +457,16 @@ class Grav extends Container
|
||||
/** @var Uri $uri */
|
||||
$uri = $this['uri'];
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $this['config'];
|
||||
|
||||
$uri_extension = $uri->extension();
|
||||
|
||||
// Only allow whitelisted types to fallback
|
||||
if (!in_array($uri_extension, $config->get('system.pages.fallback_types'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
$path_parts = pathinfo($path);
|
||||
$page = $this['pages']->dispatch($path_parts['dirname'], true);
|
||||
if ($page) {
|
||||
@@ -478,7 +488,6 @@ class Grav extends Container
|
||||
}
|
||||
|
||||
// unsupported media type, try to download it...
|
||||
$uri_extension = $uri->extension();
|
||||
if ($uri_extension) {
|
||||
$extension = $uri_extension;
|
||||
} else {
|
||||
@@ -491,7 +500,7 @@ class Grav extends Container
|
||||
|
||||
if ($extension) {
|
||||
$download = true;
|
||||
if (in_array(ltrim($extension, '.'), $this['config']->get('system.media.unsupported_inline_types', []))) {
|
||||
if (in_array(ltrim($extension, '.'), $config->get('system.media.unsupported_inline_types', []))) {
|
||||
$download = false;
|
||||
}
|
||||
Utils::download($page->path() . DIRECTORY_SEPARATOR . $uri->basename(), $download);
|
||||
|
||||
@@ -162,7 +162,7 @@ class Language
|
||||
*/
|
||||
public function setActiveFromUri($uri)
|
||||
{
|
||||
$regex = '/(^\/(' . $this->getAvailable() . ')).*/';
|
||||
$regex = '/(^\/(' . $this->getAvailable() . '))(?:\/.*|$)/i';
|
||||
|
||||
// if languages set
|
||||
if ($this->enabled()) {
|
||||
|
||||
@@ -36,6 +36,18 @@ class Collection extends Iterator
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single page to a collection
|
||||
*
|
||||
* @param Page $page
|
||||
* @return $this
|
||||
*/
|
||||
public function addPage(Page $page)
|
||||
{
|
||||
$this->items[$page->path()] = ['slug' => $page->slug()];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Create a copy of this collection
|
||||
@@ -96,6 +108,7 @@ class Collection extends Iterator
|
||||
* Remove item from the list.
|
||||
*
|
||||
* @param Page|string|null $key
|
||||
* @return $this|void
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function remove($key = null)
|
||||
@@ -110,6 +123,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
parent::remove($key);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1935,7 +1935,7 @@ class Page
|
||||
// Format: @command.param
|
||||
$cmd = $value;
|
||||
$params = array();
|
||||
} elseif (is_array($value) && count($value) == 1) {
|
||||
} elseif (is_array($value) && count($value) == 1 && !is_int(key($value))) {
|
||||
// Format: @command.param: { attr1: value1, attr2: value2 }
|
||||
$cmd = (string) key($value);
|
||||
$params = (array) current($value);
|
||||
@@ -1957,51 +1957,92 @@ class Page
|
||||
return $value;
|
||||
}
|
||||
|
||||
/** @var Pages $pages */
|
||||
$pages = self::getGrav()['pages'];
|
||||
|
||||
$parts = explode('.', $cmd);
|
||||
$current = array_shift($parts);
|
||||
|
||||
$results = null;
|
||||
$results = new Collection();
|
||||
switch ($current) {
|
||||
case '@self':
|
||||
if (!empty($parts)) {
|
||||
switch ($parts[0]) {
|
||||
case 'modular':
|
||||
// @self.modular: false (alternative to @self.children)
|
||||
if (!empty($params) && $params[0] === false) {
|
||||
$results = $this->children()->nonModular()->published();
|
||||
$results = $this->children()->nonModular();
|
||||
break;
|
||||
}
|
||||
$results = $this->children()->modular()->published();
|
||||
$results = $this->children()->modular();
|
||||
break;
|
||||
case 'children':
|
||||
$results = $this->children()->nonModular()->published();
|
||||
$results = $this->children()->nonModular();
|
||||
break;
|
||||
|
||||
case 'parent':
|
||||
$collection = new Collection();
|
||||
$results = $collection->addPage($this->parent());
|
||||
break;
|
||||
|
||||
case 'siblings':
|
||||
$results = $this->parent()->children()->remove($this->path());
|
||||
break;
|
||||
|
||||
case 'descendants':
|
||||
$results = $pages->all($this)->remove($this->path())->nonModular();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$results = $results->published();
|
||||
break;
|
||||
|
||||
case '@page':
|
||||
$page = null;
|
||||
|
||||
if (!empty($params)) {
|
||||
/** @var Pages $pages */
|
||||
$pages = self::getGrav()['pages'];
|
||||
$page = $this->find($params[0]);
|
||||
}
|
||||
|
||||
list($what, $recurse) = array_pad($params, 2, null);
|
||||
// safety check in case page is not found
|
||||
if (!isset($page)) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
if ($what == '@root') {
|
||||
$page = $pages->root();
|
||||
} else {
|
||||
$page = $this->find($what);
|
||||
// Handle a @page.descendants
|
||||
if (!empty($parts)) {
|
||||
switch ($parts[0]) {
|
||||
case 'self':
|
||||
$results = new Collection();
|
||||
$results = $results->addPage($page);
|
||||
break;
|
||||
|
||||
case 'descendants':
|
||||
$results = $pages->all($page)->remove($page->path());
|
||||
break;
|
||||
|
||||
case 'children':
|
||||
$results = $page->children();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$results = $page->children();
|
||||
}
|
||||
|
||||
if ($page) {
|
||||
if ($recurse) {
|
||||
$results = $pages->all($page)->nonModular()->published();
|
||||
} else {
|
||||
$results = $page->children()->nonModular()->published();
|
||||
}
|
||||
}
|
||||
$results = $results->nonModular()->published();
|
||||
|
||||
break;
|
||||
|
||||
case '@root':
|
||||
if (!empty($parts) && $parts[0] == 'descendants') {
|
||||
$results = $pages->all($pages->root())->nonModular()->published();
|
||||
} else {
|
||||
$results = $pages->root()->children()->nonModular()->published();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case '@taxonomy':
|
||||
// Gets a collection of pages by using one of the following formats:
|
||||
// @taxonomy.category: blog
|
||||
|
||||
@@ -133,11 +133,15 @@ class Uri
|
||||
// set the original basename
|
||||
$this->basename = $parts['basename'];
|
||||
|
||||
// set the extension
|
||||
if (isset($parts['extension'])) {
|
||||
$this->extension = $parts['extension'];
|
||||
}
|
||||
|
||||
$valid_page_types = implode('|', $config->get('system.pages.types'));
|
||||
|
||||
if (preg_match("/\.(".$valid_page_types.")$/", $parts['basename'])) {
|
||||
$uri = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, $parts['dirname']), DS). '/' .$parts['filename'];
|
||||
$this->extension = $parts['extension'];
|
||||
}
|
||||
|
||||
// set the new url
|
||||
|
||||
Reference in New Issue
Block a user