schemaorg / schemaorg

Schema.org - schemas and supporting software
https://schema.org/
Apache License 2.0
5.36k stars 819 forks source link

Proposal of a Menu/menuItems schema? #1288

Open dkutcher opened 8 years ago

dkutcher commented 8 years ago

Currently for Restaurants and FoodEstablishments there is a menu item:

http://schema.org/Restaurant menu Text or URL Either the actual menu or a URL of the menu.

But no schema for the menu(s) and menu items themselves.

For example usage, google a restaurant name + menu such as https://www.google.com/?ion=1&espv=2#q=two%20urban%20licks%20menu

You'll see the data of a menu being used in the rich formatting.

Is anyone developing the menu and menuItem schema? If not, how does one propose?

jvandriel commented 8 years ago

What if we added schema.org/OfferCatalog to schema.org/menu's expected value?

Than we could write something like this:

<script type="application/ld+json">
{
  "@context":"http://schema.org/",
  "@type":"Restaurant",
  "name":"TWO urban licks",
  "description":"TWO serves wood-fired meats and fish served in a high-energy, open kitchen featuring fiery American Food.Executive Chef at TWO, Cameron Thompson gets to let his creativity shine as his passion for innovation and desire to exceed diners’ expectation enliven the “Fiery American Cooking” praised by Atlantans year after year. All of the small plates are ideal for sharing or savoring on your own. A few of the menu’s highlights include the Salmon Chips, loaded with short smoked salmon, chipotle cream cheese, capers, and red onion; Lamb Lollipops served with grape chile jam and goat cheese; entrée options include Pork Shoulder with NY baked cheddar macaroni and pork jus; and the Bronzed Sea Scallops served over smoked gouda grits in a tomato broth.",
  "url":"http://places.singleplatform.com/two-urban-licks/menu",
  "menu":
  [
    {
      "@type":"OfferCatalog",
      "name":"Main menu",
      "itemListElement":
      [
        {
          "@type":"Offer",
          "currency":"USD",
          "price":"10",
          "itemOffered":
          {
            "@type":"Recipe",
            "name":"Salmon Chips",
            "recipeIngredient":["smoked salmon","chipotle cream","cheese","caper","red onion"]
          }
        },
        {
          "@type":"Offer",
          "currency":"USD",
          "price":"12",
          "itemOffered":
          {
            "@type":"Recipe",
            "name":"Little Necks",
            "recipeIngredient":["steamed clams","mezcal","charred jalapeno","smokey bacon"],
            "nutrition":
            {
              "@type":"NutritionInformation",
              "name":"*",
              "description":"these items fall under the consumer advisory for raw or undercooked meats or seafood. consuming raw or undercooked meats, poultry, seafood, shellfish, or eggs may increase your risk of food borne illness"
            }
          }
        }
      ]
    },
    {
      "@type":"OfferCatalog",
      "name":"Brunch menu",
      "itemListElement":
      [
        {
          "@type":"Offer",
          "currency":"USD",
          "price":"10",
          "itemOffered":
          {
            "@type":"Recipe",
            "name":"Salmon Chips",
            "recipeIngredient":["short smoked salmon","chipotle cream cheese","capers","red onion"]
          }
        },
        {
          "@type":"Offer",
          "currency":"USD",
          "price":"6",
          "itemOffered":
          {
            "@type":"Recipe",
            "name":"Brioche Beignets",
            "recipeIngredient":["confectioner's sugar","coffee cream"]
          }
        }
      ]
    }
  ]
}
</script>

Note: I used a places.singleplatform.com example as Google uses it for menu links in its Knowledge Graph panels, so it's an example based on something that's already out there, minus the markup.

dkutcher commented 8 years ago

I think that gets very, very close to what I was envisioning.

A few things I'd also consider:

and p.s. great to connect with you here as well as google+ ;)

DDeering commented 8 years ago

I don't love it but I don't hate it, @jvandriel. :-) I've been kicking around some ideas myself lately as I'd love to see a more robust way to mark up restaurant menus. But to be honest, I'm not a fan of the MTE Product-Recipe. I think those are two very different entities in the eyes of search engines. Maybe I'm wrong. But I would much rather push for a few new properties and types such as menu > URL or Menu, MenuItem, FoodItem, DrinkItem (just throwing out some initial ideas off the top of my head). We could then include some of the appropriate Recipe properties and types as well such as recipeIngredient, suitableForDiet, etc.

I know that one of the arguments against creating new properties and types specifically for a certain entity is the desire to keep schema.org streamlined. But when you consider the vast number of restaurants in the world, we could argue that it might be worth exploring and developing a bit more because of the potential use and benefits.

jvandriel commented 8 years ago

I have to say I don't have anything fixed in mind. Just thought I'd throw an example in there as a starting point. Tinker with it as much as you want to illustrate what you like to see yourself, maybe that way we can come to a proper proposal (and wider consensus).

dkutcher commented 8 years ago

Is there a link to a formatting method that I should use to formulate a proposal?

dkutcher commented 8 years ago

Along similar lines to above... (sorry for formatting, doing in spreadsheet)

A few notes:

@type Restaurant
name Dave's Restaurant
description serves wood-fired meats and fish served in a high-energy, open kitchen featuring fiery American Food.
url http://www.davesbarandgrill.com
telephone
menu
@type menuCatalog
name new years dinner menu
menuHours Tu-Sa 16:00-22:00
startDate 2015-12-31
endDate 2016-01-01
currency USD
items
@type menuItem
name Roast Beef
description a big slab of roast beef with chipoltle cream
section main course
itemIngredients beef, chipolte cream, cheese, capers, red onion
itemCalories 650
classification [vegetarian,vegan,gluten-free,paleo]
price 18
additionals
@type menuItemAdditional
name potatoes
description roasted red potatoes
price 3

gmackenz commented 8 years ago

Great to see interest about Menus, I too have been recently working on a proposal for expanding Menus.

I'd like to propose we expand the current property 'menu' on 'Restaurant' to be either allow a URL or a new type 'Menu' that inherits from Thing > CreativeWork

Menu would have two new properties:

hasMenuSection --> MenuSection (aka MenuCatalog from above)

hasMenuItem --> MenuItem

MenuSection inherits from Thing > CreativeWork

Through CreativeWork and Thing you can assert name and from offers: availability information and much more.

MenuItem inherits from Thing > CreativeWork

add specific properties for suitable for diet (RestrictedDiet), allergens (allergenPresent & allergenAbsent that point to a new Intangible > Allergen that has a list of common food allergens) and nutrition (NutritionInformation)

offers can contain all the pricing, variations with pricing and other specific data to a dish or drink. I think the previous example of menuItemAdditional could use the Offer > addOn > Offer instead of new schema.

Gordon Mackenzie | Schema Wrangler (Ontologist) | gmackenz@google.com |

On Mon, Aug 15, 2016 at 10:31 AM, dkutcher notifications@github.com wrote:

Along similar lines to above... (sorry for formatting, doing in spreadsheet)

A few notes:

  • 1 restaurant can have multiple menus.
  • Menus should have a start date and end date (optional), for seasonality and whatnot, as well as special events and holiday menus
  • Menus, such as a dinner menu, should have a time range for when that menu is relevant
  • Menu items should have an optional classification for things like gluten-free, paleo, vegan, etc.
  • Menu items should have add-on elements

@type https://github.com/type Restaurant

name Dave's Restaurant

description serves wood-fired meats and fish served in a high-energy, open kitchen featuring fiery American Food.

url http://www.davesbarandgrill.com

telephone

menu

@type https://github.com/type menuCatalog

name new years dinner menu

menuHours Tu-Sa 16:00-22:00

startDate 2015-12-31

endDate 2016-01-01

currency USD

items

@type https://github.com/type menuItem

name Roast Beef

description a big slab of roast beef with chipoltle cream

section main course

itemIngredients beef, chipolte cream, cheese, capers, red onion

itemCalories 650

classification [vegetarian,vegan,gluten-free,paleo]

price 18

additionals

@type https://github.com/type menuItemAdditional

name potatoes

description roasted red potatoes

price 3

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/schemaorg/schemaorg/issues/1288#issuecomment-239869116, or mute the thread https://github.com/notifications/unsubscribe-auth/AEeZIu9slMN-UDmNGu4HDVeQEP_e-U5Rks5qgKKIgaJpZM4JgUxT .

dkutcher commented 8 years ago

Taking a stab... sorry for the formatting

`

{ "@context":"http://schema.org/", "@type":"Restaurant", "name":"David's Bar and Grill", "description":"serves wood-fired meats and fish served in a high-energy, open kitchen featuring fiery American Food.", "url":"http://www.DavidBarAndGrill.com", "telephone":"212-222-1122", "menu": [ { "@type":"Menu", "name":"Dinner menu", "menuHours":"Tu-Sa 16:00-22:00", "startDate":"2016-01-02", "endDate":"2016-05-31", "currency":"USD", "hasMenuItem": [ { "@type":"MenuItem", "name":"Spears of Romaine", "description":"spicy caesar salad with chili croutons and parmesan", "recipeIngredient":["romaine lettuce","caesar dressing","bread","chili peppers","parmesan cheese"], "currency":"USD", "price":"10", "nutrition": { "@type":"NutritionInformation", "name":"", "description":"these items fall under the consumer advisory for raw or undercooked meats or seafood. consuming raw or undercooked meats, poultry, seafood, shellfish, or eggs may increase your risk of food borne illness", "calories": "350", "restrictedDiet":['vegetarian','gluten-free'] } "hasAddOn": [ { "@type":"AddOn", "name":"grilled chicken", "currency":"USD", "price":"6" }, { "@type":"AddOn", "name":"poached salmon", "currency":"USD", "price":"10", "nutrition": { "@type":"NutritionInformation", "name":"", "description":"these items fall under the consumer advisory for raw or undercooked meats or seafood. consuming raw or undercooked meats, poultry, seafood, shellfish, or eggs may increase your risk of food borne illness", "calories": "350" }
} ] }, { "@type":"MenuItem", "name":"Little Necks", "description":"jalepeno clams in a bacon broth", "recipeIngredient":["steamed clams","mezcal","charred jalapeno","smokey bacon"], "currency":"USD", "price":"12", "nutrition": { "@type":"NutritionInformation", "name":"*", "description":"these items fall under the consumer advisory for raw or undercooked meats or seafood. consuming raw or undercooked meats, poultry, seafood, shellfish, or eggs may increase your risk of food borne illness", "calories": "450" } } ] }, { "@type":"Menu", "name":"Brunch menu", "menuHours":"Sa-Su 09:00-14:00", "startDate":"2016-01-02", "endDate":"2016-05-31", "currency":"USD", "hasMenuItem": [ { "@type":"MenuItem", "name":"Salmon Chips", "description":"", "recipeIngredient":["short smoked salmon","chipotle cream cheese","capers","red onion"], "currency":"USD", "price":"10" }, { "@type":"MenuItem", "name":"Brioche Beignets", "description":"", "recipeIngredient":["confectioner's sugar","coffee cream"], "currency":"USD", "price":"6" } ] } ] } `

gmackenz commented 8 years ago

I like it @dkutcher! I'd like to write up a quick proposal in the next day or so based upon what we've discussed so we can have something concrete to reference in further refining this schema.

Looking at your example, I think we can use the existing CreativeWork.offers.Offer.validFrom instead of menuHours, startDate, and endDate as those three values can be captured in one validFrom.DateTime SO encoded value for duration and time intervals.

dkutcher commented 8 years ago

I'm glad, and yes, that CreativeWork.offers.Offer.validFrom works, although it seems a bit funny to be thinking of a Menu as a creativework... very philosophical for a chef!

To throw a quick stick in the cog, two situations that might not align neatly:

Thoughts?

unor commented 8 years ago

Related:

dkutcher commented 8 years ago

Bump? Anything I can do to assist?

gmackenz commented 7 years ago

Hello, been away working on a complete proposal with @vholland and here's what I've come up with as a document. I think it answers all of the questions raised so far.

@dkutcher:

Price would be in Offer under Menu or MenuSection and the MenuItems will not list a price. That's how I would do it.

You can specify availability on Menu, MenuSection or in this case by MenuItem on the Offer's availability properties. Not sure which is better, some restaurants how unique specials items on a separate menu/menu section. Others might use multiple Offer on a MenuItem, each with a different price and availability time period.

dkutcher commented 7 years ago

@gmackenz Can you make that document public? Can't see it...?

ghost commented 7 years ago

On Wed, 10 Aug 2016 at 04:27 dkutcher notifications@github.com wrote:

I think that gets very, very close to what I was envisioning.

A few things I'd also consider:

  • days/times when menu is being served
  • dates or date ranges when menu is available (special menus for holidays, as well as seasonality)
  • dairyfree, glutenfree, vegan, etc. for items

seeAlso:schema.org/diet

Properties should include means to say whether the food is 'safe' for particular allergies; in addition to, 'diet' related semantics.

USE CASE: peanutAllergy https://www.wikidata.org/wiki/Q7157933

USE CASE: https://www.thecandidadiet.com/ SeeAlso: https://www.wikidata.org/wiki/Q273510

Both should also support reputation/review properties... (ie: trusted information)

  • calorie counts for items
  • add-on items with pricing (add chicken to your salad, +$5)

and p.s. great to connect with you here as well as google+ ;)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/schemaorg/schemaorg/issues/1288#issuecomment-238645570, or mute the thread https://github.com/notifications/unsubscribe-auth/AFdABnRbqiHmqjkyCJgBaS3HpP18hh-rks5qeMZ-gaJpZM4JgUxT .

dkutcher commented 7 years ago

@mediaprophet agreed, I had put those under the NutritionInformation:

"restrictedDiet":['vegetarian','gluten-free']

gmackenz commented 7 years ago

Sorry @dkutcher, I thought I had faithfully followed all the steps to make the document publicly visible. Here's an externally hosted version. Is this accessible for all interested?

Dataliberate commented 7 years ago

Can see that now- thanks.

~Richard

On 17 Sep 2016, at 10:56, Gordon Mackenzie notifications@github.com wrote:

Sorry @dkutcher, I thought I had faithfully followed all the steps to make the document publicly visible. Here's an externally hosted version. Is this accessible for all interested?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

dkutcher commented 7 years ago

A few comments that I'm not quite sure are addressed:

Trying to think of situations...

dkutcher commented 7 years ago

Additional question:

Many sites have been using the menu property to supply a URL to the location of the menu. Within a restaurant website, all pages of the website might be pointing to site.com/menu.html

If the menu property is now being extended, how would a restaurant property define the definitive location(s) of the menu(s), where they can then be found?

gmackenz commented 7 years ago

On Tue, Sep 20, 2016 at 8:07 AM, dkutcher notifications@github.com wrote:

Additional question:

Many sites have been using the menu property to supply a URL to the location of the menu. Within a restaurant website, all pages of the website might be pointing to site.com/menu.html

If the menu property is now being extended, how would a restaurant property define the definitive location(s) of the menu(s), where they can then be found?

I don't quite understand, if you mean by the new extension of a Menu type on Restaurant > menu? They can still use URL and use the Menu as well for a marked up version. It's up to the site owner. If you mean storing the URL of the menu page within the new Menu type? Then I suppose you could store that in Thing > url.

gmackenz commented 7 years ago

Thanks for the questions and feedback!

On Sat, Sep 17, 2016 at 11:57 AM, dkutcher notifications@github.com wrote:

A few comments that I'm not quite sure are addressed:

-

menu should have availability, for example specifying that the "main dinner menu" is available "Mo-Th 17:00-23:00"

It is in menu (name:"Main Dinner Menu")> offers > availabilityStarts & availabilityEnds or if you chose to have multiple menuSections under a root FoodEstablishment's menu, then menuSection (name:"Main Dinner Menu") > offers > availabilityStarts & availabilityEnds

-

menu should have date range validity, validFrom and validTo, not tied to the items but to the menu

Yes, using offers you can do that at the menu level, menuSection level or menuItem

-

a menu can have an offer, such as "appetizers half-price" with "Mo-Th 16:30-18:00"

ability to validate a menu against today's date for things like a "daily special", so the menu is "available" on "2016-09-17"

lastUpdated specified (assuming this will be there, but didn't want to assume)

See CreativeWork's dateModified for capturing that (if provided)

-

I noticed in your example you used OpeningHoursSpecification instead of the other option OpeningHours (both found in schema.org/Restaurant), why are there two methods?

Currently I believe Place's OpeningHoursSpecification is more in use in the world (that I am aware of within my work). You can use either one but I think OpeningHours is probably an unnecessary denormalization, a duplication of the OpeningHoursSpecification but I don't know the the history of Restaurant's creation.

-

just also noticed (perhaps a separate issue) that Restaurant has specification for smoking, but not for liquor/beer/wine serving-license. This likely should be an option?

Probably, but I think those kind of properties might be better on FoodEstablishment or even higher up, LocalBusiness? Liquor licenses are idiosyncratic to local governance and can be non-traditional alcohol-serving establishments like restaurants, pubs and bars. Maybe on Place? Anyway that should discussed outside of Menu I think.

-

will addOn items also have NutritionInfo?

That's an interesting thought, maybe the addOns will require a specific menuItems listing somewhere in the menu (in an Additional Toppings menuSection for example?). That said, one could simply use the NutritionInfo property with the addOn

Trying to think of situations...

Please do so...

vholland commented 7 years ago

I don't know the entire history of openingHours and openingHoursSpecification, but openingHoursSpecification is less ambiguous. It is clearer for both readers and writers of the data what is being said rather than parsing strings.

dkutcher commented 7 years ago

I guess that means I need to go into all of my restaurant clients' websites and update their hours schema!

gmackenz commented 7 years ago

FYI I removed the allergen portion of the proposal above as @danbri pointed out to me we should look to solving that elsewhere (issue #1411). Working on creating the examples now.

gmackenz commented 7 years ago

Proposing menuAddOn markup on MenuItem to allow for directly linking add-on MenuItems or MenuSections to a MenuItem. #1432

monecchi commented 7 years ago

This thing has been discussed for ages everywhere... I've also contributed with the proposal for adding markup for Menus on a few different places I don't remember now, but I'd be immensely happy if it comes true in 2017!

dkutcher commented 7 years ago

Amen to that! Is there an ETA? I have restaurant menus ready to go!

danbri commented 7 years ago

I merged https://github.com/schemaorg/schemaorg/pull/1432 a while back, it will be in next release candidate. I see I neglected to put together release notes for http://webschemas.org/docs/releases.html#v3.2 but please take a look at http://webschemas.org/MenuItem and nearby...

dkutcher commented 7 years ago

Just implemented for two restaurants, ten more to do today!

mgh128 commented 7 years ago

In the GS1 web vocabulary, there are several properties relating to ingredients, nutritional information of food products - see http://gs1.org/voc/FoodBeverageTobaccoProduct . Some of these go beyond the nutritional properties defined in http://webschemas.org/MenuItem and our nutritional info properties are defined with reference to an explicitly defined nutrient basis quantity (e.g. per 100 gram, per serving, per pack). The GS1 web vocabulary can be used together with schema.org, as an external extension to schema.org in order to express further details.

dkutcher commented 7 years ago

Bug in the menuAddOn?

http://webschemas.org/MenuItem

why is the expected type for menuAddOn set as MenuSection? Shouldn't it be MenuItem as the expected type?

MenuItem -name -offers -menuAddOn (MenuItem) --name --offers -menuAddOn (MenuItem) --name --offers

jvandriel commented 7 years ago

I'm guessing that's probably because of how the Offer model has been put together in Goodrelations years ago already. Just have a look at http://schema.org/Offer and http://schema.org/addOn.

And since Goodrelations has been an integral part of schema.org nearly from day one. I think it would be a bad idea to move away from it. (cc: @mfhepp)

Having said that, I can imagine a purpose for using 'menuAddOn' in those situations where a FoodEstablishment has a separate MenuSection containing a group of additional menu items, eg

{
  "@type":"MenuItem",
  "name":"Spears of Romaine",
  "menuAddOn":
  {
    "@type":"MenuSection",
    "name":"Extra's",
    "hasMenuItem":
    [
      {
        "@type":"MenuItem",
        "name":"French fries"
      },
      {
        "@type":"MenuItem",
        "name":"hot vegatables"
      }
    ]
  }
}

Doing it this way means schema.org can facilitate menu's that don't have a separate 'add on' section on their menu but offer add ons directly from the MenuItem itself, while also being able to facilitate menu's that do have a separate 'add on' section.

DDeering commented 7 years ago

Hmm, I'm not sure if I'm a fan of using menuAddOn in that way. What about simply using the existing addOn property within the Offer? And really, the "add on" is not an addition to the menu but an addition to the menu item, right?

So since many menu items also include the add-ons immediately below the item description, how about doing something like this (shown in a very simple, incomplete example)?:

{ "@type": "MenuItem", "name": "Ribeye Steak", "offers": { "@type": "Offer", "price": ..... "addOn": { "@type": "Offer", "itemOffered": { "@type": "Product", "name": "Grilled Mushrooms" }, "price": .....

Personally, I think that if a restaurant has an "add-on/extras" section, it might be easier to mark it up as it's own menu or menu section. But again, just my opinion.

dkutcher commented 7 years ago

The addOn is a menu item being added onto a menu item.

Caesar Salad

IMO the menu item is being modified here (item + sub-item).

At the same time, the same item and sub-items might have different offers depending on time of day (for example).

So it could be:

Caesar Salad

That seems to me to make much more sense than nesting the chicken twice (once under each offer)

DDeering commented 7 years ago

Right. But I do think that your second scenario would probably be pretty rare to see. I think most restaurants typically have Lunch and Dinner menus as opposed to listing the item with various prices and times together.

dkutcher commented 7 years ago

Perhaps, but they might have the regular menu discounted during lunch or happy hour, without having a happy hour menu.

DDeering commented 7 years ago

True. And honestly, there are several ways to mark it up, including the way you showed.

But my main point is that I'm not sure creating a new menuAddOn property would be necessary. I think using the existing addOn property along with Offer would suffice, unless I'm overlooking something.

gmackenz commented 7 years ago

The original intent was to allow for a specific add on sub-menus, which many restaurants have currently (pizza restaurant menus are often listing pizzas by type then provide a related but separate add on menu with prices) Using addOn with Offer is perfectly valid but would make for a complicated structure for those aforementioned restaurants if you list all the same available add on items per menuItem.

Gordon Mackenzie | Schema Wrangler (Ontologist) | gmackenz@google.com |

On Thu, Jan 19, 2017 at 11:48 AM, DDeering notifications@github.com wrote:

True. And honestly, there are several ways to mark it up, including the way you showed.

But my main point is that I'm not sure creating a new menuAddOn property would be necessary. I think using the existing addOn property along with Offer would suffice, unless I'm overlooking something.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/schemaorg/schemaorg/issues/1288#issuecomment-273878831, or mute the thread https://github.com/notifications/unsubscribe-auth/AEeZIqqUo-NQdkFxXxydFKHMEp43-J-tks5rT73_gaJpZM4JgUxT .

DDeering commented 7 years ago

I see and I understand where you're coming from, @gmackenz. When marking those up, could we possibly group all of the add-on items together in one add-on menu and reference it once for each menu item? Because the problem I see is that some restaurants will list the add-ons immediately under the item description but then other menus such as for pizza will list the add-ons all in a separate menu. So what about creating a new itemAddOn property that could expect a value of either MenuItem or MenuSection?

gmackenz commented 7 years ago

I believe that was the intent for linking from various MenuItem(s) to a MenuSection of add ons items. Maybe I'm misunderstanding your suggestion but the listing add ons immediately could be done through your earlier suggestion of MenuItem > Offer > addOn > Offer.

jvandriel commented 7 years ago

OK, let's try to make it a bit more concrete.

I've taken the original markup example created by @dkutcher and tried to incorporate most of what's been said:

<script type="application/ld+json">
{
  "@context":"http://schema.org/",
  "@type":"Restaurant",
  "name":"Acme's Bar and Grill",
  "description":"serves wood-fired meats and road runner served in an open kitchen featuring American Food.",
  "url":"http://www.example.com",
  "telephone":"555-123-4567",
  "menu":
  [
    {
      "@type":"Menu",
      "name":"Dinner menu",
      "temporalCoverage":"Tu-Sa 16:00-22:00",
      "hasMenuSection":
      {
        "@type":"MenuSection",
        "name":"Starters",
        "hasMenuItem":
        [
          {
            "@type":"MenuItem",
            "name":"Spears of Romaine",
            "description":"Spicy caesar salad with chili croutons and parmesan",
            "nutrition":
            {
              "@type":"NutritionInformation",
              "name":"*",
              "description":"These items fall under the consumer advisory for raw or undercooked meats or seafood. consuming raw or undercooked meats, poultry, seafood, shellfish, or eggs may increase your risk of food borne illness",
              "calories":"350"
            },
            "suitableForDiet":
            [
              {
                "@type":"RestrictedDiet",
                "name":"Vgetarian"
              },
              {
                "@type":"RestrictedDiet",
                "name":"Gluten-free"
              }
            ],
            "offers":
            {
              "@type":"Offer",
              "priceCurrency":"USD",
              "price":"10",
              "addOn":
              [
                {
                  "@type":"Offer",
                  "priceCurrency":"USD",
                  "price":"10",
                  "itemOffered":
                  {
                    "@type":["MenuItem","Product"], // The 'itemOffered' has to be an MTE because the expected value for 'itemOffered' is either schema.org/Product or schema.org/Service.
                    "name":"Poached salmon",
                    "nutrition":
                    {
                      "@type":"NutritionInformation",
                      "name":"*",
                      "description":"This item falls under the consumer advisory for raw or undercooked meats or seafood. consuming raw or undercooked meats, poultry, seafood, shellfish, or eggs may increase your risk of food borne illness",
                      "calories":"350"
                    }
                  }
                },
                {
                  "@type":"Offer",
                  "priceCurrency":"USD",
                  "price":"6",
                  "itemOffered":
                  {
                    "@type":["MenuItem","Product"], 
                    "name":"Grilled chicken"
                  }
                }
              ]
            },
            "menuAddOn":
            {
              "@id":"#extras",
              "@type":"MenuSection",
              "name":"Extra's",
              "hasMenuItem":
              [
                {
                  "@type":"MenuItem",
                  "name":"French fries",
                  "offers":
                  {
                    "@type":"Offer",
                    "priceCurrency":"USD",
                    "price":"1"
                  }
                },
                {
                  "@type":"MenuItem",
                  "name":"Hot vegatables",
                  "offers":
                  {
                    "@type":"Offer",
                    "priceCurrency":"USD",
                    "price":"5"
                  }
                }
              ]
            }
          },
          {
            "@type":"MenuItem",
            "name":"Little Necks",
            "description":"jalepeno clams in a bacon broth",
            "nutrition":
            {
              "@type":"NutritionInformation",
              "name":"*",
              "description":"these items fall under the consumer advisory for raw or undercooked meats or seafood. consuming raw or undercooked meats, poultry, seafood, shellfish, or eggs may increase your risk of food borne illness",
              "calories":"450"
            },
            "offers":
            {
              "@type":"Offer",
              "priceCurrency":"USD",
              "price":"12"
            },
            "menuAddOn":
            {
              "@id":"#extras"
            }
          }
        ]     
      }
    },
    {
      "@type":"Menu",
      "name":"Brunch menu",
      "temporalCoverage":"Sa-Su 09:00-14:00",
      "hasMenuItem":
      [
        {
          "@type":"MenuItem",
          "name":"Salmon Chips",
          "description":"Too good to be true!",
          "offers":
          {
            "@type":"Offer",
            "priceCurrency":"USD",
            "price":"10"
          }
        },
        {
          "@type":"MenuItem",
          "name":"Brioche Beignets",
          "description":"These should be illegal!",
          "offers":
          {
            "@type":"Offer",
            "priceCurrency":"USD",
            "price":"6"
          }
        }
      ]
    }
  ]
}
</script>

Anything that should be different folks?

DDeering commented 7 years ago

No, you're right, Gordon, it certainly can be done like that. I just didn't know if it would look strange for addOn to have an expected value of Offer or MenuSection. But the way you structured it would work perfectly for single add-on items.

So for add-on menus, do you suggest doing something like this?....

..... "addOn": { "@type": "Offer", "itemOffered": { "@type": "MenuSection", "name": "Additional Toppings", "id": "#toppings", "hasMenuItem": [ { "@type": "MenuItem", "name": "Extra Cheese", "offers": { "price": "1.00", "priceCurrency": "USD" }, { "@type": "MenuItem", "name": "Extra Onions", "offers": { "price": "1.00", "priceCurrency": "USD" }, .........

The MenuSection could be nested once or marked up separately.

DDeering commented 7 years ago

Thanks, Jarno.

Sorry if I seem stubborn but I'm still not a fan of menuAddOn. A menu has menu sections but menu items have add-ons. If we already have Menu > hasMenuSection > MenuSection, why do we need menuAddOn to declare essentially another MenuSection? Can't we just use the same structure?

jvandriel commented 7 years ago

Be as stubborn as you want, I'm not that crazy about it either. I just noticed it on http://webschemas.org/ earlier and tried to make sense of why it's there.

Couldn't we let it out in favor of using addOn in combination with an multi-type entity?

  "@type":"MenuItem",
  "name":"Pepperoni pizza",
  "additionalProperty":
  {
    "@type":"PropertyValue",
    "name":"size",
    "value":"medium"
  },
  "offers":
  {
    "@type":"Offer",
    "priceCurrency":"USD",
    "price":"6.99",
    "addOn":
    {
      "@type":"Offer",
      "itemOffered":
      {
        "@type":["MenuSection","SomeProducts"],
        "name":"Extra's",
        "hasMenuItem":
        [
          {
            "@type":"MenuItem",
            "name":"Pineapple",
            "offers":
            {
              "@type":"Offer",
              "priceCurrency":"USD",
              "price":"0.50"
            }
          },
          {
            "@type":"MenuItem",
            "name":"Gouda cheese",
            "offers":
            {
              "@type":"Offer",
              "priceCurrency":"USD",
              "price":"2"
            }
          }
        ]
      }
    }
  }
DDeering commented 7 years ago

Is using an MTE really necessary in this case, Jarno? Aren't menus, menu sections, and menu items by default understood to be "some products"? And MenuItem is going to inherit all of the Product type's properties anyway, so I'm thinking that it might be a little redundant and unnecessary. But perhaps I'm overlooking something.

mfhepp commented 7 years ago

There are two things we need to keep distinct:

  1. Support for configurable products ("choose three side-dishes out of a selection of ten"). This is a general requirement for products missing in schema.org, and it should be handled at the generic product level and not by a proprietary model for menues.

  2. Support for add-ons that are offers to extend a base offer, i.e. you can only buy (or rent, in other domains) the product (accept the offer to buy or rent the add-on) if you accept the base offer, like "add a side-salad for only $3". This is already supported by schema.org via the addOn property - simply define two schema:Offer entities and link from the base to the optional extension via addOn. This is sufficient, precise, and generic.

Also, please try to keep the essential distinction between the objects that are being advertised (be they food, garments, or cars) from the offer to transfer some rights on the objects.

It would be a real pity if any domain-specific extension breaks this fundamental principle in schema.org, i.e. keeping products and offers of products distinct. This will always lead us into a mess as soon as we face bundles of products or services from multiple domains, like accommodations + foods, or rental cars and insurances, etc.

I strongly recommend reading

http://wiki.goodrelations-vocabulary.org/Documentation/Conceptual_model

and at least section 2 of the attached paper, which is an extension of the link above.

Best wishes

Martin

martin hepp http://www.heppnetz.de mhepp@computer.org @mfhepp

On 19 Jan 2017, at 20:41, dkutcher notifications@github.com wrote:

Perhaps, but they might have the regular menu discounted during lunch or happy hour, without having a happy hour menu.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

DDeering commented 7 years ago

Good point. Thanks, Martin. We certainly don't want to break from schema.org norms. Do you have any suggestions then on how to handle these things?

jvandriel commented 7 years ago

Going by Martin's comment I think it might be a good idea to remove Menu from webschemas.org until it becomes clear what to do about not being able to use menuAddOn @danbri.

danbri commented 7 years ago

After looking over this and discussing with @gmackenz and @vholland, I will move menuAddOn to the Pending section of schema.org for the upcoming #1292 release.