mirror of
https://github.com/getgrav/grav.git
synced 2026-07-04 13:59:12 +02:00
Added full blueprint support and Theme::getFormFieldTypes() just like in plugins
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
|
||||
1. [](#new)
|
||||
* Added `ControllerResponseTrait::createDownloadResponse()` method
|
||||
* Added full blueprint support to theme if you move existing files in `blueprints/` to `blueprints/pages/` folder [#3255](https://github.com/getgrav/grav/issues/3255)
|
||||
* Added support for `Theme::getFormFieldTypes()` just like in plugins
|
||||
1. [](#improved)
|
||||
* Optimized `Flex Pages` for speed
|
||||
* Optimized saving visible/ordered pages when there are a lot of siblings [#3231](https://github.com/getgrav/grav/issues/3231)
|
||||
|
||||
@@ -1174,7 +1174,14 @@ class Pages
|
||||
$event->types = $types;
|
||||
$grav->fireEvent('onGetPageBlueprints', $event);
|
||||
|
||||
$types->scanBlueprints('theme://blueprints/');
|
||||
$types->init();
|
||||
|
||||
// Try new location first.
|
||||
$lookup = 'theme://blueprints/pages/';
|
||||
if (!is_dir($lookup)) {
|
||||
$lookup = 'theme://blueprints/';
|
||||
}
|
||||
$types->scanBlueprints($lookup);
|
||||
|
||||
// Scan templates
|
||||
$event = new Event();
|
||||
|
||||
@@ -32,22 +32,23 @@ class Types implements \ArrayAccess, \Iterator, \Countable
|
||||
/** @var array */
|
||||
protected $items;
|
||||
/** @var array */
|
||||
protected $systemBlueprints;
|
||||
protected $systemBlueprints = [];
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param Blueprint|null $blueprint
|
||||
* @return void
|
||||
*/
|
||||
public function register($type, $blueprint = null)
|
||||
{
|
||||
if (!isset($this->items[$type])) {
|
||||
$this->items[$type] = [];
|
||||
} elseif (!$blueprint) {
|
||||
} elseif (null === $blueprint) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$blueprint && $this->systemBlueprints) {
|
||||
$blueprint = $this->systemBlueprints[$type] ?? $this->systemBlueprints['default'];
|
||||
if (null === $blueprint) {
|
||||
$blueprint = $this->systemBlueprints[$type] ?? $this->systemBlueprints['default'] ?? null;
|
||||
}
|
||||
|
||||
if ($blueprint) {
|
||||
@@ -55,8 +56,23 @@ class Types implements \ArrayAccess, \Iterator, \Countable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if (null === $this->systemBlueprints) {
|
||||
// Register all blueprints from the blueprints stream.
|
||||
$this->systemBlueprints = $this->findBlueprints('blueprints://pages');
|
||||
foreach ($this->systemBlueprints as $type => $blueprint) {
|
||||
$this->register($type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @return void
|
||||
*/
|
||||
public function scanBlueprints($uri)
|
||||
{
|
||||
@@ -64,15 +80,6 @@ class Types implements \ArrayAccess, \Iterator, \Countable
|
||||
throw new InvalidArgumentException('First parameter must be URI');
|
||||
}
|
||||
|
||||
if (null === $this->systemBlueprints) {
|
||||
$this->systemBlueprints = $this->findBlueprints('blueprints://pages');
|
||||
|
||||
// Register default by default.
|
||||
$this->register('default');
|
||||
|
||||
$this->register('external');
|
||||
}
|
||||
|
||||
foreach ($this->findBlueprints($uri) as $type => $blueprint) {
|
||||
$this->register($type, $blueprint);
|
||||
}
|
||||
@@ -80,6 +87,7 @@ class Types implements \ArrayAccess, \Iterator, \Countable
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @return void
|
||||
*/
|
||||
public function scanTemplates($uri)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Config\Config;
|
||||
use LogicException;
|
||||
use RocketTheme\Toolbox\File\YamlFile;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use function defined;
|
||||
@@ -35,11 +36,11 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
|
||||
/** @var Grav */
|
||||
protected $grav;
|
||||
/** @var Config */
|
||||
/** @var Config|null */
|
||||
protected $config;
|
||||
/** @var bool */
|
||||
protected $active = true;
|
||||
/** @var Blueprint */
|
||||
/** @var Blueprint|null */
|
||||
protected $blueprint;
|
||||
|
||||
/**
|
||||
@@ -127,21 +128,25 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
*/
|
||||
protected function isPluginActiveAdmin($plugin_route)
|
||||
{
|
||||
$should_run = false;
|
||||
$active = false;
|
||||
|
||||
/** @var Uri $uri */
|
||||
$uri = $this->grav['uri'];
|
||||
/** @var Config $config */
|
||||
$config = $this->config ?? $this->grav['config'];
|
||||
|
||||
if (strpos($uri->path(), $this->config->get('plugins.admin.route') . '/' . $plugin_route) === false) {
|
||||
$should_run = false;
|
||||
if (strpos($uri->path(), $config->get('plugins.admin.route') . '/' . $plugin_route) === false) {
|
||||
$active = false;
|
||||
} elseif (isset($uri->paths()[1]) && $uri->paths()[1] === $plugin_route) {
|
||||
$should_run = true;
|
||||
$active = true;
|
||||
}
|
||||
|
||||
return $should_run;
|
||||
return $active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $events
|
||||
* @return void
|
||||
*/
|
||||
protected function enable(array $events)
|
||||
{
|
||||
@@ -164,22 +169,18 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
/**
|
||||
* @param array $params
|
||||
* @param string $eventName
|
||||
* @return int
|
||||
*/
|
||||
private function getPriority($params, $eventName)
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
$override = implode('.', ['priorities', $this->name, $eventName, $params[0]]);
|
||||
if ($grav['config']->get($override) !== null) {
|
||||
return $grav['config']->get($override);
|
||||
}
|
||||
if (isset($params[1])) {
|
||||
return $params[1];
|
||||
}
|
||||
return 0;
|
||||
|
||||
return $this->grav['config']->get($override) ?? $params[1] ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $events
|
||||
* @return void
|
||||
*/
|
||||
protected function disable(array $events)
|
||||
{
|
||||
@@ -207,12 +208,13 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
$this->loadBlueprint();
|
||||
|
||||
if ($offset === 'title') {
|
||||
$offset = 'name';
|
||||
}
|
||||
return isset($this->blueprint[$offset]);
|
||||
|
||||
$blueprint = $this->getBlueprint();
|
||||
|
||||
return isset($blueprint[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,12 +225,13 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
$this->loadBlueprint();
|
||||
|
||||
if ($offset === 'title') {
|
||||
$offset = 'name';
|
||||
}
|
||||
return $this->blueprint[$offset] ?? null;
|
||||
|
||||
$blueprint = $this->getBlueprint();
|
||||
|
||||
return $blueprint[$offset] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,9 +284,12 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
*/
|
||||
protected function parseLinks($content, $function, $internal_regex = '(.*)')
|
||||
{
|
||||
$regex = '/\[plugin:(?:' . $this->name . ')\]\(' . $internal_regex . '\)/i';
|
||||
$regex = '/\[plugin:(?:' . preg_quote($this->name, '/') . ')\]\(' . $internal_regex . '\)/i';
|
||||
|
||||
return preg_replace_callback($regex, $function, $content);
|
||||
$result = preg_replace_callback($regex, $function, $content);
|
||||
\assert($result !== null);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,9 +307,12 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
*/
|
||||
protected function mergeConfig(PageInterface $page, $deep = false, $params = [], $type = 'plugins')
|
||||
{
|
||||
/** @var Config $config */
|
||||
$config = $this->config ?? $this->grav['config'];
|
||||
|
||||
$class_name = $this->name;
|
||||
$class_name_merged = $class_name . '.merged';
|
||||
$defaults = $this->config->get($type . '.' . $class_name, []);
|
||||
$defaults = $config->get($type . '.' . $class_name, []);
|
||||
$page_header = $page->header();
|
||||
$header = [];
|
||||
|
||||
@@ -356,23 +365,26 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
/**
|
||||
* Persists to disk the plugin parameters currently stored in the Grav Config object
|
||||
*
|
||||
* @param string $plugin_name The name of the plugin whose config it should store.
|
||||
*
|
||||
* @param string $name The name of the plugin whose config it should store.
|
||||
* @return bool
|
||||
*/
|
||||
public static function saveConfig($plugin_name)
|
||||
public static function saveConfig($name)
|
||||
{
|
||||
if (!$plugin_name) {
|
||||
if (!$name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $grav['locator'];
|
||||
$filename = 'config://plugins/' . $plugin_name . '.yaml';
|
||||
$file = YamlFile::instance($locator->findResource($filename, true, true));
|
||||
$content = $grav['config']->get('plugins.' . $plugin_name);
|
||||
|
||||
$filename = 'config://plugins/' . $name . '.yaml';
|
||||
$file = YamlFile::instance((string)$locator->findResource($filename, true, true));
|
||||
$content = $grav['config']->get('plugins.' . $name);
|
||||
$file->save($content);
|
||||
$file->free();
|
||||
unset($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -384,21 +396,28 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
*/
|
||||
public function getBlueprint()
|
||||
{
|
||||
if (!$this->blueprint) {
|
||||
if (null === $this->blueprint) {
|
||||
$this->loadBlueprint();
|
||||
\assert($this->blueprint instanceof Blueprint);
|
||||
}
|
||||
|
||||
return $this->blueprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load blueprints.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function loadBlueprint()
|
||||
{
|
||||
if (!$this->blueprint) {
|
||||
if (null === $this->blueprint) {
|
||||
$grav = Grav::instance();
|
||||
/** @var Plugins $plugins */
|
||||
$plugins = $grav['plugins'];
|
||||
$this->blueprint = $plugins->get($this->name)->blueprints();
|
||||
$data = $plugins->get($this->name);
|
||||
\assert($data !== null);
|
||||
$this->blueprint = $data->blueprints();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ use Grav\Common\File\CompiledYamlFile;
|
||||
use Grav\Events\PluginsLoadedEvent;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
use RuntimeException;
|
||||
use SplFileInfo;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use function get_class;
|
||||
use function is_object;
|
||||
@@ -27,7 +28,7 @@ use function is_object;
|
||||
*/
|
||||
class Plugins extends Iterator
|
||||
{
|
||||
/** @var array */
|
||||
/** @var array|null */
|
||||
public $formFieldTypes;
|
||||
|
||||
/** @var bool */
|
||||
@@ -46,6 +47,7 @@ class Plugins extends Iterator
|
||||
$iterator = $locator->getIterator('plugins://');
|
||||
|
||||
$plugins = [];
|
||||
/** @var SplFileInfo $directory */
|
||||
foreach ($iterator as $directory) {
|
||||
if (!$directory->isDir()) {
|
||||
continue;
|
||||
@@ -56,7 +58,10 @@ class Plugins extends Iterator
|
||||
sort($plugins, SORT_NATURAL | SORT_FLAG_CASE);
|
||||
|
||||
foreach ($plugins as $plugin) {
|
||||
$this->add($this->loadPlugin($plugin));
|
||||
$object = $this->loadPlugin($plugin);
|
||||
if ($object) {
|
||||
$this->add($object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,6 +163,7 @@ class Plugins extends Iterator
|
||||
* Add a plugin
|
||||
*
|
||||
* @param Plugin $plugin
|
||||
* @return void
|
||||
*/
|
||||
public function add($plugin)
|
||||
{
|
||||
@@ -183,8 +189,8 @@ class Plugins extends Iterator
|
||||
*/
|
||||
public static function getPlugins(): array
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
$plugins = $grav['plugins'];
|
||||
/** @var Plugins $plugins */
|
||||
$plugins = Grav::instance()['plugins'];
|
||||
|
||||
$list = [];
|
||||
foreach ($plugins as $instance) {
|
||||
@@ -208,11 +214,13 @@ class Plugins extends Iterator
|
||||
/**
|
||||
* Return list of all plugin data with their blueprints.
|
||||
*
|
||||
* @return array<string,Data>
|
||||
* @return Data[]
|
||||
*/
|
||||
public static function all()
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var Plugins $plugins */
|
||||
$plugins = $grav['plugins'];
|
||||
$list = [];
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
namespace Grav\Common;
|
||||
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Config\Config;
|
||||
use RocketTheme\Toolbox\File\YamlFile;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
/**
|
||||
* Class Theme
|
||||
@@ -44,53 +44,30 @@ class Theme extends Plugin
|
||||
/**
|
||||
* Persists to disk the theme parameters currently stored in the Grav Config object
|
||||
*
|
||||
* @param string $theme_name The name of the theme whose config it should store.
|
||||
* @param string $name The name of the theme whose config it should store.
|
||||
* @return bool
|
||||
*/
|
||||
public static function saveConfig($theme_name)
|
||||
public static function saveConfig($name)
|
||||
{
|
||||
if (!$theme_name) {
|
||||
if (!$name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $grav['locator'];
|
||||
$filename = 'config://themes/' . $theme_name . '.yaml';
|
||||
$file = YamlFile::instance($locator->findResource($filename, true, true));
|
||||
$content = $grav['config']->get('themes.' . $theme_name);
|
||||
|
||||
$filename = 'config://themes/' . $name . '.yaml';
|
||||
$file = YamlFile::instance((string)$locator->findResource($filename, true, true));
|
||||
$content = $grav['config']->get('themes.' . $name);
|
||||
$file->save($content);
|
||||
$file->free();
|
||||
unset($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the mergeConfig method to work for themes
|
||||
*
|
||||
* @param PageInterface $page
|
||||
* @param string $deep
|
||||
* @param array $params
|
||||
* @param string $type
|
||||
* @return Data\Data
|
||||
*/
|
||||
protected function mergeConfig(PageInterface $page, $deep = 'merge', $params = [], $type = 'themes')
|
||||
{
|
||||
return parent::mergeConfig($page, $deep, $params, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simpler getter for the theme blueprint
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBlueprint()
|
||||
{
|
||||
if (!$this->blueprint) {
|
||||
$this->loadBlueprint();
|
||||
}
|
||||
return $this->blueprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load blueprints.
|
||||
*
|
||||
@@ -100,8 +77,11 @@ class Theme extends Plugin
|
||||
{
|
||||
if (!$this->blueprint) {
|
||||
$grav = Grav::instance();
|
||||
/** @var Themes $themes */
|
||||
$themes = $grav['themes'];
|
||||
$this->blueprint = $themes->get($this->name)->blueprints();
|
||||
$data = $themes->get($this->name);
|
||||
\assert($data !== null);
|
||||
$this->blueprint = $data->blueprints();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,10 +33,8 @@ class Themes extends Iterator
|
||||
{
|
||||
/** @var Grav */
|
||||
protected $grav;
|
||||
|
||||
/** @var Config */
|
||||
protected $config;
|
||||
|
||||
/** @var bool */
|
||||
protected $inited = false;
|
||||
|
||||
@@ -95,6 +93,20 @@ class Themes extends Iterator
|
||||
$events->addSubscriber($instance);
|
||||
}
|
||||
|
||||
// Register blueprints.
|
||||
if (is_dir('theme://blueprints/pages')) {
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $this->grav['locator'];
|
||||
$locator->addPath('blueprints', '', ['theme://blueprints'], ['user', 'blueprints']);
|
||||
}
|
||||
|
||||
// Register form fields.
|
||||
if (method_exists($instance, 'getFormFieldTypes')) {
|
||||
/** @var Plugins $plugins */
|
||||
$plugins = $this->grav['plugins'];
|
||||
$plugins->formFieldTypes = $instance->getFormFieldTypes() + $plugins->formFieldTypes;
|
||||
}
|
||||
|
||||
$this->grav['theme'] = $instance;
|
||||
|
||||
$this->grav->fireEvent('onThemeInitialized');
|
||||
@@ -382,7 +394,10 @@ class Themes extends Iterator
|
||||
}
|
||||
|
||||
// Try Old style theme classes
|
||||
$path = strtolower(preg_replace('#\\\|_(?!.+\\\)#', '/', $class));
|
||||
$path = preg_replace('#\\\|_(?!.+\\\)#', '/', $class);
|
||||
\assert(null !== $path);
|
||||
|
||||
$path = strtolower($path);
|
||||
$file = $locator("themes://{$path}/theme.php") ?: $locator("themes://{$path}/{$path}.php");
|
||||
|
||||
// Load class
|
||||
|
||||
Reference in New Issue
Block a user