Trigger
The trigger metadata item can be used to cut down the amount of irrelevant
settings presented to the user in the rose config-edit GUI by
hiding any settings which are not relevant based on the value or state of other
settings.
Irrelevant (ignored or trigger-ignored) settings do not get
included in output files at runtime. In effect, they are commented
out (! or !! prefix in Rose configurations).
Example
In this example, we’ll be ordering pizza.
Create a new Rose application called trigger:
mkdir -p ~/rose-tutorial/trigger
cd ~/rose-tutorial/trigger
Create a rose-app.conf file that looks like this:
[command]
default=order.exe
[env]
BUDGET=10
[file:order.nl]
source=namelist:pizza_order namelist:side_order
[namelist:pizza_order]
extra_chicken=.false.
pepperoni_multiple=1
no_mushrooms=.false.
pizza_type='Veggie Supreme'
truffle='none'
[namelist:side_order]
garlic_bread=.false.
soft_drink=.false.
We’ll add some metadata to make it nice. Create a meta/
sub-directory with a rose-meta.conf file that looks like this:
[env]
[env=BUDGET]
type=integer
[file:order.nl]
[namelist:pizza_order]
[namelist:pizza_order=extra_chicken]
type=logical
[namelist:pizza_order=pepperoni_multiple]
values=1,2,3
[namelist:pizza_order=no_mushrooms]
type=logical
[namelist:pizza_order=pizza_type]
sort-key=00-type
values='Veggie Supreme', 'Pepperoni', 'BBQ Chicken'
[namelist:pizza_order=truffle]
values='none', 'white', 'black'
[namelist:side_order]
[namelist:side_order=garlic_bread]
type=logical
[namelist:side_order=soft_drink]
type=logical
Once you’ve done that, run rose config-edit in the application directory and navigate around the pages.
There are quite a lot of settings that are only relevant in certain
contexts - for example, namelist:pizza_order=extra_chicken is
pretty irrelevant if we’re ordering a 'Veggie Supreme'.
Adding Triggers
Let’s add some trigger information.
In the rose-meta.conf file, under
[namelist:pizza_order=pizza_type], add:
trigger=namelist:pizza_order=extra_chicken: 'BBQ Chicken';
namelist:pizza_order=pepperoni_multiple: 'Pepperoni', 'BBQ Chicken';
This states which values of pizza_type are relevant for which
settings. This means that extra_chicken is only relevant when
pizza_type is 'BBQ Chicken' - otherwise, it should be in
an ignored state. pepperoni_multiple is relevant for more than
one value of pizza_type.
We should also make sure we don’t order over our budget, especially
by splashing out on truffles. Add the following to [env=BUDGET]:
trigger=namelist:pizza_order=truffle: this > 25;
namelist:side_order: this >= 10;
See Metadata Mini-Language for details on this syntax.
What we’ve done here is use a small subset of the Rose configuration
metadata logical syntax to specify a range of allowed values (the
this > 25 part). Here, this is a placeholder for the value of
env=BUDGET; the expression syntax is essentially Pythonic.
We’ve also specified a section namelist:side_order in the trigger,
which is perfectly valid - this means that the whole section and its
options will be ignored when the value of env=BUDGET is below 10.
The truffle option will be ignored unless env=BUDGET is more than
25.
Fixing Trigger Errors
If we load the config editor (or reload the metadata) again, we
should get some trigger errors. These essentially say that some of
our settings are in the wrong state now - in our case, they should
be trigger-ignored.
You can fix them on the command line by running rose macro --fix
or rose macro -F in the app directory (one level up from the
meta directory) - this is what you would do if you were working with
a text editor and made changes to values.
Similarly, you can run “Autofix” in the config editor. You can do this in three ways:
By clicking the menu.
Using the Auto-fix toolbar button.
Or via the right-click menu for the root page in the left-hand tree panel, in this case
pizza_order.
Run “Autofix” in one of the above ways.
Results
If you accept the changes, the state of these settings will be corrected - if you go to the page, you’ll see that they’ve vanished! They’re actually just commented out, and viewable via the menu .
Try altering the values of namelist:pizza_order=pizza_type and
env=BUDGET with
on and off. This should enable and trigger-ignore different settings.
When env=BUDGET is below 10, the namelist:side_order section will
be trigger-ignored, and the garlic_bread and soft_drink will
be section-ignored - ignored because their parent section is ignored.
You can get more information about why an option is ignored in the config
editor by hovering over its ignored flag, or looking at the option’s menu
button Info entry.
Setting ids mentioned in the Info dialog are usually clickable links, so
you can go directly to the relevant id.
Multiple Inheritance
More than one setting can decide whether something is relevant. In that case, the subject is relevant only if all the parents agree that it is - an AND relationship.
For example, we already have one trigger for
namelist:pizza_order=truffle (env=BUDGET) - but it should also only
be relevant when namelist:pizza_order=no_mushrooms is .false..
Open the metadata file in a text editor, and add the following to the
[namelist:pizza_order=no_mushrooms] metadata section:
trigger=namelist:pizza_order=truffle: .false.
This means that the namelist:pizza_order=truffle option will only
be enabled when env=BUDGET is greater than 25 (our older trigger)
and namelist:pizza_order=no_mushrooms is .false..
Save the metadata file and reload the metadata in the config editor, and test it for yourself.
Cascading Triggering
Triggering is not just based on values - if a setting is missing or
trigger-ignored, any settings that it triggers will be
trigger-ignored by default i.e. triggers can
act in a cascade - A triggers B triggers C.
We can see this by replacing the env=BUDGET trigger with:
trigger=namelist:pizza_order=truffle: this > 25;
namelist:side_order: this >= 10;
namelist:pizza_order=pizza_type: this >= 5;
When env=BUDGET is less than 5, namelist:pizza_order=pizza_type
will be trigger-ignored. This means that all of its triggered
settings like namelist:pizza_order=extra_chicken are irrelevant and
will also be trigger-ignored.
We need to add no_mushrooms to the [namelist:pizza_order=pizza_type]
section so that it is trigger-ignored when no pizza can be ordered -
replace the [namelist:pizza_order=pizza_type] trigger with:
trigger=namelist:pizza_order=extra_chicken: 'BBQ Chicken';
namelist:pizza_order=pepperoni_multiple: 'Pepperoni', 'BBQ Chicken';
namelist:pizza_order=no_mushrooms;
Save, reload, and try changing env=BUDGET below 5 to see what it does
to the options in namelist:pizza_order.
Triggering Based On State
There’s also another way to express a trigger - you don’t have to express a value or range of values in a trigger expression.
Quite often you only want a setting to be trigger-ignored or enabled
purely based on the availability of another setting - whether it is present
and whether it is trigger-ignored. You might not care what particular
value it has.
This can be expressed by adding a trigger but omitting the value part of the syntax. Let’s add an option that we can use.
Add a new variable in the metadata by adding these lines to the metadata file:
[namelist:pizza_order=dip_type]
values='Garlic','Sour Cream','Salsa','Brown Sauce','Mustard'
We should add a trigger expression as well - replace the
[namelist:pizza_order=pizza_type] trigger with:
trigger=namelist:pizza_order=extra_chicken: 'BBQ Chicken';
namelist:pizza_order=pepperoni_multiple: 'Pepperoni', 'BBQ Chicken';
namelist:pizza_order=no_mushrooms;
namelist:pizza_order=dip_type;
This means that namelist:pizza_order=dip_type is dependent on
namelist:pizza_order=pizza_type, and will only be ignored when that
is ignored - but the value of pizza_type doesn’t matter to it.
Save the file and reload the metadata in the config editor. We’ll need to
add the namelist:pizza_order=dip_type to use it properly - you can do
this from the namelist:pizza_order page via:
The Add toolbar button.
The right-click page menu.
The menu.
After enabling the view, you should see dip_type appear as an option
that could be added. It will already have the correct triggered state (the
same state as namelist:pizza_order=pizza_type) - verify for yourself
that this works! You can then just add it via the menu button for the
option.
Further Reading
For more information see Configuration Metadata.