| layout | default |
|---|---|
| title | Lesson 5: More Fix concepts |
| nav_order | 5 |
| parent | Tutorial |
We already learned about simple Fixes aka Fix functions but there are three additional concepts in Fix: selector, conditionals and binds.
These Fix concepts were introduced by Catmandu (see functions, selector, conditionals and binds). Be aware that Metafacture Fix does not support all of the specific functions, selectors, conditionals and binds from Catmandu. Check the documentation for a full overview of the supported Fix functions.
The following code snippet shows examples of each of these concepts:
# Simple Fix function
add_field("hello", "world")
remove_field("my.deep.nested.junk")
copy_field("stats", "output.$append")
# Conditionals
if exists("error")
set_field("is_valid", "no")
log("error")
elsif exists("warning")
set_field("is_valid", "yes")
log("warning")
else
set_field("is_valid", "yes")
end
# Selector
if exists("error")
reject()
end
# Binds - Loops
do list(path: "foo", "var": "$i")
add_field("$i.bar", "baz")
endFix functions are used to add, change, remove or otherwise manipulate elements. They were introduced in Lesson 3.
The other three concepts help when you intend to use more complex transformations:
Conditionals are used to control the processing of Fix functions. The included Fix functions are not processed with every workflow but only under certain conditions.
Selectors can be used to filter the records you want.
Binds are wrappers for one or more Fixes. They give extra control functionality for Fixes such as loops. All binds have the same syntax:
do Bind(params,...)
Fix(...)
Fix(...)
endConditionals are a common concept in programming and scripting languages. They control processes, in our scenario: transformations, with regard to specific requirements.
For example, some of these records are of type book:
---
name: "The 13 1/2 lives of Captain Bluebear"
medium: "Book"
author: "Walter Moers"
language: "eng"
---
name: "The 13 1/2 lives of Captain Bluebear"
medium: "eBook"
author: "Walter Moers"
language: "eng"
---
name: "Die 13½ Leben des Käpt’n Blaubär"
medium: "Book"
author: "Walter Moers"
language: "ger"
---
name: "The 13 1/2 lives of Captain Bluebear"
medium: "Audio Book"
author: "Walter Moers"
narrator: "Bronson Pinchot"
language: "eng"
---
name: "Käpt'n Blaubär - Der Film"
medium: "Movie"
author: "Walter Moers"
director: "Hayo Freitag"
language: "ger"If we want to add an element type for every record then we simply use the Fix function add_field("type","BibliographicResource")
But if you want to add more specific type depending on the medium then we use contitionals.
only add_field("type","BibliographicResource") if medium contains Book:
if all_contain("medium","Book")
add_field("type","BibliographicResource")
endif all_equal("medium","Book")
add_field("type","BibliographicResource")
endUse unless to add transformations for all that do not meet the condition:
unless all_equal("medium","Book")
add_field("type","Other")
endif all_equal("medium","Book")
add_field("type","BibliographicResource")
else # if previous condition is false.
add_field("type","Other")
endif all_equal("medium","Book")
add_field("type","BibliographicResource")
elsif all_contain("medium","Audio")
add_field("type","AudioResource")
elsif all_match("medium",".*Movie.*")
add_field("type","AudioVisualResource")
else
add_field("type","Other")
endMetafacture supports lots of conditionals, find a list of all of them here.
At the moment Metafacture Fix only supports one of Catmandus selectors: reject. With reject you can kick out records that you do not want to process:
if all_contain("medium","Book")
reject()
endThis Fix used with our example above kicks out all records containing the word Book.
Selectors work in combination with conditionals to define the conditions that you want to kick out.
See the list of supported selectors.
As mentioned above Binds are wrappers for one or more Fixes. They give extra control functionality for Fixes such as loops. All binds have the same syntax:
do Bind(params,...)
Fix(...)
Fix(...)
endThe most commonly used is do list. It allows to iterate over each element of an array.
If we have a record:
---
colours:
- red
- yellow
- greenand you use the Fix
upcase("colours[].*")
append("colours[].*"," is a nice color")
copy_field("colours[].*","result.$append")It results in:
---
colours:
- "RED is a nice color"
- "YELLOW is a nice color"
- "GREEN is a nice color"
result: "RED is a nice color"
result: "YELLOW is a nice color"
result: "GREEN is a nice color"If you want to only change it under a certain condition:
if any_equal("colours[]","green")
upcase("colours[].*")
append("colours[].*"," is a nice color")
copy_field("colours[].*","result[].$append")
endThis still transforms all elements of an array because the conditional tests all elements, not each individually.
To only tranform and copy the value green to an X you have to use the do list-Bind:
do list(path:"colours[]","var":"$i")
if any_equal("$i","green")
upcase("$i")
append("$i"," is a nice color")
copy_field("$i","result[].$append")
end
endSee this example in the playground.
See the list of supported binds.
TODO: Add excercises.
Next lesson: 06 Metafacture CLI