While the above code will work, it has a couple of drawbacks. Firstly, the code to generate getters and setters cannot be re-used in other templates. Secondly, the template is arguably hard to read - the purpose of the loop's body is not immediately clear.

Notice that, in the body of the loop, we call the template operations, getter and setter, to generate the getter and setter methods for each feature. This makes the loop arguably easier to read, and the getter and setter operations can be re-used in other templates.

Template operations are annotated with @template and can mix dynamic and static sections, just like the main part of an EGL template. Operations are defined on metamodel types (Feature in the code above), and may be called on any model element that instantiates that type. In the body of an operation, the keyword self is used to refer to the model element on which the operation has been called.

Common issues

Issue: my template operation produces no output.

Resolution: ensure that the call to the template operation is placed in a dynamic output section (e.g. [%=thing.op()%]) rather than in a plain dynamic section (e.g. [% thing.op(); %]). Template operations return a value, which must then be emitted to the main template using a dynamic output section.