(* Existential type body for the fields of a table *) con crudField = fn t :: Type => { Name : text, (* Display name *) ToHtml : t -> bodyTags, (* Output the field value in HTML *) Input : tab :: NameOpt -> name :: FieldName -> tagsEnv form (Empty(Type)) [[@@tab.name : t]], (* Generate a form input tag for a value for this field *) InputInitialized : tab :: NameOpt -> name :: FieldName -> t -> tagsEnv form (Empty(Type)) [[@@tab.name : t]] (* Like Input, but with a default value *) } (* Default integer field handling *) val intFieldBody : text -> crudField integer con intField = fn name : text => pack integer with intFieldBody name as crudField end (* Default text field handling *) val textFieldBody : text -> crudField text con textField = fn name : text => pack text with textFieldBody name as crudField end (* Default unique ID field handling *) con idField = intField["ID"] (* Generate a CRUD web application entry point *) val crud : fs ::: {Exists(crudField)} (* The non-Id fields of the table *) -> tab :: Table ([Id : idField] ++ fs) (* The table itself *) -> seq :: Sequence (* Sequence for generating new Id's *) -> unit -> htmlTags