Using model transforms

Yellicode is model driven. Ideally, the structure and names in your model match those of the source code that you want te be generated. But what if you only want your template to use a specific package from your model? Or if you want to change casing of generated class members to match current coding guidelines? This is where model transforms come in.

Model transforms let you apply one or more transformations to the template's configured model. This is a powerful way to pre-process the model before your template turns it into code.

This page discusses some of the transforms built-into the @yellicode/elements package. For a full reference, see the elements API documentation. If you are interested in creating custom transforms, see creating custom transforms.

Selecting only a specific package

The following example shows how to only apply a template to a package named API.

import { TextWriter } from '@yellicode/core';  
import { Generator } from '@yellicode/templating';
import { PackageFilterTransform, Package } from '@yellicode/elements'

const packageFilterTransform = new PackageFilterTransform('API');
const options = { modelTransform: packageFilterTransform, outputFile: 'package-filter-sample.txt' };

Generator.generateFromModel(options, (writer: TextWriter, apiPackage: Package) => {
    // template code for the API package goes here
})

Renaming model elements

Other useful transforms are transforms that rename certain elements in the model. For example, the following example makes sure that all type members start with a lowercase character.

import { TextWriter } from '@yellicode/core';  
import { Generator } from '@yellicode/templating';
import { UnCapitalizingTransform, RenameTargets, Model } from '@yellicode/elements';

const renamingTransform = new UnCapitalizingTransform(RenameTargets.allMembers);
const options = { modelTransform: renamingTransform, outputFile: 'renaming-transform-sample.txt' };

Generator.generateFromModel(options, (writer: TextWriter, model: Model) => {
    // template code goes here
})  

Chaining multiple transforms

You can also apply multiple transforms to a model. To combine the transforms of the previous examples, add them to a ModelTransformPipeline as follows:

import { TextWriter, ModelTransformPipeline } from '@yellicode/core';
import { Generator } from '@yellicode/templating';
import { UnCapitalizingTransform, PackageFilterTransform, RenameTargets, Package } from '@yellicode/elements';

const transforms = new ModelTransformPipeline();
transforms.add(new PackageFilterTransform('API'));
transforms.add(new UnCapitalizingTransform(RenameTargets.allMembers));

const options = { modelTransform: transforms, outputFile: 'model-transform-pipeline-sample.txt' };

Generator.generateFromModel(options, (writer: TextWriter, apiPackage: Package) => {
    // template code for the API package goes here
})

Note that the order of transforms matters: the output of each transform is provided to the next transform as input. So, in this example, only elements from the API package will be renamed.