Catalog modeling in depth
This page is for developers and merchants who design the content classes of a store catalog. It goes through the decisions in the order they are usually made and explains the trade-offs of each in Exponential's content model.
Contents
- One product class or several
- The fields of a product
- Item numbers and identifiers
- Images and related products
- Folders and several locations
- Translations
- Models that import and report well
- A worked example
One product class or several
A class is a set of fields. Products that need different fields belong in different classes; products that differ only in values belong in one.
| Situation | Model |
|---|---|
| All products are described the same way | One class, for example product |
| Books and clothing: different fields | Two classes, each with a price field |
| Physical products and services | Two classes; services need no weight or dimensions |
| Products and gift cards | Separate classes; a gift card's delivery is custom work |
Every class with a price field is a product class. Store > Products overview shows one class at a time, and the dashboard lists the product classes with their price attribute, so a few clearly named classes are easier to run than many.
The fields of a product
| Field | Datatype | Note |
|---|---|---|
| Name | ezstring | Shown in the basket and the order; keep it short and unique enough for staff |
| Item number | ezstring (or ezisbn for books) | See below |
| Short description | ezxmltext or eztext | Used in lists and landing page blocks |
| Description | ezxmltext | The full view |
| Price | ezprice or ezmultiprice | Exactly one per class (Price fields compared) |
| Tax class | ezproductcategory | Only when VAT depends on product category (Product categories and VAT rules) |
| Options | ezoption, ezmultioption, ezmultioption2, ezrangeoption | Only for choices that change the price (Options and variants) |
| Images | ezimage or relations to image objects | See below |
| Weight, dimensions | ezfloat, ezinteger | Only if a shipping handler will read them |
How to choose datatypes in general is in Choosing datatypes for your fields.
Item numbers and identifiers
The kernel has no item number (SKU) field of its own. Add one as ezstring and make it required. It is what staff
search for, what imports match on, and what an accounting or stock system will expect. The order keeps the product's
name and price in its product collection, so an item number in the name or a separate field visible in order
templates helps staff identify products in old orders.
Images and related products
- One
ezimagefield is simplest for a small catalog. - An object relation list to image objects lets several products share images from the media library (Relations and reuse).
- An object relation list to other products gives "related products" chosen by hand. The shop also has a fetch
function,
fetch( 'shop', 'related_purchase', hash( 'contentobject_id', ..., 'limit', ... ) ), that lists products bought together with a product, from real orders (kernel/shop/function_definition.php).
Folders and several locations
Products live in folders like any content. One product can have several locations, so it can appear in "Shoes" and in "Sale" without a copy. Keep one main location for its address and breadcrumb. Sections can group products for permissions and for discount rules, which can target sections (Discounts).
Translations
A product translated into several languages is still one product: the price field and options are fields of the translation, so check prices in every language you publish. Multilingual sites are described in Multilingual sites.
Models that import and report well
- Keep field order stable: the CSV import reads columns in the order of the class's fields (Product imports and migrations).
- Use plain datatypes for data that comes from outside (strings, numbers, prices) and rich text only for descriptions.
- Give every class and field a clear identifier; templates, imports and remote services use identifiers.
- Avoid putting prices in option text: options have their own price fields.
A worked example
A small store sells printed books and gift sets, in one currency, with a reduced VAT rate for books:
| Class | Fields |
|---|---|
book | title (ezstring), ISBN (ezisbn), author (ezstring), description (ezxmltext), price (ezprice), tax class (ezproductcategory), cover (ezimage) |
gift_set | name (ezstring), item number (ezstring), description (ezxmltext), price (ezprice), tax class (ezproductcategory), image (ezimage), wrapping (ezoption) |
VAT: two VAT types (standard and reduced), two product categories ("Books", "Other"), VAT rules per country, and the VAT handler switched on (Product categories and VAT rules).
Related pages
- Catalog modeling
- Content classes for websites
- Adding a product
- Store search and navigation
- Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.