Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZO-6370: add image grid module to vivi #904

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions core/src/zeit/content/article/edit/browser/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -827,4 +827,47 @@
permission="zope.View"
/>

<!-- ImageRow -->


<browser:viewlet
for="zeit.content.article.edit.interfaces.IImageRow"
layer="zeit.cms.browser.interfaces.ICMSLayer"
view="zope.interface.Interface"
manager="zeit.edit.interfaces.IContentViewletManager"
name="edit-image-row"
class="zeit.edit.browser.form.FormLoader"
permission="zope.View"
/>

<browser:page
for="zeit.content.article.edit.interfaces.IImageRow"
layer="zeit.cms.browser.interfaces.ICMSLayer"
name="edit-image-row"
class=".edit.EditImageRow"
permission="zope.View"
/>

<!-- ImageGrid -->


<browser:viewlet
for="zeit.content.article.edit.interfaces.IImageGrid"
layer="zeit.cms.browser.interfaces.ICMSLayer"
view="zope.interface.Interface"
manager="zeit.edit.interfaces.IContentViewletManager"
name="edit-image-grid"
class="zeit.edit.browser.form.FormLoader"
permission="zope.View"
/>

<browser:page
for="zeit.content.article.edit.interfaces.IImageGrid"
layer="zeit.cms.browser.interfaces.ICMSLayer"
name="edit-image-grid"
class=".edit.EditImageGrid"
permission="zope.View"
/>


</configure>
44 changes: 44 additions & 0 deletions core/src/zeit/content/article/edit/browser/edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -575,3 +575,47 @@ class EditAnimation(zeit.cms.browser.manual.FormMixin, zeit.edit.browser.form.In
@property
def prefix(self):
return 'animation.{0}'.format(self.context.__name__)


class EditImageRow(zeit.edit.browser.form.InlineForm):
legend = ''
form_fields = zope.formlib.form.FormFields(zeit.content.article.edit.interfaces.IImageRow).omit(
*list(zeit.edit.interfaces.IBlock)
)

@property
def prefix(self):
return 'image_row.{0}'.format(self.context.__name__)


class EditImageGrid(zeit.edit.browser.form.InlineForm):
legend = ''
omitted_fields_prefix = ['images_', 'display_mode_', 'variant_name_']
form_fields = zope.formlib.form.FormFields(
zeit.content.article.edit.interfaces.IImageGrid
).omit(*list(zeit.edit.interfaces.IBlock))
_all_form_fields = form_fields

@property
def prefix(self):
return 'image_grid.{0}'.format(self.context.__name__)

def setUpWidgets(self, *args, **kw):
super().setUpWidgets(*args, **kw)
image_groups_lengths = [getattr(self.context, f'images_{i}', 0) for i in range(0, 4)]
print(image_groups_lengths)
first_empty_group = next(
(i for i, item in enumerate(image_groups_lengths) if len(item) == 0), None
)
print(f'first_empty_group: {first_empty_group}')
# All groups are filled!
if first_empty_group is None:
self.form_fields = self._all_form_fields
return
omitted_fields = [
f'{prefix}{j}'
for prefix in self.omitted_fields_prefix
for j in range(first_empty_group + 1, 4)
]
print(omitted_fields)
self.form_fields = self._all_form_fields.omit(*omitted_fields)
22 changes: 22 additions & 0 deletions core/src/zeit/content/article/edit/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,28 @@
/>
</class>

<class class=".image_row.ImageRow">
<require
interface=".interfaces.IImageRow"
permission="zope.View"
/>
<require
set_schema=".interfaces.IImageRow"
permission="zeit.EditContent"
/>
</class>

<class class=".image_grid.ImageGrid">
<require
interface=".interfaces.IImageGrid"
permission="zope.View"
/>
<require
set_schema=".interfaces.IImageGrid"
permission="zeit.EditContent"
/>
</class>

<utility factory=".videotagesschau.from_product_config" zcml:condition="not-have zeit.cms.testing" />
<utility factory="zeit.content.article.edit.videotagesschau.MockVideoTagesschau" zcml:condition="have zeit.cms.testing" />

Expand Down
54 changes: 54 additions & 0 deletions core/src/zeit/content/article/edit/image_grid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import grokcore.component as grok
import lxml

from zeit.cms.content.property import ObjectPathAttributeProperty
from zeit.cms.i18n import MessageFactory as _
import zeit.cms.content.property
import zeit.cms.content.reference
import zeit.content.article.edit.block
import zeit.content.article.edit.interfaces


@grok.implementer(zeit.content.article.edit.interfaces.IImageGrid)
class ImageGrid(zeit.content.article.edit.block.Block):
type = 'image_grid'

def __init__(self, context, xml):
# call base constructor
super(ImageGrid, self).__init__(context, xml)
for i in range(4):
if not self.xml.xpath('//group%s' % i):
self.xml.append(lxml.etree.Element('group%s' % i))

show_caption = ObjectPathAttributeProperty(
'.', 'show_caption', zeit.content.article.edit.interfaces.IImageRow['show_caption']
)
show_source = ObjectPathAttributeProperty(
'.', 'show_source', zeit.content.article.edit.interfaces.IImageRow['show_source']
)

# Images and display properties for first group
images_0 = zeit.cms.content.reference.MultiResource('.group0.image', 'image')
image_0 = zeit.cms.content.property.SingleResource('.image')
display_mode_0 = ObjectPathAttributeProperty('.group0', 'display_mode_0')
variant_name_0 = ObjectPathAttributeProperty('.group0', 'variant_name_0')

# Images and display properties for second group
images_1 = zeit.cms.content.reference.MultiResource('.group1.image', 'image')
display_mode_1 = ObjectPathAttributeProperty('.group1', 'display_mode_1')
variant_name_1 = ObjectPathAttributeProperty('.group1', 'variant_name_1')

# Images and display properties for second group
images_2 = zeit.cms.content.reference.MultiResource('.group2.image', 'image')
display_mode_2 = ObjectPathAttributeProperty('.group2', 'display_mode_2')
variant_name_2 = ObjectPathAttributeProperty('.group2', 'variant_name_2')

# Images and display properties for third group
images_3 = zeit.cms.content.reference.MultiResource('.group3.image', 'image')
display_mode_3 = ObjectPathAttributeProperty('.group3', 'display_mode_3')
variant_name_3 = ObjectPathAttributeProperty('.group3', 'variant_name_3')


class Factory(zeit.content.article.edit.block.BlockFactory):
produces = ImageGrid
title = _('Image Grid')
74 changes: 74 additions & 0 deletions core/src/zeit/content/article/edit/image_row.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import grokcore.component as grok
import lxml

from zeit.cms.content.property import ObjectPathAttributeProperty
from zeit.cms.i18n import MessageFactory as _
from zeit.content.article.source import LEGACY_DISPLAY_MODE_SOURCE, LEGACY_VARIANT_NAME_SOURCE
import zeit.cms.content.property
import zeit.cms.content.reference
import zeit.content.article.edit.block
import zeit.content.article.edit.interfaces


@grok.implementer(zeit.content.article.edit.interfaces.IImageRow)
class ImageRow(zeit.content.article.edit.block.Block):
def __init__(self, context, xml):
# call base constructor
super(ImageRow, self).__init__(context, xml)
# set xml object to default template, if it has no body
if not self.xml.xpath('//body'):
self.xml.append(lxml.etree.Element('body'))

type = 'image_row'

show_caption = ObjectPathAttributeProperty(
'.', 'show_caption', zeit.content.article.edit.interfaces.IImageRow['show_caption']
)
show_source = ObjectPathAttributeProperty(
'.', 'show_source', zeit.content.article.edit.interfaces.IImageRow['show_source']
)
_display_mode = zeit.cms.content.property.ObjectPathAttributeProperty('.', 'display_mode')
_variant_name = zeit.cms.content.property.ObjectPathAttributeProperty('.', 'variant_name')
images = zeit.cms.content.reference.MultiResource('.body.image', 'image')

@property
def display_mode(self):
if self._display_mode is not None:
return self._display_mode
# backward compatibility by mapping old layout to display_mode
layout = self.xml.get('layout', None)
mapping = dict(list(LEGACY_DISPLAY_MODE_SOURCE(self)))
return mapping.get(
layout, zeit.content.article.edit.interfaces.IImage['display_mode'].default
)

@display_mode.setter
def display_mode(self, value):
self._display_mode = value

@property
def variant_name(self):
if self._variant_name is not None:
return self._variant_name
# backward compatibility by mapping old layout to display_mode
layout = self.xml.get('layout', None)
mapping = dict(list(LEGACY_VARIANT_NAME_SOURCE(self)))
return mapping.get(
layout, zeit.content.article.edit.interfaces.IImage['variant_name'].default
)

@variant_name.setter
def variant_name(self, value):
self._variant_name = value

# first_image = zeit.cms.content.reference.SingleResource('.image[1]', 'image')
# second_image = zeit.cms.content.reference.SingleResource('.image[2]', 'image')
# third_image = zeit.cms.content.reference.SingleResource('.image[3]', 'image')
# first_image = zeit.cms.content.reference.SingleResource('.image-1', 'image')
# second_image = zeit.cms.content.reference.SingleResource('.image-2', 'image')
# third_image = zeit.cms.content.reference.SingleResource('.image-3', 'image')


class Factory(zeit.content.article.edit.block.BlockFactory):
produces = ImageRow
title = _('Image Row')
119 changes: 119 additions & 0 deletions core/src/zeit/content/article/edit/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -653,3 +653,122 @@ class IIngredientDice(IBlock):
"""

pass


IMAGE_COUNT = 4 # Define the number of image sets in the image grid


class IImageRow(IBlock):
show_caption = zope.schema.Bool(title=_('Show caption'), required=False, default=True)
show_source = zope.schema.Bool(title=_('Show source'), required=False, default=True)
images = zope.schema.Tuple(
title=_('Images'),
default=(),
max_length=3,
required=False,
value_type=zope.schema.Choice(source=zeit.content.image.interfaces.ImageGroupSource()),
)
display_mode = zope.schema.Choice(
title=_('Display Mode'),
source=zeit.content.article.source.IMAGE_DISPLAY_MODE_SOURCE,
default='column-width',
required=False,
)
# Currently need default for bw compat.
variant_name = zope.schema.Choice(
title=_('Variant Name'),
source=zeit.content.article.source.IMAGE_VARIANT_NAME_SOURCE,
default='wide',
required=False,
)


class IImageGrid(IBlock):
show_caption = zope.schema.Bool(title=_('Show caption'), required=False, default=True)
show_source = zope.schema.Bool(title=_('Show source'), required=False, default=True)
images_0 = zope.schema.Tuple(
title=_('Images'),
default=(),
max_length=3,
required=False,
value_type=zope.schema.Choice(source=zeit.content.image.interfaces.ImageGroupSource()),
)
display_mode_0 = zope.schema.Choice(
title=_('Display Mode'),
source=zeit.content.article.source.IMAGE_DISPLAY_MODE_SOURCE,
default='column-width',
required=False,
)
image_0 = zope.schema.Choice(
title=_('Image'),
description=_('Drag an image group here'),
required=False,
source=zeit.content.image.interfaces.imageGroupSource,
)
# Currently need default for bw compat.
variant_name_0 = zope.schema.Choice(
title=_('Variant Name'),
source=zeit.content.article.source.IMAGE_VARIANT_NAME_SOURCE,
default='wide',
required=False,
)
images_1 = zope.schema.Tuple(
title=_('Images'),
default=(),
max_length=3,
required=False,
value_type=zope.schema.Choice(source=zeit.content.image.interfaces.ImageGroupSource()),
)
display_mode_1 = zope.schema.Choice(
title=_('Display Mode'),
source=zeit.content.article.source.IMAGE_DISPLAY_MODE_SOURCE,
default='column-width',
required=False,
)
# Currently need default for bw compat.
variant_name_1 = zope.schema.Choice(
title=_('Variant Name'),
source=zeit.content.article.source.IMAGE_VARIANT_NAME_SOURCE,
default='wide',
required=False,
)
images_2 = zope.schema.Tuple(
title=_('Images'),
default=(),
max_length=3,
required=False,
value_type=zope.schema.Choice(source=zeit.content.image.interfaces.ImageGroupSource()),
)
display_mode_2 = zope.schema.Choice(
title=_('Display Mode'),
source=zeit.content.article.source.IMAGE_DISPLAY_MODE_SOURCE,
default='column-width',
required=False,
)
# Currently need default for bw compat.
variant_name_2 = zope.schema.Choice(
title=_('Variant Name'),
source=zeit.content.article.source.IMAGE_VARIANT_NAME_SOURCE,
default='wide',
required=False,
)
images_3 = zope.schema.Tuple(
title=_('Images'),
default=(),
max_length=3,
required=False,
value_type=zope.schema.Choice(source=zeit.content.image.interfaces.ImageGroupSource()),
)
display_mode_3 = zope.schema.Choice(
title=_('Display Mode'),
source=zeit.content.article.source.IMAGE_DISPLAY_MODE_SOURCE,
default='column-width',
required=False,
)
# Currently need default for bw compat.
variant_name_3 = zope.schema.Choice(
title=_('Variant Name'),
source=zeit.content.article.source.IMAGE_VARIANT_NAME_SOURCE,
default='wide',
required=False,
)
2 changes: 2 additions & 0 deletions core/src/zeit/content/article/edit/tests/modules.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@
<module id="video">Video</module>
<module id="volume">Ausgabe</module>
<module id="videotagesschau">ARD Video</module>
<module id="image_row">Bilderreihe</module>
<module id="image_grid">Bilder-Grid</module>
</modules>