diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d31f11..bb6ea40 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Release Notes for Craft User Manual +## 5.0.0 - 2024-04-04 +- Craft 5 support. +- Adjusted version number to reflect Craft 5 compatibility. +- Styling updates for the side for User Manual content. Nested lists now have a different style to make them easier to read. +- Added conditional messaging to help provide instructions to the developer when the plugin is installed in a fresh installation of Craft CMS with no sections or entries yet created. +- Added craftMajorVersion() twig function to help style nested lists in Craft 4. + ## 4.0.1 - 2022-06-20 - Updating name in Composer so it will update on Packagist diff --git a/README.md b/README.md index fe43002..9d7ec23 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Craft User Manual plugin for Craft CMS 4.x +# Craft User Manual plugin for Craft CMS 4.x and Craft CMS 5.x Craft User Manual allows developers (or even content editors) to provide CMS documentation using Craft's built-in sections (singles, channels, or structures) to create a "User Manual" or "Help" section directly in the control panel. @@ -10,7 +10,7 @@ This plugin requires Craft CMS 4.0.0 or later. ## Installation -### Craft 4 +### Craft 4 and Craft 5 To install the plugin in your Craft 4 project, follow these instructions. 1. Open your terminal and go to your Craft project: @@ -21,7 +21,7 @@ To install the plugin in your Craft 4 project, follow these instructions. composer require hillholliday/craft-user-manual -> Wondering why it says hillholliday and not roberskine as the org? This package was originally submitted as hillholliday, and to [preserve the artifacts on Packagist](https://packagist.org/packages/hillholliday/craft-user-manual) we have kept it as hillholliday. +> Wondering why it says `hillholliday` and not `roberskine` as the org? This package was originally submitted as hillholliday, and to [preserve the artifacts on Packagist](https://packagist.org/packages/hillholliday/craft-user-manual) we have kept it as hillholliday. 3. In the Control Panel, go to Settings → Plugins and click the “Install” button for usermanual. @@ -82,6 +82,7 @@ Defaults to true. This plugin was inspired by the team over at [70kft](http://70kft.com/) for their work on [Craft-Help](https://github.com/70kft/craft-help). While their plugin is definitely more flexible in terms of writing custom markdown in separate files, we wanted to create something that would make it easier for anyone to edit documentation without making any changes to the server. This works particularly well for larger projects where more than one person (especially non-devs) are writing documentation for how to use the CMS. ## Releases +* **5.0.0** - Craft 5 support! Thanks to [John Morton](https://github.com/) and [Dalton Rooney](daltonrooney) for your contributions. * **4.0.0** - Craft 4 support! Thanks to [Chris DuCharme](https://github.com/Chris-DuCharme) for migrating up to Craft 4. * **2.1.0** - Merging PRs from [JorgeAnzola](https://github.com/JorgeAnzola) and [sameerast](https://github.com/sameerast) * **2.0.3** - Forcing updating to plugin store diff --git a/composer.json b/composer.json index e79bad1..9a5b74a 100755 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "hillholliday/craft-user-manual", "description": "Craft User Manual allows developers (or even content editors) to provide CMS documentation using Craft's built-in sections (singles, channels, or structures) to create a `User Manual` or `Help` section directly in the control panel.", "type": "craft-plugin", - "version": "4.0.0", + "version": "5.0.0", "keywords": [ "craft", "cms", @@ -23,7 +23,7 @@ ], "require": { "php": "^8.0.2", - "craftcms/cms": "^4.0.0" + "craftcms/cms": "^4.0.0|^5.0.0" }, "autoload": { "psr-4": { diff --git a/resources/SVG/sub-menu-icon.svg b/resources/SVG/sub-menu-icon.svg new file mode 100644 index 0000000..fc664e0 --- /dev/null +++ b/resources/SVG/sub-menu-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/UserManual.php b/src/UserManual.php index 243b7de..1e56290 100644 --- a/src/UserManual.php +++ b/src/UserManual.php @@ -61,7 +61,7 @@ class UserManual extends Plugin /** * @inheritdoc */ - public function init() + public function init(): void { parent::init(); self::$plugin = $this; @@ -122,7 +122,7 @@ public function getName(): string : $pluginName; } - public function registerCpUrlRules(RegisterUrlRulesEvent $event) + public function registerCpUrlRules(RegisterUrlRulesEvent $event): void { $rules = [ 'usermanual/' => ['template' => 'usermanual/index'], @@ -131,7 +131,7 @@ public function registerCpUrlRules(RegisterUrlRulesEvent $event) $event->rules = array_merge($event->rules, $rules); } - public function afterInstallPlugin(PluginEvent $event) + public function afterInstallPlugin(PluginEvent $event): void { $isCpRequest = Craft::$app->getRequest()->isCpRequest; @@ -146,7 +146,7 @@ public function afterInstallPlugin(PluginEvent $event) /** * @inheritdoc */ - protected function createSettingsModel(): ?Model + protected function createSettingsModel(): Settings { return new Settings(); } @@ -156,27 +156,6 @@ protected function createSettingsModel(): ?Model */ protected function settingsHtml(): ?string { - $options = [[ - 'label' => '', - 'value' => '', - ]]; - foreach (Craft::$app->sections->getAllSections() as $section) { - $siteSettings = Craft::$app->sections->getSectionSiteSettings($section['id']); - $hasUrls = false; - foreach ($siteSettings as $siteSetting) { - if ($siteSetting->hasUrls) { - $hasUrls = true; - } - } - - if (!$hasUrls) { - continue; - } - $options[] = [ - 'label' => $section['name'], - 'value' => $section['id'], - ]; - } // Get override settings from config file. $overrides = Craft::$app->getConfig()->getConfigFromFile(strtolower($this->handle)); @@ -186,7 +165,7 @@ protected function settingsHtml(): ?string [ 'settings' => $this->getSettings(), 'overrides' => array_keys($overrides), - 'options' => $options, + 'options' => $this->getSectionOptions(), 'siteTemplatesPath' => Craft::$app->getPath()->getSiteTemplatesPath(), ] ); @@ -212,7 +191,17 @@ public function getSettings(): ?Model // Allow handles from config if (!is_numeric($settings->section)) { - $section = Craft::$app->getSections()->getSectionByHandle('homepage'); + // Get the Craft CMS version + $version = Craft::$app->getVersion(); + + // Check the first character to determine the major version + $majorVersion = $version[0]; + + if ($majorVersion === '4') { + $section = Craft::$app->getSections()->getSectionByHandle('homepage'); + } else { + $section = Craft::$app->entries->getSectionByHandle('homepage'); + } if ($section) { $settings->section = $section->id; } @@ -224,8 +213,77 @@ public function getSettings(): ?Model // Private Methods // ========================================================================= - private function _addTwigExtensions() + private function _addTwigExtensions(): void { Craft::$app->view->twig->addExtension(new UserManualTwigExtension); } + + private function getSectionOptions(): array + { + + $sections = $this->getSections(); + $options = []; + + foreach ($sections as $section) { + $siteSettings = $this->getSectionSiteSettings($section['id']); + $hasUrls = false; + foreach ($siteSettings as $siteSetting) { + if ($siteSetting->hasUrls) { + $hasUrls = true; + } + } + + if (!$hasUrls) { + continue; + } + $options[] = [ + 'label' => $section['name'], + 'value' => $section['id'], + ]; + } + + if (!empty($options)) { + $optionToSelectNoSection = [ + 'label' => '', + 'value' => '', + ]; + + array_unshift($options, $optionToSelectNoSection); + } + + return $options; + } + + // Abstracted Method to get major version + private function getMajorVersion(): string + { + $version = Craft::$app->getVersion(); + return $version[0]; // Assuming version format is X.Y.Z + } + + // Abstracted Method to get sections + private function getSections(): array + { + $majorVersion = $this->getMajorVersion(); + + if ($majorVersion === '4') { + $sections = Craft::$app->sections->getAllSections(); + } else { + $sections = Craft::$app->entries->getAllSections(); + } + + return $sections; + } + + // Abstracted method to get site settings based on version + private function getSectionSiteSettings($sectionId) { + $majorVersion = $this->getMajorVersion(); + + if ($majorVersion === '4') { + return Craft::$app->sections->getSectionSiteSettings($sectionId); + } + + return Craft::$app->entries->getSectionSiteSettings($sectionId); + } + } diff --git a/src/assetbundles/usermanual/dist/css/UserManual.css b/src/assetbundles/usermanual/dist/css/UserManual.css index 47ef783..ad2481b 100644 --- a/src/assetbundles/usermanual/dist/css/UserManual.css +++ b/src/assetbundles/usermanual/dist/css/UserManual.css @@ -12,8 +12,15 @@ /* * lifted from craft-help from the super smart devs over at 70kft https://github.com/70kft/craft-help + * + * Updated for version 5 of the plugin to support nested lists in the sidebar + * */ +:root { + --user-manual-indent-level: 0.4rem; +} + #user-manual { font-size: 15px; line-height: 1.5; @@ -182,8 +189,9 @@ position: static !important; } -#content{ - width: calc(100vw - 570px); +/* The rule aligns the "sub=menu" svg graphic to the top of the sub-menu items that are multiple lines long */ +#sidebar nav li a { + align-items: flex-start; } .pe-user-manual #user-manual-menu{ @@ -191,3 +199,54 @@ max-height: calc(100vh - 212px); overflow-y: scroll; } + +/* Indent sub-sections in the side bar */ + +/* Base styling for all ul elements */ +#user-manual-menu ul { + list-style-type: none; /* Removes default list styling */ + padding-left: 0; /* Resets any default padding */ + margin-left: 0; /* Resets any default margin */ +} + +/* Bullet for nested items needs adjustment for Craft CMS 4 */ +#user-manual-menu ul.craft-4 li a:before { + position: relative; + top: 3px; +} + +/* First level of nesting */ +#user-manual-menu ul > li > ul > li a:before { + text-indent: var(--user-manual-indent-level); /* Indent first level of nested ul */ +} + +#user-manual-menu ul > li > ul > li a:before { + font-size: 9px; + content: '\0025a0'; /* Add a bullet point before each nested li */ + margin-right: 0.2rem; /* Add a little space between the bullet point and the text */ + margin-left: -0.25rem; +} + +/* Second level of nesting */ +#user-manual-menu ul > li > ul > li > ul > li a:before { + content: '\0025a1'; + text-indent: calc( var(--user-manual-indent-level) * 2 ); /* Indent second level of nested ul */ +} + +/* Third level of nesting */ +#user-manual-menu ul > li > ul > li > ul > li > ul > li a:before { + content: '\0025a3'; + text-indent: calc( var(--user-manual-indent-level) * 3 ); /* Indent third level of nested ul */ +} + +/* Fourth level of nesting, and so on... */ +#user-manual-menu ul > li > ul > li > ul > li > ul > li > ul > li a:before { + content: '\00229e'; + text-indent: calc( var(--user-manual-indent-level) * 4 ); /* Indent fourth level of nested ul */ +} + +/* Fifth level of nesting, and so on... */ +#user-manual-menu ul > li > ul > li > ul > li > ul > li > ul > li > ul > li a:before { + content: '\00229f'; + text-indent: calc( var(--user-manual-indent-level) * 5 ); /* Indent fifth level of nested ul */ +} diff --git a/src/assetbundles/usermanual/dist/js/UserManual.js b/src/assetbundles/usermanual/dist/js/UserManual.js index 892b6f7..6c3a2ab 100755 --- a/src/assetbundles/usermanual/dist/js/UserManual.js +++ b/src/assetbundles/usermanual/dist/js/UserManual.js @@ -14,7 +14,4 @@ $('document').ready(function () { if(window.location.hash.substr(1)){ $('body').addClass('pe-user-manual'); } - else{ - $('#global-header').hide(); - } }); diff --git a/src/templates/index.twig b/src/templates/index.twig index 2ab4cd3..8145d25 100644 --- a/src/templates/index.twig +++ b/src/templates/index.twig @@ -1,19 +1,25 @@ {% extends "_layouts/cp" %} +{% set title = craft.userManual.name|t %} -{% do view.registerAssetBundle("roberskine\\usermanual\\assetbundles\\usermanual\\UserManualAsset") %} +{% if craft.userManual.settings.section is defined %} -{% set sectionSelected = (craft.userManual.settings.section is defined) - ? craft.userManual.settings.section - : "Homepage" %} + {% set sectionSelected = craft.userManual.settings.section %} -{% set title = craft.userManual.name|t %} + {% if sectionSelected %} + {# Does the sectionSelected have any enabled entries #} + {% set hasEntries = craft.entries.sectionId(sectionSelected).all() %} + {% endif %} + + {% do view.registerAssetBundle("roberskine\\usermanual\\assetbundles\\usermanual\\UserManualAsset") %} + +{% endif %} -{% if craft.userManual.settings.enabledSideBar %} +{% if craft.userManual.settings.enabledSideBar and sectionSelected and hasEntries %} {% set sidebar %}