248 lines
6.0 KiB
Markdown
248 lines
6.0 KiB
Markdown
# 🧩 Sistema de Bloques Editables - GKACHELE™
|
||
|
||
**© 2025 GKACHELE™. Todos los derechos reservados.**
|
||
|
||
**Hash:** `gkachele-bloques-editables-20250115-001`
|
||
|
||
---
|
||
|
||
## 📋 OBJETIVO
|
||
|
||
Implementar sistema completo de bloques editables similar a WordPress Gutenberg:
|
||
- ✅ Añadir/eliminar bloques (videos, imágenes, texto, redes sociales)
|
||
- ✅ Mover bloques (drag & drop)
|
||
- ✅ Edición inline (click con lápiz) + sidebar
|
||
- ✅ Iconos de redes sociales automáticos
|
||
- ✅ Mapa embed sin API key
|
||
- ✅ Todo sincronizado en tiempo real
|
||
|
||
---
|
||
|
||
## 🎯 FUNCIONALIDADES REQUERIDAS
|
||
|
||
### 1. Añadir Bloques
|
||
- Botón "➕ Añadir Bloque" en sidebar
|
||
- Tipos: Video (YouTube/Vimeo), Imagen, Texto, Redes Sociales, Mapa
|
||
- Cada bloque se añade al preview y al sidebar
|
||
|
||
### 2. Eliminar Bloques
|
||
- Botón "🗑️" en cada bloque del preview
|
||
- Confirmación antes de eliminar
|
||
- Sincronización automática
|
||
|
||
### 3. Mover Bloques
|
||
- Drag & drop usando HTML5 Drag API
|
||
- Indicadores visuales al arrastrar
|
||
- Guardado automático del orden
|
||
|
||
### 4. Redes Sociales con Iconos
|
||
- Al añadir URL de red social, mostrar icono automático
|
||
- Iconos: Facebook, Instagram, Twitter/X, WhatsApp, YouTube
|
||
- Usar Font Awesome o SVG inline
|
||
|
||
### 5. Mapa Embed
|
||
- Campo para URL de Google Maps (compartir → insertar mapa)
|
||
- Renderizar iframe sin necesidad de API key
|
||
- Validación de URL
|
||
|
||
### 6. Edición Híbrida
|
||
- Click en elemento → editar inline (modal)
|
||
- Cambios en sidebar → actualizar preview
|
||
- Bidireccional siempre
|
||
|
||
---
|
||
|
||
## 🔧 IMPLEMENTACIÓN
|
||
|
||
### Estructura de Datos
|
||
|
||
```json
|
||
{
|
||
"blocks": [
|
||
{
|
||
"id": "block_1234567890",
|
||
"type": "video",
|
||
"content": {
|
||
"url": "https://www.youtube.com/embed/...",
|
||
"title": "Video Tutorial"
|
||
},
|
||
"order": 0
|
||
},
|
||
{
|
||
"id": "block_1234567891",
|
||
"type": "redes_sociales",
|
||
"content": {
|
||
"facebook": "https://facebook.com/...",
|
||
"instagram": "https://instagram.com/..."
|
||
},
|
||
"order": 1
|
||
},
|
||
{
|
||
"id": "block_1234567892",
|
||
"type": "mapa",
|
||
"content": {
|
||
"url": "https://www.google.com/maps/embed?pb=..."
|
||
},
|
||
"order": 2
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### Backend (app.py)
|
||
|
||
```python
|
||
# Endpoint para añadir bloque
|
||
@app.route('/api/customizer/add-block', methods=['POST'])
|
||
def add_block():
|
||
# Añadir nuevo bloque a content_json['blocks']
|
||
pass
|
||
|
||
# Endpoint para eliminar bloque
|
||
@app.route('/api/customizer/remove-block', methods=['POST'])
|
||
def remove_block():
|
||
# Eliminar bloque por ID
|
||
pass
|
||
|
||
# Endpoint para reordenar bloques
|
||
@app.route('/api/customizer/reorder-blocks', methods=['POST'])
|
||
def reorder_blocks():
|
||
# Actualizar orden de bloques
|
||
pass
|
||
```
|
||
|
||
### Frontend (customizer.html)
|
||
|
||
```javascript
|
||
// Añadir bloque
|
||
function addBlock(type) {
|
||
const blockId = 'block_' + Date.now();
|
||
const newBlock = {
|
||
id: blockId,
|
||
type: type,
|
||
content: getDefaultContentForType(type),
|
||
order: blocks.length
|
||
};
|
||
// Añadir a preview y sidebar
|
||
renderBlock(newBlock);
|
||
saveBlocks();
|
||
}
|
||
|
||
// Eliminar bloque
|
||
function removeBlock(blockId) {
|
||
if (confirm('¿Eliminar este bloque?')) {
|
||
// Remover del DOM y del array
|
||
saveBlocks();
|
||
}
|
||
}
|
||
|
||
// Drag & Drop
|
||
function initDragDrop() {
|
||
document.querySelectorAll('.gk-block').forEach(block => {
|
||
block.draggable = true;
|
||
block.addEventListener('dragstart', handleDragStart);
|
||
block.addEventListener('dragover', handleDragOver);
|
||
block.addEventListener('drop', handleDrop);
|
||
});
|
||
}
|
||
```
|
||
|
||
### Template (template.html)
|
||
|
||
```html
|
||
<!-- Renderizar bloques dinámicamente -->
|
||
{% if blocks %}
|
||
{% for block in blocks|sort(attribute='order') %}
|
||
{% if block.type == 'video' %}
|
||
<div class="gk-block" data-block-id="{{ block.id }}" draggable="true">
|
||
<button class="gk-block-delete" onclick="removeBlock('{{ block.id }}')">🗑️</button>
|
||
<iframe src="{{ block.content.url }}" frameborder="0"></iframe>
|
||
</div>
|
||
{% elif block.type == 'redes_sociales' %}
|
||
<div class="gk-block" data-block-id="{{ block.id }}" draggable="true">
|
||
<button class="gk-block-delete" onclick="removeBlock('{{ block.id }}')">🗑️</button>
|
||
<div class="social-icons">
|
||
{% if block.content.facebook %}
|
||
<a href="{{ block.content.facebook }}"><i class="fab fa-facebook"></i></a>
|
||
{% endif %}
|
||
<!-- Más redes... -->
|
||
</div>
|
||
</div>
|
||
{% elif block.type == 'mapa' %}
|
||
<div class="gk-block" data-block-id="{{ block.id }}" draggable="true">
|
||
<button class="gk-block-delete" onclick="removeBlock('{{ block.id }}')">🗑️</button>
|
||
<iframe src="{{ block.content.url }}" width="100%" height="450" frameborder="0"></iframe>
|
||
</div>
|
||
{% endif %}
|
||
{% endfor %}
|
||
{% endif %}
|
||
```
|
||
|
||
---
|
||
|
||
## 📝 CHECKLIST
|
||
|
||
- [ ] Sistema de bloques en backend (añadir/eliminar/reordenar)
|
||
- [ ] UI para añadir bloques en sidebar
|
||
- [ ] Renderizado de bloques en template
|
||
- [ ] Drag & drop funcional
|
||
- [ ] Iconos de redes sociales (Font Awesome o SVG)
|
||
- [ ] Mapa embed sin API
|
||
- [ ] Edición inline de bloques
|
||
- [ ] Sincronización bidireccional
|
||
- [ ] Guardado automático
|
||
- [ ] Indicadores visuales (hover, drag)
|
||
|
||
---
|
||
|
||
## 🎨 ESTILOS
|
||
|
||
```css
|
||
.gk-block {
|
||
position: relative;
|
||
margin: 20px 0;
|
||
padding: 15px;
|
||
border: 2px dashed transparent;
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.gk-block:hover {
|
||
border-color: var(--primary);
|
||
}
|
||
|
||
.gk-block.dragging {
|
||
opacity: 0.5;
|
||
}
|
||
|
||
.gk-block-delete {
|
||
position: absolute;
|
||
top: 10px;
|
||
right: 10px;
|
||
background: #d63638;
|
||
color: white;
|
||
border: none;
|
||
padding: 5px 10px;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
opacity: 0;
|
||
transition: opacity 0.2s;
|
||
}
|
||
|
||
.gk-block:hover .gk-block-delete {
|
||
opacity: 1;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🔗 REFERENCIAS
|
||
|
||
- WordPress Gutenberg: Sistema de bloques
|
||
- Elementor: Drag & drop visual
|
||
- Google Maps Embed: Sin API key necesario
|
||
|
||
---
|
||
|
||
**Última actualización:** 2025-01-15
|
||
**Estado:** En desarrollo
|