From cc545f1d917c92b17d7723028ff0a54eb0f3765a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20Caux?= <git@jscaux.org> Date: Thu, 2 Feb 2023 08:46:48 +0100 Subject: [PATCH] Add markup TextareaWithPreview widget --- .../_hx_textarea_widget_value_processed.html | 13 ++++++++++++ .../forms/widgets/textarea_with_preview.html | 15 ++++++++++++++ scipost_django/markup/urls.py | 1 + scipost_django/markup/views.py | 20 ++++++++++++++++++- scipost_django/markup/widgets.py | 19 ++++++++++++++++++ 5 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 scipost_django/markup/templates/markup/forms/widgets/_hx_textarea_widget_value_processed.html create mode 100644 scipost_django/markup/templates/markup/forms/widgets/textarea_with_preview.html create mode 100644 scipost_django/markup/widgets.py diff --git a/scipost_django/markup/templates/markup/forms/widgets/_hx_textarea_widget_value_processed.html b/scipost_django/markup/templates/markup/forms/widgets/_hx_textarea_widget_value_processed.html new file mode 100644 index 000000000..e01f6d97d --- /dev/null +++ b/scipost_django/markup/templates/markup/forms/widgets/_hx_textarea_widget_value_processed.html @@ -0,0 +1,13 @@ +<div style="border: 2px solid orange;"> + <div style="margin: 1rem;"> + <strong>Preview</strong> <em>(detected language: {{ markup.language }}</em>) + {% if markup.errors %} + <span style="text-color: red;">Errors: {{ markup.errors }}</span> + {% endif %} + {% if markup.warnings %} + <span style="text-color: orange;">Errors: {{ markup.warnings }}</span> + {% endif %} + </div> + <hr> + <div style="margin: 1rem;">{{ markup.processed|safe }}</div> +</div> diff --git a/scipost_django/markup/templates/markup/forms/widgets/textarea_with_preview.html b/scipost_django/markup/templates/markup/forms/widgets/textarea_with_preview.html new file mode 100644 index 000000000..c5c703c70 --- /dev/null +++ b/scipost_django/markup/templates/markup/forms/widgets/textarea_with_preview.html @@ -0,0 +1,15 @@ +<div hx-post="{% url 'markup:_hx_process' field=widget.name %}" + hx-params="csrfmiddlewaretoken, {{ widget.name }}" + hx-target="#markup-preview-{{ widget.attrs.id }}" + hx-trigger="load, keyup from:#{{ widget.attrs.id }} delay:500ms" + hx-confirm="unset" +> +</div> + +<div id="markup-preview-{{ widget.attrs.id }}" + style="margin-bottom: 1rem;" +></div> + +<textarea name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}> + {% if widget.value %}{{ widget.value }}{% endif %} +</textarea> diff --git a/scipost_django/markup/urls.py b/scipost_django/markup/urls.py index 4043bf479..ca01ada17 100644 --- a/scipost_django/markup/urls.py +++ b/scipost_django/markup/urls.py @@ -10,6 +10,7 @@ app_name = "markup" urlpatterns = [ path("process/", views.process, name="process"), + path("_hx_process/<str:field>", views._hx_process, name="_hx_process"), path("help/", views.markup_help, name="help"), path("help/plaintext", views.plaintext_help, name="plaintext_help"), path("help/Markdown", views.markdown_help, name="markdown_help"), diff --git a/scipost_django/markup/views.py b/scipost_django/markup/views.py index 92a6f2663..e61daa531 100644 --- a/scipost_django/markup/views.py +++ b/scipost_django/markup/views.py @@ -3,7 +3,7 @@ __license__ = "AGPL v3" from django.contrib.auth.decorators import login_required -from django.http import JsonResponse +from django.http import HttpResponse, JsonResponse from django.shortcuts import render from .constants import ( @@ -33,6 +33,24 @@ def process(request): return JsonResponse({}) +@login_required +def _hx_process(request, field): + """ + API call to process the POSTed text in given for field. Returns an HTML snippet. + """ + if request.method == "POST": + data = request.POST.copy() + data["markup_text"] = request.POST.get(field, None) + form = MarkupTextForm(data) + if form.is_valid(): + return render( + request, + "markup/forms/widgets/_hx_textarea_widget_value_processed.html", + context = { "markup": form.get_processed_markup(),}, + ) + return HttpResponse() + + def markup_help(request): """ General help page about markup facilities at SciPost. diff --git a/scipost_django/markup/widgets.py b/scipost_django/markup/widgets.py new file mode 100644 index 000000000..2cc73918f --- /dev/null +++ b/scipost_django/markup/widgets.py @@ -0,0 +1,19 @@ +__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + + +from django.forms.widgets import Textarea + +from .utils import process_markup + + +class TextareaWithPreview(Textarea): + template_name = 'markup/forms/widgets/textarea_with_preview.html' + + def get_context(self, name, value, attrs): + context = super().get_context(name, value, attrs) + context["value_processed"] = process_markup( + context["widget"]["value"], + include_errors=True, + ) + return context -- GitLab