Content model

Fenómenus models a restaurant as ten public menu post types, each with its own category taxonomy, plus a small number of cross-cutting taxonomies.

Menu post types

Slug Menu type
a_la_carte_menu À la carte menu
terrace_menu Terrace menu
breakfast Breakfast
desserts Desserts
bar_menu Bar menu
wine_list Wine list
cocktails Cocktails
beverages Beverages
tasting_menu Tasting menu
set_menu Set menu

An internal eleventh type, set_menu_dishes, holds the dishes a set menu offers as choices.

Only the types enabled on a site are registered. Check with post_type_exists() rather than assuming.

Category taxonomies

Each menu type has one category taxonomy following the convention <post_type>_category:

a_la_carte_menu_category, terrace_menu_category, breakfast_category, desserts_category, bar_menu_category, wine_list_category, cocktails_category, beverages_category, tasting_menu_category, set_menu_category, set_menu_dishes_category

They are hierarchical and used one level deep by the admin tools.

Term ordering

Category terms carry a stored position in the term meta key tax_position. Every ordered query in the product uses it:

$terms = get_terms( array(
    'taxonomy'   => 'a_la_carte_menu_category',
    'hide_empty' => false,
    'orderby'    => 'meta_value_num',
    'order'      => 'ASC',
    'meta_key'   => 'tax_position',
) );

Reproduce that ordering in custom code, or your output will not match the menu.

Item ordering

Items are ordered by menu_order, ascending. The admin list writes it when rows are dragged, and bulk imports append after the current maximum.

$query = new WP_Query( array(
    'post_type' => 'a_la_carte_menu',
    'orderby'   => 'menu_order',
    'order'     => 'ASC',
) );

Cross-cutting taxonomies

Taxonomy Applies to Notes
allergen The content types enabled for allergens Terms carry an icon in the term meta key pom_category_thumbnail
featured The menu post types Non-public; the single term slug is is-featured

The featured taxonomy is deliberately not publicly queryable. Its public name is editable while the is-featured slug stays fixed.

À la carte and terrace extras

Two additional taxonomies exist for a_la_carte_menu:

  • a_la_carte_menu_not_suitable_for
  • a_la_carte_menu_options

Both are registered without their own archives.

The independent terrace_menu has the matching terrace_menu_not_suitable_for and terrace_menu_options taxonomies, also without archives.

Wine taxonomies

Taxonomy Contents
wine_list_category The wine type tree, seeded on enable
wine_vintage Years, seeded 1930–2030, non-hierarchical
wine_aging_classification Young wine, medium ageing, long ageing
wine_winery Producers
wine_grape Varieties
wine_region Origins, hierarchical

Supports

The menu post types support title and page-attributes, plus thumbnail where enabled. They do not support revisions, so there is no version history for a menu item.

wine_list does not use the content editor in the same way as the other types; its data lives in wine-specific meta and taxonomies.

The numeric wine-rating contract uses parker_score and penin_score, both constrained to 0–100. An absent rating is stored as an empty value and must not be represented as a zero score.

Statuses

Only publish and draft are used by the admin tools. Status changes made through the list screen are applied to an item and all of its translations.

Reading a menu

$terms = get_terms( array(
    'taxonomy'   => "{$post_type}_category",
    'hide_empty' => false,
    'orderby'    => 'meta_value_num',
    'order'      => 'ASC',
    'meta_key'   => 'tax_position',
) );

foreach ( $terms as $term ) {
    $items = new WP_Query( array(
        'post_type'      => $post_type,
        'posts_per_page' => -1,
        'orderby'        => 'menu_order',
        'order'          => 'ASC',
        'tax_query'      => array( array(
            'taxonomy' => "{$post_type}_category",
            'field'    => 'term_id',
            'terms'    => $term->term_id,
        ) ),
    ) );
}

That is the same traversal the PDF generator performs, and it produces the menu in the order guests read it.