Menu building pattern

I’m having troubles getting my head around the active-state handling of a menu when the menu isn’t used for routing.

I come from Drupal where the menu system handles the routing as well. so setting active state and active-trail state is handled by the route (that acts as a menu rendering system as well).

Now, a lot of PHP frameworks have Router classes that handle the routing. This seems a good separation since a Menu should not be aware of POST || OPTIONS || … requests.

But when writing the frontend, I found myself hard coding the menu. Or storing everything in the DB and passing those values to a view. What I don’t like this approach is that you are kind of creating a copy of what you already wrote in your Router but now using the Menu class.

An example:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>Route::get('/somewhere','routename.somewhere','showStuffController');
Route::post('/somewhere','routename.somewhere','saveStuffController');
Menu::add('label.somewhere','routename.somewhere');
</code>
<code>Route::get('/somewhere','routename.somewhere','showStuffController'); Route::post('/somewhere','routename.somewhere','saveStuffController'); Menu::add('label.somewhere','routename.somewhere'); </code>
Route::get('/somewhere','routename.somewhere','showStuffController');
Route::post('/somewhere','routename.somewhere','saveStuffController');

Menu::add('label.somewhere','routename.somewhere');

You are separating concerns here, so that is nice. But Menu depends heavily in Route to set its active state. The menu will also have to know about hierarchy to set active-trail.

So yes, setting active trail, and active status classes is actually a view thing. But having

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>if ( Route::currentName() === $menuitem->getRouteName() ) { print 'active'; }
</code>
<code>if ( Route::currentName() === $menuitem->getRouteName() ) { print 'active'; } </code>
if ( Route::currentName() === $menuitem->getRouteName() ) { print 'active'; }

all over your views seem stupid. Then add all those annoying active-trail if’s and it’s a real bloat. Handling that before the view gets renders and setting an active-trail flag to true just seems so ugly the way I do it know (a foreach looping over all children that loop over all children, …)

My question is:

Is there a pattern or a smart way to get this cleaner, better, …? How should one handle the active-trail ‘problem’?

I was thinking of rendering child -> parent. So start with the ad the deepest level and then work my way up. But then the child knows about its parent but the parent knows nothing about his children (seems weird).

when the menu isn’t used for routing

I would say that routing can be used for the menu.


As you already pointed out, the router would be a nice place to hook in. I don’t think that it would be ugly to use a hook which evaluates the menu meta for the current page on each request.

If you make your views responsible for tracking the active state you do not separate concerns. The views should do whatever they are made for – but it is not necessary that they also manage their menu state. The menu meta data is usually application wide the same and you only need the route to be able to locate yourself and render the menu.

Depending on your router and your needs a simple function or class that takes some static menu meta data and the current route would be enough to provide all information you need afterwards.

The menu meta itself must not necessarily be an object. A simple key value data structure without methods should be enough in most cases.

The hook might create a state object with some common functionalities related to your menu, like breadcrumbs, depth, parent page or current page and make this object known in the context of your http request. You have different possibilities inside of the hook – but generally it is about gathering, preparing and passing necessary data to something that knows how to deal with it.

This approach scales with your needs and has a few advantages:

  1. Your database does not need to deal with data, that you can provide on runtime with low costs
  2. You’ll have your menu (meta) in one place which makes it maintainable
  3. If you want your menu to completely rely 1:1 on your routes it can be achieved by providing menu meta dynamically
  4. If your content grows (and therefore the menu) you can move this data into the session which might be written into a fast key value store

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật