quill for a blog page

This commit is contained in:
Priec
2026-05-19 22:16:37 +02:00
parent 6feb6f210d
commit 57798b5ea0
14 changed files with 585 additions and 127 deletions

View File

@@ -1,6 +1,9 @@
{% extends "admin/base.html" %}
{% block title %}{{ t(key="new-article", lang=lang | default(value='sk')) }}{% endblock title %}
{% block head %}
<link href="/static/vendor/quill/quill.snow.css" rel="stylesheet" type="text/css">
{% endblock head %}
{% block content %}
<div class="space-y-2">
@@ -27,18 +30,20 @@
<div class="form-control">
<label class="label"><span class="label-text">{{ t(key="content", lang=lang | default(value='sk')) }}</span></label>
<textarea name="content" rows="18" required class="textarea textarea-bordered w-full"></textarea>
</div>
<div class="form-control">
<label class="label"><span class="label-text">{{ t(key="featured-image-id", lang=lang | default(value='sk')) }}</span></label>
<div class="flex flex-wrap gap-2">
<input type="text" name="featured_image_id" data-blog-image-id class="input input-bordered min-w-0 flex-1">
<input type="file" accept="image/jpeg,image/png,image/webp,image/gif" data-blog-image-file class="file-input file-input-bordered min-w-0 flex-1">
<button type="button" class="btn btn-outline btn-sm" data-blog-image-upload data-uploading="{{ t(key="image-uploading", lang=lang | default(value='sk')) }}" data-ready="{{ t(key="upload-featured-image", lang=lang | default(value='sk')) }}">{{ t(key="upload-featured-image", lang=lang | default(value='sk')) }}</button>
<textarea name="content" data-rich-content class="hidden"></textarea>
<input type="hidden" name="featured_image_id" data-featured-image-id>
<div data-rich-editor class="blog-editor"></div>
<div data-image-size-controls class="blog-image-size-controls hidden">
<span>{{ t(key="image-size", lang=lang | default(value='sk')) }}</span>
<button type="button" data-image-size="small">{{ t(key="image-size-small", lang=lang | default(value='sk')) }}</button>
<button type="button" data-image-size="medium">{{ t(key="image-size-medium", lang=lang | default(value='sk')) }}</button>
<button type="button" data-image-size="full">{{ t(key="image-size-full", lang=lang | default(value='sk')) }}</button>
<label>
<span>{{ t(key="image-width-px", lang=lang | default(value='sk')) }}</span>
<input type="number" min="40" max="1200" step="10" data-image-width class="input input-bordered input-sm">
</label>
</div>
<p class="text-sm opacity-70" data-blog-image-status>{{ t(key="image-upload-help", lang=lang | default(value='sk')) }}</p>
<img data-blog-image-preview alt="" class="mt-2 hidden max-h-48 rounded border border-base-300 object-cover">
<p class="text-sm opacity-70" data-rich-status data-uploading='{{ t(key="image-uploading", lang=lang | default(value='sk')) }}' data-uploaded='{{ t(key="image-uploaded", lang=lang | default(value='sk')) }}' data-error='{{ t(key="image-upload-error", lang=lang | default(value='sk')) }}'></p>
</div>
<label class="label cursor-pointer justify-start gap-2">
@@ -54,42 +59,6 @@
</div>
</div>
</div>
<script>
(function () {
const fileInput = document.querySelector('[data-blog-image-file]');
const idInput = document.querySelector('[data-blog-image-id]');
const uploadButton = document.querySelector('[data-blog-image-upload]');
const status = document.querySelector('[data-blog-image-status]');
const preview = document.querySelector('[data-blog-image-preview]');
if (!fileInput || !idInput || !uploadButton || !status || !preview) return;
function setPreview(filename) {
if (!filename) return;
preview.src = '/images/' + filename;
preview.classList.remove('hidden');
}
uploadButton.addEventListener('click', async function () {
const file = fileInput.files && fileInput.files[0];
if (!file) return;
uploadButton.disabled = true;
uploadButton.textContent = uploadButton.dataset.uploading;
const formData = new FormData();
formData.append('file', file);
try {
const response = await fetch('/images/upload', { method: 'POST', body: formData });
if (!response.ok) throw new Error('upload failed');
const result = await response.json();
idInput.value = result.filename;
setPreview(result.filename);
status.textContent = '{{ t(key="image-uploaded", lang=lang | default(value='sk')) }}';
} catch (_error) {
status.textContent = '{{ t(key="image-upload-error", lang=lang | default(value='sk')) }}';
} finally {
uploadButton.disabled = false;
uploadButton.textContent = uploadButton.dataset.ready;
}
});
})();
</script>
<script src="/static/vendor/quill/quill.js"></script>
<script src="/static/js/blog-editor.js"></script>
{% endblock content %}