Problem/Motivation

The current iplementation of drupal-menu-hierarchy does not support more than 1000 menu links per level. For more detail, see this comment.

Proposed resolution

There are a few ways to handle this:
A) Recommend not having so many menu items ;)
B) Make the padding length configurable
C) Dynamically determine the padding length per level

CommentFileSizeAuthor
#11 decoupled_menus-3204132.patch8.72 KBjohnny5th

Comments

gabesullice created an issue. See original summary.

baddysonja’s picture

johnny5th’s picture

I've tried to look around for a reasoning behind the padding on the hierarchy string, but cannot find any. If we have a delimiter, do we even need padding?

2nd thought, since Extension Target Attribute values must be represented by an array, can we get rid of the delimiter and padding altogether and use multiple array values?

{
  "drupal-menu-hierarchy":[".002.002"]
}

vs

{
  "drupal-menu-hierarchy":[2,2]
}
nod_’s picture

With the string it's very easy to sort the links, just need to compare the strings, with an array it's not hard but it's less simple.

Can't remember either why it's a string.

johnny5th’s picture

Comments on the proposed resolutions:

  • A) Baking a max-length limitation into the Core menu system seems really wrong. If Core allows a user can put 100k menu items into their menu (but why?), then we shouldn't limit them from doing that with the linkset endpoint.
  • B) Making the padding length configurable puts a burden on the site builder to either know the eventual size of their application ahead of time or have the foresight to change the configuration when their application approaches the limit. If the padding is made configurable, a warning needs to be generated when a menu level approaches the limit.
  • C) Dynamically determining the padding has it's own caveats (generation overhead, variability of length/format for site builders who write their own client), but would produce the fewest surprises.

In my opinion the simplicity of string comparison operators doesn't warrant the introduction of a length limitation. Since the Initiative intends to provide a front-end library for consuming the menus, I propose the linkset should serve the hierarchy in an array format, and the front-end library handles the complexity for the site builders.

brianperry’s picture

I suppose we can't just have people install https://www.drupal.org/project/menu_item_limit :)

Jokes aside, I agree with @johnny5th that providing the hierarchy in an array seems like the right solution here. It does seem like it will add some complexity in handling the data, but I think the hierarchy is already complex enough that many would want to turn to our module to assist with this anyway.

I created a quick archive of the linkset-menu module that was initially created to parse this: https://github.com/backlineint/linkset-menu Planning on finding a permanent home for that soon. Maybe we could prove this out by trying to update that library to provide the same response with hierarchy data provided in an array?

bbrala’s picture

I agree that the hyrarchy using real ints seems like an good idea.

gabesullice’s picture

Here is the background reasoning for strings with a known length: https://www.drupal.org/project/decoupled_menus/issues/3196342#comment-14...

The gist is that the hierarchy string has nice properties which make operations on the hierarchy itself, such as finding a link's parent,fast and easy to implement.

FWIW, an array of integers would not comply with the current linkset spec. However, we could do an array of strings and remain compliant, e.g.:

{
  "drupal-menu-hierarchy": ["2", "2"]
}

My preference is option C of the proposed resolution because it keeps more of the implementation complexity on the back end.

johnny5th’s picture

Thanks for clarifying @gabesullice! I really like your idea of storing the entire hierarchy in the field for all of the reasons that you mentioned. I'd love to further discuss the actual complexity hit to the front-end if we pre-split the hierarchy string into an array of strings (you're 100% correct about each value needing to be a string, I missed that in the spec.)

For the sake of discussion, I repeated your examples using the array-based storage on this JSFiddle (results are in the console). I also added a sorting algorithm, since we'd be comparing that against your original scheme's string sort.

I think the sorting algorithm bares the brunt of the increased complexity on the front-end, but don't think it's enough to warrant pre-joining the hierarchy on the backend. The other examples feel pretty similar to what you had already, especially as I borrowed your period-delimited scheme for comparing array contents.

gabesullice’s picture

Thanks for the examples! I'm don't feel strongly either way, so let's go with the array of strings. I like that each value clearly corresponds to the link's "weight" within a particular sub-tree. I do think we lose a bit of simplicity in the serialized document, but that might buy some flexibility on the back end. For example, it might make it easier to insert links in an alter step.

johnny5th’s picture

StatusFileSize
new8.72 KB

Attached is a patch based on the latest commits on https://www.drupal.org/project/drupal/issues/3227824. It provides both code and documentation changes to implement the hierarchy attribute as an array of strings. I can push the changes to that core issue, but I wasn't sure if there is enough consensus to implement.

brianperry’s picture

Status: Active » Reviewed & tested by the community

Reviewed this patch and it makes sense to me. Applied cleanly against the current core patch. Tested locally and it behaved as I expected.

I'm marking this as RTBC with the huge caveat that we can't merge this patch since it is based on the core patch.

@johnny5th as a next step, what do you think about creating a new branch on the issue fork for https://www.drupal.org/project/drupal/issues/3227824 that contains these changes. And maybe post the patch you posted here (or the latest comparable version) as an interdiff as well. My hope is that is the lowest friction way to try to get some consensus around this change.