Merge branch 'release/1.0.0-rc.2'

This commit is contained in:
Andy Miller
2015-10-27 14:47:43 -06:00
15 changed files with 204 additions and 74 deletions

View File

@@ -52,7 +52,11 @@ script:
FILES="$RT_DEVTOOLS/grav-dist/*.zip";
for file in ${FILES[@]}; do
NAME=${file##*/};
REPO="$(echo ${NAME} | rev | cut -f 2- -d "-" | rev)";
if [[ "$NAME" == *"-rc"* ]]; then
REPO="$(echo ${NAME} | rev | cut -f 3- -d "-" | rev)";
else
REPO="$(echo ${NAME} | rev | cut -f 2- -d "-" | rev)";
fi;
if [[ $REPO == 'grav' || $REPO == 'grav-admin' || $REPO == 'grav-update' ]]; then
REPO="grav";
fi;
@@ -60,7 +64,7 @@ script:
ASSETS="$(echo "${API}" | node gh-assets.js)";
TAG="$(echo "${API}" | grep tag_name | head -n 1 | cut -d '"' -f 4)";
if [ $REPO == "grav" ]; then
TAG=$TRAVIS_TAG;
TAG="$TRAVIS_TAG";
fi;
if [ ! -z "$ASSETS" ]; then
for asset in ${ASSETS[@]}; do

View File

@@ -1,3 +1,23 @@
# v1.0.0-rc.2
## 10/27/2015
1. [](#new)
* Added support for CSS Asset groups
* Added a `wrapped_site` system option for themes/plugins to use
* Pass `Page` object as event to `onTwigPageVariables()` event hook
* New `Data.items()` method to get all items
1. [](#improved)
* Missing pipelined remote asset will now fail quietly
* More reliably handle inline JS and CSS to remove only surrounding HTML tags
* `Medium.meta` returns new Data object so null checks are possible
* Improved Medium metadata merging to allow for automatic title/alt/class attributes
* Moved Grav object to global variable rather than template variable (useful for macros)
* German language improvements
* Updated bundled composer
1. [](#bugfix)
* Accept variety of `true` values in `User.authorize()` method
* Fix for `Validation` throwing an error if no label set
# v1.0.0-rc.1
## 10/23/2015
@@ -18,7 +38,7 @@
1. [](#improved)
* Moved hardcoded mimetypes to `media.yaml` to be treated as Page media files
* Set `errors: display: false` by default in `system.yaml`
* Strip out extra slashes in the URI
* Strip out extra slashes in the URI
* Validate hostname to ensure it is valid
* Ignore more SCM folders in Backups
* Removed `home_redirect` settings from `system.yaml`
@@ -29,7 +49,7 @@
* Debugbar vendor library update
* Always fallback to english if other translations are not available
1. [](#bugfix)
* Fix for redirecting external URL with multi-language
* Fix for redirecting external URL with multi-language
* Fix for Asset pipeline not respecting asset groups
* Fix language files with child/parent theme relationships
* Fixed a regression issue resulting in incorrect default language

Binary file not shown.

View File

@@ -750,6 +750,17 @@ form:
underline: true
fields:
wrapped_site:
type: toggle
label: PLUGIN_ADMIN.WRAPPED_SITE
highlight: 0
help: PLUGIN_ADMIN.WRAPPED_SITE_HELP
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
absolute_urls:
type: toggle
label: PLUGIN_ADMIN.ABSOLUTE_URLS

View File

@@ -2,6 +2,7 @@ absolute_urls: false # Absolute or relative URLs for `base_url
timezone: '' # Valid values: http://php.net/manual/en/timezones.php
default_locale: # Default locale (defaults to system)
param_sep: ':' # Parameter separator, use ';' for Apache on windows
wrapped_site: false # For themes/plugins to know if Grav is wrapped by another platform
languages:
supported: [] # List of languages supported. eg: [en, fr, de]

View File

@@ -2,7 +2,7 @@
// Some standard defines
define('GRAV', true);
define('GRAV_VERSION', '1.0.0-rc.1');
define('GRAV_VERSION', '1.0.0-rc.2');
define('DS', '/');
// Directories and Paths

View File

@@ -1,43 +1,43 @@
INFLECTOR_IRREGULAR:
'person': 'personen'
'man': 'menschen'
'child': 'kinder'
'sex': 'geschlecht'
'move': 'züge'
'person': 'Personen'
'man': 'Menschen'
'child': 'Kinder'
'sex': 'Geschlecht'
'move': 'Züge'
NICETIME:
NO_DATE_PROVIDED: Keine Daten vorhanden
BAD_DATE: Falsches Datum
AGO: her
FROM_NOW: ab jetzt
SECOND: sekunde
MINUTE: minute
HOUR: stunde
DAY: tag
WEEK: woche
MONTH: monat
YEAR: jahr
DECADE: dekade
SECOND: Sekunde
MINUTE: Minute
HOUR: Stunde
DAY: Tag
WEEK: Woche
MONTH: Monat
YEAR: Jahr
DECADE: Dekade
SEC: sek
MIN: min
HR: std
DAY: tag
DAY: Tag
WK: wo
MO: mo
YR: yh
DEC: dec
SECOND_PLURAL: sekunden
MINUTE_PLURAL: minuten
HOUR_PLURAL: stunden
DAY_PLURAL: tage
WEEK_PLURAL: wochen
MONTH_PLURAL: monate
YEAR_PLURAL: jahre
DECADE_PLURAL: dekaden
SEC_PLURAL: sekunden
MIN_PLURAL: minuten
HR_PLURAL: stunden
DAY_PLURAL: tage
WK_PLURAL: wochen
MO_PLURAL: monate
YR_PLURAL: jahre
DEC_PLURAL: dekaden
SECOND_PLURAL: Sekunden
MINUTE_PLURAL: Minuten
HOUR_PLURAL: Stunden
DAY_PLURAL: Tage
WEEK_PLURAL: Wochen
MONTH_PLURAL: Monate
YEAR_PLURAL: Jahre
DECADE_PLURAL: Dekaden
SEC_PLURAL: Sekunden
MIN_PLURAL: Minuten
HR_PLURAL: Stunden
DAY_PLURAL: Tage
WK_PLURAL: Wochen
MO_PLURAL: Monate
YR_PLURAL: Jahre
DEC_PLURAL: Dekaden

View File

@@ -42,6 +42,8 @@ class Assets
/** @const Regex to match CSS import content */
const CSS_IMPORT_REGEX = '{@import(.*);}';
const HTML_TAG_REGEX = '#(<([A-Z][A-Z0-9]*)>)+(.*)(<\/\2>)#is';
/**
* Closure used by the pipeline to fetch assets.
@@ -227,21 +229,22 @@ class Assets
* It checks for duplicates.
* You may add more than one asset passing an array as argument.
*
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param bool $pipeline false if this should not be pipelined
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param bool $pipeline false if this should not be pipelined
* @param null $group
*
* @return $this
*/
public function addCss($asset, $priority = null, $pipeline = null)
public function addCss($asset, $priority = null, $pipeline = null, $group = null)
{
if (is_array($asset)) {
foreach ($asset as $a) {
$this->addCss($a, $priority, $pipeline);
$this->addCss($a, $priority, $pipeline, $group);
}
return $this;
} elseif (isset($this->collections[$asset])) {
$this->add($this->collections[$asset], $priority, $pipeline);
$this->add($this->collections[$asset], $priority, $pipeline, $group);
return $this;
}
@@ -253,7 +256,8 @@ class Assets
'asset' => $asset,
'priority' => intval($priority ?: 10),
'order' => count($this->css),
'pipeline' => $pipeline ?: true
'pipeline' => $pipeline ?: true,
'group' => $group ?: 'head'
];
// check for dynamic array and merge with defaults
@@ -369,20 +373,27 @@ class Assets
* For adding chunks of string-based inline CSS
*
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param int $priority the priority, bigger comes first
* @param null $group
*
* @return $this
*/
public function addInlineCss($asset, $priority = null)
public function addInlineCss($asset, $priority = null, $group = null)
{
$asset = trim($asset);
if (is_a($asset, 'Twig_Markup')) {
$asset = strip_tags((string)$asset);
preg_match(self::HTML_TAG_REGEX, $asset, $matches );
if (isset($matches[3])) {
$asset = $matches[3];
}
}
$data = [
'priority' => intval($priority ?: 10),
'order' => count($this->inline_css),
'asset' => $asset
'asset' => $asset,
'group' => $group ?: 'head'
];
// check for dynamic array and merge with defaults
@@ -416,8 +427,13 @@ class Assets
*/
public function addInlineJs($asset, $priority = null, $group = null)
{
$asset = trim($asset);
if (is_a($asset, 'Twig_Markup')) {
$asset = strip_tags((string)$asset);
preg_match(self::HTML_TAG_REGEX, $asset, $matches );
if (isset($matches[3])) {
$asset = $matches[3];
}
}
$data = [
@@ -447,11 +463,12 @@ class Assets
/**
* Build the CSS link tags.
*
* @param string $group name of the group
* @param array $attributes
*
* @return string
*/
public function css($attributes = [])
public function css($group = 'head', $attributes = [])
{
if (!$this->css) {
return null;
@@ -479,29 +496,37 @@ class Assets
$attributes = $this->attributes(array_merge(['type' => 'text/css', 'rel' => 'stylesheet'], $attributes));
$output = '';
$inline_css = '';
if ($this->css_pipeline) {
$pipeline_result = $this->pipelineCss();
$pipeline_result = $this->pipelineCss($group);
if ($pipeline_result) {
$output .= '<link href="' . $pipeline_result . '"' . $attributes . ' />' . "\n";
}
foreach ($this->css_no_pipeline as $file) {
$media = isset($file['media']) ? sprintf(' media="%s"', $file['media']) : '';
$output .= '<link href="' . $file['asset'] . $this->timestamp . '"' . $attributes . $media . ' />' . "\n";
if ($group && $file['group'] == $group) {
$media = isset($file['media']) ? sprintf(' media="%s"', $file['media']) : '';
$output .= '<link href="' . $file['asset'] . $this->timestamp . '"' . $attributes . $media . ' />' . "\n";
}
}
} else {
foreach ($this->css as $file) {
$media = isset($file['media']) ? sprintf(' media="%s"', $file['media']) : '';
$output .= '<link href="' . $file['asset'] . $this->timestamp . '"' . $attributes . $media . ' />' . "\n";
if ($group && $file['group'] == $group) {
$media = isset($file['media']) ? sprintf(' media="%s"', $file['media']) : '';
$output .= '<link href="' . $file['asset'] . $this->timestamp . '"' . $attributes . $media . ' />' . "\n";
}
}
}
// Render Inline CSS
if (count($this->inline_css) > 0) {
$output .= "<style>\n";
foreach ($this->inline_css as $inline) {
$output .= $inline['asset'] . "\n";
foreach ($this->inline_css as $inline) {
if ($group && $inline['group'] == $group) {
$inline_css .= $inline['asset'] . "\n";
}
$output .= "</style>\n";
}
if ($inline_css) {
$output .= "\n<style>\n" . $inline_css . "\n</style>\n";
}
@@ -582,7 +607,7 @@ class Assets
*
* @return string
*/
protected function pipelineCss()
protected function pipelineCss($group = 'head')
{
/** @var Cache $cache */
$cache = self::getGrav()['cache'];
@@ -594,7 +619,7 @@ class Assets
// clear no-pipeline assets lists
$this->css_no_pipeline = [];
$file = md5(json_encode($this->css) . $this->css_minify . $this->css_rewrite) . '.css';
$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;
@@ -606,10 +631,12 @@ class Assets
// Remove any non-pipeline files
foreach ($this->css as $id => $asset) {
if (!$asset['pipeline']) {
$this->css_no_pipeline[$id] = $asset;
} else {
$temp_css[$id] = $asset;
if ($asset['group'] == $group) {
if (!$asset['pipeline']) {
$this->css_no_pipeline[$id] = $asset;
} else {
$temp_css[$id] = $asset;
}
}
}
@@ -930,6 +957,7 @@ class Assets
* Download and concatenate the content of several links.
*
* @param array $links
* @param bool $css
*
* @return string
*/
@@ -960,7 +988,12 @@ class Assets
$link = ROOT_DIR . $relative_path;
}
$file = ($this->fetch_command instanceof Closure) ? $this->fetch_command->__invoke($link) : file_get_contents($link);
$file = ($this->fetch_command instanceof Closure) ? @$this->fetch_command->__invoke($link) : @file_get_contents($link);
// No file found, skip it...
if ($file === false) {
continue;
}
// Double check last character being
if (!$css) {

View File

@@ -224,6 +224,16 @@ 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.
*

View File

@@ -36,7 +36,7 @@ class Validation
// Validate type with fallback type text.
$type = (string) isset($field['validate']['type']) ? $field['validate']['type'] : $field['type'];
$method = 'type'.strtr($type, '-', '_');
$name = ucfirst($field['label'] ? $field['label'] : $field['name']);
$name = ucfirst(isset($field['label']) ? $field['label'] : $field['name']);
$message = (string) isset($field['validate']['message']) ? $field['validate']['message'] : 'Invalid input in "' . $language->translate($name) . '""';
if (method_exists(__CLASS__, $method)) {

View File

@@ -68,6 +68,16 @@ class Medium extends Data implements RenderableInterface
$this->reset();
}
/**
* Return just metadata from the Medium object
*
* @return $this
*/
public function meta()
{
return new Data($this->items);
}
/**
* Add meta file for the medium.
*
@@ -203,9 +213,29 @@ class Medium extends Data implements RenderableInterface
}
$attributes['style'] = $style;
!empty($title) && empty($attributes['title']) && $attributes['title'] = $title;
!empty($alt) && empty($attributes['alt']) && $attributes['alt'] = $alt;
!empty($class) && empty($attributes['class']) && $attributes['class'] = $class;
if (empty($attributes['title'])) {
if (!empty($title)) {
$attributes['title'] = $title;
} elseif (!empty($this->items['title'])) {
$attributes['title'] = $this->items['title'];
}
}
if (empty($attributes['alt'])) {
if (!empty($alt)) {
$attributes['alt'] = $alt;
} elseif (!empty($this->items['alt'])) {
$attributes['alt'] = $this->items['alt'];
}
}
if (empty($attributes['class'])) {
if (!empty($class)) {
$attributes['class'] = $class;
} elseif (!empty($this->items['class'])) {
$attributes['class'] = $this->items['class'];
}
}
switch ($this->mode) {
case 'text':
@@ -376,8 +406,6 @@ class Medium extends Data implements RenderableInterface
$this->querystring($this->querystring(null, false) . '&' . $qs);
}
self::$grav['debugger']->addMessage($this->querystring());
return $this;
}

View File

@@ -7,6 +7,7 @@ use Grav\Common\Page\Page;
use Grav\Common\Inflector;
use Grav\Common\Utils;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
use RocketTheme\Toolbox\Event\Event;
/**
* The Twig object handles all the Twig template rendering for Grav. It's a singleton object
@@ -142,7 +143,6 @@ class Twig
// Set some standard variables for twig
$this->twig_vars = array(
'grav' => $this->grav,
'config' => $config,
'uri' => $this->grav['uri'],
'base_dir' => rtrim(ROOT_DIR, '/'),
@@ -202,7 +202,7 @@ class Twig
$content = $content !== null ? $content : $item->content();
// override the twig header vars for local resolution
$this->grav->fireEvent('onTwigPageVariables');
$this->grav->fireEvent('onTwigPageVariables', new Event(['page' => $item]));
$twig_vars = $this->twig_vars;
$twig_vars['page'] = $item;

View File

@@ -36,6 +36,18 @@ class TwigExtension extends \Twig_Extension
return 'GravTwigExtension';
}
/**
* Register some standard globals
*
* @return array
*/
public function getGlobals()
{
return array(
'grav' => $this->grav,
);
}
/**
* Return a list of all filters.
*

View File

@@ -5,6 +5,7 @@ use Grav\Common\Data\Blueprints;
use Grav\Common\Data\Data;
use Grav\Common\File\CompiledYamlFile;
use Grav\Common\GravTrait;
use Grav\Common\Utils;
/**
* User object
@@ -138,7 +139,7 @@ class User extends Data
return false;
}
return $this->get("access.{$action}") === true;
return Utils::isPositive($this->get("access.{$action}"));
}
/**

View File

@@ -377,4 +377,14 @@ abstract class Utils
}
}
/**
* Checks if a value is positive
*
* @param string $value
*
* @return boolean
*/
public static function isPositive($value) {
return in_array($value, [true, 1, '1', 'yes', 'on', 'true'], true);
}
}