views

webclient grammar version partitions-108.4.3.0

'dependencies': dictionary { [ using ] }
'views': dictionary {
	'translate title': stategroup (
		'no' { }
		'yes' {
			'title': [ as ] reference
		}
	)
	'node type': [ (, ) ] component 'gui node type path'
	'queries': dictionary { [ query ]
		'context': stategroup (
			'node' {
				'binds on': [ binds: ] component 'query context path'
				'switch': [ path: ] stategroup (
					'current' { }
					'root' { [ root ] }
				)
				'path': component 'query path'
			}
			'candidates' { [ candidates of ]
				'path': component 'query context path'
				'property': [ reference: ] reference
			}
		)
		'parameters': group {
			'nodes': dictionary { [ node parameter ]
				'source': component 'query parameter source'
			}
			'numbers': dictionary { [ number parameter ]
				'source': component 'query parameter source'
				'property': [ . ] reference
			}
			'texts': dictionary { [ text parameter ]
				'source': component 'query parameter source'
				'property': [ . ] reference
			}
		}
		'filters': group {
			'todo filter': stategroup (
				'yes' { [ where has-todo ]
					'path': [ (, ) ] component 'node path'
					'users filter': stategroup (
						'requesting user' { [ for user ] }
						'none' { }
					)
				}
				'no' { }
			)
			'filters': dictionary { [ where ]
				'type': [ : ] stategroup (
					'property' {
						'path': component 'node path'
						'property': [ . ] reference
						'type': stategroup (
							'number' {
								'expression': component 'number filter expression'
							}
							'state group' { [ in ]
								'states to include': [ (, ) ] dictionary { [ ? ] }
							}
							'text' { [ = ]
								'operator': stategroup (
									'in' { }
									'not in' { [ not ] }
								)
								'value': stategroup (
									'static' {
										'text': text
									}
									'parameter' { [ text $ ]
										'parameter': reference
									}
								)
							}
							'collection' {
								'operator': stategroup (
									'in' { [ in ] }
									'not in' { [ not in ] }
								)
								'candidates': [ query: ] reference
							}
						)
					}
					'node' {
						'path': component 'node path'
						'type': stategroup (
							'existence' {
								'operator': stategroup (
									'exists' { [ exists ] }
									'not exists' { [ not exists ] }
								)
							}
							'query binding context' { [ = query context ] }
							'parameter' { [ = ]
								'parameter': [ $ ] reference
							}
							'containment' {
								'operator': stategroup (
									'in' { [ in ] }
									'not in' { [ not in ] }
								)
								'references': reference
							}
						)
					}
					'texts' {
						'value': text
						'operator': stategroup (
							'in' { [ in ] }
							'not in' { [ not in ] }
						)
						'text paths': [ (, ) ] set {
							'path': [ - ] component 'node path'
							'property': [ . ] reference
						}
					}
					'repetition' { [ repetition ]
						'start': component 'query number'
						'interval': [ every ] component 'query number'
						'end': [ until ] component 'query number'
						'block start': [ in $ ] reference
						'block length': [ + $ ] reference
					}
					'condition' { [ condition $ ]
						'parameter': reference
					}
				)
				'enabled': stategroup (
					'yes' { }
					'no' { [ disabled ] }
				)
			}
		}
		'query limits': [ limit: ] group {
			'sample': stategroup (
				'yes' {
					'sample size': integer
					'show all limit': [ /, / ] integer
				}
				'no' { }
			)
			'absolute maximum': integer
		}
		'properties': component 'node query'
	}
	'instance': component 'widget expression'
}

The query binding context is the location in the model where the query binds on. This is especially convenient for queries that filter on the current node. repetition <path> .'start' every .'interval' until .'end' in $'block start' + $'block length' (number properties and number parameters); applied by the client to the result. condition $'p': the query has no entries when the node parameter is not resolved.

'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'
}
'widget configuration list' {
	'expression': component 'widget expression'
	'has next': stategroup (
		'no' { }
		'yes' { [ , ]
			'next': component 'widget configuration list'
		}
	)
}
'query context path' {
	'start at': stategroup (
		'root' { [ root ] }
		'view context' {
			'ancestor path': component 'ancestor node path'
		}
	)
	'steps': component 'gui node type path step'
}
'ancestor node path' {
	'has steps': stategroup (
		'no' { }
		'yes' { [ ^ ]
			'tail': component 'ancestor node path'
		}
	)
}
'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 (
		'switch' {
			'path': component 'node path'
			'state group': [ switch ] reference
			'states': [ (, ) ] dictionary { [ | ]
				'next': [ => ] component 'widget expression'
			}
		}
		'produce value' {
			'value': component 'widget expression tail'
		}
	)
}
'widget expression tail' {
	'type': stategroup (
		'default' { [ default ] }
		'widget' { [ widget ]
			'context': stategroup (
				'root' { [ root ] }
				'current' { }
			)
			'path': component 'context path'
			'type': stategroup (
				'inline' {
					'lazy': stategroup (
						'no' { }
						'yes' { [ lazy ] }
					)
					'widget': reference
					'configuration': component 'widget expression tail'
				}
				'view' { [ view ]
					'using views': stategroup (
						'internal' { }
						'external' { [ from ]
							'views': reference
						}
					)
					'view': [ : ] reference
				}
			)
		}
		'window' {
			'window': [ window ] reference
			'configuration': component 'widget expression tail'
		}
		'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
		}
		'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' {
					'path': component 'context path'
					'translate': [ key ] stategroup (
						'yes' { [ phrase ] }
						'no' { }
					)
				}
			)
		}
		'list' {
			'empty': stategroup (
				'yes' { [ empty ] }
				'no' {
					'path': component 'context path'
					'list': [ => [, ] ] component 'widget configuration list'
				}
			)
		}
		'states list' {
			'path': component 'context path'
			'has states': stategroup = node-switch .'states' (
				| nodes = 'yes' { 'first' = first }
				| none  = 'no'
			)
			'states': [ states (, ) ] dictionary {
				'has successor': stategroup = node-switch successor (
					| node = 'yes' { 'successor' = successor }
					| none = 'no'
				)
				'expression': [ = ] component 'widget expression'
			}
		}
		'state group' {
			'state': [ create ] reference
			'configuration': component 'widget expression tail'
		}
		'node' { [ (, ) ]
			'configuration': dictionary {
				'expression': [ = ] component 'widget expression'
			}
		}
		'binding' { [ :: ]
			'type': stategroup (
				'window' { [ window ]
					'window': reference
				}
				'entity' { [ entity ] }
				'node' { [, node ]
					'path': component 'node path'
				}
				'user' { [ user ] }
				'collection' { [ collection ]
					'path': component 'context path'
					'collection': reference
					'join': stategroup (
						'yes' { [ join ] }
						'no' { }
					)
				}
				'joined entry' { [ join ] }
				'ordered graph' { [ ordered-graph ]
					'ordered graph': [ : ] reference
				}
				'sort property' { [ sort ]
					'on': stategroup (
						'text' { [ text ] }
						'number' { [ number ] }
						'state group' { [ stategroup ] }
					)
					'property path': component 'node path'
					'property': reference
				}
				'query' { [ query ]
					'path': component 'context path'
					'query': reference
					'has refresh interval': stategroup (
						'no' { }
						'yes' { [ refresh: ]
							'interval': integer
						}
					)
				}
				'group' { [ group ]
					'path': component 'context path'
					'group': reference
				}
				'state group' { [ stategroup ]
					'path': component 'context path'
					'state group': reference
				}
				'state' { [ state ]
					'state group context': stategroup (
						'states list' { }
						'state group binding' {
							'state': reference
						}
					)
				}
				'state rule' {
					'path': component 'context path'
					'rule': [ state rule ] reference
				}
				'property rule' { [ rule ]
					'rule': reference
				}
				'number' { [ number ]
					'path': component 'context path'
					'property': reference
				}
				'text' { [ text ]
					'path': component 'context path'
					'property': reference
				}
				'file' { [ file ]
					'path': component 'context path'
					'property': reference
				}
				'command' { [ command ]
					'path': component 'context path'
					'command': reference
				}
				'action' { [ action ]
					'path': component 'context 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
							}
						)
					}
				}
				'query number' {
					'number': [ query number ] reference
				}
				'query text' {
					'text': [ query text ] reference
				}
				'query file' {
					'file': [ query file ] reference
				}
				'query stategroup' {
					'stategroup': [ query stategroup ] reference
				}
				'query collection' {
					'collection': [ query collection ] reference
				}
				'query filter' { [ query ]
					'type': stategroup (
						'text' { [ text ] }
						'generic' { }
					)
					'filter': [ filter ] reference
				}
				'query collection filter' {
					'filter': [ query collection filter ] reference
				}
				'report' {
					'path': component 'context path'
					'report': [ report ] reference
				}
				'report text parameter' {
					'text': [ report text ] reference
				}
				'report number parameter' {
					'number': [ report number ] reference
				}
			)
			'configuration': component 'widget expression tail'
		}
		'none' { [ none ] }
	)
}
'node step' {
	'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
		}
	)
}
'context path' {
	'has steps': stategroup (
		'no' { }
		'yes' {
			'step': component 'node step'
			'tail': component 'context path'
		}
	)
}
'node path' {
	'path': component 'context path'
}
'node query' {
	'has properties': stategroup = node-switch .'properties' (
		| nodes = 'yes' { 'first' = first }
		| none  = 'no'
	)
	'properties': [ [, ] ] dictionary {
		'has successor': stategroup = node-switch successor (
			| node = 'yes' { 'successor' = successor }
			| none = 'no'
		)
		'name': reference
		'column type': stategroup (
			'id' { [ id ] }
			'content' { }
		)
		'enumerable': stategroup (
			'no' { [ no-enum ] }
			'yes' { }
		)
		'hidden': stategroup (
			'no' { }
			'yes' { [ hidden ] }
		)
		'path': [ -> ] component 'node path'
		'type': [ : ] stategroup (
			'text' {
				'text': [ text ] reference
				'filter': stategroup (
					'none' { }
					'simple' { [ filter ]
						'operator': stategroup (
							'in' { }
							'not in' { [ not ] }
						)
						'criteria': text
					}
					'current id path' { [ filter ] }
					'containment' {
						'operator': stategroup (
							'in' { [ in ] }
							'not in' { [ not in ] }
						)
						'references': reference
					}
				)
			}
			'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 ] }
							)
						}
					}
				)
			}
			'collection' {
				'collection': [ collection ] reference
				'has filter': stategroup (
					'no' { }
					'yes' {
						'candidates': [ filter: ] reference
					}
				)
				'properties': component 'node query'
			}
			'widget' {
				'instance': component 'widget expression'
			}
		)
	}
}

If no-enum is provided, the query property will be excluded from the columns collection in the client bindings. For exmaple: it is only available as a query text or query text column binding.

'query path step' {
	'has steps': stategroup (
		'no' { }
		'yes' {
			'type': stategroup (
				'group' {
					// The '+' is used to be compatibel with the client request schema.
					'group': [ + ] reference //FIXME use dot notation
				}
				'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
			'type': stategroup (
				'candidates' { [ candidates ] }
				'existing entries' { }
			)
			'tail': component 'query path'
		}
	)
}
'number filter expression' {
	'operator': stategroup (
		'range' {
			'greater than': stategroup (
				'yes' { [ > ]
					'terms': component 'number criterium terms'
					'criterium': integer
				}
				'no' { }
			)
			'less than': stategroup (
				'yes' { [ < ]
					'terms': component 'number criterium terms'
					'criterium': integer
				}
				'no' { }
			)
		}
		'equals' { [ == ]
			'terms': component 'number criterium terms'
			'criterium': integer
		}
	)
}

$'a' + $'b' + 5 is the sum of the parameters a and b and 5.

'number criterium terms' {
	'terms': dictionary { [ $, + ] }
}
'query number' {
	'path': component 'node path'
	'property': [ . ] reference
}
'query parameter source' {
	'type': stategroup (
		'query binding context' { [ query context ]
			'path': component 'node path'
		}
	)
}