Hitz for Craft CMS

Concepts

Plans

A plan is one floor of one venue: Spring Trade Fair 2026, ground floor. It is a Craft element with a title, a slug, your own fields, and a frame:

  • Width and depth in real units — metres or feet.
  • Grid step — what the designer snaps corners to. 0 draws freehand.
  • Underlay — an optional drawing (PNG, JPG or SVG) stretched to the frame.

Everything on a plan is measured in the frame's units, never in pixels or percentages. A 6 × 4 m stand is 6 × 4 m whatever size the underlay is, and replacing the underlay never moves a stand.

The slug is how templates name a plan: craft.hitz.render('spring-fair') keeps working when the database is refreshed from production; an ID would not.

Areas

An area is a shape on a plan — a hall, a stand, a café. Areas are elements too: they have a title, a code, your own fields (per area type), they are searchable, they go to the trash and come back, and any element can be related to one.

Per-site vs. shared: the shape, code, hall and availability are shared by every site — a stand does not move when a visitor switches language. The title and field values are ordinary per-site content, so "Catering" can be "Gastronomie" on the same shape.

Area types and kinds

Every area has a type — Shell-scheme stand, Premium island, Toilets — with a colour and its own field layout. Every type has one of three kinds, and the kind is what decides behaviour:

KindBehaviour
hallA container. Drawn beneath other areas; decides which hall a stand is in; lettered A, B, C.
standBookable. Numbered after its hall (A-01, A-02); carries availability.
featureEverything else. No code by default; labelled with its title.

Coordinates

Plans are a Cartesian plane in plan units with the origin at the top-left and y pointing down — the way a floor plan is drawn and the way CAD exports number it. Leaflet's CRS.Simple displays it; you only meet that if you write your own JavaScript, where plan point [x, y] is L.latLng(-y, x).

Shapes are stored as:

{ "type": "rectangle", "points": [[10, 20], [16, 20], [16, 24], [10, 24]] }
{ "type": "polygon",   "points": [[0, 0], [5, 0], [5, 5], [10, 5], [10, 10], [0, 10]] }
{ "type": "circle",    "center": [30, 30], "radius": 2 }

A rectangle is four corners rather than a box, so a rotated stand is still a rectangle. Every coordinate is rounded to three decimals — a millimetre, in metres.

What Hitz works out for you

  • Surface (m² or ft²), centroid and bounding box of every shape, stored so you can sort the index by stand size or query surface('>= 20').
  • Dimensions — "6 × 4 m", from the sides of a rectangle even when it is rotated.
  • The hall a stand is in: the smallest hall-kind area containing its centre. Move a stand into Hall B, or move Hall B over a row of stands, and every affected area is re-homed.
  • Codes. Halls get the next free letter. A stand inside a coded hall gets <hall>-<n>, padded to two digits (or to the width the plan already uses). A stand outside any hall uses its type's code prefix. Features get none. Codes are unique within a plan; change any of them.