From c48adc7540cbf9137e513783fe41cd3392f8e9f2 Mon Sep 17 00:00:00 2001 From: Michal Kleiner Date: Thu, 19 Dec 2019 15:38:49 +1300 Subject: [PATCH] Add Taxonomies overview feature Linked from the tagging interface (gridfield or treemultiselect), the simple table gives content authors a global overview of all taxonomies, their hierarchies, titles and descriptions. --- _config/config.yml | 4 ++ client/style.css | 3 +- .../TaxonomyOverviewController.php | 48 ++++++++++++++ .../DataObjectTaxonomiesDataExtension.php | 5 ++ .../FileFormFactoryTaxonomyExtension.php | 12 +++- src/Forms/GridFieldInfoLink.php | 64 +++++++++++++++++++ src/Models/TaxonomyTerm.php | 39 +++++++++++ .../Controllers/TaxonomyOverviewController.ss | 36 +++++++++++ .../TaxonomyOverviewController_TermRow.ss | 14 ++++ .../TaxonomyOverviewController_Terms.ss | 12 ++++ .../Forms/GridFieldInfoLink.ss | 5 ++ 11 files changed, 238 insertions(+), 4 deletions(-) create mode 100644 src/Controllers/TaxonomyOverviewController.php create mode 100644 src/Forms/GridFieldInfoLink.php create mode 100644 templates/Chrometoaster/AdvancedTaxonomies/Controllers/TaxonomyOverviewController.ss create mode 100644 templates/Chrometoaster/AdvancedTaxonomies/Controllers/TaxonomyOverviewController_TermRow.ss create mode 100644 templates/Chrometoaster/AdvancedTaxonomies/Controllers/TaxonomyOverviewController_Terms.ss create mode 100644 templates/Chrometoaster/AdvancedTaxonomies/Forms/GridFieldInfoLink.ss diff --git a/_config/config.yml b/_config/config.yml index 82afdad..2c5d726 100644 --- a/_config/config.yml +++ b/_config/config.yml @@ -5,6 +5,10 @@ SilverStripe\Admin\ModelAdmin: extensions: - Chrometoaster\AdvancedTaxonomies\Extensions\LeftAndMainTaxonomyExtension +SilverStripe\Control\Director: + rules: + at-taxonomy-overview: Chrometoaster\AdvancedTaxonomies\Controllers\TaxonomyOverviewController + --- Only: moduleexists: 'silverstripe/cms' diff --git a/client/style.css b/client/style.css index 3961d57..66addef 100644 --- a/client/style.css +++ b/client/style.css @@ -58,12 +58,13 @@ } /* style for a link with .at-link-external */ -a.at-link-external { +.at-link-external { padding-right: 1em; background-image: url(./img/icons/external-icon--blue.svg); background-repeat: no-repeat; background-position: 100%; background-size: .75em .75em; + text-decoration: underline; } /* Mobile view fixing for GridField that lists TaxonomyTerm */ diff --git a/src/Controllers/TaxonomyOverviewController.php b/src/Controllers/TaxonomyOverviewController.php new file mode 100644 index 0000000..e4e1035 --- /dev/null +++ b/src/Controllers/TaxonomyOverviewController.php @@ -0,0 +1,48 @@ + 'index', + ]; + + private static $allowed_actions = [ + 'index', + ]; + + + /** + * Render a hierarchy + * + * @param HTTPRequest $request + * @return \SilverStripe\ORM\FieldType\DBHTMLText + */ + public function index(HTTPRequest $request) + { + $parentID = (int) $request->param('ParentID'); // empty param is the same as 0 for the sake of this report + + $terms = TaxonomyTerm::get()->filter(['ParentID' => $parentID]); + + $parentTerm = null; + if ($parentID) { + $parentTerm = TaxonomyTerm::get()->byID($parentID); + } + + return $this->customise(ArrayData::create([ + 'Terms' => $terms, + 'ParentTerm' => ($parentTerm && $parentTerm->exists()) ? $parentTerm : false, + ]))->renderWith(self::class); + } +} diff --git a/src/Extensions/DataObjectTaxonomiesDataExtension.php b/src/Extensions/DataObjectTaxonomiesDataExtension.php index 2b58a2a..cdf16a9 100644 --- a/src/Extensions/DataObjectTaxonomiesDataExtension.php +++ b/src/Extensions/DataObjectTaxonomiesDataExtension.php @@ -3,6 +3,7 @@ namespace Chrometoaster\AdvancedTaxonomies\Extensions; use Chrometoaster\AdvancedTaxonomies\Forms\GridFieldAddTagsAutocompleter; +use Chrometoaster\AdvancedTaxonomies\Forms\GridFieldInfoLink; use Chrometoaster\AdvancedTaxonomies\Forms\GridFieldOrderableRows; use Chrometoaster\AdvancedTaxonomies\Models\DataObjectTaxonomyTerm; use Chrometoaster\AdvancedTaxonomies\Models\TaxonomyTerm; @@ -78,6 +79,10 @@ public function updateCMSFields(FieldList $fields) $addExisting = new GridFieldAddTagsAutocompleter('buttons-before-left') ); + $components->addComponent( + new GridFieldInfoLink('buttons-before-left', '/at-taxonomy-overview', "Open 'All taxonomies' overview") + ); + $components->getComponentByType(GridFieldDataColumns::class)->setDisplayFields( [ 'getNameAsTagWithExtraInfo' => 'Name', diff --git a/src/Extensions/FileFormFactoryTaxonomyExtension.php b/src/Extensions/FileFormFactoryTaxonomyExtension.php index 5e06bde..b79ab22 100644 --- a/src/Extensions/FileFormFactoryTaxonomyExtension.php +++ b/src/Extensions/FileFormFactoryTaxonomyExtension.php @@ -8,6 +8,7 @@ use SilverStripe\Assets\Folder; use SilverStripe\Core\Extension; use SilverStripe\Forms\FieldList; +use SilverStripe\Forms\LiteralField; use SilverStripe\Forms\Tab; use SilverStripe\Forms\TreeMultiselectField; @@ -54,10 +55,15 @@ public function updateFormFields(FieldList $fields, $controller, $formName, $con ->setEmptyString('Add tags by name') ->setShowSearch(true); - $fields->addFieldToTab( - 'Editor.Tags', - $tags + $taxonomiesOverviewLink = LiteralField::create( + 'TaxonomiesOverviewLink', + 'Open \'All taxonomies\' overview' ); + + $fields->addFieldsToTab('Editor.Tags', [ + $tags, + $taxonomiesOverviewLink, + ]); } } } diff --git a/src/Forms/GridFieldInfoLink.php b/src/Forms/GridFieldInfoLink.php new file mode 100644 index 0000000..07e3f8f --- /dev/null +++ b/src/Forms/GridFieldInfoLink.php @@ -0,0 +1,64 @@ +targetFragment = $targetFragment; + $this->url = $url; + $this->label = $label; + } + + + /** + * @param GridField $gridField + * @return array + */ + public function getHTMLFragments($gridField) + { + $fragment = ArrayData::create([ + 'Url' => $this->url, + 'Label' => $this->label, + ])->renderWith(self::class); + + return [$this->targetFragment => $fragment]; + } +} diff --git a/src/Models/TaxonomyTerm.php b/src/Models/TaxonomyTerm.php index caefdba..793d962 100644 --- a/src/Models/TaxonomyTerm.php +++ b/src/Models/TaxonomyTerm.php @@ -37,6 +37,7 @@ use SilverStripe\Security\PermissionProvider; use SilverStripe\Versioned\GridFieldArchiveAction; use SilverStripe\View\ViewableData; +use SilverStripe\View\ArrayData; use UndefinedOffset\SortableGridField\Forms\GridFieldSortableRows; /** @@ -692,6 +693,44 @@ public function getTermHierarchy(string $separator = ' ▸ ', callable $termsDec } + /** + * Get term depth in the hierarchy + * + * @param bool $asArrayList + * @return int + */ + public function getTermLevel(): int + { + $level = 0; + $term = $this; + + while ($term->ParentID) { + $level++; + $term = $term->Parent(); + } + + return $level; + } + + + /** + * Get a list of dummy position indicators for use in templates + * to e.g. indent terms or so + * + * @return ArrayList + */ + public function getTermLevelList(): ArrayList + { + $list = ArrayList::create([]); + + for ($i = 0; $i < $this->getTermLevel(); $i++) { + $list->push(ArrayData::create(['Pos' => $i])); + } + + return $list; + } + + /** * Description limited to 15 words for limited spaces such as gridfields * diff --git a/templates/Chrometoaster/AdvancedTaxonomies/Controllers/TaxonomyOverviewController.ss b/templates/Chrometoaster/AdvancedTaxonomies/Controllers/TaxonomyOverviewController.ss new file mode 100644 index 0000000..e04361b --- /dev/null +++ b/templates/Chrometoaster/AdvancedTaxonomies/Controllers/TaxonomyOverviewController.ss @@ -0,0 +1,36 @@ + + + + + + + + + + Advanced Taxonomies overview + + + + + +

Taxonomies overview

+ <% if $ParentTerm %>

Parent term: {$ParentTerm.Title}

<% end_if %> + + <% include Chrometoaster\AdvancedTaxonomies\Controllers\TaxonomyOverviewController_Terms %> + + + diff --git a/templates/Chrometoaster/AdvancedTaxonomies/Controllers/TaxonomyOverviewController_TermRow.ss b/templates/Chrometoaster/AdvancedTaxonomies/Controllers/TaxonomyOverviewController_TermRow.ss new file mode 100644 index 0000000..48656a6 --- /dev/null +++ b/templates/Chrometoaster/AdvancedTaxonomies/Controllers/TaxonomyOverviewController_TermRow.ss @@ -0,0 +1,14 @@ +<% loop $Terms.Sort('Sort') %> + + <% if $TermLevel == 0 %> + {$Name} + <% else %> + <% loop $TermLevelList %> - <% end_loop %>{$Name} + <% end_if %> + {$Description} + {$AuthorDefinition} + + <% if $Children.count %> + <% include Chrometoaster\AdvancedTaxonomies\Controllers\TaxonomyOverviewController_TermRow Terms=$Children %> + <% end_if %> +<% end_loop %> diff --git a/templates/Chrometoaster/AdvancedTaxonomies/Controllers/TaxonomyOverviewController_Terms.ss b/templates/Chrometoaster/AdvancedTaxonomies/Controllers/TaxonomyOverviewController_Terms.ss new file mode 100644 index 0000000..6c06519 --- /dev/null +++ b/templates/Chrometoaster/AdvancedTaxonomies/Controllers/TaxonomyOverviewController_Terms.ss @@ -0,0 +1,12 @@ + + + + + + + + + + <% include Chrometoaster\AdvancedTaxonomies\Controllers\TaxonomyOverviewController_TermRow %> + +
TermDescriptionAuthor definition
diff --git a/templates/Chrometoaster/AdvancedTaxonomies/Forms/GridFieldInfoLink.ss b/templates/Chrometoaster/AdvancedTaxonomies/Forms/GridFieldInfoLink.ss new file mode 100644 index 0000000..2c60734 --- /dev/null +++ b/templates/Chrometoaster/AdvancedTaxonomies/Forms/GridFieldInfoLink.ss @@ -0,0 +1,5 @@ + + + {$Label.XML} + +