import os import json import sqlite3 from flask import current_app from config import THEMES_DIR, MAIN_DB def scan_available_themes(): """Escanear todos los templates disponibles y cargar sus configuraciones""" themes = {} if not os.path.exists(THEMES_DIR): return themes for theme_dir in os.listdir(THEMES_DIR): theme_path = os.path.join(THEMES_DIR, theme_dir) if not os.path.isdir(theme_path) or theme_dir.startswith('_'): continue config_path = os.path.join(theme_path, 'config.json') template_path = os.path.join(theme_path, 'template.html') if not os.path.exists(config_path) or not os.path.exists(template_path): continue try: with open(config_path, 'r', encoding='utf-8') as f: config = json.load(f) themes[theme_dir] = { 'id': theme_dir, 'name': config.get('name', theme_dir), 'description': config.get('description', ''), 'rubro': config.get('rubro', 'general'), 'plan': config.get('plan', 'base'), 'sections': config.get('sections', []), 'colors': config.get('colors', {}), 'typography': config.get('typography', {}), 'features': config.get('features', {}), 'preview': f'/themes/{theme_dir}/preview.jpg' if os.path.exists(os.path.join(theme_path, 'preview.jpg')) else None } except Exception as e: print(f"⚠️ Error cargando template {theme_dir}: {e}") continue return themes def get_theme_config(theme_id): """Obtener configuración de un template específico""" config_path = os.path.join(THEMES_DIR, theme_id, 'config.json') if not os.path.exists(config_path): return None try: with open(config_path, 'r', encoding='utf-8') as f: return json.load(f) except Exception as e: print(f"⚠️ Error cargando config de {theme_id}: {e}") return None def get_themes_by_rubro(rubro, user_plan='base'): """Obtener templates filtrados por rubro y plan del usuario""" all_themes = scan_available_themes() plan_priority = {'base': 1, 'pro': 2, 'premium': 3} user_level = plan_priority.get(user_plan, 1) filtered_themes = {} for k, v in all_themes.items(): theme_level = plan_priority.get(v.get('plan', 'base'), 1) # Solo mostrar temas del rubro (o general) que estén dentro del plan del usuario if (v.get('rubro') == rubro or v.get('rubro') == 'general') and theme_level <= user_level: filtered_themes[k] = v return filtered_themes def get_site_menus(site_id, user_id): """Obtener menús del sitio organizados por ubicación""" conn = sqlite3.connect(MAIN_DB) c = conn.cursor() c.execute('''SELECT location, title, url, order_index, parent_id FROM menus WHERE site_id = ? AND user_id = ? ORDER BY location, order_index''', (site_id, user_id)) rows = c.fetchall() conn.close() menus = {'header': [], 'footer': [], 'sidebar': []} for row in rows: location, title, url, order_index, parent_id = row menu_item = { 'title': title, 'url': url, 'order': order_index, 'parent_id': parent_id } if location in menus: menus[location].append(menu_item) return menus def get_site_widgets(site_id, user_id, area='sidebar'): """Obtener widgets del sitio por área""" conn = sqlite3.connect(MAIN_DB) c = conn.cursor() c.execute('''SELECT type, title, content, order_index FROM widgets WHERE site_id = ? AND user_id = ? AND area = ? ORDER BY order_index''', (site_id, user_id, area)) rows = c.fetchall() conn.close() widgets = [] for row in rows: widget_type, title, content, order_index = row widgets.append({ 'type': widget_type, 'title': title, 'content': content, 'order': order_index }) return widgets def render_gkachele_template(theme, content, site_id=None, user_id=None): """Renderizar template usando estructura GKACHELE (header.php, footer.php, sidebar.php)""" menus = {'header': [], 'footer': [], 'sidebar': []} widgets = [] if site_id and user_id: try: menus = get_site_menus(site_id, user_id) widgets = get_site_widgets(site_id, user_id) except Exception as e: print(f"⚠️ Error obteniendo menús/widgets: {e}") theme_template = '' theme_path = os.path.join(THEMES_DIR, theme, 'template.html') if os.path.exists(theme_path): with open(theme_path, 'r', encoding='utf-8') as f: theme_template = f.read() else: theme_template = '

{{ hero_title or "Bienvenido" }}

' header = '' footer = '' sidebar = '' header_path = os.path.join(THEMES_DIR, '_gkachele', 'header.php') footer_path = os.path.join(THEMES_DIR, '_gkachele', 'footer.php') sidebar_path = os.path.join(THEMES_DIR, '_gkachele', 'sidebar.php') if os.path.exists(header_path): with open(header_path, 'r', encoding='utf-8') as f: header = f.read() else: header = '' # Fallback simplificado if os.path.exists(footer_path): with open(footer_path, 'r', encoding='utf-8') as f: footer = f.read() else: footer = '' if os.path.exists(sidebar_path): with open(sidebar_path, 'r', encoding='utf-8') as f: sidebar = f.read() template_data = { 'site_name': content.get('site_name', 'GKACHELE Site'), 'hero_title': content.get('hero_title', 'Bienvenido'), 'hero_description': content.get('hero_description', ''), 'colors': content.get('colors', {}), 'typography': content.get('typography', {}), 'horarios': content.get('horarios', {}), 'redes_sociales': content.get('redes_sociales', {}), 'blocks': content.get('blocks', []), 'menus': menus, 'widgets': widgets, 'especialidad_culinaria': content.get('especialidad_culinaria', {}), 'menu_items': content.get('menu_items', {}), 'menu_url': content.get('menu_url', ''), 'capacidad': content.get('capacidad', '50'), 'direccion': content.get('direccion', ''), 'telefono': content.get('telefono', ''), 'email': content.get('email', ''), 'mapa_url': content.get('mapa_url', ''), **content } from jinja2 import Template is_full_page = False if theme == 'restaurante-moderno' or '' in theme_template: is_full_page = True if is_full_page: template = Template(theme_template) return template.render(**template_data) full_template = header + theme_template + sidebar + footer # Inject WhatsApp Button if configured whatsapp = content.get('redes_sociales', {}).get('whatsapp') if whatsapp: wa_html = f''' ''' if is_full_page: theme_template = theme_template.replace('', wa_html + '') else: footer = footer.replace('', wa_html + '') template = Template(theme_template if is_full_page else header + theme_template + sidebar + footer) return template.render(**template_data)