How to design a recursive menu schema?

30

1

I want to define a schema to store the content of a hierarchical menu, which has a depth not known in advance. Let the menu items be just link/caption pairs. This structure is self-contained, that is: it is not related to any pages/structure groups hierarchy, so it seems reasonable to use embedded schema(s) for the menu items.

The above sounds sound in theory, but in practice is a bit trickier. Here's what I've tried and got:

  1. Created MenuItem embedded schema and tried to make it's multivalue Items field reference itself. This didn't work from the start, because the UI is aware of this situation and hides the current schema from the available options in the embeddable field configuration.

  2. Cloned MenuItem as MenuItemEven and tried to crossreference them. The UI allows this. But the component creation form appears to be broken: after selecting the schema it just shows nothing, not even "normal", non-embeddable fields. (And it requires some brain-work to annihilate these schemas without breaking the schema design UI, the easiest one being "irreversible history rollback" for each).

  3. The only option that worked was to create dedicated embedded schemas for each level. Obviously, this required relaxing the initial condition of allowing the structure to have an infinite depth (and ditching the whole idea of recursion).

Intuitively it's clear why recursion of embedded schemas is not allowed: there's not even such an entity as "embedded schema" on content level, and the whole hierarchy of fields must be instantiated in advance down to the lowest ends.

But is there any "official" reason why recursive schemas are not possible in Tridion? Isn't it just UI limitation? XML/XSD shortcoming?

esteewhy

Posted 2013-02-19T21:59:45.627

Reputation: 279

Answers

38

XSD would allow for this, and it is a very commonly used pattern. The Tridion CME/FieldBuilder will not understand it though, so you'd have to create a custom schema and an editor to go with it.

I've done this in the past using Component links - you create a hierarchy, just like you defined it, but each entry in the menu is represented by a component, with links to its "children" components.

Since this is obviously hard to represent visually, this implementation was done with a custom page that allows editors to "see" the full hierarchy of the menus they are creating. At publish time this hierarchy was "flattened" into one XML file with the full navigation tree.

A - perhaps - better way to do this since Tridion 2009 is to use a Category and Keywords hierarchy to represent your menu structure.

Nuno Linhares

Posted 2013-02-19T21:59:45.627

Reputation: 27 884

Indeed, the UI will not understand the XML, since it won't be based on a "Tridion Web Schema". – Nuno Linhares – 2013-02-20T20:10:30.897

3+1 For the suggestion to use a Category and Keywords hierarchy to represent the menu structure in versions since Tridion 2009. This approach is very flexible and allows your navigation structure to be different than your Structure Group hierarchy if needed. – Jonathan Williams – 2013-03-07T10:36:47.337

Thanks Nuno,

So is this the final verdict:

  1. Technically possible, but ..
  2. .. not via UI?
  3. < – esteewhy – 2013-02-20T09:26:00.477

5

I'm seeing this pattern again with the popular "slide out" type navigation (from the hamburger menu) and can offer two follow-up considerations.

  1. The nested items are editorial (manually curated), not based on structure, but are (likely) related to existing content. So rather than just links of Components to other Components, also add these links to existing pages or components.
  2. Make a "flat" Schema with all the links in it, similar to how we indent text when making a hierarchy.
  3. Use folders instead of Structure Groups.

The first approach would be to have each page reference its related content, which could then be:

  • Components linked from Page Metadata
  • Component Presentations on each page
  • Components linked from a "main" Component

These would then be flattened on Publish just like with Nuno's approach. The catch with component links on any approach is when to resolve them and handling the same Component in different Pages, but that's another discussion.

The flat approach replicates what we do in documents. when making a hierarchy with text (in Word, OneNote, TRex, etc.), we use indentation:

  • Item 1.0 at Level 1
    • Item 1.1 Level 2
    • Item 1.2 at Level 2
      • Item 1.2.1 at Level 3
  • Item 2.0 at Level 1

But we don't have an "indent" option for Schemas (unless you consider manually making bullets in Rich Text Format areas), so a rough interpretation could be a field for level like so:

Using radio buttons to mimic indents

The pro is a form that has all of its links inside with no additional Schemas are needed with a con on needing to handle the logic for the "indents."

Finally, components in folders could also work because the nesting can be "infinite" and editors could cut, copy, and paste items between folders.

With any approach, I'd recommend consolidating these Components with whatever manages page and/or SEO information.

Update: also consider performance in any case. As a web content management system designed for websites and their editors, I've hundreds to thousands of items work well in the Content Manager Explorer lists and forms. Very large forms can have an impact to performance as well as managing the items (where infinite scrolling is definitely not ideal).

Alvin Reyes

Posted 2013-02-19T21:59:45.627

Reputation: 8 870

Interesting approach. This allows for the full navigation to be created in one component, however is still somewhat cumbersome when it comes to editors reviewing the navigation in the CME. Also, potentially, it could become a bit slow loading in very large navigation structure. – Chris Morgan – 2015-01-08T03:38:26.343

Yeah, it'll be more cumbersome the more fields you have per item. For a single (Component) link, this will feel a like like moving "pages" in One Note. I'll add a caveat on performance. – Alvin Reyes – 2015-01-13T01:25:28.077

3

Although your question specifically mentions that the design you are considering involves embedded schemas, you could aslo solve the same problem using a taxonomy. If as you say, all you need is name value pairs, then keywords would allow you to capture these, and also the hierarchy. If you want to add something like a component link, then this too is possible by adding suitable metadata to your keywords.

After publishing the taxonomy, the data for your menu will be available via the Content Delivery API.

Dominic Cronin

Posted 2013-02-19T21:59:45.627

Reputation: 14 997