\label{doc_tutorials_code-generator_md_md_doc_tutorials_code_generator}%
\Hypertarget{doc_tutorials_code-generator_md_md_doc_tutorials_code_generator}%
 This guide focuses on writing new templates for the code-\/generator. For using the code generator take a look at the man-\/page \mbox{\hyperlink{doc_help_kdb-gen_md}{\`{}kdb-\/gen(1)\`{}}}. For specifically using the code-\/generator for the high-\/level API you may want to follow \mbox{\hyperlink{doc_tutorials_highlevel_md}{this guide}}.\hypertarget{doc_tutorials_code-generator_md_autotoc_md3518}{}\doxysection{Basics}\label{doc_tutorials_code-generator_md_autotoc_md3518}
The underlying framework of {\ttfamily kdb gen} is quite flexible. It is based on the \href{https://mustache.github.io/}{\texttt{ mustache templating system}}. Concretely we use \href{https://github.com/kainjow/Mustache}{\texttt{ this C++ library}} as a basis.

To distinguish the user facing parts of {\ttfamily kdb gen} from the internal layer interfacing {\ttfamily kdb gen} to the mustache library, we will call the internal layer the {\itshape framework}.

The file \href{/home/jenkins/workspace/libelektra-release/src/tools/kdb/gen.cpp}{\texttt{ {\ttfamily src/tools/kdb/gen.\+cpp}}} implements the command-\/line interface (CLI) and is of little interest to this guide. Instead we will focus on the framework that is invoked via the CLI. The bulk of the framework is implemented in the classes \href{/home/jenkins/workspace/libelektra-release/src/tools/kdb/gen/template.hpp}{\texttt{ {\ttfamily Gen\+Template} and {\ttfamily Gen\+Template\+List}}} (and of course kainjow\textquotesingle{}s mustache library).

First we need to define a few terms\+:


\begin{DoxyItemize}
\item {\itshape template name}\+: This is the main identifier of a template. It is used in the command line to choose the template.
\item {\itshape template base name}\+: Unlike the template name, this identifier is internal to the framework. It will not be seen by users of {\ttfamily kdb gen}. This is the base name of all mustache files belonging to the template. In most cases this will be the same as the template name.
\item {\itshape input keyset}\+: This keyset contains the data with which the template will be instantiated by the code-\/generator.
\item {\itshape parent key}\+: The parent key is given in the command line and defines the input keyset (the keys below the parent key).
\item {\itshape output name}\+: The base name for the output files as given in the command line. Suffixes may be appended, if there are multiple output files.
\item {\itshape parts}\+: Each template may consist of multiple parts. Each part corresponds to exactly one mustache file and therefore exactly one output file.
\item {\itshape part suffix}\+: Parts are identified by there part suffix. This suffix is appended to the template base name to obtain the name of the mustache file corresponding to the part. Similarly it is appended to the output name to obtain the output file for this part. The empty string {\ttfamily \char`\"{}\char`\"{}} is a valid part suffix, although it is only recommend for templates with a single output file.
\end{DoxyItemize}

All templates consist of two pieces. The set of mustache files (on for each part) and an accompanying C++ class to supply the mustache rendering engine with data from the input keyset.\hypertarget{doc_tutorials_code-generator_md_autotoc_md3519}{}\doxysection{Creating a new template}\label{doc_tutorials_code-generator_md_autotoc_md3519}
In this guide we will create a basic template, that generates a single file containing a simple list of all keys in our input keyset. An example output from running {\ttfamily kdb gen} with our to-\/be-\/developed template would be\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{user:/sw/myapp/\#0/current}
\DoxyCodeLine{user:/sw/myapp/\#0/current/dir0}
\DoxyCodeLine{user:/sw/myapp/\#0/current/dir0/subdir0/key0}
\DoxyCodeLine{user:/sw/myapp/\#0/current/dir0/subdir0/key1}
\DoxyCodeLine{user:/sw/myapp/\#0/current/dir1}

\end{DoxyCode}


As you can see, the result matches that of redirecting the stdout of {\ttfamily kdb ls} into a file.\hypertarget{doc_tutorials_code-generator_md_autotoc_md3520}{}\doxysubsection{Creating the mustache template}\label{doc_tutorials_code-generator_md_autotoc_md3520}
The first thing we need to create is a mustache template. You will need (at least) one template file for each output file. If you make use of partials (see \href{\#using-partials}{\texttt{ below}}), you of course have to write multiple files.

All template files must be located in the \`{}src/tools/kdb/gen/templates\`{} folder and must be named according to the scheme {\ttfamily $<$template base name$>$.$<$part suffix$>$.mustache}.

For our simple example we create the file {\ttfamily src/tools/kdb/gen/templates/example.\+txt.\+mustache} with the following content\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\{\{\# keys \}\}}
\DoxyCodeLine{\{\{\{ name \}\}\}}
\DoxyCodeLine{\{\{/ keys \}\}}

\end{DoxyCode}


Note\+: we will not go into detail on how mustache templates work, for more information see e.\+g. \href{https://mustache.github.io/mustache.5.html}{\texttt{ here}}. All of features supported by the kainjow library should be supported by our framework as well.

Our CMake script will collect all {\ttfamily .mustache} files in {\ttfamily src/tools/kdb/gen/templates} into a header containing a {\ttfamily static const char $\ast$} field for each file and a {\ttfamily std\+::unordered\+\_\+map} containing references to all the fields. The naming scheme is needed so that the other C++ code can access the files contents via the map. This approach was chosen to allow executing the code-\/generator without first running the install script.

When you create a new {\ttfamily .mustache} file (either for a new part or a new partial), you need to invoke {\ttfamily cmake} again, so that all the files are collected.\hypertarget{doc_tutorials_code-generator_md_autotoc_md3521}{}\doxysubsection{Creating the supporting class}\label{doc_tutorials_code-generator_md_autotoc_md3521}
Since we need to some way of supplying data to our template, we have to create a subclass of {\ttfamily Gen\+Template}.

First we create a new directory for our template class in {\ttfamily src/tools/kdb/gen}, for our template it should be {\ttfamily src/tools/kdb/gen/example}. In this directory we then create {\ttfamily example.\+cpp} and {\ttfamily example.\+hpp}. If your template class becomes sufficiently complex, it may make sense to split the code into multiple classes and into multiple files, for this reason we recommend creating a new directory for each template. The CMake script will also automatically recognize your files, if you put them directly into {\ttfamily src/tools/kdb/gen}, but using additional subdirectories (beyond the one matching your template name) like {\ttfamily src/tools/kdb/gen/example/src} would require modifying \`{}src/tools/kdb/\+CMake\+Lists.txt\`{}.

In {\ttfamily example.\+cpp} and {\ttfamily example.\+hpp} we create our subclass of {\ttfamily Gen\+Template}. Therefore {\ttfamily example.\+hpp} should look like this\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#ifndef ELEKTRA\_EXAMPLE\_HPP}}
\DoxyCodeLine{\textcolor{preprocessor}{\#define ELEKTRA\_EXAMPLE\_HPP}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <gen/template.hpp>}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{class }ExampleGenTemplate : \textcolor{keyword}{public} GenTemplate}
\DoxyCodeLine{\{}
\DoxyCodeLine{\textcolor{keyword}{public}:}
\DoxyCodeLine{    ExampleGenTemplate () : GenTemplate (\textcolor{stringliteral}{"{}example"{}}, \{ \textcolor{stringliteral}{"{}.txt"{}} \}, \{\}, \{\})}
\DoxyCodeLine{    \{}
\DoxyCodeLine{    \}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{protected}:}
\DoxyCodeLine{    kainjow::mustache::data getTemplateData (\textcolor{keyword}{const} std::string \& outputName, \textcolor{keyword}{const} std::string \& part, \textcolor{keyword}{const} \mbox{\hyperlink{classkdb_1_1KeySet}{kdb::KeySet}} \& ks,}
\DoxyCodeLine{                                             \textcolor{keyword}{const} std::string \& parentKey) \textcolor{keyword}{const override};}
\DoxyCodeLine{\};}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#endif }\textcolor{comment}{// ELEKTRA\_EXAMPLE\_HPP}}

\end{DoxyCode}


Apart from the line {\ttfamily Example\+Gen\+Template () \+: Gen\+Template (\char`\"{}example\char`\"{}, \{ \char`\"{}.\+txt\char`\"{} \}, \{\}, \{\})} everything should be more or less the same for all templates. Let\textquotesingle{}s dissect this line\+:


\begin{DoxyItemize}
\item {\ttfamily Example\+Gen\+Template ()} we declare a zero argument constructor. All templates {\itshape must} have only a single zero argument constructor, otherwise the framework cannot instantiate them.
\item {\ttfamily \+: Gen\+Template (} the constructor must invoke the base-\/class constructor.
\item {\ttfamily \char`\"{}example\char`\"{},} we decided to use {\ttfamily example} as the base name for our template files. This base name will be replaced by the {\ttfamily output\+Name} chosen by the user, when invoking the code-\/generator.
\item {\ttfamily \{ \char`\"{}.\+txt\char`\"{} \},} this is the list of part suffixes for our template. We only have a single part (output file) with the suffix {\ttfamily .txt}.
\item {\ttfamily \{\},} the first empty list would contain all the partials our template uses. We don\textquotesingle{}t use any.
\item {\ttfamily \{\},} the second empty list, is actually a map. It would contain all parameters and whether they are required or not. We don\textquotesingle{}t have parameters.
\end{DoxyItemize}

As you can see, the header is quite simple. The more important part is actually the source file. It contains the implementation of {\ttfamily get\+Template\+Data}, the function that delivers all the template data to the framework.

For our example we will use this implementation\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#include "{}example.hpp"{}}}
\DoxyCodeLine{}
\DoxyCodeLine{kainjow::mustache::data ExampleGenTemplate::getTemplateData (\textcolor{keyword}{const} std::string \& outputName, \textcolor{keyword}{const} std::string \& part,}
\DoxyCodeLine{                                                             \textcolor{keyword}{const} \mbox{\hyperlink{classkdb_1_1KeySet}{kdb::KeySet}} \& ks, \textcolor{keyword}{const} std::string \& parentKey)\textcolor{keyword}{ const}}
\DoxyCodeLine{\textcolor{keyword}{}\{}
\DoxyCodeLine{    \textcolor{keyword}{using namespace }\mbox{\hyperlink{namespacekdb}{kdb}};}
\DoxyCodeLine{    \textcolor{keyword}{using namespace }kainjow::mustache;}
\DoxyCodeLine{}
\DoxyCodeLine{    list keyList;}
\DoxyCodeLine{}
\DoxyCodeLine{    \textcolor{keywordflow}{for} (\textcolor{keyword}{auto} it = ks.begin (); it != ks.end (); ++it)}
\DoxyCodeLine{    \{}
\DoxyCodeLine{        Key key = *it;}
\DoxyCodeLine{}
\DoxyCodeLine{        \textcolor{keyword}{auto} keyObject = object(\{ \{ \textcolor{stringliteral}{"{}name"{}}, key.getName() \} \});}
\DoxyCodeLine{}
\DoxyCodeLine{        keyList.emplace\_back(keyObject);}
\DoxyCodeLine{    \}}
\DoxyCodeLine{}
\DoxyCodeLine{    \textcolor{keyword}{auto} data = object(\{ \{ \textcolor{stringliteral}{"{}keys"{}}, keyList \} \});}
\DoxyCodeLine{}
\DoxyCodeLine{    \textcolor{keywordflow}{return} data;}
\DoxyCodeLine{\}}

\end{DoxyCode}


The framework will invoke {\ttfamily get\+Template\+Data} for each part of our template with the {\ttfamily output\+Name} and {\ttfamily parent\+Key} as given on the command line, as well as the current part suffix ({\ttfamily part}) and the input keyset {\ttfamily ks}. All keys of the input keyset are guaranteed to be below {\ttfamily parent\+Key}.

The code above simply iterates over the input Key\+Set and for each key creates an object {\ttfamily \{ name\+: \$key\+Name \}}. All those objects are collected into a list, which is then stored under the key {\ttfamily keys} in the global object.\hypertarget{doc_tutorials_code-generator_md_autotoc_md3522}{}\doxysubsection{Adding the class to $<$tt$>$\+Gen\+Template\+List$<$/tt$>$}\label{doc_tutorials_code-generator_md_autotoc_md3522}
To make the framework aware of our class (and by extension our template), we have to then add it to {\ttfamily Gen\+Template\+List}. This is simply done by adding a line to the implementation of {\ttfamily Gen\+Template\+List\+::\+Gen\+Template\+List ()} in \href{/home/jenkins/workspace/libelektra-release/src/tools/kdb/gen/template.cpp}{\texttt{ {\ttfamily template.\+cpp}}}.

For our example that is\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{addTemplate<ExampleGenTemplate> (\textcolor{stringliteral}{"{}example"{}});}

\end{DoxyCode}


We need to specify {\ttfamily \char`\"{}example\char`\"{}} again, because this string defines how our template shall be called, i.\+e. what we need to specify in the terminal to invoke it.

You also need to add the appropriate {\ttfamily \#include} at the top of the file. In our case this is\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#include "{}example/example.hpp"{}}}

\end{DoxyCode}
\hypertarget{doc_tutorials_code-generator_md_autotoc_md3523}{}\doxysection{Using the new template}\label{doc_tutorials_code-generator_md_autotoc_md3523}
Now you should be able to use the new template by running (after compiling/installing Elektra again)\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{kdb gen example user userkeys}

\end{DoxyCode}


This should produce the file {\ttfamily userkeys.\+txt}. The file should be the same, as if we had called {\ttfamily kdb ls user\+:/ $>$ userkeys.\+txt}.\hypertarget{doc_tutorials_code-generator_md_autotoc_md3524}{}\doxysection{Advanced concepts}\label{doc_tutorials_code-generator_md_autotoc_md3524}
Lastly, we will discuss a few more advanced concepts.\hypertarget{doc_tutorials_code-generator_md_autotoc_md3525}{}\doxysubsection{Switching delimiters}\label{doc_tutorials_code-generator_md_autotoc_md3525}
Switching the delimiters is fully supported and already in use in the high-\/level API template to allow for easier formatting.\hypertarget{doc_tutorials_code-generator_md_autotoc_md3526}{}\doxysubsection{Parameters}\label{doc_tutorials_code-generator_md_autotoc_md3526}
Sometimes you want to incorporate user input beyond the contents of the input keyset into the code-\/generation. For example, if you generate a web page, you may need to now where it is going to be hosted, so that you can generate correct links. Another example would be letting the user choose the name of a generated function, when generating C code.

The first case would be required parameter. Without the domain name, we cannot generate the links. The second example meanwhile may be an optional parameter. We could just use a sensible default name for the function, since it doesn\textquotesingle{}t matter much which function the user will call in their own code.

Our framework supports both required and optional parameters. To define the parameters of your template use the {\ttfamily parameters} argument of the {\ttfamily Gen\+Template} constructor. This parameter is a map from strings to bools. The keys are the parameter names and the values define, whether the parameter is required ({\ttfamily true} means required).

Our two examples could use {\ttfamily \{ \{ \char`\"{}domain\+\_\+name\char`\"{}, true \} \}} and {\ttfamily \{ \{ \char`\"{}function\+\_\+name\char`\"{}, false \} \}} respectively.

To access the parameter value call one of the {\ttfamily get\+Parameter} overloads. One takes a default value, the other takes a map of values and verifies that one of the given values has been chosen. For more information see the relevant code documentation. There is also {\ttfamily get\+Bool\+Parameter} which a specialised version for boolean parameters. It accepts only {\ttfamily 0} and {\ttfamily 1} as values.

Calling {\ttfamily kdb gen} for the web page example (called {\ttfamily webpage} below) would then look like this\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{kdb gen webpage <parentKey> <outputName> domain\_name=somedomain.xyz}

\end{DoxyCode}


Since {\ttfamily function\+\_\+name} is optional in our other example (called {\ttfamily ccode} below), both of the following calls are valid\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{kdb gen ccode <parentKey> <outputName>}
\DoxyCodeLine{}
\DoxyCodeLine{kdb gen ccode <parentKey> <outputName> function\_name=foo}

\end{DoxyCode}
\hypertarget{doc_tutorials_code-generator_md_autotoc_md3527}{}\doxysubsection{Using partials}\label{doc_tutorials_code-generator_md_autotoc_md3527}
The use of partials is bit more involved than in other mustache frameworks. All the partial files for template {\ttfamily X} must be placed in the folder {\ttfamily src/tools/kdb/gen/templates/X} and must use the file extension {\ttfamily .mustache}. Apart from the the filename can be chosen arbitrarily.

To use the partial named {\ttfamily Y} (i.\+e. the file {\ttfamily src/tools/kdb/gen/templates/\+X/\+Y.\+mustache}) you must use this mustache command\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\{\{> partial.enum.c \}\}}

\end{DoxyCode}


The prefix {\ttfamily partial.} is required by the framework, if you omit it, there will be an error.\hypertarget{doc_tutorials_code-generator_md_autotoc_md3528}{}\doxysubsection{Custom escape functions}\label{doc_tutorials_code-generator_md_autotoc_md3528}
By default mustache escapes values for use in HTML (unless {\ttfamily \{\{\{ name \}\}\}} or {\ttfamily \{\{\& name \}\}} is used). Since most of our templates are not HTML, the escape function can be customised. You simply have to override {\ttfamily Gen\+Template\+::escape\+Function}. For an example see {\ttfamily Highlevel\+Gen\+Template\+::escape\+Function} in \href{/home/jenkins/workspace/libelektra-release/src/tools/kdb/gen/highlevel/highlevel.hpp}{\texttt{ {\ttfamily src/tools/kdb/gen/highlevel/highlevel.\+hpp}}}, it is designed for C code instead of HTML.\hypertarget{doc_tutorials_code-generator_md_autotoc_md3529}{}\doxysubsection{Dynamic list of parts}\label{doc_tutorials_code-generator_md_autotoc_md3529}
For some templates it might be necessary to switch which parts are produced based on the given parameters. This can be done by overriding {\ttfamily get\+Parts()} in your template class.

To achieve a dynamic parts list, simply pass {\itshape all possible} parts in the constructor invocation. Then in your override of {\ttfamily get\+Parts()} you simply inspect the given parameters and remove any parts that should not be generated.\hypertarget{doc_tutorials_code-generator_md_autotoc_md3530}{}\doxysubsection{Non-\/\+Mustache parts}\label{doc_tutorials_code-generator_md_autotoc_md3530}
It may also be useful to generate some output files without a mustache template. You could of course just write a template that renders as its string input data, but that won\textquotesingle{}t work for binary files.

The proper way to achieve non-\/mustache-\/based parts is to inspect the {\ttfamily part} value passed to {\ttfamily get\+Template\+Data()}. When you detect a non-\/mustache-\/based part you write to the file named {\ttfamily output\+Name + part} and once you are done you return {\ttfamily kainjow\+::mustache\+::data(false)}. This tells the render function to not invoke mustache for this part and instead continue with the next part. 