diff --git a/shared/media_archive/admin.py b/shared/media_archive/admin.py
index e4b8204..5d1f345 100644
--- a/shared/media_archive/admin.py
+++ b/shared/media_archive/admin.py
@@ -2,12 +2,11 @@ from django import VERSION as DJANGO_VERSION
from django.contrib import admin
from django.contrib.admin.filters import ChoicesFieldListFilter, FieldListFilter
from django.db.models import Count
+from django.template.loader import render_to_string
from django.utils.encoding import smart_text
-from django.utils.html import format_html, mark_safe
+from django.utils.html import format_html, mark_safe, strip_tags
from django.utils.translation import gettext_lazy as _
-from imagekit.admin import AdminThumbnail
-
from .conf import USE_TRANSLATABLE_FIELDS
from .forms import MediaCategoryAdminForm
from . import admin_actions, mixins, models
@@ -22,6 +21,38 @@ else:
return fieldname
+class AdminThumbnail:
+ # Taken from ImageKit and adapted for django-imagefield
+ image_field = 'file'
+ format_name = 'admin_thumbnail'
+ template = 'imagekit/admin/selectable_thumbnail.html'
+ short_description = _('Thumbnail')
+ allow_tags = True
+
+ def __init__(self, image_field=None, format_name=None, template=None):
+ if image_field:
+ self.image_field = image_field
+ if format_name:
+ self.format_name = format_name
+ if template:
+ self.template = template
+
+ def __call__(self, obj):
+ if callable(self.image_field):
+ thumbnail = self.image_field(obj)
+ else:
+ thumbnail = getattr(getattr(obj, self.image_field), self.format_name)
+
+ original_image = getattr(thumbnail, 'source', None) or thumbnail
+ template = self.template or 'imagekit/admin/thumbnail.html'
+
+ return render_to_string(template, {
+ 'model': obj,
+ 'thumbnail': thumbnail,
+ 'original_image': original_image,
+ })
+
+
class CategoryFieldListFilter(ChoicesFieldListFilter):
"""
Customization of ChoicesFilterSpec which sorts in the user-expected format.
@@ -121,36 +152,42 @@ class MediaAdminBase(admin_actions.MediaBaseActionsMixin, mixins.DropUploadAdmin
fieldsets = (
(None, {
'fields': [
- 'is_public',
- ('file', 'image_ppoi'),
+ *i18n_fields('caption'),
*i18n_fields('name'),
- 'role',
+ ('file', 'image_ppoi'),
+ (
+ 'is_public',
+ 'role',
+ ),
]}),
- (_("Texte"), {
+ (_("Bildnachweise"), {
'fields': [
- *i18n_fields('caption'),
*i18n_fields('credits'),
*i18n_fields('copyright'),
]}),
- (_("Ordnung"), {
+ (_("Verwaltung"), {
+ 'classes': ['collapse'],
'fields': [
'categories',
]}),
)
filter_horizontal = ['categories']
- admin_thumbnail = AdminThumbnail(
- image_field='thumbnail',
- template='imagekit/admin/selectable_thumbnail.html')
- admin_thumbnail.short_description = _("Foto")
+ admin_thumbnail = AdminThumbnail()
# TODO class Media: add switch_languages script
def get_name_display(self, obj):
+ caption = strip_tags(obj.caption)
+ if obj.name and obj.name != caption:
+ caption = mark_safe(f"
{caption}")
+ else:
+ caption = ""
return format_html(
- "{categories}
{caption}",
+ "{categories}
{name}{caption}",
categories=", ".join([str(p) for p in obj.categories.all()]),
- caption=str(obj),
+ name=str(obj),
+ caption=caption,
)
get_name_display.short_description = _("Name")
get_name_display.admin_order_field = lang_suffix(fieldname='name')
@@ -189,9 +226,7 @@ class ImageGalleryRelInline(admin.TabularInline):
verbose_name = _("Bild")
verbose_name_plural = _("Bilder")
- admin_thumbnail = AdminThumbnail(
- image_field=image_thumbnail_image,
- template='imagekit/admin/selectable_thumbnail.html')
+ admin_thumbnail = AdminThumbnail()
admin_thumbnail.short_description = _("Foto")
diff --git a/shared/media_archive/conf.py b/shared/media_archive/conf.py
index 37353ae..0598672 100644
--- a/shared/media_archive/conf.py
+++ b/shared/media_archive/conf.py
@@ -1,5 +1,6 @@
from django.conf import settings
+
USE_TRANSLATABLE_FIELDS = (
getattr(settings, 'CONTENT_PLUGINS_USE_TRANSLATABLE_FIELDS', False) or
getattr(settings, 'USE_TRANSLATABLE_FIELDS', False)
diff --git a/shared/media_archive/models.py b/shared/media_archive/models.py
index 07ceaa6..e24a0fc 100644
--- a/shared/media_archive/models.py
+++ b/shared/media_archive/models.py
@@ -1,14 +1,15 @@
import logging
import posixpath
import re
+from functools import partial
from django.db import models
from django.utils.html import strip_tags
+from django.utils.text import Truncator
from django.utils.translation import ugettext_lazy as _
from imagefield.fields import ImageField, PPOIField
-from imagekit.models import ImageSpecField
-from imagekit.processors import Adjust, Thumbnail, ResizeToFit, ResizeToFill
+from shared.utils.text import html_to_text, sanitized_html
from shared.utils.models.slugs import DowngradingSlugField, slugify
from .conf import UPLOAD_TO, USE_TRANSLATABLE_FIELDS
@@ -34,7 +35,7 @@ class MediaCategoryManager(models.Manager):
class MediaCategory(models.Model):
- name = models.CharField(_("name"), max_length=200)
+ name = models.CharField(_("name"), blank=True, max_length=200)
parent = models.ForeignKey(
'self', blank=True, null=True,
on_delete=models.CASCADE,
@@ -78,7 +79,8 @@ class Gallery(models.Model):
help_text=_("Publicly visible name."))
slug = models.SlugField(_("Slug"), null=True, blank=True)
credits = TranslatableCharField(_("Credits"), null=True, blank=True, max_length=500)
- caption = TranslatableCleansedRichTextField(_("Caption"), null=True, blank=True)
+ caption = TranslatableCleansedRichTextField(_("Caption"),
+ null=True, blank=True, config_name='caption')
is_public = models.BooleanField(_("Active"), default=False)
order_index = models.PositiveIntegerField(_("Order Index"), default=0)
# background_color = models.ForeignKey('site_pages.Color', on_delete=models.PROTECT,
@@ -165,8 +167,8 @@ class MediaRole(models.Model):
name = TranslatableCharField(_("name"), max_length=200)
class Meta:
- verbose_name = _("Bild-Typ")
- verbose_name_plural = _("Bild-Typen")
+ verbose_name = _("Art")
+ verbose_name_plural = _("Arten")
ordering = i18n_fields('name')
def __str__(self):
@@ -194,7 +196,9 @@ class MediaBase(DeleteOldFileMixin, models.Model):
verbose_name=_("Typ"),
null=True, blank=True)
name = TranslatableCharField(_("Name"), max_length=200, null=True, blank=True)
- caption = TranslatableCleansedRichTextField(_("Bildunterschrift"), blank=True)
+ caption = TranslatableCleansedRichTextField(_("Bildunterschrift"), blank=True,
+ config_name='caption',
+ cleanse=partial(sanitized_html, config_name='caption'))
credits = TranslatableCharField(_("Credits"), max_length=500, null=True, blank=True)
copyright = TranslatableCharField(_('Rechteinhaber/in'), max_length=2000, blank=True)
@@ -211,6 +215,11 @@ class MediaBase(DeleteOldFileMixin, models.Model):
return self.name or strip_tags(self.caption) or posixpath.basename(self.file.name)
def save(self, *args, **kwargs):
+ if not self.name:
+ if self.caption:
+ self.name = Truncator(html_to_text(self.caption)).chars(200, truncate=' …')
+ else:
+ self.name = Truncator(posixpath.basename(self.file.name)).chars(200, truncate=' …')
if self.file:
try:
self.file_size = self.file.size
@@ -221,14 +230,6 @@ class MediaBase(DeleteOldFileMixin, models.Model):
class Image(MediaBase):
- image_width = models.PositiveIntegerField(
- _("image width"), blank=True, null=True, editable=False
- )
- image_height = models.PositiveIntegerField(
- _("image height"), blank=True, null=True, editable=False
- )
- image_ppoi = PPOIField(_("primary point of interest"))
- # file = models.ImageField(_("Datei"))
file = ImageField(
_("image"),
max_length=200,
@@ -238,43 +239,11 @@ class Image(MediaBase):
ppoi_field="image_ppoi",
blank=True,
)
-
- logo_image = ImageSpecField(source='file',
- processors=[ResizeToFit(150, 150)])
-
- thumbnail = ImageSpecField(source='file',
- processors=[Adjust(contrast=1.2, sharpness=1.1),
- Thumbnail(100, 50)],
- format='JPEG', options={'quality': 90})
-
- square_image = ImageSpecField(source='file',
- processors=[ResizeToFill(800, 800)],
- format='JPEG', options={'quality': 90})
-
- small_article_image = ImageSpecField(source='file',
- processors=[ResizeToFit(400, 400)],
- format='JPEG', options={'quality': 90})
-
- article_image = ImageSpecField(source='file',
- processors=[ResizeToFit(800, 800)],
- format='JPEG', options={'quality': 90})
-
- gallery_image = ImageSpecField(source='file',
- processors=[ResizeToFit(1200, 1200)],
- format='JPEG', options={'quality': 90})
-
- gallery_image_thumbnail = ImageSpecField(source='file',
- processors=[
- Adjust(contrast=1.2, sharpness=1.1),
- # ResizeToFit(180, 120)
- ResizeToFit(220, 155)
- ],
- format='JPEG', options={'quality': 90})
-
- lightbox_image = ImageSpecField(source='file',
- processors=[ResizeToFit(1600, 1600)],
- format='JPEG', options={'quality': 90})
- highres_image = lightbox_image
+ image_width = models.PositiveIntegerField(
+ _("image width"), blank=True, null=True, editable=False)
+ image_height = models.PositiveIntegerField(
+ _("image height"), blank=True, null=True, editable=False)
+ image_ppoi = PPOIField(_("primary point of interest"))
type = 'image'
diff --git a/shared/media_archive/templates/imagekit/admin/selectable_thumbnail.html b/shared/media_archive/templates/imagekit/admin/selectable_thumbnail.html
index 6d88740..8effd7b 100644
--- a/shared/media_archive/templates/imagekit/admin/selectable_thumbnail.html
+++ b/shared/media_archive/templates/imagekit/admin/selectable_thumbnail.html
@@ -1,3 +1 @@
-{% if thumbnail %}
-
-{% endif %}
+{% if thumbnail %}
{% endif %}