From 756694dad04309df81a279b2c96546a45b8060b5 Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Wed, 28 Aug 2024 11:04:18 +0100 Subject: [PATCH 01/11] Added blocks controller to cms editor --- Plugin.php | 46 +++- controllers/BlocksController.php | 211 ++++++++++++++++++ .../blockscontroller/_button_commit.php | 14 ++ .../blockscontroller/_button_lastmodified.php | 8 + .../blockscontroller/_button_reset.php | 14 ++ .../_common_toolbar_actions.php | 19 ++ .../_concurrency_resolve_form.php | 29 +++ controllers/blockscontroller/_form_page.php | 16 ++ .../blockscontroller/_partial_toolbar.php | 12 + .../blockscontroller/_safemode_notice.php | 6 + controllers/blockscontroller/_sidepanel.php | 21 ++ .../blockscontroller/block_fields.yaml | 45 ++++ .../blockscontroller/config_block_list.yaml | 8 + controllers/blockscontroller/index.php | 31 +++ 14 files changed, 478 insertions(+), 2 deletions(-) create mode 100644 controllers/BlocksController.php create mode 100644 controllers/blockscontroller/_button_commit.php create mode 100644 controllers/blockscontroller/_button_lastmodified.php create mode 100644 controllers/blockscontroller/_button_reset.php create mode 100644 controllers/blockscontroller/_common_toolbar_actions.php create mode 100644 controllers/blockscontroller/_concurrency_resolve_form.php create mode 100644 controllers/blockscontroller/_form_page.php create mode 100644 controllers/blockscontroller/_partial_toolbar.php create mode 100644 controllers/blockscontroller/_safemode_notice.php create mode 100644 controllers/blockscontroller/_sidepanel.php create mode 100644 controllers/blockscontroller/block_fields.yaml create mode 100644 controllers/blockscontroller/config_block_list.yaml create mode 100644 controllers/blockscontroller/index.php diff --git a/Plugin.php b/Plugin.php index 519a3c6..48906fc 100644 --- a/Plugin.php +++ b/Plugin.php @@ -2,15 +2,19 @@ namespace Winter\Blocks; +use Backend\Classes\NavigationManager; use Backend\Classes\WidgetManager; +use Backend\Facades\Backend; +use Backend\Models\UserRole; use Cms\Classes\AutoDatasource; use Cms\Classes\Theme; -use Event; use System\Classes\PluginBase; +use Winter\Blocks\Classes\Block as BlockModel; use Winter\Blocks\Classes\BlockManager; use Winter\Blocks\Classes\BlocksDatasource; -use Winter\Blocks\Classes\Block as BlockModel; use Winter\Blocks\FormWidgets\Block; +use Winter\Storm\Support\Facades\Config; +use Winter\Storm\Support\Facades\Event; /** * Blocks Plugin Information File @@ -103,6 +107,27 @@ public function boot(): void { $this->extendThemeDatasource(); $this->extendControlLibraryBlocks(); + + if ($this->app->runningInBackend() && in_array('Cms', Config::get('cms.loadModules'))) { + $this->extendCms(); + } + } + + /** + * Registers any back-end permissions used by this plugin. + * + * @return array + */ + public function registerPermissions() + { + return [ + 'winter.blocks.manage_blocks' => [ + 'tab' => 'winter.blocks::lang.plugin.name', + 'order' => 200, + 'roles' => [UserRole::CODE_DEVELOPER, UserRole::CODE_PUBLISHER], + 'label' => 'winter.blocks::lang.blocks.manage_blocks' + ], + ]; } /** @@ -176,4 +201,21 @@ protected function extendControlLibraryBlocks(): void } }); } + + /** + * Extend the CMS to implement the BlocksController as a child of the CMS + */ + public function extendCms(): void + { + Event::listen('backend.menu.extendItems', function (NavigationManager $manager) { + $manager->addSideMenuItem('winter.cms', 'cms', 'blocks', [ + 'label' => 'winter.blocks::lang.plugin.name', + 'icon' => 'icon-cubes', + 'url' => Backend::url('winter/blocks/blockscontroller'), + // TODO: Make good + 'attributes' => 'onclick="window.location.href = this.querySelector(\'a\').href;"', + 'permissions' => ['winter.blocks.manage_blocks'] + ]); + }); + } } diff --git a/controllers/BlocksController.php b/controllers/BlocksController.php new file mode 100644 index 0000000..76ffea4 --- /dev/null +++ b/controllers/BlocksController.php @@ -0,0 +1,211 @@ +theme = $theme; + + new TemplateList($this, 'blockList', function () use ($theme) { + return Block::listInTheme($theme, true); + }); + } catch (\Exception $ex) { + $this->handleError($ex); + } + } + + /** + * Index page action + * @return void + */ + public function index() + { + parent::index(); + $this->addJs('/plugins/winter/blocks/assets/dist/js/winter.cmspage.extension.js', 'core'); + } + + /** + * Resolves a template type to its class name + * @param string $type + * @return string + */ + protected function resolveTypeClassName($type) + { + if ($type !== 'block') { + throw new ApplicationException(Lang::get('cms::lang.template.invalid_type')); + } + + return Block::class; + } + + /** + * Returns a form widget for a specified template type. + * @param string $type + * @param string $template + * @param string $alias + * @return Backend\Widgets\Form + */ + protected function makeTemplateFormWidget($type, $template, $alias = null) + { + if ($type !== 'block') { + throw new ApplicationException(Lang::get('cms::lang.template.not_found')); + } + + $formConfig = '~/plugins/winter/blocks/controllers/blockscontroller/block_fields.yaml'; + + $widgetConfig = $this->makeConfig($formConfig); + + $ext = pathinfo($template->fileName, PATHINFO_EXTENSION); + if ($type === 'content') { + switch ($ext) { + case 'htm': + $type = 'richeditor'; + break; + case 'md': + $type = 'markdown'; + break; + default: + $type = 'codeeditor'; + break; + } + array_set($widgetConfig->secondaryTabs, 'fields.markup.type', $type); + } + + $lang = 'php'; + if (array_get($widgetConfig->secondaryTabs, 'fields.markup.type') === 'codeeditor') { + switch ($ext) { + case 'htm': + $lang = 'twig'; + break; + case 'html': + $lang = 'html'; + break; + case 'css': + $lang = 'css'; + break; + case 'js': + case 'json': + $lang = 'javascript'; + break; + } + } + + $widgetConfig->model = $template; + $widgetConfig->alias = $alias ?: 'form'.studly_case($type).md5($template->exists ? $template->getFileName() : uniqid()); + + return $this->makeWidget('Backend\Widgets\Form', $widgetConfig); + } + + /** + * Saves the template currently open + * @return array + */ + public function onSave() + { + $this->validateRequestTheme(); + $type = Request::input('templateType'); + $templatePath = trim(Request::input('templatePath')); + $template = $templatePath ? $this->loadTemplate($type, $templatePath) : $this->createTemplate($type); + $formWidget = $this->makeTemplateFormWidget($type, $template); + + $saveData = $formWidget->getSaveData(); + $postData = post(); + $templateData = []; + + $settings = array_get($saveData, 'settings', []) + Request::input('settings', []); + $settings = $this->upgradeSettings($settings, $template->settings); + + if ($settings) { + $templateData['settings'] = $settings; + } + + $fields = ['markup', 'code', 'fileName', 'content', 'yaml']; + + foreach ($fields as $field) { + if (array_key_exists($field, $saveData)) { + $templateData[$field] = $saveData[$field]; + } + elseif (array_key_exists($field, $postData)) { + $templateData[$field] = $postData[$field]; + } + } + + if (!empty($templateData['markup']) && Config::get('cms.convertLineEndings', false) === true) { + $templateData['markup'] = $this->convertLineEndings($templateData['markup']); + } + + if (!empty($templateData['code']) && Config::get('cms.convertLineEndings', false) === true) { + $templateData['code'] = $this->convertLineEndings($templateData['code']); + } + + if ( + !Request::input('templateForceSave') && $template->mtime + && Request::input('templateMtime') != $template->mtime + ) { + throw new ApplicationException('mtime-mismatch'); + } + + $template->attributes = []; + $template->fill($templateData); + + $template->save(); + + /** + * @event cms.template.save + * Fires after a CMS template (page|partial|layout|content|asset) has been saved. + * + * Example usage: + * + * Event::listen('cms.template.save', function ((\Cms\Controllers\Index) $controller, (mixed) $templateObject, (string) $type) { + * \Log::info("A $type has been saved"); + * }); + * + * Or + * + * $CmsIndexController->bindEvent('template.save', function ((mixed) $templateObject, (string) $type) { + * \Log::info("A $type has been saved"); + * }); + * + */ + $this->fireSystemEvent('cms.template.save', [$template, $type]); + + Flash::success(Lang::get('cms::lang.template.saved')); + + return $this->getUpdateResponse($template, $type); + } +} diff --git a/controllers/blockscontroller/_button_commit.php b/controllers/blockscontroller/_button_commit.php new file mode 100644 index 0000000..90a4abd --- /dev/null +++ b/controllers/blockscontroller/_button_commit.php @@ -0,0 +1,14 @@ + diff --git a/controllers/blockscontroller/_button_lastmodified.php b/controllers/blockscontroller/_button_lastmodified.php new file mode 100644 index 0000000..daff6f3 --- /dev/null +++ b/controllers/blockscontroller/_button_lastmodified.php @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/controllers/blockscontroller/_button_reset.php b/controllers/blockscontroller/_button_reset.php new file mode 100644 index 0000000..a5a8c87 --- /dev/null +++ b/controllers/blockscontroller/_button_reset.php @@ -0,0 +1,14 @@ + diff --git a/controllers/blockscontroller/_common_toolbar_actions.php b/controllers/blockscontroller/_common_toolbar_actions.php new file mode 100644 index 0000000..2e923a1 --- /dev/null +++ b/controllers/blockscontroller/_common_toolbar_actions.php @@ -0,0 +1,19 @@ +makePartial('button_commit'); ?> + +makePartial('button_reset'); ?> + + + +makePartial('button_lastmodified'); ?> diff --git a/controllers/blockscontroller/_concurrency_resolve_form.php b/controllers/blockscontroller/_concurrency_resolve_form.php new file mode 100644 index 0000000..03ec6ca --- /dev/null +++ b/controllers/blockscontroller/_concurrency_resolve_form.php @@ -0,0 +1,29 @@ +'return false']) ?> + + + + diff --git a/controllers/blockscontroller/_form_page.php b/controllers/blockscontroller/_form_page.php new file mode 100644 index 0000000..74d1b2f --- /dev/null +++ b/controllers/blockscontroller/_form_page.php @@ -0,0 +1,16 @@ + 'layout', + 'data-change-monitor' => 'true', + 'data-window-close-confirm' => e(trans('backend::lang.form.confirm_tab_close')), + 'data-inspector-external-parameters' => true +]) ?> + render() ?> + + + + + + + + + \ No newline at end of file diff --git a/controllers/blockscontroller/_partial_toolbar.php b/controllers/blockscontroller/_partial_toolbar.php new file mode 100644 index 0000000..094da3b --- /dev/null +++ b/controllers/blockscontroller/_partial_toolbar.php @@ -0,0 +1,12 @@ +
+ + + + + makePartial('common_toolbar_actions', ['toolbarSource' => 'block']); ?> +
diff --git a/controllers/blockscontroller/_safemode_notice.php b/controllers/blockscontroller/_safemode_notice.php new file mode 100644 index 0000000..b9e320c --- /dev/null +++ b/controllers/blockscontroller/_safemode_notice.php @@ -0,0 +1,6 @@ +
+
+ +

+
+
diff --git a/controllers/blockscontroller/_sidepanel.php b/controllers/blockscontroller/_sidepanel.php new file mode 100644 index 0000000..0223688 --- /dev/null +++ b/controllers/blockscontroller/_sidepanel.php @@ -0,0 +1,21 @@ + +
+
+
+ user->hasAccess('winter.blocks.manage_blocks')): ?> + +
+ widget->blockList->render() ?> +
+ +
+
+
diff --git a/controllers/blockscontroller/block_fields.yaml b/controllers/blockscontroller/block_fields.yaml new file mode 100644 index 0000000..8223579 --- /dev/null +++ b/controllers/blockscontroller/block_fields.yaml @@ -0,0 +1,45 @@ +# =================================== +# Form Field Definitions +# =================================== + +fields: + fileName: + span: left + label: cms::lang.editor.filename + attributes: + default-focus: 1 + + toolbar: + type: partial + path: partial_toolbar + cssClass: collapse-visible + +tabs: + cssClass: master-area + +secondaryTabs: + stretch: true + fields: + yaml: + tab: winter.blocks::lang.editor.settings + stretch: true + type: codeeditor + language: yaml + + markup: + tab: cms::lang.editor.markup + stretch: true + type: codeeditor + language: twig + + safemode_notice: + tab: cms::lang.editor.code + type: partial + hidden: true + cssClass: p-b-0 + + code: + tab: cms::lang.editor.code + stretch: true + type: codeeditor + language: php diff --git a/controllers/blockscontroller/config_block_list.yaml b/controllers/blockscontroller/config_block_list.yaml new file mode 100644 index 0000000..be56179 --- /dev/null +++ b/controllers/blockscontroller/config_block_list.yaml @@ -0,0 +1,8 @@ +# =================================== +# Configures the partial list widget +# =================================== + +descriptionProperty: description +noRecordsMessage: 'cms::lang.partial.no_list_records' +deleteConfirmation: 'cms::lang.partial.delete_confirm_multiple' +itemType: block diff --git a/controllers/blockscontroller/index.php b/controllers/blockscontroller/index.php new file mode 100644 index 0000000..138c663 --- /dev/null +++ b/controllers/blockscontroller/index.php @@ -0,0 +1,31 @@ + + fatalError): ?> + makePartial('sidepanel') ?> + + + + + fatalError): ?> +
+ +
+
+ +
+
+
+
+ +
+ +

fatalError)) ?>

+ + From f43b57f803d7bfeae4fd5c5da2669a1484940a6e Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Wed, 28 Aug 2024 11:04:44 +0100 Subject: [PATCH 02/11] Added fillable to block model --- classes/Block.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/classes/Block.php b/classes/Block.php index 9962b2c..4f928eb 100644 --- a/classes/Block.php +++ b/classes/Block.php @@ -26,6 +26,16 @@ class Block extends CmsCompoundObject */ protected $allowedExtensions = ['block']; + /** + * @var array The attributes that are mass assignable. + */ + protected $fillable = [ + 'markup', + 'settings', + 'code', + 'yaml' + ]; + protected PartialStack $partialStack; public function __construct(array $attributes = []) From c3890beefcc4b087a3bb2b14221919e1d9ea798c Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Wed, 28 Aug 2024 11:05:34 +0100 Subject: [PATCH 03/11] Added yaml property to blocks --- classes/BlockParser.php | 58 +++++++++++++++++++++++++++++++++++++- classes/BlockProcessor.php | 3 +- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/classes/BlockParser.php b/classes/BlockParser.php index 6e7d9d0..e793377 100644 --- a/classes/BlockParser.php +++ b/classes/BlockParser.php @@ -23,6 +23,62 @@ public static function parseSettings(string $settings): array */ public static function renderSettings(array $data): string { - return Yaml::render($data); + return is_string($data['yaml']) ? $data['yaml'] : Yaml::render($data); + } + + /** + * Parses Halcyon section content. + * The expected file format is following: + * + * INI settings section + * == + * PHP code section + * == + * Twig markup section + * + * If the content has only 2 sections they are parsed as settings and markup. + * If there is only a single section, it is parsed as markup. + * + * Returns an array with the following elements: (array|null) 'settings', + * (string|null) 'markup', (string|null) 'code'. + */ + public static function parse(string $content, array $options = []): array + { + $sectionOptions = array_merge([ + 'isCompoundObject' => true + ], $options); + extract($sectionOptions); + + $result = [ + 'settings' => [], + 'code' => null, + 'markup' => null, + 'yaml' => null + ]; + + if (!isset($isCompoundObject) || $isCompoundObject === false || !strlen($content)) { + return $result; + } + + $sections = static::parseIntoSections($content); + $count = count($sections); + foreach ($sections as &$section) { + $section = trim($section); + } + + if ($count >= 3) { + $result['yaml'] = $sections[0]; + $result['settings'] = static::parseSettings($sections[0]); + $result['code'] = static::parseCode($sections[1]); + $result['markup'] = static::parseMarkup($sections[2]); + } elseif ($count == 2) { + $result['yaml'] = $sections[0]; + $result['settings'] = static::parseSettings($sections[0]); + $result['markup'] = static::parseMarkup($sections[1]); + } elseif ($count == 1) { + $result['markup'] = static::parseMarkup($sections[0]); + } + + return $result; } } diff --git a/classes/BlockProcessor.php b/classes/BlockProcessor.php index 7794ab4..f8efa97 100644 --- a/classes/BlockProcessor.php +++ b/classes/BlockProcessor.php @@ -32,7 +32,8 @@ protected function parseTemplateContent($query, $result, $fileName) 'content' => $content, 'mtime' => array_get($result, 'mtime'), 'markup' => $processed['markup'], - 'code' => $processed['code'] + 'code' => $processed['code'], + 'yaml' => $processed['yaml'], ] + $processed['settings']; } From 608facae3af54c39bda19db133a99a460862be4c Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Wed, 28 Aug 2024 11:05:56 +0100 Subject: [PATCH 04/11] Added lang strings --- lang/en/lang.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lang/en/lang.php b/lang/en/lang.php index 724a88a..818fc0f 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -23,6 +23,9 @@ 'tabs' => [ 'display' => 'Display', ], + 'editor' => [ + 'settings' => 'Settings' + ], 'blocks' => [ 'button' => [ 'name' => 'Button', @@ -101,6 +104,7 @@ 'description' => 'Embed a YouTube video', 'youtube_id' => 'YouTube Video ID', ], + 'manage_blocks' => 'Manage Blocks', ], 'fields' => [ 'actions_prompt' => 'Add action', @@ -120,4 +124,10 @@ 'right' => 'Right', ], ], + 'models' => [ + 'blockscontroller' => [ + 'label' => 'Blocks Controller', + 'label_plural' => 'Blocks Controllers', + ], + ], ]; From c302aaa640f6c41476877a8feb2109c0834de66b Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Wed, 28 Aug 2024 11:06:30 +0100 Subject: [PATCH 05/11] Added js extension for cmspage custom logic --- assets/src/js/winter.cmspage.extension.js | 21 +++++++++++++++++++++ winter.mix.js | 1 + 2 files changed, 22 insertions(+) create mode 100644 assets/src/js/winter.cmspage.extension.js diff --git a/assets/src/js/winter.cmspage.extension.js b/assets/src/js/winter.cmspage.extension.js new file mode 100644 index 0000000..8318d4f --- /dev/null +++ b/assets/src/js/winter.cmspage.extension.js @@ -0,0 +1,21 @@ +(($) => { + $.wn.cmsPage.updateModifiedCounter = function () { + var counters = { + page: {menu: 'pages', count: 0}, + partial: {menu: 'partials', count: 0}, + layout: {menu: 'layouts', count: 0}, + content: {menu: 'content', count: 0}, + asset: {menu: 'assets', count: 0}, + block: {menu: 'blocks', count: 0}, + } + + $('> div.tab-content > div.tab-pane[data-modified]', '#cms-master-tabs').each(function () { + var inputType = $('> form > input[name=templateType]', this).val(); + counters[inputType].count++; + }); + + $.each(counters, function (type, data) { + $.wn.sideNav.setCounter('cms/' + data.menu, data.count); + }); + }; +})(window.jQuery); diff --git a/winter.mix.js b/winter.mix.js index 082f4b8..ac70e1d 100644 --- a/winter.mix.js +++ b/winter.mix.js @@ -3,4 +3,5 @@ const mix = require('laravel-mix'); mix .setPublicPath(__dirname) .js('assets/src/js/blocks.js', 'assets/dist/js/blocks.js') + .js('assets/src/js/winter.cmspage.extension.js', 'assets/dist/js/winter.cmspage.extension.js') .less('formwidgets/blocks/assets/less/blocks.less', 'formwidgets/blocks/assets/css/blocks.css'); From 0fa3c22252fb4574d00f86031c0226e7217a9500 Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Wed, 28 Aug 2024 11:06:44 +0100 Subject: [PATCH 06/11] Added compiled js --- assets/dist/js/winter.cmspage.extension.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 assets/dist/js/winter.cmspage.extension.js diff --git a/assets/dist/js/winter.cmspage.extension.js b/assets/dist/js/winter.cmspage.extension.js new file mode 100644 index 0000000..60195eb --- /dev/null +++ b/assets/dist/js/winter.cmspage.extension.js @@ -0,0 +1 @@ +(()=>{var t;(t=window.jQuery).wn.cmsPage.updateModifiedCounter=function(){var n={page:{menu:"pages",count:0},partial:{menu:"partials",count:0},layout:{menu:"layouts",count:0},content:{menu:"content",count:0},asset:{menu:"assets",count:0},block:{menu:"blocks",count:0}};t("> div.tab-content > div.tab-pane[data-modified]","#cms-master-tabs").each((function(){var e=t("> form > input[name=templateType]",this).val();n[e].count++})),t.each(n,(function(n,e){t.wn.sideNav.setCounter("cms/"+e.menu,e.count)}))}})(); \ No newline at end of file From 82b9b51092b6c2e1475fcb8547f39b8a8dc1a931 Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Wed, 28 Aug 2024 13:19:28 +0100 Subject: [PATCH 07/11] Added a fix that ensures Yaml::parse return is an array --- classes/BlockParser.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/classes/BlockParser.php b/classes/BlockParser.php index e793377..a2cc42d 100644 --- a/classes/BlockParser.php +++ b/classes/BlockParser.php @@ -15,7 +15,9 @@ class BlockParser extends SectionParser */ public static function parseSettings(string $settings): array { - return Yaml::parse($settings); + $parsed = Yaml::parse($settings); + // Ensure that the parsed settings returns an array (errors return input string) + return is_array($parsed) ? $parsed : []; } /** From a21837a5d57d78e5edb07063b5ed133850fefe70 Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Wed, 28 Aug 2024 13:21:39 +0100 Subject: [PATCH 08/11] Added fix for add new block --- controllers/BlocksController.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/controllers/BlocksController.php b/controllers/BlocksController.php index 76ffea4..2bb19d6 100644 --- a/controllers/BlocksController.php +++ b/controllers/BlocksController.php @@ -73,6 +73,21 @@ protected function resolveTypeClassName($type) return Block::class; } + /** + * Returns the text for a template tab + * @param string $type + * @param string $template + * @return string + */ + protected function getTabTitle($type, $template) + { + if ($type !== 'block') { + throw new ApplicationException(Lang::get('cms::lang.template.invalid_type')); + } + + return Lang::get('winter.blocks::lang.editor.new'); + } + /** * Returns a form widget for a specified template type. * @param string $type From 604738b56e12e7d7f5bbb8752d48b61e02ccc8e7 Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Wed, 28 Aug 2024 13:22:12 +0100 Subject: [PATCH 09/11] Added lang string for new block --- lang/en/lang.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lang/en/lang.php b/lang/en/lang.php index 818fc0f..abfce55 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -24,7 +24,8 @@ 'display' => 'Display', ], 'editor' => [ - 'settings' => 'Settings' + 'settings' => 'Settings', + 'new' => 'New Block', ], 'blocks' => [ 'button' => [ From 90344c0033feb52149ab418addb5cbef8207be7f Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Wed, 28 Aug 2024 13:52:06 +0100 Subject: [PATCH 10/11] Added fix for existing file name in tab title --- controllers/BlocksController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/BlocksController.php b/controllers/BlocksController.php index 2bb19d6..4cae699 100644 --- a/controllers/BlocksController.php +++ b/controllers/BlocksController.php @@ -85,7 +85,7 @@ protected function getTabTitle($type, $template) throw new ApplicationException(Lang::get('cms::lang.template.invalid_type')); } - return Lang::get('winter.blocks::lang.editor.new'); + return $template->getFileName() ?? Lang::get('winter.blocks::lang.editor.new'); } /** From ccdc9c2daee50ece1306edc7e4a32b855ed0263e Mon Sep 17 00:00:00 2001 From: Jack Wilkinson Date: Fri, 30 Aug 2024 10:18:46 +0100 Subject: [PATCH 11/11] Added fix for cms links on blocks controller --- controllers/BlocksController.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/controllers/BlocksController.php b/controllers/BlocksController.php index 4cae699..1d2b6db 100644 --- a/controllers/BlocksController.php +++ b/controllers/BlocksController.php @@ -2,15 +2,17 @@ namespace Winter\Blocks\Controllers; -use BackendMenu; use Backend\Classes\Controller; +use Backend\Classes\NavigationManager; +use Backend\Facades\Backend; +use Backend\Facades\BackendMenu; use Cms\Classes\Theme; +use Cms\Controllers\Index as CmsIndexController; use Cms\Widgets\TemplateList; use Illuminate\Support\Facades\Lang; use Illuminate\Support\Facades\Request; use Winter\Blocks\Classes\Block; use Winter\Storm\Exception\ApplicationException; -use Cms\Controllers\Index as CmsIndexController; use Winter\Storm\Support\Facades\Config; use Winter\Storm\Support\Facades\Flash; @@ -47,6 +49,16 @@ public function __construct() } catch (\Exception $ex) { $this->handleError($ex); } + + // Dynamically re-write the cms menu item urls to allow the user to return back to those pages + BackendMenu::registerCallback(function (NavigationManager $navigationManager) { + foreach ($navigationManager->getMainMenuItem('Winter.Cms', 'cms')->sideMenu as $menuItem) { + if ($menuItem->url === 'javascript:;') { + $menuItem->url = Backend::url('cms#' . $menuItem->code); + $menuItem->attributes = 'onclick="window.location.href = this.querySelector(\'a\').href;"'; + } + } + }); } /**