📐 Control de espacios en blanco en plantillas de Go: Bucles anidados 🔗

Al trabajar con el paquete text/template de Go, dar formato a estructuras de datos anidadas suele generar líneas en blanco no deseadas. Dado que las plantillas de Go conservan todos los espacios en blanco —incluidos los saltos de línea utilizados para dar formato al propio código de la plantilla—, los bucles estándar producen una salida llena de huecos innecesarios.

A continuación veremos cómo resolver el problema de los espacios en blanco utilizando los marcadores de recorte (trim markers) de las plantillas de Go.

📑 Tabla de Contenidos 🔗


⚠️ El problema: Saltos de línea conservados 🔗

Supongamos que queremos formatear esta estructura de datos anidada:

var data = map[string]map[string][]string{
	"1": {
		"1.1": {"1.1.1", "1.1.2", "1.1.3"},
	},
	"2": {
		"2.1": {"2.1.1", "2.1.2", "2.1.3"},
	},
}

Una forma natural de escribir la plantilla es utilizar bloques {{ range }} estándar:

{{ range $name, $map := . }}
{{ $name }}:
  {{ range $name, $values := $map }}
  {{ $name }}:
    {{ range $value := $values }}
    {{ $value }}
    {{ end }}
  {{ end }}
{{ end }}

Como cada salto de línea y espacio de sangría de la plantilla se imprime exactamente tal y como está escrito, el resultado queda plagado de líneas en blanco:

1:
  
  1.1:
    
    1.1.1
    
    1.1.2
    
    1.1.3
    
  

2:
...

✂️ La solución: El marcador de recorte (-) 🔗

Puedes indicar al motor de plantillas de Go que consuma los espacios en blanco adyacentes añadiendo un signo menos (-) dentro de las etiquetas de acción:

Para corregir nuestro bucle anidado, colocamos estratégicamente el marcador - para absorber los saltos de línea de formato de la plantilla sin eliminar la sangría que deseamos conservar:

{{- range $name, $map := . -}}
{{ $name }}:
  {{- range $name, $values := $map }}
  {{ $name }}:
    {{- range $value := $values }}
    {{ $value }}
    {{- end }}
  {{- end }}
{{ end -}}

Al eliminar los saltos de línea inmediatamente posteriores a las declaraciones range y a los bloques end, obtenemos una salida limpia y compacta:

1:
  1.1:
    1.1.1
    1.1.2
    1.1.3
2:
  2.1:
    2.1.1
    2.1.2
    2.1.3

💻 Ejemplo completo ejecutable 🔗

Puedes copiar y ejecutar este código para probar el comportamiento directamente.

package main

import (
	"fmt"
	"os"
	"text/template"
)

var data = map[string]map[string][]string{
	"1": {
		"1.1": {"1.1.1", "1.1.2", "1.1.3"},
	},
	"2": {
		"2.1": {"2.1.1", "2.1.2", "2.1.3"},
	},
}

func main() {
	const tpl = `
{{- range $name, $map := . -}}
{{ $name }}:
  {{- range $name, $values := $map }}
  {{ $name }}:
    {{- range $value := $values }}
    {{ $value }}
    {{- end }}
  {{- end }}
{{ end -}}
`
	fmt.Println("Output:")
	fmt.Println("'''")
	
	t := template.Must(template.New("nested").Parse(tpl))
	t.Execute(os.Stdout, data)
	
	fmt.Println("'''")
}

📚 Descarga Mi Ebook Gratuito 🔗

Obtén la edición sin conexión de El Estilo de Vida de Kaue—una guía práctica para optimizar 🍏 Salud, 💰 Riqueza, ❤️ Amor y 🧘 Sentido.

El Estilo de Vida de Kaue

El Estilo de Vida de Kaue

📬 Suscríbete a Mi Boletín 🔗

Recibe notificaciones cuando publique nuevos ensayos, resúmenes de libros y guías prácticas sobre cómo vivir bien. Sin spam—cancela cuando quieras.


💬 Comentarios y Debate 🔗

¿Tienes alguna pregunta, perspectiva o sugerencia? Comparte tus ideas abajo. Los comentarios funcionan con GitHub Discussions (sin anuncios y sin spam)—haz clic en Iniciar sesión con GitHub abajo para comentar o reaccionar (crear una cuenta gratuita en GitHub toma menos de un minuto).



Actualizado el 11 oct 2026.

AVISO LEGAL: El contenido de este sitio tiene fines exclusivamente informativos y educativos y no constituye asesoramiento médico, psicológico, financiero, de inversión, fiscal ni legal. Las ideas, la selección y las opiniones aquí presentadas son exclusivamente mías y no representan las de mi empleador. Los resúmenes de libros, conferencias y artículos son comentarios educativos independientes y siguen siendo propiedad intelectual de sus respectivos autores. Se pueden utilizar herramientas de IA para ayudar en la edición, el formato y la síntesis; aunque se hace todo lo posible por garantizar la precisión, pueden producirse errores. PRIVACIDAD: Este sitio utiliza servicios de terceros para la suscripción opcional al boletín (follow.it), los comentarios (giscus / GitHub Discussions) y el contenido multimedia incrustado (YouTube), que pueden procesar las direcciones IP y las cookies de los visitantes de acuerdo con sus respectivas políticas de privacidad.