History for SkinScriptSyntax
??changed:- The !SkinScript Language Reference Preface This document describes the syntax for !SkinScript as defined in !ZPatterns 0.4.3, which is not yet publically available. If you are using an earlier version of !ZPatterns, the following features are not available: * The 'QUERY' keyword and the 'OTHERWISE LET' clause on 'WITH/COMPUTE' declarations * The 'INITIALIZE OBJECT WITH' declaration * The 'DEPENDENT ON' clause of 'WITH/COMPUTE' declarations It is also recommended that you read about HowTriggersWork before trying to define complex rules with !SkinScript. Basic Concepts and Syntax If you're familiar with ZPatterns, you know that DataSkins get their attributes and behavior from AttributeProviders and RuleAgents, respectively. Providers and Agents (known as DataPlugIns) can be written directly in Python, but it is much easier to write them in !SkinScript. !SkinScript lets you define an individual attribute provider or rule agent in a single declarative statement, using standard Zope tools such as SQL Methods, DTML Methods, Python Methods, and so on to do the actual data retrieval or storage. In effect, !SkinScript is a "glue language" which lets you define the linkages between a !DataSkin and the methods you want to implement its "skeleton" of data storage and triggered behavior. In most languages, the order that statements appear in makes a difference to the results you get, and !SkinScript is no exception. Although each !SkinScript statement defines a seperate and independent data plug-in, the ordering makes a difference in how they will be used by DataSkins. When a !DataSkin needs to perform an operation (such as retrieving an attribute), it asks its !DataManager for a list of suitable DataPlugIns. This list is ordered according to the original order of plug-ins as listed on the Data Plug-ins tab of the [Racks] or [Customizers] involved. And the declarations of a !SkinScript Method are treated as though they were individual plug-ins appearing in place of the !SkinScript Method in that list. In other words, !SkinScript is literally a language for defining data plug-ins. A !SkinScript *script* consists of a series of *declarations*, seperated by whitespace. Each declaration is compiled into a single data plug-in. !SkinScript is a keyword-driven language, is case-sensitive, and is not whitespace sensitive, even for Python expressions contained within declarations. All whitespace which occurs outside of quoted strings is treated as though it were a single space. (Incidentally, this means that the usual Python rules about where you can put linebreaks in expressions do not apply. You can write the expression '1+2' split across three lines, if you so desire.) Comments are marked as in Python, using a '#' symbol to mean that the rest of the current line is a comment. Comments are treated as simple whitespace. Declarations Declarations are the basic building block of !SkinScript. Declarations are compiled into AttributeProviders or RuleAgents, one per declaration. Some declarations provide attribute values: - 'INITIALIZE OBJECT WITH' *assignmentlist* - 'WITH ![QUERY]' *expression* 'COMPUTE' *nameorassignlist* ![OTHERWISE LET assignmentlist] ![DEPENDENT ON dependencies] - 'WITH SELF COMPUTE' *assignmentlist* Some handle attribute storage: - ![WHEN eventspec] 'STORE' *attributelist* 'USING' *expression* ![SAVING mementolist] - 'STORE' *attributelist* 'IN SELF' And others can call an expression upon transaction commit: - 'WHEN' *eventspec* 'CALL' *expression* ![SAVING mementolist] Each declaration has its own parameters, but there are certain conventions which are followed across most kinds of declarations. Declaration Parameters *expression* -- A DTML-style Python expression. As with DTML, the "_" object is available for access to Python built-ins and library functions. Please see the section below on "Variables and Functions Available in Expressions" for details on how names other than "_" are looked up in !SkinScript expressions. *assignmentlist* -- A comma-seperated list of assignments in the form *attributename* = *expression*, similar to passing keyword arguments to a function or method. *nameorassignlist* -- Similar to *assignmentlist*, but with a special shorthand for the case where *attributename* and *expression* are the same (e.g. 'foo=foo'). To make such an assignment, you can replace *attributename* '=' *expression* with just *attributename*. So 'foo=bar,baz=baz,bada=bing' can be simplified to 'foo=bar,baz,bada=bing' if a clause's syntax allows a *nameorassignmentlist*. *mementolist* -- A *mementolist* is syntactically identical to a *nameorassignlist*, but has a different context and purpose. A *mementolist* is used to save old values of expressions for later comparison purposes when a (sub)transaction commits, and appears only in 'SAVING' clauses. Expression variables are looked up in the context of the !DataSkin whose snapshot is being taken. So in the clause 'SAVING bar,foo=baz' the DataSkin's 'bar' attribute will be saved as OLD!['bar'], and its 'baz' attribute will be saved as OLD!['foo']. A *mementolist* is computed only once per (sub)transaction for a given !DataSkin. The first time the !DataSkin is changed in a (sub)transaction, the 'SAVING' clause is executed for all declarations that have one, even if the declaration never ends up firing. *eventspec* -- A clause of the form 'OBJECT ADDED, CHANGED, DELETED', where the 'ADDED', 'CHANGED' and 'DELETED' keywords may be used in any combination. For example, 'OBJECT ADDED,DELETED' and 'OBJECT CHANGED' are both valid *eventspec* clauses. Please see HowTriggersWork for details on how !ZPatterns events are interpreted by !SkinScript. *attributelist* -- A comma-seperated list of attribute names, to which the declaration will be applied. An asterisk ("*") may be used as a wildcard attribute name, meaning that the declaration will be applicable for any attribute name. Remember, however, that declarations associated with specific names will take precedence over wildcard declarations, even if the wildcard declaration comes before the specific declaration and would match the name being looked up. *dependencies* -- A comma-seperated list of attribute names which, when changed, will cause the dependent attributes to be recalculated on their next access. Wildcards cannot be used, only actual attribute names. Variables and Functions Available in Expressions Names used in an expression are usually looked up from the attributes of individual !SkinScript statement and its acquisition parents (e.g. the Rack or Customizer which it's contained in, and so on up the line). One exception to this rule is in the 'COMPUTE' clause of a WITH/COMPUTE declaration, where names are first looked up in the 'RESULT' object returned by the 'WITH' clause. The other exception is in 'SAVING' clauses, where names are looked up in the context of the !DataSkin whose snapshot is being taken. The following variable names and functions are provided by !SkinScript for use in expressions. * Generally available: 'self' -- The !DataSkin instance which the declaration is being applied to at the time the expression is being called. 'NOT_FOUND' -- A special value which causes an attribute to be non-existent, if this is the value provided. In a WITH/COMPUTE declaration, if the 'WITH' expression returns 'NOT_FOUND', the 'COMPUTE' clause is ignored, and the 'OTHERWISE LET' clause is activated if one exists. * Available for WITH/COMPUTE declarations: 'RESULT' -- The result of the 'WITH' expression in a WITH/COMPUTE declaration. Available only from expressions in the 'COMPUTE' clause. This variable is placed atop the DTML namespace stack during execution of the 'COMPUTE' clause, so just referring to a name in a 'COMPUTE' expression will look up that name in the 'RESULT' object first. Only if it is not found there, will the search continue to the declaration and its acquisition context. 'ATTRIBUTE_NAME' -- A string containing the name of the attribute which the !DataSkin is currently trying to retrieve. Available in both the 'WITH' and 'COMPUTE' clauses. * Available for WHEN/STORE and WHEN/CALL declarations: 'TRIGGER_EVENT' -- A string, either "ADD", "CHANGE", or "DELETE", denoting the type of event which caused the expression to be executed. 'OLD!["name"]' -- 'OLD' is a mapping object containing the values saved by the "SAVING mementolist" clause of a WHEN/STORE or WHEN/CALL declaration. [499 more lines...]
 
             Log in
                Log in
             Forgot your password?
                   Forgot your password?
                