Code Templates and snippets

From OpenPetra Wiki
Jump to navigation Jump to search


We use Code templates for the code generation. This allows us to write common code with placeholders. It should be easy to read and maintain, and avoids writing code several times.

We use code templates for the Object Relational Mapping (ORM), ie. for the typed data tables and typed datasets. This code was previously generated with CodeDOM, but that got too complicated. The alternative would have been to have the source in strings in the generator code, but that is hard to read and to maintain.

We also use code templates for the Winforms generation, for the same reasons.

It might help to have a look at the template files, they are in csharp/ICT/PetraTools/Templates (on Git).



A placeholder is always with curly brackets, with a hash sign (#) and the name in capital letters.

eg. this is a place holder: {#NAMESPACE}

Now in the code generator, we call FTemplate.ReplacePlaceHolder("NAMESPACE", FCodeStorage.FNamespace);. You could also call FTemplate.SetCodelet("NAMESPACE", FCodeStorage.FNamespace);, it has the same effect, but ReplacePlaceHolder allows only one replacement, while SetCodelet overwrites previous assignments.

Alternatively, we can add several lines in a reserved place: eg.

   private void ShowData()

In the code generator, you will find the line:

FTemplate.AddToCodelet("SHOWDATA", "ShowDataManual();" + Environment.NewLine);

Note that all lines inserted into a place holder will have the same identation as the place holder had.

You can also clear a place holder, so that it will not appear in the result at all:


It is useful to clear the place holder before the code is processed, so that in the case there is no meaningful value for this place holder, then you will not get an error message. You can still call AddToCodelet or SetCodelet in the depths of your code generation. For a good place to initialise a codelet, see eg. Ict.Tools.CodeGeneration.Winforms, the function CreateCode, there is a comment "init some template variables that can be empty", with a number of initialisations of place holders.


Some code is needed several times inside a file. It has to be inserted by the generator.

The snippets are written at the end of a template file.

A snippet starts with a tag with two hash values (eg. {##SHOWDATAFORCOLUMN}), and ends when a new snippet starts or at the bottom of the file.



In the generator, you have to create a new Template for the snippet:

ProcessTemplate snippetShowData = writer.Template.GetSnippet("SHOWDATAFORCOLUMN");

You will insert the placeholders in that snippet, eg.:

snippetShowData.SetCodelet("CANBENULL", !AField.bNotNull ? "yes" : "");
snippetShowData.SetCodelet("DETERMINECONTROLISNULL", this.GetControlValue(ctrl, null));

And then insert the snippet into the main template, into a placeholder:

writer.Template.InsertSnippet("SHOWDETAILS", snippetShowData);


To avoid too much duplicate code, you can write template code once into one file, and include that template file into other template files.

The syntax is:

{#INCLUDE copyvalues.cs}

This is used for most of the Winforms templates to include commonly used snippets.


To generate code differently depending for several situations, you can create sections that will be enabled or disabled depending whether the referenced placeholder is empty or has a value.

Please note that {#IFDEF}, {#IFNDEF} and the closing tags {#ENDIF} and {#ENDIFN} need to have no leading nor trailing spaces.

a few examples:

       // get the details from the previously selected row
       if (FPreviouslySelectedDetailRow != null)