Allow Flex Pages to be initialized separately in site and admin, remove Flex Objects plugin dependency

This commit is contained in:
Matias Griese 2019-10-09 15:24:26 +03:00
parent 41851b73b9
commit 9beefb3162
5 changed files with 214 additions and 36 deletions

View File

@ -2,7 +2,7 @@
## mm/dd/2019
1. [](#new)
* Added Flex Pages classes
* Added Flex Pages to Grav core and removed Flex Objects plugin dependency
1. [](#bugfix)
* Fixed `Page::untranslatedLanguages()` not being symmetrical to `Page::translatedLanguages()`
* Fixed `Flex Pages` not calling `onPageProcessed` event when cached

View File

@ -0,0 +1,123 @@
title: Flex Pages
description: Manage your Grav Pages in Flex.
type: flex-objects
extends@:
type: default
context: blueprints://pages
config:
admin:
menu:
list:
route: '/pages'
title: PLUGIN_ADMIN.PAGES
icon: fa-file-text
authorize: ['admin.pages', 'admin.super']
priority: 5
template: grav-pages
list:
fields:
published:
width: 8
alias: header.published
visible:
width: 8
field:
label: Visible
type: toggle
menu:
link: edit
alias: header.menu
full_route:
field:
label: Route
type: text
link: edit
sort:
field: key
name:
width: 8
field:
label: Type
type: text
translations:
width: 8
field:
label: Translations
type: text
# updated_date:
# alias: header.update_date
options:
per_page: 20
order:
by: key
dir: asc
# TODO: not used yet
buttons:
back:
icon: reply
title: PLUGIN_ADMIN.BACK
add:
icon: plus
label: PLUGIN_ADMIN.ADD
edit:
# TODO: not used yet
buttons:
back:
icon: reply
title: PLUGIN_ADMIN.BACK
preview:
icon: eye
title: PLUGIN_ADMIN.PREVIEW
add:
icon: plus
label: PLUGIN_ADMIN.ADD
copy:
icon: copy
label: PLUGIN_ADMIN.COPY
move:
icon: arrows
label: PLUGIN_ADMIN.MOVE
delete:
icon: close
label: PLUGIN_ADMIN.DELETE
save:
icon: check
label: PLUGIN_ADMIN.SAVE
site:
filter:
- withPublished
data:
object: 'Grav\Common\Page\Flex\PageObject'
collection: 'Grav\Common\Page\Flex\PageCollection'
index: 'Grav\Common\Page\Flex\PageIndex'
storage:
class: 'Grav\Common\Page\Flex\PageStorage'
options:
formatter:
class: 'Grav\Framework\File\Formatter\MarkdownFormatter'
folder: 'page://'
ordering:
key: ASC
search:
options:
contains: 1
fields:
- key
- menu
- title
- name
form:
fields:
lang:
type: hidden
value: ''

View File

@ -27,6 +27,7 @@ use Grav\Framework\Flex\FlexDirectory;
use Grav\Framework\Flex\Interfaces\FlexObjectInterface;
use Grav\Plugin\Admin;
use RocketTheme\Toolbox\Event\Event;
use RocketTheme\Toolbox\Event\EventDispatcher;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
use Whoops\Exception\ErrorException;
use Collator;
@ -36,8 +37,8 @@ class Pages
/** @var Grav */
protected $grav;
/** @var Flex */
protected $flex;
/** @var FlexDirectory */
private $directory;
/** @var array|PageInterface[] */
protected $instances;
@ -92,11 +93,16 @@ class Pages
/**
* Constructor
*
* @param Grav $c
* @param Grav $grav
*/
public function __construct(Grav $c)
public function __construct(Grav $grav)
{
$this->grav = $c;
$this->grav = $grav;
$type = $grav['config']->get('system.pages.type');
if ($type === 'flex') {
$this->initFlexPages();
}
}
/**
@ -253,9 +259,6 @@ class Pages
$this->ignore_files = $config->get('system.pages.ignore_files');
$this->ignore_folders = $config->get('system.pages.ignore_folders');
$this->ignore_hidden = $config->get('system.pages.ignore_hidden');
if ($config->get('system.pages.type') === 'flex') {
$this->flex = $this->grav['flex_objects'] ?? null;
}
$this->instances = [];
$this->children = [];
@ -291,14 +294,14 @@ class Pages
*/
public function instances()
{
if (!$this->flex) {
if (!$this->directory) {
return $this->instances;
}
$list = [];
foreach ($this->instances as $path => $instance) {
if (!$instance instanceof PageInterface) {
$instance = $this->flex->getObject($instance);
$instance = $this->directory->getObject($instance, 'flex_key');
}
$list[$path] = $instance;
}
@ -701,7 +704,7 @@ class Pages
{
$instance = $this->instances[(string)$path] ?? null;
if (\is_string($instance)) {
$instance = $this->flex ? $this->flex->getObject($instance) : null;
$instance = $this->directory ? $this->directory->getObject($instance, 'flex_key') : null;
if (method_exists($instance, 'initialize') && $this->grav['config']->get('system.pages.events.page')) {
$instance->initialize();
}
@ -1169,7 +1172,7 @@ class Pages
{
$accessLevels = [];
foreach ($this->all() as $page) {
if (isset($page->header()->access)) {
if (isset($page, $page->header()->access)) {
if (\is_array($page->header()->access)) {
foreach ($page->header()->access as $index => $accessLevel) {
if (\is_array($accessLevel)) {
@ -1201,8 +1204,6 @@ class Pages
return self::getParents($rawRoutes);
}
/**
* Gets the home route
*
@ -1255,6 +1256,60 @@ class Pages
return self::getHomeRoute();
}
protected function initFlexPages(): void
{
/** @var Debugger $debugger */
$debugger = $this->grav['debugger'];
$debugger->addMessage('Pages: Flex Directory');
/** @var Config $config */
$config = $this->grav['config'];
$options = [
'enabled' => true,
] + ($config->get('plugins.flex-objects.object') ?: []);
$directory = new FlexDirectory('pages', 'blueprints://flex/pages.yaml', $options);
/** @var EventDispatcher $dispatcher */
$dispatcher = $this->grav['events'];
$dispatcher->addListener(
'onFlexInit',
static function (Event $event) use ($directory)
{
/** @var Flex $flex */
$flex = $event['flex'];
$flex->addDirectory($directory);
}
);
// Stop /admin/pages from working, display error instead.
$dispatcher->addListener(
'onAdminPage',
static function (Event $event) use ($directory) {
$grav = Grav::instance();
[,$location,] = $grav['admin']->getRouteDetails();
if ($location !== 'pages') {
return;
}
$event->stopPropagation();
/** @var PageInterface $page */
$page = $event['page'];
$page->init(new \SplFileInfo('plugin://admin/pages/admin/error.md'));
$page->routable(true);
$page->content('## Please install **Flex Objects** plugin. It is required to edit **Flex Pages**.');
$header = $page->header();
$menu = $directory->getConfig('admin.menu.list');
$header->access = $menu['authorize'] ?? ['admin.pages', 'admin.super'];
},
100000);
$this->directory = $directory;
}
/**
* Builds pages.
*
@ -1273,21 +1328,21 @@ class Pages
$debugger = $this->grav['debugger'];
$debugger->startTimer('build-pages', 'Init frontend routes');
$directory = $this->flex ? $this->flex->getDirectory('grav-pages') : null;
if ($directory) {
$this->buildFlexPages($directory);
if ($this->directory) {
$this->buildFlexPages();
} else {
$this->buildRegularPages();
}
$debugger->stopTimer('build-pages');
}
protected function buildFlexPages(FlexDirectory $directory)
protected function buildFlexPages()
{
/** @var Config $config */
$config = $this->grav['config'];
$directory = $this->directory;
// TODO: right now we are just emulating normal pages, it is inefficient and bad... but works!
$collection = $directory->getIndex();
$cache = $directory->getCache('index');
@ -1874,7 +1929,7 @@ class Pages
protected function getVersion()
{
return $this->flex ? 'flex' : 'page';
return $this->directory ? 'flex' : 'page';
}
/**

View File

@ -23,6 +23,8 @@ class PluginsProcessor extends ProcessorBase
$this->startTimer();
// TODO: remove in 2.0.
$this->container['accounts'];
// TODO: remove in 2.0.
$this->container['pages'];
$this->container['plugins']->init();
$this->container->fireEvent('onPluginsInitialized');
$this->stopTimer();

View File

@ -22,21 +22,19 @@ class PagesServiceProvider implements ServiceProviderInterface
{
public function register(Container $container)
{
$container['pages'] = function ($c) {
return new Pages($c);
$container['pages'] = function (Grav $grav) {
return new Pages($grav);
};
$container['page'] = function ($c) {
/** @var Grav $c */
$container['page'] = static function (Grav $grav) {
/** @var Pages $pages */
$pages = $c['pages'];
$pages = $grav['pages'];
/** @var Config $config */
$config = $c['config'];
$config = $grav['config'];
/** @var Uri $uri */
$uri = $c['uri'];
$uri = $grav['uri'];
$path = $uri->path() ?: '/'; // Don't trim to support trailing slash default routes
$page = $pages->dispatch($path);
@ -45,13 +43,13 @@ class PagesServiceProvider implements ServiceProviderInterface
if ($page) {
// some debugger override logic
if ($page->debugger() === false) {
$c['debugger']->enabled(false);
$grav['debugger']->enabled(false);
}
if ($config->get('system.force_ssl')) {
if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {
$url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$c->redirect($url);
$grav->redirect($url);
}
}
@ -72,15 +70,15 @@ class PagesServiceProvider implements ServiceProviderInterface
}
/** @var Language $language */
$language = $c['language'];
$language = $grav['language'];
// Language-specific redirection scenarios
if ($language->enabled() && ($language->isLanguageInUrl() xor $language->isIncludeDefaultLanguage())) {
$c->redirect($url);
$grav->redirect($url);
}
// Default route test and redirect
if ($config->get('system.pages.redirect_default_route') && $page->route() !== $path) {
$c->redirect($url);
$grav->redirect($url);
}
}
@ -88,10 +86,10 @@ class PagesServiceProvider implements ServiceProviderInterface
if (!$page || !$page->routable()) {
// Try fallback URL stuff...
$page = $c->fallbackUrl($path);
$page = $grav->fallbackUrl($path);
if (!$page) {
$path = $c['locator']->findResource('system://pages/notfound.md');
$path = $grav['locator']->findResource('system://pages/notfound.md');
$page = new Page();
$page->init(new \SplFileInfo($path));
$page->routable(false);