docs: Add comprehensive documentation for all new features
- FEATURES_OVERVIEW.md: Complete summary of all system features - ANALYTICS.md: Analytics and reporting system documentation - ODOO_INTEGRATION.md: Odoo ERP integration guide - AB_TESTING.md: A/B testing system documentation - CONTENT_RECYCLING.md: Content recycling system docs - THREAD_SERIES.md: Thread series and scheduled posts - IMAGE_TEMPLATES.md: Visual template system documentation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
350
docs/IMAGE_TEMPLATES.md
Normal file
350
docs/IMAGE_TEMPLATES.md
Normal file
@@ -0,0 +1,350 @@
|
||||
# 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": "<div class='card'>...</div>",
|
||||
"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": "<div>{{title}}</div>",
|
||||
"variables": {
|
||||
"title": "Mi título"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"rendered_html": "<div>Mi título</div>",
|
||||
"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
|
||||
<div class="card">
|
||||
<span class="emoji">{{emoji}}</span>
|
||||
<h1>{{title}}</h1>
|
||||
<p>{{content}}</p>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Ejemplo Completo
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1080px;
|
||||
height: 1080px;
|
||||
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.card {
|
||||
width: 900px;
|
||||
padding: 60px;
|
||||
background: rgba(255,255,255,0.05);
|
||||
border-radius: 24px;
|
||||
border: 1px solid rgba(212, 165, 116, 0.3);
|
||||
}
|
||||
.emoji {
|
||||
font-size: 64px;
|
||||
display: block;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
h1 {
|
||||
color: #d4a574;
|
||||
font-size: 36px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
p {
|
||||
font-size: 24px;
|
||||
line-height: 1.6;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
.footer {
|
||||
margin-top: 40px;
|
||||
color: #888;
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<span class="emoji">{{emoji}}</span>
|
||||
<h1>{{title}}</h1>
|
||||
<p>{{content}}</p>
|
||||
<div class="footer">@{{username}} • Consultoría AS</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## 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="""
|
||||
<div style="...">
|
||||
<h1>{{title}}</h1>
|
||||
<p>{{content}}</p>
|
||||
</div>
|
||||
""",
|
||||
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"
|
||||
)
|
||||
```
|
||||
Reference in New Issue
Block a user