# Image Templates
Sistema de plantillas para generar imágenes dinámicas.
## Descripción
Las plantillas de imagen permiten:
- Definir diseños reutilizables en HTML/CSS
- Insertar variables dinámicas
- Generar imágenes para diferentes plataformas
- Mantener consistencia visual
## Modelo de Datos
### ImageTemplate
```python
ImageTemplate:
id: int
name: str
description: str
category: str # tip, producto, servicio, promocion, etc.
template_type: str # tip_card, product_card, quote, promo, announcement
# Plantilla
template_file: str # Ruta a archivo (opcional)
html_template: str # HTML inline
preview_url: str # URL de imagen preview
# Variables
variables: [str] # ["title", "content", "accent_color"]
# Configuración de diseño
design_config: JSON
# {
# "width": 1080,
# "height": 1080,
# "background_color": "#1a1a2e",
# "accent_color": "#d4a574",
# "font_family": "Inter"
# }
# Tamaños de salida
output_sizes: JSON
# {
# "instagram": {"width": 1080, "height": 1080},
# "x": {"width": 1200, "height": 675},
# "facebook": {"width": 1200, "height": 630}
# }
is_active: bool
```
## API Endpoints
### GET /api/templates/
Lista todas las plantillas.
**Parámetros:**
- `category`: tip, producto, servicio, etc.
- `template_type`: tip_card, product_card, etc.
- `active_only` (bool, default=true)
- `limit` (int, default=50)
**Respuesta:**
```json
{
"templates": [
{
"id": 1,
"name": "Tip Card Oscuro",
"description": "Tarjeta para tips con fondo oscuro",
"category": "tip",
"template_type": "tip_card",
"variables": ["title", "content", "emoji"],
"preview_url": "/uploads/previews/tip_card_dark.png"
}
],
"count": 10
}
```
### GET /api/templates/{template_id}
Obtiene una plantilla con detalles completos.
Incluye `full_html_template` con el HTML completo.
### POST /api/templates/
Crea una nueva plantilla.
**Body:**
```json
{
"name": "Quote Card",
"description": "Tarjeta para frases motivacionales",
"category": "frase",
"template_type": "quote",
"html_template": "
...
",
"variables": ["quote", "author", "background_image"],
"design_config": {
"width": 1080,
"height": 1080,
"background_color": "#1a1a2e"
},
"output_sizes": {
"instagram": {"width": 1080, "height": 1080},
"x": {"width": 1200, "height": 675}
}
}
```
**Validación:**
- Requiere `html_template` o `template_file`
### PUT /api/templates/{template_id}
Actualiza una plantilla.
### DELETE /api/templates/{template_id}
Elimina una plantilla.
### POST /api/templates/preview
Genera preview de una plantilla con variables.
**Body:**
```json
{
"template_id": 1,
"variables": {
"title": "Tip del día",
"content": "Automatiza tus procesos con IA",
"emoji": "💡"
},
"output_size": {"width": 1080, "height": 1080}
}
```
O con HTML directo:
```json
{
"html_template": "{{title}}
",
"variables": {
"title": "Mi título"
}
}
```
**Respuesta:**
```json
{
"rendered_html": "Mi título
",
"output_size": {"width": 1080, "height": 1080},
"variables_used": ["title"]
}
```
### GET /api/templates/categories/list
Lista categorías disponibles.
### GET /api/templates/types/list
Lista tipos de plantilla disponibles.
## Estructura HTML
### Variables
Las variables se definen con doble llave: `{{variable}}`
```html
{{emoji}}
{{title}}
{{content}}
```
### Ejemplo Completo
```html
{{emoji}}
{{title}}
{{content}}
```
## Categorías
| Categoría | Uso |
|-----------|-----|
| `tip` | Tips tecnológicos |
| `producto` | Fichas de producto |
| `servicio` | Promoción de servicios |
| `promocion` | Ofertas y descuentos |
| `frase` | Frases motivacionales |
| `dato` | Datos curiosos |
| `anuncio` | Anuncios generales |
## Tipos de Plantilla
| Tipo | Descripción |
|------|-------------|
| `tip_card` | Tarjeta de tip con emoji |
| `product_card` | Ficha de producto con imagen |
| `quote` | Frase con autor |
| `promo` | Promoción con precio |
| `announcement` | Anuncio destacado |
| `stats` | Estadísticas/números |
| `comparison` | Antes/después o A vs B |
## Tamaños por Plataforma
| Plataforma | Ancho | Alto | Ratio |
|------------|-------|------|-------|
| Instagram Post | 1080 | 1080 | 1:1 |
| Instagram Story | 1080 | 1920 | 9:16 |
| X (Twitter) | 1200 | 675 | 16:9 |
| Facebook | 1200 | 630 | 1.91:1 |
| LinkedIn | 1200 | 627 | 1.91:1 |
| Threads | 1080 | 1080 | 1:1 |
## Ejemplo de Uso
```python
from app.models.image_template import ImageTemplate
from app.core.database import SessionLocal
db = SessionLocal()
# Crear plantilla
template = ImageTemplate(
name="Tip Card Dark",
category="tip",
template_type="tip_card",
html_template="""
""",
variables=["title", "content"],
design_config={
"width": 1080,
"height": 1080,
"background_color": "#1a1a2e"
}
)
db.add(template)
db.commit()
# Renderizar
html = template.html_template
html = html.replace("{{title}}", "Mi Título")
html = html.replace("{{content}}", "Mi contenido")
```
## Generación de Imágenes
Para convertir HTML a imagen se recomienda:
### Playwright (recomendado)
```python
from playwright.async_api import async_playwright
async def html_to_image(html: str, width: int, height: int) -> bytes:
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page(viewport={"width": width, "height": height})
await page.set_content(html)
screenshot = await page.screenshot(type="png")
await browser.close()
return screenshot
```
### WeasyPrint (alternativa)
```python
from weasyprint import HTML
def html_to_pdf(html: str) -> bytes:
return HTML(string=html).write_pdf()
```
## Mejores Prácticas
1. **Fuentes web:** Usa Google Fonts o incluye fuentes inline
2. **Colores consistentes:** Define palette en design_config
3. **Responsive:** Usa unidades relativas cuando sea posible
4. **Contraste:** Asegura legibilidad texto/fondo
5. **Logo:** Incluye branding en todas las plantillas
6. **Variables descriptivas:** `{{product_name}}` mejor que `{{name}}`
7. **Fallbacks:** Define valores por defecto para variables opcionales
## Integración con Posts
```python
# Al crear un post con imagen generada
post = Post(
content="Tip del día...",
image_template_id=template.id, # Referencia a la plantilla usada
image_url="/uploads/generated/tip_123.png"
)
```