Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

image plugin improvements

  • Loading branch information...
commit 28cbd897a9508e1f4e4a7a877361916a1db7c209 1 parent 3c8867e
Daniele Procida authored
514 arkestra_image_plugin/cms_plugins.py
View
@@ -2,7 +2,7 @@
import os
from django.utils.translation import ugettext_lazy as _
-from django.contrib import admin
+from django.contrib import admin, messages
from django import forms
from django.db import models
@@ -12,52 +12,99 @@
from easy_thumbnails.files import get_thumbnailer
from widgetry.tabs.admin import ModelAdminWithTabs
+from widgetry import fk_lookup
-from arkestra_utilities.output_libraries.plugin_widths import *
+from arkestra_utilities.output_libraries.plugin_widths import get_placeholder_width, calculate_container_width
+from arkestra_utilities.mixins import AutocompleteMixin
-from models import FilerImage, ImageSetItem, ImageSetPlugin
+from links import schema
-def width_of_image(context, plugin, image):
- # print "** image", image
- aspect_ratio = float(image.width)/image.height
- plugin.has_borders = False
+from models import FilerImage, ImageSetItem, ImageSetPlugin
- # use native width
- if not plugin.width:
- width = float(image.width) # is float needed?
+# a dictionary to show how many items per row depending on the number of items
+LIGHTBOX_COLUMNS = {2:2, 3:3, 4:4, 5:5, 6:3, 7:4, 8:4, 9:3, 10:5, 11:4, 12:4, 13:5, 14:5, 15:5, 16:4, 17:6, 18:6, 19:5, 20:5, 21:6, 22:6, 23:6, 24:6, 25:5 }
- # absolute widths
- elif plugin.width < 0:
- width = -plugin.width
- # a special case: 50px images are square
- if width == 50:
- plugin.aspect_ratio = 1
+def width_of_image_container(context, plugin):
+ # Based on the plugin settings and placeholder width, calculate image width
+
+ # work out native image aspect ratio
+ plugin.has_borders = False
+
+ # width values
+ # None: use native width
+ # <0: an absolute value
+ # <=100: a percentage of placeholder's width
+ # 1000: automatic, based on placeholder's width
+
+ placeholder_width = get_placeholder_width(context, plugin)
- # relative widths
+ if plugin.width > 0 and plugin.width <= 100:
+ width = placeholder_width/100.0 * plugin.width
+ auto = False
else:
- # calculate the width of the placeholder
- placeholder_width = get_placeholder_width(context, plugin)
-
- # widths a fraction of nominal container width (deprecated)
- if plugin.width <= 10:
- width = placeholder_width/plugin.width
-
- # widths relative to placeholder width
+ width = placeholder_width
+ auto = True
+
+ # calculate the width of the block the image will be in
+ width = calculate_container_width(context, plugin, width, auto)
+
+ return width
+
+def width_of_image(plugin, image=None):
+ # no plugin width?
+ if not plugin.width:
+ if image:
+ # use native image width
+ width = image.width
else:
- # widths a percentage of placeholder width
- if plugin.width <= 100:
- width = placeholder_width/100.0 * plugin.width
- auto = False
+ # use container width
+ width = plugin.container_width
+ elif plugin.width < 0:
+ width = -plugin.width
+ else:
+ width = plugin.container_width
+ return width
- # automatic width
- elif plugin.width == 1000:
- width = placeholder_width
- auto = True
-
- # calculate the width of the block the image will be in
- width = calculate_container_width(context, plugin, width, auto)
-
- return width, aspect_ratio
+ # if plugin.width >= 0:
+ # placeholder_width = get_placeholder_width(context, plugin)
+ #
+ # if plugin.width == 1000 or not plugin.width:
+ # width = placeholder_width
+ # auto = True
+ #
+ # elif plugin.width <= 100:
+ # width = placeholder_width/100.0 * plugin.width
+ # auto = False
+ #
+ #
+ #
+ #
+ #
+ # elif plugin.width < 0:
+ # width = -plugin.width
+ #
+ # else:
+ # # we need to know the width of the placeholder
+ # placeholder_width = get_placeholder_width(context, plugin)
+ #
+ # # widths relative to placeholder width
+ # # widths a percentage of placeholder width
+ # if plugin.width <= 100:
+ # width = placeholder_width/100.0 * plugin.width
+ # auto = False
+ #
+ # # automatic width
+ # elif plugin.width == 1000 or not plugin.width:
+ # width = placeholder_width
+ # auto = True
+ #
+ # # calculate the width of the block the image will be in
+ # width = calculate_container_width(context, plugin, width, auto)
+ #
+ # return width
+
+def calculate_aspect_ratio(image):
+ return float(image.width)/image.height
def shave_if_floated(plugin, width):
# shave off 5 point if the image is floated, to make room for a margin
@@ -66,103 +113,107 @@ def shave_if_floated(plugin, width):
# print "-5 for float"
return width - 5
-def calculate_height(plugin, width, aspect_ratio):
+def calculate_height(given_width, given_height, given_aspect_ratio, width, aspect_ratio):
+
+ # rules:
# if the instance has an aspect ratio, use that to calculate the height
- if plugin.aspect_ratio:
- height = width / plugin.aspect_ratio
- # if the instance has no width, but does have a height, use the aspect ratio to calculate it
- if plugin.height and not plugin.width:
- width = height * plugin.aspect_ratio
-
# if the instance has no aspect ratio, but does have a height, use the height
- elif plugin.height:
- height = plugin.height
+ # if the instance has no aspect ratio, we use the native aspect ratio
+
+ # has aspect ratio
+ if given_aspect_ratio:
+ height = width / given_aspect_ratio
+ # if the instance has no width, but does have a height, use the aspect ratio to calculate it
+ if given_height and not given_width:
+ width = height * given_aspect_ratio
+ # has height
+ elif given_height:
+ height = given_height
# if it had no width either, we can use the native aspect ratio to calculate that
- if not plugin.width:
+ if not given_width:
width = aspect_ratio * height
- # if the instance has no aspect ratio, we use the native aspect ratio
+ # use the native aspect ratio
else:
height = width / aspect_ratio
return width, height
def set_image_caption(image):
- # set caption
- if image.use_description_as_caption:
+ # prefer the manually-entered caption on the plugin, otherwise the one from the filer
+ if image.caption or (image.use_description_as_caption and image.image.description):
return image.caption or image.image.description
-class FilerImagePlugin(CMSPluginBase):
- model = FilerImage
- name = _("Image")
- render_template = "cmsplugin_filer_image/image.html"
- text_enabled = True
- raw_id_fields = ('image',)
- admin_preview = False
-
- def render(self, context, instance, placeholder):
- """
- if width => 0: image width will be relative to placeholder's width
- if width > 0 but <= 10: now no longer available - image width = placeholder's width/width
- if width > 10 but <= 100: image width = width% of placeholder's width
- if width = 1000: width will be calculated automatically
- if width < 0: absolute widths (preset in choices)
- image width = - width
- if image width = 50: special case: small square images
- aspect ratio = 1
- if width = "":
- image width = image's native width
-
- """
- # TODO: this scaling code needs to be in a common place
- # use the placeholder width as a hint for sizing
- # print
- # print "----------------- Image plugin ------------------------"
- # print "image:", instance.image, "image width:", instance.image.width
- # get the image's aspect ratio, in case we need it later
- aspect_ratio = float(instance.image.width)/instance.image.height
- instance.has_borders = False
-
- # calculate its width
- print "**", width_of_image(context, instance, instance.image)
- width, aspect_ratio = width_of_image(context, instance, instance.image)
-
- # shave if floated
- width = shave_if_floated(instance, width) or width
-
- # calculate height
- width, height = calculate_height(instance, width, aspect_ratio)
-
- # set caption
- instance.caption = set_image_caption(instance)
-
- # print
- # print "final output size", width, "x", height
-
- context.update({
- 'object':instance,
- #'link':instance.link,
- #'image_url':instance.scaled_image_url,
- 'image_size': u'%sx%s' % (int(width), int(height)),
- 'caption_width': int(width),
- 'placeholder':placeholder,
- })
- return context
-
- def get_thumbnail(self, context, instance):
- if instance.image:
- return instance.image.image.file.get_thumbnail(self._get_thumbnail_options(context, instance))
- def icon_src(self, instance):
- return instance.image.thumbnails['admin_tiny_icon']
+class ImageSetItemLinkInlineForm(forms.ModelForm):
+ class Meta:
+ model=ImageSetItem
+
+ def __init__(self, *args, **kwargs):
+ super(ImageSetItemLinkInlineForm, self).__init__(*args, **kwargs)
+ if self.instance.pk is not None and self.instance.destination_content_type:
+ destination_content_type = self.instance.destination_content_type.model_class()
+ else:
+ destination_content_type = None
+ self.fields['destination_object_id'].widget = fk_lookup.GenericFkLookup('id_%s-destination_content_type' % self.prefix, destination_content_type)
+ self.fields['destination_content_type'].widget.choices = schema.content_type_choices()
+
+ def clean(self):
+ # the Link is optional, but unless both fields both Type and Item fields are provided,
+ # reset them to None
+ if not self.cleaned_data["destination_content_type"] or not self.cleaned_data["destination_object_id"]:
+ self.cleaned_data["destination_content_type"]=None
+ self.cleaned_data["destination_object_id"]=None
+
+ # no alt-text? no links for you!
+ if self.cleaned_data["destination_object_id"] and not self.cleaned_data["alt_text"]:
+ raise forms.ValidationError('You <strong>must</strong> provide alt text for users on images that serve as links')
+
+ if "click here" in self.cleaned_data["alt_text"].lower():
+ raise forms.ValidationError("'Click here'?! In alt text?! You cannot be serious. Fix this at once.")
+
+ return self.cleaned_data
+
+
+class ImageSetItemLinkInlineFormset(forms.models.BaseInlineFormSet):
+ def clean(self):
+
+ some_have_links = False
+ some_do_not_have_links = False
+
+ for form in self.forms:
+ # if a subform is invalid Django explicity raises
+ # an AttributeError for cleaned_data
+ try:
+ # only forms with an image field count - the others might be blank
+ if form.cleaned_data:
+ if form.cleaned_data.get("destination_content_type") and form.cleaned_data.get("destination_object_id"):
+ some_have_links = True
+ else:
+ some_do_not_have_links = True
+ except AttributeError:
+ pass
+
+ # if some_have_links and some_do_not_have_links then that's inconsistent
+ if some_have_links and some_do_not_have_links:
+ raise forms.ValidationError('Either all or none of the items in this set should have links')
+
-class ImageSetItemEditor(admin.TabularInline):
+class ImageSetItemEditor(admin.StackedInline, AutocompleteMixin):
+ form = ImageSetItemLinkInlineForm
+ formset = ImageSetItemLinkInlineFormset
+ # related_search_fields = ['destination_content_type']
model = ImageSetItem
extra=1
- fieldset_basic = ('', {'fields': (('image', 'alt_text',),)})
+ fieldset_basic = ('', {'fields': (('image',),)})
fieldset_advanced = ('Caption', {'fields': (( 'use_description_as_caption', 'caption'),), 'classes': ('collapse',)})
- fieldsets = (fieldset_basic, fieldset_advanced)
+ fieldsets = (fieldset_basic, fieldset_advanced,
+ ("Link", {
+ 'fields': (('destination_content_type', 'destination_object_id',), 'alt_text',),
+ 'classes': ('collapse',),
+ }),
+)
formfield_overrides = {
models.TextField: {'widget': forms.Textarea(attrs={'cols':30, 'rows':3,},),},
}
@@ -173,10 +224,11 @@ class ImageSetPublisher(CMSPluginBase):
text_enabled = True
raw_id_fields = ('image',)
inlines = (ImageSetItemEditor,)
- admin_preview = False
+ admin_preview = False
fieldset_basic = ('Size & proportions', {'fields': (('kind', 'width', 'aspect_ratio',),)})
fieldset_advanced = ('Advanced', {'fields': (( 'float', 'height'),), 'classes': ('collapse',)})
- fieldsets = (fieldset_basic, fieldset_advanced)
+ fieldset_items_per_row = ('For Multiple and Lightbox plugins only', {'fields': ('items_per_row',), 'classes': ('collapse',)})
+ fieldsets = (fieldset_basic, fieldset_items_per_row, fieldset_advanced)
def __init__(self, model = None, admin_site = None):
self.admin_preview = False
@@ -184,136 +236,139 @@ def __init__(self, model = None, admin_site = None):
super(ImageSetPublisher, self).__init__(model, admin_site)
def render(self, context, imageset, placeholder):
+
+ # don't do anything if there are no items in the imageset
if imageset.imageset_item.count():
- if imageset.kind == "slider" and imageset.imageset_item.count() > 2:
- self.render_template = "arkestra_image_plugin/slider.html"
-
- # calculate the width of the placeholder
- placeholder_width = get_placeholder_width(context, imageset)
- # widths a percentage of placeholder width
- if imageset.width <= 100:
- width = placeholder_width/100.0 * imageset.width
- auto = False
-
- # automatic width
- elif imageset.width == 1000:
- width = placeholder_width
- auto = True
-
- # calculate the width of the block the image will be in
- width = calculate_container_width(context, imageset, width, auto)
-
- items = list(imageset.imageset_item.all())
- heights = []
- for item in items:
- divider = 1.0/float(item.image.width)
- height_multiplier = float(item.image.height)*divider
- heights.append(height_multiplier)
- heights.sort()
- height_multiplier = heights[0]
+ # calculate the width of the block the image will be in
+ imageset.container_width = width_of_image_container(context, imageset)
+
+ # nice ways to refer to the items and their number
+ imageset.items = imageset.imageset_item.all()
+ number_of_items = imageset.imageset_item.count()
+
+ # =================================== slider =============================
+ # at least three items are required for a slider - just two is unaesthetic
+ if imageset.kind == "slider" and number_of_items > 2:
+ self.render_template = "arkestra_image_plugin/slider.html"
+ width = width_of_image(imageset)
if imageset.aspect_ratio:
- height = width / imageset.aspect_ratio
+ height = imageset.container_width / imageset.aspect_ratio
+ elif imageset.height:
+ height = imageset.height
else:
+ # use the aspect ratio of the widest image
+ heights = []
+ for item in imageset.items:
+ divider = 1.0/float(item.image.width)
+ height_multiplier = float(item.image.height)*divider
+ heights.append(height_multiplier)
+ heights.sort()
+ height_multiplier = heights[0]
height = width * height_multiplier
- size= (int(width),int(height))
- imageset.items = items
+ imageset.size = (int(width),int(height))
context.update({
'imageset':imageset,
- 'icon_size': size,
- # 'image_size': u'%sx%s' % (int(width), int(height)),
- # 'caption_width': int(width),
'placeholder':placeholder,
})
+ # =================================== lightbox =============================
elif imageset.kind == "lightbox":
self.render_template = "arkestra_image_plugin/lightbox.html"
- # set captions
- items = imageset.imageset_item.all()
- for imageset_item in items:
+ # loop over each item to set attributes for the lightbox (i.e. large) image
+ for item in imageset.items:
thumbnail_options = {}
-
# set a caption for the item
- imageset_item.caption = set_image_caption(imageset_item)
-
+ item.caption = set_image_caption(item)
+
# get width, height and lightbox_max_dimension
- [width, height] = [imageset_item.image.width, imageset_item.image.height]
+ lightbox_width, lightbox_height = item.image.width, item.image.height
lightbox_max_dimension = context.get("lightbox_max_dimension")
-
# user has set aspect ratio? apply it, set crop argument for thumbnailer
if imageset.aspect_ratio:
- height = width / imageset.aspect_ratio
+ lightbox_height = lightbox_width / imageset.aspect_ratio
thumbnail_options.update({'crop': True})
-
# get scaler value from width, height
- scaler = min(lightbox_max_dimension / dimension for dimension in [width, height])
-
- # set size of thumbnail using scaler
- thumbnail_options.update({'size': (width * scaler, height * scaler)})
-
+ scaler = min(lightbox_max_dimension / dimension for dimension in [lightbox_width, lightbox_height])
+ # set size of lightbox using scaler
+ thumbnail_options.update({'size': (int(lightbox_width * scaler), int(lightbox_height * scaler))})
# get thumbnailer object for the image
- thumbnailer = get_thumbnailer(imageset_item.image)
-
+ thumbnailer = get_thumbnailer(item.image)
# apply options and get url
- imageset_item.url = thumbnailer.get_thumbnail(thumbnail_options).url
-
- imageset.items = items
- num_of_items = len(items)
-
- # calculate the width of the placeholder
- placeholder_width = get_placeholder_width(context, imageset)
-
- # calculate the width of the block the image will be in
- container_width = calculate_container_width(context, imageset, placeholder_width, auto=True)
-
- # widths a percentage of placeholder width
- if imageset.width <= 100:
- icon_width = (container_width/100 * imageset.width) / num_of_items
- icon_height = imageset.height or icon_width
-
- # automatic width
- else:
- LIGHTBOX_COLUMNS = {2:2, 3:3, 4:4, 5:5, 6:3, 7:4, 8:4, 9:3, 10:5, 11:4, 12:4, 13:5, 14:5, 15:5, 16:4, 17:6, 18:6, 19:5, 20:5, 21:6, 22:6, 23:6, 24:6, 25:5 }
- divider = LIGHTBOX_COLUMNS.get(num_of_items, 6)
- icon_width = container_width / divider
- icon_height = imageset.height or icon_width
-
- # make the icons small enough to fit neatly on a line; if too small, make them bigger
- while icon_width < 30:
- icon_width = icon_width * 2
- icon_height = icon_height / 2
+ item.large_url = thumbnailer.get_thumbnail(thumbnail_options).url
+ # now work out the sizes of the little thumbnails
+ icon_width = imageset.container_width / (imageset.items_per_row or LIGHTBOX_COLUMNS[number_of_items])
+ icon_height = imageset.height or icon_width
+ # make the icons small enough to fit neatly on a line; if too small, make them bigger
+ while icon_width < 30:
+ icon_width = icon_width * 2
+ icon_height = icon_height / 2
+ # fancybox icons have 3px padding, so:
icon_width = icon_width - 6
+ imageset.size = (int(icon_width), int(icon_height))
context.update({
'imageset':imageset,
- 'icon_size': (int(icon_width), int(icon_height)),
'placeholder':placeholder,
})
- # we'll use the basic style
+ # =================================== multiple images =============================
+ elif imageset.kind == "multiple":
+ self.render_template = "arkestra_image_plugin/multiple_images.html"
+
+ items_per_row = imageset.items_per_row or LIGHTBOX_COLUMNS[number_of_items]
+
+ # no specified aspect ratio or height? get an average and use that
+ if not imageset.aspect_ratio and not imageset.height:
+ aspect_ratio = sum([calculate_aspect_ratio(item.image) for item in imageset.items])/number_of_items
+ # use aspect ratio
+ else:
+ aspect_ratio = imageset.aspect_ratio
+
+ # set up each item
+ for counter, item in enumerate(imageset.items, start = 1):
+ # mark end-of-row items so the CSS doesn't apply a margin-right
+ if not counter%items_per_row:
+ item.lastinrow = True
+ # get its width
+ item.width = width_of_image(imageset, item.image)
+ # if we are using automatic/percentage widths, base them on the placeholder
+ if imageset.width > 0:
+ item.width = item.width / items_per_row
+ # calculate height
+ item.width, item.height = calculate_height(imageset.width, imageset.height, imageset.aspect_ratio, item.width, aspect_ratio)
+ if imageset.width> 0:
+ item.width = item.width - (items_per_row-1)*6/items_per_row
+ item.width,item.height = int(item.width), int(item.height)
+ item.icon_size = u'%sx%s' %(item.width, item.height)
+ context.update({
+ 'imageset':imageset,
+ # 'icon_size': u'%sx%s' % (int(width), int(height)),
+ # 'caption_width': int(width),
+ 'placeholder':placeholder,
+ })
+
+ # =================================== single image =============================
else:
self.render_template = "arkestra_image_plugin/single_image.html"
-
# choose an image at random from the set
imageset_item = imageset.imageset_item.order_by('?')[0]
-
- # calculate its width
- width, aspect_ratio = width_of_image(context, imageset, imageset_item.image)
-
+ # calculate its native aspect ratio
+ aspect_ratio = calculate_aspect_ratio(imageset_item.image)
+ # get width
+ width = width_of_image(imageset, imageset_item)
# shave if floated
width = shave_if_floated(imageset, width) or width
# calculate height
- width, height = calculate_height(imageset, width, aspect_ratio)
+ width, height = calculate_height(imageset.width, imageset.height, imageset.aspect_ratio, width, aspect_ratio)
# set caption
imageset_item.caption = set_image_caption(imageset_item)
-
- # print "final output size", width, "x", height
-
+
context.update({
'imageset':imageset,
'imageset_item': imageset_item,
@@ -321,6 +376,7 @@ def render(self, context, imageset, placeholder):
'caption_width': int(width),
'placeholder':placeholder,
})
+
# no items, use a null template
else:
@@ -347,6 +403,54 @@ def icon_src(self, instance):
return "/static/plugin_icons/image_slider.png"
plugin_pool.register_plugin(ImageSetPublisher)
+
+
+class FilerImagePlugin(CMSPluginBase):
+ model = FilerImage
+ name = _("Image")
+ render_template = "cmsplugin_filer_image/image.html"
+ text_enabled = True
+ raw_id_fields = ('image',)
+ admin_preview = False
+
+ def render(self, context, instance, placeholder):
+ self.render_template = "arkestra_image_plugin/single_image.html"
+ instance.has_borders = False
+
+ # calculate its width and aspect ratio
+ image_block_width = width_of_image_container(context, instance)
+ aspect_ratio = calculate_aspect_ratio(instance.image)
+ # shave if floated
+ width = shave_if_floated(instance, image_block_width) or image_block_width
+ # calculate height
+ width, height = calculate_height(instance.width, instance.height, instance.aspect_ratio, image_block_width, aspect_ratio)
+ # set caption
+ instance.caption = set_image_caption(instance)
+
+ context.update({
+ 'object':instance,
+ #'link':instance.link,
+ #'image_url':instance.scaled_image_url,
+ 'image_size': u'%sx%s' % (int(width), int(height)),
+ 'caption_width': int(width),
+ 'placeholder':placeholder,
+
+ 'imageset':instance,
+ 'imageset_item': instance,
+ 'image_size': u'%sx%s' % (int(width), int(height)),
+ 'caption_width': int(width),
+ 'placeholder':placeholder,
+ })
+ return context
+
+ def get_thumbnail(self, context, instance):
+ if instance.image:
+ return instance.image.image.file.get_thumbnail(self._get_thumbnail_options(context, instance))
+
+ def icon_src(self, instance):
+ return instance.image.thumbnails['admin_tiny_icon']
+
+
plugin_pool.register_plugin(FilerImagePlugin)
# gcbirzan's suggestion on how to calculate LIGHTBOX_COLUMNS
45 arkestra_image_plugin/models.py
View
@@ -1,13 +1,20 @@
+from posixpath import join, basename, splitext, exists
+
from django.utils.translation import ugettext_lazy as _
from django.db import models
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.contenttypes import generic
+from django.utils.translation import ugettext_lazy as _
+from django.conf import settings
+
from cms.models import CMSPlugin, Page
from cms.models.fields import PageField
-from django.utils.translation import ugettext_lazy as _
-from posixpath import join, basename, splitext, exists
+from cms import settings as cms_settings
+
from filer.fields.image import FilerImageField
from filer.fields.file import FilerFileField
-from cms import settings as cms_settings
-from django.conf import settings
+
+from links.models import LinkMethodsMixin
class FilerImage(CMSPlugin):
LEFT = "left"
@@ -55,6 +62,8 @@ class FilerImage(CMSPlugin):
)
float = models.CharField(_("float"), max_length=10, blank=True, null=True, choices=FLOAT_CHOICES)
+
+
'''
@property
def scaled_image_url(self):
@@ -84,6 +93,7 @@ def link(self):
class ImageSetPlugin(CMSPlugin):
IMAGESET_KINDS = (
("basic", "Basic"),
+ ("multiple", "Multiple images"),
("lightbox", "LightBox"),
("slider", "Slider"),
)
@@ -105,12 +115,14 @@ class ImageSetPlugin(CMSPlugin):
(-350.0, u'350 pixels'),
)
),
- ('', u"Image's native width"),
+ ('0', u"Image's native width (use with caution)"),
)
- width = models.FloatField(null=True, blank=True, choices = IMAGE_WIDTHS, default = 1000.0)
- height = models.PositiveIntegerField(null=True, blank=True)
+ width = models.FloatField(choices = IMAGE_WIDTHS, default = 1000.0)
+ height = models.PositiveIntegerField(null=True, blank=True,
+ help_text = "Only applies when <strong>Aspect ratio</strong> is <em>Automatic</em>")
+
ASPECT_RATIOS = (
- (0, u'Native'),
+ (0, u'Automatic'),
(3.0, u'3x1'),
(1.778, u'16x9'),
(1.618, u'Golden ratio (horizonal)'),
@@ -123,24 +135,37 @@ class ImageSetPlugin(CMSPlugin):
(0.563, u'16x9'),
(0.3, u'1x3'),
)
- aspect_ratio = models.FloatField(null=True, choices = ASPECT_RATIOS, default = 0)
+ aspect_ratio = models.FloatField(null=True, choices = ASPECT_RATIOS, default = 0,
+ help_text = "<em>Automatic</em> means native aspect ratio will be used where possible and calculated otherwise")
+
LEFT = "left"
RIGHT = "right"
FLOAT_CHOICES = ((LEFT, _("left")),
(RIGHT, _("right")),
)
float = models.CharField(_("float"), max_length=10, blank=True, null=True, choices=FLOAT_CHOICES)
+ items_per_row = models.PositiveSmallIntegerField(blank = True, null = True,
+ help_text = "Only applies to Multiple and Lightbox plugins")
+
+ @property
+ def items_have_links(self):
+ return all(item.destination_content_object is not None for item in self.imageset_item.all())
+
def __unicode__(self):
return u"image-set-%s" % self.kind
-class ImageSetItem(models.Model):
+class ImageSetItem(models.Model, LinkMethodsMixin):
plugin = models.ForeignKey(ImageSetPlugin, related_name="imageset_item")
image = FilerImageField()
alt_text = models.CharField(null=True, blank=True, max_length=255)
use_description_as_caption = models.BooleanField(verbose_name = "Use description", default=False, help_text = "Use image's description field as caption")
caption = models.TextField(_("Caption"), blank=True, null=True)
+ destination_content_type = models.ForeignKey(ContentType, verbose_name="Type", related_name = "links_to_%(class)s", null = True, blank = True)
+ destination_object_id = models.PositiveIntegerField(verbose_name="Item", null = True, blank = True)
+ destination_content_object = generic.GenericForeignKey('destination_content_type', 'destination_object_id')
+
def __unicode__(self):
if self.image:
return self.image.label
2  arkestra_image_plugin/templates/arkestra_image_plugin/lightbox.html
View
@@ -30,4 +30,4 @@
{% endaddtoblock %}
-<div class="fancybox">{% for item in imageset.items %}<a class='{{ class|default:"fancy" }}' rel='{{ rel|default:"gallery_1" }}' href="{{ item.url}}" title='{{ item.caption|default:"" }}'><img class="fancybox-icon" alt="" src="{% thumbnail item.image icon_size crop subject_location=image.subject_location %}" /></a>{% endfor %}</div>
+<div class="fancybox" style="width: {{ imageset.container_width }}px;">{% for item in imageset.items %}<a class='{{ class|default:"fancy" }}' rel='{{ rel|default:"gallery_1" }}' href="{{ item.large_url}}" title='{{ item.caption|default:"" }}'><img class="fancybox-icon" alt="" src="{% thumbnail item.image imageset.size crop subject_location=image.subject_location %}" /></a>{% endfor %}</div>
5 arkestra_image_plugin/templates/arkestra_image_plugin/multiple_images.html
View
@@ -0,0 +1,5 @@
+{% load thumbnail %}
+
+<ul class="multiple-images" style="width: {{ imageset.container_width }}px;">
+{% for item in imageset.items %}<li {% if item.lastinrow %}class="lastinrow"{% endif %}><img alt="" src="{% thumbnail item.image item.icon_size crop subject_location=image.subject_location %}" /></li>{% endfor %}
+</ul>
19 arkestra_image_plugin/templates/arkestra_image_plugin/single_image.html
View
@@ -1,7 +1,12 @@
-{% load thumbnail filer_tags filer_image_tags %}{% spaceless %}
-<span class = "image {{imageset.float}}"><img alt="{% if imageset_item.alt %}{{ imageset_item.alt }}{% endif %}" class="plugin" src="{% thumbnail imageset_item.image.file image_size crop subject_location=imageset_item.image.subject_location %}" />
- {% if imageset_item.caption %}<span style="width: {{caption_width}}px" class="image_caption">{{ imageset_item.caption }}</span>{% endif %}
- {% if imageset_item.show_author %}
- <span class="image_author">(Author: {{ imageset_item.image.author }})</span>
- {% endif %}
-</span>{% endspaceless %}
+{% load thumbnail filer_tags filer_image_tags %}
+{% spaceless %}
+ <span class = "image {{imageset.float}}">
+ {% if imageset_item.url %}<a href="{{ imageset_item.url }}">{% endif %}
+ <img alt="{% if imageset_item.alt %}{{ imageset_item.alt }}{% endif %}" class="plugin" src="{% thumbnail imageset_item.image.file image_size crop subject_location=imageset_item.image.subject_location %}" />
+ {% if imageset_item.url %}</a>{% endif %}
+ {% if imageset_item.caption %}<span style="width: {{caption_width}}px" class="image_caption">{{ imageset_item.caption }}</span>{% endif %}
+ {% if imageset_item.show_author %}
+ <span class="image_author">(Author: {{ imageset_item.image.author }})</span>
+ {% endif %}
+ </span>
+{% endspaceless %}
6 arkestra_image_plugin/templates/arkestra_image_plugin/slider.html
View
@@ -1,7 +1,7 @@
{% load sekizai_tags thumbnail %}
<ul id="{{ imageset|default:"slider"}}">
{% for item in imageset.items %}
- <li><img src="{% thumbnail item.image icon_size crop subject_location=item.image.subject_location %}" alt=""></li>
+ <li><img src="{% thumbnail item.image imageset.size crop subject_location=item.image.subject_location %}" alt=""></li>
{% endfor %}
</ul>
@@ -12,8 +12,8 @@
<link rel="stylesheet" href="{{ STATIC_URL }}slider/css/theme-minimalist-square.css">
<style>
#{{ imageset|default:"slider"}} {
- width: {{ icon_size.0 }}px;
- height: {{ icon_size.1 }}px;
+ width: {{ imageset.size.0 }}px;
+ height: {{ imageset.size.1 }}px;
list-style: none;
/* Prevent FOUC (see FAQ page) and keep things readable if javascript is disabled */
overflow-y: auto;
1  arkestra_utilities/output_libraries/plugin_widths.py
View
@@ -27,7 +27,6 @@ def get_placeholder_width(context, plugin):
placeholder_width = context.get("placeholder_width")
placeholder_width = placeholder_width or context.get("width")
placeholder_width = float(placeholder_width or 100.0)
- # placeholder_width = float(context.get("placeholder_width", context.get("width", 100.0)))
# run all registered placeholder_width modifiers
for cls in adjuster_pool.adjusters["placeholder_width"]:
10 arkestra_utilities/static/arkestra/css/arkestra_images.css
View
@@ -1,4 +1,12 @@
-/* Navigation Links */
+/* Arkestra image plugin */
+
+ul.multiple-images {padding: 0; margin: 0;}
+ul.multiple-images li {display: inline-block; margin-right: 6px;}
+ul.multiple-images li.lastinrow {margin-right: 0px;}
+
+/* Slider
+
+Navigation Links */
body div.anythingSlider-minimalist-square .anythingControls {
float: right;
position: relative;
Please sign in to comment.
Something went wrong with that request. Please try again.