What's on the Menu, Symfony?
Menus are often considered as the domain of front end developers as they're mostly tangible on through trends like Hamburger Menus, Mega Menus and other design fads. Yet due to their central role in most experiences on the web, they should be architected just as any other vital application component.
In the minds of many developers menus are similar to forms as they are mundane, completely lack glamour and are a "minor detail". Yet both are central to the experience of both the administrator end users of the website or web application.
Menu management as an afterthought easily leads to horrible implementation, useless repetition and limited flexibility for real-world use cases. Frustration all around, over such a trivial thing as menus. It's a lose-lose.
Don't write that dirty menu array!
I've repeated myself countless times by writing simple arrays and looping through them in the template. In many cases that has worked fine, but in many cases I've needed to create some exceptions and maybe a quick link to an external site. In time this piles up to creating monster menus that nobody dares to touch.
There are a number of options for building menus in PHP, but the de-facto standard method for Symfony Framework is the KnpMenuBundle. It uses the KnpMenu library which is an object oriented PHP library for constructing and rendering menus.
Together with the Symfony Framework integration it covers a lot of routine tasks needed for menu development. KnpMenu offers a familiar interface for developers to construct menus across different Symfony (and PHP in general) applications.
Rightfully as a library KnpMenu focuses only on the structure and rendering, but does not define where the data for the menus are coming from.
To integrate deeper with the Symfony Framework, there are additional bundles that ease menu creation. One of the most simple and practical ones is the Rollerworks NavigationBundle, which allows application menus to be defined in the application configuration:
The above configuration approach simplifies creation, but can be too limiting for more dynamic menus. Symfony applications often use a database and the Doctrine ORM. Persisting menu items as entities can be done with the KtwDatabaseMenuBundle:
The above menu being a standard Doctrine object it can be managed with the EasyAdminBundle or any other interface.
However choose to construct and persist your menu is that you'll always work with familiar menu item objects. They remain the same regardless of the backend used to generate the menus and your templating logic will have been future proof from day one.
The above are just some examples of options that are available and there are plenty more options, some of which are linked at the end of the article.
CMSes are mediocre, but can excel in menus
CMSes are multipurpose tools that often lead to mediocre results if they are stretched beyond their comfort limits. In many cases a purpose built application might give better end results more efficiently than the initially perceived ease of using a CMS vs a framework.
With all the common features covered, what breaks or makes a popular CMS is the editor experience. Where Symfony struggles to have an identifiable interface, content management tools like WordPress and Concrete 5 provide a familiar interface for users.
One key ingredient in great CMSes is menu management. While Open Source generally lags in user experience. The four Content Management Systems I develop with regularly each have a distinct approach to menu management:
- Bolt CMS: Menus in YAML - flexible but dev centric
- Drupal: Menu blocks - flexible, but can be confusing
- eZ Platform: Content tree structure - intuitive, but not very flexible
- WordPress: Free form menus - flexible and easy to use
While I have criticized WordPress, it does shine when it comes to the user experience. WordPress sets the gold standard for menu management with it's flexible and intuitive menu editor for any system I have used:
Due to the tight coupling of the straightforward content model (content, pages, categories) the editor provides excellent tools for end users to craft their menus with unparallelled flexibility.
So the next time you're starting a new project - consider how you'll build and manage your menus from day one. Using something like the KnpMenu library may add some learning overhead in the beginning, but the payoff comes later.
Or latest in your next project when you don't need to create a mechanism on how to mark that this page is now active in the menu. And those who consume your menu via JSON will be delighted that the structure remains consistent.
More on Menus:
- Elcodi MenuBundle
- Symfony CMF MenuBundle
- ORO NavigationBundle
- Kunstmaan MenuBundle
- WordPress OakTree navigation plugin