diff --git a/crochet/pattern_render.py b/crochet/pattern_render.py new file mode 100644 index 0000000..9c283a4 --- /dev/null +++ b/crochet/pattern_render.py @@ -0,0 +1,159 @@ +"""Renderizado del patrón a HTML plano para la vista de solo lectura. + +A diferencia del editor (que construye el resultado con JS a partir del DOM +editable, ver static/js/section-types.js), esto genera HTML estático en el +servidor, sin ningún /
- -
+

Secciones

-
-

Vista previa

+
+

Vista previa

diff --git a/crochet/templates/crochet/pattern_detail.html b/crochet/templates/crochet/pattern_detail.html new file mode 100644 index 0000000..fbc7083 --- /dev/null +++ b/crochet/templates/crochet/pattern_detail.html @@ -0,0 +1,37 @@ +{% load static %} + + + + + + + {{ page_settings.title|default:"Crochet" }} + + + + + + + + +
+
+
+ {{ rendered_pattern }} +
+
+
+ + + diff --git a/crochet/views.py b/crochet/views.py index 3e58beb..2cebfec 100644 --- a/crochet/views.py +++ b/crochet/views.py @@ -7,32 +7,19 @@ from django.views import View from django.views.generic import DetailView from crochet.models import Pattern, PatternImage, StitchType +from crochet.pattern_render import render_pattern_html, sanitize_page_settings -class PatternContextMixin: - def get_pattern_context(self): - return { - # Resuelto por LocaleMiddleware a partir del prefijo de idioma de - # la URL (/es/..., /en/...; ver i18n_patterns en config/urls.py), - # no hace falta declararlo aparte como parámetro de esta vista. - 'lang': get_language(), - # Se pasa tal cual a la plantilla con {{ pattern_data|json_script:"..." }} - # para que main.js reconstruya el editor con el contenido guardado - # en vez del esqueleto por defecto. - 'pattern_data': { - 'sections': self.object.sections, - 'pageSettings': self.object.page_settings, - }, - # Catálogo de puntos arrastrables (ver StitchType): es el mismo para - # cualquier patrón, no depende de este objeto en concreto. - 'stitch_types': [ - {'id': stitch_type.id, 'translations': stitch_type.translations} - for stitch_type in StitchType.objects.all() - ], - } +def _stitch_types_data(): + # Catálogo de puntos arrastrables (ver StitchType): es el mismo para + # cualquier patrón, no depende de ninguno en concreto. + return [ + {'id': stitch_type.id, 'translations': stitch_type.translations} + for stitch_type in StitchType.objects.all() + ] -class PatternEditView(PatternContextMixin, DetailView): +class PatternEditView(DetailView): model = Pattern template_name = 'crochet/pattern.html' context_object_name = 'pattern' @@ -41,27 +28,46 @@ class PatternEditView(PatternContextMixin, DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context.update(self.get_pattern_context()) + # Resuelto por LocaleMiddleware a partir del prefijo de idioma de la + # URL (/es/..., /en/...; ver i18n_patterns en config/urls.py). + context['lang'] = get_language() + # Se pasa tal cual a la plantilla con {{ pattern_data|json_script:"..." }} + # para que main.js reconstruya el editor con el contenido guardado + # en vez del esqueleto por defecto. + context['pattern_data'] = { + 'sections': self.object.sections, + 'pageSettings': self.object.page_settings, + } + context['stitch_types'] = _stitch_types_data() return context -class PatternDetailView(PatternContextMixin, DetailView): - # Misma plantilla que PatternEditView: así el resultado sale con el mismo - # formato y estilo que la "Vista previa" del editor sin duplicar el - # renderizado (ver pattern.html, que oculta con `hidden` en vez de - # quitar el panel de edición cuando `readonly` está activo, ya que el - # propio panel es el que construye las secciones que luego lee - # render.js para pintar el resultado). +class PatternDetailView(DetailView): + # Plantilla propia, sin nada en común con la del editor: esta vista es + # de solo lectura y no debe cargar ningún /