Skip to main content

Context

Context related methods and properties are used to retrieve information, perform operations, and generate code within the current code generator's context. These methods or properties are called directly by name, for example:

{{head}}
{{next this}}
{{lang}}
{{exist meta.path}}

align

align aligns the given text with the same indent as the first line.

Example (without align):

	{{print "hello\nworld"}}

Output:

	hello
world

To align it, you can use align:

	{{align "hello\nworld"}}

Output:

	hello
world

It's useful when you want to align the generated content, especially for multi-line strings (e.g., comments).

debug

debug outputs a debug message in the console.

Example:

{{debug "Hello, world"}}
{{debug "Hello, %s" "world"}}
tip

It's useful when you want to print debug information in the console during code generation.

env

env represents the environment variables defined in the command line with the flag -D.

Example:

$ next -D PROJECT_NAME=demo
{{env.PROJECT_NAME}}

error

error used to return an error message in the template.

Example:

{{error "Something went wrong"}}
{{error "%s went wrong" "Something"}}
tip

Using .Pos to get the current object's position in source file is a good practice.

{{- define "next/protobuf/enum" -}}
{{- if not .MemberType.Kind.IsInteger -}}
{{error "%s: enum type must be an integer" .Pos}}
{{- end}}
{{- end}}

exist

exist checks whether the given path exists. If the path is not absolute, it will be resolved relative to the current output directory for the current language by command line flag -O.

Example:

{{exist "path/to/file"}}
{{exist "/absolute/path/to/file"}}
{{exist meta.path}}

head

head outputs the header of the generated file.

Example:

{{head}}

Output (for c++):

// Code generated by "next v0.0.1"; DO NOT EDIT.

Output (for c):

/* Code generated by "next v0.0.1"; DO NOT EDIT. */

lang

lang represents the current language to be generated.

Example:

{{lang}}
{{printf "%s_alias" lang}}

load

load loads a template file. It will execute the template immediately but ignore the output. It's useful when you want to load a template file and import the templates it needs.

Example:

{{load "path/to/template.npl"}}

meta

meta represents the metadata of entrypoint template file by flag -T. To define a meta, you should define a template with the name meta/<key>. Currently, the following meta keys are used by the code generator:

  • meta/this: the current object to be rendered. See this for details.
  • meta/path: the output path for the current object. If the path is not absolute, it will be resolved relative to the current output directory for the current language by command line flag -O.
  • meta/skip: whether to skip the current object.

You can use them in the templates like {{meta.<key>}}.

tip

User-defined meta key MUST be prefixed with _, e.g., _custom_key.

Example:

{{- define "meta/this" -}}file{{- end -}}
{{- define "meta/path" -}}path/to/file{{- end -}}
{{- define "meta/skip" -}}{{exist meta.path}}{{- end -}}
{{- define "meta/_custom_key" -}}custom value{{- end -}}

{{meta._custom_key}}
note

The metadata will be resolved in the order of the template definition before rendering the entrypoint template.

next

next executes the next template with the given Object. {{next object}} is equivalent to {{render (object.Typeof) object}}.

Example:

{{- /* Overrides "next/go/struct": add method 'MessageType' for each message after struct */ -}}
{{- define "go/struct"}}
{{- super .}}
{{- with .Annotations.message.type}}

func ({{next $.Type}}) MessageType() int { return {{.}} }
{{- end}}
{{- end -}}

{{next this}}

pwd

pwd returns the current template file's directory.

Example:

{{pwd}}

render

render executes the template with the given name and data.

  • Parameters: (name: string, data: any[, lang: string])

name is the template name to be executed. lang is the current language by default if not specified.

name has a specific format. When the corresponding template is not found, it will look up the parent template according to the rules of super.

Example:

{{render "struct" this}}
{{render "struct" this "go"}}

super

super executes the super template with the given Object. super is used to call the parent template in the current template. It's useful when you want to extend the parent template. The super template looks up the template with the following priority:

e.g.,

  • struct -> go/struct -> next/go/struct -> next/struct
  • struct:foo -> go/struct:foo -> next/go/struct:foo -> next/struct:foo

Example:

{{- /* Overrides "next/go/struct": add method 'MessageType' for each message after struct */ -}}
{{- define "go/struct"}}
{{- super .}}
{{- with .Annotations.message.type}}

func ({{next $.Type}}) MessageType() int { return {{.}} }
{{- end}}
{{- end -}}

this

this represents the current Decl object to be rendered. this defined in the template meta meta/this. Supported types are:

It's "file" by default.

type

type outputs the string representation of the given Type for the current language. The type function will lookup the type mapping in the command line flag -M and return the corresponding type. If the type is not found, it will lookup LANG.map file (e.g., cpp.map) for the type mapping. If the type is still not found, it will return an error.