This commit is contained in:
2021-05-12 12:05:01 +02:00
parent ec6c71798f
commit ffb5dbdaae
104 changed files with 6733 additions and 3490 deletions
+52
View File
@@ -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
+129 -45
View File
@@ -1,66 +1,150 @@
# ![](https://avatars1.githubusercontent.com/u/8237355?v=2&s=50) Grav
#Installation site GIP EPAU
[![PHPStan](https://img.shields.io/badge/PHPStan-enabled-brightgreen.svg?style=flat)](https://github.com/phpstan/phpstan)
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad/mini.png)](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad)
[![Discord](https://img.shields.io/discord/501836936584101899.svg?logo=discord&colorB=728ADA&label=Discord%20Chat)](https://chat.getgrav.org)
[![PHP Tests](https://github.com/getgrav/grav/workflows/PHP%20Tests/badge.svg?branch=develop)](https://github.com/getgrav/grav/actions?query=workflow%3A%22PHP+Tests%22) [![OpenCollective](https://opencollective.com/grav/backers/badge.svg)](#backers) [![OpenCollective](https://opencollective.com/grav/sponsors/badge.svg)](#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 ladmin
```
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
+3 -17
View File
@@ -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"
Generated
+125 -113
View File
@@ -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": {
+1
View File
@@ -18,6 +18,7 @@ config:
configure:
path: '/accounts/configure'
redirects:
'/groups': '/accounts/groups'
'/accounts': '/accounts/groups'
# Permissions
+1 -1
View File
@@ -121,7 +121,7 @@ form:
underline: true
folder:
type: text
type: folder-slug
label: PLUGIN_ADMIN.FOLDER_NAME
validate:
rule: slug
+2
View File
@@ -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)
+28 -17
View File
@@ -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, '://')) {
+2 -1
View File
@@ -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;
+1 -1
View File
@@ -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.');
}
+4 -1
View File
@@ -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;
}
}
+1 -1
View File
@@ -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());
}
/**
+1 -1
View File
@@ -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.
+1 -1
View File
@@ -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));
}
}
File diff suppressed because it is too large Load Diff
@@ -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);
}
}
+48 -16
View File
@@ -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),
File diff suppressed because it is too large Load Diff
+309 -72
View File
@@ -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 = '&hellip;')
@@ -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);
}
+1 -1
View File
@@ -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'])) {
+24 -7
View File
@@ -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.
+3
View File
@@ -0,0 +1,3 @@
enabled: true
dropdown:
enabled: true
+1 -1
View File
@@ -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 leau, de la conception des ouvrages et des opérations damé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 daménagement.\r\n \r\n "
texte_de_presentation: "Le programme de recherche-action Coubertin construit le récit, au fil de leau, de la conception des ouvrages et des opérations damé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 damé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
Binary file not shown.

After

Width:  |  Height:  |  Size: 790 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 970 KiB

+10 -25
View File
@@ -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 dactivité présente les principales actions réalisées par les programmes Europan, POPSU et Coubertin à loccasion de lanné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 dorientation présente la stratégie de lEurope 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:
Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 MiB

@@ -11,22 +11,22 @@ personnes:
-
nom: 'Catherine Chevillot'
fonction: 'Présidente de la Cité de lArchitecture 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 dOrsay (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 dOrsay, où elle a créé le Prix du musée dOrsay (2003), conservateur en chef au musée dOrsay (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 larchitecture & 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 larchitecture, 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 larchitecture. 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 laménagement, lurbanisme 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 laménagement d’Île-de-France de 2007 à 2009, puis directrice adjointe en charge de la stratégie opérationnelle à la direction de limmobilier 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 lurbanisme au cabinet du maire de Paris en 2013, avant de prendre la direction du service de laménagement à la direction de lurbanisme de 2015 à 2017. Depuis juillet 2017, elle était directrice générale adjointe en charge de lamé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 larchitecture. 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 laménagement, lurbanisme et la construction publique. \nCheffe de la mission immobilière auprès du directeur régional et interdépartementale de l’écologie et de laménagement d’Île-de-France de 2007 à 2009, puis directrice adjointe en charge de la stratégie opérationnelle à la direction de limmobilier 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 lurbanisme au cabinet du maire de Paris en 2013, avant de prendre la direction du service de laménagement à la direction de lurbanisme de 2015 à 2017. Depuis juillet 2017, elle était directrice générale adjointe en charge de laménagement au sein de Grand Paris Aménagement."
portrait: aurelie-cousi-nommee-aux-fonctions-de-directrice.jpg
-
nom: 'Alain Maugard'
fonction: 'Président de lAssociation 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 lUrbanisme 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 daménagement de la Défense (epad), jusquen 1993 où il prend la présidence du cstb. Il quitte ces fonctions en 2008 pour rejoindre le Conseil général de lenvironnement 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 dadministration de lAdeme. Il a également piloté le Comité opérationnel (comop) du chantier n°1 « Bâtiments neufs publics et privés » du Grenelle de lEnvironnement. \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 lUrbanisme 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 daménagement de la Défense (epad), jusquen 1993 où il prend la présidence du cstb. Il quitte ces fonctions en 2008 pour rejoindre le Conseil général de lenvironnement 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 dadministration de lAdeme. Il a également piloté le Comité opérationnel (comop) du chantier n°1 « Bâtiments neufs publics et privés » du Grenelle de lEnvironnement. "
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 dinté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 lEcole nationale supérieure darchitecture de Versailles et de lEcole 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 lEcole nationale supérieure darchitecture de Versailles et de lEcole 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 lEPAU, 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
---
Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

@@ -5,24 +5,24 @@ personnes:
-
nom: 'Isabelle Moulin'
fonction: 'Secrétaire générale de lAssociation 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
---
+3 -2
View File
@@ -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
---
![logo_gouvernment](logo_gouvernment.png "logo_gouvernment") ![logo%20MCTRCT](logo%20MCTRCT.png "logo%20MCTRCT") ![logo%20minist%C3%A8re%20culture](logo%20minist%C3%A8re%20culture.png "logo%20minist%C3%A8re%20culture") ![logo%20min%20logement](logo%20min%20logement.png "logo%20min%20logement") ![europan_france](europan_france.jpg "europan_france") ![puca](puca.png "puca") ![logo%20cit%C3%A9%20archi](logo%20cit%C3%A9%20archi.jpg "logo%20cit%C3%A9%20archi")
![logo_gouvernment](logo_gouvernment.png "logo_gouvernment")![logo%20MCTRCT](logo%20MCTRCT.png "logo%20MCTRCT")![logo%20minist%C3%A8re%20culture](logo%20minist%C3%A8re%20culture.png "logo%20minist%C3%A8re%20culture") ![logo%20min%20logement](logo%20min%20logement.png "logo%20min%20logement")![europan_france](europan_france.jpg "europan_france") ![puca](puca.png "puca")![logo%20cit%C3%A9%20archi](logo%20cit%C3%A9%20archi.jpg "logo%20cit%C3%A9%20archi")
+2
View File
@@ -0,0 +1,2 @@
.sass-cache
.DS_Store
+81 -1
View File
@@ -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
-7
View File
@@ -1,10 +1,3 @@
enabled: true
dropdown:
enabled: false
streams:
schemes:
theme:
type: ReadOnlyStream
paths:
- user/themes/antimatter
+6 -3
View File
@@ -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
+20 -7
View File
@@ -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 -1
View File
@@ -1,2 +1,2 @@
title: Nopad
@extends: default
'@extends': default
+5 -5
View File
@@ -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:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -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;
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 248 KiB

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.
+15
View File
@@ -0,0 +1,15 @@
{
"project":"grav-theme-antimatter",
"platforms":{
"grav":{
"nodes":{
"theme":[
{
"source":"/",
"destination":"/user/themes/antimatter"
}
]
}
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

+294 -1
View File
@@ -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: Jai 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;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More