Figure I'd query with the geniuses over on StackExchange as I think I've hit a roadblock in my project. I'm building a website containing menus from multiple restaurants with the vision that it could eventually grow to become a local online food ordering marketplace.

Taking into consideration the e-commerce plugins currently in development, I'm going to make an assumption that a single product would constitute as a single entry with these add-ons, so this makes the hierarchy of data a bit of a challenge.

Some requirements:

  • Menu items need to be associated with a restaurant.
  • Menu items need to be categorized, but categories are unique per restaurant

I've played with various configurations thus far and haven't really found a method that I'd deem "ideal."

I've considered using Structure exclusively where parent items would be the restaurants and children would be the menu categories with the items nested beneath. What are your thoughts on this? Could use a few different entry types for indexes and one for menu items.

Right now, I'm using a combination of related entries, an Inverse related entries plugin for informational purposes where restaurants are also channels, but just doesn't seem like a sensible approach so far, so probably scrapping this method.

Thoughts, advice, any feedback really appreciated. Thank you so much!

2 Answers 2


Ok, just spitballing here, but this is where my brain is going...

Channel: Restaurants

Each restaurant is a unique entity, correct? So they wouldn't need to be in any specific order, nor nested. (Chain restaurants could be related by other means.) All of your broad restaurant-based fields would be here, including location, phone number, hours of operation, etc.

Channel: Menu

I feel the menu should be a separate channel from the parent restaurants for a couple of reasons:

  • Seasonal/specialty menus: One restaurant, many menus.
  • Chain restaurants would share a menu: Many restaurants, one menu.

Within your Restaurants channel, create an Entries field (with a limit of 1) called "Menu". So each restaurant could select its current menu.

Matrix: Menu Items

Within your Menu channel, you'd have a Menu Options matrix field. Each menu option would be its own matrix block.

If you want to use the built-in category system, you may be able to create Category Groups based on different restaurant genres (Mexican, Thai, etc). You could then simply use those very broadly. However, I'd be concerned that those broad categories don't properly address the needs of each individual restaurant.

Alternatively, you may end up needing to create faux categories... I'm not sure you could get the normal category system to work for you here. There would be such wide-ranging variations between the categories of different restaurants, it would be a nightmare to keep up with that using the standard categorization options.

Faux Categories

You could potentially create a dropdown menu to represent your "categories" for a particular restaurant. That faux categories menu could be driven by the amazingly powerful LJ Dynamic Fields plugin. Might take a little trial & error, but that plugin will allow you to build a dropdown menu to be exactly as you need it.

With this method, you could allow each Menu to have its own definition of categories. Create a table field called "Categories" in your Menu section, and allow LJ Dynamic Fields to take advantage of that.

eCommerce Options

I can see why you'd gravitate towards making each menu item into its own entry, but I don't believe that's necessary. Take a look at some of the more generic, non-Craft options for building your checkout process. Specifically Snipcart and Foxycart allow you to render a product however you want to, and don't restrict your back-end data to any particular architecture.

My instinct is telling me that your menu options would be much better suited as a matrix field (or even table field), rather than being their own entries.

Hope that helps, even if it just gives you some new ideas to kick around! :)

  • Thank you so much for the feedback. This is a great suggestion! Will have to tinker away to find out how I can pull the table channel categories into the LJ Dynamic Field! Super amazed at the creativity behind these solutions. Wish I could come up with these things!
    – Danny
    Dec 22, 2014 at 18:11
  • Any idea on how I could pull the ID of the entry dynamically so it could output the categories of the active entry the user is editing? I have a categories field called 'fauxCategories' and a table with column 'category' that's added to the 'Menu (Channels)' section.
    – Danny
    Dec 22, 2014 at 18:51
  • 1
    That's a great question... I've never attempted to have an entry reference itself via an LJ Dynamic Field. It is exactly what I suggested though, so I'm hoping it's possible! If simply using entry.id doesn't work for you, it might be worth reaching out to the developer of the plugin to see how he would recommend handling that.
    – Lindsey D
    Dec 22, 2014 at 20:16
  • 1
    Or conversely, you could post a new Stack Exchange question about it... would be a great question for the community!
    – Lindsey D
    Dec 22, 2014 at 20:16

As suggested by Lyndsey D, use the LJ Dynamic Fields plugin with the following Twig code to create your dynamic dropdown menu. It appears that Craft doesn't have a built-in way for an entry to self-reference itself as you'd like, but we can use Twig's built in filters to get around this by getting the id directly from the URL.

{% set thisEntry = craft.entries.id(craft.request.getSegment(3) | split("-") | first).first %}
    {% if thisEntry.fauxCategories is defined %}
        {% for row in thisEntry.fauxCategories %}
        { "value":"{{ row.category | raw }}" , "label":"{{ row.category | raw }}" }
        {% if not loop.last %},{% endif %}
    {% endfor %}
{% endif %}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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