Skip to content

Commit

Permalink
use django-tinymce and clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
theithec committed Nov 27, 2023
1 parent 57453cf commit e66e9d6
Show file tree
Hide file tree
Showing 18 changed files with 53 additions and 116 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
# The executor is the environment in which the steps below will be executed - below will use a python 3.10.2 container
# Change the version below to your required version of python
docker:
- image: cimg/python:3.8.13
- image: cimg/python:3.11
# Checkout the code as the first step. This is a dedicated CircleCI step.
# The python orb's install-packages step will install the dependencies from a Pipfile via Pipenv by default.
# Here we're making sure we use just use the system-wide pip. By default it uses the project root's requirements.txt.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/github-actions-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: [3.8, 3.9]
python-version: [3.11]

steps:
- uses: actions/checkout@v2
Expand Down
12 changes: 0 additions & 12 deletions .travis.yml

This file was deleted.

15 changes: 15 additions & 0 deletions demo/demo/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
DEBUG = True
ALLOWED_HOSTS = ["*"]
INSTALLED_APPS = [
"tinymce",
"grappelli.dashboard", # optional (pagetools provides two dashboard modules),
# needs further configuration
"grappelli", # required
Expand Down Expand Up @@ -152,3 +153,17 @@
PT_MAILFORM_RECEIVERS = ["nobody@localhost.localdomain"]
INTERNAL_IPS = ["127.0.0.1"]
from crispy_forms_foundation.settings import *

TINYMCE_DEFAULT_CONFIG = {
"theme": "silver",
"height": 500,
"menubar": False,
"plugins": "link,advlist,autolink,lists,link,image,charmap,print,preview,anchor,"
"searchreplace,visualblocks,code,fullscreen,insertdatetime,media,table,paste,"
"code,help,wordcount",
"toolbar": "undo redo | formatselect | "
"bold italic backcolor | alignleft aligncenter "
"alignright alignjustify | bullist numlist outdent indent | "
"removeformat | link |help",
}
X_FRAME_OPTIONS = "SAMEORIGIN"
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@
# built documents.
#
# The short X.Y version.
version = "0.9.8"
version = "0.9.9"
# The full version, including alpha/beta/rc tags.
release = "0.9.8"
release = "0.9.9"

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
1 change: 0 additions & 1 deletion pagetools/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Core features for pagetools"""
import logging


logger = logging.getLogger("pagetools") # pylint: disable=invalid-name
19 changes: 2 additions & 17 deletions pagetools/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from django.conf import settings
from django.contrib import admin
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _
Expand All @@ -7,20 +6,6 @@
from .utils import filter_expired, get_adminedit_url


class TinyMCEMixin(admin.ModelAdmin):
"""
Add tinymce media files
"""

class Media:
url = settings.STATIC_URL
js = [
f"{url}grappelli/tinymce/jscripts/tiny_mce/tiny_mce.js",
f"{url}grappelli/tinymce_setup/tinymce_setup.js",
]
"""Sphinx shows this as a hardcoded string, but it is not."""


class AdminLinkMixin:
@admin_attr_decorator
def admin_link(self, instance, linktext=None):
Expand All @@ -42,9 +27,9 @@ def get_actions(self, request):
return actions


class PagelikeAdmin(AdminLinkMixin, DeleteExpiredMixinAdmin, TinyMCEMixin):
class PagelikeAdmin(AdminLinkMixin, DeleteExpiredMixinAdmin):
"""
Prepopulate slug from title and add tinymce-media
Prepopulate slug from title
"""

prepopulated_fields = {"slug": ("title",)}
Expand Down
7 changes: 3 additions & 4 deletions pagetools/menus/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _

from pagetools.admin import TinyMCEMixin
from pagetools.utils import get_adminadd_url, get_classname

from .apps import MenusConfig
Expand Down Expand Up @@ -75,7 +74,7 @@ class Meta:
}


class MenuAdmin(TinyMCEMixin, admin.ModelAdmin):
class MenuAdmin(admin.ModelAdmin):
save_as = True
list_display = ("title", "lang")

Expand Down Expand Up @@ -206,8 +205,8 @@ def clean(self):
self.existing_menuentries.append(entry)
return cleaned_data

class Media(TinyMCEMixin.Media):
js = TinyMCEMixin.Media.js + [settings.STATIC_URL + "pagetools/admin/js/pre_sel_menu.js"]
class Media:
js = [settings.STATIC_URL + "pagetools/admin/js/pre_sel_menu.js"]


class EntrieableAdmin(admin.ModelAdmin):
Expand Down
10 changes: 6 additions & 4 deletions pagetools/models.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
"""Core models, managers and querysets for pagetools
"""
# pylint: disable=arguments-differ # because of kwargs
from typing import Any, Protocol
from typing import Any, ClassVar, Protocol

from django.conf import settings
from django.db import models
from django.utils.translation import get_language
from django.utils.translation import gettext_lazy as _
from django_stubs_ext import StrOrPromise
from model_utils.choices import Choices
from model_utils.models import StatusModel, TimeStampedModel

from . import settings as ptsettings


class AdminAttributes(Protocol):
short_description: str
short_description: StrOrPromise
allow_tags: bool
boolean: bool
admin_order_field: str
Expand All @@ -36,6 +37,7 @@ def lfilter(self, lang=False, **kwargs):
if self.use_lang and not kwargs.pop("skip_lang", False):
if lang is False:
lang = get_language() or ""
assert isinstance(lang, str)
kwargs.update(lang__in=(lang, lang.split("-")[0], ""))
return self.filter(**kwargs)

Expand All @@ -61,7 +63,7 @@ class LangModel(models.Model):
empty lang is saved as "".
"""

objects = models.Manager()
objects: ClassVar[models.Manager] = models.Manager()
lang = models.CharField(
max_length=20,
choices=settings.LANGUAGES,
Expand Down Expand Up @@ -119,7 +121,7 @@ class PublishableLangModel(LangModel, StatusModel):

_translated_choices = [(slug, _(name)) for (slug, name) in ptsettings.STATUS_CHOICES]
STATUS = Choices(*_translated_choices)
public = PublishableLangManager()
public: ClassVar[PublishableLangManager] = PublishableLangManager()

@admin_attr_decorator
def _is_published(self):
Expand Down
8 changes: 3 additions & 5 deletions pagetools/pages/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
from django.urls import reverse
from django.utils.html import strip_tags
from django.utils.translation import gettext_lazy as _
from tinymce.models import HTMLField

from pagetools.models import PagelikeModel
from pagetools.widgets.models import PageType

from .settings import INDEX_VIEW_SLUG
from .validators import validate_emails_str


Expand Down Expand Up @@ -91,16 +91,14 @@ class Meta:
class BasePage(IncludedEmailForm, AuthPage, PagelikeModel):
"""A basemodel for a page with one main content area"""

content = models.TextField(_("Content"))
content = HTMLField(_("Content"))
objects = models.Manager()
pagetype = models.ForeignKey(PageType, blank=True, null=True, on_delete=models.CASCADE)

def get_pagetype(self, **kwargs):
return self.pagetype

def get_absolute_url(self):
if self.slug == INDEX_VIEW_SLUG:
return "/"
return reverse("pages:pageview", kwargs={"slug": self.slug})

class Meta(PagelikeModel.Meta):
Expand All @@ -117,7 +115,7 @@ class Page(BasePage):
class PageBlockMixin(models.Model):
"""Abstract Content blocks for pages"""

content = models.TextField(_("Content"), blank=True)
content = HTMLField(_("Content"), blank=True)
visible = models.BooleanField(_("Visible"), default=True)
# in concrete model:
# page = models.ForeignKey(MyBlockPage)
Expand Down
10 changes: 5 additions & 5 deletions pagetools/pages/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class PageViewTestCase(MenuDataTestCase):
def test_detailview(self):
response = self.client.get(self.page1.get_absolute_url())
self.assertEqual(response.status_code, 200)
self.assertEqual(response.status_code, 200) # type: ignore

@mock.patch("pagetools.pages.forms.MAILFORM_RECEIVERS", ["q@w.de"])
@mock.patch("captcha.conf.settings.CAPTCHA_TEST_MODE", True)
Expand All @@ -19,15 +19,15 @@ def test_with_form(self):
"message": "The Message",
"content": "Content",
"subject": "Subject",
"captcha_0": "xPASSED",
"captcha_0": "PASSED",
"captcha_1": "PASSED",
}
pagetools.pages.models.Page.includable_forms = {"Contactform": CaptchaContactForm}
pagetools.pages.models.Page.includable_forms = {"Contactform": CaptchaContactForm} # type: ignore
response = self.client.post(self.page1.get_absolute_url(), data)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.status_code, 200, response.content) # type: ignore
self.assertNotContains(response, "An error occured")

data.pop("sender")
response = self.client.post(self.page1.get_absolute_url(), data)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.status_code, 200) # type: ignore
self.assertContains(response, "error_1_id_sender")
31 changes: 0 additions & 31 deletions pagetools/sections/tests/test_admin.py

This file was deleted.

3 changes: 2 additions & 1 deletion pagetools/subscriptions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from tinymce.models import HTMLField

from pagetools.models import LangManager, LangModel
from pagetools.utils import import_cls
Expand Down Expand Up @@ -65,7 +66,7 @@ class QueuedEmail(LangModel):
modifydate = models.DateTimeField("Last modified on", auto_now_add=True, blank=True, editable=False)
senddate = models.DateTimeField("Send after", auto_now_add=True, blank=True, editable=True)
subject = models.CharField(verbose_name="Subject", default="", unique=False, blank=True, max_length=255)
body = models.TextField(verbose_name="Body", default="", unique=False, blank=True)
body = HTMLField(verbose_name="Body", default="", unique=False, blank=True)

class Meta:
verbose_name = _("News-Mail")
Expand Down
22 changes: 0 additions & 22 deletions pagetools/tests/test_admin.py

This file was deleted.

7 changes: 6 additions & 1 deletion pagetools/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
"""
from django.conf import settings
from django.conf.urls.static import static
from django.urls import include, path

urlpatterns = []
urlpatterns = [

path('tinymce/', include('tinymce.urls')),

]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
3 changes: 1 addition & 2 deletions pagetools/widgets/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from django.http.response import HttpResponseRedirect
from django.urls import reverse

from pagetools.admin import TinyMCEMixin
from pagetools.utils import get_classname, get_perm_str

from .models import (
Expand Down Expand Up @@ -126,7 +125,7 @@ class PageTypeAdmin(admin.ModelAdmin):
model = PageType


class ContentWidgetAdmin(BaseWidgetAdmin, TinyMCEMixin):
class ContentWidgetAdmin(BaseWidgetAdmin):
pass


Expand Down
4 changes: 3 additions & 1 deletion pagetools/widgets/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

from pagetools.models import LangManager, LangModel
from pagetools.utils import get_adminedit_url, import_cls
from tinymce.models import HTMLField


from . import settings

Expand Down Expand Up @@ -46,7 +48,7 @@ class ContentWidget(BaseWidget):
A wiget with a text area
"""

content = models.TextField(_("Content"))
content = HTMLField(_("Content"))

def get_content(self, context, request): # pylint: disable=unused-argument
return self.content
Expand Down
Loading

0 comments on commit e66e9d6

Please sign in to comment.