templates go go-templates

templates - ¿Cómo usar un campo de estructura o valor variable como nombre de plantilla?



go go-templates (1)

Podemos definir el nombre de la plantilla a través de {{define "home"}} , y luego cargarlo en otra plantilla (padre) a través de {{template "home"}} .

Cómo puedo cargar la plantilla a través del valor variable {{template .TemplateName}} . O es imposible?


Lamentablemente no puedes.

La sintaxis de la acción {{template}} :

{{template "name"}} The template with the specified name is executed with nil data. {{template "name" pipeline}} The template with the specified name is executed with dot set to the value of the pipeline.

El nombre de la plantilla que se incluirá es una cadena constante , no es una tubería que podría variar durante la ejecución en función de los parámetros.

Si la sintaxis permitida sería:

{{template pipeline}}

entonces podría usar algo como {{template .TemplName}} pero como la sintaxis solo permite una cadena constante, no puede.

Razonamiento de Rob por qué la invocación de plantillas dinámicas no está permitida ( source ):

Queremos que el lenguaje de la plantilla sea analizable estáticamente para que el contexto de la invocación de una plantilla sea claro, comprobable y bloqueable. Si un punto de invocación es totalmente dinámico, esto no se puede hacer. Del mismo modo, si una plantilla puede pertenecer a múltiples conjuntos, su contexto puede diferir entre conjuntos de una manera que requeriría que todos los conjuntos se analicen simultáneamente. Dado que ambas restricciones son fáciles de solucionar si lo desea, a costa de perder esas comprobaciones estáticas en un paquete de nivel superior, parecía prudente controlar la situación en la implementación de la plantilla base. Un paquete de nivel superior, como un envoltorio hipotético de solo HTML, puede garantizar que no haya soluciones alternativas más fácilmente si las restricciones son claras.

Alternativa n. ° 1: Ejecutar plantilla incluida primero

Lo que puede hacer es ejecutar primero la plantilla que desea incluir e insertar el resultado donde desea incluirla. Puede usar tipos especiales para no escapar del resultado de la plantilla interna al insertar, por ejemplo html.HTML en el caso de plantillas HTML.

Ver este ejemplo:

func main() { t := template.Must(template.New("t").Parse(t)) template.Must(t.New("t1").Parse(t1)) params := struct { Name string Value interface{} }{"t1", nil} b := bytes.Buffer{} t.ExecuteTemplate(&b, params.Name, nil) params.Value = template.HTML(b.String()) t.Execute(os.Stdout, params) } const t = `<html><body> Now I will include template with name: {{.Name}} {{.Value}} </body>/html>` const t1 = `I''m template <b>t1</b>.`

Salida:

<html><body> Now I will include template with name: t1 I''m template <b>t1</b>. </body>/html>

Pruébalo en Go Playground .

El resultado de la plantilla t1 se insertó sin escape. Si omite la template.HTML . template.HTML :

params.Value = b.String()

t1 se insertaría escapado, así:

<html><body> Now I will include template with name: t1 I&#39;m template &lt;b&gt;t1&lt;/b&gt;. </body>/html>

Alternativa # 2: reestructurar plantillas

Puede reestructurar sus plantillas para que no se encuentren en situaciones en las que desee incluir una plantilla con diferentes nombres.

Ejemplo: es posible que desee crear páginas donde tenga una plantilla de page similar a esta:

<html><body> Title, headers etc. {{template .Page}} Footers </body></html>

Puedes reestructurarlo para que sea algo como esto:

plantilla de header :

<html><body> Title, headers, etc.

plantilla de footer :

Footers </body></html

Y sus plantillas de página incluirían header y footer como este:

{{template "header" .}} Page content comes here. {{template "footer" .}}

Alternativa n. ° 3: utilice la acción {{if}} y nombres predefinidos

Si conoce los nombres de las plantillas anteriormente y no es una lista exhaustiva, puede usar la acción de plantilla {{if}} para incluir la plantilla deseada. Ejemplo:

{{if eq .Name "page1"}} {{template "page1" .}} {{else if eq .Name "page2"}} {{template "page2" .}} ... {{end}}

Alternativa # 4: Modificar el texto de la plantilla estática

La idea aquí es que puede modificar el texto estático de la plantilla externa manualmente e insertar el nombre de la plantilla interna que desea incluir.

La desventaja de este método es que después de insertar el nombre de la plantilla interna, debe volver a analizar la plantilla, por lo que no lo recomiendo.