District Core Developer DocsDistrict Core Developer Docs
Developers
Boilerplate
Modules
Bitbucket
Developers
Boilerplate
Modules
Bitbucket
  • Modules

    • ABN
    • ActivityLog
    • AnalyticsApi
    • ApiConnector
    • BlockApi
    • CategoryApi
    • CloneApi
    • CommentApi
    • ContentApi
    • Core
    • Documents
    • EmbedApi
    • Event
    • ExportApi
    • FeatureApi
    • FormApi
    • GTM
    • GalleryApi
    • HelpApi
    • Hotspot
    • IdeaSurvey
    • ImportApi
    • InteractionsApi
    • Intercom
    • MailApi
    • MapApi
    • MapSurvey
    • MediaApi
    • MenuApi
    • MetaTagApi
    • NlpApi
    • NotificationApi
    • Page
    • ParentableContent
    • PaymentApi
    • PermissionsApi
    • Postcode
    • ReCaptcha
    • Redirects
    • Renderer
    • ReportApi
    • RestrictionApi
    • RevisionApi
    • SearchApi
    • Settings
    • ShareableApi
    • Slack
    • SlugApi
    • SubscribableApi
    • Survey
    • Team
    • TenantApi
    • TestApi
    • ThemeApi
    • Timeline
    • TranslationApi
    • Update
    • Users
    • VisualisationApi
    • WorkflowApi
    • Wysiwyg

MenuAPI Module

This module provides an abstraction layer for getting and setting menu items. Default menu trees are in Config/menu_trees.php. This module gets loaded first (see module.json priority) and creates a new MenuRepository as a singleton in the service provider. Other modules and app can then get/set/add to menu trees in a dedicated definition file under Plugins/MenuLinks.

NOTE: If your module has a priority lower than -1000 (this module priority), you won't be able to access the default menu_trees provided by this module.

Menu trees

The following trees are available:

  • frontend_main
  • frontend_footer
  • dash

Menu definitions

Menu definitions should:

  • Be located under app/Plugins/MenuLinks or Modules/[ModuleName]/Plugins/MenuLinks
  • Extend Modules/MenuApi/Plugins/MenuLinks/BaseMenuDefinition that implements Modules/MenuApi/Contracts/MenuDefinitionInterface
  • Define links in their constructor by calling $this->menu()->...

Examples

Anatomy of a menu link

 $link = [
   'label' => 'Link label',
   'href' => 'Url for link (only used if route unavailable)',
   'route' => 'a.route.name',
   'params' => ['params' => 'if', 'route' => 'used'],
   'icon' => 'a-district-icon-code',
   'children' => ['array of child links'],
   'permission' => 'can do permission',
   'addToChildren' => false, // VerticalMenu: Prepend parent to children it has any, default is true.
 ];

Adding a link to a menu via a menu definition.

class MenuDefinition extends \Modules\MenuApi\Plugins\MenuLinks\BaseMenuDefinition
{
    public function __construct() {       
        // Add a link to the end of the `dash` tree.
        $this->menu()->addToMenuTree(MenuService::TREE_NAME_DASH, [
            'route' => 'dashboard.example_module.index',
            'icon' => 'icon-name',
            'title' => 'Example',
        ]);
        
        // Add breadcrumbs.
    }
}

Updating a tree via via a menu definition..

class MenuDefinition extends \Modules\MenuApi\Plugins\MenuLinks\BaseMenuDefinition
{
    public function __construct() {       
        // Remove first link in the `dash` tree.
        $tree = $menuProvider->getMenuTreeCurrentState('dash');
        unset($tree[0]);
        $this->menu()->setMenuTree('dash', $tree);
    }
}

Config overrides

Possible to override the menu_trees config at app level that will override the starter menus and menu list.

Breadcrumbs

Breadcrumbs are defined in a very similar way to menu links. A repository is used to cache all breadcrumb definitions and the current matching breadcrumbs are added to the page props so they can be rendered by the frontend.

Anatomy of the breadcrumb map

Breadcrumb map is keyed by the uri pattern that should match the current page with the value being an array of links (see menu link structure above).

[
  'path/that/matches/current/uri' => [$breadcrumbLink, $breadcrumbLink, $breadcrumbLink],
  'path/with/exact/{model}/uri/match' => [$breadcrumbLink, $breadcrumbLink, $breadcrumbLink],
  'path/with/wildcard/*/uri/match' => [$breadcrumbLink, $breadcrumbLink, $breadcrumbLink],
]

Matching uris

  • A full uri match is first the preference. See php artisan route:list or request()->route()->uri() for what this might look like for a given page. Eg dash/pages/{page} will match on that route exactly.
  • A fallback is a wildcard match, this is useful when many pages have the same breadcrumbs. Eg. dash/pages/* will match dash/page/1, dash/page/1/edit, etc

To get the current crumbs for the given url you can:

MenuService::getBreadcrumbsForUri(request()->route()->uri())

Getting current breadcrumbs in the frontend

The current matching breadcrumbs are passed to the frontend via global props and can be accessed with

this.$page.props.district.Breadcrumbs

If no breadcrumbs are found, this prop should still exist but be an empty array.

Defining breadcrumbs in your module

Breadcrumbs are defined in a MenuDefinition plugin (along with menu links as described above). An example of defining breadcrumbs for a path is

class MenuDefinition extends \Modules\MenuApi\Plugins\MenuLinks\BaseMenuDefinition
{
    public function __construct() {       
        // Define breadcrumbs for `path/to/*/content/*`
        $this->breadcrumbs()->setBreadcrumbs('path/to/*/content/*', [
            [
                'route' => 'dashboard.example_module.index',
                'title' => 'Crumb 1',
            ],
            [
                'route' => 'dashboard.example_module.index',
                'title' => 'Crumb 2',
            ],
        ]);
        
        // Add menu links.
    }
}

There are many more helpers other than setBreadcrumbs, see BreadcrumbProvider for docs.

Using context in breadcrumbs

Often breadcrumbs need to have context, eg showing the current model/url or the current models parent.

Eg. If you are on a survey that has a parent, you probably want Parents > parent > surveys. In this case parent will be dynamic and need context.

To use context, add a key to the link type with value of context, then for the title and href of the link, add the Json path to get that value from this.$page.props.

Example of defining breadcrumbs that have a dynamic context

class MenuDefinition extends \Modules\MenuApi\Plugins\MenuLinks\BaseMenuDefinition
{
    public function __construct() {       
        // Define breadcrumbs for `path/to/*/content/*`
        $this->breadcrumbs()->setBreadcrumbs('path/to/*/content/*', [
            // Default static crumb. 
            [
                'route' => 'dashboard.example_module.index',
                'title' => 'Crumb 1',
            ],
            // The below crumb will populate from the page props.
            [
                'type' => 'context',
                'title' => 'parentableModel.title',
                'href' => 'parentableModel.action_urls.show',
            ],
        ]);
        
        // Add menu links.
    }
}

This should result in something like below when on path/to/*/content/*

this.$page.props.district.Breadcrumbs === [
    {title: 'Crumb 1', route: 'dashboard.example_module.index'},
    {title: 'Parentable model title', href: `parentable/model/url`}  
]

Edit this page
Prev
MediaApi
Next
MetaTagApi