Clase 05 — Strings Multilínea
¿Cómo escribir textos largos en YAML sin perder legibilidad? YAML ofrece dos operadores de bloque: Literal (|) y Folded (>).
El problema
# ❌ Poco legible
descripcion: "Este es un texto muy largo que describe la aplicación y sus funcionalidades principales incluyendo autenticación, base de datos y API REST"
Literal Block Scalar (|) — Preserva saltos de línea
descripcion: |
Esta es la primera línea.
Esta es la segunda línea.
Esta es la tercera línea.
Resultado: "Esta es la primera línea.\nEsta es la segunda línea.\nEsta es la tercera línea.\n"
Folded Block Scalar (>) — Une líneas en una sola
descripcion: >
Esta es una frase larga
que se escribió en múltiples
líneas pero se unirá
en una sola.
Resultado: "Esta es una frase larga que se escribió en múltiples líneas pero se unirá en una sola.\n"
Folded con párrafos
# Las líneas vacías crean párrafos (saltos de línea reales)
texto: >
Primer párrafo que se une
en una sola línea.
Segundo párrafo que también
se une en una línea.
Tercer párrafo.
Resultado: "Primer párrafo que se une en una sola línea.\nSegundo párrafo que también se une en una línea.\nTercer párrafo.\n"
Chomping — Controlar el salto de línea final
| Indicador | Nombre | Comportamiento |
|---|---|---|
| o > | Clip (default) | Un salto de línea al final |
|- o >- | Strip | Sin salto de línea al final |
|+ o >+ | Keep | Mantiene TODOS los saltos finales |
# Clip (default) - Un \n al final
clip: |
Hola
Mundo
# Strip - Sin \n al final
strip: |-
Hola
Mundo
# Keep - Mantiene todos los \n finales
keep: |+
Hola
Mundo
Resultados:
clip: "Hola\nMundo\n"
strip: "Hola\nMundo"
keep: "Hola\nMundo\n\n\n"
Ejemplo: Scripts en GitHub Actions
# .github/workflows/ci.yml
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup y Build
run: |
echo "Instalando dependencias..."
npm install
echo "Ejecutando tests..."
npm test
echo "Construyendo aplicación..."
npm run build
echo "Build completado!"
- name: Deploy con script complejo
run: |
if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
echo "Deploying a producción..."
aws s3 sync ./build s3://mi-bucket-prod/
else
echo "Deploying a staging..."
aws s3 sync ./build s3://mi-bucket-staging/
fi
Ejemplo: Kubernetes ConfigMap con archivos
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
nginx.conf: |
server {
listen 80;
server_name ejemplo.com;
location / {
proxy_pass http://backend:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static {
alias /var/www/static;
expires 30d;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
default.conf: |
upstream backend {
server api-1:8080;
server api-2:8080;
server api-3:8080;
}
Ejemplo: Docker Compose con scripts de inicialización
version: "3.8"
services:
app:
build: .
depends_on:
- postgres
labels:
com.example.description: >-
Esta aplicación gestiona la API principal
del sistema de Pokémon, incluyendo endpoints
de búsqueda, creación y actualización.
init-db:
image: postgres:16-alpine
depends_on:
- postgres
command: >
bash -c "
echo 'Esperando a PostgreSQL...'
until pg_isready -h postgres -U postgres; do
sleep 2
done
echo 'PostgreSQL listo!'
psql -h postgres -U postgres -c 'CREATE DATABASE IF NOT EXISTS app_db;'
echo 'Base de datos creada!'
"
Ejemplo: Helm values con templates
app:
name: mi-api
config: |
[database]
host = {{ .Values.db.host }}
port = {{ .Values.db.port }}
name = {{ .Values.db.name }}
[server]
port = {{ .Values.app.port }}
workers = {{ .Values.app.workers }}
debug = false
changelog: |-
## v2.0.0
- Migración a FastAPI
- Nuevo endpoint de búsqueda
- Soporte para paginación
## v1.0.0
- Release inicial
- CRUD básico de Pokémon
Indentación en bloques multilínea
# Indicador de indentación explícito
datos:
script: |2
Esta línea tiene 6 espacios
Y esta también
El "2" indica 2 espacios de indentación del bloque
# Sin indicador (se detecta automáticamente)
otro_script: |
Esta línea tiene 4 espacios
Se detecta automáticamente
Resumen visual
| → Literal (mantiene \n) "línea1\nlínea2\n"
|- → Literal Strip (sin \n final) "línea1\nlínea2"
|+ → Literal Keep (todos los \n) "línea1\nlínea2\n\n"
> → Folded (una línea) "línea1 línea2\n"
>- → Folded Strip "línea1 línea2"
>+ → Folded Keep "línea1 línea2\n\n"
Ejercicios
- Escribí un GitHub Actions workflow donde un step ejecute un script de 10+ líneas con
| - Creá un Kubernetes ConfigMap que contenga un archivo
.envy unnginx.confcompletos - Experimentá con
|,|-,>,>-y verificá las diferencias con Python:import yaml
data = yaml.safe_load(open("test.yaml"))
for k, v in data.items():
print(f"{k}: {repr(v)}")