1

I have this requirement where I would need to create a menu every time a user creates a new instance of a custom entity I'm building. One can easily do this with Menu::create() on entity creation, but there is one problem: Menus are configuration.

When one creates a menu either programmatically or via menu admin, it creates "unexported configuration" of that menu that lives in the DB. The next time code is deployed and those menus aren't exported to code, those menus either get deleted (if empty) or halt the deploy (if there are menu links present).

I was hoping to preserve the menu functionality (menu management, etc.) but have them not be config. Is there a way to create menus that aren't configuration?

1

Not exactly. You could theoretically build non-config menus with a custom module, but I don't think that's what you want to do.

You can, however, get keep the menus as config, but keep them from being exported / imported. You can use two contrib modules to do this.

The first module, Config ignore is required. This module allows to set config files that should be ignored when importing config via its UI at admin/config/development/configuration/ignore. Some example configuration for your situation might look like:

system.menu.*
~system.menu.main
~system.menu.admin

The first line will tell config_ignore to prevent all menu configs from being imported. The second line tells it to unignore the main menu configuration, the third line tells it to unignore the admin menu configuration. This would prevent any of your on-the-fly menus from being deleted during import, but allow you to keep the main and admin menus managed via your configuration. Obviously, you can also unignore any number of additional menus.

One minor issue with config_ignore is that it only prevents configuration from being imported, it doesn't stop them from being exported. So, for example, if you were to pull your prod DB down to your local environment and then export your config, all of the configuration for those new menus will be exported to the sync directory. All of those configuration files will be ignored on the import end so it doesn't hurt, but I don't like having a bunch of extra config in my sync directory that 1. isn't used and, 2. isn't an accurate representation of the actual state of the menus.

The second module, Config Split is optional, but I like to use it in this situation to help keep things tidy; it solves the minor issue with config_ignore that I mentioned in the last paragraph.

Config split lets you split some configuration from the main sync directory to other directories. The main way I've used this is to split out environment specific configuration to environment specific directories. For example, I have one split for my local environment, a second for staging, and another for prod. However, config_split also allows you to use a special database storage, instead of a file directory, if you don't define a split directory, i.e. leave that field empty. This is a great feature because you can use it to route all of the menu configuration files, the files that you're ignoring with config_ignore, to the special database storage. This keeps them out of your sync directory, thus removing all that clutter!

To use this special database storage, navigate to Config Split's UI at /admin/config/development/configuration/config-split and Add A Configuration Split Setting. First, give it a label, e.g. Database Storage. Second, in the COMPLETE SPLIT section, enter settings in the Additional Configuration field that are identical to what you entered in the config_ignore settings. For example:

system.menu.*
~system.menu.main
~system.menu.admin

That's it. Boom! The menus that you programmatically created on prod won't be deleted when you deploy. The configuration for those items now lives totally in the database.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.