Changes between Version 5 and Version 6 of KeepInterfaceSimplePlugin


Ignore:
Timestamp:
Nov 25, 2016, 6:48:28 PM (7 years ago)
Author:
Jon Ashley
Comment:

Minor improvements to the descriptions. Changed the expression grammar to make function parameters richer

Legend:

Unmodified
Added
Removed
Modified
  • KeepInterfaceSimplePlugin

    v5 v6  
    55== Description
    66
    7 This plugin helps manage configurations that contain lots of fields or have lots of rules about what is and isn't permitted. It can dynamically control what fields appear in the user interface depending on easily-configurable conditions. It can also block commits if necessary, such as when certain information hasn't been provided.
     7This plugin helps manage configurations that contain lots of fields or need to enforce rules for what is and isn't permitted. It can dynamically control what fields appear in the user interface depending on easily-configurable conditions. It can also block commits if specific conditions haven't been met.
    88
    99There are two main components, named 'assistant' and 'warden'. The Assistant manages the user-interface side, hiding and showing fields and options, and filling in fields for the user. The Warden enforces the rules that prevent commits.
     
    1111=== Hiding a field
    1212
    13 The Assistant uses simple C-like expressions to define what fields are presented to the user in different circumstances. For example, let's assume that the tickets contain a fields named 'approval', that should be hidden if the ticket is in the 'new' or 'closed' state. Write a `kis_assistant` rule for `approval.visible`:
     13The Assistant uses expressions to define what fields are presented to the user in different circumstances. Rule names start with the name of the field, followed by a dot, followed by the attribute "visible". If the rule evaluates to false, the field is hidden. The rule is re-evaluated whenever one of the fields affecting the result changes.
     14
     15For example, let's assume that the tickets contain a field named 'approval' that is to be hidden if the ticket is in the 'new' or 'closed' state. Write a `kis_assistant` rule for `approval.visible`:
    1416{{{#!ini
    1517[kis_assistant]
     
    2123approval.visible = status != 'new' && status != 'closed'
    2224}}}
    23 Because lists of states are quite common however, the Assistant also provides an `in` operator, with very high precedence. So another acceptable alternative would be:
     25Because lists of states are common, the Assistant also provides an `in` operator, with very high precedence. So another acceptable alternative would be:
    2426{{{#!ini
    2527[kis_assistant]
     
    2729}}}
    2830
    29 In expressions, 'authname' evaluates to the authenticated name of the user, and 'status' evaluates to the current ticket status.
    30 
    3131=== Hiding options
    3232
    33 Let's assume that we have a set of people on our project with the role of 'approver' (i.e. they are members of the Trac permissions group 'approver'). Let's also assume that the 'approval' field mentioned above is a Select or Radio field that has options 'Not assessed', 'Denied' and 'Approved'. The basic set of options 'Not assessed' or 'Denied' are available to all, but the full set of options including 'Approved' is only available if the user is a member of the 'approver' group or if the field already had the value 'Approved' when the page was loaded.
     33Options for a field are grouped into named sets, by adding the attribute ".options" to the field name, followed by a dot, followed by the name of the set. There is then a matching rule that has the attribute ".available" followed by a dot, followed by the name of the set. If the "available" rule evaluates true, the options in the set become available for selection in the interface.
     34
     35For example, let's assume that we have a set of people on our project with the role of 'approver' (i.e. they are members of the Trac permissions group 'approver'). Let's also assume that the 'approval' field mentioned above is a Select or Radio field that has options 'Not assessed', 'Denied' and 'Approved'. The basic set of options 'Not assessed' or 'Denied' are available to all, but the full set of options including 'Approved' is only available if the user is a member of the 'approver' group or if the field already had the value 'Approved' when the page was loaded.
    3436{{{#!ini
    3537approval.options.basic_set = 'Not assessed', 'Denied'
     
    3840approval.available.full_set = has_role('approver') || _approval == 'Approved'
    3941}}}
    40 The condition for the basic set of options being available is therefore just 'true'. The full set of options is available if the function 'has_role' returned 'true' when called with the parameter 'approver', or if the value of 'approval' when the page was loaded was already set to 'Approved'. The underscore in front of 'approval' means "use the value of this field at the time the page was loaded".
     42The condition for the basic set of options being available is therefore just 'true'. The full set of options is available if the function 'has_role' returned 'true' when called with the parameter 'approver', or if the value of 'approval' when the page was loaded was already set to 'Approved'. (The underscore in front of 'approval' means "use the value of this field at the time the page was loaded".)
    4143
    4244Note that the options are hidden, not removed. The user will still be able to select the option in most browsers by using keyboard shortcuts. Use a Warden rule to restrict the values accepted when a ticket is submitted, if that is what is needed.
     
    8082=== Blocking commits
    8183
    82 The Warden prevents commits from being made if certain conditions aren't met. For example, take the rules:
     84The Warden prevents commits from being made if certain conditions aren't met. Warden rules use the same expressions as the Assistant, but they are only evaluated when the ticket is submitted (or previewed).
     85
     86Rule names are arbitrary, but should be descriptive as they are reported to the user if the rule causes a ticket submission to be blocked.
     87
     88For example, take the rules:
    8389{{{#!ini
    8490[kis_warden]
     
    9197== Functions
    9298
    93 The 'has_role(<group>)' function is built-in, and returns true if and only if the user is a member of the named group. (A second parameter can be given, and allows a different user to be named, but this isn't normally needed.)
    94 
    95 Another built-in function is 'is_parent()', which returns true if and only if some other ticket has a field named 'parent' which contains a Trac link that points at the current ticket. It's designed to work with the ChildTicketsPlugin.
     99The same functions are available in both the Assistant and the Warden. Functions in the Assistant are evaluated once for a given set of parameters, and the result of the function call is cached. Unless the parameters change, the function won't be re-evaluated.
     100
     101=== Built-in functions
     102
     103There are two built-in functions:
     104 * has_role(<group> [, <user> ])
     105
     106   <group> is a string parameter naming a Trac permissions group. If the <user> parameter is omitted, it defaults to the current user. The function returns true if the user is a member of the named group, otherwise it returns false.
     107 * is_parent([ <ticket> ])
     108
     109   If the <ticket> parameter is omitted, it defaults to the current ticket. The function returns true if some other ticket has a field named 'parent' which contains a Trac link that points at the <ticket>, otherwise it returns false. This function is useful in conjunction with the ChildTicketsPlugin.
    96110
    97111=== User-defined functions
     
    122136== Expression syntax
    123137
    124 In expressions, field names evaluate to the current value of the corresponding field, except for the special names `status`, which evaluates to the ticket status, `authname`, which evaluates to the current username, `true` which evaluates True and `false`, which evaluates False. If the field name is prefixed with an underscore, it evaluates to the value of the field at the time the page was loaded.
     138In expressions, field names evaluate to the current value of the corresponding field, except for the special names `status`, which evaluates to the ticket status, `authname`, which evaluates to the current username, `true` which evaluates true and `false`, which evaluates false. If the field name is prefixed with an underscore, it evaluates to the value of the field at the time the page was loaded.
    125139
    126140Text-type fields evaluate to their contents, checkboxes evaluate to true if checked or false if not, and Select or Radio fields evaluate to the selected item if an item is selected or undefined if no item is selected.
     
    148162                             | <function_name> "(" param_list ")"
    149163                  cmp_list ::= "(" cmp_list ")"
    150                              | func_term
    151                              | func_term "," cmp_list
     164                             | expression
     165                             | expression "," cmp_list
    152166                param_list ::= *empty*
    153                              | term
    154                              | term "," param_list
     167                             | expression
     168                             | expression "," param_list
    155169                      term ::= "(" expression ")"
    156170                             | <number>
     
    158172                             | "'" <string> "'"
    159173}}}
    160 `~=` is an operator that returns True only if the value on the left is matched by the regular expression on the right. `in` is an operator that returns True only if the value on the left appears in the list on the right. The operators `!`, `==`, `!=`, `||` and `&&` are negation, equality, inequality, OR and AND respectively.
     174`~=` is a pattern-matching operator that returns True only if the value on the left is matched by the regular expression on the right. `in` is an operator that returns true only if the value on the left appears in the list on the right. The operators `!`, `==`, `!=`, `||` and `&&` are negation, equality, inequality, OR and AND respectively.
    161175
    162176Note that the `&&` and `||` operators evaluate in the same way as the Javascript operators (or the Python `and` and `or` operators). So 'x && y' evaluates to 'x' if 'x' is false; 'y' if 'x' is true. [[span('x || y')]] evaluates to 'x' if 'x' is true; 'y' if 'x' is false.