Tcl8.6 Coroutine domain. Invoking the domain URL creates a coroutine with semantics given by a lambda (evaluated within the Coco namespace,) and associates this running coroutine with an automatically-generated URL. The domain URL invocation, having generated its coroutine, redirects to it. Coco is like a [Direct] domain except the functional element is a coroutine not a namespace or object instance. The coroutine created by invoking a Coco domain has a unique name which will persist until the coroutine exits or until the server restarts. Coroutines maintain their local variable state, so Coco may be used to maintain persistent state for as long as the coroutine exists. It is possible, therefore, to use Coco as the basis of a session facility. The Cocoroutine is called with the request dict. [[yield]] may return a response to that request, which will subsequently be returned to the client. If [[yield]] is called without an argument, it returns an HTTP redirect to the coroutine's URL. == Coco Forms == Since Coco provides lightweight session persistence, keyed by synthetic URL, it can be used to validate forms. The [[Coco form]] command is invoked as ''[[Coco form $request $form [[list $fail_message $predicate]] ... ]]''. Where $request is the current HTTP request dict, $form is an HTML form (with an optional %MESSAGE string embedded), and args are a validation dict. Validation dicts associate the name of a field in the form with a list comprising a message to be displayed if the validation fails, and a tcl validation expression or predicate. The predicate may be anything acceptable to Tcl's [[expr]], and is expected to return a boolean value. All form fields are available to each predicate as tcl variables of the same name. [[Coco form]] will cause the Coco coroutine to re-issue the form until all validation predicates evaluate true. === Example: validating a form === [[Coco form]] provides a form validation facility. Once called, it will return the supplied form until all validation predicates are true. Nub domain /copf/ Coco lambda {r { set referer [Http Referer $r] ;# remember referer set r [yield] ;# initially just redirect set prefix "[
"Referer: '$referer'"]" set suffix [
[clock format [clock seconds]]] # validate the supplied form against a dict of field/validators set r [my Form $r info -prefix $prefix -suffix $suffix {
class message [join %MESSAGE%
]
fieldset personal {
legend [
]
text phone title "Phone number" -invalid "Phone number has to look like a phone number." -validate {[regexp {^[-0-9+ ]+$} $phone]}
}
}]
# now all the variable/fields mentioned in [form] have valid values
# resume where you were
return [Http Redirect $r $referer]
}}
== Examples ==
=== Simple interaction example ===
This Cocoroutine returns a simple form, collects its response, echoes it to the client, and terminates.
Nub domain /said/ Coco lambda {r {
set r [yield [Http Ok+ [yield] [