Skip to content

Commit

Permalink
feat: better core subsites support
Browse files Browse the repository at this point in the history
  • Loading branch information
wilr committed Aug 10, 2023
1 parent 395d5b6 commit c50fcec
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 51 deletions.
82 changes: 46 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,11 @@ be deleted through the CMS.

```yaml
Heyday\MenuManager\MenuSet:
default_sets:
- Main
- Footer
default_sets:
- Main
- Footer
```
### Creating MenuItems
Once you have saved your MenuSet you can add MenuItems.
Expand Down Expand Up @@ -73,7 +72,7 @@ Page as well the link will be overwritten by the Page you chose.
#### IsNewWindow
Can be used as a check to see if 'target="_blank"' should be added to links.
Can be used as a check to see if 'target="\_blank"' should be added to links.
### Disable creating Menu Sets in the CMS
Expand All @@ -82,7 +81,7 @@ disable the ability to create new Menu Sets in the CMS:

```yml
Heyday\MenuManager\MenuAdmin:
enable_cms_create: false
enable_cms_create: false
```

_Note: Non-default Menu Sets can still be deleted, to help tidy unwanted CMS
Expand All @@ -91,46 +90,44 @@ content._
### Usage in template

```html
<% loop $MenuSet('YourMenuName').MenuItems %>
<a href="{$Link}" class="{$LinkingMode}">{$MenuTitle}</a>
<% end_loop %>
<% loop $MenuSet('YourMenuName').MenuItems %>
<a href="{$Link}" class="{$LinkingMode}">{$MenuTitle}</a>
<% end_loop %>
```

To loop through *all* MenuSets and their items:
To loop through _all_ MenuSets and their items:

<% loop $MenuSets %>
<% loop $MenuItems %>
<a href="$Link" class="$LinkingMode">$MenuTitle</a>
<% end_loop %>
<% end_loop %>
<% loop $MenuSets %>
<% loop $MenuItems %>
<a href="$Link" class="$LinkingMode">$MenuTitle</a>
<% end_loop %>
<% end_loop %>

Optionally you can also limit the number of MenuSets and MenuItems that are looped through.

The example below will fetch the top 4 MenuSets (as seen in Menu Management), and the top 5 MenuItems for each:

<% loop $MenuSets.Limit(4) %>
<% loop $MenuItems.Limit(5) %>
<a href="$Link" class="$LinkingMode">$MenuTitle</a>
<% end_loop %>
<% end_loop %>
<% loop $MenuSets.Limit(4) %>
<% loop $MenuItems.Limit(5) %>
<a href="$Link" class="$LinkingMode">$MenuTitle</a>
<% end_loop %>
<% end_loop %>

#### Enabling partial caching

[Partial caching](https://docs.silverstripe.org/en/4/developer_guides/performance/partial_caching/)
can be enabled with your menu to speed up rendering of your templates.

```html
<% with $MenuSet('YourMenuName') %>
<% cached 'YourMenuNameCacheKey', $LastEdited, $MenuItems.max('LastEdited'), $MenuItems.count %>
<% if $MenuItems %>
<nav>
<% loop $MenuItems %>
<a href="{$Link}" class="{$LinkingMode}"> $MenuTitle.XML </a>
<% end_loop %>
</nav>
<% end_if %>
<% end_cached %>
<% end_with %>
<% with $MenuSet('YourMenuName') %> <% cached 'YourMenuNameCacheKey',
$LastEdited, $MenuItems.max('LastEdited'), $MenuItems.count %> <% if $MenuItems
%>
<nav>
<% loop $MenuItems %>
<a href="{$Link}" class="{$LinkingMode}"> $MenuTitle.XML </a>
<% end_loop %>
</nav>
<% end_if %> <% end_cached %> <% end_with %>
```

### Allow sorting of MenuSets
Expand All @@ -139,16 +136,29 @@ By default menu sets cannot be sorted, however, you can set your configuration t

```yaml
Heyday\MenuManager\MenuSet:
allow_sorting: true
allow_sorting: true
```

## Subsite Support

### Code guidelines
If you're using SilverStripe Subsites, you can make MenuManager subsite aware
via applying an extension to the MenuSet.

This project follows the standards defined in:
_app/\_config/menus.yml_

* [PSR-1](http://www.php-fig.org/psr/psr-1/)
* [PSR-2](http://www.php-fig.org/psr/psr-2/)
```
Heyday\MenuManager\MenuSet:
create_menu_sets_per_subsite: true
extensions:
- Heyday\MenuManager\Extensions\MenuSubsiteExtension
Heyday\MenuManager\MenuItem:
extensions:
- Heyday\MenuManager\Extensions\MenuSubsiteExtension
```
## Code guidelines
This project follows the standards defined in:
- [PSR-1](http://www.php-fig.org/psr/psr-1/)
- [PSR-2](http://www.php-fig.org/psr/psr-2/)
13 changes: 13 additions & 0 deletions _config/extensions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
Name: menu-manager#extensions
Only:
classexists: '\SilverStripe\Subsites\Model\Subsite'
---
SilverStripe\Subsites\Model\Subsite:
has_many:
- MenuSets => 'Heyday\MenuManager\MenuSet'
cascade_deletes:
- MenuSets
Heyday\MenuManager\MenuAdmin:
extensions:
- SilverStripe\Subsites\Extensions\SubsiteMenuExtension
67 changes: 67 additions & 0 deletions src/Extensions/MenuSubsiteExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace Heyday\MenuManager\Extensions;

use Heyday\MenuManager\MenuSet;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\HiddenField;
use SilverStripe\ORM\DataExtension;
use SilverStripe\Subsites\State\SubsiteState;

if (!class_exists('\SilverStripe\Subsites\Model\Subsite') || !class_exists('\SilverStripe\Subsites\State\SubsiteState')) {
return;
}

class MenuSubsiteExtension extends DataExtension
{
private static $has_one = [
'Subsite' => 'SilverStripe\Subsites\Model\Subsite'
];

public function updateCMSFields(FieldList $fields)
{
$fields->replaceField('SubsiteID', new HiddenField('SubsiteID'));
}

public function onBeforeWrite()
{
if (!$this->owner->SubsiteID) {
$this->owner->SubsiteID = \SilverStripe\Subsites\State\SubsiteState::singleton()->getSubsiteId();
}
}


public function requireDefaultRecords()
{
if ($this->owner->config()->get('create_menu_sets_per_subsite')) {
$subsites = \SilverStripe\Subsites\Model\Subsite::get();
$names = $this->owner->getDefaultSetNames();

if ($names) {
foreach ($subsites as $subsite) {
$state = \SilverStripe\Subsites\State\SubsiteState::singleton();

$state->withState(function () use ($subsite, $names) {
\SilverStripe\Subsites\State\SubsiteState::singleton()->setSubsiteId($subsite->ID);

foreach ($names as $name) {
$existingRecord = MenuSet::get()
->filter([
'Name' => $name,
'SubsiteID' => $subsite->ID
])
->first();

if (!$existingRecord) {
$set = MenuSet::create();
$set->Name = $name;
$set->SubsiteID = $subsite->ID;
$set->write();
}
}
});
}
}
}
}
}
18 changes: 16 additions & 2 deletions src/MenuAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

use SilverStripe\Admin\ModelAdmin;
use SilverStripe\Core\Config\Config;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldAddNewButton;
use SilverStripe\Forms\GridField\GridFieldImportButton;
Expand Down Expand Up @@ -80,4 +78,20 @@ public function getEditForm($id = null, $fields = null)

return $form;
}


public function getList()
{
$list = parent::getList();

if ($this->modelClass === MenuSet::class) {
if (class_exists('\SilverStripe\Subsites\State\SubsiteState')) {
$list = $list->filter([
'SubsiteID' => \SilverStripe\Subsites\State\SubsiteState::singleton()->getSubsiteId()
]);
}
}

return $list;
}
}
12 changes: 11 additions & 1 deletion src/MenuManagerTemplateProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public static function MenuSet($name): ?MenuSet
/**
* @return MenuSet|null
*/
public static function MenuSets(): ?MenuSet
public static function MenuSets(): ?DataList
{
return MenuSet::get();
}
Expand All @@ -54,8 +54,18 @@ public function findMenuSetByName(string $name): ?DataObject
if (empty($name)) {
throw new InvalidArgumentException("Please pass in the name of the MenuSet you're trying to find");
}

$result = MenuSet::get()->filter('Name', $name);

if ($result->exists() && $result->first()->hasExtension('Heyday\MenuManager\Extensions\MenuSubsiteExtension')) {
$result = $result->where(sprintf(
'SubsiteID = %s',
\SilverStripe\Subsites\State\SubsiteState::singleton()->getSubsiteId()
));
}

$this->extend('updateFindMenuSetByName', $result);

return $result->first();
}
}
43 changes: 31 additions & 12 deletions src/MenuSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldAddExistingAutocompleter;
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
use SilverStripe\Forms\TabSet;
use SilverStripe\Forms\TextareaField;
Expand Down Expand Up @@ -37,6 +38,10 @@ class MenuSet extends DataObject implements PermissionProvider
'MenuItems'
];

private static array $cascade_duplicates = [
'MenuItems'
];

private static array $searchable_fields = [
'Name',
'Description'
Expand Down Expand Up @@ -70,7 +75,6 @@ public function validate()
* Use an index for the Name field instead https://docs.silverstripe.org/en/4/developer_guides/model/indexes/
*/
if ($existing && $existing->ID !== $this->ID) {
// MenuSets must have a unique Name
$result->addError(
_t(
__CLASS__ . 'AlreadyExists',
Expand Down Expand Up @@ -177,19 +181,34 @@ public function requireDefaultRecords(): void
{
parent::requireDefaultRecords();

foreach ($this->getDefaultSetNames() as $name) {
$existingRecord = MenuSet::get()
->filter('Name', $name)
->first();
if ($this->createDefaultMenuSets()) {
DB::alteration_message(sprintf(
"MenuSets created (%s)",
implode(', ', $this->getDefaultSetNames())
), 'created');
}
}

if (!$existingRecord) {
$set = MenuSet::create();
$set->Name = $name;
$set->write();

DB::alteration_message("MenuSet '$name' created", 'created');
public function createDefaultMenuSets()
{
if ($this->getDefaultSetNames()) {
foreach ($this->getDefaultSetNames() as $name) {
$existingRecord = MenuSet::get()
->filter('Name', $name)
->first();

if (!$existingRecord) {
$set = MenuSet::create();
$set->Name = $name;
$set->write();
}
}

return true;
}

return false;
}


Expand All @@ -214,7 +233,7 @@ public function getCMSFields(): FieldList
);

$config->addComponent(new GridFieldOrderableRows('Sort'));

$config->removeComponentsByType(GridFieldAddExistingAutocompleter::class);
$fields->addFieldToTab(
'Root.Meta',
TextareaField::create('Description', _t(__CLASS__ . '.DB_Description', 'Description'))
Expand Down Expand Up @@ -268,7 +287,7 @@ public function onBeforeDelete()
*
* @return string[]
*/
protected function getDefaultSetNames()
public function getDefaultSetNames()
{
return $this->config()->get('default_sets') ?: [];
}
Expand Down

0 comments on commit c50fcec

Please sign in to comment.