views

webclient grammar version xindi.1.1

'dependencies': dictionary { [ using ] }
'views': dictionary {
	'translate title': stategroup (
		'no' { }
		'yes' {
			'title': [ as ] reference
		}
	)
	'node type': [ (, ) ] component 'gui node type path'
	'queries': dictionary { [ query ]
		'context': [ from ] stategroup (
			'node' {
				'switch': stategroup (
					'current' {
						'query context': component 'gui node type path step'
					}
					'root' { [ root ] }
				)
				'path': [ path ] component 'query path'
			}
			'candidates' { [ candidates of ]
				'property context': component 'gui node type path step'
				'property': [ reference: ] reference
			}
		)
		'filters': group {
			'todo filter': stategroup (
				'yes' { [ where has-todo ]
					'path': [ (, ) ] component 'node path'
				}
				'no' { }
			)
			'filters': dictionary {
				'path': [ : ] component 'node path'
				'type': stategroup (
					'property' {
						'property': [ . ] reference
						'type': stategroup (
							'number' {
								'expression': component 'number filter expression'
							}
							'state group' { [ in ]
								'states to include': [ (, ) ] dictionary { [ ? ] }
							}
							'text' { [ = ]
								'text': text
							}
							'collection' {
								'operator': stategroup (
									'in' { [ in ] }
									'not in' { [ not in ] }
								)
								'keys': [ (, ) ] dictionary { [ [, ] ] }
							}
						)
					}
					'node' {
						'type': stategroup (
							'existence' {
								'operator': stategroup (
									'exists' { [ exists ] }
									'not exists' { [ not exists ] }
								)
							}
							'view context' { [ = view context ] }
						)
					}
				)
			}
		}
		'query limits': [ limit: ] group {
			'sample size': integer
			'show all limit': [ / ] integer
			'absolute maximum': [ / ] integer
		}
		'has columns': stategroup = node-switch .'columns' (
			| nodes = 'yes' { 'first' = first }
			| none  = 'no'
		)
		'columns': [ [, ] ] dictionary {
			'has successor': stategroup = node-switch successor (
				| node = 'yes' { 'successor' = successor }
				| none = 'no'
			)
			'name': reference
			'column type': stategroup (
				'id' { [ id ] }
				'content' { }
			)
			'path': [ -> ] component 'node path'
			'type': [ : ] stategroup (
				'text' {
					'text': [ text ] reference
					'filter': stategroup (
						'none' { }
						'simple' { [ filter ]
							'criteria': text
						}
						'current id path' { [ filter ] }
					)
				}
				'file' { [ file ]
					'file': reference
				}
				'number' {
					'number': [ number ] reference
					'has filter': stategroup (
						'no' { }
						'yes' { [ filter ]
							'operator selected': stategroup (
								'no' { }
								'yes' {
									'operator': stategroup (
										'smaller than' { [ < ] }
										'smaller than or equal to' { [ <= ] }
										'equal to' { [ = ] }
										'greater than or equal to' { [ >= ] }
										'greater than' { [ > ] }
									)
								}
							)
							'initial criteria': stategroup (
								'none' { [ none ] }
								'yes' {
									'source': stategroup (
										'now' { [ now ]
											'has offset': stategroup (
												'none' { }
												'yes' {
													'offset': [ + ] integer
												}
											)
										}
										'static' {
											'number': integer //fixme nest criteria in operator selected
										}
									)
								}
							)
						}
					)
				}
				'state group' {
					'state group': [ stategroup ] reference
					'has filter': stategroup (
						'no' { }
						'yes' { [ filter ]
							'filter enabled': stategroup (
								'yes' { [ enabled ] }
								'no' { [ disabled ] }
							)
							'states': [ ? ] dictionary { [ | ]
								'is selected': stategroup (
									'no' { }
									'yes' { [ selected ] }
								)
							}
						}
					)
				}
				'widget' {
					'instance': component 'widget expression'
				}
			)
		}
	}
	'instance': component 'widget expression'
}

The view context is the location in the model where the view binds to. This is especially convenient for queries that filter on the current node.

'gui node type path step' {
	'has steps': stategroup (
		'no' { }
		'yes' {
			'attribute': [ . ] reference
			'type': stategroup (
				'state' {
					'state': [ ? ] reference
				}
				'node' { }
			)
			'tail': component 'gui node type path step'
		}
	)
}
'gui node type path' {
	'steps': component 'gui node type path step'
}
'gui widget configuration list' {
	'has steps': stategroup (
		'no' { }
		'yes' {
			'configuration': component 'gui widget configuration node'
			'tail': component 'gui widget configuration list'
		}
	)
}
'view context parent path' {
	'type': stategroup (
		'state parent' { [ ?^ ] }
		'collection parent' { [ .^ ] }
		'group parent' { [ +^ ] }
	)
	'has tail': stategroup (
		'no' { }
		'yes' {
			'tail': component 'view context parent path'
		}
	)
}
'view context path' {
	'has steps': stategroup (
		'no' { }
		'yes' {
			'type': stategroup (
				'query entry' { [ entry ] }
				'parent' {
					'path': component 'view context parent path'
				}
				'reference' { [ > ] }
				'entity' { [ $ ] }
				'state rule' { [ *& ] }
			)
		}
	)
}
'widget expression' {
	'type': stategroup (
		'group' {
			'group': [ . ] reference
			'next': component 'widget expression'
		}
		'state' {
			'state group': [ . ] reference
			'state': [ ? ] reference
			'next': component 'widget expression'
		}
		'reference' {
			'text': [ > ] reference
			'next': component 'widget expression'
		}
		'reference rule' {
			'text': [ . ] reference
			'rule': [ & ] reference
			'next': component 'widget expression'
		}
		'state context rule' {
			'rule': [ .& ] reference
			'next': component 'widget expression'
		}
		'switch' {
			'state group': [ switch ] reference
			'states': [ (, ) ] dictionary { [ | ]
				'next': [ -> ] component 'widget expression'
			}
		}
		'parent' { [ ^ ]
			'next': component 'widget expression'
		}
		'widget' {
			'lazy': stategroup (
				'no' { }
				'yes' { [ lazy ] }
			)
			'widget': component 'widget instance'
		}
		'view' { [ view ]
			'using views': stategroup (
				'internal' { }
				'external' { [ from ]
					'views': reference
				}
			)
			'view': [ : ] reference
		}
	)
}
'widget instance' {
	'widget': reference
	'configuration': component 'gui widget configuration node'
}
'gui widget configuration attribute' {
	'type': stategroup (
		'widget' { [ : widget ]
			'instance': component 'widget expression'
		}
		'window' {
			'window': [ window ] reference
			'configuration': component 'gui widget configuration node'
		}
		'view' {
			'render': stategroup (
				'in window' { [ : open view ]
					'window': [ @ ] reference
				}
			)
			'using views': stategroup (
				'internal' { }
				'external' { [ from ]
					'views': reference
				}
			)
			'view context': component 'view context path'
			'view': [ : ] reference
		}
		'configuration' { [ : ]
			'type': stategroup (
				'number' {
					'source': stategroup (
						'now' { [ now ]
							'has offset': stategroup (
								'none' { }
								'yes' {
									'offset': [ + ] integer
								}
							)
						}
						'static' {
							'number': integer
						}
					)
				}
				'text' {
					'type': stategroup (
						'static' {
							'value': text
						}
						'phrase' {
							'value': reference
						}
						'key' { [, key ]
							'translate': stategroup (
								'yes' { [ phrase ] }
								'no' { }
							)
						}
					)
				}
				'list' {
					'list': [ [, ] ] component 'gui widget configuration list'
				}
				'states list' {
					'has states': stategroup = node-switch .'states' (
						| nodes = 'yes' { 'first' = first }
						| none  = 'no'
					)
					'states': [ (, ) ] dictionary {
						'has successor': stategroup = node-switch successor (
							| node = 'yes' { 'successor' = successor }
							| none = 'no'
						)
						'configuration': [ -> ] component 'gui widget configuration node'
					}
				}
				'state group' {
					'state': reference
					'configuration': component 'gui widget configuration node'
				}
			)
		}
		'model binding' { [ :: ]
			'type': stategroup (
				'window' { [ window ]
					'window': reference
					'configuration': component 'gui widget configuration node'
				}
				'entity' { [ entity ]
					'configuration': component 'gui widget configuration node'
				}
				'user' { [ user ]
					'configuration': component 'gui widget configuration node'
				}
				'current node' { [ node ]
					'property path': component 'model binding property path'
					'configuration': component 'gui widget configuration node'
				}
				'collection' { [ collection ]
					'property path': component 'model binding property path'
					'collection': [ . ] reference
					'join': stategroup (
						'yes' { [ join ] }
						'no' { }
					)
					'configuration': component 'gui widget configuration node'
				}
				'joined entry' { [ join ]
					'configuration': component 'gui widget configuration node'
				}
				'ordered graph' { [ ordered-graph ]
					'ordered graph': [ : ] reference
					'configuration': component 'gui widget configuration node'
				}
				'sort property' { [ sort ]
					'on': stategroup (
						'text' { [ text ] }
						'number' { [ number ] }
						'state group' { [ stategroup ] }
					)
					'property path': component 'model binding property path'
					'property': reference
					'configuration': component 'gui widget configuration node'
				}
				'query' { [ query ]
					'query context': stategroup (
						'node' {
							'switch': stategroup (
								'root' { [ on root ]
									'query': reference
								}
								'current node' {
									'property path': component 'model binding property path'
									'query': reference
								}
							)
						}
						'candidates' { [ candidates ]
							'query': reference
						}
					)
					'has refresh interval': stategroup (
						'no' { }
						'yes' { [ refresh: ]
							'interval': integer
						}
					)
					'configuration': component 'gui widget configuration node'
				}
				'group' {
					'group': [ group ] reference
					'configuration': component 'gui widget configuration node'
				}
				'state group' { [ stategroup ]
					'property path': component 'model binding property path'
					'state group': reference
					'configuration': [ -> ] component 'gui widget configuration node'
				}
				'state' { [ state ]
					'state group context': stategroup (
						'states list' { }
						'state group binding' {
							'state': [ | ] reference
						}
					)
					'configuration': component 'gui widget configuration node'
				}
				'state rule' { [ *& ]
					'rule': reference
					'configuration': component 'gui widget configuration node'
				}
				'number' { [ number ]
					'property path': component 'model binding property path'
					'property': reference
					'configuration': component 'gui widget configuration node'
				}
				'text' { [ text ]
					'property path': component 'model binding property path'
					'property': reference
					'configuration': component 'gui widget configuration node'
				}
				'file' { [ file ]
					'property path': component 'model binding property path'
					'property': reference
					'configuration': component 'gui widget configuration node'
				}
				'command' { [ command ]
					'property path': component 'model binding property path'
					'command': reference
					'configuration': component 'gui widget configuration node'
				}
				'action' { [ action ]
					'property path': component 'model binding property path'
					'action': reference
					'can use containing view': stategroup (
						'no' { }
						'yes' { [ use containing view ] }
					)
					'view bindings': dictionary {
						'window': [ : open view @ ] reference
						'using views': stategroup (
							'internal' { }
							'external' { [ from ]
								'views': reference
							}
						)
						'view': [ : ] reference
						'can open entry': stategroup (
							'no' { }
							'yes' {
								'window': [ and open view @ ] reference
								'using views': stategroup (
									'internal' { }
									'external' { [ from ]
										'views': reference
									}
								)
								'view': [ : ] reference
							}
						)
					}
					'configuration': component 'gui widget configuration node'
				}
				'query number' {
					'number': [ query number ] reference
					'configuration': component 'gui widget configuration node'
				}
				'query text' {
					'text': [ query text ] reference
					'configuration': component 'gui widget configuration node'
				}
				'query file' {
					'file': [ query file ] reference
					'configuration': component 'gui widget configuration node'
				}
				'query stategroup' {
					'stategroup': [ query stategroup ] reference
					'configuration': component 'gui widget configuration node'
				}
				'report' {
					'report': [ report ] reference
					'configuration': component 'gui widget configuration node'
				}
				'report text parameter' {
					'text': [ report text ] reference
					'configuration': component 'gui widget configuration node'
				}
				'report number parameter' {
					'number': [ report number ] reference
					'configuration': component 'gui widget configuration node'
				}
			)
		}
	)
}
'gui widget configuration node' { [ {, } ]
	'configuration': dictionary {
		'attribute': component 'gui widget configuration attribute'
	}
}
'node path' {
	'has steps': stategroup (
		'no' { }
		'yes' {
			'type': stategroup (
				'parent' { [ ^ ] }
				'state rule' { [ .& ]
					'rule': reference
				}
				'reference rule' {
					'property': [ . ] reference
					'rule': [ & ] reference
				}
				'reference' {
					'text': [ > ] reference
				}
				'group' {
					'group': [ + ] reference
				}
				'collection entry' {
					'collection': [ . ] reference
					'entry key': [ [, ] ] text
				}
				'state' {
					'state group': [ . ] reference
					'state': [ ? ] reference
				}
			)
			'tail': component 'node path'
		}
	)
}
'model binding property path' {
	'has steps': stategroup (
		'no' { }
		'yes' {
			'type': stategroup (
				'parent' { [ ^ ] }
				'group' {
					'group': [ + ] reference
				}
				'state group' {
					'state group': [ ? ] reference
					'state': [ | ] reference
				}
			)
			'tail': component 'model binding property path'
		}
	)
}
'query path step' {
	'has steps': stategroup (
		'no' { }
		'yes' {
			'type': stategroup (
				'group' {
					'group': [ + ] reference
				}
				'state' {
					'state group': [ ? ] reference
					'state': [ | ] reference
				}
			)
			'tail': component 'query path step'
		}
	)
}
'query path' {
	'has steps': stategroup (
		'no' { }
		'yes' {
			'head': component 'query path step'
			'collection': [ . ] reference
			'tail': component 'query path'
		}
	)
}
'number filter expression' {
	'operator': stategroup (
		'range' {
			'greater than': stategroup (
				'yes' { [ > ]
					'criterium': integer
				}
				'no' { }
			)
			'less than': stategroup (
				'yes' { [ < ]
					'criterium': integer
				}
				'no' { }
			)
		}
		'equals' { [ == ]
			'criterium': integer
		}
	)
}