resp
@@ -1,3 +1,55 @@
|
||||
# v1.7.14
|
||||
## 04/29/2021
|
||||
|
||||
1. [](#new)
|
||||
* Added `MediaUploadTrait::checkFileMetadata()` method
|
||||
1. [](#improved)
|
||||
* Updating a theme should always keep the custom files [getgrav/grav-plugin-admin#2135](https://github.com/getgrav/grav-plugin-admin/issues/2135)
|
||||
1. [](#bugfix)
|
||||
* Fixed broken numeric language codes in Flex Pages [#3332](https://github.com/getgrav/grav/issues/3332)
|
||||
* Fixed broken `exif_imagetype()` twig function
|
||||
|
||||
# v1.7.13
|
||||
## 04/23/2021
|
||||
|
||||
1. [](#new)
|
||||
* Added support for getting translated collection of Flex Pages using `$collection->withTranslated('de')`
|
||||
1. [](#improved)
|
||||
* Moved `gregwar/Image` and `gregwar/Cache` in-house to official `getgrav/Image` and `getgrav/Cache` packagist packages. This will help environments with very strict proxy setups that don't allow VCS setup. [#3289](https://github.com/getgrav/grav/issues/3289)
|
||||
* Improved XSS Invalid Protocol detection regex [#3298](https://github.com/getgrav/grav/issues/3298)
|
||||
* Added support for user provided folder in Flex `$page->copy()`
|
||||
1. [](#bugfix)
|
||||
* Fixed `The "Grav/Common/Twig/TwigExtension" extension is not enabled` when using markdown twig tag [#3317](https://github.com/getgrav/grav/issues/3317)
|
||||
* Fixed text field maxlength validation newline issue [#3324](https://github.com/getgrav/grav/issues/3324)
|
||||
* Fixed a bug in Flex Object `refresh()` method
|
||||
|
||||
# v1.7.12
|
||||
## 04/15/2021
|
||||
|
||||
1. [](#improved)
|
||||
* Improve JSON support for the request
|
||||
1. [](#bugfix)
|
||||
* Fixed absolute path support for Windows [#3297](https://github.com/getgrav/grav/issues/3297)
|
||||
* Fixed adding tags in admin after upgrading Grav [#3315](https://github.com/getgrav/grav/issues/3315)
|
||||
|
||||
# v1.7.11
|
||||
## 04/13/2021
|
||||
|
||||
1. [](#new)
|
||||
* Added configuration options to allow PHP methods to be used in Twig functions (`system.twig.safe_functions`) and filters (`system.twig.safe_filters`)
|
||||
* Deprecated using PHP methods in Twig without them being in the safe lists
|
||||
* Prevent dangerous PHP methods from being used as Twig functions and filters
|
||||
* Restrict filesystem Twig functions to accept only local filesystem and grav streams
|
||||
1. [](#improved)
|
||||
* Better GPM detection of unauthorized installations
|
||||
1. [](#bugfix)
|
||||
* **IMPORTANT** Fixed security vulnerability with Twig allowing dangerous PHP functions by default [GHSA-g8r4-p96j-xfxc](https://github.com/getgrav/grav/security/advisories/GHSA-g8r4-p96j-xfxc)
|
||||
* Fixed nxinx appending repeating `?_url=` in some redirects
|
||||
* Fixed deleting page with language code not removing the folder if it was the last language [#3305](https://github.com/getgrav/grav/issues/3305)
|
||||
* Fixed fatal error when using markdown links with `image://` stream [#3285](https://github.com/getgrav/grav/issues/3285)
|
||||
* Fixed `system.languages.session_store_active` not having any effect [#3269](https://github.com/getgrav/grav/issues/3269)
|
||||
* Fixed fatal error if `system.pages.types` is not an array [#2984](https://github.com/getgrav/grav/issues/2984)
|
||||
|
||||
# v1.7.10
|
||||
## 04/06/2021
|
||||
|
||||
|
||||
@@ -1,66 +1,150 @@
|
||||
#  Grav
|
||||
|
||||
#Installation site GIP EPAU
|
||||
[](https://github.com/phpstan/phpstan)
|
||||
[](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad)
|
||||
[](https://chat.getgrav.org)
|
||||
[](https://github.com/getgrav/grav/actions?query=workflow%3A%22PHP+Tests%22) [](#backers) [](#sponsors)
|
||||
|
||||
### intall grav avec composer
|
||||
Grav is a **Fast**, **Simple**, and **Flexible**, file-based Web-platform. There is **Zero** installation required. Just extract the ZIP archive, and you are already up and running. It follows similar principles to other flat-file CMS platforms, but has a different design philosophy than most. Grav comes with a powerful **Package Management System** to allow for simple installation and upgrading of plugins and themes, as well as simple updating of Grav itself.
|
||||
|
||||
The underlying architecture of Grav is designed to use well-established and _best-in-class_ technologies to ensure that Grav is simple to use and easy to extend. Some of these key technologies include:
|
||||
|
||||
* [Twig Templating](https://twig.sensiolabs.org/): for powerful control of the user interface
|
||||
* [Markdown](https://en.wikipedia.org/wiki/Markdown): for easy content creation
|
||||
* [YAML](https://yaml.org): for simple configuration
|
||||
* [Parsedown](https://parsedown.org/): for fast Markdown and Markdown Extra support
|
||||
* [Doctrine Cache](https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html): layer for performance
|
||||
* [Pimple Dependency Injection Container](https://pimple.sensiolabs.org/): for extensibility and maintainability
|
||||
* [Symfony Event Dispatcher](https://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling
|
||||
* [Symfony Console](https://symfony.com/doc/current/components/console/introduction.html): for CLI interface
|
||||
* [Gregwar Image Library](https://github.com/Gregwar/Image): for dynamic image manipulation
|
||||
|
||||
# Requirements
|
||||
|
||||
- PHP 7.3.6 or higher. Check the [required modules list](https://learn.getgrav.org/basics/requirements#php-requirements)
|
||||
- Check the [Apache](https://learn.getgrav.org/basics/requirements#apache-requirements) or [IIS](https://learn.getgrav.org/basics/requirements#iis-requirements) requirements
|
||||
|
||||
# Documentation
|
||||
|
||||
The full documentation can be found from [learn.getgrav.org](https://learn.getgrav.org).
|
||||
|
||||
# QuickStart
|
||||
|
||||
These are the options to get Grav:
|
||||
|
||||
### Downloading a Grav Package
|
||||
|
||||
You can download a **ready-built** package from the [Downloads page on https://getgrav.org](https://getgrav.org/downloads)
|
||||
|
||||
### With Composer
|
||||
|
||||
You can create a new project with the latest **stable** Grav release with the following command:
|
||||
|
||||
```
|
||||
composer create-project getgrav/grav ~/webroot/grav
|
||||
$ composer create-project getgrav/grav ~/webroot/grav
|
||||
```
|
||||
|
||||
### From GitHub
|
||||
|
||||
1. Clone the Grav repository from [https://github.com/getgrav/grav]() to a folder in the webroot of your server, e.g. `~/webroot/grav`. Launch a **terminal** or **console** and navigate to the webroot folder:
|
||||
```
|
||||
$ cd ~/webroot
|
||||
$ git clone https://github.com/getgrav/grav.git
|
||||
```
|
||||
|
||||
#### installer version admin
|
||||
2. Install the **plugin** and **theme dependencies** by using the [Grav CLI application](https://learn.getgrav.org/advanced/grav-cli) `bin/grav`:
|
||||
```
|
||||
$ cd ~/webroot/grav
|
||||
$ bin/grav install
|
||||
```
|
||||
|
||||
mise à jours
|
||||
```
|
||||
cd ~/webroot/nomdusite
|
||||
bin/gpm selfupgrade
|
||||
```
|
||||
installe l’admin
|
||||
```
|
||||
bin/gpm install admin
|
||||
```
|
||||
créer un nouvel utilisateur
|
||||
```
|
||||
bin/plugin login newuser
|
||||
```
|
||||
Check out the [install procedures](https://learn.getgrav.org/basics/installation) for more information.
|
||||
|
||||
#### installe devtools et créer nouveau theme
|
||||
# Adding Functionality
|
||||
|
||||
You can download [plugins](https://getgrav.org/downloads/plugins) or [themes](https://getgrav.org/downloads/themes) manually from the appropriate tab on the [Downloads page on https://getgrav.org](https://getgrav.org/downloads), but the preferred solution is to use the [Grav Package Manager](https://learn.getgrav.org/advanced/grav-gpm) or `GPM`:
|
||||
|
||||
```
|
||||
bin/gpm install devtools
|
||||
|
||||
bin/plugin devtools new-theme
|
||||
$ bin/gpm index
|
||||
```
|
||||
|
||||
|
||||
# Dans le navigateur
|
||||
|
||||
aller sur http://localhost:8000/
|
||||
pour voir le site
|
||||
|
||||
aller sur http://localhost:8000/admin
|
||||
pour accéder au back office
|
||||
|
||||
|
||||
|
||||
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
||||
|
||||
|
||||
|
||||
# Compilé les SCSS
|
||||
This will display all the available plugins and then you can install one or more with:
|
||||
|
||||
```
|
||||
$ cd chemin/du/dossier/dev-epau.archi.fr
|
||||
$ bin/gpm install <plugin/theme>
|
||||
```
|
||||
```
|
||||
$ npm install
|
||||
```
|
||||
(uniquement la première fois)
|
||||
|
||||
puis à chaque fois, dans une 2e fenêtre de Terminal, qui doit également restée ouverte:
|
||||
# Updating
|
||||
|
||||
To update Grav you should use the [Grav Package Manager](https://learn.getgrav.org/advanced/grav-gpm) or `GPM`:
|
||||
|
||||
```
|
||||
$ cd chemin/du/dossier/dev-epau.archi.fr/user/theme/epau-antimatter
|
||||
$ npm run sass
|
||||
$ bin/gpm selfupgrade
|
||||
```
|
||||
|
||||
To update plugins and themes:
|
||||
|
||||
```
|
||||
$ bin/gpm update
|
||||
```
|
||||
|
||||
## Upgrading from older version
|
||||
|
||||
* [Upgrading to Grav 1.7](https://learn.getgrav.org/16/advanced/grav-development/grav-17-upgrade-guide)
|
||||
* [Upgrading to Grav 1.6](https://learn.getgrav.org/16/advanced/grav-development/grav-16-upgrade-guide)
|
||||
* [Upgrading from Grav <1.6](https://learn.getgrav.org/16/advanced/grav-development/grav-15-upgrade-guide)
|
||||
|
||||
# Contributing
|
||||
We appreciate any contribution to Grav, whether it is related to bugs, grammar, or simply a suggestion or improvement! Please refer to the [Contributing guide](CONTRIBUTING.md) for more guidance on this topic.
|
||||
|
||||
## Security issues
|
||||
If you discover a possible security issue related to Grav or one of its plugins, please email the core team at contact@getgrav.org and we'll address it as soon as possible.
|
||||
|
||||
# Getting Started
|
||||
|
||||
* [What is Grav?](https://learn.getgrav.org/basics/what-is-grav)
|
||||
* [Install](https://learn.getgrav.org/basics/installation) Grav in few seconds
|
||||
* Understand the [Configuration](https://learn.getgrav.org/basics/grav-configuration)
|
||||
* Take a peek at our available free [Skeletons](https://getgrav.org/downloads/skeletons)
|
||||
* If you have questions, jump on our [Discord Chat Server](https://chat.getgrav.org)!
|
||||
* Have fun!
|
||||
|
||||
# Exploring More
|
||||
|
||||
* Have a look at our [Basic Tutorial](https://learn.getgrav.org/basics/basic-tutorial)
|
||||
* Dive into more [advanced](https://learn.getgrav.org/advanced) functions
|
||||
* Learn about the [Grav CLI](https://learn.getgrav.org/cli-console/grav-cli)
|
||||
* Review examples in the [Grav Cookbook](https://learn.getgrav.org/cookbook)
|
||||
* More [Awesome Grav Stuff](https://github.com/getgrav/awesome-grav)
|
||||
|
||||
# Backers
|
||||
Support Grav with a monthly donation to help us continue development. [[Become a backer](https://opencollective.com/grav#backer)]
|
||||
|
||||
<img src="https://opencollective.com/grav/tiers/backers.svg?avatarHeight=36&width=600" />
|
||||
|
||||
# Sponsors
|
||||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/grav#sponsor)]
|
||||
|
||||
<img src="https://opencollective.com/grav/tiers/sponsors.svg?avatarHeight=36&width=600" />
|
||||
|
||||
# License
|
||||
|
||||
See [LICENSE](LICENSE.txt)
|
||||
|
||||
|
||||
[gitflow-model]: http://nvie.com/posts/a-successful-git-branching-model/
|
||||
[gitflow-extensions]: https://github.com/nvie/gitflow
|
||||
|
||||
# Running Tests
|
||||
|
||||
First install the dev dependencies by running `composer install` from the Grav root.
|
||||
|
||||
Then `composer test` will run the Unit Tests, which should be always executed successfully on any site.
|
||||
Windows users should use the `composer test-windows` command.
|
||||
You can also run a single unit test file, e.g. `composer test tests/unit/Grav/Common/AssetsTest.php`
|
||||
|
||||
To run phpstan tests, you should run:
|
||||
|
||||
* `composer phpstan` for global tests
|
||||
* `composer phpstan-framework` for more strict tests
|
||||
* `composer phpstan-plugins` to test all installed plugins
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
"filp/whoops": "~2.9",
|
||||
"matthiasmullie/minify": "^1.3",
|
||||
"monolog/monolog": "~1.25",
|
||||
"gregwar/image": "dev-php8",
|
||||
"gregwar/cache": "dev-php8",
|
||||
"getgrav/image": "^3.0",
|
||||
"getgrav/cache": "^2.0",
|
||||
"donatj/phpuseragentparser": "~1.1",
|
||||
"pimple/pimple": "~3.3.0",
|
||||
"rockettheme/toolbox": "~1.5",
|
||||
@@ -67,7 +67,7 @@
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpstan/phpstan-deprecation-rules": "^0.12",
|
||||
"phpunit/php-code-coverage": "~9.2",
|
||||
"victorjonsson/markdowndocs": "dev-master",
|
||||
"getgrav/markdowndocs": "^2.0",
|
||||
"codeception/module-asserts": "^1.3",
|
||||
"codeception/module-phpbrowser": "^1.0",
|
||||
"symfony/service-contracts": "*"
|
||||
@@ -91,20 +91,6 @@
|
||||
"php": "7.3.6"
|
||||
}
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/trilbymedia/PHP-Markdown-Documentation-Generator"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/getgrav/Cache"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/getgrav/Image"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Grav\\": "system/src/Grav"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "4ae6fc7274c018b1bb34bb1b80bd62c5",
|
||||
"content-hash": "36375d8a5daf3aef0341f9a2b023f4e9",
|
||||
"packages": [
|
||||
{
|
||||
"name": "antoligy/dom-string-iterators",
|
||||
@@ -212,40 +212,39 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/cache",
|
||||
"version": "1.10.2",
|
||||
"version": "1.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/cache.git",
|
||||
"reference": "13e3381b25847283a91948d04640543941309727"
|
||||
"reference": "a9c1b59eba5a08ca2770a76eddb88922f504e8e0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/cache/zipball/13e3381b25847283a91948d04640543941309727",
|
||||
"reference": "13e3381b25847283a91948d04640543941309727",
|
||||
"url": "https://api.github.com/repos/doctrine/cache/zipball/a9c1b59eba5a08ca2770a76eddb88922f504e8e0",
|
||||
"reference": "a9c1b59eba5a08ca2770a76eddb88922f504e8e0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "~7.1 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/common": ">2.2,<2.4"
|
||||
"doctrine/common": ">2.2,<2.4",
|
||||
"psr/cache": ">=3"
|
||||
},
|
||||
"require-dev": {
|
||||
"alcaeus/mongo-php-adapter": "^1.1",
|
||||
"doctrine/coding-standard": "^6.0",
|
||||
"cache/integration-tests": "dev-master",
|
||||
"doctrine/coding-standard": "^8.0",
|
||||
"mongodb/mongodb": "^1.1",
|
||||
"phpunit/phpunit": "^7.0",
|
||||
"predis/predis": "~1.0"
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||
"predis/predis": "~1.0",
|
||||
"psr/cache": "^1.0 || ^2.0",
|
||||
"symfony/cache": "^4.4 || ^5.2"
|
||||
},
|
||||
"suggest": {
|
||||
"alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
|
||||
@@ -292,7 +291,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/cache/issues",
|
||||
"source": "https://github.com/doctrine/cache/tree/1.10.x"
|
||||
"source": "https://github.com/doctrine/cache/tree/1.11.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -308,7 +307,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-07-07T18:54:01+00:00"
|
||||
"time": "2021-04-13T14:46:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/collections",
|
||||
@@ -642,16 +641,16 @@
|
||||
},
|
||||
{
|
||||
"name": "filp/whoops",
|
||||
"version": "2.12.0",
|
||||
"version": "2.12.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/filp/whoops.git",
|
||||
"reference": "d501fd2658d55491a2295ff600ae5978eaad7403"
|
||||
"reference": "c13c0be93cff50f88bbd70827d993026821914dd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/d501fd2658d55491a2295ff600ae5978eaad7403",
|
||||
"reference": "d501fd2658d55491a2295ff600ae5978eaad7403",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/c13c0be93cff50f88bbd70827d993026821914dd",
|
||||
"reference": "c13c0be93cff50f88bbd70827d993026821914dd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -701,7 +700,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/filp/whoops/issues",
|
||||
"source": "https://github.com/filp/whoops/tree/2.12.0"
|
||||
"source": "https://github.com/filp/whoops/tree/2.12.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -709,21 +708,21 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-03-30T12:00:00+00:00"
|
||||
"time": "2021-04-25T12:00:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "gregwar/cache",
|
||||
"version": "dev-php8",
|
||||
"name": "getgrav/cache",
|
||||
"version": "v2.0.0",
|
||||
"target-dir": "Gregwar/Cache",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/getgrav/Cache.git",
|
||||
"reference": "49ccdf9ae760b009a192bc3c7b417980c8a8cc2e"
|
||||
"reference": "56fd63f752779928fcd1074ab7d12f406dde8861"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/getgrav/Cache/zipball/49ccdf9ae760b009a192bc3c7b417980c8a8cc2e",
|
||||
"reference": "49ccdf9ae760b009a192bc3c7b417980c8a8cc2e",
|
||||
"url": "https://api.github.com/repos/getgrav/Cache/zipball/56fd63f752779928fcd1074ab7d12f406dde8861",
|
||||
"reference": "56fd63f752779928fcd1074ab7d12f406dde8861",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -735,6 +734,7 @@
|
||||
"Gregwar\\Cache": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
@@ -742,6 +742,11 @@
|
||||
{
|
||||
"name": "Gregwar",
|
||||
"email": "g.passault@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Grav CMS",
|
||||
"email": "hello@getgrav.org",
|
||||
"homepage": "https://getgrav.org"
|
||||
}
|
||||
],
|
||||
"description": "A lightweight file-system cache system",
|
||||
@@ -752,28 +757,28 @@
|
||||
"system"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/getgrav/Cache/tree/php8"
|
||||
"source": "https://github.com/getgrav/Cache/tree/v2.0.0"
|
||||
},
|
||||
"time": "2020-12-02T10:54:35+00:00"
|
||||
"time": "2021-04-20T05:48:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "gregwar/image",
|
||||
"version": "dev-php8",
|
||||
"name": "getgrav/image",
|
||||
"version": "v3.0.0",
|
||||
"target-dir": "Gregwar/Image",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/getgrav/Image.git",
|
||||
"reference": "ea23859700f32447a85e79d96f331e3d6c8897a8"
|
||||
"reference": "02c1bb2c179dd894c4f6610c9c49da364ee7d264"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/getgrav/Image/zipball/ea23859700f32447a85e79d96f331e3d6c8897a8",
|
||||
"reference": "ea23859700f32447a85e79d96f331e3d6c8897a8",
|
||||
"url": "https://api.github.com/repos/getgrav/Image/zipball/02c1bb2c179dd894c4f6610c9c49da364ee7d264",
|
||||
"reference": "02c1bb2c179dd894c4f6610c9c49da364ee7d264",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-gd": "*",
|
||||
"gregwar/cache": "dev-php8",
|
||||
"getgrav/cache": "^2.0",
|
||||
"php": "^5.6 || ^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
@@ -789,6 +794,7 @@
|
||||
"Gregwar\\Image": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
@@ -797,6 +803,11 @@
|
||||
"name": "Grégoire Passault",
|
||||
"email": "g.passault@gmail.com",
|
||||
"homepage": "http://www.gregwar.com/"
|
||||
},
|
||||
{
|
||||
"name": "Grav CMS",
|
||||
"email": "hello@getgrav.org",
|
||||
"homepage": "https://getgrav.org"
|
||||
}
|
||||
],
|
||||
"description": "Image handling",
|
||||
@@ -806,9 +817,9 @@
|
||||
"image"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/getgrav/Image/tree/php8"
|
||||
"source": "https://github.com/getgrav/Image/tree/v3.0.0"
|
||||
},
|
||||
"time": "2021-03-15T17:03:52+00:00"
|
||||
"time": "2021-04-20T05:50:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
@@ -2135,16 +2146,16 @@
|
||||
},
|
||||
{
|
||||
"name": "rockettheme/toolbox",
|
||||
"version": "1.5.7",
|
||||
"version": "1.5.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/rockettheme/toolbox.git",
|
||||
"reference": "8d3ebc4d982595d6eac90e851f2b4d5c0cec0399"
|
||||
"reference": "2d6693235aaca2efaadb61c84dac927aaf4eabfa"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/rockettheme/toolbox/zipball/8d3ebc4d982595d6eac90e851f2b4d5c0cec0399",
|
||||
"reference": "8d3ebc4d982595d6eac90e851f2b4d5c0cec0399",
|
||||
"url": "https://api.github.com/repos/rockettheme/toolbox/zipball/2d6693235aaca2efaadb61c84dac927aaf4eabfa",
|
||||
"reference": "2d6693235aaca2efaadb61c84dac927aaf4eabfa",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2185,9 +2196,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/rockettheme/toolbox/issues",
|
||||
"source": "https://github.com/rockettheme/toolbox/tree/1.5.7"
|
||||
"source": "https://github.com/rockettheme/toolbox/tree/1.5.9"
|
||||
},
|
||||
"time": "2021-02-17T17:58:36+00:00"
|
||||
"time": "2021-04-14T19:52:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "seld/cli-prompt",
|
||||
@@ -3415,16 +3426,16 @@
|
||||
},
|
||||
{
|
||||
"name": "codeception/codeception",
|
||||
"version": "4.1.19",
|
||||
"version": "4.1.20",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Codeception/Codeception.git",
|
||||
"reference": "138dc9345a81ec994dcd6b9680c501a752a37b00"
|
||||
"reference": "d8b16e13e1781dbc3a7ae8292117d520c89a9c5a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/138dc9345a81ec994dcd6b9680c501a752a37b00",
|
||||
"reference": "138dc9345a81ec994dcd6b9680c501a752a37b00",
|
||||
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/d8b16e13e1781dbc3a7ae8292117d520c89a9c5a",
|
||||
"reference": "d8b16e13e1781dbc3a7ae8292117d520c89a9c5a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3498,7 +3509,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Codeception/Codeception/issues",
|
||||
"source": "https://github.com/Codeception/Codeception/tree/4.1.19"
|
||||
"source": "https://github.com/Codeception/Codeception/tree/4.1.20"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -3506,7 +3517,7 @@
|
||||
"type": "open_collective"
|
||||
}
|
||||
],
|
||||
"time": "2021-03-28T13:26:08+00:00"
|
||||
"time": "2021-04-02T16:41:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "codeception/lib-asserts",
|
||||
@@ -3564,16 +3575,16 @@
|
||||
},
|
||||
{
|
||||
"name": "codeception/lib-innerbrowser",
|
||||
"version": "1.4.1",
|
||||
"version": "1.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Codeception/lib-innerbrowser.git",
|
||||
"reference": "693e116f81ef98eae98c43ef785a726faf87394e"
|
||||
"reference": "4b0d89b37fe454e060a610a85280a87ab4f534f1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Codeception/lib-innerbrowser/zipball/693e116f81ef98eae98c43ef785a726faf87394e",
|
||||
"reference": "693e116f81ef98eae98c43ef785a726faf87394e",
|
||||
"url": "https://api.github.com/repos/Codeception/lib-innerbrowser/zipball/4b0d89b37fe454e060a610a85280a87ab4f534f1",
|
||||
"reference": "4b0d89b37fe454e060a610a85280a87ab4f534f1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3618,9 +3629,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Codeception/lib-innerbrowser/issues",
|
||||
"source": "https://github.com/Codeception/lib-innerbrowser/tree/1.4.1"
|
||||
"source": "https://github.com/Codeception/lib-innerbrowser/tree/1.5.0"
|
||||
},
|
||||
"time": "2021-03-02T08:01:54+00:00"
|
||||
"time": "2021-04-23T06:18:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "codeception/module-asserts",
|
||||
@@ -3891,6 +3902,58 @@
|
||||
],
|
||||
"time": "2020-11-10T18:47:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "getgrav/markdowndocs",
|
||||
"version": "2.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/getgrav/PHP-Markdown-Documentation-Generator.git",
|
||||
"reference": "4a24d1b64a88da17e8f1696dc64969f5ca769064"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/getgrav/PHP-Markdown-Documentation-Generator/zipball/4a24d1b64a88da17e8f1696dc64969f5ca769064",
|
||||
"reference": "4a24d1b64a88da17e8f1696dc64969f5ca769064",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5.0",
|
||||
"symfony/console": ">=2.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "3.7.23"
|
||||
},
|
||||
"bin": [
|
||||
"bin/phpdoc-md"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"PHPDocsMD": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Victor Jonsson",
|
||||
"email": "kontakt@victorjonsson.se"
|
||||
},
|
||||
{
|
||||
"name": "Grav CMS",
|
||||
"email": "hello@getgrav.org",
|
||||
"homepage": "https://getgrav.org"
|
||||
}
|
||||
],
|
||||
"description": "Command line tool for generating markdown-formatted class documentation",
|
||||
"homepage": "https://github.com/victorjonsson/PHP-Markdown-Documentation-Generator",
|
||||
"support": {
|
||||
"source": "https://github.com/getgrav/PHP-Markdown-Documentation-Generator/tree/2.0.1"
|
||||
},
|
||||
"time": "2021-04-20T06:04:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "7.3.0",
|
||||
@@ -4501,16 +4564,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "0.12.82",
|
||||
"version": "0.12.84",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "3920f0fb0aff39263d3a4cb0bca120a67a1a6a11"
|
||||
"reference": "9c43f15da8798c8f30a4b099e6a94530a558cfd5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/3920f0fb0aff39263d3a4cb0bca120a67a1a6a11",
|
||||
"reference": "3920f0fb0aff39263d3a4cb0bca120a67a1a6a11",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/9c43f15da8798c8f30a4b099e6a94530a558cfd5",
|
||||
"reference": "9c43f15da8798c8f30a4b099e6a94530a558cfd5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4541,7 +4604,7 @@
|
||||
"description": "PHPStan - PHP Static Analysis Tool",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpstan/issues",
|
||||
"source": "https://github.com/phpstan/phpstan/tree/0.12.82"
|
||||
"source": "https://github.com/phpstan/phpstan/tree/0.12.84"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4557,7 +4620,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-03-19T06:08:17+00:00"
|
||||
"time": "2021-04-19T17:10:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-deprecation-rules",
|
||||
@@ -6368,53 +6431,6 @@
|
||||
],
|
||||
"time": "2020-07-12T23:59:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "victorjonsson/markdowndocs",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/trilbymedia/PHP-Markdown-Documentation-Generator.git",
|
||||
"reference": "c9fa153b28a79f5da89ec32aa501be92db212aed"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/trilbymedia/PHP-Markdown-Documentation-Generator/zipball/c9fa153b28a79f5da89ec32aa501be92db212aed",
|
||||
"reference": "c9fa153b28a79f5da89ec32aa501be92db212aed",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5.0",
|
||||
"symfony/console": ">=2.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "3.7.23"
|
||||
},
|
||||
"default-branch": true,
|
||||
"bin": [
|
||||
"bin/phpdoc-md"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"PHPDocsMD": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Victor Jonsson",
|
||||
"email": "kontakt@victorjonsson.se"
|
||||
}
|
||||
],
|
||||
"description": "Command line tool for generating markdown-formatted class documentation",
|
||||
"homepage": "https://github.com/victorjonsson/PHP-Markdown-Documentation-Generator",
|
||||
"support": {
|
||||
"source": "https://github.com/trilbymedia/PHP-Markdown-Documentation-Generator/tree/master"
|
||||
},
|
||||
"time": "2017-09-20T13:29:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.10.0",
|
||||
@@ -6476,11 +6492,7 @@
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"gregwar/image": 20,
|
||||
"gregwar/cache": 20,
|
||||
"victorjonsson/markdowndocs": 20
|
||||
},
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
||||
@@ -18,6 +18,7 @@ config:
|
||||
configure:
|
||||
path: '/accounts/configure'
|
||||
redirects:
|
||||
'/groups': '/accounts/groups'
|
||||
'/accounts': '/accounts/groups'
|
||||
|
||||
# Permissions
|
||||
|
||||
@@ -121,7 +121,7 @@ form:
|
||||
underline: true
|
||||
|
||||
folder:
|
||||
type: text
|
||||
type: folder-slug
|
||||
label: PLUGIN_ADMIN.FOLDER_NAME
|
||||
validate:
|
||||
rule: slug
|
||||
|
||||
@@ -113,6 +113,8 @@ twig:
|
||||
autoescape: true # Autoescape Twig vars (DEPRECATED, always enabled in strict mode)
|
||||
undefined_functions: true # Allow undefined functions
|
||||
undefined_filters: true # Allow undefined filters
|
||||
safe_functions: [] # List of PHP functions which are allowed to be used as Twig functions
|
||||
safe_filters: [] # List of PHP functions which are allowed to be used as Twig filters
|
||||
umask_fix: false # By default Twig creates cached files as 755, fix switches this to 775
|
||||
|
||||
assets: # Configuration for Assets Manager (JS, CSS)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav\Core
|
||||
*
|
||||
@@ -8,7 +9,7 @@
|
||||
|
||||
// Some standard defines
|
||||
define('GRAV', true);
|
||||
define('GRAV_VERSION', '1.7.10');
|
||||
define('GRAV_VERSION', '1.7.14');
|
||||
define('GRAV_SCHEMA', '1.7.0_2020-11-20_1');
|
||||
define('GRAV_TESTING', false);
|
||||
|
||||
@@ -22,58 +23,68 @@ if (!defined('DS')) {
|
||||
define('DS', '/');
|
||||
}
|
||||
|
||||
// Directories and Paths
|
||||
// Absolute path to Grav root. This is where Grav is installed into.
|
||||
if (!defined('GRAV_ROOT')) {
|
||||
$path = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, getenv('GRAV_ROOT') ?: getcwd()), DS);
|
||||
define('GRAV_ROOT', $path);
|
||||
}
|
||||
// Absolute path to Grav webroot. This is the path where your site is located in.
|
||||
if (!defined('GRAV_WEBROOT')) {
|
||||
define('GRAV_WEBROOT', GRAV_ROOT);
|
||||
$path = rtrim(getenv('GRAV_WEBROOT') ?: GRAV_ROOT, DS);
|
||||
define('GRAV_WEBROOT', $path);
|
||||
}
|
||||
// Relative path to user folder. This path needs to be located under GRAV_WEBROOT.
|
||||
if (!defined('GRAV_USER_PATH')) {
|
||||
$path = rtrim(getenv('GRAV_USER_PATH') ?: 'user', DS);
|
||||
define('GRAV_USER_PATH', $path);
|
||||
}
|
||||
// Absolute or relative path to system folder. Defaults to GRAV_ROOT/system
|
||||
// If system folder is outside of webroot, see https://github.com/getgrav/grav/issues/3297#issuecomment-810294972
|
||||
if (!defined('GRAV_SYSTEM_PATH')) {
|
||||
$path = rtrim(getenv('GRAV_SYSTEM_PATH') ?: 'system', DS);
|
||||
define('GRAV_SYSTEM_PATH', $path);
|
||||
}
|
||||
// Absolute or relative path to cache folder. Defaults to GRAV_ROOT/cache
|
||||
if (!defined('GRAV_CACHE_PATH')) {
|
||||
$path = rtrim(getenv('GRAV_CACHE_PATH') ?: 'cache', DS);
|
||||
define('GRAV_CACHE_PATH', $path);
|
||||
}
|
||||
// Absolute or relative path to logs folder. Defaults to GRAV_ROOT/logs
|
||||
if (!defined('GRAV_LOG_PATH')) {
|
||||
$path = rtrim(getenv('GRAV_LOG_PATH') ?: 'logs', DS);
|
||||
define('GRAV_LOG_PATH', $path);
|
||||
}
|
||||
// Absolute or relative path to tmp folder. Defaults to GRAV_ROOT/tmp
|
||||
if (!defined('GRAV_TMP_PATH')) {
|
||||
$path = rtrim(getenv('GRAV_TMP_PATH') ?: 'tmp', DS);
|
||||
define('GRAV_TMP_PATH', $path);
|
||||
}
|
||||
// Absolute or relative path to backup folder. Defaults to GRAV_ROOT/backup
|
||||
if (!defined('GRAV_BACKUP_PATH')) {
|
||||
$path = rtrim(getenv('GRAV_BACKUP_PATH') ?: 'backup', DS);
|
||||
define('GRAV_BACKUP_PATH', $path);
|
||||
}
|
||||
unset($path);
|
||||
|
||||
define('USER_PATH', GRAV_USER_PATH . DS);
|
||||
define('CACHE_PATH', GRAV_CACHE_PATH . DS);
|
||||
define('ROOT_DIR', GRAV_ROOT . DS);
|
||||
define('USER_DIR', (!str_starts_with(USER_PATH, '/') ? GRAV_WEBROOT . '/' : '') . USER_PATH);
|
||||
define('CACHE_DIR', (!str_starts_with(CACHE_PATH, '/') ? ROOT_DIR : '') . CACHE_PATH);
|
||||
// INTERNAL: Do not use!
|
||||
define('USER_DIR', GRAV_WEBROOT . '/' . GRAV_USER_PATH . '/');
|
||||
define('CACHE_DIR', (!preg_match('`^(/|[a-z]:[\\\/])`ui', GRAV_CACHE_PATH) ? GRAV_ROOT . '/' : '') . GRAV_CACHE_PATH . '/');
|
||||
|
||||
// DEPRECATED: Do not use!
|
||||
define('CACHE_PATH', GRAV_CACHE_PATH . DS);
|
||||
define('USER_PATH', GRAV_USER_PATH . DS);
|
||||
define('ROOT_DIR', GRAV_ROOT . DS);
|
||||
define('ASSETS_DIR', GRAV_WEBROOT . '/assets/');
|
||||
define('IMAGES_DIR', GRAV_WEBROOT . '/images/');
|
||||
define('ACCOUNTS_DIR', USER_DIR .'accounts/');
|
||||
define('PAGES_DIR', USER_DIR .'pages/');
|
||||
define('DATA_DIR', USER_DIR .'data/');
|
||||
define('PLUGINS_DIR', USER_DIR .'plugins/');
|
||||
define('THEMES_DIR', USER_DIR .'themes/');
|
||||
define('SYSTEM_DIR', (!str_starts_with(GRAV_SYSTEM_PATH, '/') ? ROOT_DIR : '') . GRAV_SYSTEM_PATH);
|
||||
define('LIB_DIR', SYSTEM_DIR .'src/');
|
||||
define('VENDOR_DIR', ROOT_DIR .'vendor/');
|
||||
define('LOG_DIR', (!str_starts_with(GRAV_LOG_PATH, '/') ? ROOT_DIR : '') . GRAV_LOG_PATH . DS);
|
||||
define('ACCOUNTS_DIR', USER_DIR . 'accounts/');
|
||||
define('PAGES_DIR', USER_DIR . 'pages/');
|
||||
define('DATA_DIR', USER_DIR . 'data/');
|
||||
define('PLUGINS_DIR', USER_DIR . 'plugins/');
|
||||
define('THEMES_DIR', USER_DIR . 'themes/');
|
||||
define('SYSTEM_DIR', (!preg_match('`^(/|[a-z]:[\\\/])`ui', GRAV_SYSTEM_PATH) ? GRAV_ROOT . '/' : '') . GRAV_SYSTEM_PATH . '/');
|
||||
define('LIB_DIR', SYSTEM_DIR . 'src/');
|
||||
define('VENDOR_DIR', GRAV_ROOT . '/vendor/');
|
||||
define('LOG_DIR', (!preg_match('`^(/|[a-z]:[\\\/])`ui', GRAV_LOG_PATH) ? GRAV_ROOT . '/' : '') . GRAV_LOG_PATH . '/');
|
||||
// END DEPRECATED
|
||||
|
||||
// Some extensions
|
||||
|
||||
@@ -90,7 +90,7 @@ trait AssetUtilsTrait
|
||||
}
|
||||
|
||||
$relative_dir = dirname($relative_path);
|
||||
$link = ROOT_DIR . $relative_path;
|
||||
$link = GRAV_ROOT . '/' . $relative_path;
|
||||
}
|
||||
|
||||
// TODO: looks like this is not being used.
|
||||
|
||||
@@ -252,7 +252,7 @@ trait TestingAssetsTrait
|
||||
*/
|
||||
public function addDir($directory, $pattern = self::DEFAULT_REGEX)
|
||||
{
|
||||
$root_dir = rtrim(ROOT_DIR, '/');
|
||||
$root_dir = GRAV_ROOT;
|
||||
|
||||
// Check if $directory is a stream.
|
||||
if (strpos($directory, '://')) {
|
||||
|
||||
@@ -238,6 +238,7 @@ class Validation
|
||||
$value = trim($value);
|
||||
}
|
||||
|
||||
$value = preg_replace("/\r\n|\r/um", "\n", $value);
|
||||
$len = mb_strlen($value);
|
||||
|
||||
$min = (int)($params['min'] ?? 0);
|
||||
@@ -280,7 +281,7 @@ class Validation
|
||||
$value = trim($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
return preg_replace("/\r\n|\r/um", "\n", $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -746,6 +746,16 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa
|
||||
return $bool ? $this->select($list) : $this->unselect($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $languageCode
|
||||
* @param bool|null $fallback
|
||||
* @return PageIndex
|
||||
*/
|
||||
public function withTranslated(string $languageCode = null, bool $fallback = null)
|
||||
{
|
||||
return $this->getIndex()->withTranslated($languageCode, $fallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter pages by given filters.
|
||||
*
|
||||
|
||||
@@ -18,6 +18,7 @@ use Grav\Common\File\CompiledYamlFile;
|
||||
use Grav\Common\Flex\Traits\FlexGravTrait;
|
||||
use Grav\Common\Flex\Traits\FlexIndexTrait;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Language\Language;
|
||||
use Grav\Common\Page\Header;
|
||||
use Grav\Common\Page\Interfaces\PageCollectionInterface;
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
@@ -164,6 +165,31 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
|
||||
return $root;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $languageCode
|
||||
* @param bool|null $fallback
|
||||
* @return PageIndex
|
||||
*/
|
||||
public function withTranslated(string $languageCode = null, bool $fallback = null)
|
||||
{
|
||||
if (null === $languageCode) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$entries = $this->translateEntries($this->getEntries(), $languageCode, $fallback);
|
||||
$params = ['language' => $languageCode, 'language_fallback' => $fallback] + $this->getParams();
|
||||
|
||||
return $this->createFrom($entries)->setParams($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getLanguage(): ?string
|
||||
{
|
||||
return $this->_params['language'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the collection params
|
||||
*
|
||||
@@ -174,6 +200,17 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
|
||||
return $this->_params ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the collection param
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function getParam(string $name)
|
||||
{
|
||||
return $this->_params[$name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parameters to the Collection
|
||||
*
|
||||
@@ -187,6 +224,20 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a parameter to the Collection
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setParam(string $name, $value)
|
||||
{
|
||||
$this->_params[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the collection params
|
||||
*
|
||||
@@ -197,6 +248,15 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
|
||||
return $this->getParams();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getCacheKey()
|
||||
*/
|
||||
public function getCacheKey(): string
|
||||
{
|
||||
return $this->getTypePrefix() . $this->getFlexType() . '.' . sha1(json_encode($this->getKeys()) . $this->getKeyField() . $this->getLanguage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter pages by given filters.
|
||||
*
|
||||
@@ -345,6 +405,96 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
|
||||
return $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $entries
|
||||
* @param string $lang
|
||||
* @param bool|null $fallback
|
||||
* @return array
|
||||
*/
|
||||
protected function translateEntries(array $entries, string $lang, bool $fallback = null): array
|
||||
{
|
||||
$languages = $this->getFallbackLanguages($lang, $fallback);
|
||||
foreach ($entries as $key => &$entry) {
|
||||
// Find out which version of the page we should load.
|
||||
$translations = $this->getLanguageTemplates((string)$key);
|
||||
if (!$translations) {
|
||||
// No translations found, is this a folder?
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find a translation.
|
||||
$template = null;
|
||||
foreach ($languages as $code) {
|
||||
if (isset($translations[$code])) {
|
||||
$template = $translations[$code];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We couldn't find a translation, remove entry from the list.
|
||||
if (!isset($code, $template)) {
|
||||
unset($entries['key']);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the main key without template and langauge.
|
||||
[$main_key,] = explode('|', $entry['storage_key'] . '|', 2);
|
||||
|
||||
// Update storage key and language.
|
||||
$entry['storage_key'] = $main_key . '|' . $template . '.' . $code;
|
||||
$entry['lang'] = $code;
|
||||
}
|
||||
unset($entry);
|
||||
|
||||
return $entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getLanguageTemplates(string $key): array
|
||||
{
|
||||
$meta = $this->getMetaData($key);
|
||||
$template = $meta['template'] ?? 'folder';
|
||||
$translations = $meta['markdown'] ?? [];
|
||||
$list = [];
|
||||
foreach ($translations as $code => $search) {
|
||||
if (isset($search[$template])) {
|
||||
// Use main template if possible.
|
||||
$list[$code] = $template;
|
||||
} elseif (!empty($search)) {
|
||||
// Fall back to first matching template.
|
||||
$list[$code] = key($search);
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $languageCode
|
||||
* @param bool|null $fallback
|
||||
* @return array
|
||||
*/
|
||||
protected function getFallbackLanguages(string $languageCode = null, bool $fallback = null): array
|
||||
{
|
||||
$fallback = $fallback ?? true;
|
||||
if (!$fallback && null !== $languageCode) {
|
||||
return [$languageCode];
|
||||
}
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var Language $language */
|
||||
$language = $grav['language'];
|
||||
$languageCode = $languageCode ?? '';
|
||||
if ($languageCode === '' && $fallback) {
|
||||
return $language->getFallbackLanguages(null, true);
|
||||
}
|
||||
|
||||
return $fallback ? $language->getFallbackLanguages($languageCode, true) : [$languageCode];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
* @return array
|
||||
|
||||
@@ -474,17 +474,28 @@ class PageStorage extends FolderStorage
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if page folder should be deleted.
|
||||
*
|
||||
* Deleting page can be done either by deleting everything or just a single language.
|
||||
* If key contains the language, delete only it, unless it is the last language.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
protected function canDeleteFolder(string $key): bool
|
||||
{
|
||||
// Return true if there's no language in the key.
|
||||
$keys = $this->extractKeysFromStorageKey($key);
|
||||
if ($keys['lang']) {
|
||||
return false;
|
||||
if (!$keys['lang']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
// Get the main key and reload meta.
|
||||
$key = $this->buildStorageKey($keys);
|
||||
$meta = $this->getObjectMeta($key, true);
|
||||
|
||||
// Return true if there aren't any markdown files left.
|
||||
return empty($meta['markdown'] ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,7 +22,6 @@ use Grav\Common\Grav;
|
||||
use Grav\Common\Media\Interfaces\MediaCollectionInterface;
|
||||
use Grav\Common\Media\Interfaces\MediaUploadInterface;
|
||||
use Grav\Common\Page\Media;
|
||||
use Grav\Common\Page\Medium\Medium;
|
||||
use Grav\Common\Page\Medium\MediumFactory;
|
||||
use Grav\Common\User\Access;
|
||||
use Grav\Common\User\Authentication;
|
||||
@@ -78,16 +77,12 @@ class UserObject extends FlexObject implements UserInterface, Countable
|
||||
|
||||
/** @var array|null */
|
||||
protected $_uploads_original;
|
||||
|
||||
/** @var FileInterface|null */
|
||||
protected $_storage;
|
||||
|
||||
/** @var UserGroupIndex */
|
||||
protected $_groups;
|
||||
|
||||
/** @var Access */
|
||||
protected $_access;
|
||||
|
||||
/** @var array|null */
|
||||
protected $access;
|
||||
|
||||
|
||||
@@ -527,7 +527,7 @@ class GPM extends Iterator
|
||||
$plugins = $this->getRepositoryPlugins();
|
||||
|
||||
if (null === $themes || null === $plugins) {
|
||||
if (!is_writable(ROOT_DIR . '/cache/gpm')) {
|
||||
if (!is_writable(GRAV_ROOT . '/cache/gpm')) {
|
||||
throw new RuntimeException('The cache/gpm folder is not writable. Please check the folder permissions.');
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +135,10 @@ class Installer
|
||||
}
|
||||
|
||||
if (!$options['sophisticated']) {
|
||||
if ($options['theme']) {
|
||||
$isTheme = $options['theme'] ?? false;
|
||||
// Make sure that themes are always being copied, even if option was not set!
|
||||
$isTheme = $isTheme || preg_match('|/themes/[^/]+|ui', $install_path);
|
||||
if ($isTheme) {
|
||||
self::copyInstall($extracted, $install_path);
|
||||
} else {
|
||||
self::moveInstall($extracted, $install_path);
|
||||
|
||||
@@ -71,15 +71,6 @@ trait MediaUploadTrait
|
||||
*/
|
||||
public function checkUploadedFile(UploadedFileInterface $uploadedFile, string $filename = null, array $settings = null): string
|
||||
{
|
||||
// Add the defaults to the settings.
|
||||
$settings = $this->getUploadSettings($settings);
|
||||
|
||||
// Destination is always needed (but it can be set in defaults).
|
||||
$self = $settings['self'] ?? false;
|
||||
if (!isset($settings['destination']) && $self === false) {
|
||||
throw new RuntimeException($this->translate('PLUGIN_ADMIN.DESTINATION_NOT_SPECIFIED'), 400);
|
||||
}
|
||||
|
||||
// Check if there is an upload error.
|
||||
switch ($uploadedFile->getError()) {
|
||||
case UPLOAD_ERR_OK:
|
||||
@@ -101,10 +92,38 @@ trait MediaUploadTrait
|
||||
throw new RuntimeException($this->translate('PLUGIN_ADMIN.UNKNOWN_ERRORS'), 400);
|
||||
}
|
||||
|
||||
$metadata = [
|
||||
'filename' => $uploadedFile->getClientFilename(),
|
||||
'mime' => $uploadedFile->getClientMediaType(),
|
||||
'size' => $uploadedFile->getSize(),
|
||||
];
|
||||
|
||||
return $this->checkFileMetadata($metadata, $filename, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that file metadata meets the requirements. Returns new filename.
|
||||
*
|
||||
* @param array $metadata
|
||||
* @param array|null $settings
|
||||
* @return string|null
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function checkFileMetadata(array $metadata, string $filename = null, array $settings = null): string
|
||||
{
|
||||
// Add the defaults to the settings.
|
||||
$settings = $this->getUploadSettings($settings);
|
||||
|
||||
// Destination is always needed (but it can be set in defaults).
|
||||
$self = $settings['self'] ?? false;
|
||||
if (!isset($settings['destination']) && $self === false) {
|
||||
throw new RuntimeException($this->translate('PLUGIN_ADMIN.DESTINATION_NOT_SPECIFIED'), 400);
|
||||
}
|
||||
|
||||
if (null === $filename) {
|
||||
// If no filename is given, use the filename from the uploaded file (path is not allowed).
|
||||
$folder = '';
|
||||
$filename = $uploadedFile->getClientFilename() ?? '';
|
||||
$filename = $metadata['filename'] ?? '';
|
||||
} else {
|
||||
// If caller sets the filename, we will accept any custom path.
|
||||
$folder = dirname($filename);
|
||||
@@ -128,7 +147,7 @@ trait MediaUploadTrait
|
||||
$filename = date('YmdHis') . '-' . $filename;
|
||||
}
|
||||
}
|
||||
$filepath = $folder !== '' ? $folder . $filename : $filename;
|
||||
$filepath = $folder . $filename;
|
||||
|
||||
// Check if the filename is allowed.
|
||||
if (!Utils::checkFilename($filename)) {
|
||||
@@ -148,14 +167,14 @@ trait MediaUploadTrait
|
||||
$filesize = $settings['filesize'];
|
||||
if ($filesize) {
|
||||
$max_filesize = $filesize * 1048576;
|
||||
if ($uploadedFile->getSize() > $max_filesize) {
|
||||
if ($metadata['size'] > $max_filesize) {
|
||||
// TODO: use own language string
|
||||
throw new RuntimeException($this->translate('PLUGIN_ADMIN.EXCEEDED_GRAV_FILESIZE_LIMIT'), 400);
|
||||
}
|
||||
} elseif (null === $filesize) {
|
||||
// Check size against the Grav upload limit.
|
||||
$grav_limit = Utils::getUploadLimit();
|
||||
if ($grav_limit > 0 && $uploadedFile->getSize() > $grav_limit) {
|
||||
if ($grav_limit > 0 && $metadata['size'] > $grav_limit) {
|
||||
throw new RuntimeException($this->translate('PLUGIN_ADMIN.EXCEEDED_GRAV_FILESIZE_LIMIT'), 400);
|
||||
}
|
||||
}
|
||||
@@ -165,6 +184,11 @@ trait MediaUploadTrait
|
||||
$errors = [];
|
||||
// Do not trust mime type sent by the browser.
|
||||
$mime = Utils::getMimeByFilename($filename);
|
||||
$mimeTest = $metadata['mime'] ?? $mime;
|
||||
if ($mime !== $mimeTest) {
|
||||
throw new RuntimeException('The mime type does not match to file extension', 400);
|
||||
}
|
||||
|
||||
foreach ((array)$settings['accept'] as $type) {
|
||||
// Force acceptance of any file when star notation
|
||||
if ($type === '*') {
|
||||
|
||||
@@ -95,8 +95,8 @@ class Excerpts
|
||||
*/
|
||||
public function processLinkExcerpt(array $excerpt, string $type = 'link'): array
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
$url = htmlspecialchars_decode(rawurldecode($excerpt['element']['attributes']['href']));
|
||||
|
||||
$url_parts = $this->parseUrl($url);
|
||||
|
||||
// If there is a query, then parse it and build action calls.
|
||||
@@ -114,7 +114,7 @@ class Excerpts
|
||||
);
|
||||
|
||||
// Valid attributes supported.
|
||||
$valid_attributes = Grav::instance()['config']->get('system.pages.markdown.valid_link_attributes');
|
||||
$valid_attributes = $grav['config']->get('system.pages.markdown.valid_link_attributes') ?? [];
|
||||
|
||||
$skip = [];
|
||||
// Unless told to not process, go through actions.
|
||||
@@ -155,9 +155,11 @@ class Excerpts
|
||||
// If scheme isn't http(s)..
|
||||
if (!empty($url_parts['scheme']) && !in_array($url_parts['scheme'], ['http', 'https'])) {
|
||||
// Handle custom streams.
|
||||
if ($type !== 'image' && !empty($url_parts['stream']) && !empty($url_parts['path'])) {
|
||||
$grav = Grav::instance();
|
||||
$url_parts['path'] = $grav['base_url_relative'] . '/' . $this->resolveStream("{$url_parts['scheme']}://{$url_parts['path']}");
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $grav['locator'];
|
||||
if ($locator->isStream($url)) {
|
||||
$path = $locator->findResource($url, false) ?: $locator->findResource($url, false, true);
|
||||
$url_parts['path'] = $grav['base_url_relative'] . '/' . $path;
|
||||
unset($url_parts['stream'], $url_parts['scheme']);
|
||||
}
|
||||
|
||||
@@ -338,20 +340,4 @@ class Excerpts
|
||||
|
||||
return $url_parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
protected function resolveStream(string $url)
|
||||
{
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
|
||||
if ($locator->isStream($url)) {
|
||||
return $locator->findResource($url, false) ?: $locator->findResource($url, false, true);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2095,7 +2095,7 @@ class Page implements PageInterface
|
||||
*/
|
||||
public function filePathClean()
|
||||
{
|
||||
return str_replace(ROOT_DIR, '', $this->filePath());
|
||||
return str_replace(GRAV_ROOT . DS, '', $this->filePath());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -311,7 +311,7 @@ class Plugins extends Iterator
|
||||
}
|
||||
} else {
|
||||
$grav['log']->addWarning(
|
||||
sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clear-cache`", $name)
|
||||
sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clearcache`", $name)
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,14 @@ class InitializeProcessor extends ProcessorBase
|
||||
// Load pages.
|
||||
$this->initializePages($config);
|
||||
|
||||
// Initialize URI.
|
||||
// Load accounts (decides class to be used).
|
||||
// TODO: remove in 2.0.
|
||||
$this->container['accounts'];
|
||||
|
||||
// Initialize session.
|
||||
$this->initializeSession($config);
|
||||
|
||||
// Initialize URI (uses session, see issue #3269).
|
||||
$this->initializeUri($config);
|
||||
|
||||
// Grav may return redirect response right away.
|
||||
@@ -115,13 +122,6 @@ class InitializeProcessor extends ProcessorBase
|
||||
}
|
||||
}
|
||||
|
||||
// Load accounts (decides class to be used).
|
||||
// TODO: remove in 2.0.
|
||||
$this->container['accounts'];
|
||||
|
||||
// Initialize session.
|
||||
$this->initializeSession($config);
|
||||
|
||||
$this->stopTimer('_init');
|
||||
|
||||
// Wrap call to next handler so that debugger can profile it.
|
||||
|
||||
@@ -210,7 +210,7 @@ class Security
|
||||
'on_events' => '#(<[^>]+[[a-z\x00-\x20\"\'\/])([\s\/]on|\sxmlns)[a-z].*=>?#iUu',
|
||||
|
||||
// Match javascript:, livescript:, vbscript:, mocha:, feed: and data: protocols
|
||||
'invalid_protocols' => '#(' . implode('|', array_map('preg_quote', $invalid_protocols, ['#'])) . '):.*?#iUu',
|
||||
'invalid_protocols' => '#(' . implode('|', array_map('preg_quote', $invalid_protocols, ['#'])) . '):\S.*?#iUu',
|
||||
|
||||
// Match -moz-bindings
|
||||
'moz_binding' => '#-moz-binding[a-z\x00-\x20]*:#u',
|
||||
|
||||
@@ -10,10 +10,18 @@
|
||||
namespace Grav\Common\Service;
|
||||
|
||||
use Grav\Common\Uri;
|
||||
use JsonException;
|
||||
use Nyholm\Psr7\Factory\Psr17Factory;
|
||||
use Nyholm\Psr7Server\ServerRequestCreator;
|
||||
use Pimple\Container;
|
||||
use Pimple\ServiceProviderInterface;
|
||||
use function explode;
|
||||
use function fopen;
|
||||
use function function_exists;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function strtolower;
|
||||
use function trim;
|
||||
|
||||
/**
|
||||
* Class RequestServiceProvider
|
||||
@@ -36,7 +44,56 @@ class RequestServiceProvider implements ServiceProviderInterface
|
||||
$psr17Factory // StreamFactory
|
||||
);
|
||||
|
||||
return $creator->fromGlobals();
|
||||
$server = $_SERVER;
|
||||
if (false === isset($server['REQUEST_METHOD'])) {
|
||||
$server['REQUEST_METHOD'] = 'GET';
|
||||
}
|
||||
$method = $server['REQUEST_METHOD'];
|
||||
|
||||
$headers = function_exists('getallheaders') ? getallheaders() : $creator::getHeadersFromServer($_SERVER);
|
||||
|
||||
$post = null;
|
||||
if (in_array($method, ['POST', 'PUT', 'PATCH', 'DELETE'])) {
|
||||
foreach ($headers as $headerName => $headerValue) {
|
||||
if ('content-type' !== strtolower($headerName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$contentType = strtolower(trim(explode(';', $headerValue, 2)[0]));
|
||||
switch ($contentType) {
|
||||
case 'application/x-www-form-urlencoded':
|
||||
case 'multipart/form-data':
|
||||
$post = $_POST;
|
||||
break 2;
|
||||
case 'application/json':
|
||||
case 'application/vnd.api+json':
|
||||
try {
|
||||
$json = file_get_contents('php://input');
|
||||
$post = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
|
||||
if (!is_array($post)) {
|
||||
$post = null;
|
||||
}
|
||||
} catch (JsonException $e) {
|
||||
$post = null;
|
||||
}
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove _url from ngnix routes.
|
||||
$get = $_GET;
|
||||
unset($get['_url']);
|
||||
if (isset($server['QUERY_STRING'])) {
|
||||
$query = $server['QUERY_STRING'];
|
||||
if (strpos($query, '_url=') !== false) {
|
||||
parse_str($query, $query);
|
||||
unset($query['_url']);
|
||||
$server['QUERY_STRING'] = http_build_query($query);
|
||||
}
|
||||
}
|
||||
|
||||
return $creator->fromArrays($server, $headers, $_COOKIE, $get, $post, $_FILES, fopen('php://input', 'rb') ?: null);
|
||||
};
|
||||
|
||||
$container['route'] = $container->factory(function () {
|
||||
|
||||
@@ -0,0 +1,351 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav\Common\Twig
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Common\Twig\Extension;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Utils;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFunction;
|
||||
|
||||
/**
|
||||
* Class FilesystemExtension
|
||||
* @package Grav\Common\Twig\Extension
|
||||
*/
|
||||
class FilesystemExtension extends AbstractExtension
|
||||
{
|
||||
/** @var UniformResourceLocator */
|
||||
private $locator;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->locator = Grav::instance()['locator'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFunction[]
|
||||
*/
|
||||
public function getFilters()
|
||||
{
|
||||
return $this->getFunctions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all functions.
|
||||
*
|
||||
* @return TwigFunction[]
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new TwigFunction('file_exists', [$this, 'file_exists']),
|
||||
new TwigFunction('fileatime', [$this, 'fileatime']),
|
||||
new TwigFunction('filectime', [$this, 'filectime']),
|
||||
new TwigFunction('filemtime', [$this, 'filemtime']),
|
||||
new TwigFunction('filesize', [$this, 'filesize']),
|
||||
new TwigFunction('filetype', [$this, 'filetype']),
|
||||
new TwigFunction('is_dir', [$this, 'is_dir']),
|
||||
new TwigFunction('is_file', [$this, 'is_file']),
|
||||
new TwigFunction('is_link', [$this, 'is_link']),
|
||||
new TwigFunction('is_readable', [$this, 'is_readable']),
|
||||
new TwigFunction('is_writable', [$this, 'is_writable']),
|
||||
new TwigFunction('is_writeable', [$this, 'is_writable']),
|
||||
new TwigFunction('lstat', [$this, 'lstat']),
|
||||
new TwigFunction('getimagesize', [$this, 'getimagesize']),
|
||||
new TwigFunction('exif_read_data', [$this, 'exif_read_data']),
|
||||
new TwigFunction('read_exif_data', [$this, 'exif_read_data']),
|
||||
new TwigFunction('exif_imagetype', [$this, 'exif_imagetype']),
|
||||
new TwigFunction('hash_file', [$this, 'hash_file']),
|
||||
new TwigFunction('hash_hmac_file', [$this, 'hash_hmac_file']),
|
||||
new TwigFunction('md5_file', [$this, 'md5_file']),
|
||||
new TwigFunction('sha1_file', [$this, 'sha1_file']),
|
||||
new TwigFunction('get_meta_tags', [$this, 'get_meta_tags']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return bool
|
||||
*/
|
||||
public function file_exists($filename): bool
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return file_exists($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return int|false
|
||||
*/
|
||||
public function fileatime($filename)
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return fileatime($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return int|false
|
||||
*/
|
||||
public function filectime($filename)
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return filectime($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return int|false
|
||||
*/
|
||||
public function filemtime($filename)
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return filemtime($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return int|false
|
||||
*/
|
||||
public function filesize($filename)
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return filesize($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return string|false
|
||||
*/
|
||||
public function filetype($filename)
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return filetype($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return bool
|
||||
*/
|
||||
public function is_dir($filename): bool
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_dir($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return bool
|
||||
*/
|
||||
public function is_file($filename): bool
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_file($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return bool
|
||||
*/
|
||||
public function is_link($filename): bool
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_link($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return bool
|
||||
*/
|
||||
public function is_readable($filename): bool
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_readable($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return bool
|
||||
*/
|
||||
public function is_writable($filename): bool
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_writable($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return array|false
|
||||
*/
|
||||
public function lstat($filename)
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return lstat($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return array|false
|
||||
*/
|
||||
public function getimagesize($filename)
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getimagesize($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param string|null $required_sections
|
||||
* @param bool $as_arrays
|
||||
* @param bool $read_thumbnail
|
||||
* @return array|false
|
||||
*/
|
||||
public function exif_read_data($file, ?string $required_sections, bool $as_arrays = false, bool $read_thumbnail = false)
|
||||
{
|
||||
if (!Utils::functionExists('exif_read_data') || !$this->checkFilename($file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return exif_read_data($file, $required_sections, $as_arrays, $read_thumbnail);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return string|false
|
||||
*/
|
||||
public function exif_imagetype($filename)
|
||||
{
|
||||
if (!Utils::functionExists('exif_imagetype') || !$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return @exif_imagetype($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $algo
|
||||
* @param string $filename
|
||||
* @param bool $binary
|
||||
* @return string|false
|
||||
*/
|
||||
public function hash_file(string $algo, string $filename, bool $binary = false)
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return hash_file($algo, $filename, $binary);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $algo
|
||||
* @param string $data
|
||||
* @param string $key
|
||||
* @param bool $binary
|
||||
* @return string|false
|
||||
*/
|
||||
public function hash_hmac_file(string $algo, string $data, string $key, bool $binary = false)
|
||||
{
|
||||
if (!$this->checkFilename($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return hash_hmac_file($algo, $data, $key, $binary);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @param bool $binary
|
||||
* @return string|false
|
||||
*/
|
||||
public function md5_file($filename, bool $binary = false)
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return md5_file($filename, $binary);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @param bool $binary
|
||||
* @return string|false
|
||||
*/
|
||||
public function sha1_file($filename, bool $binary = false)
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return sha1_file($filename, $binary);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return array|false
|
||||
*/
|
||||
public function get_meta_tags($filename)
|
||||
{
|
||||
if (!$this->checkFilename($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return get_meta_tags($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return bool
|
||||
*/
|
||||
private function checkFilename($filename): bool
|
||||
{
|
||||
return is_string($filename) && (!str_contains($filename, '://') || $this->locator->isStream($filename));
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,6 @@ class TwigNodeMarkdown extends Node implements NodeOutputInterface
|
||||
->write('$lines = explode("\n", $content);' . PHP_EOL)
|
||||
->write('$content = preg_replace(\'/^\' . $matches[0]. \'/\', "", $lines);' . PHP_EOL)
|
||||
->write('$content = join("\n", $content);' . PHP_EOL)
|
||||
->write('echo $this->env->getExtension(\'Grav\Common\Twig\TwigExtension\')->markdownFunction($context, $content);' . PHP_EOL);
|
||||
->write('echo $this->env->getExtension(\'Grav\Common\Twig\Extension\GravExtension\')->markdownFunction($context, $content);' . PHP_EOL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@ use Grav\Common\Language\Language;
|
||||
use Grav\Common\Language\LanguageCodes;
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Page\Pages;
|
||||
use Grav\Common\Twig\Extension\FilesystemExtension;
|
||||
use Grav\Common\Twig\Extension\GravExtension;
|
||||
use Grav\Common\Utils;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use Phive\Twig\Extensions\Deferred\DeferredExtension;
|
||||
@@ -34,6 +37,8 @@ use Twig\Profiler\Profile;
|
||||
use Twig\TwigFilter;
|
||||
use Twig\TwigFunction;
|
||||
use function function_exists;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
|
||||
/**
|
||||
* Class Twig
|
||||
@@ -154,27 +159,53 @@ class Twig
|
||||
|
||||
$this->twig = new TwigEnvironment($loader_chain, $params);
|
||||
|
||||
if ($config->get('system.twig.undefined_functions')) {
|
||||
$this->twig->registerUndefinedFunctionCallback(function ($name) {
|
||||
$this->twig->registerUndefinedFunctionCallback(function ($name) use ($config) {
|
||||
$allowed = $config->get('system.twig.safe_functions');
|
||||
if (is_array($allowed) && in_array($name, $allowed, true) && function_exists($name)) {
|
||||
return new TwigFunction($name, $name);
|
||||
}
|
||||
if ($config->get('system.twig.undefined_functions')) {
|
||||
if (function_exists($name)) {
|
||||
return new TwigFunction($name, $name);
|
||||
if (!Utils::isDangerousFunction($name)) {
|
||||
user_error("PHP function {$name}() was used as Twig function. This is deprecated in Grav 1.7. Please add it to system configuration: `system.twig.safe_functions`", E_USER_DEPRECATED);
|
||||
|
||||
return new TwigFunction($name, $name);
|
||||
}
|
||||
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = $this->grav['debugger'];
|
||||
$debugger->addException(new RuntimeException("Blocked potentially dangerous PHP function {$name}() being used as Twig function. If you really want to use it, please add it to system configuration: `system.twig.safe_functions`"));
|
||||
}
|
||||
|
||||
return new TwigFunction($name, static function () {
|
||||
});
|
||||
});
|
||||
}
|
||||
return new TwigFunction($name, static function () {});
|
||||
}
|
||||
|
||||
if ($config->get('system.twig.undefined_filters')) {
|
||||
$this->twig->registerUndefinedFilterCallback(function ($name) {
|
||||
return false;
|
||||
});
|
||||
|
||||
$this->twig->registerUndefinedFilterCallback(function ($name) use ($config) {
|
||||
$allowed = $config->get('system.twig.safe_filters');
|
||||
if (is_array($allowed) && in_array($name, $allowed, true) && function_exists($name)) {
|
||||
return new TwigFilter($name, $name);
|
||||
}
|
||||
if ($config->get('system.twig.undefined_filters')) {
|
||||
if (function_exists($name)) {
|
||||
return new TwigFilter($name, $name);
|
||||
if (!Utils::isDangerousFunction($name)) {
|
||||
user_error("PHP function {$name}() used as Twig filter. This is deprecated in Grav 1.7. Please add it to system configuration: `system.twig.safe_filters`", E_USER_DEPRECATED);
|
||||
|
||||
return new TwigFilter($name, $name);
|
||||
}
|
||||
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = $this->grav['debugger'];
|
||||
$debugger->addException(new RuntimeException("Blocked potentially dangerous PHP function {$name}() being used as Twig filter. If you really want to use it, please add it to system configuration: `system.twig.safe_filters`"));
|
||||
}
|
||||
|
||||
return new TwigFilter($name, static function () {
|
||||
});
|
||||
});
|
||||
}
|
||||
return new TwigFilter($name, static function () {});
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
$this->grav->fireEvent('onTwigInitialized');
|
||||
|
||||
@@ -188,7 +219,8 @@ class Twig
|
||||
if ($config->get('system.twig.debug')) {
|
||||
$this->twig->addExtension(new DebugExtension());
|
||||
}
|
||||
$this->twig->addExtension(new TwigExtension());
|
||||
$this->twig->addExtension(new GravExtension());
|
||||
$this->twig->addExtension(new FilesystemExtension());
|
||||
$this->twig->addExtension(new DeferredExtension());
|
||||
$this->twig->addExtension(new StringLoaderExtension());
|
||||
|
||||
@@ -211,7 +243,7 @@ class Twig
|
||||
'assets' => $this->grav['assets'],
|
||||
'taxonomy' => $this->grav['taxonomy'],
|
||||
'browser' => $this->grav['browser'],
|
||||
'base_dir' => rtrim(ROOT_DIR, '/'),
|
||||
'base_dir' => GRAV_ROOT,
|
||||
'home_url' => $pages->homeUrl($active_language),
|
||||
'base_url' => $pages->baseUrl($active_language),
|
||||
'base_url_absolute' => $pages->baseUrl($active_language, true),
|
||||
|
||||
@@ -44,7 +44,7 @@ use function strlen;
|
||||
*/
|
||||
abstract class Utils
|
||||
{
|
||||
/** @var array */
|
||||
/** @var array */
|
||||
protected static $nonces = [];
|
||||
|
||||
protected const ROOTURL_REGEX = '{^((?:http[s]?:\/\/[^\/]+)|(?:\/\/[^\/]+))(.*)}';
|
||||
@@ -178,8 +178,8 @@ abstract class Utils
|
||||
/**
|
||||
* Check if the $haystack string starts with the substring $needle
|
||||
*
|
||||
* @param string $haystack
|
||||
* @param string|string[] $needle
|
||||
* @param string $haystack
|
||||
* @param string|string[] $needle
|
||||
* @param bool $case_sensitive
|
||||
* @return bool
|
||||
*/
|
||||
@@ -202,8 +202,8 @@ abstract class Utils
|
||||
/**
|
||||
* Check if the $haystack string ends with the substring $needle
|
||||
*
|
||||
* @param string $haystack
|
||||
* @param string|string[] $needle
|
||||
* @param string $haystack
|
||||
* @param string|string[] $needle
|
||||
* @param bool $case_sensitive
|
||||
* @return bool
|
||||
*/
|
||||
@@ -227,9 +227,9 @@ abstract class Utils
|
||||
/**
|
||||
* Check if the $haystack string contains the substring $needle
|
||||
*
|
||||
* @param string $haystack
|
||||
* @param string|string[] $needle
|
||||
* @param bool $case_sensitive
|
||||
* @param string $haystack
|
||||
* @param string|string[] $needle
|
||||
* @param bool $case_sensitive
|
||||
* @return bool
|
||||
*/
|
||||
public static function contains($haystack, $needle, $case_sensitive = true)
|
||||
@@ -266,19 +266,19 @@ abstract class Utils
|
||||
{
|
||||
$regex = str_replace(
|
||||
array("\*", "\?"), // wildcard chars
|
||||
array('.*','.'), // regexp chars
|
||||
array('.*', '.'), // regexp chars
|
||||
preg_quote($wildcard_pattern, '/')
|
||||
);
|
||||
|
||||
return preg_match('/^'.$regex.'$/is', $haystack);
|
||||
return preg_match('/^' . $regex . '$/is', $haystack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render simple template filling up the variables in it. If value is not defined, leave it as it was.
|
||||
*
|
||||
* @param string $template Template string
|
||||
* @param array $variables Variables with values
|
||||
* @param array $brackets Optional array of opening and closing brackets or symbols
|
||||
* @param string $template Template string
|
||||
* @param array $variables Variables with values
|
||||
* @param array $brackets Optional array of opening and closing brackets or symbols
|
||||
* @return string Final string filled with values
|
||||
*/
|
||||
public static function simpleTemplate(string $template, array $variables, array $brackets = ['{', '}']): string
|
||||
@@ -376,8 +376,8 @@ abstract class Utils
|
||||
/**
|
||||
* Merge two objects into one.
|
||||
*
|
||||
* @param object $obj1
|
||||
* @param object $obj2
|
||||
* @param object $obj1
|
||||
* @param object $obj2
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
@@ -415,7 +415,7 @@ abstract class Utils
|
||||
*/
|
||||
public static function arrayRemoveValue(array $search, $value)
|
||||
{
|
||||
foreach ((array) $value as $val) {
|
||||
foreach ((array)$value as $val) {
|
||||
$key = array_search($val, $search);
|
||||
if ($key !== false) {
|
||||
unset($search[$key]);
|
||||
@@ -481,8 +481,8 @@ abstract class Utils
|
||||
/**
|
||||
* Array combine but supports different array lengths
|
||||
*
|
||||
* @param array $arr1
|
||||
* @param array $arr2
|
||||
* @param array $arr1
|
||||
* @param array $arr2
|
||||
* @return array|false
|
||||
*/
|
||||
public static function arrayCombine($arr1, $arr2)
|
||||
@@ -495,7 +495,7 @@ abstract class Utils
|
||||
/**
|
||||
* Array is associative or not
|
||||
*
|
||||
* @param array $arr
|
||||
* @param array $arr
|
||||
* @return bool
|
||||
*/
|
||||
public static function arrayIsAssociative($arr)
|
||||
@@ -517,15 +517,15 @@ abstract class Utils
|
||||
$now = new DateTime();
|
||||
|
||||
$date_formats = [
|
||||
'd-m-Y H:i' => 'd-m-Y H:i (e.g. '.$now->format('d-m-Y H:i').')',
|
||||
'Y-m-d H:i' => 'Y-m-d H:i (e.g. '.$now->format('Y-m-d H:i').')',
|
||||
'm/d/Y h:i a' => 'm/d/Y h:i a (e.g. '.$now->format('m/d/Y h:i a').')',
|
||||
'H:i d-m-Y' => 'H:i d-m-Y (e.g. '.$now->format('H:i d-m-Y').')',
|
||||
'h:i a m/d/Y' => 'h:i a m/d/Y (e.g. '.$now->format('h:i a m/d/Y').')',
|
||||
];
|
||||
'd-m-Y H:i' => 'd-m-Y H:i (e.g. ' . $now->format('d-m-Y H:i') . ')',
|
||||
'Y-m-d H:i' => 'Y-m-d H:i (e.g. ' . $now->format('Y-m-d H:i') . ')',
|
||||
'm/d/Y h:i a' => 'm/d/Y h:i a (e.g. ' . $now->format('m/d/Y h:i a') . ')',
|
||||
'H:i d-m-Y' => 'H:i d-m-Y (e.g. ' . $now->format('H:i d-m-Y') . ')',
|
||||
'h:i a m/d/Y' => 'h:i a m/d/Y (e.g. ' . $now->format('h:i a m/d/Y') . ')',
|
||||
];
|
||||
$default_format = Grav::instance()['config']->get('system.pages.dateformat.default');
|
||||
if ($default_format) {
|
||||
$date_formats = array_merge([$default_format => $default_format.' (e.g. '.$now->format($default_format).')'], $date_formats);
|
||||
$date_formats = array_merge([$default_format => $default_format . ' (e.g. ' . $now->format($default_format) . ')'], $date_formats);
|
||||
}
|
||||
|
||||
return $date_formats;
|
||||
@@ -552,11 +552,11 @@ abstract class Utils
|
||||
/**
|
||||
* Truncate text by number of characters but can cut off words.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $limit Max number of characters.
|
||||
* @param bool $up_to_break truncate up to breakpoint after char count
|
||||
* @param string $break Break point.
|
||||
* @param string $pad Appended padding to the end of the string.
|
||||
* @param string $string
|
||||
* @param int $limit Max number of characters.
|
||||
* @param bool $up_to_break truncate up to breakpoint after char count
|
||||
* @param string $break Break point.
|
||||
* @param string $pad Appended padding to the end of the string.
|
||||
* @return string
|
||||
*/
|
||||
public static function truncate($string, $limit = 150, $up_to_break = false, $break = ' ', $pad = '…')
|
||||
@@ -582,7 +582,7 @@ abstract class Utils
|
||||
* Truncate text by number of characters in a "word-safe" manor.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $limit
|
||||
* @param int $limit
|
||||
* @return string
|
||||
*/
|
||||
public static function safeTruncate($string, $limit = 150)
|
||||
@@ -594,9 +594,9 @@ abstract class Utils
|
||||
/**
|
||||
* Truncate HTML by number of characters. not "word-safe"!
|
||||
*
|
||||
* @param string $text
|
||||
* @param int $length in characters
|
||||
* @param string $ellipsis
|
||||
* @param string $text
|
||||
* @param int $length in characters
|
||||
* @param string $ellipsis
|
||||
* @return string
|
||||
*/
|
||||
public static function truncateHtml($text, $length = 100, $ellipsis = '...')
|
||||
@@ -607,9 +607,9 @@ abstract class Utils
|
||||
/**
|
||||
* Truncate HTML by number of characters in a "word-safe" manor.
|
||||
*
|
||||
* @param string $text
|
||||
* @param int $length in words
|
||||
* @param string $ellipsis
|
||||
* @param string $text
|
||||
* @param int $length in words
|
||||
* @param string $ellipsis
|
||||
* @return string
|
||||
*/
|
||||
public static function safeTruncateHtml($text, $length = 25, $ellipsis = '...')
|
||||
@@ -633,8 +633,8 @@ abstract class Utils
|
||||
*
|
||||
* @param string $file the full path to the file to be downloaded
|
||||
* @param bool $force_download as opposed to letting browser choose if to download or render
|
||||
* @param int $sec Throttling, try 0.1 for some speed throttling of downloads
|
||||
* @param int $bytes Size of chunks to send in bytes. Default is 1024
|
||||
* @param int $sec Throttling, try 0.1 for some speed throttling of downloads
|
||||
* @param int $bytes Size of chunks to send in bytes. Default is 1024
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function download($file, $force_download = true, $sec = 0, $bytes = 1024)
|
||||
@@ -645,7 +645,7 @@ abstract class Utils
|
||||
|
||||
$file_parts = pathinfo($file);
|
||||
$mimetype = static::getMimeByExtension($file_parts['extension']);
|
||||
$size = filesize($file); // File size
|
||||
$size = filesize($file); // File size
|
||||
|
||||
// clean all buffers
|
||||
while (ob_get_level()) {
|
||||
@@ -742,7 +742,7 @@ abstract class Utils
|
||||
// Set from uri extension
|
||||
$uri_extension = $uri->extension();
|
||||
if (is_string($uri_extension) && $uri->isValidExtension($uri_extension)) {
|
||||
return($uri_extension);
|
||||
return ($uri_extension);
|
||||
}
|
||||
|
||||
// Use content negotiation via the `accept:` header
|
||||
@@ -1060,7 +1060,7 @@ abstract class Utils
|
||||
|
||||
$pretty_offset = "UTC${offset_prefix}${offset_formatted}";
|
||||
|
||||
$timezone_list[$timezone] = "(${pretty_offset}) ".str_replace('_', ' ', $timezone);
|
||||
$timezone_list[$timezone] = "(${pretty_offset}) " . str_replace('_', ' ', $timezone);
|
||||
}
|
||||
|
||||
return $timezone_list;
|
||||
@@ -1069,11 +1069,11 @@ abstract class Utils
|
||||
/**
|
||||
* Recursively filter an array, filtering values by processing them through the $fn function argument
|
||||
*
|
||||
* @param array $source the Array to filter
|
||||
* @param callable $fn the function to pass through each array item
|
||||
* @param array $source the Array to filter
|
||||
* @param callable $fn the function to pass through each array item
|
||||
* @return array
|
||||
*/
|
||||
public static function arrayFilterRecursive(Array $source, $fn)
|
||||
public static function arrayFilterRecursive(array $source, $fn)
|
||||
{
|
||||
$result = [];
|
||||
foreach ($source as $key => $value) {
|
||||
@@ -1093,15 +1093,15 @@ abstract class Utils
|
||||
/**
|
||||
* Flatten a multi-dimensional associative array into query params.
|
||||
*
|
||||
* @param array $array
|
||||
* @param string $prepend
|
||||
* @param array $array
|
||||
* @param string $prepend
|
||||
* @return array
|
||||
*/
|
||||
public static function arrayToQueryParams($array, $prepend = '')
|
||||
{
|
||||
$results = [];
|
||||
foreach ($array as $key => $value) {
|
||||
$name = $prepend ? $prepend . '[' . $key . ']' : $key;
|
||||
$name = $prepend ? $prepend . '[' . $key . ']' : $key;
|
||||
|
||||
if (is_array($value)) {
|
||||
$results = array_merge($results, static::arrayToQueryParams($value, $name));
|
||||
@@ -1138,8 +1138,8 @@ abstract class Utils
|
||||
/**
|
||||
* Flatten a multi-dimensional associative array into dot notation
|
||||
*
|
||||
* @param array $array
|
||||
* @param string $prepend
|
||||
* @param array $array
|
||||
* @param string $prepend
|
||||
* @return array
|
||||
*/
|
||||
public static function arrayFlattenDotNotation($array, $prepend = '')
|
||||
@@ -1147,9 +1147,9 @@ abstract class Utils
|
||||
$results = array();
|
||||
foreach ($array as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$results = array_merge($results, static::arrayFlattenDotNotation($value, $prepend.$key.'.'));
|
||||
$results = array_merge($results, static::arrayFlattenDotNotation($value, $prepend . $key . '.'));
|
||||
} else {
|
||||
$results[$prepend.$key] = $value;
|
||||
$results[$prepend . $key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1297,7 +1297,7 @@ abstract class Utils
|
||||
* with reverse proxy setups.
|
||||
*
|
||||
* @param string $action
|
||||
* @param bool $previousTick if true, generates the token for the previous tick (the previous 12 hours)
|
||||
* @param bool $previousTick if true, generates the token for the previous tick (the previous 12 hours)
|
||||
* @return string the nonce string
|
||||
*/
|
||||
private static function generateNonceString($action, $previousTick = false)
|
||||
@@ -1334,8 +1334,8 @@ abstract class Utils
|
||||
* Creates a hashed nonce tied to the passed action. Tied to the current user and time. The nonce for a given
|
||||
* action is the same for 12 hours.
|
||||
*
|
||||
* @param string $action the action the nonce is tied to (e.g. save-user-admin or move-page-homepage)
|
||||
* @param bool $previousTick if true, generates the token for the previous tick (the previous 12 hours)
|
||||
* @param string $action the action the nonce is tied to (e.g. save-user-admin or move-page-homepage)
|
||||
* @param bool $previousTick if true, generates the token for the previous tick (the previous 12 hours)
|
||||
* @return string the nonce
|
||||
*/
|
||||
public static function getNonce($action, $previousTick = false)
|
||||
@@ -1353,7 +1353,7 @@ abstract class Utils
|
||||
/**
|
||||
* Verify the passed nonce for the give action
|
||||
*
|
||||
* @param string|string[] $nonce the nonce to verify
|
||||
* @param string|string[] $nonce the nonce to verify
|
||||
* @param string $action the action to verify the nonce to
|
||||
* @return boolean verified or not
|
||||
*/
|
||||
@@ -1370,9 +1370,7 @@ abstract class Utils
|
||||
}
|
||||
|
||||
//Nonce generated 12-24 hours ago
|
||||
$previousTick = true;
|
||||
|
||||
return $nonce === self::getNonce($action, $previousTick);
|
||||
return $nonce === self::getNonce($action, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1382,11 +1380,7 @@ abstract class Utils
|
||||
*/
|
||||
public static function isAdminPlugin()
|
||||
{
|
||||
if (isset(Grav::instance()['admin'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return isset(Grav::instance()['admin']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1440,7 +1434,7 @@ abstract class Utils
|
||||
while (count($keys) > 1) {
|
||||
$key = array_shift($keys);
|
||||
|
||||
if (! isset($array[$key]) || ! is_array($array[$key])) {
|
||||
if (!isset($array[$key]) || !is_array($array[$key])) {
|
||||
$array[$key] = array();
|
||||
}
|
||||
|
||||
@@ -1731,7 +1725,7 @@ abstract class Utils
|
||||
$size *= 1024 ** stripos('bkmgtpezy', $unit[0]);
|
||||
}
|
||||
|
||||
return (int) abs(round($size));
|
||||
return (int)abs(round($size));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1776,7 +1770,7 @@ abstract class Utils
|
||||
public static function processMarkdown($string, $block = true, $page = null)
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
$page = $page ?? $grav['page'] ?? null;
|
||||
$page = $page ?? $grav['page'] ?? null;
|
||||
$defaults = [
|
||||
'markdown' => $grav['config']->get('system.pages.markdown', []),
|
||||
'images' => $grav['config']->get('system.images', [])
|
||||
@@ -1818,12 +1812,12 @@ abstract class Utils
|
||||
$ip = (string)inet_pton($ip);
|
||||
|
||||
// Maximum netmask length = same as packed address
|
||||
$len = 8*strlen($ip);
|
||||
$len = 8 * strlen($ip);
|
||||
if ($prefix > $len) {
|
||||
$prefix = $len;
|
||||
}
|
||||
|
||||
$mask = str_repeat('f', $prefix>>2);
|
||||
$mask = str_repeat('f', $prefix >> 2);
|
||||
|
||||
switch ($prefix & 3) {
|
||||
case 3:
|
||||
@@ -1836,7 +1830,7 @@ abstract class Utils
|
||||
$mask .= '8';
|
||||
break;
|
||||
}
|
||||
$mask = str_pad($mask, $len>>2, '0');
|
||||
$mask = str_pad($mask, $len >> 2, '0');
|
||||
|
||||
// Packed representation of netmask
|
||||
$mask = pack('H*', $mask);
|
||||
@@ -1850,11 +1844,14 @@ abstract class Utils
|
||||
* Wrapper to ensure html, htm in the front of the supported page types
|
||||
*
|
||||
* @param array|null $defaults
|
||||
* @return array|mixed
|
||||
* @return array
|
||||
*/
|
||||
public static function getSupportPageTypes(array $defaults = null)
|
||||
{
|
||||
$types = Grav::instance()['config']->get('system.pages.types', $defaults);
|
||||
if (!is_array($types)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// remove html/htm
|
||||
$types = static::arrayRemoveValue($types, ['html', 'htm']);
|
||||
@@ -1864,4 +1861,244 @@ abstract class Utils
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public static function isDangerousFunction(string $name): bool
|
||||
{
|
||||
static $commandExecutionFunctions = [
|
||||
'exec',
|
||||
'passthru',
|
||||
'system',
|
||||
'shell_exec',
|
||||
'popen',
|
||||
'proc_open',
|
||||
'pcntl_exec',
|
||||
];
|
||||
|
||||
static $codeExecutionFunctions = [
|
||||
'assert',
|
||||
'preg_replace',
|
||||
'create_function',
|
||||
'include',
|
||||
'include_once',
|
||||
'require',
|
||||
'require_once'
|
||||
];
|
||||
|
||||
static $callbackFunctions = [
|
||||
'ob_start' => 0,
|
||||
'array_diff_uassoc' => -1,
|
||||
'array_diff_ukey' => -1,
|
||||
'array_filter' => 1,
|
||||
'array_intersect_uassoc' => -1,
|
||||
'array_intersect_ukey' => -1,
|
||||
'array_map' => 0,
|
||||
'array_reduce' => 1,
|
||||
'array_udiff_assoc' => -1,
|
||||
'array_udiff_uassoc' => [-1, -2],
|
||||
'array_udiff' => -1,
|
||||
'array_uintersect_assoc' => -1,
|
||||
'array_uintersect_uassoc' => [-1, -2],
|
||||
'array_uintersect' => -1,
|
||||
'array_walk_recursive' => 1,
|
||||
'array_walk' => 1,
|
||||
'assert_options' => 1,
|
||||
'uasort' => 1,
|
||||
'uksort' => 1,
|
||||
'usort' => 1,
|
||||
'preg_replace_callback' => 1,
|
||||
'spl_autoload_register' => 0,
|
||||
'iterator_apply' => 1,
|
||||
'call_user_func' => 0,
|
||||
'call_user_func_array' => 0,
|
||||
'register_shutdown_function' => 0,
|
||||
'register_tick_function' => 0,
|
||||
'set_error_handler' => 0,
|
||||
'set_exception_handler' => 0,
|
||||
'session_set_save_handler' => [0, 1, 2, 3, 4, 5],
|
||||
'sqlite_create_aggregate' => [2, 3],
|
||||
'sqlite_create_function' => 2,
|
||||
];
|
||||
|
||||
static $informationDiscosureFunctions = [
|
||||
'phpinfo',
|
||||
'posix_mkfifo',
|
||||
'posix_getlogin',
|
||||
'posix_ttyname',
|
||||
'getenv',
|
||||
'get_current_user',
|
||||
'proc_get_status',
|
||||
'get_cfg_var',
|
||||
'disk_free_space',
|
||||
'disk_total_space',
|
||||
'diskfreespace',
|
||||
'getcwd',
|
||||
'getlastmo',
|
||||
'getmygid',
|
||||
'getmyinode',
|
||||
'getmypid',
|
||||
'getmyuid'
|
||||
];
|
||||
|
||||
static $otherFunctions = [
|
||||
'extract',
|
||||
'parse_str',
|
||||
'putenv',
|
||||
'ini_set',
|
||||
'mail',
|
||||
'header',
|
||||
'proc_nice',
|
||||
'proc_terminate',
|
||||
'proc_close',
|
||||
'pfsockopen',
|
||||
'fsockopen',
|
||||
'apache_child_terminate',
|
||||
'posix_kill',
|
||||
'posix_mkfifo',
|
||||
'posix_setpgid',
|
||||
'posix_setsid',
|
||||
'posix_setuid',
|
||||
];
|
||||
|
||||
if (in_array($name, $commandExecutionFunctions)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (in_array($name, $codeExecutionFunctions)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isset($callbackFunctions[$name])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (in_array($name, $informationDiscosureFunctions)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (in_array($name, $otherFunctions)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return static::isFilesystemFunction($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public static function isFilesystemFunction(string $name): bool
|
||||
{
|
||||
static $fileWriteFunctions = [
|
||||
'fopen',
|
||||
'tmpfile',
|
||||
'bzopen',
|
||||
'gzopen',
|
||||
// write to filesystem (partially in combination with reading)
|
||||
'chgrp',
|
||||
'chmod',
|
||||
'chown',
|
||||
'copy',
|
||||
'file_put_contents',
|
||||
'lchgrp',
|
||||
'lchown',
|
||||
'link',
|
||||
'mkdir',
|
||||
'move_uploaded_file',
|
||||
'rename',
|
||||
'rmdir',
|
||||
'symlink',
|
||||
'tempnam',
|
||||
'touch',
|
||||
'unlink',
|
||||
'imagepng',
|
||||
'imagewbmp',
|
||||
'image2wbmp',
|
||||
'imagejpeg',
|
||||
'imagexbm',
|
||||
'imagegif',
|
||||
'imagegd',
|
||||
'imagegd2',
|
||||
'iptcembed',
|
||||
'ftp_get',
|
||||
'ftp_nb_get',
|
||||
];
|
||||
|
||||
static $fileContentFunctions = [
|
||||
'file_get_contents',
|
||||
'file',
|
||||
'filegroup',
|
||||
'fileinode',
|
||||
'fileowner',
|
||||
'fileperms',
|
||||
'glob',
|
||||
'is_executable',
|
||||
'is_uploaded_file',
|
||||
'parse_ini_file',
|
||||
'readfile',
|
||||
'readlink',
|
||||
'realpath',
|
||||
'gzfile',
|
||||
'readgzfile',
|
||||
'stat',
|
||||
'imagecreatefromgif',
|
||||
'imagecreatefromjpeg',
|
||||
'imagecreatefrompng',
|
||||
'imagecreatefromwbmp',
|
||||
'imagecreatefromxbm',
|
||||
'imagecreatefromxpm',
|
||||
'ftp_put',
|
||||
'ftp_nb_put',
|
||||
'hash_update_file',
|
||||
'highlight_file',
|
||||
'show_source',
|
||||
'php_strip_whitespace',
|
||||
];
|
||||
|
||||
static $filesystemFunctions = [
|
||||
// read from filesystem
|
||||
'file_exists',
|
||||
'fileatime',
|
||||
'filectime',
|
||||
'filemtime',
|
||||
'filesize',
|
||||
'filetype',
|
||||
'is_dir',
|
||||
'is_file',
|
||||
'is_link',
|
||||
'is_readable',
|
||||
'is_writable',
|
||||
'is_writeable',
|
||||
'linkinfo',
|
||||
'lstat',
|
||||
//'pathinfo',
|
||||
'getimagesize',
|
||||
'exif_read_data',
|
||||
'read_exif_data',
|
||||
'exif_thumbnail',
|
||||
'exif_imagetype',
|
||||
'hash_file',
|
||||
'hash_hmac_file',
|
||||
'md5_file',
|
||||
'sha1_file',
|
||||
'get_meta_tags',
|
||||
];
|
||||
|
||||
if (in_array($name, $fileWriteFunctions)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (in_array($name, $fileContentFunctions)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (in_array($name, $filesystemFunctions)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,11 +73,11 @@ class InstallCommand extends GravCommand
|
||||
$io = $this->getIO();
|
||||
|
||||
$dependencies_file = '.dependencies';
|
||||
$this->destination = $input->getArgument('destination') ?: GRAV_ROOT;
|
||||
$this->destination = $input->getArgument('destination') ?: GRAV_WEBROOT;
|
||||
|
||||
// fix trailing slash
|
||||
$this->destination = rtrim($this->destination, DS) . DS;
|
||||
$this->user_path = $this->destination . USER_PATH;
|
||||
$this->user_path = $this->destination . GRAV_USER_PATH . DS;
|
||||
if ($local_config_file = $this->loadLocalConfig()) {
|
||||
$io->writeln('Read local config from <cyan>' . $local_config_file . '</cyan>');
|
||||
}
|
||||
|
||||
@@ -600,7 +600,13 @@ class InstallCommand extends GpmCommand
|
||||
try {
|
||||
$output = Response::get($package->zipball_url . $query, [], [$this, 'progress']);
|
||||
} catch (Exception $e) {
|
||||
$error = str_replace("\n", "\n | '- ", $e->getMessage());
|
||||
if (!empty($package->premium) && $e->getCode() === 401) {
|
||||
$message = '<yellow>Unauthorized Premium License Key</yellow>';
|
||||
} else {
|
||||
$message = $e->getMessage();
|
||||
}
|
||||
|
||||
$error = str_replace("\n", "\n | '- ", $message);
|
||||
$io->write("\x0D");
|
||||
// extra white spaces to clear out the buffer properly
|
||||
$io->writeln(' |- Downloading package... <red>error</red> ');
|
||||
|
||||
@@ -112,7 +112,7 @@ class UninstallCommand extends GpmCommand
|
||||
|
||||
unset($this->data['not_found'], $this->data['total']);
|
||||
|
||||
// Plugins need to be initialized in order to make clear-cache to work.
|
||||
// Plugins need to be initialized in order to make clearcache to work.
|
||||
try {
|
||||
$this->initializePlugins();
|
||||
} catch (Throwable $e) {
|
||||
|
||||
@@ -173,6 +173,7 @@ trait ControllerResponseTrait
|
||||
if ($method !== 'GET' && $method !== 'HEAD') {
|
||||
$this->setMessage($message, 'error');
|
||||
$referer = $request->getHeaderLine('Referer');
|
||||
|
||||
return $this->createRedirectResponse($referer, 303);
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ class FlexForm implements FlexObjectFormInterface, JsonSerializable
|
||||
}
|
||||
$this->setUniqueId($uniqueId);
|
||||
$directory = $object->getFlexDirectory();
|
||||
$this->setFlashLookupFolder($directory->getBlueprint()->get('form/flash_folder') ?? 'tmp://forms/[SESSIONID]');
|
||||
$this->setFlashLookupFolder($options['flash_folder'] ?? $directory->getBlueprint()->get('form/flash_folder') ?? 'tmp://forms/[SESSIONID]');
|
||||
$this->form = $options['form'] ?? null;
|
||||
|
||||
if (!empty($options['reset'])) {
|
||||
|
||||
@@ -196,9 +196,10 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
/**
|
||||
* Refresh object from the storage.
|
||||
*
|
||||
* @param bool $keepMissing
|
||||
* @return bool True if the object was refreshed
|
||||
*/
|
||||
public function refresh(): bool
|
||||
public function refresh(bool $keepMissing = false): bool
|
||||
{
|
||||
$key = $this->getStorageKey();
|
||||
if ('' === $key) {
|
||||
@@ -216,20 +217,36 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get current elements (if requested).
|
||||
$current = $keepMissing ? $this->getElements() : [];
|
||||
// Get elements from the filesystem.
|
||||
$elements = $storage->readRows([$key => null])[$key] ?? null;
|
||||
if (null !== $elements || isset($elements['__ERROR'])) {
|
||||
$meta = $elements['_META'] ?? $meta;
|
||||
if (null !== $elements) {
|
||||
$meta = $elements['__META'] ?? $meta;
|
||||
unset($elements['__META']);
|
||||
$this->filterElements($elements);
|
||||
$newKey = $meta['key'] ?? $this->getKey();
|
||||
if ($meta) {
|
||||
$this->setMetaData($meta);
|
||||
}
|
||||
$this->objectConstruct($elements, $newKey);
|
||||
}
|
||||
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = Grav::instance()['debugger'];
|
||||
$debugger->addMessage("Refreshed {$this->getFlexType()} object {$this->getKey()}", 'debug');
|
||||
if ($current) {
|
||||
// Inject back elements which are missing in the filesystem.
|
||||
$data = $this->getBlueprint()->flattenData($current);
|
||||
foreach ($data as $property => $value) {
|
||||
if (strpos($property, '.') === false) {
|
||||
$this->defProperty($property, $value);
|
||||
} else {
|
||||
$this->defNestedProperty($property, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = Grav::instance()['debugger'];
|
||||
$debugger->addMessage("Refreshed {$this->getFlexType()} object {$this->getKey()}", 'debug');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -320,14 +320,21 @@ trait PageLegacyTrait
|
||||
|
||||
// Find non-existing key.
|
||||
$parentKey = $parent ? $parent->getKey() : '';
|
||||
$key = trim($parentKey . '/' . basename($this->getKey()), '/');
|
||||
$key = preg_replace('/-\d+$/', '', $key);
|
||||
$i = 1;
|
||||
do {
|
||||
$i++;
|
||||
$test = "{$key}-{$i}";
|
||||
} while ($index->containsKey($test));
|
||||
$key = $test;
|
||||
if ($this instanceof FlexPageObject) {
|
||||
$key = trim($parentKey . '/' . $this->folder(), '/');
|
||||
} else {
|
||||
$key = trim($parentKey . '/' . basename($this->getKey()), '/');
|
||||
}
|
||||
|
||||
if ($index->containsKey($key)) {
|
||||
$key = preg_replace('/\d+$/', '', $key);
|
||||
$i = 1;
|
||||
do {
|
||||
$i++;
|
||||
$test = "{$key}{$i}";
|
||||
} while ($index->containsKey($test));
|
||||
$key = $test;
|
||||
}
|
||||
$folder = basename($key);
|
||||
|
||||
// Get the folder name.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
enabled: true
|
||||
dropdown:
|
||||
enabled: true
|
||||
@@ -2,6 +2,6 @@
|
||||
title: Accueil
|
||||
body_classes: modular
|
||||
visible: true
|
||||
debugger: true
|
||||
debugger: false
|
||||
---
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ programmes:
|
||||
site: 'http://www.popsu.archi.fr/'
|
||||
-
|
||||
nom_du_programme: 'Programme Coubertin'
|
||||
texte_de_presentation: "Le programme de recherche-action Coubertin construit le récit, au fil de l’eau, de la conception des ouvrages et des opérations d’aménagement des Jeux Olympiques et Paralympiques de Paris 2024. À travers une observation embarquée au sein de la SOLIDEO, l’équipe de chercheurs analyse la production architecturale et urbaine et sa capacité à transformer les pratiques d’aménagement.\r\n \r\n "
|
||||
texte_de_presentation: "Le programme de recherche-action Coubertin construit le récit, au fil de l’eau, de la conception des ouvrages et des opérations d’aménagement des Jeux Olympiques et Paralympiques de Paris 2024. À travers une observation embarquée au sein de la SOLIDEO, l’équipe de chercheurs analyse la production architecturale et urbaine et sa capacité à transformer les pratiques d’aménagement.\n \n "
|
||||
logo: logo_coubertin.png
|
||||
site: 'http://www.urbanisme-puca.gouv.fr/programme-coubertin-un-programme-de-recherche-a2089.html#:~:text=Un%20centre%20de%20ressources%20sur%20les%20Jeux%20Olympiques%20et%20Paralympiques,Olympiques%20et%20Paralympiques%20de%20Paris%E2%80%A6'
|
||||
-
|
||||
@@ -23,7 +23,7 @@ programmes:
|
||||
logo: forum_solution.png
|
||||
site: 'http://www.urbanisme-puca.gouv.fr/forums-des-solutions-en-videos-a1879.html'
|
||||
visible: true
|
||||
debugger: true
|
||||
debugger: false
|
||||
media_order: '14360_default_big.jpg,10361_web_01.jpg,hyperliens_marseille.PNG,popsu.png,forum_solution.png,europan_france.jpg,logo_coubertin.png,POPSU2018_LOGO_moinsde6cm.png'
|
||||
process:
|
||||
markdown: true
|
||||
|
||||
|
After Width: | Height: | Size: 790 KiB |
|
After Width: | Height: | Size: 970 KiB |
@@ -1,35 +1,20 @@
|
||||
---
|
||||
title: Ressources
|
||||
body_classes: modular
|
||||
media_order: 'rapport_activite_V1.pdf,rapport_activite_V1.png,rapport_activite_V1.pdf'
|
||||
media_order: 'Couv note orientation.PNG,Couv rapport activités.PNG,Note d''orientation EPAU 2021-2023.pdf,Rapport d''activité EPAU 2020.pdf'
|
||||
visible: true
|
||||
debugger: true
|
||||
debugger: false
|
||||
rapports:
|
||||
-
|
||||
titre_du_rapport: 'rapport d''activité 2020'
|
||||
texte_de_presentation: "Courte explicationVita estillis semper in fuga uxoresque mercenariae\r\n infugauxoresque mercenariae conductae ad tempus expacto atque, ut conductae ad tempus ex pacto atque, ut sit species matrimonii, dotis nomine futura coniunx hastam.\r\n"
|
||||
couverture: rapport_activite_V1.png
|
||||
pdf: rapport_activite_V1.pdf
|
||||
titre_du_rapport: 'Rapport d''activité 2020'
|
||||
texte_de_presentation: "Le rapport d’activité présente les principales actions réalisées par les programmes Europan, POPSU et Coubertin à l’occasion de l’année 2020. \n"
|
||||
couverture: 'Couv rapport activités.PNG'
|
||||
pdf: 'Rapport d''activité EPAU 2020.pdf'
|
||||
-
|
||||
titre_du_rapport: 'rapport 3'
|
||||
texte_de_presentation: "Courte explicationVita estillis semper in fuga uxoresque mercenariae\r\n infugauxoresque mercenariae conductae ad tempus expacto atque, ut conductae ad tempus ex pacto atque, ut sit species matrimonii, dotis nomine futura coniunx hastam.\r\n"
|
||||
couverture: rapport_activite_V1.png
|
||||
pdf: rapport_activite_V1.pdf
|
||||
-
|
||||
titre_du_rapport: 'exemple 3'
|
||||
texte_de_presentation: "Courte explicationVita estillis semper in fuga uxoresque mercenariae\r\n infugauxoresque mercenariae conductae ad tempus expacto atque, ut conductae ad tempus ex pacto atque, ut sit species matrimonii, dotis nomine futura coniunx hastam.\r\n"
|
||||
couverture: rapport_activite_V1.png
|
||||
pdf: rapport_activite_V1.pdf
|
||||
-
|
||||
titre_du_rapport: 'exemple 4'
|
||||
texte_de_presentation: "Courte explicationVita estillis semper in fuga uxoresque mercenariae\r\n infugauxoresque mercenariae conductae ad tempus expacto atque, ut conductae ad tempus ex pacto atque, ut sit species matrimonii, dotis nomine futura coniunx hastam.\r\n"
|
||||
couverture: rapport_activite_V1.png
|
||||
pdf: rapport_activite_V1.pdf
|
||||
-
|
||||
titre_du_rapport: 'exempl 5'
|
||||
texte_de_presentation: "Courte explicationVita estillis semper in fuga uxoresque mercenariae\r\n infugauxoresque mercenariae conductae ad tempus expacto atque, ut conductae ad tempus ex pacto atque, ut sit species matrimonii, dotis nomine futura coniunx hastam.\r\n"
|
||||
couverture: rapport_activite_V1.png
|
||||
pdf: rapport_activite_V1.pdf
|
||||
titre_du_rapport: 'Note d''orientation 2021-2023'
|
||||
texte_de_presentation: "La note d’orientation présente la stratégie de l’Europe des projets architecturaux et urbains de 2021 à 2023. \n"
|
||||
couverture: 'Couv note orientation.PNG'
|
||||
pdf: 'Note d''orientation EPAU 2021-2023.pdf'
|
||||
process:
|
||||
markdown: true
|
||||
twig: false
|
||||
|
||||
@@ -6,7 +6,7 @@ personnes:
|
||||
-
|
||||
nom: 'Hélène Peskine'
|
||||
fonction: 'Secrétaire permanente du Plan Urbanisme Construction Architecture, Ministère de la Transition écologique, Ministère de la Cohésion des territoires et des Relations avec les Collectivités territoriales'
|
||||
biographie: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam nec sagittis massa. Nulla facilisi. Cras id arcu lorem, et semper purus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vel enim mi, in lobortis sem. Vestibulum luctus elit eu libero ultrices id fermentum sem sagittis. Nulla imperdiet mauris sed sapien dignissim id aliquam est aliquam. Maecenas non odio ipsum, a elementum nisi. Mauris non erat eu erat placerat convallis. Mauris in pretium urna. Cras laoreet molestie odio, consequat consequat velit commodo eu. Integer vitae lectus ac nunc posuere pellentesque non at eros. Suspendisse non lectus lorem.'
|
||||
biographie: null
|
||||
portrait: MB-3-crop.jpg
|
||||
admin: { }
|
||||
process:
|
||||
|
||||
|
After Width: | Height: | Size: 346 KiB |
|
After Width: | Height: | Size: 17 MiB |
@@ -11,22 +11,22 @@ personnes:
|
||||
-
|
||||
nom: 'Catherine Chevillot'
|
||||
fonction: 'Présidente de la Cité de l’Architecture et du Patrimoine'
|
||||
biographie: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam nec sagittis massa. Nulla facilisi. Cras id arcu lorem, et semper purus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vel enim mi, in lobortis sem. Vestibulum luctus elit eu libero ultrices id fermentum sem sagittis. Nulla imperdiet mauris sed sapien dignissim id aliquam est aliquam. Maecenas non odio ipsum, a elementum nisi. Mauris non erat eu erat placerat convallis. Mauris in pretium urna. Cras laoreet molestie odio, consequat consequat velit commodo eu. Integer vitae lectus ac nunc posuere pellentesque non at eros. Suspendisse non lectus lorem.'
|
||||
portrait: catherine-chevillot-nouvelle-presidente-de-cite.JPG
|
||||
biographie: 'Conservateur du patrimoine depuis 1987, Catherine Chevillot a été successivement adjointe au directeur du musée de Grenoble (1988), conservateur au musée d’Orsay (1990), chef de la filière Sculpture au Centre de Recherche et de Restauration des Musées de France (1999), chef du service de la recherche du musée d’Orsay, où elle a créé le Prix du musée d’Orsay (2003), conservateur en chef au musée d’Orsay (2012) et directrice du musée Rodin (2012). Après trois mandats au musée Rodin, sur proposition de la ministre de la Culture Roselyne Bachelot-Narquin, elle accède le 8 mars 2021 à la présidence de la Cité de l’architecture & du patrimoine.'
|
||||
portrait: 'catherine chevillot 274 (1).jpg'
|
||||
-
|
||||
nom: 'Aurélie Cousi'
|
||||
fonction: 'Directrice, adjointe au directeur général des patrimoines, chargée de l’architecture, Ministère de la Culture'
|
||||
biographie: "Aurélie Cousi a rejoint le ministère de la Culture le 1 er février 2020 dans les fonctions de directrice, adjointe au directeur général des patrimoines, chargée de l’architecture. Diplômée de l’École polytehnique et ingénieure en chef des ponts, des eaux et des forêts, elle exerce depuis 15 ans au sein de l’État, de ses établissements publics et des collectivités dans les domaines de l’aménagement, l’urbanisme et la construction publique. \r\nCheffe de la mission immobilière auprès du directeur régional et interdépartementale de l’écologie et de l’aménagement d’Île-de-France de 2007 à 2009, puis directrice adjointe en charge de la stratégie opérationnelle à la direction de l’immobilier de l’établissement public Paris-Saclay, en charge du pilotage des projets de construction des grandes écoles et universités, Aurélie Cousi est nommée conseillère en charge de l’urbanisme au cabinet du maire de Paris en 2013, avant de prendre la direction du service de l’aménagement à la direction de l’urbanisme de 2015 à 2017. Depuis juillet 2017, elle était directrice générale adjointe en charge de l’aménagement au sein de Grand Paris Aménagement."
|
||||
biographie: "Aurélie Cousi a rejoint le ministère de la Culture le 1 er février 2020 dans les fonctions de directrice, adjointe au directeur général des patrimoines, chargée de l’architecture. Diplômée de l’École polytehnique et ingénieure en chef des ponts, des eaux et des forêts, elle exerce depuis 15 ans au sein de l’État, de ses établissements publics et des collectivités dans les domaines de l’aménagement, l’urbanisme et la construction publique. \nCheffe de la mission immobilière auprès du directeur régional et interdépartementale de l’écologie et de l’aménagement d’Île-de-France de 2007 à 2009, puis directrice adjointe en charge de la stratégie opérationnelle à la direction de l’immobilier de l’établissement public Paris-Saclay, en charge du pilotage des projets de construction des grandes écoles et universités, Aurélie Cousi est nommée conseillère en charge de l’urbanisme au cabinet du maire de Paris en 2013, avant de prendre la direction du service de l’aménagement à la direction de l’urbanisme de 2015 à 2017. Depuis juillet 2017, elle était directrice générale adjointe en charge de l’aménagement au sein de Grand Paris Aménagement."
|
||||
portrait: aurelie-cousi-nommee-aux-fonctions-de-directrice.jpg
|
||||
-
|
||||
nom: 'Alain Maugard'
|
||||
fonction: 'Président de l’Association Europan France'
|
||||
biographie: "Né le 23 avril 1943 à Nérac (Lot-et-Garonne), Alain Maugard est un ancien élève de l’École polytechnique et Ingénieur général des Ponts et Chaussées. Il débute sa carrière au ministère de l’Équipement au service des Affaires économiques et internationales et dans les services urbanisme construction des Directions Départementales. Chef du service de la politique technique à la direction de la Construction et secrétaire permanent du Plan Construction, de 1978 à 1981, il devient successivement directeur adjoint de cabinet des ministres de l’Urbanisme et du Logement Roger Quilliot et Paul Quilès puis directeur de la Construction au ministère de l’Équipement, du Logement, des Transports et de la Mer. En 1990, il est nommé directeur général de l’Établissement public d’aménagement de la Défense (epad), jusqu’en 1993 où il prend la présidence du cstb. Il quitte ces fonctions en 2008 pour rejoindre le Conseil général de l’environnement et du développement durable où il assure la présidence de la section « risques, sécurité, sûreté ». En septembre 2009, il accède à la présidence de Qualibat. \r\nEn outre, Alain Maugard est membre du conseil d’administration de l’Ademe. Il a également piloté le Comité opérationnel (comop) du chantier n°1 « Bâtiments neufs publics et privés » du Grenelle de l’Environnement. \r\n\r\nBibliographie\_:\r\n- Regards sur le bâtiment — Le futur en construction, éditions Le Moniteur, 2006\r\n - Regard sur la ville durable, Alain Maugard et Jean-Pierre Cuisinier, CSTB, mars 2010\r\n - Le BEPOS pour tous (livre électronique), http://outils.xpair.com/livre/bepos-pourtous/7.htm (25 juin 2015)"
|
||||
portrait: 'Alain Maugard_TROUVE.jpg'
|
||||
biographie: "Né le 23 avril 1943 à Nérac (Lot-et-Garonne), Alain Maugard est un ancien élève de l’École polytechnique et Ingénieur général des Ponts et Chaussées. Il débute sa carrière au ministère de l’Équipement au service des Affaires économiques et internationales et dans les services urbanisme construction des Directions Départementales. Chef du service de la politique technique à la direction de la Construction et secrétaire permanent du Plan Construction, de 1978 à 1981, il devient successivement directeur adjoint de cabinet des ministres de l’Urbanisme et du Logement Roger Quilliot et Paul Quilès puis directeur de la Construction au ministère de l’Équipement, du Logement, des Transports et de la Mer. En 1990, il est nommé directeur général de l’Établissement public d’aménagement de la Défense (epad), jusqu’en 1993 où il prend la présidence du cstb. Il quitte ces fonctions en 2008 pour rejoindre le Conseil général de l’environnement et du développement durable où il assure la présidence de la section « risques, sécurité, sûreté ». En septembre 2009, il accède à la présidence de Qualibat et de l'association Europan France. \nEn outre, Alain Maugard est membre du conseil d’administration de l’Ademe. Il a également piloté le Comité opérationnel (comop) du chantier n°1 « Bâtiments neufs publics et privés » du Grenelle de l’Environnement. "
|
||||
portrait: 'Alain Maugard.jpg'
|
||||
debugger: true
|
||||
template: modular/personnes
|
||||
media_order: 'photo_butlen.jpeg,aurelie-cousi-nommee-aux-fonctions-de-directrice.jpg,catherine-chevillot-nouvelle-presidente-de-cite.JPG,Alain Maugard_TROUVE.jpg'
|
||||
media_order: 'photo_butlen.jpeg,aurelie-cousi-nommee-aux-fonctions-de-directrice.jpg,catherine chevillot 274 (1).jpg,Alain Maugard.jpg'
|
||||
---
|
||||
|
||||
### Membres de l'assemblée générale du Groupement d’intérêt public Europe des projets architecturaux et urbains
|
||||
### Membres de l'assemblée générale de l'Europe des projets architecturaux et urbains
|
||||
|
||||
|
||||
@@ -5,17 +5,17 @@ personnes:
|
||||
-
|
||||
nom: 'Jean-Baptiste Marie'
|
||||
fonction: 'Directeur général Intégrer la bio du conseil stratégique POPSU'
|
||||
biographie: "Jean-Baptiste MARIE, architecte, docteur en architecture, diplômé de l’Ecole nationale supérieure d’architecture de Versailles et de l’Ecole Boulle. Il est directeur de la Plateforme d'observation des projets et stratégies urbaines pilotée par le Puca (Plan Urbanisme Construction Architecture) au Ministère de la Transition écologique et au Ministère \Lde la Cohésion des territoires et des Relations avec les collectivités territoriales, au sein du GIP Europe des projets architecturaux et urbains (EPAU).\r\nIl assurait auparavant, depuis 2008, le secrétariat scientifique de la plateforme européenne Popsu et depuis 2011 de la plateforme française. Il est par ailleurs Professeur des Écoles nationales supérieures d'architecture (Ensa) où il enseigne dans le champ Théories et pratiques de la conception architecturale et urbaine à l'Ensa de Clermont-Ferrand et y dirige l’équipe de recherche Ressources. Il a auparavant enseigné dans les Ensa de Normandie et de Versailles.\r\njean-baptiste.marie@developpement-durable.gouv.fr\r\n+\_33\_(1)\_40\_81\_24\_68\_\r\n+\_33\_(6)\_64\_52\_75\_57"
|
||||
biographie: "Jean-Baptiste MARIE, architecte, docteur en architecture, diplômé de l’Ecole nationale supérieure d’architecture de Versailles et de l’Ecole Boulle. Il est directeur de la Plateforme d'observation des projets et stratégies urbaines pilotée par le Puca (Plan Urbanisme Construction Architecture) au Ministère de la Transition écologique et au Ministère \Lde la Cohésion des territoires et des Relations avec les collectivités territoriales, au sein du GIP Europe des projets architecturaux et urbains (EPAU).\nIl assurait auparavant, depuis 2008, le secrétariat scientifique de la plateforme européenne Popsu et depuis 2011 de la plateforme française. Il est par ailleurs Professeur des Écoles nationales supérieures d'architecture (Ensa) où il enseigne dans le champ Théories et pratiques de la conception architecturale et urbaine à l'Ensa de Clermont-Ferrand et y dirige l’équipe de recherche Ressources. Il a auparavant enseigné dans les Ensa de Normandie et de Versailles.\njean-baptiste.marie@developpement-durable.gouv.fr\n+\_33\_(1)\_40\_81\_24\_68\_\n+\_33\_(6)\_64\_52\_75\_57"
|
||||
portrait: jb_marie_crop.jpg
|
||||
-
|
||||
nom: 'Fabienne Dran'
|
||||
fonction: 'Assistante de direction'
|
||||
biographie: "Fabienne.Dran@developpement-durable.gouv.fr \r\n+ 33 (0)1 40 81 93 27\r\n+33 (0)7 86 50 33 31"
|
||||
biographie: "Fabienne.Dran@developpement-durable.gouv.fr \n+ 33 (0)1 40 81 93 27\n+33 (0)7 86 50 33 31"
|
||||
portrait: null
|
||||
-
|
||||
nom: 'Jérôme Candevan'
|
||||
fonction: 'Responsable du service financier et facturier de l’EPAU, Agent comptable ENSA'
|
||||
biographie: "jerome.candevan@paris-lavillette.archi.fr \r\n+33 (0)6 26 04 82 09\r\n"
|
||||
biographie: "jerome.candevan@paris-lavillette.archi.fr \n+33 (0)6 26 04 82 09\n"
|
||||
portrait: null
|
||||
media_order: jb_marie_crop.jpg
|
||||
---
|
||||
|
||||
|
After Width: | Height: | Size: 326 KiB |
@@ -5,24 +5,24 @@ personnes:
|
||||
-
|
||||
nom: 'Isabelle Moulin'
|
||||
fonction: 'Secrétaire générale de l’Association Europan France, Directrice du programme Europan '
|
||||
biographie: "Isabelle Moulin a travaillé avec des agences telles que\_Guy Naizot&Ass., Atelier Ruelle, Latitude Nord, Christian Devillers&Ass., en tant que cheffe de projet conception et réalisation d'espaces publics et de paysage. Elle a exercé la profession d'architecte libérale, pour la réalisation (réhabilitation /reconstruction/ aménagement) de petits équipements publics (maison des associations, halte-garderie, atelier de mécanique, projets d'aménagements paysagers) et de réalisations architecturales privées (maisons d'habitation, réhabilitations intérieures, Bureau de Presse). L'imbrication des échelles de projets, les différents types de gouvernance rencontrés, la multiple dimension à la fois urbaine, paysagère et architecturale des projets étudiés et réalisés, des relations avec un large réseau d'acteurs urbains et architecturaux, l'ont amenée à se présenter à\_la direction du concours Europan en 2012. Elle est actuellement secrétaire générale de l'association Europan France, et mise à disposition pour la direction du programme Europan auprès du GIP EPAU, l'association étant membre fondatrice de cette structure.\r\n\r\ni.moulin@europanfrance.org\r\n+33 (0)6 42 65 75 04\r\n+33 (0)1 48 57 72 66"
|
||||
biographie: "Isabelle Moulin a travaillé avec des agences telles que\_Guy Naizot&Ass., Atelier Ruelle, Latitude Nord, Christian Devillers&Ass., en tant que cheffe de projet conception et réalisation d'espaces publics et de paysage. Elle a exercé la profession d'architecte libérale, pour la réalisation (réhabilitation /reconstruction/ aménagement) de petits équipements publics (maison des associations, halte-garderie, atelier de mécanique, projets d'aménagements paysagers) et de réalisations architecturales privées (maisons d'habitation, réhabilitations intérieures, Bureau de Presse). L'imbrication des échelles de projets, les différents types de gouvernance rencontrés, la multiple dimension à la fois urbaine, paysagère et architecturale des projets étudiés et réalisés, des relations avec un large réseau d'acteurs urbains et architecturaux, l'ont amenée à se présenter à\_la direction du concours Europan en 2012. Elle est actuellement secrétaire générale de l'association Europan France, et mise à disposition pour la direction du programme Europan auprès du GIP EPAU, l'association étant membre fondatrice de cette structure.\n\ni.moulin@europanfrance.org\n+33 (0)6 42 65 75 04\n+33 (0)1 48 57 72 66"
|
||||
portrait: 'Isabelle Moulin.jpg'
|
||||
-
|
||||
nom: 'Louis Vitalis'
|
||||
fonction: 'Chargé de missions'
|
||||
biographie: " • Photo et bio demandées\r\nl.vitalis@europanfrance.org \r\n+33 (0)1 48 57 72 66"
|
||||
portrait: null
|
||||
biographie: "Architecte formé à l'ENSA Paris Val de Seine, Docteur en architecture du Conservatoire National des Arts et Métiers et de l'UMR MAP (Modèles et simulations pour l'Architecture et le Patrimoine), Louis Vitalis est également enseignant-chercheur à l'ENSA Paris La Villette.\n\nl.vitalis@europanfrance.org \n+33 (0)1 48 57 72 66"
|
||||
portrait: 'Louis Vitalis.png'
|
||||
-
|
||||
nom: 'Mimrose Akbar'
|
||||
fonction: 'Assistante de projets'
|
||||
biographie: " • Photo et bio demandées\r\nm.akbar@europanfrance.org \r\n+33 (0)1 48 57 72 66"
|
||||
biographie: " \nm.akbar@europanfrance.org \n+33 (0)1 48 57 72 66"
|
||||
portrait: null
|
||||
-
|
||||
nom: 'Mathilde Morize'
|
||||
fonction: 'Chargée de projet '
|
||||
biographie: "m.morize@europanfrance.org \r\n+33 (0)1 48 57 72 66\r\n Photo et bio demandées"
|
||||
biographie: "m.morize@europanfrance.org \n+33 (0)1 48 57 72 66\n"
|
||||
portrait: null
|
||||
media_order: 'Isabelle Moulin.jpg'
|
||||
media_order: 'Isabelle Moulin.jpg,Louis Vitalis.png'
|
||||
---
|
||||
|
||||
### Direction du programme Europan France
|
||||
@@ -5,7 +5,7 @@ personnes:
|
||||
-
|
||||
nom: 'Julien Moulard'
|
||||
fonction: 'Responsable de programme'
|
||||
biographie: " Photo et bio demandées\r\njulien.moulard@popsu.archi.fr\r\n+ 33 (0)1 40 81 70 72\r\n+ 33 (0)7 86 50 43 17"
|
||||
biographie: "julien.moulard@popsu.archi.fr\n+ 33 (0)1 40 81 70 72\n+ 33 (0)7 86 50 43 17"
|
||||
portrait: null
|
||||
---
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ content:
|
||||
- _equipe-epau
|
||||
admin:
|
||||
children_display_order: collection
|
||||
debugger: true
|
||||
debugger: false
|
||||
---
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
title: Contact
|
||||
body_classes: modular
|
||||
media_order: 'puca.png,logo cité archi.jpg,logo ministère culture.png,europan_france.jpg,logo_gouvernment.png,logo MCTRCT.png,logo min logement.png'
|
||||
media_order: 'logo_gouvernment.png,logo MCTRCT.png,logo min logement.png,logo ministère culture.png,europan_france.jpg,puca.png,logo cité archi.jpg'
|
||||
published: true
|
||||
debugger: false
|
||||
---
|
||||
|
||||
      
|
||||
  
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
.sass-cache
|
||||
.DS_Store
|
||||
@@ -1,3 +1,83 @@
|
||||
# v2.2.1
|
||||
## 01/15/2021
|
||||
|
||||
1. [](#improved)
|
||||
* Fixed autoescaping in preparation for Grav 1.7
|
||||
1. [](#bugfix)
|
||||
* Fix deprecated messages from macros [#140](https://github.com/getgrav/grav-theme-antimatter/issues/140)
|
||||
|
||||
# v2.2.0
|
||||
## 03/21/2019
|
||||
|
||||
1. [](#new)
|
||||
* Set Dependency of Grav 1.5.10+ which has support for new **Deferred Block** Twig extension
|
||||
* Implement assets rendering using **Deferred Block** Twig extension
|
||||
|
||||
# v2.1.2
|
||||
## 9/28/2017
|
||||
|
||||
1. [](#improved)
|
||||
* Added polish and brazilian portuguese translations
|
||||
* Allow overriding the slidebar by moving it to its own `sidebar_navigation` block [#110](https://github.com/getgrav/grav-theme-antimatter/pull/110)
|
||||
1. [](#bugfix)
|
||||
* Fix showcase template overlapping when not at top [#99](https://github.com/getgrav/grav-theme-antimatter/pull/99)
|
||||
|
||||
# v2.1.1
|
||||
## 02/26/2017
|
||||
|
||||
1. [](#bugfix)
|
||||
* Allow to add a `external` class to site.yaml links to work on modular pages [#95](https://github.com/getgrav/grav-theme-antimatter/pull/95)
|
||||
|
||||
# v2.1.0
|
||||
## 01/24/2017
|
||||
|
||||
1. [](#new)
|
||||
* Updated to FontAwesome 4.7.0 with [Grav icon](http://fontawesome.io/icon/grav/)
|
||||
1. [](#improved)
|
||||
* Added croatian
|
||||
* Changed "SimpleSearch" string in the sidebar to "Search"
|
||||
1. [](#bugfix)
|
||||
* Removed unreachable condition [#85](https://github.com/getgrav/grav-theme-antimatter/pull/85)
|
||||
* Fixed a typo in the french translation
|
||||
|
||||
# v2.0.0
|
||||
## 07/14/2016
|
||||
|
||||
1. [](#new)
|
||||
* Added microformats2 support [#64](https://github.com/getgrav/grav-theme-antimatter/pull/64)
|
||||
1. [](#improved)
|
||||
* Updated to FontAwesome 4.6.3
|
||||
* Added romanian, russian and ukranian
|
||||
|
||||
# v2.0.0-beta.1
|
||||
## 05/23/2016
|
||||
|
||||
1. [](#new)
|
||||
* New and improved **dropdown** styling
|
||||
1. [](#improved)
|
||||
* Removed templates from `form` + `snipcart` plugins
|
||||
* Added support for search button
|
||||
* Updated some translations
|
||||
* Automatically add comments if configured
|
||||
* Relative path for favicon
|
||||
* Slightly modified the blockquote background color
|
||||
* Removed unneeded streams from YAML
|
||||
* Use common language strings in Blueprint
|
||||
|
||||
# v1.8.0
|
||||
## 11/20/2015
|
||||
|
||||
1. [](#new)
|
||||
* Added logic to include site.menu items in modular pages
|
||||
* Added a configurable lang field for HTML tag
|
||||
* Added a `bottom` JS output call
|
||||
1. [](#improved)
|
||||
* Updated to FontAwesome 4.4.0
|
||||
1. [](#bugfix)
|
||||
* Fixed extra `/` in some tag URLs
|
||||
* Better support for PECL Yaml parser
|
||||
* Fixes for blog page blueprint
|
||||
|
||||
# v1.7.6
|
||||
## 10/07/2015
|
||||
|
||||
@@ -46,7 +126,7 @@
|
||||
1. [](#new)
|
||||
* Blueprints that work with new admin plugin!
|
||||
1. [](#bugfix)
|
||||
* Favicon with full image URL
|
||||
* Favicon with full image URL
|
||||
|
||||
# v1.6.1
|
||||
## 07/24/2015
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
enabled: true
|
||||
dropdown:
|
||||
enabled: false
|
||||
|
||||
streams:
|
||||
schemes:
|
||||
theme:
|
||||
type: ReadOnlyStream
|
||||
paths:
|
||||
- user/themes/antimatter
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Antimatter
|
||||
version: 1.7.6
|
||||
version: 2.2.1
|
||||
description: "Antimatter is the default theme included with **Grav**"
|
||||
icon: empire
|
||||
author:
|
||||
@@ -12,6 +12,9 @@ keywords: antimatter, theme, core, modern, fast, responsive, html5, css3
|
||||
bugs: https://github.com/getgrav/grav-theme-antimatter/issues
|
||||
license: MIT
|
||||
|
||||
dependencies:
|
||||
- { name: grav, version: '>=1.5.10' }
|
||||
|
||||
form:
|
||||
validation: loose
|
||||
fields:
|
||||
@@ -21,7 +24,7 @@ form:
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
1: Enabled
|
||||
0: Disabled
|
||||
1: PLUGIN_ADMIN.ENABLED
|
||||
0: PLUGIN_ADMIN.DISABLED
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
@@ -26,9 +26,9 @@ form:
|
||||
type: upload
|
||||
label: Upload
|
||||
allow:
|
||||
@media.*.keys
|
||||
'@media.*.keys'
|
||||
accept:
|
||||
@media.*.values
|
||||
'@media.*.values'
|
||||
|
||||
filename:
|
||||
type: text
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
title: Blog
|
||||
@extends:
|
||||
'@extends':
|
||||
type: default
|
||||
context: blueprints://pages
|
||||
|
||||
@@ -33,11 +33,10 @@ form:
|
||||
|
||||
fields:
|
||||
header.content.items:
|
||||
type: select
|
||||
type: textarea
|
||||
yaml: true
|
||||
label: Items
|
||||
default: @self.children
|
||||
options:
|
||||
@self.children: Children
|
||||
default: '@self.children'
|
||||
|
||||
header.content.limit:
|
||||
type: text
|
||||
@@ -72,5 +71,19 @@ form:
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
1: Enabled
|
||||
0: Disabled
|
||||
1: PLUGIN_ADMIN.ENABLED
|
||||
0: PLUGIN_ADMIN.DISABLED
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
|
||||
header.content.url_taxonomy_filters:
|
||||
type: toggle
|
||||
label: URL Taxonomy Filters
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
1: PLUGIN_ADMIN.ENABLED
|
||||
0: PLUGIN_ADMIN.DISABLED
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
title: Nopad
|
||||
@extends: default
|
||||
'@extends': default
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
title: Item
|
||||
@extends:
|
||||
'@extends':
|
||||
type: default
|
||||
context: blueprints://pages
|
||||
|
||||
@@ -26,8 +26,8 @@ form:
|
||||
help: Enabled displaying of a header image
|
||||
highlight: 1
|
||||
options:
|
||||
1: Enabled
|
||||
0: Disabled
|
||||
1: PLUGIN_ADMIN.ENABLED
|
||||
0: PLUGIN_ADMIN.DISABLED
|
||||
|
||||
header.header_image_file:
|
||||
type: text
|
||||
@@ -73,8 +73,8 @@ form:
|
||||
label: Summary
|
||||
highlight: 1
|
||||
options:
|
||||
1: Enabled
|
||||
0: Disabled
|
||||
1: PLUGIN_ADMIN.ENABLED
|
||||
0: PLUGIN_ADMIN.DISABLED
|
||||
|
||||
header.summary.format:
|
||||
type: select
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
title: Features
|
||||
@extends: default
|
||||
'@extends': default
|
||||
|
||||
form:
|
||||
fields:
|
||||
@@ -13,12 +13,12 @@ form:
|
||||
fields:
|
||||
name:
|
||||
default: modular/features
|
||||
@data-options: '\Grav\Common\Page\Pages::modularTypes'
|
||||
'@data-options': '\Grav\Common\Page\Pages::modularTypes'
|
||||
overrides:
|
||||
fields:
|
||||
header.template:
|
||||
default: modular/features
|
||||
@data-options: '\Grav\Common\Page\Pages::modularTypes'
|
||||
'@data-options': '\Grav\Common\Page\Pages::modularTypes'
|
||||
features:
|
||||
type: tab
|
||||
title: Features
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
title: Showcase
|
||||
@extends: default
|
||||
'@extends': default
|
||||
|
||||
form:
|
||||
fields:
|
||||
@@ -13,12 +13,12 @@ form:
|
||||
fields:
|
||||
name:
|
||||
default: modular/showcase
|
||||
@data-options: '\Grav\Common\Page\Pages::modularTypes'
|
||||
'@data-options': '\Grav\Common\Page\Pages::modularTypes'
|
||||
overrides:
|
||||
fields:
|
||||
header.template:
|
||||
default: modular/showcase
|
||||
@data-options: '\Grav\Common\Page\Pages::modularTypes'
|
||||
'@data-options': '\Grav\Common\Page\Pages::modularTypes'
|
||||
buttons:
|
||||
type: tab
|
||||
title: Buttons
|
||||
@@ -38,8 +38,9 @@ form:
|
||||
type: toggle
|
||||
label: Primary
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
1: Yes
|
||||
0: No
|
||||
1: 'Yes'
|
||||
0: 'No'
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
title: Text
|
||||
@extends: default
|
||||
'@extends': default
|
||||
|
||||
form:
|
||||
fields:
|
||||
@@ -13,12 +13,12 @@ form:
|
||||
fields:
|
||||
name:
|
||||
default: modular/text
|
||||
@data-options: '\Grav\Common\Page\Pages::modularTypes'
|
||||
'@data-options': '\Grav\Common\Page\Pages::modularTypes'
|
||||
overrides:
|
||||
fields:
|
||||
header.template:
|
||||
default: modular/text
|
||||
@data-options: '\Grav\Common\Page\Pages::modularTypes'
|
||||
'@data-options': '\Grav\Common\Page\Pages::modularTypes'
|
||||
content:
|
||||
fields:
|
||||
uploads:
|
||||
|
||||
@@ -1,98 +1,3 @@
|
||||
.text-left {
|
||||
text-align: left !important; }
|
||||
.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}.text-justify{text-align:justify !important}@media all and (min-width: 75em){.large-desktop-text-left{text-align:left !important}.large-desktop-text-right{text-align:right !important}.large-desktop-text-center{text-align:center !important}.large-desktop-text-justify{text-align:justify !important}}@media all and (min-width: 60em) and (max-width: 74.938em){.desktop-text-left{text-align:left !important}.desktop-text-right{text-align:right !important}.desktop-text-center{text-align:center !important}.desktop-text-justify{text-align:justify !important}}@media all and (min-width: 48em) and (max-width: 59.938em){.tablet-text-left{text-align:left !important}.tablet-text-right{text-align:right !important}.tablet-text-center{text-align:center !important}.tablet-text-justify{text-align:justify !important}}@media all and (min-width: 30.063em) and (max-width: 47.938em){.large-mobile-text-left{text-align:left !important}.large-mobile-text-right{text-align:right !important}.large-mobile-text-center{text-align:center !important}.large-mobile-text-justify{text-align:justify !important}}@media all and (max-width: 30em){.small-mobile-text-left{text-align:left !important}.small-mobile-text-right{text-align:right !important}.small-mobile-text-center{text-align:center !important}.small-mobile-text-justify{text-align:justify !important}}@media all and (min-width: 48em){.no-mobile-text-left{text-align:left !important}.no-mobile-text-right{text-align:right !important}.no-mobile-text-center{text-align:center !important}.no-mobile-text-justify{text-align:justify !important}}@media all and (max-width: 47.938em){.mobile-only-text-left{text-align:left !important}.mobile-only-text-right{text-align:right !important}.mobile-only-text-center{text-align:center !important}.mobile-only-text-justify{text-align:justify !important}}
|
||||
|
||||
.text-right {
|
||||
text-align: right !important; }
|
||||
|
||||
.text-center {
|
||||
text-align: center !important; }
|
||||
|
||||
.text-justify {
|
||||
text-align: justify !important; }
|
||||
|
||||
@media all and (min-width: 75em) {
|
||||
.large-desktop-text-left {
|
||||
text-align: left !important; }
|
||||
|
||||
.large-desktop-text-right {
|
||||
text-align: right !important; }
|
||||
|
||||
.large-desktop-text-center {
|
||||
text-align: center !important; }
|
||||
|
||||
.large-desktop-text-justify {
|
||||
text-align: justify !important; } }
|
||||
@media all and (min-width: 60em) and (max-width: 74.938em) {
|
||||
.desktop-text-left {
|
||||
text-align: left !important; }
|
||||
|
||||
.desktop-text-right {
|
||||
text-align: right !important; }
|
||||
|
||||
.desktop-text-center {
|
||||
text-align: center !important; }
|
||||
|
||||
.desktop-text-justify {
|
||||
text-align: justify !important; } }
|
||||
@media all and (min-width: 48em) and (max-width: 59.938em) {
|
||||
.tablet-text-left {
|
||||
text-align: left !important; }
|
||||
|
||||
.tablet-text-right {
|
||||
text-align: right !important; }
|
||||
|
||||
.tablet-text-center {
|
||||
text-align: center !important; }
|
||||
|
||||
.tablet-text-justify {
|
||||
text-align: justify !important; } }
|
||||
@media all and (min-width: 30.063em) and (max-width: 47.938em) {
|
||||
.large-mobile-text-left {
|
||||
text-align: left !important; }
|
||||
|
||||
.large-mobile-text-right {
|
||||
text-align: right !important; }
|
||||
|
||||
.large-mobile-text-center {
|
||||
text-align: center !important; }
|
||||
|
||||
.large-mobile-text-justify {
|
||||
text-align: justify !important; } }
|
||||
@media all and (max-width: 30em) {
|
||||
.small-mobile-text-left {
|
||||
text-align: left !important; }
|
||||
|
||||
.small-mobile-text-right {
|
||||
text-align: right !important; }
|
||||
|
||||
.small-mobile-text-center {
|
||||
text-align: center !important; }
|
||||
|
||||
.small-mobile-text-justify {
|
||||
text-align: justify !important; } }
|
||||
@media all and (min-width: 48em) {
|
||||
.no-mobile-text-left {
|
||||
text-align: left !important; }
|
||||
|
||||
.no-mobile-text-right {
|
||||
text-align: right !important; }
|
||||
|
||||
.no-mobile-text-center {
|
||||
text-align: center !important; }
|
||||
|
||||
.no-mobile-text-justify {
|
||||
text-align: justify !important; } }
|
||||
@media all and (max-width: 47.938em) {
|
||||
.mobile-only-text-left {
|
||||
text-align: left !important; }
|
||||
|
||||
.mobile-only-text-right {
|
||||
text-align: right !important; }
|
||||
|
||||
.mobile-only-text-center {
|
||||
text-align: center !important; }
|
||||
|
||||
.mobile-only-text-justify {
|
||||
text-align: justify !important; } }
|
||||
|
||||
/*# sourceMappingURL=particles.css.map */
|
||||
/*# sourceMappingURL=particles.css.map */
|
||||
@@ -1,7 +1,95 @@
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "AAsBC,UAAW;EACV,UAAU,EAAE,eAAe;;AAE5B,WAAY;EACX,UAAU,EAAE,gBAAgB;;AAE7B,YAAa;EACZ,UAAU,EAAE,iBAAiB;;AAE9B,aAAc;EACb,UAAU,EAAE,kBAAkB;;AAI9B,gCAA8C;EAC7C,wBAA4C;IAAE,UAAU,EAAE,eAAe;;EACzE,yBAA+C;IAAE,UAAU,EAAE,gBAAgB;;EAC7E,0BAA+C;IAAE,UAAU,EAAE,iBAAiB;;EAC9E,2BAA+C;IAAE,UAAU,EAAE,kBAAkB;AAJhF,0DAA8C;EAC7C,kBAA4C;IAAE,UAAU,EAAE,eAAe;;EACzE,mBAA+C;IAAE,UAAU,EAAE,gBAAgB;;EAC7E,oBAA+C;IAAE,UAAU,EAAE,iBAAiB;;EAC9E,qBAA+C;IAAE,UAAU,EAAE,kBAAkB;AAJhF,0DAA8C;EAC7C,iBAA4C;IAAE,UAAU,EAAE,eAAe;;EACzE,kBAA+C;IAAE,UAAU,EAAE,gBAAgB;;EAC7E,mBAA+C;IAAE,UAAU,EAAE,iBAAiB;;EAC9E,oBAA+C;IAAE,UAAU,EAAE,kBAAkB;AAJhF,8DAA8C;EAC7C,uBAA4C;IAAE,UAAU,EAAE,eAAe;;EACzE,wBAA+C;IAAE,UAAU,EAAE,gBAAgB;;EAC7E,yBAA+C;IAAE,UAAU,EAAE,iBAAiB;;EAC9E,0BAA+C;IAAE,UAAU,EAAE,kBAAkB;AAJhF,gCAA8C;EAC7C,uBAA4C;IAAE,UAAU,EAAE,eAAe;;EACzE,wBAA+C;IAAE,UAAU,EAAE,gBAAgB;;EAC7E,yBAA+C;IAAE,UAAU,EAAE,iBAAiB;;EAC9E,0BAA+C;IAAE,UAAU,EAAE,kBAAkB;AAJhF,gCAA8C;EAC7C,oBAA4C;IAAE,UAAU,EAAE,eAAe;;EACzE,qBAA+C;IAAE,UAAU,EAAE,gBAAgB;;EAC7E,sBAA+C;IAAE,UAAU,EAAE,iBAAiB;;EAC9E,uBAA+C;IAAE,UAAU,EAAE,kBAAkB;AAJhF,oCAA8C;EAC7C,sBAA4C;IAAE,UAAU,EAAE,eAAe;;EACzE,uBAA+C;IAAE,UAAU,EAAE,gBAAgB;;EAC7E,wBAA+C;IAAE,UAAU,EAAE,iBAAiB;;EAC9E,yBAA+C;IAAE,UAAU,EAAE,kBAAkB",
|
||||
"sources": ["../scss/nucleus/particles/_align-text.scss"],
|
||||
"names": [],
|
||||
"file": "particles.css"
|
||||
"version": 3,
|
||||
"file": "particles.css",
|
||||
"sources": [
|
||||
"../scss/particles.scss",
|
||||
"../scss/vendor/bourbon/_bourbon.scss",
|
||||
"../scss/vendor/bourbon/settings/_prefixer.scss",
|
||||
"../scss/vendor/bourbon/settings/_px-to-em.scss",
|
||||
"../scss/vendor/bourbon/helpers/_convert-units.scss",
|
||||
"../scss/vendor/bourbon/helpers/_gradient-positions-parser.scss",
|
||||
"../scss/vendor/bourbon/helpers/_is-num.scss",
|
||||
"../scss/vendor/bourbon/helpers/_linear-angle-parser.scss",
|
||||
"../scss/vendor/bourbon/helpers/_linear-gradient-parser.scss",
|
||||
"../scss/vendor/bourbon/helpers/_linear-positions-parser.scss",
|
||||
"../scss/vendor/bourbon/helpers/_linear-side-corner-parser.scss",
|
||||
"../scss/vendor/bourbon/helpers/_radial-arg-parser.scss",
|
||||
"../scss/vendor/bourbon/helpers/_radial-positions-parser.scss",
|
||||
"../scss/vendor/bourbon/helpers/_radial-gradient-parser.scss",
|
||||
"../scss/vendor/bourbon/helpers/_render-gradients.scss",
|
||||
"../scss/vendor/bourbon/helpers/_shape-size-stripper.scss",
|
||||
"../scss/vendor/bourbon/helpers/_str-to-num.scss",
|
||||
"../scss/vendor/bourbon/functions/_assign.scss",
|
||||
"../scss/vendor/bourbon/functions/_color-lightness.scss",
|
||||
"../scss/vendor/bourbon/functions/_flex-grid.scss",
|
||||
"../scss/vendor/bourbon/functions/_golden-ratio.scss",
|
||||
"../scss/vendor/bourbon/functions/_grid-width.scss",
|
||||
"../scss/vendor/bourbon/functions/_modular-scale.scss",
|
||||
"../scss/vendor/bourbon/functions/_px-to-em.scss",
|
||||
"../scss/vendor/bourbon/functions/_px-to-rem.scss",
|
||||
"../scss/vendor/bourbon/functions/_strip-units.scss",
|
||||
"../scss/vendor/bourbon/functions/_tint-shade.scss",
|
||||
"../scss/vendor/bourbon/functions/_transition-property-name.scss",
|
||||
"../scss/vendor/bourbon/functions/_unpack.scss",
|
||||
"../scss/vendor/bourbon/css3/_animation.scss",
|
||||
"../scss/vendor/bourbon/css3/_appearance.scss",
|
||||
"../scss/vendor/bourbon/css3/_backface-visibility.scss",
|
||||
"../scss/vendor/bourbon/css3/_background.scss",
|
||||
"../scss/vendor/bourbon/css3/_background-image.scss",
|
||||
"../scss/vendor/bourbon/css3/_border-image.scss",
|
||||
"../scss/vendor/bourbon/css3/_border-radius.scss",
|
||||
"../scss/vendor/bourbon/css3/_box-sizing.scss",
|
||||
"../scss/vendor/bourbon/css3/_calc.scss",
|
||||
"../scss/vendor/bourbon/css3/_columns.scss",
|
||||
"../scss/vendor/bourbon/css3/_filter.scss",
|
||||
"../scss/vendor/bourbon/css3/_flex-box.scss",
|
||||
"../scss/vendor/bourbon/css3/_font-face.scss",
|
||||
"../scss/vendor/bourbon/css3/_hyphens.scss",
|
||||
"../scss/vendor/bourbon/css3/_hidpi-media-query.scss",
|
||||
"../scss/vendor/bourbon/css3/_image-rendering.scss",
|
||||
"../scss/vendor/bourbon/css3/_keyframes.scss",
|
||||
"../scss/vendor/bourbon/css3/_linear-gradient.scss",
|
||||
"../scss/vendor/bourbon/css3/_perspective.scss",
|
||||
"../scss/vendor/bourbon/css3/_radial-gradient.scss",
|
||||
"../scss/vendor/bourbon/css3/_transform.scss",
|
||||
"../scss/vendor/bourbon/css3/_transition.scss",
|
||||
"../scss/vendor/bourbon/css3/_user-select.scss",
|
||||
"../scss/vendor/bourbon/css3/_placeholder.scss",
|
||||
"../scss/vendor/bourbon/addons/_button.scss",
|
||||
"../scss/vendor/bourbon/addons/_clearfix.scss",
|
||||
"../scss/vendor/bourbon/addons/_directional-values.scss",
|
||||
"../scss/vendor/bourbon/addons/_ellipsis.scss",
|
||||
"../scss/vendor/bourbon/addons/_font-family.scss",
|
||||
"../scss/vendor/bourbon/addons/_hide-text.scss",
|
||||
"../scss/vendor/bourbon/addons/_html5-input-types.scss",
|
||||
"../scss/vendor/bourbon/addons/_position.scss",
|
||||
"../scss/vendor/bourbon/addons/_prefixer.scss",
|
||||
"../scss/vendor/bourbon/addons/_retina-image.scss",
|
||||
"../scss/vendor/bourbon/addons/_size.scss",
|
||||
"../scss/vendor/bourbon/addons/_timing-functions.scss",
|
||||
"../scss/vendor/bourbon/addons/_triangle.scss",
|
||||
"../scss/vendor/bourbon/addons/_word-wrap.scss",
|
||||
"../scss/vendor/bourbon/_bourbon-deprecated-upcoming.scss",
|
||||
"../scss/configuration/nucleus/_base.scss",
|
||||
"../scss/configuration/nucleus/_core.scss",
|
||||
"../scss/configuration/nucleus/_breakpoints.scss",
|
||||
"../scss/configuration/nucleus/_layout.scss",
|
||||
"../scss/configuration/nucleus/_typography.scss",
|
||||
"../scss/configuration/nucleus/_nav.scss",
|
||||
"../scss/configuration/template/_base.scss",
|
||||
"../scss/configuration/template/_colors.scss",
|
||||
"../scss/configuration/template/_typography.scss",
|
||||
"../scss/configuration/template/_bullets.scss",
|
||||
"../scss/configuration/template/_variables.scss",
|
||||
"../scss/nucleus/functions/_base.scss",
|
||||
"../scss/nucleus/functions/_direction.scss",
|
||||
"../scss/nucleus/functions/_range.scss",
|
||||
"../scss/nucleus/mixins/_base.scss",
|
||||
"../scss/nucleus/mixins/_breakpoints.scss",
|
||||
"../scss/nucleus/mixins/_utilities.scss",
|
||||
"../scss/nucleus/particles/_align-text.scss",
|
||||
"../scss/nucleus/particles/_visibility.scss"
|
||||
],
|
||||
"mappings": "AqFsBC,AAAA,UAAU,AAAC,CACV,UAAU,CAAE,eAAgB,CAC5B,AACD,AAAA,WAAW,AAAC,CACX,UAAU,CAAE,gBAAiB,CAC7B,AACD,AAAA,YAAY,AAAC,CACZ,UAAU,CAAE,iBAAkB,CAC9B,AACD,AAAA,aAAa,AAAC,CACb,UAAU,CAAE,kBAAmB,CAC/B,AAGA,MAAM,CAAN,GAAG,MAAM,SAAS,EAAC,IAAI,EACtB,AAAA,wBAAwB,AAAxB,CAAE,UAAU,CAAE,eAAgB,CAAI,AAClC,AAAA,yBAAyB,AAAzB,CAAE,UAAU,CAAE,gBAAiB,CAAI,AACnC,AAAA,0BAA0B,AAA1B,CAAE,UAAU,CAAE,iBAAkB,CAAI,AACpC,AAAA,2BAA2B,AAA3B,CAAE,UAAU,CAAE,kBAAmB,CAAI,CAJtC,MAAM,CAAN,GAAG,MAAM,SAAS,EAAC,IAAI,OAAO,SAAS,EAAC,QAAQ,EAC/C,AAAA,kBAAkB,AAAlB,CAAE,UAAU,CAAE,eAAgB,CAAI,AAClC,AAAA,mBAAmB,AAAnB,CAAE,UAAU,CAAE,gBAAiB,CAAI,AACnC,AAAA,oBAAoB,AAApB,CAAE,UAAU,CAAE,iBAAkB,CAAI,AACpC,AAAA,qBAAqB,AAArB,CAAE,UAAU,CAAE,kBAAmB,CAAI,CAJtC,MAAM,CAAN,GAAG,MAAM,SAAS,EAAC,IAAI,OAAO,SAAS,EAAC,QAAQ,EAC/C,AAAA,iBAAiB,AAAjB,CAAE,UAAU,CAAE,eAAgB,CAAI,AAClC,AAAA,kBAAkB,AAAlB,CAAE,UAAU,CAAE,gBAAiB,CAAI,AACnC,AAAA,mBAAmB,AAAnB,CAAE,UAAU,CAAE,iBAAkB,CAAI,AACpC,AAAA,oBAAoB,AAApB,CAAE,UAAU,CAAE,kBAAmB,CAAI,CAJtC,MAAM,CAAN,GAAG,MAAM,SAAS,EAAC,QAAQ,OAAO,SAAS,EAAC,QAAQ,EACnD,AAAA,uBAAuB,AAAvB,CAAE,UAAU,CAAE,eAAgB,CAAI,AAClC,AAAA,wBAAwB,AAAxB,CAAE,UAAU,CAAE,gBAAiB,CAAI,AACnC,AAAA,yBAAyB,AAAzB,CAAE,UAAU,CAAE,iBAAkB,CAAI,AACpC,AAAA,0BAA0B,AAA1B,CAAE,UAAU,CAAE,kBAAmB,CAAI,CAJtC,MAAM,CAAN,GAAG,MAAM,SAAS,EAAC,IAAI,EACtB,AAAA,uBAAuB,AAAvB,CAAE,UAAU,CAAE,eAAgB,CAAI,AAClC,AAAA,wBAAwB,AAAxB,CAAE,UAAU,CAAE,gBAAiB,CAAI,AACnC,AAAA,yBAAyB,AAAzB,CAAE,UAAU,CAAE,iBAAkB,CAAI,AACpC,AAAA,0BAA0B,AAA1B,CAAE,UAAU,CAAE,kBAAmB,CAAI,CAJtC,MAAM,CAAN,GAAG,MAAM,SAAS,EAAC,IAAI,EACtB,AAAA,oBAAoB,AAApB,CAAE,UAAU,CAAE,eAAgB,CAAI,AAClC,AAAA,qBAAqB,AAArB,CAAE,UAAU,CAAE,gBAAiB,CAAI,AACnC,AAAA,sBAAsB,AAAtB,CAAE,UAAU,CAAE,iBAAkB,CAAI,AACpC,AAAA,uBAAuB,AAAvB,CAAE,UAAU,CAAE,kBAAmB,CAAI,CAJtC,MAAM,CAAN,GAAG,MAAM,SAAS,EAAC,QAAQ,EAC1B,AAAA,sBAAsB,AAAtB,CAAE,UAAU,CAAE,eAAgB,CAAI,AAClC,AAAA,uBAAuB,AAAvB,CAAE,UAAU,CAAE,gBAAiB,CAAI,AACnC,AAAA,wBAAwB,AAAxB,CAAE,UAAU,CAAE,iBAAkB,CAAI,AACpC,AAAA,yBAAyB,AAAzB,CAAE,UAAU,CAAE,kBAAmB,CAAI",
|
||||
"names": []
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
@import url(//fonts.googleapis.com/css?family=Montserrat:400|Raleway:300,400,600|Inconsolata);
|
||||
#header #logo h3, #header #navbar ul.navigation, #header #navbar .panel-activation, #footer p {
|
||||
#header #logo h3, #header #navbar .panel-activation, #footer p {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
-webkit-transform: translateY(-50%);
|
||||
@@ -51,7 +51,7 @@ b, strong, label, th {
|
||||
.right {
|
||||
float: right; }
|
||||
|
||||
.default-animation, #body, #header, #header #logo h3, .modular .showcase .button {
|
||||
.default-animation, #body, #header, #header #logo h3, #header #navbar ul.navigation, .modular .showcase .button {
|
||||
-webkit-transition: all 0.5s ease;
|
||||
-moz-transition: all 0.5s ease;
|
||||
transition: all 0.5s ease; }
|
||||
@@ -94,6 +94,8 @@ b, strong, label, th {
|
||||
color: #0e6e90 !important; }
|
||||
#header.scrolled #navbar a:before, #header.scrolled #navbar a:after {
|
||||
background-color: #1BB3E9 !important; }
|
||||
#header.scrolled .navigation {
|
||||
margin-top: 0.5rem !important; }
|
||||
#header > .grid, #header #logo, #header #navbar {
|
||||
height: 100%; }
|
||||
#header #logo {
|
||||
@@ -106,21 +108,49 @@ b, strong, label, th {
|
||||
#header #logo h3 a {
|
||||
color: #444; }
|
||||
#header #navbar {
|
||||
font-size: 0.9rem; }
|
||||
font-size: 0.9rem;
|
||||
/* Child Indicator */ }
|
||||
#header #navbar .has-children > a > span {
|
||||
display: inline-block;
|
||||
padding-right: 8px; }
|
||||
#header #navbar .has-children > a > span:after {
|
||||
font-family: FontAwesome;
|
||||
content: '\f107';
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
right: 8px;
|
||||
top: 4px; }
|
||||
#header #navbar .has-children > a:after, #header #navbar .has-children > a:before {
|
||||
display: none; }
|
||||
#header #navbar .has-children .has-children > a > span:after {
|
||||
content: '\f105'; }
|
||||
#header #navbar .navigation > .has-children:hover > a {
|
||||
background: #f6f6f6;
|
||||
border: 1px solid #ececec;
|
||||
border-bottom-color: #f6f6f6;
|
||||
margin: -1px -1px 0 -1px;
|
||||
z-index: 1000;
|
||||
position: relative;
|
||||
padding-bottom: 1px; }
|
||||
#header #navbar ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none; }
|
||||
#header #navbar ul.navigation {
|
||||
display: inline-block;
|
||||
float: right; }
|
||||
float: right;
|
||||
margin-top: 1.4rem; }
|
||||
#header #navbar ul.navigation li {
|
||||
float: left;
|
||||
position: relative; }
|
||||
position: relative;
|
||||
/*Active dropdown nav item */
|
||||
/* Dropdown CSS */
|
||||
/* Active on Hover */ }
|
||||
#header #navbar ul.navigation li a {
|
||||
font-family: "Montserrat", "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif;
|
||||
display: inline-block;
|
||||
padding: 0.3rem 0.8rem; }
|
||||
padding: 0.3rem 0.8rem;
|
||||
-webkit-backface-visibility: hidden; }
|
||||
#header #navbar ul.navigation li a:before, #header #navbar ul.navigation li a:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
@@ -162,29 +192,35 @@ b, strong, label, th {
|
||||
-o-transform: scaleX(0.75);
|
||||
transform: scaleX(0.75); }
|
||||
#header #navbar ul.navigation li ul {
|
||||
display: none;
|
||||
padding: 0;
|
||||
box-shadow: 0 0.05rem 1rem rgba(0, 0, 0, 0.15) !important; }
|
||||
position: absolute;
|
||||
background-color: #f6f6f6;
|
||||
border: 1px solid #ececec;
|
||||
border-top: 0;
|
||||
min-width: 12rem;
|
||||
text-align: left;
|
||||
z-index: 999;
|
||||
left: -1px;
|
||||
display: none; }
|
||||
#header #navbar ul.navigation li ul li {
|
||||
display: block;
|
||||
float: none;
|
||||
/* Active Dropdown nav item */ }
|
||||
#header #navbar ul.navigation li ul li.active > a {
|
||||
background-color: #ececec;
|
||||
color: #1BB3E9; }
|
||||
#header #navbar ul.navigation li ul li:hover > a {
|
||||
background-color: #1BB3E9;
|
||||
color: #fff; }
|
||||
#header #navbar ul.navigation li ul li a {
|
||||
display: block;
|
||||
margin: 0 -1px; }
|
||||
#header #navbar ul.navigation li ul li a:after, #header #navbar ul.navigation li ul li a:before {
|
||||
display: none; }
|
||||
#header #navbar ul.navigation li ul ul {
|
||||
left: 100%;
|
||||
top: 0; }
|
||||
top: 0px; }
|
||||
#header #navbar ul.navigation li:hover > ul {
|
||||
display: block;
|
||||
position: absolute;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
width: 10rem; }
|
||||
#header #navbar ul.navigation li:hover li {
|
||||
float: none;
|
||||
margin: 0;
|
||||
padding: 0; }
|
||||
#header #navbar ul.navigation li:hover li a {
|
||||
padding: 0.5rem 0.8rem;
|
||||
display: block; }
|
||||
#header #navbar ul.navigation li:hover li a:before, #header #navbar ul.navigation li:hover li a:after {
|
||||
display: none; }
|
||||
#header #navbar ul.navigation li:hover li.active > a {
|
||||
background: #1BB3E9;
|
||||
color: #fff; }
|
||||
display: block; }
|
||||
@media only all and (max-width: 59.938em) {
|
||||
#header #navbar ul.navigation {
|
||||
display: none; } }
|
||||
@@ -214,16 +250,14 @@ b, strong, label, th {
|
||||
.header-image #header {
|
||||
background-color: rgba(255, 255, 255, 0);
|
||||
box-shadow: none; }
|
||||
.header-image #header .navigation .has-children:hover a {
|
||||
color: #1BB3E9; }
|
||||
.header-image #header #logo h3, .header-image #header #logo a {
|
||||
color: #FFFFFF; }
|
||||
.header-image #header a, .header-image #header .menu-btn {
|
||||
color: #FFFFFF; }
|
||||
.header-image #header a:before, .header-image #header a:after {
|
||||
background-color: rgba(255, 255, 255, 0.7) !important; }
|
||||
.header-image #header #navbar ul.navigation ul li a {
|
||||
color: #1BB3E9; }
|
||||
.header-image #header #navbar ul.navigation ul li a:hover {
|
||||
color: #0e6e90; }
|
||||
|
||||
#footer {
|
||||
position: absolute;
|
||||
@@ -357,21 +391,37 @@ blockquote > blockquote > blockquote {
|
||||
border-left: 10px solid #F0AD4E;
|
||||
background: #FCF8F2;
|
||||
color: #df8a13; }
|
||||
blockquote > blockquote > blockquote > p a {
|
||||
color: #b06d0f; }
|
||||
blockquote > blockquote > blockquote > p a:hover {
|
||||
color: #f2b866; }
|
||||
blockquote > blockquote > blockquote > blockquote > p {
|
||||
margin-left: -94px;
|
||||
border-left: 10px solid #D9534F;
|
||||
background: #FDF7F7;
|
||||
color: #b52b27; }
|
||||
blockquote > blockquote > blockquote > blockquote > p a {
|
||||
color: #8b211e; }
|
||||
blockquote > blockquote > blockquote > blockquote > p a:hover {
|
||||
color: #de6764; }
|
||||
blockquote > blockquote > blockquote > blockquote > blockquote > p {
|
||||
margin-left: -118px;
|
||||
border-left: 10px solid #5BC0DE;
|
||||
background: #F4F8FA;
|
||||
color: #28a1c5; }
|
||||
blockquote > blockquote > blockquote > blockquote > blockquote > p a {
|
||||
color: #1f7e9a; }
|
||||
blockquote > blockquote > blockquote > blockquote > blockquote > p a:hover {
|
||||
color: #70c8e2; }
|
||||
blockquote > blockquote > blockquote > blockquote > blockquote > blockquote > p {
|
||||
margin-left: -142px;
|
||||
border-left: 10px solid #5CB85C;
|
||||
background: #F1F9F1;
|
||||
color: #3d8b3d; }
|
||||
blockquote > blockquote > blockquote > blockquote > blockquote > blockquote > p a {
|
||||
color: #2d672d; }
|
||||
blockquote > blockquote > blockquote > blockquote > blockquote > blockquote > p a:hover {
|
||||
color: #6ec06e; }
|
||||
|
||||
code,
|
||||
kbd,
|
||||
@@ -385,7 +435,7 @@ code {
|
||||
|
||||
pre {
|
||||
padding: 2rem;
|
||||
background: #f6f6f6;
|
||||
background: #f0f0f0;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px; }
|
||||
pre code {
|
||||
@@ -713,6 +763,11 @@ ul.pagination {
|
||||
@media only all and (max-width: 47.938em) {
|
||||
.simplesearch .search-item {
|
||||
margin-left: 0; } }
|
||||
.simplesearch .search-wrapper .search-submit {
|
||||
height: 52px;
|
||||
padding: 0 10px; }
|
||||
.simplesearch .search-wrapper .search-submit img {
|
||||
width: 30px; }
|
||||
.simplesearch .search-details {
|
||||
float: right;
|
||||
margin-top: -2.5rem;
|
||||
|
||||
|
Before Width: | Height: | Size: 248 KiB After Width: | Height: | Size: 434 KiB |
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"project":"grav-theme-antimatter",
|
||||
"platforms":{
|
||||
"grav":{
|
||||
"nodes":{
|
||||
"theme":[
|
||||
{
|
||||
"source":"/",
|
||||
"destination":"/user/themes/antimatter"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
@@ -1,2 +1,295 @@
|
||||
en:
|
||||
TRANSLATION_TEST: Antimatter!
|
||||
TRANSLATION_TEST: Antimatter!
|
||||
BLOG:
|
||||
ITEM:
|
||||
CONTINUE_READING: Continue reading...
|
||||
NEXT_POST: Next Post
|
||||
PREV_POST: Previous Post
|
||||
SIDEBAR:
|
||||
SIMPLE_SEARCH:
|
||||
HEADLINE: Search
|
||||
RELATED_POSTS:
|
||||
HEADLINE: Related Posts
|
||||
RANDOM_ARTICLE:
|
||||
HEADLINE: Random Article
|
||||
FEELING_LUCKY: I'm Feeling Lucky!
|
||||
SOME_TEXT_WIDGET:
|
||||
HEADLINE: Some Text Widget
|
||||
POPULAR_TAGS:
|
||||
HEADLINE: Popular Tags
|
||||
ARCHIVES:
|
||||
HEADLINE: Archives
|
||||
SYNDICATE:
|
||||
HEADLINE: Syndicate
|
||||
FORM_DATA:
|
||||
SUMMARY: "Here is the summary of what you wrote to us:"
|
||||
ERROR: Error
|
||||
|
||||
de:
|
||||
TRANSLATION_TEST: Antimatter!
|
||||
BLOG:
|
||||
ITEM:
|
||||
CONTINUE_READING: Weiterlesen...
|
||||
NEXT_POST: Nächster Beitrag
|
||||
PREV_POST: Vorheriger Beitrag
|
||||
SIDEBAR:
|
||||
SIMPLE_SEARCH:
|
||||
HEADLINE: SimpleSearch
|
||||
RELATED_POSTS:
|
||||
HEADLINE: Ähnliche Beiträge
|
||||
RANDOM_ARTICLE:
|
||||
HEADLINE: Zufälliger Artikel
|
||||
FEELING_LUCKY: Auf gut Glück!
|
||||
SOME_TEXT_WIDGET:
|
||||
HEADLINE: Text Widget Beispiel
|
||||
POPULAR_TAGS:
|
||||
HEADLINE: Häufigste Tags
|
||||
ARCHIVES:
|
||||
HEADLINE: Archiv
|
||||
SYNDICATE:
|
||||
HEADLINE: Abonnements
|
||||
FORM_DATA:
|
||||
SUMMARY: "Folgendes haben Sie uns mitgeteilt:"
|
||||
ERROR: Fehler
|
||||
|
||||
es:
|
||||
TRANSLATION_TEST: Antimatter!
|
||||
BLOG:
|
||||
ITEM:
|
||||
CONTINUE_READING: Continuar leyendo...
|
||||
NEXT_POST: Siguiente Entrada
|
||||
PREV_POST: Entrada Anterior
|
||||
SIDEBAR:
|
||||
SIMPLE_SEARCH:
|
||||
HEADLINE: Buscar
|
||||
RELATED_POSTS:
|
||||
HEADLINE: Entradas Relacionadas
|
||||
RANDOM_ARTICLE:
|
||||
HEADLINE: Artículo Aleatorio
|
||||
FEELING_LUCKY: Voy a tener suerte!
|
||||
SOME_TEXT_WIDGET:
|
||||
HEADLINE: Algunos Widget de Texto
|
||||
POPULAR_TAGS:
|
||||
HEADLINE: Etiquetas Populares
|
||||
ARCHIVES:
|
||||
HEADLINE: Archivos
|
||||
SYNDICATE:
|
||||
HEADLINE: Distribuir
|
||||
FORM_DATA:
|
||||
SUMMARY: "Este es un resumen de lo escrito:"
|
||||
ERROR: Error
|
||||
|
||||
fr:
|
||||
TRANSLATION_TEST: Antimatter !
|
||||
BLOG:
|
||||
ITEM:
|
||||
CONTINUE_READING: Continuer la lecture...
|
||||
NEXT_POST: Article suivant
|
||||
PREV_POST: Article précédent
|
||||
SIDEBAR:
|
||||
SIMPLE_SEARCH:
|
||||
HEADLINE: Recherche simple
|
||||
RELATED_POSTS:
|
||||
HEADLINE: Articles en relation
|
||||
RANDOM_ARTICLE:
|
||||
HEADLINE: Article aléatoire
|
||||
FEELING_LUCKY: J’ai de la chance !
|
||||
SOME_TEXT_WIDGET:
|
||||
HEADLINE: Du texte gadget
|
||||
POPULAR_TAGS:
|
||||
HEADLINE: Tags populaires
|
||||
ARCHIVES:
|
||||
HEADLINE: Archives
|
||||
SYNDICATE:
|
||||
HEADLINE: Syndication
|
||||
FORM_DATA:
|
||||
SUMMARY: "Voici le résumé de ce que vous avez écrit pour nous :"
|
||||
ERROR: Erreur
|
||||
|
||||
it:
|
||||
TRANSLATION_TEST: Antimatter!
|
||||
BLOG:
|
||||
ITEM:
|
||||
CONTINUE_READING: Continua a leggere...
|
||||
NEXT_POST: Prossimo articolo
|
||||
PREV_POST: Articolo precedente
|
||||
SIDEBAR:
|
||||
SIMPLE_SEARCH:
|
||||
HEADLINE: SimpleSearch
|
||||
RELATED_POSTS:
|
||||
HEADLINE: Articoli correlati
|
||||
RANDOM_ARTICLE:
|
||||
HEADLINE: Articolo a caso
|
||||
FEELING_LUCKY: Mi sento fortunato!
|
||||
SOME_TEXT_WIDGET:
|
||||
HEADLINE: Widget di testo
|
||||
POPULAR_TAGS:
|
||||
HEADLINE: Tag popolari
|
||||
ARCHIVES:
|
||||
HEADLINE: Archivio
|
||||
SYNDICATE:
|
||||
HEADLINE: Feed
|
||||
FORM_DATA:
|
||||
SUMMARY: "Questo è il riassunto di quanto ci hai scritto:"
|
||||
ERROR: Errore
|
||||
|
||||
ro:
|
||||
BLOG:
|
||||
ITEM:
|
||||
CONTINUE_READING: Mai multe...
|
||||
NEXT_POST: Următorul articol
|
||||
PREV_POST: Articolul anterior
|
||||
SIDEBAR:
|
||||
SIMPLE_SEARCH:
|
||||
HEADLINE: Căutare
|
||||
RELATED_POSTS:
|
||||
HEADLINE: Articole corelate
|
||||
RANDOM_ARTICLE:
|
||||
HEADLINE: Articol aleator
|
||||
FEELING_LUCKY: Mă simt norocos
|
||||
SOME_TEXT_WIDGET:
|
||||
HEADLINE: Text modular
|
||||
POPULAR_TAGS:
|
||||
HEADLINE: Etichete populare
|
||||
ARCHIVES:
|
||||
HEADLINE: Arhive
|
||||
SYNDICATE:
|
||||
HEADLINE: Abonați-vă
|
||||
FORM_DATA:
|
||||
SUMMARY: "Acesta este rezumatul mesajului Dvs:"
|
||||
ERROR: Eroare
|
||||
|
||||
ru:
|
||||
TRANSLATION_TEST: Antimatter!
|
||||
BLOG:
|
||||
ITEM:
|
||||
CONTINUE_READING: Читать далее...
|
||||
NEXT_POST: Следующая запись
|
||||
PREV_POST: Предыдущая запись
|
||||
SIDEBAR:
|
||||
SIMPLE_SEARCH:
|
||||
HEADLINE: Поиск
|
||||
RELATED_POSTS:
|
||||
HEADLINE: Также читайте
|
||||
RANDOM_ARTICLE:
|
||||
HEADLINE: Случайная запись
|
||||
FEELING_LUCKY: Мне повезёт!
|
||||
SOME_TEXT_WIDGET:
|
||||
HEADLINE: Текстовой виджет
|
||||
POPULAR_TAGS:
|
||||
HEADLINE: Популярные теги
|
||||
ARCHIVES:
|
||||
HEADLINE: Архив
|
||||
SYNDICATE:
|
||||
HEADLINE: Синдикация
|
||||
FORM_DATA:
|
||||
SUMMARY: "Вы написали нам:"
|
||||
ERROR: Ошибка
|
||||
|
||||
uk:
|
||||
TRANSLATION_TEST: Antimatter!
|
||||
BLOG:
|
||||
ITEM:
|
||||
CONTINUE_READING: Читати далі...
|
||||
NEXT_POST: Наступний запис
|
||||
PREV_POST: Попередній запис
|
||||
SIDEBAR:
|
||||
SIMPLE_SEARCH:
|
||||
HEADLINE: Пошук
|
||||
RELATED_POSTS:
|
||||
HEADLINE: Також читайте
|
||||
RANDOM_ARTICLE:
|
||||
HEADLINE: Випадковий запис
|
||||
FEELING_LUCKY: Мені пощастить!
|
||||
SOME_TEXT_WIDGET:
|
||||
HEADLINE: Текстовий віджет
|
||||
POPULAR_TAGS:
|
||||
HEADLINE: Популярні теги
|
||||
ARCHIVES:
|
||||
HEADLINE: Архів
|
||||
SYNDICATE:
|
||||
HEADLINE: Синдикація
|
||||
FORM_DATA:
|
||||
SUMMARY: "Ви написали нам:"
|
||||
ERROR: Помилка
|
||||
|
||||
hr:
|
||||
TRANSLATION_TEST: Antimatter!
|
||||
BLOG:
|
||||
ITEM:
|
||||
CONTINUE_READING: Nastavi s čitanjem...
|
||||
NEXT_POST: Slijedeća objava
|
||||
PREV_POST: Prethodna objava
|
||||
SIDEBAR:
|
||||
SIMPLE_SEARCH:
|
||||
HEADLINE: Pretraživanje
|
||||
RELATED_POSTS:
|
||||
HEADLINE: Povezane objave
|
||||
RANDOM_ARTICLE:
|
||||
HEADLINE: Slučajni članak
|
||||
FEELING_LUCKY: Osjećam se sretno!
|
||||
SOME_TEXT_WIDGET:
|
||||
HEADLINE: Neki tekst widget
|
||||
POPULAR_TAGS:
|
||||
HEADLINE: Popularni tagovi
|
||||
ARCHIVES:
|
||||
HEADLINE: Arhiva
|
||||
SYNDICATE:
|
||||
HEADLINE: Kanali
|
||||
FORM_DATA:
|
||||
SUMMARY: "Ovo je sažetak onog što ste nam napisali:"
|
||||
ERROR: Greška
|
||||
|
||||
pl:
|
||||
TRANSLATION_TEST: Antimatter!
|
||||
BLOG:
|
||||
ITEM:
|
||||
CONTINUE_READING: Czytaj dalej...
|
||||
NEXT_POST: Następny wpis
|
||||
PREV_POST: Poprzedni wpis
|
||||
SIDEBAR:
|
||||
SIMPLE_SEARCH:
|
||||
HEADLINE: Szukaj
|
||||
RELATED_POSTS:
|
||||
HEADLINE: Powiązane wpisy
|
||||
RANDOM_ARTICLE:
|
||||
HEADLINE: Losowy wpis
|
||||
FEELING_LUCKY: Szczęśliwy traf!
|
||||
SOME_TEXT_WIDGET:
|
||||
HEADLINE: Jakiś tekst - widget
|
||||
POPULAR_TAGS:
|
||||
HEADLINE: Popularne tagi
|
||||
ARCHIVES:
|
||||
HEADLINE: Archiwum
|
||||
SYNDICATE:
|
||||
HEADLINE: Feed
|
||||
FORM_DATA:
|
||||
SUMMARY: "Podsumowanie tego co do nas napisałeś:"
|
||||
ERROR: Błąd
|
||||
|
||||
pt-BR:
|
||||
TRANSLATION_TEST: Antimatter!
|
||||
BLOG:
|
||||
ITEM:
|
||||
CONTINUE_READING: Continue lendo...
|
||||
NEXT_POST: Próximo Post
|
||||
PREV_POST: Post anterior
|
||||
SIDEBAR:
|
||||
SIMPLE_SEARCH:
|
||||
HEADLINE: Buscar
|
||||
RELATED_POSTS:
|
||||
HEADLINE: Posts relacionados
|
||||
RANDOM_ARTICLE:
|
||||
HEADLINE: Artigo aleatório
|
||||
FEELING_LUCKY: Me sinto sortudo.
|
||||
SOME_TEXT_WIDGET:
|
||||
HEADLINE: Algum widget de texto
|
||||
POPULAR_TAGS:
|
||||
HEADLINE: Tags Populares
|
||||
ARCHIVES:
|
||||
HEADLINE: Arquivos
|
||||
SYNDICATE:
|
||||
HEADLINE: Feed
|
||||
FORM_DATA:
|
||||
SUMMARY: "Aqui está o resumo do que você nos escreveu:"
|
||||
ERROR: Erro
|
||||
|
||||
@@ -52,7 +52,7 @@ $rule-color: #F0F2F4;
|
||||
$code-text: #c7254e;
|
||||
$code-bg: #f9f2f4;
|
||||
$pre-text: #237794;
|
||||
$pre-bg: #f6f6f6;
|
||||
$pre-bg: #f0f0f0;
|
||||
|
||||
// Dark Contrast variation
|
||||
$dark-navbar-text: #999;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Header styling
|
||||
$dropdown-color: #f6f6f6;
|
||||
|
||||
#header {
|
||||
@extend .default-animation;
|
||||
@@ -32,6 +33,10 @@
|
||||
#navbar a:before, #navbar a:after {
|
||||
background-color: $core-accent !important;
|
||||
}
|
||||
|
||||
.navigation {
|
||||
margin-top: 0.5rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
// set heights for vertical centering
|
||||
@@ -56,6 +61,44 @@
|
||||
|
||||
#navbar {
|
||||
font-size: $core-font-size - 0.1rem;
|
||||
|
||||
/* Child Indicator */
|
||||
.has-children {
|
||||
|
||||
& > a {
|
||||
& > span {
|
||||
display: inline-block;
|
||||
padding-right: 8px;
|
||||
|
||||
&:after {
|
||||
font-family: FontAwesome;
|
||||
content: '\f107';
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
right: 8px;
|
||||
top: 4px;
|
||||
}
|
||||
}
|
||||
&:after, &:before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
& .has-children > a > span:after {
|
||||
content: '\f105';
|
||||
}
|
||||
}
|
||||
|
||||
.navigation > .has-children:hover > a {
|
||||
background: $dropdown-color;
|
||||
border: 1px solid darken($dropdown-color, 4%);
|
||||
border-bottom-color: $dropdown-color;
|
||||
margin: -1px -1px 0 -1px;
|
||||
z-index: 1000;
|
||||
position: relative;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
ul {
|
||||
|
||||
margin: 0;
|
||||
@@ -63,10 +106,12 @@
|
||||
list-style: none;
|
||||
|
||||
&.navigation {
|
||||
@extend %vertical-align;
|
||||
display: inline-block;
|
||||
|
||||
float: right;
|
||||
@extend .default-animation;
|
||||
|
||||
margin-top: 1.4rem;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
position: relative;
|
||||
@@ -76,6 +121,9 @@
|
||||
display: inline-block;
|
||||
padding: 0.3rem 0.8rem;
|
||||
|
||||
-webkit-backface-visibility: hidden;
|
||||
|
||||
|
||||
&:before, &:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
@@ -87,6 +135,7 @@
|
||||
visibility: hidden;
|
||||
@include transform(scaleX(0));
|
||||
@include transition(all 0.2s ease);
|
||||
|
||||
}
|
||||
|
||||
&:hover:before {
|
||||
@@ -109,49 +158,55 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Dropdown Menu Styles
|
||||
/*Active dropdown nav item */
|
||||
ul {
|
||||
position: absolute;
|
||||
background-color: $dropdown-color;
|
||||
border: 1px solid darken($dropdown-color, 4%);
|
||||
border-top: 0;
|
||||
min-width: 12rem;
|
||||
text-align: left;
|
||||
z-index: 999;
|
||||
left: -1px;
|
||||
display: none;
|
||||
padding: 0;
|
||||
box-shadow: 0 0.05rem 1rem rgba(0,0,0, 0.15) !important;
|
||||
}
|
||||
|
||||
ul li {
|
||||
display: block;
|
||||
float: none;
|
||||
|
||||
/* Active Dropdown nav item */
|
||||
&.active > a {
|
||||
background-color: darken($dropdown-color, 4%);
|
||||
color: $core-accent;
|
||||
}
|
||||
|
||||
&:hover > a {
|
||||
background-color: $core-accent;
|
||||
color: $white;
|
||||
}
|
||||
|
||||
a {
|
||||
display: block;
|
||||
margin: 0 -1px;
|
||||
|
||||
&:after, &:before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Dropdown CSS */
|
||||
ul ul {
|
||||
left: 100%;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
|
||||
&:hover {
|
||||
& > ul {
|
||||
display: block;
|
||||
position: absolute;
|
||||
background: rgba($white, 0.9);
|
||||
width: 10rem;
|
||||
}
|
||||
|
||||
li {
|
||||
float: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
a {
|
||||
padding: 0.5rem 0.8rem;
|
||||
display: block;
|
||||
|
||||
&:before, &:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
& > a {
|
||||
background: $core-accent;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
}
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
/* Active on Hover */
|
||||
&:hover > ul {
|
||||
display: block;
|
||||
}
|
||||
|
||||
}
|
||||
@include breakpoint(desktop-only) {
|
||||
display: none;
|
||||
@@ -207,6 +262,10 @@
|
||||
background-color: rgba($header-text,0);
|
||||
box-shadow: none;
|
||||
|
||||
.navigation .has-children:hover a {
|
||||
color: $core-accent;
|
||||
}
|
||||
|
||||
#logo h3, #logo a {
|
||||
color: $header-text;
|
||||
}
|
||||
@@ -217,15 +276,5 @@
|
||||
background-color: rgba($header-text,0.7) !important;
|
||||
}
|
||||
|
||||
#navbar ul.navigation {
|
||||
|
||||
ul li a {
|
||||
|
||||
color: $core-accent;
|
||||
&:hover {
|
||||
color: darken($core-accent, 20%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
.search-wrapper {
|
||||
.search-submit {
|
||||
height: 52px;
|
||||
padding: 0 10px;
|
||||
img {
|
||||
width: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.search-details {
|
||||
float: right;
|
||||
margin-top: -2.5rem;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
{% else %}
|
||||
<div class="blog-header">
|
||||
{% endif %}
|
||||
{{ page.content }}
|
||||
{{ page.content|raw }}
|
||||
</div>
|
||||
|
||||
{% if config.plugins.breadcrumbs.enabled %}
|
||||
@@ -18,7 +18,7 @@
|
||||
{% endif %}
|
||||
|
||||
<div class="content-wrapper blog-content-list grid pure-g">
|
||||
<div id="listing" class="block pure-u-2-3">
|
||||
<div id="listing" class="block pure-u-2-3 h-feed">
|
||||
{% for child in collection %}
|
||||
{% include 'partials/blog_item.html.twig' with {'blog':page, 'page':child, 'truncate':true} %}
|
||||
{% endfor %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends 'partials/base.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
{{ page.content }}
|
||||
{{ page.content|raw }}
|
||||
{% endblock %}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
{% block content %}
|
||||
<div id="error">
|
||||
<div>
|
||||
<h1>Error {{ page.header.http_response_code }}</h1>
|
||||
<h1>{{ 'ERROR'|t }} {{ page.header.http_response_code }}</h1>
|
||||
<p>
|
||||
{{ page.content }}
|
||||
{{ page.content|raw }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{% block content %}
|
||||
|
||||
{{ content }}
|
||||
{{ content|raw }}
|
||||
{% include "forms/form.html.twig" %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
{% endif %}
|
||||
|
||||
<div class="blog-content-item grid pure-g-r">
|
||||
<div id="item" class="block pure-u-2-3">
|
||||
<div id="item" class="block pure-u-2-3 h-entry">
|
||||
{% include 'partials/blog_item.html.twig' with {'blog':page.parent, 'truncate':false} %}
|
||||
</div>
|
||||
<div id="sidebar" class="block size-1-3 pure-u-1-3">
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
{% endfor %}
|
||||
{% for mitem in site.menu %}
|
||||
<li>
|
||||
<a href="{{ mitem.url }}">
|
||||
<a {% if mitem.class %}class="{{ mitem.class }}"{% endif %} href="{{ mitem.url }}">
|
||||
{% if mitem.icon %}<i class="fa fa-{{ mitem.icon }}"></i>{% endif %}
|
||||
{{ mitem.text }}
|
||||
</a>
|
||||
@@ -48,9 +48,9 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{{ page.content }}
|
||||
{{ page.content|raw }}
|
||||
{% for module in page.collection() %}
|
||||
<div id="{{ _self.pageLinkName(module.menu) }}"></div>
|
||||
{{ module.content }}
|
||||
{{ module.content|raw }}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="modular-row features {{ page.header.class}}">
|
||||
{{ content }}
|
||||
{{ content|raw }}
|
||||
<div class="feature-items">
|
||||
{% for feature in page.header.features %}
|
||||
<div class="feature">
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{% set showcase_image = page.media.images|first.grayscale().contrast(20).brightness(-125).colorize(-35,81,122) %}
|
||||
{% if showcase_image %}
|
||||
<div class="modular-row showcase flush-top" style="background-image: url({{ showcase_image.url }});">
|
||||
<div class="modular-row showcase{% if page == page.parent.collection.first %} flush-top{% endif %}" style="background-image: url({{ showcase_image.url }});">
|
||||
{% else %}
|
||||
<div class="modular-row showcase">
|
||||
{% endif %}
|
||||
{{ content }}
|
||||
{{ content|raw }}
|
||||
|
||||
{% for button in page.header.buttons %}
|
||||
<a class="button{% if button.primary %} primary{% endif %}" href="{{ button.url }}">{{ button.text }}</a>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="modular-row callout">
|
||||
{% set image = page.media.images|first %}
|
||||
{% if image %}
|
||||
{{ image.cropResize(400,400).html('','','align-'~page.header.image_align) }}
|
||||
{{ image.cropResize(400,400).html('','','align-'~page.header.image_align)|raw }}
|
||||
{% endif %}
|
||||
{{ content }}
|
||||
{{ content|raw }}
|
||||
</div>
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{% set theme_config = attribute(config.themes, config.system.pages.theme) %}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ grav.language.getActive ?: grav.config.site.default_lang }}">
|
||||
<head>
|
||||
{% block head %}
|
||||
<meta charset="utf-8" />
|
||||
<title>{% if header.title %}{{ header.title|e('html') }} | {% endif %}{{ site.title|e('html') }}</title>
|
||||
{% include 'partials/metadata.html.twig' %}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<link rel="icon" type="image/png" href="{{ url('theme://images/favicon.png', true) }}" />
|
||||
<link rel="icon" type="image/png" href="{{ url('theme://images/favicon.png') }}" />
|
||||
<link rel="canonical" href="{{ page.url(true, true) }}" />
|
||||
|
||||
{% block stylesheets %}
|
||||
{% do assets.addCss('theme://css/pure-0.5.0/grids-min.css', 103) %}
|
||||
{% do assets.addCss('theme://css-compiled/nucleus.css',102) %}
|
||||
{% do assets.addCss('theme://css-compiled/template.css',101) %}
|
||||
{% do assets.addCss('theme://css/custom.css',100) %}
|
||||
{% do assets.addCss('theme://css/font-awesome.min.css',100) %}
|
||||
{% do assets.addCss('theme://css-compiled/nucleus.css', 102) %}
|
||||
{% do assets.addCss('theme://css-compiled/template.css', 101) %}
|
||||
{% do assets.addCss('theme://css/custom.css', 100) %}
|
||||
{% do assets.addCss('theme://css/font-awesome.min.css', 100) %}
|
||||
{% do assets.addCss('theme://css/slidebars.min.css') %}
|
||||
|
||||
{% if browser.getBrowser == 'msie' and browser.getVersion == 10 %}
|
||||
@@ -27,17 +26,20 @@
|
||||
{% do assets.addJs('theme://js/html5shiv-printshiv.min.js') %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{{ assets.css() }}
|
||||
|
||||
{% block javascripts %}
|
||||
{% do assets.addJs('jquery',101) %}
|
||||
{% do assets.addJs('theme://js/modernizr.custom.71422.js',100) %}
|
||||
{% do assets.addJs('jquery', 101) %}
|
||||
{% do assets.addJs('theme://js/modernizr.custom.71422.js', 100) %}
|
||||
{% do assets.addJs('theme://js/antimatter.js') %}
|
||||
{% do assets.addJs('theme://js/slidebars.min.js') %}
|
||||
{% endblock %}
|
||||
{{ assets.js() }}
|
||||
|
||||
{% endblock head%}
|
||||
{% block assets deferred %}
|
||||
{{ assets.css()|raw }}
|
||||
{{ assets.js()|raw }}
|
||||
{% endblock %}
|
||||
|
||||
{% endblock head %}
|
||||
</head>
|
||||
<body id="top" class="{{ page.header.body_classes }}">
|
||||
<div id="sb-site">
|
||||
@@ -76,23 +78,25 @@
|
||||
</footer>
|
||||
{% endblock %}
|
||||
</div>
|
||||
<div class="sb-slidebar sb-left sb-width-thin">
|
||||
<div id="panel">
|
||||
{% include 'partials/navigation.html.twig' %}
|
||||
{% block sidebar_navigation %}
|
||||
<div class="sb-slidebar sb-left sb-width-thin">
|
||||
<div id="panel">
|
||||
{% include 'partials/navigation.html.twig' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block bottom %}
|
||||
|
||||
<script>
|
||||
$(function () {
|
||||
$(document).ready(function() {
|
||||
$.slidebars({
|
||||
hideControlClasses: true,
|
||||
scrollLock: true
|
||||
});
|
||||
<script>
|
||||
$(function () {
|
||||
$(document).ready(function() {
|
||||
$.slidebars({
|
||||
hideControlClasses: true,
|
||||
scrollLock: true
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
{{ assets.js('bottom')|raw }}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="list-item">
|
||||
<div class="list-item h-entry">
|
||||
|
||||
{% set header_image = page.header.header_image|defined(true) %}
|
||||
{% set header_image_width = page.header.header_image_width|defined(900) %}
|
||||
@@ -7,24 +7,26 @@
|
||||
|
||||
<div class="list-blog-header">
|
||||
<span class="list-blog-date">
|
||||
<span>{{ page.date|date("d") }}</span>
|
||||
<em>{{ page.date|date("M") }}</em>
|
||||
<time class="dt-published" datetime="{{ page.date|date("c") }}">
|
||||
<span>{{ page.date|date("d") }}</span>
|
||||
<em>{{ page.date|date("M") }}</em>
|
||||
</time>
|
||||
</span>
|
||||
{% if page.header.link %}
|
||||
<h4>
|
||||
{% if page.header.continue_link is not sameas(false) %}
|
||||
<a href="{{ page.url }}"><i class="fa fa-angle-double-right"></i></a>
|
||||
<h4 class="p-name">
|
||||
{% if page.header.continue_link is not same as(false) %}
|
||||
<a href="{{ page.url }}"><i class="fa fa-angle-double-right u-url"></i></a>
|
||||
{% endif %}
|
||||
<a href="{{ page.header.link }}">{{ page.title }}</a>
|
||||
<a href="{{ page.header.link }}" class="u-url">{{ page.title }}</a>
|
||||
</h4>
|
||||
{% else %}
|
||||
<h4><a href="{{ page.url }}">{{ page.title }}</a></h4>
|
||||
<h4 class="p-name"><a href="{{ page.url }}" class="u-url">{{ page.title }}</a></h4>
|
||||
{% endif %}
|
||||
|
||||
{% if page.taxonomy.tag %}
|
||||
<span class="tags">
|
||||
{% for tag in page.taxonomy.tag %}
|
||||
<a href="{{ blog.url }}/tag{{ config.system.param_sep }}{{ tag }}">{{ tag }}</a>
|
||||
<a href="{{ blog.url|rtrim('/') }}/tag{{ config.system.param_sep }}{{ tag }}" class="p-category">{{ tag }}</a>
|
||||
{% endfor %}
|
||||
</span>
|
||||
{% endif %}
|
||||
@@ -34,30 +36,39 @@
|
||||
{% else %}
|
||||
{% set header_image_media = page.media.images|first %}
|
||||
{% endif %}
|
||||
{{ header_image_media.cropZoom(header_image_width, header_image_height).html }}
|
||||
{{ header_image_media.cropZoom(header_image_width, header_image_height).html|raw }}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
<div class="list-blog-padding">
|
||||
|
||||
{% if page.header.continue_link is sameas(false) %}
|
||||
{{ page.content }}
|
||||
{% if page.header.continue_link is same as(false) %}
|
||||
<div class="e-content">
|
||||
{{ page.content|raw }}
|
||||
</div>
|
||||
{% if not truncate %}
|
||||
{% set show_prev_next = true %}
|
||||
{% endif %}
|
||||
{% elseif truncate and page.summary != page.content %}
|
||||
{{ page.summary }}
|
||||
<p><a href="{{ page.url }}">Continue Reading...</a></p>
|
||||
<div class="p-summary e-content">
|
||||
{{ page.summary|raw }}
|
||||
<p><a href="{{ page.url }}">{{ 'BLOG.ITEM.CONTINUE_READING'|t }}</a></p>
|
||||
</div>
|
||||
{% elseif truncate %}
|
||||
{% if page.summary != page.content %}
|
||||
{{ page.content|truncate(550) }}
|
||||
{% else %}
|
||||
{{ page.content }}
|
||||
{% endif %}
|
||||
<p><a href="{{ page.url }}">Continue Reading...</a></p>
|
||||
<div class="p-summary e-content">
|
||||
{{ page.content|raw }}
|
||||
<p><a href="{{ page.url }}">{{ 'BLOG.ITEM.CONTINUE_READING'|t }}</a></p>
|
||||
</div>
|
||||
{% else %}
|
||||
{{ page.content }}
|
||||
<div class="e-content">
|
||||
{{ page.content|raw }}
|
||||
</div>
|
||||
|
||||
{% if config.plugins.comments.enabled %}
|
||||
{% include 'partials/comments.html.twig' %}
|
||||
{% endif %}
|
||||
|
||||
{% set show_prev_next = true %}
|
||||
{% endif %}
|
||||
|
||||
@@ -65,11 +76,11 @@
|
||||
|
||||
<p class="prev-next">
|
||||
{% if not page.isFirst %}
|
||||
<a class="button" href="{{ page.nextSibling.url }}"><i class="fa fa-chevron-left"></i> Next Post</a>
|
||||
<a class="button" href="{{ page.nextSibling.url }}"><i class="fa fa-chevron-left"></i> {{ 'BLOG.ITEM.NEXT_POST'|t }}</a>
|
||||
{% endif %}
|
||||
|
||||
{% if not page.isLast %}
|
||||
<a class="button" href="{{ page.prevSibling.url }}">Previous Post <i class="fa fa-chevron-right"></i></a>
|
||||
<a class="button" href="{{ page.prevSibling.url }}">{{ 'BLOG.ITEM.PREV_POST'|t }} <i class="fa fa-chevron-right"></i></a>
|
||||
{% endif %}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,23 +1,34 @@
|
||||
{% import _self as macros %}
|
||||
|
||||
{% macro loop(page) %}
|
||||
{% import _self as macros %}
|
||||
{% for p in page.children.visible %}
|
||||
{% set current_page = (p.active or p.activeChild) ? 'active' : '' %}
|
||||
<li class="{{ current_page }}">
|
||||
<a href="{{ p.url }}">
|
||||
{% if p.header.icon %}<i class="fa fa-{{ p.header.icon }}"></i>{% endif %}
|
||||
{{ p.menu }}
|
||||
</a>
|
||||
{% if p.children.visible.count > 0 %}
|
||||
{% if p.children.visible.count > 0 %}
|
||||
<li class="has-children {{ current_page }}">
|
||||
<a href="{{ p.url }}">
|
||||
{% if p.header.icon %}<i class="fa fa-{{ p.header.icon }}"></i>{% endif %}
|
||||
{{ p.menu }}
|
||||
<span></span>
|
||||
</a>
|
||||
<ul>
|
||||
{{ _self.loop(p) }}
|
||||
{{ macros.loop(p) }}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="{{ current_page }}">
|
||||
<a href="{{ p.url }}">
|
||||
{% if p.header.icon %}<i class="fa fa-{{ p.header.icon }}"></i>{% endif %}
|
||||
{{ p.menu }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
<ul class="navigation">
|
||||
{% if theme_config.dropdown.enabled %}
|
||||
{{ _self.loop(pages) }}
|
||||
{{ macros.loop(pages) }}
|
||||
{% else %}
|
||||
{% for page in pages.children.visible %}
|
||||
{% set current_page = (page.active or page.activeChild) ? 'active' : '' %}
|
||||
|
||||
@@ -3,39 +3,39 @@
|
||||
|
||||
{% if config.plugins.simplesearch.enabled %}
|
||||
<div class="sidebar-content">
|
||||
<h4>SimpleSearch</h4>
|
||||
<h4>{{ 'SIDEBAR.SIMPLE_SEARCH.HEADLINE'|t }}</h4>
|
||||
{% include 'partials/simplesearch_searchbox.html.twig' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if config.plugins.relatedpages.enabled and related_pages|length > 0 %}
|
||||
<h4>Related Posts</h4>
|
||||
<h4>{{ 'SIDEBAR.RELATED_POSTS.HEADLINE'|t }}</h4>
|
||||
{% include 'partials/relatedpages.html.twig' %}
|
||||
{% endif %}
|
||||
{% if config.plugins.random.enabled %}
|
||||
<div class="sidebar-content">
|
||||
<h4>Random Article</h4>
|
||||
<a class="button" href="{{ base_url }}/random"><i class="fa fa-retweet"></i> I'm Feeling Lucky!</a>
|
||||
<h4>{{ 'SIDEBAR.RANDOM_ARTICLE.HEADLINE'|t }}</h4>
|
||||
<a class="button" href="{{ base_url }}/random"><i class="fa fa-retweet"></i> {{ 'SIDEBAR.RANDOM_ARTICLE.FEELING_LUCKY'|t }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="sidebar-content">
|
||||
<h4>Some Text Widget</h4>
|
||||
<h4>{{ 'SIDEBAR.SOME_TEXT_WIDGET.HEADLINE'|t }}</h4>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna.</p>
|
||||
</div>
|
||||
{% if config.plugins.taxonomylist.enabled %}
|
||||
<div class="sidebar-content">
|
||||
<h4>Popular Tags</h4>
|
||||
<h4>{{ 'SIDEBAR.POPULAR_TAGS.HEADLINE'|t }}</h4>
|
||||
{% include 'partials/taxonomylist.html.twig' with {'base_url':new_base_url, 'taxonomy':'tag'} %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if config.plugins.archives.enabled %}
|
||||
<div class="sidebar-content">
|
||||
<h4>Archives</h4>
|
||||
<h4>{{ 'SIDEBAR.ARCHIVES.HEADLINE'|t }}</h4>
|
||||
{% include 'partials/archives.html.twig' with {'base_url':new_base_url} %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if config.plugins.feed.enabled %}
|
||||
<div class="sidebar-content syndicate">
|
||||
<h4>Syndicate</h4>
|
||||
<h4>{{ 'SIDEBAR.SYNDICATE.HEADLINE'|t }}</h4>
|
||||
<a class="button" href="{{ feed_url }}.atom"><i class="fa fa-rss-square"></i> Atom 1.0</a>
|
||||
<a class="button" href="{{ feed_url }}.rss"><i class="fa fa-rss-square"></i> RSS</a>
|
||||
</div>
|
||||
|
||||
@@ -990,6 +990,9 @@ ul.pagination {
|
||||
@media (max-width: 1024px) {
|
||||
.texte-cache {
|
||||
max-height: 445px; } }
|
||||
@media (max-width: 1024px) and (max-width: 442px) {
|
||||
.texte-cache {
|
||||
max-height: 400px; } }
|
||||
|
||||
/*Style du module TEXTE lorsqu'il est ouvert*/
|
||||
.texte-cache.ouvert {
|
||||
@@ -1008,9 +1011,15 @@ ul.pagination {
|
||||
@media (max-width: 1024px) {
|
||||
.modular .features {
|
||||
width: 80% !important;
|
||||
margin-left: 8rem !important; }
|
||||
margin: auto !important; } }
|
||||
|
||||
@media (max-width: 442px) {
|
||||
.modular .features .feature {
|
||||
width: 24% !important; } }
|
||||
width: 80%; } }
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.modular .features .feature {
|
||||
width: 24%; } }
|
||||
|
||||
.bouton-ouverture {
|
||||
position: relative;
|
||||
@@ -1120,10 +1129,10 @@ ul.pagination {
|
||||
padding-left: 0.8rem;
|
||||
font-size: 0.75rem;
|
||||
padding-right: 0.6rem; } }
|
||||
.mozaique_personnes .equipe .personne .mozaique:hover {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
transition: 0.2s ease-in-out; }
|
||||
.mozaique_personnes .equipe .personne .mozaique .info:hover {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
transition: 0.2s ease-in-out; }
|
||||
|
||||
.bouton {
|
||||
border: solid !important;
|
||||
@@ -1450,7 +1459,3 @@ button:focus {
|
||||
|
||||
.modular .modular-row:last-child {
|
||||
margin-bottom: 2rem; }
|
||||
|
||||
@media (max-width: 442px) {
|
||||
h1 {
|
||||
font-size: 1.5rem; } }
|
||||
|
||||
@@ -359,6 +359,9 @@
|
||||
transition: max-height 1s ease; /* Transition CSS entre l'ouverture et la fermeture*/
|
||||
@media (max-width: 1024px) {
|
||||
max-height: 445px;
|
||||
@media (max-width:442px) {
|
||||
max-height: 400px;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -381,20 +384,22 @@
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.modular .features {
|
||||
|
||||
width: 80% !important;
|
||||
margin-left: 8rem !important;
|
||||
}
|
||||
.modular .features .feature {
|
||||
width: 24% !important;
|
||||
// margin-bottom: 10rem;
|
||||
.modular .features {
|
||||
@media (max-width: 1024px) {
|
||||
width: 80% !important;
|
||||
margin: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
.modular .features .feature {
|
||||
// margin-bottom: 10rem;
|
||||
@media (max-width: 442px) {width: 80% ;}
|
||||
@media (max-width: 1024px) {width: 24% ;}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.bouton-ouverture {
|
||||
position: relative;
|
||||
justify-content: center;
|
||||
@@ -543,14 +548,16 @@
|
||||
font-size: 0.75rem;
|
||||
padding-right: 0.6rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
transition:0.2s ease-in-out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
transition:0.2s ease-in-out;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||