mirror of
https://github.com/getgrav/grav.git
synced 2026-07-07 11:21:54 +02:00
Merge branch 'release/0.9.30'
This commit is contained in:
@@ -44,7 +44,7 @@ before_install:
|
||||
- go get github.com/aktau/github-release
|
||||
- git clone --quiet --depth=50 --branch=master https://${BB_TOKEN}bitbucket.org/rockettheme/grav-devtools.git $RT_DEVTOOLS &>/dev/null;
|
||||
- if [ ! -z "$TRAVIS_TAG" ]; then
|
||||
cd $RT_DEVTOOLS;
|
||||
cd "${RT_DEVTOOLS}";
|
||||
./build-grav.sh skeletons.txt;
|
||||
fi
|
||||
script:
|
||||
|
||||
39
CHANGELOG.md
39
CHANGELOG.md
@@ -1,3 +1,26 @@
|
||||
# v0.9.30
|
||||
## 07/08/2015
|
||||
|
||||
1. [](#new)
|
||||
* BIG NEWS! Extensive Multi-Language support is all new in 0.9.30!
|
||||
* Translation support via Twig filter/function and PHP method
|
||||
* Page specific default route
|
||||
* Page specific route aliases
|
||||
* Canonical URL route support
|
||||
* Added built-in session support
|
||||
* New `Page.rawRoute()` to get a consistent folder-based route to a page
|
||||
* Added option to always redirect to default page on alias URL
|
||||
* Added language safe redirect function for use in core and plugins
|
||||
2. [](#improved)
|
||||
* Improved `Page.active()` and `Page.activeChild()` methods to support route aliases
|
||||
* Various spelling corrections in `.php` comments, `.md` and `.yaml` files
|
||||
* `Utils::startsWith()` and `Utils::endsWith()` now support needle arrays
|
||||
* Added a new timer around `pageInitialized` event
|
||||
* Updated jQuery library to v2.1.4
|
||||
3. [](#bugfix)
|
||||
* In-page CSS and JS files are now handled properly
|
||||
* Fix for `enable_media_timestamp` not working properly
|
||||
|
||||
# v0.9.29
|
||||
## 06/22/2015
|
||||
|
||||
@@ -35,7 +58,7 @@
|
||||
* Fix for `+` in image filenames
|
||||
* Fix for dot files causing issues with page processing
|
||||
* Fix for Uri path detection on Windows platform
|
||||
* Fix for atlernative media resolutions
|
||||
* Fix for alternative media resolutions
|
||||
* Fix for modularTypes key properties
|
||||
|
||||
# v0.9.27
|
||||
@@ -49,7 +72,7 @@
|
||||
* Added a new `parseLinks` method to Plugins class
|
||||
* Added `starts_with` and `ends_with` Twig filters
|
||||
2. [](#improved)
|
||||
* Opitmized install of vendor libraries for speed improvement
|
||||
* Optimized install of vendor libraries for speed improvement
|
||||
* Improved configuration handling in preparation for admin plugin
|
||||
* Cache optimization: Don't cache Twig templates when you pass dynamic params
|
||||
* Moved `Utils::rcopy` to `Folder::rcopy`
|
||||
@@ -63,7 +86,7 @@
|
||||
* Fix for URLs with trailing slashes
|
||||
* Handle condition where certain errors resulted in blank page
|
||||
* Fix for issue with theme name equal to base_url and asset pipeline
|
||||
* Fix to properly nomralize font rewrite path
|
||||
* Fix to properly normalize font rewrite path
|
||||
* Fix for absolute URLs below the current page
|
||||
* Fix for `..` page references
|
||||
|
||||
@@ -81,7 +104,7 @@
|
||||
2. [](#improved)
|
||||
* Refactored media image handling to make it more flexible and support absolute paths
|
||||
* Refactored page modification check process to make it faster
|
||||
* User account improvements in preparation for Admin plugin
|
||||
* User account improvements in preparation for admin plugin
|
||||
* Protect against timing attacks
|
||||
* Reset default system expires time to 0 seconds (can override if you need to)
|
||||
3. [](#bugfix)
|
||||
@@ -209,7 +232,7 @@
|
||||
* Improved the markdown Lightbox functionality to better mimic Twig version
|
||||
* Fullsize Lightbox can now have filters applied
|
||||
* Added a new `mergeConfig()` method to Plugin class to merge system + page header configuration
|
||||
* Added a new `disable()` method to Plugin class to programatically disable a plugin
|
||||
* Added a new `disable()` method to Plugin class to programmatically disable a plugin
|
||||
* Updated Parsedown and Parsedown Extra to address bugs
|
||||
* Various PSR fixes
|
||||
3. [](#bugfix)
|
||||
@@ -262,7 +285,7 @@
|
||||
* Added `publish_date` in page headers to automatically publish page
|
||||
* Added `unpublish_date` in page headers to automatically unpublish page
|
||||
* Added `dateRange()` capability for collections
|
||||
* Added ability to dynamically control Cache lifetime programatically
|
||||
* Added ability to dynamically control Cache lifetime programmatically
|
||||
* Added ability to sort by anything in the page header. E.g. `sort: header.taxonomy.year`
|
||||
* Added various helper methods to collections: `copy, nonVisible, modular, nonModular, published, nonPublished, nonRoutable`
|
||||
2. [](#improved)
|
||||
@@ -437,7 +460,7 @@
|
||||
* Broke cache types out into multiple directories in the cache folder
|
||||
* Removed vendor libs from github repository
|
||||
* Various PSR cleanup of code
|
||||
* Various Blueprint updates to support upcoming Admin plugin
|
||||
* Various Blueprint updates to support upcoming admin plugin
|
||||
* Added ability to filter page children for normal/modular/all
|
||||
* Added `sort_by_key` twig filter
|
||||
* Added `visible()` and `routable()` filters to page collections
|
||||
@@ -510,7 +533,7 @@
|
||||
* Addition of Dependency Injection Container
|
||||
* Refactored plugins to use Symfony Event Dispatcher
|
||||
* New Asset Manager to provide unified management of JavaScript and CSS
|
||||
* Asset Pipelining to provide unification, minify, and optimazation of JavaScript and CSS
|
||||
* Asset Pipelining to provide unification, minify, and optimization of JavaScript and CSS
|
||||
* Grav Media support directly in Markdown syntax
|
||||
* Additional Grav Generator meta tag in default themes
|
||||
* Added support for PHP Stream Wrapper for resource location
|
||||
|
||||
4
system/assets/jquery/jquery-2.1.3.min.js
vendored
4
system/assets/jquery/jquery-2.1.3.min.js
vendored
File diff suppressed because one or more lines are too long
4
system/assets/jquery/jquery-2.1.4.min.js
vendored
Normal file
4
system/assets/jquery/jquery-2.1.4.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -6,22 +6,25 @@ author:
|
||||
|
||||
taxonomies: [category,tag] # Arbitrary list of taxonomy types
|
||||
|
||||
blog:
|
||||
route: '/blog' # Route to blog (deprecated)
|
||||
|
||||
metadata:
|
||||
description: 'My Grav Site' # Site description
|
||||
|
||||
summary:
|
||||
enabled: true # enable or disable summary of page
|
||||
format: short # long = summary delimiter will be ignored; short = use the first occurence of delimter or size
|
||||
format: short # long = summary delimiter will be ignored; short = use the first occurrence of delimiter or size
|
||||
size: 300 # Maximum length of summary (characters)
|
||||
delimiter: === # The summary delimiter
|
||||
|
||||
redirects:
|
||||
/redirect-test: / # Redirect test goes to home page
|
||||
/old/(.*): /new/$1 # Would redirect /old/my-page to /new/my-page
|
||||
|
||||
routes:
|
||||
/something/else: '/blog/sample-3' # Alias for /blog/sample-3
|
||||
/another/one/here: '/blog/sample-3' # Another alias for /blog/sample-3
|
||||
/new/*: '/blog/*' # Wildcard any /new/my-page URL to /blog/my-page Route
|
||||
/new/(.*): '/blog/$1' # Regex any /new/my-page URL to /blog/my-page Route
|
||||
|
||||
blog:
|
||||
route: '/blog' # Custom value added (accessible via system.blog.route)
|
||||
|
||||
#menu: # Sample Menu Example
|
||||
# - text: Source
|
||||
|
||||
@@ -31,9 +31,10 @@ pages:
|
||||
'>': 'gt'
|
||||
'<': 'lt'
|
||||
types: 'txt|xml|html|json|rss|atom' # Pipe separated list of valid page types
|
||||
expires: 0 # Page expires time in seconds (604800 seconds = 7 days)
|
||||
expires: 604800 # Page expires time in seconds (604800 seconds = 7 days)
|
||||
last_modified: false # Set the last modified date header based on file modifcation timestamp
|
||||
etag: false # Set the etag header tag
|
||||
redirect_default_route: false # Automatically redirect to a page's default route
|
||||
|
||||
cache:
|
||||
enabled: true # Set to true to enable caching
|
||||
@@ -60,9 +61,9 @@ assets: # Configuration for Assets Manager (JS, C
|
||||
css_rewrite: true # Rewrite any CSS relative URLs during pipelining
|
||||
js_pipeline: false # The JS pipeline is the unification of multiple JS resources into one file
|
||||
js_minify: true # Minify the JS during pipelining
|
||||
enable_asset_timestamp: false # Enable asset timetsamps
|
||||
enable_asset_timestamp: false # Enable asset timestamps
|
||||
collections:
|
||||
jquery: system://assets/jquery/jquery-2.1.3.min.js
|
||||
jquery: system://assets/jquery/jquery-2.1.4.min.js
|
||||
|
||||
errors:
|
||||
display: true # Display full backtrace-style error page
|
||||
@@ -82,5 +83,10 @@ media:
|
||||
enable_media_timestamp: false # Enable media timetsamps
|
||||
upload_limit: 0 # Set maximum upload size in bytes (0 is unlimited)
|
||||
|
||||
session:
|
||||
enabled: true # Enable Session support
|
||||
timeout: 1800 # Timeout in seconds
|
||||
name: grav-site # Name prefix of the session cookie
|
||||
|
||||
security:
|
||||
default_hash: $2y$10$kwsyMVwM8/7j0K/6LHT.g.Fs49xOCTp2b8hh/S5.dPJuJcJB6T.UK
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// Some standard defines
|
||||
define('GRAV', true);
|
||||
define('GRAV_VERSION', '0.9.29');
|
||||
define('GRAV_VERSION', '0.9.30');
|
||||
define('DS', '/');
|
||||
|
||||
// Directories and Paths
|
||||
|
||||
@@ -47,7 +47,7 @@ class Assets
|
||||
* Closure used by the pipeline to fetch assets.
|
||||
*
|
||||
* Useful when file_get_contents() function is not available in your PHP
|
||||
* instalation or when you want to apply any kind of preprocessing to
|
||||
* installation or when you want to apply any kind of preprocessing to
|
||||
* your assets before they get pipelined.
|
||||
*
|
||||
* The closure will receive as the only parameter a string with the path/URL of the asset and
|
||||
@@ -509,7 +509,7 @@ class Assets
|
||||
|
||||
|
||||
/**
|
||||
* Minifiy and concatenate CSS / JS files.
|
||||
* Minify and concatenate CSS / JS files.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -741,7 +741,7 @@ class Assets
|
||||
/**
|
||||
* Determine whether a link is local or remote.
|
||||
*
|
||||
* Undestands both "http://" and "https://" as well as protocol agnostic links "//"
|
||||
* Understands both "http://" and "https://" as well as protocol agnostic links "//"
|
||||
*
|
||||
* @param string $link
|
||||
*
|
||||
@@ -920,7 +920,7 @@ class Assets
|
||||
*
|
||||
* @param string $directory
|
||||
* @param string $pattern (regex)
|
||||
* @param string $ltrim Will be trimed from the left of the file path
|
||||
* @param string $ltrim Will be trimmed from the left of the file path
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -271,7 +271,7 @@ class Cache extends Getters
|
||||
|
||||
|
||||
/**
|
||||
* Set the cache lifetime programatically
|
||||
* Set the cache lifetime programmatically
|
||||
*
|
||||
* @param int $future timestamp
|
||||
*/
|
||||
|
||||
@@ -60,6 +60,12 @@ class Config extends Data
|
||||
'' => ['user://themes'],
|
||||
]
|
||||
],
|
||||
'languages' => [
|
||||
'type' => 'ReadOnlyStream',
|
||||
'prefixes' => [
|
||||
'' => ['user://languages', 'system/languages'],
|
||||
]
|
||||
],
|
||||
'cache' => [
|
||||
'type' => 'Stream',
|
||||
'prefixes' => [
|
||||
@@ -85,17 +91,21 @@ class Config extends Data
|
||||
|
||||
protected $blueprintFiles = [];
|
||||
protected $configFiles = [];
|
||||
protected $languageFiles = [];
|
||||
protected $checksum;
|
||||
protected $timestamp;
|
||||
|
||||
protected $configLookup;
|
||||
protected $blueprintLookup;
|
||||
protected $pluginLookup;
|
||||
protected $languagesLookup;
|
||||
|
||||
protected $finder;
|
||||
protected $environment;
|
||||
protected $messages = [];
|
||||
|
||||
protected $languages;
|
||||
|
||||
public function __construct(array $setup = array(), Grav $grav = null, $environment = null)
|
||||
{
|
||||
$this->grav = $grav ?: Grav::instance();
|
||||
@@ -164,42 +174,61 @@ class Config extends Data
|
||||
$this->blueprintLookup = $locator->findResources('blueprints://config');
|
||||
$this->pluginLookup = $locator->findResources('plugins://');
|
||||
|
||||
|
||||
$this->loadCompiledBlueprints($this->blueprintLookup, $this->pluginLookup, 'master');
|
||||
$this->loadCompiledConfig($this->configLookup, $this->pluginLookup, 'master');
|
||||
|
||||
// process languages if supported
|
||||
if ($this->get('languages', false)) {
|
||||
$this->languagesLookup = $locator->findResources('languages://');
|
||||
$this->loadCompiledLanguages($this->languagesLookup, $this->pluginLookup, 'master');
|
||||
}
|
||||
|
||||
$this->initializeLocator($locator);
|
||||
}
|
||||
|
||||
public function checksum()
|
||||
{
|
||||
$checkBlueprints = $this->get('system.cache.check.blueprints', false);
|
||||
$checkConfig = $this->get('system.cache.check.config', true);
|
||||
$checkSystem = $this->get('system.cache.check.system', true);
|
||||
if (empty($this->checksum)) {
|
||||
$checkBlueprints = $this->get('system.cache.check.blueprints', false);
|
||||
$checkLanguages = $this->get('system.cache.check.languages', false);
|
||||
$checkConfig = $this->get('system.cache.check.config', true);
|
||||
$checkSystem = $this->get('system.cache.check.system', true);
|
||||
|
||||
if (!$checkBlueprints && !$checkConfig && !$checkSystem) {
|
||||
$this->messages[] = 'Skip configuration timestamp check.';
|
||||
return false;
|
||||
if (!$checkBlueprints && !!$checkLanguages && $checkConfig && !$checkSystem) {
|
||||
$this->messages[] = 'Skip configuration timestamp check.';
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate checksum according to the configuration settings.
|
||||
if (!$checkConfig) {
|
||||
$this->messages[] = 'Check configuration timestamps from system.yaml files.';
|
||||
// Just check changes in system.yaml files and ignore all the other files.
|
||||
$cc = $checkSystem ? $this->finder->locateConfigFile($this->configLookup, 'system') : [];
|
||||
} else {
|
||||
$this->messages[] = 'Check configuration timestamps from all configuration files.';
|
||||
// Check changes in all configuration files.
|
||||
$cc = $this->finder->locateConfigFiles($this->configLookup, $this->pluginLookup);
|
||||
}
|
||||
|
||||
if ($checkBlueprints) {
|
||||
$this->messages[] = 'Check blueprint timestamps from all blueprint files.';
|
||||
$cb = $this->finder->locateBlueprintFiles($this->blueprintLookup, $this->pluginLookup);
|
||||
} else {
|
||||
$cb = [];
|
||||
}
|
||||
|
||||
if ($checkLanguages) {
|
||||
$this->messages[] = 'Check language timestamps from all language files.';
|
||||
$cl = $this->finder->locateLanguageFiles($this->languagesLookup, $this->pluginLookup);
|
||||
} else {
|
||||
$cl = [];
|
||||
}
|
||||
|
||||
$this->checksum = md5(json_encode([$cc, $cb, $cl]));
|
||||
}
|
||||
|
||||
// Generate checksum according to the configuration settings.
|
||||
if (!$checkConfig) {
|
||||
$this->messages[] = 'Check configuration timestamps from system.yaml files.';
|
||||
// Just check changes in system.yaml files and ignore all the other files.
|
||||
$cc = $checkSystem ? $this->finder->locateConfigFile($this->configLookup, 'system') : [];
|
||||
} else {
|
||||
$this->messages[] = 'Check configuration timestamps from all configuration files.';
|
||||
// Check changes in all configuration files.
|
||||
$cc = $this->finder->locateConfigFiles($this->configLookup, $this->pluginLookup);
|
||||
}
|
||||
|
||||
if ($checkBlueprints) {
|
||||
$this->messages[] = 'Check blueprint timestamps from all blueprint files.';
|
||||
$cb = $this->finder->locateBlueprintFiles($this->blueprintLookup, $this->pluginLookup);
|
||||
} else {
|
||||
$cb = [];
|
||||
}
|
||||
|
||||
return md5(json_encode([$cc, $cb]));
|
||||
return $this->checksum;
|
||||
}
|
||||
|
||||
protected function autoDetectEnvironmentConfig($items)
|
||||
@@ -312,6 +341,54 @@ class Config extends Data
|
||||
$this->items = $cache['data'];
|
||||
}
|
||||
|
||||
protected function loadCompiledLanguages($languages, $plugins, $filename = null)
|
||||
{
|
||||
$checksum = md5(json_encode($languages));
|
||||
$filename = $filename
|
||||
? CACHE_DIR . 'compiled/languages/' . $filename . '-' . $this->environment . '.php'
|
||||
: CACHE_DIR . 'compiled/languages/' . $checksum . '-' . $this->environment . '.php';
|
||||
$file = PhpFile::instance($filename);
|
||||
$cache = $file->exists() ? $file->content() : null;
|
||||
$languageFiles = $this->finder->locateLanguageFiles($languages, $plugins);
|
||||
$checksum .= ':' . md5(json_encode($languageFiles));
|
||||
$class = get_class($this);
|
||||
|
||||
// Load real file if cache isn't up to date (or is invalid).
|
||||
if (
|
||||
!is_array($cache)
|
||||
|| !isset($cache['checksum'])
|
||||
|| !isset($cache['@class'])
|
||||
|| $cache['checksum'] != $checksum
|
||||
|| $cache['@class'] != $class
|
||||
) {
|
||||
// Attempt to lock the file for writing.
|
||||
$file->lock(false);
|
||||
|
||||
// Load languages.
|
||||
$this->languages = new Languages;
|
||||
foreach ($languageFiles as $files) {
|
||||
$this->loadLanguagesFiles($files);
|
||||
}
|
||||
|
||||
$this->languages->reformat();
|
||||
|
||||
$cache = [
|
||||
'@class' => $class,
|
||||
'checksum' => $checksum,
|
||||
'files' => $languageFiles,
|
||||
'data' => $this->languages->toArray()
|
||||
];
|
||||
// If compiled file wasn't already locked by another process, save it.
|
||||
if ($file->locked() !== false) {
|
||||
$this->messages[] = 'Saving compiled languages.';
|
||||
$file->save($cache);
|
||||
$file->unlock();
|
||||
}
|
||||
} else {
|
||||
$this->languages = new Languages($cache['data']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load blueprints.
|
||||
*
|
||||
@@ -338,6 +415,14 @@ class Config extends Data
|
||||
}
|
||||
}
|
||||
|
||||
public function loadLanguagesFiles(array $files)
|
||||
{
|
||||
foreach ($files as $name => $item) {
|
||||
$file = CompiledYamlFile::instance($item['file']);
|
||||
$this->languages->join($name, $file->content(), '/');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize resource locator by using the configuration.
|
||||
*
|
||||
@@ -380,4 +465,9 @@ class Config extends Data
|
||||
|
||||
return $schemes;
|
||||
}
|
||||
|
||||
public function getLanguages()
|
||||
{
|
||||
return $this->languages;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,18 @@ class ConfigFinder
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function locateLanguageFiles(array $languages, array $plugins)
|
||||
{
|
||||
$list = [];
|
||||
foreach (array_reverse($plugins) as $folder) {
|
||||
$list += $this->detectLanguagesInFolder($folder, 'languages');
|
||||
}
|
||||
foreach (array_reverse($languages) as $folder) {
|
||||
$list += $this->detectRecursive($folder);
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all locations for a single configuration file.
|
||||
*
|
||||
@@ -90,11 +102,11 @@ class ConfigFinder
|
||||
$list = [];
|
||||
|
||||
if (is_dir($folder)) {
|
||||
$iterator = new \DirectoryIterator($folder);
|
||||
$iterator = new \FilesystemIterator($folder);
|
||||
|
||||
/** @var \DirectoryIterator $directory */
|
||||
foreach ($iterator as $directory) {
|
||||
if (!$directory->isDir() || $directory->isDot()) {
|
||||
if (!$directory->isDir()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -111,6 +123,34 @@ class ConfigFinder
|
||||
return [$path => $list];
|
||||
}
|
||||
|
||||
protected function detectLanguagesInFolder($folder, $lookup = null)
|
||||
{
|
||||
$path = trim(Folder::getRelativePath($folder), '/');
|
||||
|
||||
$list = [];
|
||||
|
||||
if (is_dir($folder)) {
|
||||
$iterator = new \FilesystemIterator($folder);
|
||||
|
||||
/** @var \DirectoryIterator $directory */
|
||||
foreach ($iterator as $directory) {
|
||||
if (!$directory->isDir()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = $directory->getBasename();
|
||||
$find = ($lookup ?: $name) . '.yaml';
|
||||
$filename = "{$path}/{$name}/$find";
|
||||
|
||||
if (file_exists($filename)) {
|
||||
$list["plugins"] = ['file' => $filename, 'modified' => filemtime($filename)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [$path => $list];
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects all plugins with a configuration file and returns them with last modification time.
|
||||
*
|
||||
|
||||
27
system/src/Grav/Common/Config/Languages.php
Normal file
27
system/src/Grav/Common/Config/Languages.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace Grav\Common\Config;
|
||||
|
||||
use Grav\Common\Data\Data;
|
||||
|
||||
/**
|
||||
* The Languages class contains configuration rules.
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Languages extends Data
|
||||
{
|
||||
|
||||
public function reformat()
|
||||
{
|
||||
if (isset($this->items['plugins'])) {
|
||||
$this->items = array_merge_recursive($this->items, $this->items['plugins']);
|
||||
unset($this->items['plugins']);
|
||||
}
|
||||
}
|
||||
|
||||
public function mergeRecursive(array $data)
|
||||
{
|
||||
$this->items = array_merge_recursive($this->items, $data);
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ trait DataMutatorTrait
|
||||
}
|
||||
|
||||
/**
|
||||
* Sey value by using dot notation for nested arrays/objects.
|
||||
* Set value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $value = $data->set('this.is.my.nested.variable', true);
|
||||
*
|
||||
|
||||
@@ -38,12 +38,12 @@ abstract class Folder
|
||||
* Recursively find the last modified time under given path by file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $extensions
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function lastModifiedFile($path)
|
||||
public static function lastModifiedFile($path, $extensions = 'md|yaml')
|
||||
{
|
||||
// pipe separated list of extensions to search for changes with
|
||||
$extensions = 'md|yaml';
|
||||
$last_modified = 0;
|
||||
|
||||
$dirItr = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS);
|
||||
|
||||
@@ -361,7 +361,7 @@ class GPM extends Iterator
|
||||
}
|
||||
|
||||
if ($found = $this->findPackage($search)) {
|
||||
// set override respository if provided
|
||||
// set override repository if provided
|
||||
if ($repository) {
|
||||
$found->override_repository = $repository;
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ class Installer
|
||||
|
||||
|
||||
/**
|
||||
* Unnstalls one or more given package
|
||||
* Uninstalls one or more given package
|
||||
*
|
||||
* @param string $path The slug of the package(s)
|
||||
* @param array $options Options to use for uninstalling
|
||||
|
||||
@@ -65,7 +65,7 @@ class Upgrader
|
||||
* Returns the changelog list for each version of Grav
|
||||
* @param string $diff the version number to start the diff from
|
||||
*
|
||||
* @return array return the chagenlog list for each version
|
||||
* @return array return the changelog list for each version
|
||||
*/
|
||||
public function getChangelog($diff = null)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace Grav\Common;
|
||||
|
||||
use Grav\Common\Language\Language;
|
||||
use Grav\Common\Page\Medium\ImageMedium;
|
||||
use Grav\Common\Page\Pages;
|
||||
use Grav\Common\Service\ConfigServiceProvider;
|
||||
@@ -55,6 +56,8 @@ class Grav extends Container
|
||||
|
||||
$container['grav'] = $container;
|
||||
|
||||
|
||||
|
||||
$container['debugger'] = new Debugger();
|
||||
$container['debugger']->startTimer('_init', 'Initialize');
|
||||
|
||||
@@ -76,6 +79,9 @@ class Grav extends Container
|
||||
$container['cache'] = function ($c) {
|
||||
return new Cache($c);
|
||||
};
|
||||
$container['session'] = function ($c) {
|
||||
return new Session($c);
|
||||
};
|
||||
$container['plugins'] = function ($c) {
|
||||
return new Plugins();
|
||||
};
|
||||
@@ -88,12 +94,16 @@ class Grav extends Container
|
||||
$container['taxonomy'] = function ($c) {
|
||||
return new Taxonomy($c);
|
||||
};
|
||||
$container['language'] = function ($c) {
|
||||
return new Language($c);
|
||||
};
|
||||
|
||||
$container['pages'] = function ($c) {
|
||||
return new Page\Pages($c);
|
||||
};
|
||||
$container['assets'] = function ($c) {
|
||||
return new Assets();
|
||||
};
|
||||
|
||||
$container['assets'] = new Assets();
|
||||
|
||||
$container['page'] = function ($c) {
|
||||
/** @var Pages $pages */
|
||||
$pages = $c['pages'];
|
||||
@@ -106,29 +116,16 @@ class Grav extends Container
|
||||
|
||||
$page = $pages->dispatch($path);
|
||||
|
||||
// handle redirect if not 'default route' configuration
|
||||
if ($page && $c['config']->get('system.pages.redirect_default_route') && $page->route() != $path) {
|
||||
$c->redirectLangSafe($page->route());
|
||||
}
|
||||
|
||||
// if page is not found, try some fallback stuff
|
||||
if (!$page || !$page->routable()) {
|
||||
$path_parts = pathinfo($path);
|
||||
$page = $c['pages']->dispatch($path_parts['dirname'], true);
|
||||
if ($page) {
|
||||
$media = $page->media()->all();
|
||||
|
||||
$parsed_url = parse_url(urldecode($uri->basename()));
|
||||
|
||||
$media_file = $parsed_url['path'];
|
||||
|
||||
// if this is a media object, try actions first
|
||||
if (isset($media[$media_file])) {
|
||||
$medium = $media[$media_file];
|
||||
foreach ($uri->query(null, true) as $action => $params) {
|
||||
if (in_array($action, ImageMedium::$magic_actions)) {
|
||||
call_user_func_array(array(&$medium, $action), explode(',', $params));
|
||||
}
|
||||
}
|
||||
Utils::download($medium->path(), false);
|
||||
} else {
|
||||
Utils::download($page->path() . DIRECTORY_SEPARATOR . $uri->basename(), true);
|
||||
}
|
||||
}
|
||||
// Try fallback URL stuff...
|
||||
$c->fallbackUrl($page, $path);
|
||||
|
||||
// If no page found, fire event
|
||||
$event = $c->fireEvent('onPageNotFound');
|
||||
@@ -174,6 +171,7 @@ class Grav extends Container
|
||||
// Initialize configuration.
|
||||
$debugger->startTimer('_config', 'Configuration');
|
||||
$this['config']->init();
|
||||
$this['session']->init();
|
||||
$this['uri']->init();
|
||||
$this['errors']->resetHandlers();
|
||||
$debugger->init();
|
||||
@@ -222,7 +220,9 @@ class Grav extends Container
|
||||
$this->fireEvent('onPagesInitialized');
|
||||
$debugger->stopTimer('pages');
|
||||
|
||||
$debugger->startTimer('pageinit', 'Page Initialized');
|
||||
$this->fireEvent('onPageInitialized');
|
||||
$debugger->stopTimer('pageinit');
|
||||
|
||||
$debugger->addAssets();
|
||||
|
||||
@@ -267,6 +267,25 @@ class Grav extends Container
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect browser to another location taking language into account (preferred)
|
||||
*
|
||||
* @param string $route Internal route.
|
||||
* @param int $code Redirection code (30x)
|
||||
*/
|
||||
public function redirectLangSafe($route, $code = 303)
|
||||
{
|
||||
/** @var Language $language */
|
||||
$language = $this['language'];
|
||||
$config = $this['config'];
|
||||
|
||||
if ($language->enabled()) {
|
||||
return $this->redirect($language->getLanguage() . $route, $code);
|
||||
} else {
|
||||
return $this->redirect($route);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns mime type for the file format.
|
||||
*
|
||||
@@ -387,4 +406,46 @@ class Grav extends Container
|
||||
|
||||
$this->fireEvent('onShutdown');
|
||||
}
|
||||
|
||||
/**
|
||||
* This attempts to fine media, other files, and download them
|
||||
* @param $page
|
||||
* @param $path
|
||||
*/
|
||||
protected function fallbackUrl($page, $path)
|
||||
{
|
||||
/** @var Uri $uri */
|
||||
$uri = $this['uri'];
|
||||
|
||||
$path_parts = pathinfo($path);
|
||||
$page = $this['pages']->dispatch($path_parts['dirname'], true);
|
||||
if ($page) {
|
||||
$media = $page->media()->all();
|
||||
|
||||
$parsed_url = parse_url(urldecode($uri->basename()));
|
||||
|
||||
$media_file = $parsed_url['path'];
|
||||
|
||||
// if this is a media object, try actions first
|
||||
if (isset($media[$media_file])) {
|
||||
$medium = $media[$media_file];
|
||||
foreach ($uri->query(null, true) as $action => $params) {
|
||||
if (in_array($action, ImageMedium::$magic_actions)) {
|
||||
call_user_func_array(array(&$medium, $action), explode(',', $params));
|
||||
}
|
||||
}
|
||||
Utils::download($medium->path(), false);
|
||||
}
|
||||
|
||||
// has an extension, try to download it...
|
||||
if (isset($path_parts['extension'])) {
|
||||
$download = true;
|
||||
// little work-around to ensure .css and .js files are always sent inline not downloaded
|
||||
if (in_array($path_parts['extension'], ['.css', '.js'])) {
|
||||
$download = false;
|
||||
}
|
||||
Utils::download($page->path() . DIRECTORY_SEPARATOR . $uri->basename(), $download);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
310
system/src/Grav/Common/Language/Language.php
Normal file
310
system/src/Grav/Common/Language/Language.php
Normal file
@@ -0,0 +1,310 @@
|
||||
<?php
|
||||
namespace Grav\Common\Language;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
|
||||
/**
|
||||
* Language and translation functionality for Grav
|
||||
*/
|
||||
class Language
|
||||
{
|
||||
protected $grav;
|
||||
protected $enabled = true;
|
||||
protected $languages = [];
|
||||
protected $page_extensions = [];
|
||||
protected $fallback_languages = [];
|
||||
protected $default;
|
||||
protected $active;
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \Grav\Common\Grav $grav
|
||||
*/
|
||||
public function __construct(Grav $grav)
|
||||
{
|
||||
$this->grav = $grav;
|
||||
$this->config = $grav['config'];
|
||||
$this->languages = $this->config->get('system.languages.supported', []);
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the default and enabled languages
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->default = reset($this->languages);
|
||||
|
||||
if (empty($this->languages)) {
|
||||
$this->enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that languages are enabled
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function enabled()
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the array of supported languages
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLanguages()
|
||||
{
|
||||
return $this->languages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current supported languages manually
|
||||
*
|
||||
* @param $langs
|
||||
*/
|
||||
public function setLanguages($langs)
|
||||
{
|
||||
$this->languages = $langs;
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a pipe-separated string of available languages
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAvailable()
|
||||
{
|
||||
return implode('|', $this->languages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets language, active if set, else default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLanguage()
|
||||
{
|
||||
return $this->active ? $this->active : $this->default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current default language
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDefault()
|
||||
{
|
||||
return $this->default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets default language manually
|
||||
*
|
||||
* @param $lang
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setDefault($lang)
|
||||
{
|
||||
if ($this->validate($lang)) {
|
||||
$this->default = $lang;
|
||||
return $lang;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current active language
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getActive()
|
||||
{
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets active language manually
|
||||
*
|
||||
* @param $lang
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setActive($lang)
|
||||
{
|
||||
if ($this->validate($lang)) {
|
||||
$this->active = $lang;
|
||||
return $lang;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active language based on the first part of the URL
|
||||
*
|
||||
* @param $uri
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function setActiveFromUri($uri)
|
||||
{
|
||||
$regex = '/(\/('.$this->getAvailable().')).*/';
|
||||
|
||||
// if languages set
|
||||
if ($this->enabled()) {
|
||||
// try setting from prefix of URL (/en/blah/blah)
|
||||
if (preg_match($regex, $uri, $matches)) {
|
||||
$this->active = $matches[2];
|
||||
$uri = preg_replace("/\\" . $matches[1] . "/", '', $matches[0], 1);
|
||||
|
||||
// store in session if different
|
||||
if ($this->config->get('system.session.enabled', false)
|
||||
&& $this->config->get('system.language.session_store_active', true)
|
||||
&& $this->grav['session']->active_language != $this->active) {
|
||||
$this->grav['session']->active_language = $this->active;
|
||||
}
|
||||
} else {
|
||||
// try getting from session, else no active
|
||||
if ($this->config->get('system.session.enabled', false) && $this->config->get('system.language.session_store_active', true)) {
|
||||
$this->active = $this->grav['session']->active_language ?: null;
|
||||
} else {
|
||||
$this->active = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $uri;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets an array of valid extensions with active first, then fallback extensions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFallbackPageExtensions($file_ext = null)
|
||||
{
|
||||
if (empty($this->page_extensions)) {
|
||||
if (empty($file_ext)) {
|
||||
$file_ext = CONTENT_EXT;
|
||||
}
|
||||
|
||||
if ($this->enabled()) {
|
||||
$valid_lang_extensions = [];
|
||||
foreach ($this->languages as $lang) {
|
||||
$valid_lang_extensions[] = '.'.$lang.$file_ext;
|
||||
}
|
||||
|
||||
if ($this->active) {
|
||||
$active_extension = '.'.$this->active.$file_ext;
|
||||
$key = array_search($active_extension, $valid_lang_extensions);
|
||||
unset($valid_lang_extensions[$key]);
|
||||
array_unshift($valid_lang_extensions, $active_extension);
|
||||
}
|
||||
|
||||
$this->page_extensions = array_merge($valid_lang_extensions, (array) $file_ext);
|
||||
} else {
|
||||
$this->page_extensions = (array) $file_ext;
|
||||
}
|
||||
}
|
||||
return $this->page_extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of languages with active first, then fallback languages
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFallbackLanguages()
|
||||
{
|
||||
if (empty($this->fallback_languages)) {
|
||||
if ($this->enabled()) {
|
||||
$fallback_languages = $this->languages;
|
||||
|
||||
if ($this->active) {
|
||||
$active_extension = $this->active;
|
||||
$key = array_search($active_extension, $fallback_languages);
|
||||
unset($fallback_languages[$key]);
|
||||
array_unshift($fallback_languages, $active_extension);
|
||||
}
|
||||
$this->fallback_languages = $fallback_languages;
|
||||
}
|
||||
}
|
||||
return $this->fallback_languages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the language is valid and supported
|
||||
*
|
||||
* @param $lang
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validate($lang)
|
||||
{
|
||||
if (in_array($lang, $this->languages)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a key and possibly arguments into a string using current lang and fallbacks
|
||||
*
|
||||
* @param Array $args first argument is the lookup key value
|
||||
* other arguments can be passed and replaced in the translation with sprintf syntax
|
||||
* @return string
|
||||
*/
|
||||
public function translate(Array $args, $languages = null)
|
||||
{
|
||||
$lookup = array_shift($args);
|
||||
|
||||
if ($this->enabled() && $lookup) {
|
||||
|
||||
if (empty($languages)) {
|
||||
if ($this->config->get('system.languages.translations.fallback', true)) {
|
||||
$languages = $this->getFallbackLanguages();
|
||||
} else {
|
||||
$languages = (array) $this->getDefault();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->getFallbackLanguages() as $lang) {
|
||||
$translation = $this->getTranslation($lang, $lookup);
|
||||
|
||||
if ($translation) {
|
||||
if (count($args) >= 1) {
|
||||
return vsprintf($translation, $args);
|
||||
} else {
|
||||
return $translation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return '<span class="untranslated">'.$lookup.'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the translation text for a given lang and key
|
||||
*
|
||||
* @param $lang lang code
|
||||
* @param $key key to lookup with
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTranslation($lang, $key) {
|
||||
$languages = $this->config->getLanguages();
|
||||
|
||||
$translation = $languages->get($lang.'.'.$key, null);
|
||||
if (is_array($translation)) {
|
||||
return (string) array_shift($translation);
|
||||
}
|
||||
|
||||
return $translation;
|
||||
}
|
||||
}
|
||||
770
system/src/Grav/Common/Language/LanguageCodes.php
Normal file
770
system/src/Grav/Common/Language/LanguageCodes.php
Normal file
@@ -0,0 +1,770 @@
|
||||
<?php
|
||||
namespace Grav\Common\Language;
|
||||
|
||||
/**
|
||||
* Language and translation functionality for Grav
|
||||
*/
|
||||
class LanguageCodes
|
||||
{
|
||||
protected static $codes = [
|
||||
"ab" => [
|
||||
"name" => "Abkhaz",
|
||||
"nativeName" => "аҧсуа"
|
||||
],
|
||||
"aa" => [
|
||||
"name" => "Afar",
|
||||
"nativeName" => "Afaraf"
|
||||
],
|
||||
"af" => [
|
||||
"name" => "Afrikaans",
|
||||
"nativeName" => "Afrikaans"
|
||||
],
|
||||
"ak" => [
|
||||
"name" => "Akan",
|
||||
"nativeName" => "Akan"
|
||||
],
|
||||
"sq" => [
|
||||
"name" => "Albanian",
|
||||
"nativeName" => "Shqip"
|
||||
],
|
||||
"am" => [
|
||||
"name" => "Amharic",
|
||||
"nativeName" => "አማርኛ"
|
||||
],
|
||||
"ar" => [
|
||||
"name" => "Arabic",
|
||||
"nativeName" => "العربية"
|
||||
],
|
||||
"an" => [
|
||||
"name" => "Aragonese",
|
||||
"nativeName" => "Aragonés"
|
||||
],
|
||||
"hy" => [
|
||||
"name" => "Armenian",
|
||||
"nativeName" => "Հայերեն"
|
||||
],
|
||||
"as" => [
|
||||
"name" => "Assamese",
|
||||
"nativeName" => "অসমীয়া"
|
||||
],
|
||||
"av" => [
|
||||
"name" => "Avaric",
|
||||
"nativeName" => "авар мацӀ"
|
||||
],
|
||||
"ae" => [
|
||||
"name" => "Avestan",
|
||||
"nativeName" => "avesta"
|
||||
],
|
||||
"ay" => [
|
||||
"name" => "Aymara",
|
||||
"nativeName" => "aymar aru"
|
||||
],
|
||||
"az" => [
|
||||
"name" => "Azerbaijani",
|
||||
"nativeName" => "azərbaycan dili"
|
||||
],
|
||||
"bm" => [
|
||||
"name" => "Bambara",
|
||||
"nativeName" => "bamanankan"
|
||||
],
|
||||
"ba" => [
|
||||
"name" => "Bashkir",
|
||||
"nativeName" => "башҡорт теле"
|
||||
],
|
||||
"eu" => [
|
||||
"name" => "Basque",
|
||||
"nativeName" => "euskara"
|
||||
],
|
||||
"be" => [
|
||||
"name" => "Belarusian",
|
||||
"nativeName" => "Беларуская"
|
||||
],
|
||||
"bn" => [
|
||||
"name" => "Bengali",
|
||||
"nativeName" => "বাংলা"
|
||||
],
|
||||
"bh" => [
|
||||
"name" => "Bihari",
|
||||
"nativeName" => "भोजपुरी"
|
||||
],
|
||||
"bi" => [
|
||||
"name" => "Bislama",
|
||||
"nativeName" => "Bislama"
|
||||
],
|
||||
"bs" => [
|
||||
"name" => "Bosnian",
|
||||
"nativeName" => "bosanski jezik"
|
||||
],
|
||||
"br" => [
|
||||
"name" => "Breton",
|
||||
"nativeName" => "brezhoneg"
|
||||
],
|
||||
"bg" => [
|
||||
"name" => "Bulgarian",
|
||||
"nativeName" => "български език"
|
||||
],
|
||||
"my" => [
|
||||
"name" => "Burmese",
|
||||
"nativeName" => "ဗမာစာ"
|
||||
],
|
||||
"ca" => [
|
||||
"name" => "Catalan",
|
||||
"nativeName" => "Català"
|
||||
],
|
||||
"ch" => [
|
||||
"name" => "Chamorro",
|
||||
"nativeName" => "Chamoru"
|
||||
],
|
||||
"ce" => [
|
||||
"name" => "Chechen",
|
||||
"nativeName" => "нохчийн мотт"
|
||||
],
|
||||
"ny" => [
|
||||
"name" => "Chichewa",
|
||||
"nativeName" => "chiCheŵa"
|
||||
],
|
||||
"zh" => [
|
||||
"name" => "Chinese",
|
||||
"nativeName" => "中文"
|
||||
],
|
||||
"cv" => [
|
||||
"name" => "Chuvash",
|
||||
"nativeName" => "чӑваш чӗлхи"
|
||||
],
|
||||
"kw" => [
|
||||
"name" => "Cornish",
|
||||
"nativeName" => "Kernewek"
|
||||
],
|
||||
"co" => [
|
||||
"name" => "Corsican",
|
||||
"nativeName" => "corsu"
|
||||
],
|
||||
"cr" => [
|
||||
"name" => "Cree",
|
||||
"nativeName" => "ᓀᐦᐃᔭᐍᐏᐣ"
|
||||
],
|
||||
"hr" => [
|
||||
"name" => "Croatian",
|
||||
"nativeName" => "hrvatski"
|
||||
],
|
||||
"cs" => [
|
||||
"name" => "Czech",
|
||||
"nativeName" => "česky"
|
||||
],
|
||||
"da" => [
|
||||
"name" => "Danish",
|
||||
"nativeName" => "dansk"
|
||||
],
|
||||
"dv" => [
|
||||
"name" => "Divehi",
|
||||
"nativeName" => "ދިވެހި"
|
||||
],
|
||||
"nl" => [
|
||||
"name" => "Dutch",
|
||||
"nativeName" => "Nederlands"
|
||||
],
|
||||
"en" => [
|
||||
"name" => "English",
|
||||
"nativeName" => "English"
|
||||
],
|
||||
"eo" => [
|
||||
"name" => "Esperanto",
|
||||
"nativeName" => "Esperanto"
|
||||
],
|
||||
"et" => [
|
||||
"name" => "Estonian",
|
||||
"nativeName" => "eesti"
|
||||
],
|
||||
"ee" => [
|
||||
"name" => "Ewe",
|
||||
"nativeName" => "Eʋegbe"
|
||||
],
|
||||
"fo" => [
|
||||
"name" => "Faroese",
|
||||
"nativeName" => "føroyskt"
|
||||
],
|
||||
"fj" => [
|
||||
"name" => "Fijian",
|
||||
"nativeName" => "vosa Vakaviti"
|
||||
],
|
||||
"fi" => [
|
||||
"name" => "Finnish",
|
||||
"nativeName" => "suomi"
|
||||
],
|
||||
"fr" => [
|
||||
"name" => "French",
|
||||
"nativeName" => "français"
|
||||
],
|
||||
"ff" => [
|
||||
"name" => "Fula",
|
||||
"nativeName" => "Fulfulde"
|
||||
],
|
||||
"gl" => [
|
||||
"name" => "Galician",
|
||||
"nativeName" => "Galego"
|
||||
],
|
||||
"ka" => [
|
||||
"name" => "Georgian",
|
||||
"nativeName" => "ქართული"
|
||||
],
|
||||
"de" => [
|
||||
"name" => "German",
|
||||
"nativeName" => "Deutsch"
|
||||
],
|
||||
"el" => [
|
||||
"name" => "Greek",
|
||||
"nativeName" => "Ελληνικά"
|
||||
],
|
||||
"gn" => [
|
||||
"name" => "Guaraní",
|
||||
"nativeName" => "Avañeẽ"
|
||||
],
|
||||
"gu" => [
|
||||
"name" => "Gujarati",
|
||||
"nativeName" => "ગુજરાતી"
|
||||
],
|
||||
"ht" => [
|
||||
"name" => "Haitian",
|
||||
"nativeName" => "Kreyòl ayisyen"
|
||||
],
|
||||
"ha" => [
|
||||
"name" => "Hausa",
|
||||
"nativeName" => "هَوُسَ"
|
||||
],
|
||||
"he" => [
|
||||
"name" => "Hebrew",
|
||||
"nativeName" => "עברית"
|
||||
],
|
||||
"hz" => [
|
||||
"name" => "Herero",
|
||||
"nativeName" => "Otjiherero"
|
||||
],
|
||||
"hi" => [
|
||||
"name" => "Hindi",
|
||||
"nativeName" => "हिन्दी"
|
||||
],
|
||||
"ho" => [
|
||||
"name" => "Hiri Motu",
|
||||
"nativeName" => "Hiri Motu"
|
||||
],
|
||||
"hu" => [
|
||||
"name" => "Hungarian",
|
||||
"nativeName" => "Magyar"
|
||||
],
|
||||
"ia" => [
|
||||
"name" => "Interlingua",
|
||||
"nativeName" => "Interlingua"
|
||||
],
|
||||
"id" => [
|
||||
"name" => "Indonesian",
|
||||
"nativeName" => "Bahasa Indonesia"
|
||||
],
|
||||
"ie" => [
|
||||
"name" => "Interlingue",
|
||||
"nativeName" => "Interlingue"
|
||||
],
|
||||
"ga" => [
|
||||
"name" => "Irish",
|
||||
"nativeName" => "Gaeilge"
|
||||
],
|
||||
"ig" => [
|
||||
"name" => "Igbo",
|
||||
"nativeName" => "Asụsụ Igbo"
|
||||
],
|
||||
"ik" => [
|
||||
"name" => "Inupiaq",
|
||||
"nativeName" => "Iñupiaq"
|
||||
],
|
||||
"io" => [
|
||||
"name" => "Ido",
|
||||
"nativeName" => "Ido"
|
||||
],
|
||||
"is" => [
|
||||
"name" => "Icelandic",
|
||||
"nativeName" => "Íslenska"
|
||||
],
|
||||
"it" => [
|
||||
"name" => "Italian",
|
||||
"nativeName" => "Italiano"
|
||||
],
|
||||
"iu" => [
|
||||
"name" => "Inuktitut",
|
||||
"nativeName" => "ᐃᓄᒃᑎᑐᑦ"
|
||||
],
|
||||
"ja" => [
|
||||
"name" => "Japanese",
|
||||
"nativeName" => "日本語"
|
||||
],
|
||||
"jv" => [
|
||||
"name" => "Javanese",
|
||||
"nativeName" => "basa Jawa"
|
||||
],
|
||||
"kl" => [
|
||||
"name" => "Kalaallisut",
|
||||
"nativeName" => "kalaallisut"
|
||||
],
|
||||
"kn" => [
|
||||
"name" => "Kannada",
|
||||
"nativeName" => "ಕನ್ನಡ"
|
||||
],
|
||||
"kr" => [
|
||||
"name" => "Kanuri",
|
||||
"nativeName" => "Kanuri"
|
||||
],
|
||||
"ks" => [
|
||||
"name" => "Kashmiri",
|
||||
"nativeName" => "कश्मीरी"
|
||||
],
|
||||
"kk" => [
|
||||
"name" => "Kazakh",
|
||||
"nativeName" => "Қазақ тілі"
|
||||
],
|
||||
"km" => [
|
||||
"name" => "Khmer",
|
||||
"nativeName" => "ភាសាខ្មែរ"
|
||||
],
|
||||
"ki" => [
|
||||
"name" => "Kikuyu",
|
||||
"nativeName" => "Gĩkũyũ"
|
||||
],
|
||||
"rw" => [
|
||||
"name" => "Kinyarwanda",
|
||||
"nativeName" => "Ikinyarwanda"
|
||||
],
|
||||
"ky" => [
|
||||
"name" => "Kirghiz",
|
||||
"nativeName" => "кыргыз тили"
|
||||
],
|
||||
"kv" => [
|
||||
"name" => "Komi",
|
||||
"nativeName" => "коми кыв"
|
||||
],
|
||||
"kg" => [
|
||||
"name" => "Kongo",
|
||||
"nativeName" => "KiKongo"
|
||||
],
|
||||
"ko" => [
|
||||
"name" => "Korean",
|
||||
"nativeName" => "한국어"
|
||||
],
|
||||
"ku" => [
|
||||
"name" => "Kurdish",
|
||||
"nativeName" => "كوردی"
|
||||
],
|
||||
"kj" => [
|
||||
"name" => "Kwanyama",
|
||||
"nativeName" => "Kuanyama"
|
||||
],
|
||||
"la" => [
|
||||
"name" => "Latin",
|
||||
"nativeName" => "latine"
|
||||
],
|
||||
"lb" => [
|
||||
"name" => "Luxembourgish",
|
||||
"nativeName" => "Lëtzebuergesch"
|
||||
],
|
||||
"lg" => [
|
||||
"name" => "Luganda",
|
||||
"nativeName" => "Luganda"
|
||||
],
|
||||
"li" => [
|
||||
"name" => "Limburgish",
|
||||
"nativeName" => "Limburgs"
|
||||
],
|
||||
"ln" => [
|
||||
"name" => "Lingala",
|
||||
"nativeName" => "Lingála"
|
||||
],
|
||||
"lo" => [
|
||||
"name" => "Lao",
|
||||
"nativeName" => "ພາສາລາວ"
|
||||
],
|
||||
"lt" => [
|
||||
"name" => "Lithuanian",
|
||||
"nativeName" => "lietuvių kalba"
|
||||
],
|
||||
"lu" => [
|
||||
"name" => "Luba-Katanga",
|
||||
"nativeName" => "Luba-Katanga"
|
||||
],
|
||||
"lv" => [
|
||||
"name" => "Latvian",
|
||||
"nativeName" => "latviešu valoda"
|
||||
],
|
||||
"gv" => [
|
||||
"name" => "Manx",
|
||||
"nativeName" => "Gaelg"
|
||||
],
|
||||
"mk" => [
|
||||
"name" => "Macedonian",
|
||||
"nativeName" => "македонски јазик"
|
||||
],
|
||||
"mg" => [
|
||||
"name" => "Malagasy",
|
||||
"nativeName" => "Malagasy fiteny"
|
||||
],
|
||||
"ms" => [
|
||||
"name" => "Malay",
|
||||
"nativeName" => "بهاس ملايو"
|
||||
],
|
||||
"ml" => [
|
||||
"name" => "Malayalam",
|
||||
"nativeName" => "മലയാളം"
|
||||
],
|
||||
"mt" => [
|
||||
"name" => "Maltese",
|
||||
"nativeName" => "Malti"
|
||||
],
|
||||
"mi" => [
|
||||
"name" => "Māori",
|
||||
"nativeName" => "te reo Māori"
|
||||
],
|
||||
"mr" => [
|
||||
"name" => "Marathi",
|
||||
"nativeName" => "मराठी"
|
||||
],
|
||||
"mh" => [
|
||||
"name" => "Marshallese",
|
||||
"nativeName" => "Kajin M̧ajeļ"
|
||||
],
|
||||
"mn" => [
|
||||
"name" => "Mongolian",
|
||||
"nativeName" => "монгол"
|
||||
],
|
||||
"na" => [
|
||||
"name" => "Nauru",
|
||||
"nativeName" => "Ekakairũ Naoero"
|
||||
],
|
||||
"nv" => [
|
||||
"name" => "Navajo",
|
||||
"nativeName" => "Diné bizaad"
|
||||
],
|
||||
"nb" => [
|
||||
"name" => "Norwegian Bokmål",
|
||||
"nativeName" => "Norsk bokmål"
|
||||
],
|
||||
"nd" => [
|
||||
"name" => "North Ndebele",
|
||||
"nativeName" => "isiNdebele"
|
||||
],
|
||||
"ne" => [
|
||||
"name" => "Nepali",
|
||||
"nativeName" => "नेपाली"
|
||||
],
|
||||
"ng" => [
|
||||
"name" => "Ndonga",
|
||||
"nativeName" => "Owambo"
|
||||
],
|
||||
"nn" => [
|
||||
"name" => "Norwegian Nynorsk",
|
||||
"nativeName" => "Norsk nynorsk"
|
||||
],
|
||||
"no" => [
|
||||
"name" => "Norwegian",
|
||||
"nativeName" => "Norsk"
|
||||
],
|
||||
"ii" => [
|
||||
"name" => "Nuosu",
|
||||
"nativeName" => "ꆈꌠ꒿ Nuosuhxop"
|
||||
],
|
||||
"nr" => [
|
||||
"name" => "South Ndebele",
|
||||
"nativeName" => "isiNdebele"
|
||||
],
|
||||
"oc" => [
|
||||
"name" => "Occitan",
|
||||
"nativeName" => "Occitan"
|
||||
],
|
||||
"oj" => [
|
||||
"name" => "Ojibwe, Ojibwa",
|
||||
"nativeName" => "ᐊᓂᔑᓈᐯᒧᐎᓐ"
|
||||
],
|
||||
"cu" => [
|
||||
"name" => "Church Slavic",
|
||||
"nativeName" => "ѩзыкъ словѣньскъ"
|
||||
],
|
||||
"om" => [
|
||||
"name" => "Oromo",
|
||||
"nativeName" => "Afaan Oromoo"
|
||||
],
|
||||
"or" => [
|
||||
"name" => "Oriya",
|
||||
"nativeName" => "ଓଡ଼ିଆ"
|
||||
],
|
||||
"os" => [
|
||||
"name" => "Ossetian",
|
||||
"nativeName" => "ирон æвзаг"
|
||||
],
|
||||
"pa" => [
|
||||
"name" => "Panjabi",
|
||||
"nativeName" => "ਪੰਜਾਬੀ"
|
||||
],
|
||||
"pi" => [
|
||||
"name" => "Pāli",
|
||||
"nativeName" => "पाऴि"
|
||||
],
|
||||
"fa" => [
|
||||
"name" => "Persian",
|
||||
"nativeName" => "فارسی"
|
||||
],
|
||||
"pl" => [
|
||||
"name" => "Polish",
|
||||
"nativeName" => "polski"
|
||||
],
|
||||
"ps" => [
|
||||
"name" => "Pashto",
|
||||
"nativeName" => "پښتو"
|
||||
],
|
||||
"pt" => [
|
||||
"name" => "Portuguese",
|
||||
"nativeName" => "Português"
|
||||
],
|
||||
"qu" => [
|
||||
"name" => "Quechua",
|
||||
"nativeName" => "Runa Simi"
|
||||
],
|
||||
"rm" => [
|
||||
"name" => "Romansh",
|
||||
"nativeName" => "rumantsch grischun"
|
||||
],
|
||||
"rn" => [
|
||||
"name" => "Kirundi",
|
||||
"nativeName" => "kiRundi"
|
||||
],
|
||||
"ro" => [
|
||||
"name" => "Romanian",
|
||||
"nativeName" => "română"
|
||||
],
|
||||
"ru" => [
|
||||
"name" => "Russian",
|
||||
"nativeName" => "русский язык"
|
||||
],
|
||||
"sa" => [
|
||||
"name" => "Sanskrit",
|
||||
"nativeName" => "संस्कृतम्"
|
||||
],
|
||||
"sc" => [
|
||||
"name" => "Sardinian",
|
||||
"nativeName" => "sardu"
|
||||
],
|
||||
"sd" => [
|
||||
"name" => "Sindhi",
|
||||
"nativeName" => "सिन्धी"
|
||||
],
|
||||
"se" => [
|
||||
"name" => "Northern Sami",
|
||||
"nativeName" => "Davvisámegiella"
|
||||
],
|
||||
"sm" => [
|
||||
"name" => "Samoan",
|
||||
"nativeName" => "gagana faa Samoa"
|
||||
],
|
||||
"sg" => [
|
||||
"name" => "Sango",
|
||||
"nativeName" => "yângâ tî sängö"
|
||||
],
|
||||
"sr" => [
|
||||
"name" => "Serbian",
|
||||
"nativeName" => "српски језик"
|
||||
],
|
||||
"gd" => [
|
||||
"name" => "Scottish Gaelic",
|
||||
"nativeName" => "Gàidhlig"
|
||||
],
|
||||
"sn" => [
|
||||
"name" => "Shona",
|
||||
"nativeName" => "chiShona"
|
||||
],
|
||||
"si" => [
|
||||
"name" => "Sinhala",
|
||||
"nativeName" => "සිංහල"
|
||||
],
|
||||
"sk" => [
|
||||
"name" => "Slovak",
|
||||
"nativeName" => "slovenčina"
|
||||
],
|
||||
"sl" => [
|
||||
"name" => "Slovene",
|
||||
"nativeName" => "slovenščina"
|
||||
],
|
||||
"so" => [
|
||||
"name" => "Somali",
|
||||
"nativeName" => "Soomaaliga"
|
||||
],
|
||||
"st" => [
|
||||
"name" => "Southern Sotho",
|
||||
"nativeName" => "Sesotho"
|
||||
],
|
||||
"es" => [
|
||||
"name" => "Spanish",
|
||||
"nativeName" => "español"
|
||||
],
|
||||
"su" => [
|
||||
"name" => "Sundanese",
|
||||
"nativeName" => "Basa Sunda"
|
||||
],
|
||||
"sw" => [
|
||||
"name" => "Swahili",
|
||||
"nativeName" => "Kiswahili"
|
||||
],
|
||||
"ss" => [
|
||||
"name" => "Swati",
|
||||
"nativeName" => "SiSwati"
|
||||
],
|
||||
"sv" => [
|
||||
"name" => "Swedish",
|
||||
"nativeName" => "svenska"
|
||||
],
|
||||
"ta" => [
|
||||
"name" => "Tamil",
|
||||
"nativeName" => "தமிழ்"
|
||||
],
|
||||
"te" => [
|
||||
"name" => "Telugu",
|
||||
"nativeName" => "తెలుగు"
|
||||
],
|
||||
"tg" => [
|
||||
"name" => "Tajik",
|
||||
"nativeName" => "тоҷикӣ"
|
||||
],
|
||||
"th" => [
|
||||
"name" => "Thai",
|
||||
"nativeName" => "ไทย"
|
||||
],
|
||||
"ti" => [
|
||||
"name" => "Tigrinya",
|
||||
"nativeName" => "ትግርኛ"
|
||||
],
|
||||
"bo" => [
|
||||
"name" => "Tibetan",
|
||||
"nativeName" => "བོད་ཡིག"
|
||||
],
|
||||
"tk" => [
|
||||
"name" => "Turkmen",
|
||||
"nativeName" => "Türkmen"
|
||||
],
|
||||
"tl" => [
|
||||
"name" => "Tagalog",
|
||||
"nativeName" => "Wikang Tagalog"
|
||||
],
|
||||
"tn" => [
|
||||
"name" => "Tswana",
|
||||
"nativeName" => "Setswana"
|
||||
],
|
||||
"to" => [
|
||||
"name" => "Tonga",
|
||||
"nativeName" => "faka Tonga"
|
||||
],
|
||||
"tr" => [
|
||||
"name" => "Turkish",
|
||||
"nativeName" => "Türkçe"
|
||||
],
|
||||
"ts" => [
|
||||
"name" => "Tsonga",
|
||||
"nativeName" => "Xitsonga"
|
||||
],
|
||||
"tt" => [
|
||||
"name" => "Tatar",
|
||||
"nativeName" => "татарча"
|
||||
],
|
||||
"tw" => [
|
||||
"name" => "Twi",
|
||||
"nativeName" => "Twi"
|
||||
],
|
||||
"ty" => [
|
||||
"name" => "Tahitian",
|
||||
"nativeName" => "Reo Tahiti"
|
||||
],
|
||||
"ug" => [
|
||||
"name" => "Uighur",
|
||||
"nativeName" => "Uyƣurqə"
|
||||
],
|
||||
"uk" => [
|
||||
"name" => "Ukrainian",
|
||||
"nativeName" => "українська"
|
||||
],
|
||||
"ur" => [
|
||||
"name" => "Urdu",
|
||||
"nativeName" => "اردو"
|
||||
],
|
||||
"uz" => [
|
||||
"name" => "Uzbek",
|
||||
"nativeName" => "zbek"
|
||||
],
|
||||
"ve" => [
|
||||
"name" => "Venda",
|
||||
"nativeName" => "Tshivenḓa"
|
||||
],
|
||||
"vi" => [
|
||||
"name" => "Vietnamese",
|
||||
"nativeName" => "Tiếng Việt"
|
||||
],
|
||||
"vo" => [
|
||||
"name" => "Volapük",
|
||||
"nativeName" => "Volapük"
|
||||
],
|
||||
"wa" => [
|
||||
"name" => "Walloon",
|
||||
"nativeName" => "Walon"
|
||||
],
|
||||
"cy" => [
|
||||
"name" => "Welsh",
|
||||
"nativeName" => "Cymraeg"
|
||||
],
|
||||
"wo" => [
|
||||
"name" => "Wolof",
|
||||
"nativeName" => "Wollof"
|
||||
],
|
||||
"fy" => [
|
||||
"name" => "Western Frisian",
|
||||
"nativeName" => "Frysk"
|
||||
],
|
||||
"xh" => [
|
||||
"name" => "Xhosa",
|
||||
"nativeName" => "isiXhosa"
|
||||
],
|
||||
"yi" => [
|
||||
"name" => "Yiddish",
|
||||
"nativeName" => "ייִדיש"
|
||||
],
|
||||
"yo" => [
|
||||
"name" => "Yoruba",
|
||||
"nativeName" => "Yorùbá"
|
||||
],
|
||||
"za" => [
|
||||
"name" => "Zhuang",
|
||||
"nativeName" => "Saɯ cueŋƅ"
|
||||
]
|
||||
];
|
||||
|
||||
public static function getName($code)
|
||||
{
|
||||
return static::get($code, 'name');
|
||||
}
|
||||
|
||||
public static function getNativeName($code)
|
||||
{
|
||||
return static::get($code, 'nativeName');
|
||||
}
|
||||
|
||||
public static function getNames(array $keys)
|
||||
{
|
||||
$results = [];
|
||||
foreach ($keys as $key) {
|
||||
if (isset(static::$codes[$key])) {
|
||||
$results[$key] = static::$codes[$key];
|
||||
}
|
||||
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
protected static function get($code, $type)
|
||||
{
|
||||
if (isset(static::$codes[$code][$type])) {
|
||||
return static::$codes[$code][$type];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ trait ParsedownGravTrait
|
||||
protected $twig_link_regex = '/\!*\[(?:.*)\]\((\{([\{%#])\s*(.*?)\s*(?:\2|\})\})\)/';
|
||||
|
||||
/**
|
||||
* Initialiazation function to setup key variables needed by the MarkdownGravLinkTrait
|
||||
* Initialization function to setup key variables needed by the MarkdownGravLinkTrait
|
||||
*
|
||||
* @param $page
|
||||
* @param $defaults
|
||||
|
||||
@@ -216,7 +216,7 @@ class ImageMedium extends Medium
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn the current Medium inta a Link with lightbox enabled
|
||||
* Turn the current Medium into a Link with lightbox enabled
|
||||
*
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
|
||||
@@ -60,7 +60,7 @@ class Medium extends Data implements RenderableInterface
|
||||
{
|
||||
parent::__construct($items, $blueprint);
|
||||
|
||||
if (self::getGrav()['config']->get('media.enable_media_timestamp', true)) {
|
||||
if (self::getGrav()['config']->get('system.media.enable_media_timestamp', true)) {
|
||||
$this->querystring('&' . self::getGrav()['cache']->getKey());
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ class Medium extends Data implements RenderableInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn the current Medium inta a Link with lightbox enabled
|
||||
* Turn the current Medium into a Link with lightbox enabled
|
||||
*
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
|
||||
@@ -90,7 +90,7 @@ class ThumbnailImageMedium extends ImageMedium
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn the current Medium inta a Link with lightbox enabled
|
||||
* Turn the current Medium into a Link with lightbox enabled
|
||||
*
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
|
||||
@@ -34,16 +34,9 @@ class Page
|
||||
* @var string Filename. Leave as null if page is folder.
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var string Folder name.
|
||||
*/
|
||||
protected $folder;
|
||||
|
||||
/**
|
||||
* @var string Path to the folder. Add $this->folder to get full path.
|
||||
*/
|
||||
protected $path;
|
||||
protected $extension;
|
||||
|
||||
protected $parent;
|
||||
protected $template;
|
||||
@@ -54,6 +47,9 @@ class Page
|
||||
protected $unpublish_date;
|
||||
protected $slug;
|
||||
protected $route;
|
||||
protected $raw_route;
|
||||
protected $url;
|
||||
protected $routes;
|
||||
protected $routable;
|
||||
protected $modified;
|
||||
protected $id;
|
||||
@@ -120,7 +116,7 @@ class Page
|
||||
$this->header();
|
||||
$this->date();
|
||||
$this->metadata();
|
||||
$this->slug();
|
||||
$this->url();
|
||||
$this->visible();
|
||||
$this->modularTwig($this->slug[0] == '_');
|
||||
|
||||
@@ -142,6 +138,7 @@ class Page
|
||||
}
|
||||
}
|
||||
$this->published();
|
||||
$this->extension();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,6 +223,9 @@ class Page
|
||||
if (isset($this->header->slug)) {
|
||||
$this->slug = trim($this->header->slug);
|
||||
}
|
||||
if (isset($this->header->routes)) {
|
||||
$this->routes = (array)($this->header->routes);
|
||||
}
|
||||
if (isset($this->header->title)) {
|
||||
$this->title = trim($this->header->title);
|
||||
}
|
||||
@@ -617,6 +617,22 @@ class Page
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get page extension
|
||||
*
|
||||
* @param $var
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function extension($var = null)
|
||||
{
|
||||
if ($var !== null) {
|
||||
$this->extension = $var;
|
||||
}
|
||||
|
||||
return $this->extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save page if there's a file assigned to it.
|
||||
* @param bool $reorder Internal use.
|
||||
@@ -820,7 +836,7 @@ class Page
|
||||
$this->template = $var;
|
||||
}
|
||||
if (empty($this->template)) {
|
||||
$this->template = ($this->modular() ? 'modular/' : '') . str_replace(CONTENT_EXT, '', $this->name());
|
||||
$this->template = ($this->modular() ? 'modular/' : '') . str_replace($this->extension, '', $this->name());
|
||||
}
|
||||
return $this->template;
|
||||
}
|
||||
@@ -1050,16 +1066,13 @@ class Page
|
||||
{
|
||||
if ($var !== null) {
|
||||
$this->slug = $var;
|
||||
$baseRoute = $this->parent ? (string) $this->parent()->route() : null;
|
||||
$this->route = isset($baseRoute) ? $baseRoute . '/'. $this->slug : null;
|
||||
}
|
||||
|
||||
if (empty($this->slug)) {
|
||||
$regex = '/^[0-9]+\./u';
|
||||
$this->slug = preg_replace($regex, '', $this->folder);
|
||||
$baseRoute = $this->parent ? (string) $this->parent()->route() : null;
|
||||
$this->route = isset($baseRoute) ? $baseRoute . '/'. $this->slug : null;
|
||||
}
|
||||
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
@@ -1104,19 +1117,36 @@ class Page
|
||||
/**
|
||||
* Gets the url for the Page.
|
||||
*
|
||||
* @param bool $include_host Defaults false, but true would include http://yourhost.com
|
||||
* @return string The url.
|
||||
* @param bool $include_host Defaults false, but true would include http://yourhost.com
|
||||
* @param bool $canonical true to return the canonical URL
|
||||
*
|
||||
* @return string The url.
|
||||
*/
|
||||
public function url($include_host = false)
|
||||
public function url($include_host = false, $canonical = false)
|
||||
{
|
||||
|
||||
/** @var Pages $pages */
|
||||
$pages = self::getGrav()['pages'];
|
||||
|
||||
/** @var Language $language */
|
||||
$language = self::getGrav()['language'];
|
||||
|
||||
// get pre-route
|
||||
$pre_route = $language->enabled() && $language->getActive() ? '/'.$language->getActive() : '';
|
||||
|
||||
// get canonical route if requested
|
||||
if ($canonical) {
|
||||
$route = $pre_route . $this->routeCanonical();
|
||||
} else {
|
||||
$route = $pre_route . $this->route();
|
||||
}
|
||||
|
||||
/** @var Uri $uri */
|
||||
$uri = self::getGrav()['uri'];
|
||||
|
||||
$rootUrl = $uri->rootUrl($include_host) . $pages->base();
|
||||
$url = $rootUrl.'/'.trim($this->route(), '/');
|
||||
|
||||
$url = $rootUrl.'/'.trim($route, '/');
|
||||
|
||||
// trim trailing / if not root
|
||||
if ($url !== '/') {
|
||||
@@ -1127,7 +1157,8 @@ class Page
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the route for the page based on the parents route and the current Page's slug.
|
||||
* Gets the route for the page based on the route headers if available, else from
|
||||
* the parents route and the current Page's slug.
|
||||
*
|
||||
* @param string $var Set new default route.
|
||||
*
|
||||
@@ -1138,9 +1169,81 @@ class Page
|
||||
if ($var !== null) {
|
||||
$this->route = $var;
|
||||
}
|
||||
|
||||
if (empty($this->route)) {
|
||||
// calculate route based on parent slugs
|
||||
$baseRoute = $this->parent ? (string) $this->parent()->route() : null;
|
||||
$this->route = isset($baseRoute) ? $baseRoute . '/'. $this->slug() : null;
|
||||
|
||||
if (!empty($this->routes) && isset($this->routes['default'])) {
|
||||
$this->routes['aliases'][] = $this->route;
|
||||
$this->route = $this->routes['default'];
|
||||
return $this->route;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->route;
|
||||
}
|
||||
|
||||
public function rawRoute($var = null)
|
||||
{
|
||||
if ($var !== null) {
|
||||
$this->raw_route = $var;
|
||||
}
|
||||
|
||||
if (empty($this->raw_route)) {
|
||||
$baseRoute = $this->parent ? (string) $this->parent()->rawRoute() : null;
|
||||
|
||||
$regex = '/^[0-9]+\./u';
|
||||
$slug = preg_replace($regex, '', $this->folder);
|
||||
|
||||
$this->raw_route = isset($baseRoute) ? $baseRoute . '/'. $slug : null;
|
||||
}
|
||||
|
||||
return $this->raw_route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the route aliases for the page based on page headers.
|
||||
*
|
||||
* @param array $var list of route aliases
|
||||
*
|
||||
* @return array The route aliases for the Page.
|
||||
*/
|
||||
public function routeAliases($var = null)
|
||||
{
|
||||
if ($var !== null) {
|
||||
$this->routes['aliases'] = (array) $var;
|
||||
}
|
||||
|
||||
if (!empty($this->routes) && isset($this->routes['aliases'])) {
|
||||
return $this->routes['aliases'];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the canonical route for this page if its set. If provided it will use
|
||||
* that value, else if it's `true` it will use the default route.
|
||||
*
|
||||
* @param null $var
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public function routeCanonical($var = null)
|
||||
{
|
||||
if ($var !== null) {
|
||||
$this->routes['canonical'] = (array)$var;
|
||||
}
|
||||
|
||||
if (!empty($this->routes) && isset($this->routes['canonical'])) {
|
||||
return $this->routes['canonical'];
|
||||
}
|
||||
|
||||
return $this->route();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets and sets the identifier for this Page object.
|
||||
*
|
||||
@@ -1500,10 +1603,14 @@ class Page
|
||||
*/
|
||||
public function active()
|
||||
{
|
||||
/** @var Uri $uri */
|
||||
$uri = self::getGrav()['uri'];
|
||||
if ($this->url() == $uri->url()) {
|
||||
return true;
|
||||
$uri_path = self::getGrav()['uri']->path();
|
||||
$routes = self::getGrav()['pages']->routes();
|
||||
|
||||
if (isset($routes[$uri_path])) {
|
||||
if ($routes[$uri_path] == $this->path()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1516,20 +1623,18 @@ class Page
|
||||
*/
|
||||
public function activeChild()
|
||||
{
|
||||
/** @var Uri $uri */
|
||||
$uri = self::getGrav()['uri'];
|
||||
$config = self::getGrav()['config'];
|
||||
$pages = self::getGrav()['pages'];
|
||||
$uri_path = $uri->path();
|
||||
$routes = self::getGrav()['pages']->routes();
|
||||
|
||||
// Special check when item is home
|
||||
if ($this->home()) {
|
||||
$paths = $uri->paths();
|
||||
$home = ltrim($config->get('system.home.alias'), '/');
|
||||
if (isset($paths[0]) && $paths[0] == $home) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (strpos($uri->url(), $this->url()) === 0) {
|
||||
return true;
|
||||
if (isset($routes[$uri_path])) {
|
||||
$child_page = $pages->dispatch($uri->route())->parent();
|
||||
while (!$child_page->root()) {
|
||||
if ($this->path() == $child_page->path()) {
|
||||
return true;
|
||||
}
|
||||
$child_page = $child_page->parent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1734,7 +1839,6 @@ class Page
|
||||
return $results;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether or not this Page object has a .md file associated with it or if its just a directory.
|
||||
*
|
||||
|
||||
@@ -6,6 +6,7 @@ use Grav\Common\Config\Config;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Common\Cache;
|
||||
use Grav\Common\Taxonomy;
|
||||
use Grav\Common\Language;
|
||||
use Grav\Common\Data\Blueprint;
|
||||
use Grav\Common\Data\Blueprints;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
@@ -66,6 +67,8 @@ class Pages
|
||||
*/
|
||||
static protected $types;
|
||||
|
||||
static protected $home_route;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -276,7 +279,7 @@ class Pages
|
||||
try {
|
||||
$found = preg_replace($pattern, $replace, $url);
|
||||
if ($found != $url) {
|
||||
$this->grav->redirect($found);
|
||||
$this->grav->redirectLangSafe($found);
|
||||
}
|
||||
} catch (ErrorException $e) {
|
||||
$this->grav['log']->error('site.redirects: '. $pattern . '-> ' . $e->getMessage());
|
||||
@@ -451,6 +454,48 @@ class Pages
|
||||
return $pages->getList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get's the home route
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getHomeRoute()
|
||||
{
|
||||
if (empty(self::$home)) {
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $grav['config'];
|
||||
|
||||
/** @var Language $language */
|
||||
$language = $grav['language'];
|
||||
|
||||
$home = $config->get('system.home.alias');
|
||||
|
||||
if ($language->enabled()) {
|
||||
$home_aliases = $config->get('system.home.aliases');
|
||||
if ($home_aliases) {
|
||||
$active = $language->getActive();
|
||||
$default = $language->getDefault();
|
||||
|
||||
try {
|
||||
if ($active) {
|
||||
$home = $home_aliases[$active];
|
||||
} else {
|
||||
$home = $home_aliases[$default];
|
||||
}
|
||||
} catch (ErrorException $e) {
|
||||
$home = $home_aliases[$default];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
self::$home_route = trim($home, '/');
|
||||
}
|
||||
return self::$home_route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds pages.
|
||||
*
|
||||
@@ -463,6 +508,9 @@ class Pages
|
||||
/** @var Config $config */
|
||||
$config = $this->grav['config'];
|
||||
|
||||
/** @var Language $language */
|
||||
$language = $this->grav['language'];
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $this->grav['locator'];
|
||||
$pagesDir = $locator->findResource('page://');
|
||||
@@ -486,7 +534,7 @@ class Pages
|
||||
$last_modified = Folder::lastModifiedFile($pagesDir);
|
||||
}
|
||||
|
||||
$page_cache_id = md5(USER_DIR.$last_modified.$config->checksum());
|
||||
$page_cache_id = md5(USER_DIR.$last_modified.$language->getActive().$config->checksum());
|
||||
|
||||
list($this->instances, $this->routes, $this->children, $taxonomy_map, $this->sort) = $cache->fetch($page_cache_id);
|
||||
if (!$this->instances) {
|
||||
@@ -523,15 +571,21 @@ class Pages
|
||||
protected function recurse($directory, Page &$parent = null)
|
||||
{
|
||||
$directory = rtrim($directory, DS);
|
||||
$iterator = new \DirectoryIterator($directory);
|
||||
$page = new Page;
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $this->grav['config'];
|
||||
|
||||
// Fire event for memory and time consuming plugins...
|
||||
if ($parent === null && $config->get('system.pages.events.page')) {
|
||||
$this->grav->fireEvent('onBuildPagesInitialized');
|
||||
/** @var Language $language */
|
||||
$language = $this->grav['language'];
|
||||
|
||||
// stuff to do at root page
|
||||
if ($parent === null) {
|
||||
|
||||
// Fire event for memory and time consuming plugins...
|
||||
if ($config->get('system.pages.events.page')) {
|
||||
$this->grav->fireEvent('onBuildPagesInitialized');
|
||||
}
|
||||
}
|
||||
|
||||
$page->path($directory);
|
||||
@@ -552,17 +606,39 @@ class Pages
|
||||
throw new \RuntimeException('Fatal error when creating page instances.');
|
||||
}
|
||||
|
||||
$content_exists = false;
|
||||
$pages_found = glob($directory.'/*'.CONTENT_EXT);
|
||||
$page_extensions = $language->getFallbackPageExtensions();
|
||||
|
||||
if ($pages_found) {
|
||||
foreach ($page_extensions as $extension) {
|
||||
foreach ($pages_found as $found) {
|
||||
if (preg_match('/^.*\/[0-9A-Za-z\-\_]+('.$extension.')$/', $found)) {
|
||||
$page_found = $found;
|
||||
$page_extension = $extension;
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($page_found)) {
|
||||
$file = new \SplFileInfo($page_found);
|
||||
$page->init($file);
|
||||
$page->extension($page_extension);
|
||||
|
||||
$content_exists = true;
|
||||
|
||||
if ($config->get('system.pages.events.page')) {
|
||||
$this->grav->fireEvent('onPageProcessed', new Event(['page' => $page]));
|
||||
}
|
||||
}
|
||||
|
||||
// set current modified of page
|
||||
$last_modified = $page->modified();
|
||||
|
||||
// flat for content availability
|
||||
$content_exists = false;
|
||||
|
||||
/** @var \DirectoryIterator $file */
|
||||
foreach ($iterator as $file) {
|
||||
if ($file->isDot()) {
|
||||
continue;
|
||||
}
|
||||
foreach (new \FilesystemIterator($directory) as $file) {
|
||||
|
||||
$name = $file->getFilename();
|
||||
|
||||
@@ -571,15 +647,6 @@ class Pages
|
||||
if ($file->getBasename() !== '.DS_Store' && ($modified = $file->getMTime()) > $last_modified) {
|
||||
$last_modified = $modified;
|
||||
}
|
||||
|
||||
if (preg_match('/^[^.].*'.CONTENT_EXT.'$/', $name)) {
|
||||
$page->init($file);
|
||||
$content_exists = true;
|
||||
|
||||
if ($config->get('system.pages.events.page')) {
|
||||
$this->grav->fireEvent('onPageProcessed', new Event(['page' => $page]));
|
||||
}
|
||||
}
|
||||
} elseif ($file->isDir()) {
|
||||
if (!$page->path()) {
|
||||
$page->path($file->getPath());
|
||||
@@ -623,29 +690,45 @@ class Pages
|
||||
/** @var $taxonomy Taxonomy */
|
||||
$taxonomy = $this->grav['taxonomy'];
|
||||
|
||||
// Get the home route
|
||||
$home = self::getHomeRoute();
|
||||
|
||||
// Build routes and taxonomy map.
|
||||
/** @var $page Page */
|
||||
foreach ($this->instances as $page) {
|
||||
$parent = $page->parent();
|
||||
|
||||
if ($parent) {
|
||||
$route = rtrim($parent->route(), '/') . '/' . $page->slug();
|
||||
$this->routes[$route] = $page->path();
|
||||
$page->route($route);
|
||||
}
|
||||
|
||||
if (!empty($route)) {
|
||||
if (!$page->root()) {
|
||||
// process taxonomy
|
||||
$taxonomy->addTaxonomy($page);
|
||||
} else {
|
||||
$page->routable(false);
|
||||
|
||||
$route = $page->route();
|
||||
$raw_route = $page->rawRoute();
|
||||
$page_path = $page->path();
|
||||
|
||||
// add regular route
|
||||
$this->routes[$route] = $page_path;
|
||||
|
||||
// add raw route
|
||||
if ($raw_route != $route) {
|
||||
$this->routes[$raw_route] = $page_path;
|
||||
}
|
||||
|
||||
// add canonical route
|
||||
$route_canonical = $page->routeCanonical();
|
||||
if ($route_canonical && ($route !== $route_canonical)) {
|
||||
$this->routes[$route_canonical] = $page_path;
|
||||
}
|
||||
|
||||
// add aliases to routes list if they are provided
|
||||
$route_aliases = $page->routeAliases();
|
||||
if ($route_aliases) {
|
||||
foreach ($route_aliases as $alias) {
|
||||
$this->routes[$alias] = $page_path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $this->grav['config'];
|
||||
|
||||
// Alias and set default route to home page.
|
||||
$home = trim($config->get('system.home.alias'), '/');
|
||||
if ($home && isset($this->routes['/' . $home])) {
|
||||
$this->routes['/'] = $this->routes['/' . $home];
|
||||
$this->get($this->routes['/' . $home])->route('/');
|
||||
|
||||
35
system/src/Grav/Common/Session.php
Normal file
35
system/src/Grav/Common/Session.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace Grav\Common;
|
||||
|
||||
/**
|
||||
* Wrapper for Session
|
||||
*/
|
||||
class Session extends \RocketTheme\Toolbox\Session\Session
|
||||
{
|
||||
protected $grav;
|
||||
protected $session;
|
||||
|
||||
public function __construct(Grav $grav)
|
||||
{
|
||||
$this->grav = $grav;
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
/** @var Uri $uri */
|
||||
$uri = $this->grav['uri'];
|
||||
$config = $this->grav['config'];
|
||||
|
||||
if ($config->get('system.session.enabled')) {
|
||||
// Define session service.
|
||||
parent::__construct(
|
||||
$config->get('system.session.timeout', 1800),
|
||||
$config->get('system.session.path', '/' . ltrim($uri->rootUrl(false), '/'))
|
||||
);
|
||||
|
||||
$site_identifier = $config->get('site.title', 'unkown');
|
||||
$this->setName($config->get('system.session.name', 'grav_site') . '_' . substr(md5($site_identifier), 0, 7));
|
||||
$this->start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,13 +52,13 @@ class Taxonomy
|
||||
$page_taxonomy = $page->taxonomy();
|
||||
}
|
||||
|
||||
if (!$page->published()) {
|
||||
if (!$page->published() || empty($page_taxonomy)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $this->grav['config'];
|
||||
if ($config->get('site.taxonomies') && count($page_taxonomy) > 0) {
|
||||
if ($config->get('site.taxonomies')) {
|
||||
foreach ((array) $config->get('site.taxonomies') as $taxonomy) {
|
||||
if (isset($page_taxonomy[$taxonomy])) {
|
||||
foreach ((array) $page_taxonomy[$taxonomy] as $item) {
|
||||
@@ -76,7 +76,7 @@ class Taxonomy
|
||||
*
|
||||
* @param array $taxonomies taxonomies to search, eg ['tag'=>['animal','cat']]
|
||||
* @param string $operator can be 'or' or 'and' (defaults to 'or')
|
||||
* @return Colleciton Collection object set to contain matches found in the taxonomy map
|
||||
* @return Collection Collection object set to contain matches found in the taxonomy map
|
||||
*/
|
||||
public function findTaxonomy($taxonomies, $operator = 'and')
|
||||
{
|
||||
|
||||
@@ -221,7 +221,13 @@ class Themes extends Iterator
|
||||
protected function loadConfiguration($name, Config $config)
|
||||
{
|
||||
$themeConfig = CompiledYamlFile::instance("themes://{$name}/{$name}" . YAML_EXT)->content();
|
||||
|
||||
$config->joinDefaults("themes.{$name}", $themeConfig);
|
||||
|
||||
if ($this->grav['language']->enabled()) {
|
||||
$languages = CompiledYamlFile::instance("themes://{$name}/languages". YAML_EXT)->content();
|
||||
if ($languages) {
|
||||
$config->getLanguages()->mergeRecursive($languages);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ class Twig
|
||||
public function __construct(Grav $grav)
|
||||
{
|
||||
$this->grav = $grav;
|
||||
$this->twig_paths = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,7 +73,23 @@ class Twig
|
||||
$locator = $this->grav['locator'];
|
||||
$debugger = $this->grav['debugger'];
|
||||
|
||||
$this->twig_paths = $locator->findResources('theme://templates');
|
||||
/** @var Language $language */
|
||||
$language = $this->grav['language'];
|
||||
|
||||
$active_language = $language->getActive();
|
||||
|
||||
$language_append = $active_language ? '/'.$active_language : '';
|
||||
|
||||
// handle language templates if available
|
||||
if ($language->enabled()) {
|
||||
$lang_templates = $locator->findResource('theme://templates/'.$active_language);
|
||||
if ($lang_templates) {
|
||||
$this->twig_paths[] = $lang_templates;
|
||||
}
|
||||
}
|
||||
|
||||
$this->twig_paths = array_merge($this->twig_paths, $locator->findResources('theme://templates'));
|
||||
|
||||
$this->grav->fireEvent('onTwigTemplatePaths');
|
||||
|
||||
$this->loader = new \Twig_Loader_Filesystem($this->twig_paths);
|
||||
@@ -131,9 +148,9 @@ class Twig
|
||||
'config' => $config,
|
||||
'uri' => $this->grav['uri'],
|
||||
'base_dir' => rtrim(ROOT_DIR, '/'),
|
||||
'base_url' => $this->grav['base_url'],
|
||||
'base_url_absolute' => $this->grav['base_url_absolute'],
|
||||
'base_url_relative' => $this->grav['base_url_relative'],
|
||||
'base_url' => $this->grav['base_url'] . $language_append,
|
||||
'base_url_absolute' => $this->grav['base_url_absolute'] . $language_append,
|
||||
'base_url_relative' => $this->grav['base_url_relative'] . $language_append,
|
||||
'theme_dir' => $locator->findResource('theme://'),
|
||||
'theme_url' => $this->grav['base_url'] .'/'. $locator->findResource('theme://', false),
|
||||
'site' => $config->get('site'),
|
||||
|
||||
@@ -16,11 +16,13 @@ class TwigExtension extends \Twig_Extension
|
||||
{
|
||||
protected $grav;
|
||||
protected $debugger;
|
||||
protected $config;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->grav = Grav::instance();
|
||||
$this->debugger = isset($this->grav['debugger']) ? $this->grav['debugger'] : null;
|
||||
$this->config = $this->grav['config'];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +56,8 @@ class TwigExtension extends \Twig_Extension
|
||||
new \Twig_SimpleFilter('absolute_url', [$this, 'absoluteUrlFilter']),
|
||||
new \Twig_SimpleFilter('markdown', [$this, 'markdownFilter']),
|
||||
new \Twig_SimpleFilter('starts_with', [$this, 'startsWithFilter']),
|
||||
new \Twig_SimpleFilter('ends_with', [$this, 'endsWithFilter'])
|
||||
new \Twig_SimpleFilter('ends_with', [$this, 'endsWithFilter']),
|
||||
new \Twig_SimpleFilter('t', [$this, 'translateFilter'])
|
||||
];
|
||||
}
|
||||
|
||||
@@ -72,6 +75,7 @@ class TwigExtension extends \Twig_Extension
|
||||
new \Twig_SimpleFunction('debug', [$this, 'dump'], ['needs_context' => true, 'needs_environment' => true]),
|
||||
new \Twig_SimpleFunction('gist', [$this, 'gistFunc']),
|
||||
new \Twig_simpleFunction('random_string', [$this, 'randomStringFunc']),
|
||||
new \Twig_simpleFunction('t', [$this, 'translateFunc'])
|
||||
];
|
||||
}
|
||||
|
||||
@@ -108,7 +112,7 @@ class TwigExtension extends \Twig_Extension
|
||||
* Truncate content by a limit.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $limit Nax number of characters.
|
||||
* @param int $limit Max number of characters.
|
||||
* @param string $break Break point.
|
||||
* @param string $pad Appended padding to the end of the string.
|
||||
* @return string
|
||||
@@ -335,7 +339,7 @@ class TwigExtension extends \Twig_Extension
|
||||
public function markdownFilter($string)
|
||||
{
|
||||
$page = $this->grav['page'];
|
||||
$defaults = $this->grav['config']->get('system.pages.markdown');
|
||||
$defaults = $this->$config->get('system.pages.markdown');
|
||||
|
||||
// Initialize the preferred variant of Parsedown
|
||||
if ($defaults['extra']) {
|
||||
@@ -349,14 +353,19 @@ class TwigExtension extends \Twig_Extension
|
||||
return $string;
|
||||
}
|
||||
|
||||
public function startsWithFilter($needle, $haystack)
|
||||
public function startsWithFilter($haystack, $needle)
|
||||
{
|
||||
return Utils::startsWith($needle, $haystack);
|
||||
return Utils::startsWith($haystack, $needle);
|
||||
}
|
||||
|
||||
public function endsWithFilter($needle, $haystack)
|
||||
public function endsWithFilter($haystack, $needle)
|
||||
{
|
||||
return Utils::endsWith($needle, $haystack);
|
||||
return Utils::endsWith($haystack, $needle);
|
||||
}
|
||||
|
||||
public function translateFilter()
|
||||
{
|
||||
return $this->grav['language']->translate(func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -459,4 +468,9 @@ class TwigExtension extends \Twig_Extension
|
||||
{
|
||||
return Utils::generateRandomString($count);
|
||||
}
|
||||
|
||||
public function translateFunc()
|
||||
{
|
||||
return $this->grav['language']->translate(func_get_args());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<?php
|
||||
namespace Grav\Common;
|
||||
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Page\Pages;
|
||||
|
||||
/**
|
||||
* The URI object provides information about the current URL
|
||||
*
|
||||
@@ -72,7 +75,10 @@ class Uri
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$config = Grav::instance()['config'];
|
||||
$grav = Grav::instance();
|
||||
|
||||
$config = $grav['config'];
|
||||
$language = $grav['language'];
|
||||
|
||||
// resets
|
||||
$this->paths = [];
|
||||
@@ -86,6 +92,19 @@ class Uri
|
||||
// process params
|
||||
$uri = $this->processParams($uri, $config->get('system.param_sep'));
|
||||
|
||||
// set active language
|
||||
$uri = $language->setActiveFromUri($uri);
|
||||
|
||||
// redirect to language specific homepage if configured to do so
|
||||
if ($uri == '/' && $language->enabled() && !$language->getActive()) {
|
||||
if ($config->get('system.languages.home_redirect.include_route', true)) {
|
||||
$prefix = $config->get('system.languages.home_redirect.include_lang', true) ? $language->getDefault() . '/' : '';
|
||||
$grav->redirect($prefix . Pages::getHomeRoute());
|
||||
} elseif ($config->get('system.languages.home_redirect.include_lang', true)) {
|
||||
$grav->redirect($language->getDefault() . '/');
|
||||
}
|
||||
}
|
||||
|
||||
// split the URL and params
|
||||
$bits = parse_url($uri);
|
||||
|
||||
@@ -384,7 +403,7 @@ class Uri
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrun the IP address of the current user
|
||||
* Return the IP address of the current user
|
||||
*
|
||||
* @return string ip address
|
||||
*/
|
||||
@@ -407,6 +426,7 @@ class Uri
|
||||
return $ipaddress;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this an external URL? if it starts with `http` then yes, else false
|
||||
*
|
||||
@@ -450,7 +470,7 @@ class Uri
|
||||
*
|
||||
* @return string the more friendly formatted url
|
||||
*/
|
||||
public static function convertUrl($page, $markdown_url)
|
||||
public static function convertUrl(Page $page, $markdown_url)
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ class User extends Data
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks user authorisation to the action.
|
||||
* Checks user authorization to the action.
|
||||
*
|
||||
* @param string $action
|
||||
* @return bool
|
||||
|
||||
@@ -19,6 +19,16 @@ abstract class Utils
|
||||
*/
|
||||
public static function startsWith($haystack, $needle)
|
||||
{
|
||||
if (is_array($needle)) {
|
||||
$status = false;
|
||||
foreach ($needle as $each_needle) {
|
||||
$status = $status || ($each_needle === '' || strpos($haystack, $each_needle) === 0);
|
||||
if ($status) {
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
return $needle === '' || strpos($haystack, $needle) === 0;
|
||||
}
|
||||
|
||||
@@ -29,6 +39,16 @@ abstract class Utils
|
||||
*/
|
||||
public static function endsWith($haystack, $needle)
|
||||
{
|
||||
if (is_array($needle)) {
|
||||
$status = false;
|
||||
foreach ($needle as $each_needle) {
|
||||
$status = $status || ($each_needle === '' || substr($haystack, -strlen($each_needle)) === $each_needle);
|
||||
if ($status) {
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
return $needle === '' || substr($haystack, -strlen($needle)) === $needle;
|
||||
}
|
||||
|
||||
@@ -72,7 +92,7 @@ abstract class Utils
|
||||
if (strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
|
||||
return $text;
|
||||
}
|
||||
// splits all html-tags to scanable lines
|
||||
// splits all html-tags to scannable lines
|
||||
preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);
|
||||
$total_length = strlen($ending);
|
||||
$truncate = '';
|
||||
@@ -137,7 +157,7 @@ abstract class Utils
|
||||
}
|
||||
// if the words shouldn't be cut in the middle...
|
||||
if (!$exact) {
|
||||
// ...search the last occurance of a space...
|
||||
// ...search the last occurrence of a space...
|
||||
$spacepos = strrpos($truncate, ' ');
|
||||
if (isset($spacepos)) {
|
||||
// ...and cut the text in this position
|
||||
|
||||
@@ -281,7 +281,7 @@ class SandboxCommand extends Command
|
||||
private function perms()
|
||||
{
|
||||
$this->output->writeln('');
|
||||
$this->output->writeln('<comment>Permisions Initializing</comment>');
|
||||
$this->output->writeln('<comment>Permissions Initializing</comment>');
|
||||
|
||||
$dir_perms = 0755;
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ class SelfupgradeCommand extends Command
|
||||
exit;
|
||||
}
|
||||
|
||||
// not used but pre-loaded just in case!
|
||||
// not used but preloaded just in case!
|
||||
new ArrayInput([]);
|
||||
|
||||
$questionHelper = $this->getHelper('question');
|
||||
|
||||
@@ -142,8 +142,6 @@ class UninstallCommand extends Command
|
||||
*/
|
||||
private function uninstallPackage($slug, $package)
|
||||
{
|
||||
$locator = self::getGrav()['locator'];
|
||||
|
||||
$path = self::getGrav()['locator']->findResource($package->package_type . '://' .$slug);
|
||||
Installer::uninstall($path);
|
||||
$errorCode = Installer::lastErrorCode();
|
||||
|
||||
@@ -160,7 +160,7 @@ class UpdateCommand extends Command
|
||||
$commandExec = $installCommand->run($args, $this->output);
|
||||
|
||||
if ($commandExec != 0) {
|
||||
$this->output->writeln("<red>Error:</red> An error occured while trying to install the extensions");
|
||||
$this->output->writeln("<red>Error:</red> An error occurred while trying to install the extensions");
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user