CMS New data type form for Real estate with properties.json storage
Real estate type form

Appifio Creator · Lesson AS20 · Custom types · Real-estate example

Custom data types
Panel Save · fields · taxonomy · real-estate site

Declare on the Panel so CMS updates both declaration files correctly - then ask AI to polish list/detail pages and filters.

Learning goals: Create a properties type, pick field types correctly, enable categories; know what the Panel creates; ask AI to edit HTML safely.

Prerequisites: AS19 · AS07 · Backend Advanced + CMS

Prompt: Aura Complete + Appifio Aura CMS + Storage - Complete AI Guide · Related: AS21 (AI declares the type)

Recommended: Always create types on the Panel → Custom data types → Save. The Panel merges the content table + UI contract + sample HTML + routes. You don’t need to hand-edit the two JSON files.

1. Fields - how to pick a type?

CMS Real estate list with a published District 1 apartment listing
Listings with data
typeWidgetUse when
stringtextTitle, short address
texttextareaLong plain text
htmltextarea / wysiwygFormatted description
numbernumberPrice, m², room counts
enumselectFixed set: sale / rent
booleantoggleYes / no
urlurlExternal link
imageimageCover image (upload in CMS)
No ref / array / datetime on the custom-type form. Many property kinds → enable Categories. Only a few fixed values → enum.

2. publish_state ≠ status

Custom types use the system field publish_state (draft / published / private / trash) for the public site. Built-in blog uses status.

A custom field named status (e.g. “sold”) is a separate field - it does not replace publish_state. The Panel does not put id / slug / timestamps in the fields you declare (the system attaches those when saving an item).

3. Real-estate example - data design

NeedHow to declare
Listing of propertiesType code properties · data_file: properties.json
Sale / Rentlisting_type · enum: sale, rent
Apartment, land, condo…Enable Categories → usually properties-categories.json
Price, area, roomsprice, area_m2, bedrooms · number
Description / imagedescription html · cover_image image

3.1 Fill on the Panel (copy)

Type code: properties
Label: Real estate
Data file: properties.json
List route: properties → properties/index.html
Detail route: properties/{slug} → properties/detail.html
✓ Enable categories

Fields:
  title (string, required)
  description (html)
  listing_type (enum: sale, rent) required
  price · area_m2 · bedrooms · bathrooms (number)
  address · city (string)
  cover_image (image)

Don’t use reserved codes: posts, products, pages, contacts, orders, blog, shop, cart

3.2 After Panel Save - what does the system do?

(Same order as the AI docs - you don’t do this by hand if you already Saved on the Panel.)

  1. Update __cms_manifest__.json (properties entity + hidden category entity if enabled)
  2. Update __cms_ui_contract__.json (de_properties_list / detail / … keys + #de-item-list hook)
  3. Create sample HTML: properties/index.html, detail.html, (maybe) category.html
  4. Attach the public list route
  5. Menu at /cms shows a Real estate item

The listings data file (properties.json) is usually created when you add the first item - it doesn’t have to exist at Save-type time.

3.3 What you do in CMS

  1. Categories: Apartment, Condo, Townhouse, Land…
  2. Add listings: sale/rent, category, price, image…
  3. Set publish_state = published to show on the site

4. HTML hooks to keep

  • List: #de-item-list · body has data-aura-cms-root and data-aura-cms-entity="properties"
  • Detail: #de-item-detail
  • Category page (if any): #de-tax-item-list

5. What may AI edit? (after you Saved the type)

Edit: site HTML/JS (properties/index.html, detail.html) - grid, sale/rent filter, property-kind filter, price cards.

Don’t edit: platform admin UI under /cms.

await window.waitForAppStorage();

const mRes = await appifio_client.appifio_readFsFile('__cms_manifest__.json');
let manifest = mRes.data.content;
if (typeof manifest === 'string') manifest = JSON.parse(manifest);

const ent = manifest.entities.properties;
const dataFile = ent.data_file;

const r = await appifio_client.appifio_readList(
  dataFile,
  ['id','title','slug','listing_type','price','area_m2','city','cover_image','publish_state','category_id']
);
let items = (r.data.content || []).filter(p => p.publish_state === 'published');
// items = items.filter(p => p.listing_type === 'rent');

const catFile = ent.taxonomy?.categories?.data_file;
const cats = catFile
  ? (await appifio_client.appifio_readList(catFile, ['id','name','slug'])).data.content || []
  : [];
Common mistakes: JSON.parse again after readList; filter with status; hardcode file names; writeFile the whole ledger on a public page; delete the #de-item-list hook.

6. Sample prompt for AI

After Panel Save (recommended):

“CMS already has a properties type (Saved on the Panel). Read __cms_manifest__.json and __cms_ui_contract__.json, adjust properties/index.html + detail.html: listing grid, Sale/Rent filter (listing_type), property-kind filter (category_id), show only publish_state === published. Keep hooks #de-item-list / #de-item-detail. Don’t use Easy.”

Want AI to create the type (no Panel): see AS21 - must merge both declaration files exactly like the Panel.

7. Real-estate checklist

  1. CMS + Advanced + Aura prompt (+ CMS guide)
  2. Panel: create properties + fields from §3.1 + enable categories → Save
  3. Add categories + a few published listings
  4. Ask AI to polish HTML (prompt in §6)
  5. Check list/detail URLs + filters + hooks still present
  6. Don’t enable Easy Prompt

8. Common issues

SituationFix
Can’t create code posts / productsReserved codes - rename (e.g. properties)
CMS has items but list is emptyCheck publish_state (not status); read the correct data_file from the manifest
Layout looks good then CMS inject breaksRestore #de-item-list / #de-item-detail and body attrs

Next

AS21 - AI declares a custom type: merge manifest + UI contract like the Panel

Appifio Creator · AS20 · Custom types · Real estate