Building Custom Trees in Umbraco 14 using menus!

Table of Contents

Some Thoughts

Building Custom Menu Item Components

Rendering Menu Items with Umbraco’s UI Menu Item Component
Example: Fetching and Rendering a Dynamic Tree

Manifests

Defining the Tree Space with ManifestSectionSid…


This content originally appeared on DEV Community and was authored by Yari Mariën

Table of Contents

  1. Some Thoughts
  2. Building Custom Menu Item Components
    • Rendering Menu Items with Umbraco's UI Menu Item Component
    • Example: Fetching and Rendering a Dynamic Tree
  3. Manifests
    • Defining the Tree Space with ManifestSectionSidebarApp
    • Defining the Menu with ManifestMenu
    • Linking the Custom Elements with ManifestMenuItem
  4. Final Result

Some Thoughts

There are several methods to create custom trees. One approach is using a full Tree structure, which involves numerous components like ManifestTree, ManifestTreeItem, ManifestTreeStore, DataSource, Repository, and many more files.

File structure Umbraco document section

However, I find this approach overly complex and unnecessary for small, simple trees.

For a basic tree with, I prefer using a menu with custom-rendered menu items using a custom Lit element, as I will demonstrate in this example.

Building Custom Menu Item Components

Rendering Menu Items with Umbraco's UI Menu Item Component

To render your menu items in Umbraco, you can make use of the powerful Umbraco UI Menu Item component. This component allows you to easily create nested menu structures with just a few lines of code.

Example:

<uui-menu-item label="Menu Item 1" has-children>
    <uui-menu-item label="Nested Menu Item 1"></uui-menu-item>
    <uui-menu-item label="Nested Menu Item 2"></uui-menu-item>
</uui-menu-item>

Image of result example code

Example: Fetching and Rendering a Dynamic Tree

In this example, the entire tree is fetched when the component is rendered. Once the data is loaded, we put the items in a @state(). This will trigger a re-render of the tree because it is a reactive property.

With the retrieved data, I dynamically render nested menu items, each with relevant icons. The core functionality of the tree such as opening, closing, and indenting nodes comes from the menu item component itself.

To display the caret icon indicating nested items, you can set the has-children attribute dynamically like this: ?has-children=${bool}.

menu-items.ts:

import { UmbMenuItemElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { html, TemplateResult } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { FormXTreeItemResponseModel, FormXTreeResource } from '../../../api';


const elementName = 'formx-menu-item';

@customElement(elementName)
class FormXMenuItems extends UmbLitElement implements UmbMenuItemElement {
    @state()
    private _items: FormXTreeItemResponseModel[] = []; // Store fetched items
    @state()
    private _loading: boolean = true; // Track loading state
    @state()
    private _error: string | null = null; // Track any errors

    constructor() {
        super();
        this.fetchInitialItems(); // Start fetching on component load
    }

    // Fetch initial items
    async fetchInitialItems() {
        try {
            this._loading = true;
            this._items = ((await FormXTreeResource.getFormxApiV1Tree()).items); // Fetch root-level items
        } catch (e) {
            this._error = 'Error fetching items';
        } finally {
            this._loading = false;
        }
    }

    // Render items
    renderItems(items: FormXTreeItemResponseModel[]): TemplateResult {
        return html`
            ${items.map(element => html`
                <uui-menu-item label="${element.name}" ?has-children=${element.hasChildren}>
                ${element.type === 1 
                ? html`<uui-icon slot="icon" name="icon-folder"></uui-icon>` 
                : html`<uui-icon slot="icon" name="icon-autofill"></uui-icon>`}
                    ${element.hasChildren ? this.renderItems(element.children) : ''}
                </uui-menu-item>
            `)}
        `;
    }

    // Main render function
    render() {
        if (this._loading) {
            return html`<uui-loader></uui-loader>`;
        }

        if (this._error) {
            return html`<uui-menu-item active disabled label="Could not load form tree!">
        </uui-menu-item>`;
        }

        // Render items if loading is done and no error occurred
        return html`${this.renderItems(this._items)}`;
    }
}



export { FormXMenuItems as element };

declare global {
    interface HTMLElementTagNameMap {
        [elementName]: FormXMenuItems;
    }
}

The result will be a menu that looks like the following:

Result of what our custom element would look like.

Manifests

For this setup, you'll need three key manifests that work together to render a tree using a custom menu.

Let’s start by defining a reusable alias:

const FORMX_MENU_ALIAS = "Our.Umbraco.FormX.menu";

Defining the Tree Space with ManifestSectionSidebarApp

The first manifest defines the space where your tree will appear. This is achieved by creating a ManifestSectionSidebarApp. We can connect the menu to the sidebar using the menu alias.

const sidebarApps: Array<ManifestSectionSidebarApp> = [
    {
        type: 'sectionSidebarApp',
        kind: 'menuWithEntityActions',
        alias: 'Our.Umbraco.FormX.sidebar',
        name: 'FormX Sidebar App',
        meta: {
            label: "Forms",
            menu: FORMX_MENU_ALIAS
        },
        conditions: [
            {
                alias: "Umb.Condition.SectionAlias",
                match: "Our.Umbraco.FormX.section"
            }
        ]
    }
];

Defining the Menu with ManifestMenu

Next, you’ll define the actual menu where your items will be rendered. For this we can use a ManifestMenu.

const menuManifest: Array<ManifestMenu> = [
    {
        type: 'menu',
        alias: FORMX_MENU_ALIAS,
        name: 'FormX Menu'
    }
];

Linking the Custom Elements with ManifestMenuItem

Lastly, we need to link our custom elements that fetch and render your menu items. This is where the ManifestMenuItem comes in.

const menuItemManifest: Array<ManifestMenuItem> = [
    {
        type: 'menuItem',
        alias: 'formx-menu-items',
        name: 'FormX Menu Items',
        meta: {
            label: 'FormX',
            menus: [FORMX_MENU_ALIAS]
        },
        element: () => import('./menu-items.ts')
    }
];

Final Result

Once the SectionSidebarApp is linked to our custom section, the tree will be rendered with the specified label and custom elements.

Example of what our custom section with our newly created custom tree would look like.


This content originally appeared on DEV Community and was authored by Yari Mariën


Print Share Comment Cite Upload Translate Updates
APA

Yari Mariën | Sciencx (2024-09-25T15:01:51+00:00) Building Custom Trees in Umbraco 14 using menus!. Retrieved from https://www.scien.cx/2024/09/25/building-custom-trees-in-umbraco-14-using-menus/

MLA
" » Building Custom Trees in Umbraco 14 using menus!." Yari Mariën | Sciencx - Wednesday September 25, 2024, https://www.scien.cx/2024/09/25/building-custom-trees-in-umbraco-14-using-menus/
HARVARD
Yari Mariën | Sciencx Wednesday September 25, 2024 » Building Custom Trees in Umbraco 14 using menus!., viewed ,<https://www.scien.cx/2024/09/25/building-custom-trees-in-umbraco-14-using-menus/>
VANCOUVER
Yari Mariën | Sciencx - » Building Custom Trees in Umbraco 14 using menus!. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/09/25/building-custom-trees-in-umbraco-14-using-menus/
CHICAGO
" » Building Custom Trees in Umbraco 14 using menus!." Yari Mariën | Sciencx - Accessed . https://www.scien.cx/2024/09/25/building-custom-trees-in-umbraco-14-using-menus/
IEEE
" » Building Custom Trees in Umbraco 14 using menus!." Yari Mariën | Sciencx [Online]. Available: https://www.scien.cx/2024/09/25/building-custom-trees-in-umbraco-14-using-menus/. [Accessed: ]
rf:citation
» Building Custom Trees in Umbraco 14 using menus! | Yari Mariën | Sciencx | https://www.scien.cx/2024/09/25/building-custom-trees-in-umbraco-14-using-menus/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.