🍳 Foodlangalpha

Order Format & Tokens

Foodlang has two sides. The recipe side (.food / .food.yaml) describes how to make something. The order side described here describes what a customer wants, chosen from a pre-published, versioned menu.

An order never inlines a recipe. It references item identifiers — each of which is assumed to already have its own .food receipt recipe on the restaurant's side — plus the customer's variant params and args. That keeps orders tiny, stable across menu revisions, and safe to put in a QR code or a link.

Try it live on the Order page.


1. The .food order code (KDL)

The canonical, human-readable order is a strict-KDL document rooted at an order node:

order "Sakura Ramen House" {
  menu "spring-2026" version=3
  service takeout
  line tonkotsu_ramen 2 {
    spice medium
    noodles firm
    egg
    extra_chashu
  }
  line gyoza 1 {
    style pan_fried
  }
  line green_tea 2 {
    temp iced
  }
  note "no scallions"
}

Grammar

Node Form Meaning
order order "<name>" { … } Root. The string is the restaurant's display name.
menu menu "<id>" version=<n> Which published menu, and which version. Both are required so the kitchen resolves item ids against the exact menu the customer saw.
service service <dine_in|takeout|delivery> Fulfilment method.
line line <item_id> <qty> { … } One ordered item. item_id is a bare identifier that maps to a .food recipe; qty is a positive integer. The child block is optional.
select param <key> <value> A single-choice variant (e.g. spice medium).
bare arg <ref> A boolean add-on / flag (e.g. egg, extra_chashu).
note note "<text>" Free-text kitchen note.

Because every construct is valid strict KDL, an order code parses with any KDL v1 parser and passes Foodlang's isStrictKdl() check. A one-line compact form (using ; separators) is equivalent:

order "Sakura Ramen House" { menu "spring-2026" version=3; service takeout; line tonkotsu_ramen 2 { spice medium; noodles firm; egg; extra_chashu }; note "no scallions" }

Design rules

  • Ids over recipes. line tonkotsu_ramen refers to the restaurant's tonkotsu_ramen.food. The order does not, and must not, restate the recipe.
  • Version everything. An id only means something within a menu version. Ship the menu … version= line so a re-priced or renamed menu can't silently change what a customer ordered.
  • Params are the customer's, not the kitchen's. Selects (spice medium) and bare flags (egg) are the only customer-authored data. Prices, descriptions, and preparation live on the recipe side.

2. The condensed order token (FOT/1)

The KDL code is readable but verbose. For a small, dense QR or a short share link, Foodlang defines a single-line wire format: the Foodlang Order Token, version 1.

fot1~sakura-ramen-house~spring-2026:3~t~tonkotsu_ramen*2.spice-medium,noodles-firm,egg,extra_chashu;gyoza*1.style-pan_fried~no scallions

Grammar

token   = "fot1" "~" rid "~" menu ":" version "~" svc "~" lines [ "~" note ]
lines   = line *( ";" line )
line    = item_id "*" qty [ "." args ]
args    = arg *( "," arg )
arg     = key "-" value        ; a select param
        | ref                  ; a bare add-on / flag
svc     = "d" / "t" / "x"      ; dine_in / takeout / delivery
Section Example Notes
Magic + version fot1 Literal prefix; bump the digit for future formats.
rid sakura-ramen-house Restaurant id ([a-z0-9-]).
menu:version spring-2026:3 Menu id and integer version.
svc t One letter: d, t, or x.
lines tonkotsu_ramen*2.spice-medium,egg ;-separated. Each is id*qty then optional .args.
note no scallions Optional. Always last, so it may contain any character except ~.

Reserved characters: ~ ; . , * : -. Item ids, keys, and values are [a-z0-9_] (underscore, never dash — dash is the select separator). This keeps tokens URL-safe without escaping, apart from the note.

Round-trip

FOT/1 is loss-free with respect to the KDL order code: decode a token, and you can regenerate byte-identical .food order code (given the same menu). The Order page does exactly this — the token is what it embeds in the QR and the share link, and what it decodes when one is opened.


3. Sending an order

An order can reach the clerk three ways. All are generated client-side; the first two need no network at all.

a. Offline QR

The QR encodes either the FOT/1 token (default — smallest) or the full compact .food code. The clerk scans it at the counter. Nothing leaves the device.

b. Condensed token

Copy the fot1~… string and send it however you like — it is short enough to read aloud or type. The kitchen's Foodlang tooling decodes it back to an order.

c. Online share link

For remote / ahead-of-time ordering, the token rides in a URL fragment:

https://foodlang.com/order.html#o=<url-encoded FOT/1 token>

Because the token is in the # fragment, it is never sent to the server — the page reconstructs the order entirely in the browser. Opening the link selects the right restaurant and rebuilds the exact cart, ready to confirm or re-share. On devices with the Web Share API, the Share order button hands this link to the native share sheet (Messages, Mail, etc.).

The fragment approach means the same link works whether the recipient is online or offline once loaded, and no order data is logged by any host.