fix: TinyMCE über lokalen Plugin-Endpunkt ausliefern
This commit is contained in:
@@ -5,7 +5,7 @@ class DocumentationConfig(PluginConfig):
|
||||
name = "netbox_documentation"
|
||||
verbose_name = "Dokumentation"
|
||||
description = "Wiki und Office-Dokumentation direkt in NetBox"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
author = "NetBox Documentation Contributors"
|
||||
base_url = "documentation"
|
||||
min_version = "4.0.0"
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
{% extends 'generic/object_edit.html' %}
|
||||
{% load static %}
|
||||
|
||||
{% block javascript %}
|
||||
{{ block.super }}
|
||||
<script src="{% static 'tinymce/tinymce.min.js' %}"></script>
|
||||
<script src="{% url 'plugins:netbox_documentation:editor_asset' asset_path='tinymce.min.js' %}"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const editorAssetBase = "{% url 'plugins:netbox_documentation:editor_asset' asset_path='_' %}".replace(/_$/, '');
|
||||
if (typeof tinymce === 'undefined') {
|
||||
const editor = document.querySelector('[data-rich-text-editor]');
|
||||
if (editor) {
|
||||
const warning = document.createElement('div');
|
||||
warning.className = 'alert alert-warning';
|
||||
warning.textContent = 'Der Rich-Text-Editor konnte nicht geladen werden. Der Inhalt kann als HTML bearbeitet werden.';
|
||||
warning.textContent = 'Der Rich-Text-Editor konnte nicht vom lokalen Plugin-Endpunkt geladen werden. Bitte Browser-Konsole und Netzwerkprotokoll prüfen.';
|
||||
editor.parentNode.insertBefore(warning, editor);
|
||||
}
|
||||
return;
|
||||
}
|
||||
tinymce.init({
|
||||
selector: 'textarea[data-rich-text-editor]',
|
||||
base_url: editorAssetBase.replace(/\/$/, ''),
|
||||
suffix: '.min',
|
||||
license_key: 'gpl',
|
||||
height: 650,
|
||||
menubar: 'file edit view insert format tools table help',
|
||||
|
||||
@@ -3,6 +3,7 @@ from netbox.views.generic import ObjectChangeLogView
|
||||
from . import models, views
|
||||
|
||||
urlpatterns = (
|
||||
path("editor-assets/<path:asset_path>", views.EditorAssetView.as_view(), name="editor_asset"),
|
||||
path("", views.DocumentListView.as_view(), name="document_list"),
|
||||
path("documents/add/", views.DocumentEditView.as_view(), name="document_add"),
|
||||
path("documents/import/", views.DocumentImportView.as_view(), name="document_import"),
|
||||
@@ -15,4 +16,3 @@ urlpatterns = (
|
||||
path("assignments/<int:pk>/edit/", views.AssignmentEditView.as_view(), name="documentassignment_edit"),
|
||||
path("assignments/<int:pk>/delete/", views.AssignmentDeleteView.as_view(), name="documentassignment_delete"),
|
||||
)
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
from pathlib import Path
|
||||
import mimetypes
|
||||
import tinymce
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
from django.db import transaction
|
||||
from django.http import FileResponse, Http404
|
||||
from django.shortcuts import redirect, render
|
||||
from django.utils.text import slugify
|
||||
from django.views import View
|
||||
@@ -14,6 +17,21 @@ from .models import Document, DocumentAssignment, DocumentAttachment
|
||||
from .tables import DocumentTable, AssignmentTable
|
||||
|
||||
|
||||
class EditorAssetView(View):
|
||||
"""Serve the bundled editor assets when NetBox's static proxy is unavailable."""
|
||||
|
||||
def get(self, request, asset_path):
|
||||
root = (Path(tinymce.__file__).resolve().parent / "static" / "tinymce").resolve()
|
||||
candidate = (root / asset_path).resolve()
|
||||
if root not in candidate.parents or not candidate.is_file():
|
||||
raise Http404
|
||||
content_type = mimetypes.guess_type(candidate.name)[0] or "application/octet-stream"
|
||||
response = FileResponse(candidate.open("rb"), content_type=content_type)
|
||||
response["Cache-Control"] = "public, max-age=31536000, immutable"
|
||||
response["X-Content-Type-Options"] = "nosniff"
|
||||
return response
|
||||
|
||||
|
||||
class DocumentListView(generic.ObjectListView):
|
||||
queryset = Document.objects.prefetch_related("assignments")
|
||||
table = DocumentTable
|
||||
|
||||
Reference in New Issue
Block a user