Models

Complete P9 model definition syntax — objects, applications, fields, selects, lookups, and layouts.

Model Definition

A P9 model defines a business object — its fields, relationships, and user interface. Every object in Tuli is defined using this declarative syntax in .model files.

Object Declaration

Every model starts with object metadata:

@object Contract
@application Leasing
@icon "file-text-icon"
@group "Lease Management"
@order 1, 5
Directive Required Description
@object Yes Unique object name (PascalCase, no spaces)
@application Yes Module this object belongs to
@icon No Icon identifier for UI
@group No Navigation group within the module
@order No Display order (position, subposition)

Field Definitions

Fields use inline attribute syntax with colon-separated key-value pairs:

field TenantName type:Lookup label:"Tenant" required:true

field MonthlyRent type:Money label:"Monthly Rent" required:true

field StartDate type:Date label:"Lease Start Date" required:true default:[now()]

field Notes type:Text label:"Notes" optional:true multi-line:true placeholder:"Enter any additional notes..."

field ContractNumber type:Autonumber label:"Contract #" format:"CON-{yy}-#" readonly:true

Select Blocks

Define dropdown options for Select fields using curly braces:

field LeaseType type:Select label:"Lease Type" required:true

select LeaseType {
	label:"New" value:"New" default:true
	label:"Renewal" value:"Renewal"
	label:"Amendment" value:"Amendment"
	label:"Sublease" value:"Sublease"
}

Select options support visual indicators:

select Status {
	label:"Active" value:"Active" sentiment:Positive default:true
	label:"Pending" value:"Pending" sentiment:Neutral
	label:"Expired" value:"Expired" sentiment:Negative
}

select Priority {
	label:"Critical" value:"Critical" stars:5
	label:"High" value:"High" stars:4
	label:"Normal" value:"Normal" stars:3 default:true
	label:"Low" value:"Low" stars:2
}

Lookup Blocks

Define relationships to other objects:

field Tenant type:Lookup label:"Tenant" required:true

lookup Tenant {
	lookupobjectname:"Tenant"

	displayfield {
		"Name"
		"Number"
	}

	filter {
		Status="Active"
	}
}

Cascading lookups with parent relationships:

field Building type:Lookup label:"Building" required:true
field Unit type:Lookup label:"Unit" required:true parent:Building

lookup Unit {
	lookupobjectname:"Unit"

	displayfield {
		"Number"
		"Floor"
	}

	parents {
		Building {
			parentobjectfield: "Building"
		}
	}

	filter {
		Status="Available"
	}
}

Layout Definition

Control the form layout using a 12-column grid:

@layout
form {
	create {
		title:"Create Contract"
		savebuttontext:"Save"
		cancelbuttontext:"Cancel"

		section {
			title:"Contract Details"
			subtitle:"Basic contract information"

			row {
				layout:6,6
				fields ContractNumber,LeaseType
			}

			row {
				layout:12
				fields Tenant
			}

			row {
				layout:6,6
				fields Building,Unit
			}
		}

		section {
			title:"Term"
			subtitle:"Contract duration"

			row {
				layout:6,6
				fields StartDate,EndDate
			}

			row {
				layout:6
				fields Duration
			}
		}

		section {
			title:"Financial"
			subtitle:"Payment terms"

			row {
				layout:6,6
				fields MonthlyRent,AnnualRent
			}

			row {
				layout:6
				fields SecurityDeposit
			}
		}
	}

	list {
		mobile {
			fields ContractNumber,Tenant,MonthlyRent
		}

		desktop {
			fields ContractNumber,Tenant,Building,Unit,StartDate,EndDate,MonthlyRent,Status
		}
	}
}

Layout Columns:

  • layout:12 = one field, full width
  • layout:6,6 = two fields, 50% width each
  • layout:4,4,4 = three fields, 33% width each
  • layout:3,3,3,3 = four fields, 25% width each

Conditional Sections

Sections can have conditional visibility:

section show:[{Type}='Commercial'] {
	title:"Commercial Terms"

	row {
		layout:6,6
		fields CAMCharges,EscalationRate
	}
}

section show:[$RecordId != null] {
	title:"Status"

	row {
		layout:6
		fields Status
	}
}

Complete Contract Example

@object Contract
@application Leasing
@icon "file-text-icon"
@group "Lease Management"
@order 1, 1

field ContractNumber type:Autonumber label:"Contract #" format:"CON-{yy}-#" readonly:true search-field:true filter-order:"1"

field LeaseType type:Select label:"Lease Type" required:true

select LeaseType {
	label:"New" value:"New" default:true
	label:"Renewal" value:"Renewal"
	label:"Amendment" value:"Amendment"
}

field Tenant type:Lookup label:"Tenant" required:true linked-view:true advance-search:true

lookup Tenant {
	lookupobjectname:"Tenant"

	displayfield {
		"Name"
		"Number"
	}

	filter {
		Status="Active"
	}
}

field Building type:Lookup label:"Building" required:true linked-view:true advance-search:true

lookup Building {
	lookupobjectname:"Building"

	displayfield {
		"Name"
		"Number"
	}
}

field Unit type:Lookup label:"Unit" required:true parent:Building

lookup Unit {
	lookupobjectname:"Unit"

	displayfield {
		"Number"
		"Floor"
	}

	parents {
		Building {
			parentobjectfield: "Building"
		}
	}
}

field StartDate type:Date label:"Start Date" required:true

field EndDate type:Date label:"End Date" required:true

field Duration type:Number label:"Duration (Months)" required:true default:"12"

field MonthlyRent type:Money label:"Monthly Rent" required:true

field SecurityDeposit type:Money label:"Security Deposit" optional:true

field AnnualRent type:Calculated label:"Annual Rent" expression:"{MonthlyRent} * 12" readonly:true

field Status type:Select label:"Status" readonly:true

select Status {
	label:"Draft" value:"Draft" default:true
	label:"Pending Approval" value:"PendingApproval"
	label:"Active" value:"Active" sentiment:Positive
	label:"Expired" value:"Expired" sentiment:Negative
	label:"Terminated" value:"Terminated" sentiment:Negative
}

@layout
form {
	create {
		title:"Create Contract"
		savebuttontext:"Save"
		cancelbuttontext:"Cancel"

		section {
			title:"Contract Details"
			subtitle:"Basic contract information"

			row {
				layout:6,6
				fields ContractNumber,LeaseType
			}

			row {
				layout:12
				fields Tenant
			}

			row {
				layout:6,6
				fields Building,Unit
			}
		}

		section {
			title:"Term"
			subtitle:"Contract duration"

			row {
				layout:6,6
				fields StartDate,EndDate
			}

			row {
				layout:6
				fields Duration
			}
		}

		section {
			title:"Financial"
			subtitle:"Payment terms"

			row {
				layout:6,6
				fields MonthlyRent,AnnualRent
			}

			row {
				layout:6
				fields SecurityDeposit
			}
		}

		section show:[$RecordId != null] {
			title:"Status"

			row {
				layout:6
				fields Status
			}
		}
	}

	list {
		mobile {
			fields ContractNumber,Tenant,MonthlyRent
		}

		desktop {
			fields ContractNumber,Tenant,Building,Unit,StartDate,EndDate,MonthlyRent,Status
		}
	}
}

Experience the Platform

See how P9 and the Tuli platform work together

Ready to Build with P9?

Get hands-on with the platform. See how P9 accelerates your development workflow and integrates seamlessly with your existing systems.