Saltar al contenido principal

Plantillas externas

[Traducción Beta No Oficial]

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

ent acepta plantillas Go externas para ejecutar usando la bandera --template. Si el nombre de la plantilla ya está definido por ent, sobrescribirá la existente. De lo contrario, escribirá la salida de ejecución en un archivo con el mismo nombre que la plantilla. Por ejemplo:

stringer.tmpl - Este ejemplo de plantilla se escribirá en un archivo llamado: ent/stringer.go.

{{/* The line below tells Intellij/GoLand to enable the autocompletion based on the *gen.Graph type. */}}
{{/* gotype: entgo.io/ent/entc/gen.Graph */}}

{{ define "stringer" }}

{{/* Add the base header for the generated file */}}
{{ $pkg := base $.Config.Package }}
{{ template "header" $ }}

{{/* Loop over all nodes and implement the "GoStringer" interface */}}
{{ range $n := $.Nodes }}
{{ $receiver := $n.Receiver }}
func ({{ $receiver }} *{{ $n.Name }}) GoString() string {
if {{ $receiver }} == nil {
return fmt.Sprintf("{{ $n.Name }}(nil)")
}
return {{ $receiver }}.String()
}
{{ end }}

{{ end }}

debug.tmpl - Este ejemplo de plantilla se escribirá en un archivo llamado: 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 }}

Para sobrescribir una plantilla existente, usa su nombre. Por ejemplo:

{{/* 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 }}

Plantillas auxiliares

Como se mencionó, ent escribe la salida de ejecución de cada plantilla en un archivo con el mismo nombre que la plantilla. Por ejemplo, la salida de una plantilla definida como {{ define "stringer" }} se escribirá en un archivo llamado ent/stringer.go.

Por defecto, ent escribe cada plantilla declarada con {{ define "<name>" }} en un archivo. Sin embargo, a veces se desea definir plantillas auxiliares - plantillas que no se invocarán directamente sino que serán ejecutadas por otras plantillas. Para facilitar este caso de uso, ent soporta dos formatos de nombres que designan una plantilla como auxiliar. Los formatos son:

1. {{ define "helper/.+" }} para plantillas auxiliares globales. Por ejemplo:

{{ define "helper/foo" }}
{{/* Logic goes here. */}}
{{ end }}

{{ define "helper/bar/baz" }}
{{/* Logic goes here. */}}
{{ end }}

2. {{ define "<root-template>/helper/.+" }} para plantillas auxiliares locales. Una plantilla se considera "raíz" si su salida de ejecución se escribe en un archivo. Por ejemplo:

{{/* A root template that is executed on the `gen.Graph` and will be written to a file named: `ent/http.go`.*/}}
{{ define "http" }}
{{ range $n := $.Nodes }}
{{ template "http/helper/get" $n }}
{{ template "http/helper/post" $n }}
{{ end }}
{{ end }}

{{/* A helper template that is executed on `gen.Type` */}}
{{ define "http/helper/get" }}
{{/* Logic goes here. */}}
{{ end }}

{{/* A helper template that is executed on `gen.Type` */}}
{{ define "http/helper/post" }}
{{/* Logic goes here. */}}
{{ end }}

Anotaciones

Las anotaciones de esquema permiten adjuntar metadatos a campos y bordes e inyectarlos en plantillas externas.
Una anotación debe ser un tipo Go serializable a valor JSON en crudo (ej. struct, map o slice) e implementar la interfaz Annotation.

Aquí un ejemplo de anotación y su uso en esquema y plantilla:

1. Definición de anotación:

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"
}

2. Uso de anotación en 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",
}),
}
}

3. Uso de anotación en plantillas externas:

{{ range $node := $.Nodes }}
{{ range $f := $node.Fields }}
{{/* Get the annotation by its name. See: Annotation.Name */}}
{{ if $annotation := $f.Annotations.EntGQL }}
{{/* Get the field from the annotation. */}}
{{ $orderField := $annotation.OrderField }}
{{ end }}
{{ end }}
{{ end }}

Anotaciones globales

La anotación global es un tipo de anotación que se inyecta en el objeto gen.Config y puede accederse globalmente en todas las plantillas. Por ejemplo, una anotación que contiene información de archivo de configuración (ej. gqlgen.yml o swagger.yml) puede accederse en todas las plantillas:

1. Definición de anotación:

package gqlconfig

import (
"entgo.io/ent/schema"
"github.com/99designs/gqlgen/codegen/config"
)

// Annotation defines a custom annotation
// to be inject globally to all templates.
type Annotation struct {
Config *config.Config
}

func (Annotation) Name() string {
return "GQL"
}

var _ schema.Annotation = (*Annotation)(nil)

2. Uso de anotación en 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)
}
}

3. Uso de anotación en plantillas externas:

{{- 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 }}

Ejemplos

  • Plantilla personalizada para implementar la API Node de GraphQL - Github.

  • Ejemplo de ejecución de plantillas externas con funciones personalizadas. Ver configuración y su archivo README.

Documentación

Templates are executed on either a specific node type, or the entire schema graph. For API documentation, see the GoDoc.

Autocompletado

Usuarios de JetBrains pueden añadir la siguiente anotación de plantilla para habilitar el autocompletado:

{{/* 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 }}

Ver en acción:

template-autocomplete