External Templates
stringer.tmpl
- This template example will be written in a file named: ent/stringer.go
.
debug.tmpl
- This template example will be written in a file named: ent/debug.go
.
{{ define "debug" }}
{{/* A template that adds the functionality for running each client <T> in debug mode */}}
{{/* Add the base header for the generated file */}}
{{ $pkg := base $.Config.Package }}
{{ template "header" $ }}
{{/* Loop over all nodes and add option the "Debug" method */}}
{{ range $n := $.Nodes }}
{{ $client := print $n.Name "Client" }}
func (c *{{ $client }}) Debug() *{{ $client }} {
if c.debug {
return c
}
cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true, hooks: c.hooks}
return &{{ $client }}{config: cfg}
}
{{ end }}
{{ end }}
In order to override an existing template, use its name. For example:
{{/* A template for adding additional fields to specific types. */}}
{{ define "model/fields/additional" }}
{{- /* Add static fields to the "Card" entity. */}}
{{- if eq $.Name "Card" }}
// StaticField defined by templates.
StaticField string `json:"static_field,omitempty"`
{{- end }}
{{ end }}
As mentioned above, ent
writes each template’s execution output to a file named the same as the template. For example, the output from a template defined as {{ define "stringer" }}
will be written to a file named ent/stringer.go
.
{{ define "helper/.+" }}
for global helper templates. For example:
{{ define "helper/foo" }}
{{/* Logic goes here. */}}
{{ define "helper/bar/baz" }}
{{/* Logic goes here. */}}
{{ end }}
{{ define "<root-template>/helper/.+" }}
for local helper templates. A template is considered as “root” if its execution output is written to a file. For example:
Annotations
Schema annotations allow attaching metadata to fields and edges and inject them to external templates.
An annotation must be a Go type that is serializable to JSON raw value (e.g. struct, map or slice) and implement the interface.
Here’s an example of an annotation and its usage in schema and template:
- An annotation definition:
package entgql
// Annotation annotates fields with metadata for templates.
type Annotation struct {
// OrderField is the ordering field as defined in graphql schema.
OrderField string
}
// Name implements ent.Annotation interface.
func (Annotation) Name() string {
return "EntGQL"
}
- Annotation usage in ent/schema:
// User schema.
type User struct {
ent.Schema
}
// Fields of the user.
func (User) Fields() []ent.Field {
return []ent.Field{
field.Time("creation_date").
Annotations(entgql.Annotation{
OrderField: "CREATED_AT",
}),
}
}
- Annotation usage in external templates:
{{ range $node := $.Nodes }}
{{ range $f := $node.Fields }}
{{/* Get the annotation by its name. See: Annotation.Name */}}
{{ $orderField := $annotation.OrderField }}
{{ end }}
{{ end }}
{{ end }}
Global annotation is a type of annotation that is injected into the gen.Config
object and can be accessed globally in all templates. For example, an annotation that holds a config file information (e.g. gqlgen.yml
or swagger.yml
) add can accessed in all templates:
- An annotation definition:
- Annotation usage in
ent/entc.go
:
func main() {
cfg, err := config.LoadConfig("<path to gqlgen.yml>")
if err != nil {
log.Fatalf("loading gqlgen config: %v", err)
}
opts := []entc.Option{
entc.TemplateDir("./template"),
entc.Annotations(gqlconfig.Annotation{Config: cfg}),
}
err = entc.Generate("./schema", &gen.Config{
Templates: entgql.AllTemplates,
}, opts...)
if err != nil {
log.Fatalf("running ent codegen: %v", err)
}
}
- Annotation usage in external templates:
{{- with $.Annotations.GQL.Config.StructTag }}
{{/* Access the GQL configuration on *gen.Graph */}}
{{- end }}
{{ range $node := $.Nodes }}
{{- with $node.Config.Annotations.GQL.Config.StructTag }}
{{/* Access the GQL configuration on *gen.Type */}}
{{- end }}
{{ end }}
Examples
A custom template for implementing the
Node
API for GraphQL - .
Templates are executed on either a specific node type, or the entire schema graph. For API documentation, see the GoDoc.
AutoCompletion
JetBrains users can add the following template annotation to enable the autocompletion in their templates:
{{/* The line below tells Intellij/GoLand to enable the autocompletion based on the *gen.Graph type. */}}
{{/* gotype: entgo.io/ent/entc/gen.Graph */}}
{{ define "template" }}
{{ end }}
See it in action: