Пример #1
0
 def __call__(self, redirect=''):
     self.context.reload_image_folder()
     self.send_message(_('Image folder was synchronised.'))
     url = self.url('@@overview.html')
     if redirect.lower() != 'false':
         self.redirect(url)
     return url
Пример #2
0
 def _toFieldValue(self, value):
     value = super(SolrQueryWidget, self)._toFieldValue(value)
     try:
         zeit.find.search.search(value, rows=1)
     except pysolr.SolrError:
         raise zope.formlib.interfaces.ConversionError(
             _('Invalid solr query'), value)
     return value
Пример #3
0
 def _check_duplicate_item(self, folder, name):
     if name in folder:
         transaction.doom()
         self.errors = (DuplicateVolumeWarning(),)
         self.status = _('There were errors')
         self.form_reset = False
         return True
     return False
Пример #4
0
 def ask_before_adding_author_twice(self, author):
     if self.confirmed_duplicate or not author.exists:
         return False
     transaction.doom()
     self.need_confirmation_checkbox = True
     self.errors = (DuplicateAuthorWarning(),)
     self.status = _('There were errors')
     self.form_reset = False
     return True
Пример #5
0
class TargetSource(zc.sourcefactory.basic.BasicSourceFactory):

    values = {'_blank': _('New window')}

    def getValues(self):
        return ('_blank', )

    def getTitle(self, value):
        return self.values.get(value, value)
Пример #6
0
 def __call__(self):
     parent = self.context.__parent__
     title = self.context.title
     del parent[self.context.__name__]
     self.send_message(
         _('"${name}" was removed from the clipboard.',
           mapping=dict(name=title)))
     self.redirect(self.url(parent))
     return u''
Пример #7
0
 def __call__(self, unique_id):
     source = zeit.cms.interfaces.ICMSContent(unique_id)
     copier = zope.copypastemove.interfaces.IObjectCopier(source)
     new_name = copier.copyTo(self.context)
     new_obj = self.context[new_name]
     self.send_message(
         _('${source} was copied to ${target}.',
           mapping=dict(source=unique_id, target=new_obj.uniqueId)))
     self.redirect(self.url(new_obj))
Пример #8
0
class SocialEditForm(SocialBase, zeit.cms.browser.form.EditForm):

    form_fields = zope.formlib.form.FormFields()

    @zope.formlib.form.action(_('Apply'),
                              condition=zope.formlib.form.haveInputWidgets)
    def handle_edit_action(self, action, data):
        self.applyAccountData(self.context, data)
        super(SocialEditForm, self).handle_edit_action.success(data)
Пример #9
0
class FormBase(zeit.cms.browser.form.CharlimitMixin):

    _form_fields = zope.formlib.form.FormFields(
        zeit.content.author.interfaces.IAuthor,
        zeit.cms.interfaces.ICMSContent)
    omit_fields = []

    field_groups = (
        gocept.form.grouped.Fields(_("Contact"),
                                   ('title', 'firstname', 'lastname', 'email',
                                    'twitter', 'facebook', 'instagram'),
                                   css_class='column-left'),
        gocept.form.grouped.RemainingFields(_("misc."),
                                            css_class='column-right'),
        gocept.form.grouped.Fields(
            _("Author Favourites"),
            ('favourite_content', 'topiclink_label_1', 'topiclink_url_1',
             'topiclink_label_2', 'topiclink_url_2', 'topiclink_label_3',
             'topiclink_url_3'),
            css_class='wide-widgets column-left'),
    )

    def __init__(self, context, request):
        super(FormBase, self).__init__(context, request)
        self.form_fields = self._form_fields.omit(*self.omit_fields)

        source = zeit.content.author.interfaces.BIOGRAPHY_QUESTIONS(
            self.context)
        for name in source:
            field = zope.schema.Text(title=source.title(name), required=False)
            field.__name__ = name
            field.interface = (
                zeit.content.author.interfaces.IBiographyQuestions)
            self.form_fields += zope.formlib.form.FormFields(field)

        self.field_groups += (gocept.form.grouped.Fields(
            _("Biography"), ('summary', 'biography') + tuple(source),
            css_class='wide-widgets full-width'), )

    def setUpWidgets(self, *args, **kw):
        super(FormBase, self).setUpWidgets(*args, **kw)
        for field in self.form_fields:
            if getattr(field.field, 'max_length', None):
                self.set_charlimit(field.__name__)
Пример #10
0
 def doc(self):
     text, encoding, e = self.args
     return _(
         'Could not encode charachters ${start}-${end} to ${encoding} '
         '(${characters}): ${reason}',
         mapping=dict(start=e.start,
                      end=e.end,
                      encoding=encoding,
                      characters=text[e.start:e.end],
                      reason=e.reason))
Пример #11
0
class AreaFactory(zeit.edit.block.ElementFactory):

    grok.context(zeit.content.cp.interfaces.IRegion)
    produces = Area
    # XML tags are named "region", thus do not change.
    tag_name = 'region'
    title = _('Area')

    def get_xml(self):
        return getattr(lxml.objectify.E, self.tag_name)()
Пример #12
0
class ImageBrowser(object):

    title = _("Images")

    def images(self):
        for obj in self.context.values():
            if not zeit.content.image.interfaces.IImage.providedBy(obj):
                continue
            metadata = zeit.content.image.interfaces.IImageMetadata(obj)
            yield dict(image=obj, metadata=metadata)
Пример #13
0
class ICMSContent(zope.interface.Interface):
    """Interface for all CMS content being loaded from the repository.

    """

    uniqueId = zope.interface.Attribute("Unique Id")

    __name__ = zope.schema.TextLine(title=_("File name"),
                                    readonly=True,
                                    constraint=valid_name)
Пример #14
0
 def canCheckin(self):
     if not zeit.cms.workingcopy.interfaces.ILocalContent.providedBy(
             self.context):
         self.last_validation_error = _('Object is not local content')
         return False
     lockable = zope.app.locking.interfaces.ILockable(self.context, None)
     if (lockable is not None and not lockable.ownLock()
             and lockable.locked()):
         self.last_validation_error = _('Cannot acquire lock')
         return False
     workingcopy = self.context.__parent__
     if not workingcopy.temporary:
         event = zeit.cms.checkout.interfaces.ValidateCheckinEvent(
             self.context, workingcopy, self.principal)
         zope.event.notify(event)
         self.last_validation_error = event.vetoed
         if self.last_validation_error is not None:
             return False
     return True
Пример #15
0
class RecensionForms(zeit.edit.browser.form.FoldableFormGroup):
    """Article recension forms."""

    title = _('Recensions')

    def render(self):
        if not zeit.cms.checkout.interfaces.ILocalContent.providedBy(
                self.context):
            return ''
        return super(RecensionForms, self).render()
Пример #16
0
 def cell_formatter(self, value, item, formatter):
     img = zope.component.getMultiAdapter(
         (value, formatter.request),
         name='preview').tag()
     master = ''
     if zeit.content.image.interfaces.IMasterImage.providedBy(value):
         master = '<div class="master-image">%s</div>' % (
             zope.i18n.translate(_('Master image'),
                                 context=formatter.request))
     return img + master
Пример #17
0
class EditJobTicker(zeit.edit.browser.form.InlineForm):

    legend = ''
    undo_description = _('edit jobbox ticker')
    form_fields = zope.formlib.form.FormFields(
        zeit.content.article.edit.interfaces.IJobTicker).select('feed')

    @property
    def prefix(self):
        return 'jobticker.{0}'.format(self.context.__name__)
Пример #18
0
class FeedType(zeit.cms.type.XMLContentTypeDeclaration):

    interface = zeit.cms.syndication.interfaces.IFeed
    factory = Feed
    type = 'channel'
    title = _('Channel')
    addform = 'zeit.cms.syndication.feed.Add'

    def register_as_type(self, config):
        return config.hasFeature('zeit.cms.decentral-syndication')
Пример #19
0
class View(zeit.cms.browser.listing.Listing):

    title = _('Image group')
    filter_interface = zeit.content.image.interfaces.IImage

    columns = (
        zeit.cms.browser.listing.LockedColumn(u'', name='locked'),
        zeit.cms.browser.listing.GetterColumn(
            title=_("File name"),
            # zc.table can't deal with spaces in colum names
            name='filename',
            getter=lambda i, f: i.__name__),
        zeit.cms.browser.listing.GetterColumn(
            title=_('Dimensions'),
            getter=lambda i, f: i.context.getImageSize(),
            cell_formatter=lambda v, i, f: 'x'.join(str(i) for i in v)),
        ImageColumn(title=_('Image')),
        zeit.cms.browser.listing.MetadataColumn(u'Metadaten', name='metadata'),
    )
Пример #20
0
class CheckoutMenuItem(MenuItem):
    """MenuItem for checking out."""

    title = _('Checkout ^O')
    base_action = 'checkout'
    accesskey = 'o'

    def is_visible(self):
        manager = zeit.cms.checkout.interfaces.ICheckoutManager(self.context)
        return manager.canCheckout
Пример #21
0
class StudyCourse(zeit.edit.browser.form.InlineForm):

    legend = ''
    undo_description = _('edit study course')
    form_fields = zope.formlib.form.FormFields(
        zeit.campus.interfaces.IStudyCourse).select('course')

    @property
    def prefix(self):
        return 'studycourse.{0}'.format(self.context.__name__)
Пример #22
0
 def __call__(self):
     return (u'<input type="text" class="autocomplete" '
             u'placeholder={placeholder} '
             u'cms:autocomplete-source="{url}" />').format(
                 url=zope.component.queryMultiAdapter(
                     (self.source, self.request),
                     zeit.cms.browser.interfaces.ISourceQueryURL),
                 placeholder=xml.sax.saxutils.quoteattr(
                     zope.i18n.translate(_('Type to find entries ...'),
                                         context=self.request)))
Пример #23
0
class IAdjustSemanticPublish(zope.interface.Interface):
    """Schema for admin form to adjust date_last_published_semantic.

    Setting date_last_published_semantic to another date is not enough, since
    has_semantic_change and last_semantic_change might need changes as well.
    Therefore we use this separate interface and take care of all attributes in
    one place.

    """

    adjust_semantic_publish = zope.schema.Datetime(
        title=_('Adjust last published with semantic change'),
        required=False,
        max=zeit.cms.interfaces.MAX_PUBLISH_DATE)

    adjust_first_released = zope.schema.Datetime(
        title=_('Adjust first released'),
        required=False,
        max=zeit.cms.interfaces.MAX_PUBLISH_DATE)
Пример #24
0
 def log_success(self):
     self.object_log.log(
         _(
             'Push notification for "${name}" sent.'
             ' (Message: "${message}", Details: ${details})',
             mapping={
                 'name': self.type.capitalize(),
                 'message': self.text,
                 'details': self.log_message_details
             }))
Пример #25
0
 def update(self):
     self.undo_description = _(
         "add '${type}' block",
         mapping=dict(type=self.type))
     factory = zope.component.getAdapter(
         self.context, zeit.edit.interfaces.IElementFactory,
         name=self.type)
     created = factory()
     self.reload()
     self.signal('after-reload', 'added', created.__name__)
Пример #26
0
class AssetWorkflow(WorkflowForm):

    zope.component.adapts(zeit.cms.interfaces.IAsset,
                          zeit.cms.browser.interfaces.ICMSLayer)

    field_groups = (gocept.form.grouped.Fields(_("Status"),
                                               WorkflowForm.modified_fields,
                                               css_class='column-left'),
                    gocept.form.grouped.RemainingFields(
                        _("Settings"), css_class='column-right'),
                    gocept.form.grouped.Fields(_("Log"),
                                               fields=('logs', ),
                                               css_class='full-width'))

    form_fields = (zope.formlib.form.FormFields(
        zeit.workflow.interfaces.IAssetWorkflow,
        zeit.objectlog.interfaces.ILog, zeit.cms.workflow.interfaces.IModified,
        zeit.cms.content.interfaces.ISemanticChange).omit(
            *WorkflowForm.omit_fields))
Пример #27
0
class EditFormCO(zeit.cms.browser.form.EditForm):

    form_fields = zope.formlib.form.Fields(
        zeit.cms.content.interfaces.ICommonMetadata).select(
            'banner', 'banner_content', 'banner_outer',
            'hide_adblocker_notification')

    # Without field group it will look weird when context is an Article.
    field_groups = (gocept.form.grouped.RemainingFields(
        _('admin-field-group'), 'column-left-small'), )
Пример #28
0
 def __call__(self, unique_id, view=''):
     obj = zeit.cms.interfaces.ICMSContent(unique_id, None)
     if obj is None:
         msg = _("The object '${id}' could not be found.",
                 mapping=dict(id=unique_id))
         return '<div class="error">%s</div>' % zope.i18n.translate(
             msg, context=self.request)
     self.request.response.setHeader('Cache-Control', 'no-cache')
     self.redirect(self.url(obj, view), status=301)
     return u''
Пример #29
0
class IVideo(zeit.edit.interfaces.IBlock, ILayoutable):

    video = zope.schema.Choice(
        title=_('Video'),
        description=_("Drag a video here"),
        required=False,
        source=zeit.content.video.interfaces.videoOrPlaylistSource)

    layout = zope.schema.Choice(title=_('Layout'),
                                source=VideoLayoutSource(),
                                default=u'large',
                                required=False)

    # XXX it would be nice if could somehow express that IVideo actually
    # is a kind of IReference (only it has video/video_2 instead of references)
    is_empty = zope.schema.Bool(
        title=_('true if this block has no reference; benefits XSLT'),
        required=False,
        default=True)
Пример #30
0
class IAccessCounter(zope.interface.Interface):
    """Give information about how many times an object was accessed."""

    hits = zope.schema.Int(
        title=_('Hits today'),
        description=_('Indicates how many times a page viewed today.'),
        required=False,
        default=None)

    total_hits = zope.schema.Int(
        title=_('Total hits'),
        description=_('Indicates how many times a page was viewed in total, '
                      'i.e. during its entire life time.'),
        required=False,
        default=None)

    detail_url = zope.schema.URI(title=_('URI to the access counting details'),
                                 required=False,
                                 default=None)
Пример #31
0
class IContentAdder(zope.interface.Interface):

    type_ = zope.schema.Choice(
        title=_("Type"),
        source=zeit.cms.content.sources.AddableCMSContentTypeSource())

    ressort = zope.schema.Choice(
        title=_("Ressort"),
        source=zeit.cms.content.sources.RessortSource(),
        required=False)

    sub_ressort = zope.schema.Choice(
        title=_('Sub ressort'),
        source=zeit.cms.content.sources.SubRessortSource(),
        required=False)

    year = zope.schema.Int(title=_("Year"), min=1900, max=2100)

    month = zope.schema.Int(title=_("Month"), min=1, max=12)
Пример #32
0
    def publish(self, priority=None, background=True, **kw):
        """Publish object."""
        info = zeit.cms.workflow.interfaces.IPublishInfo(self.context)
        if info.can_publish() == CAN_PUBLISH_ERROR:
            raise zeit.cms.workflow.interfaces.PublishingError(
                "Publish pre-conditions not satisifed.")

        return self._execute_task(
            PUBLISH_TASK, [self.context.uniqueId], priority, background,
            _('Publication scheduled'), **kw)
Пример #33
0
class QueryTypeSource(SimpleDictSource):

    values = collections.OrderedDict([
        ('channels', _('query-type-channels')),
        ('serie', _('query-type-serie')),
        ('product', _('query-type-product')),
        ('ressort', _('query-type-ressort')),
        ('genre', _('query-type-genre')),
        ('authorships', _('query-type-authorships')),
        ('access', _('query-type-access')),
        ('content_type', _('query-type-content-type')),
    ])
Пример #34
0
class IPushMessages(zope.interface.Interface):
    """Configures push services that are notified if context is published.

    Available services are stored in `message_config` on checkin of context.
    When the context is published, send a push notification for each stored
    service whose configuration defines it as `enabled` by looking up a named
    `IMessage` adapter that forwards the actual push to an `IPushNotifier`
    utility.

    """

    date_last_pushed = zope.schema.Datetime(title=_('Last push'),
                                            required=False,
                                            readonly=True)

    # BBB deprecated, Facebook texts are now stored per account in
    # message_config.
    long_text = zope.schema.Text(title=_('Long push text'), required=False)
    short_text = zope.schema.TextLine(
        title=_('Short push text'),
        required=False,
        # 117 + 1 Space + 23 characters t.co-URL = 140
        #
        # XXX It's not yet clear what we can do when the user enters another
        # URL as part of the tweet and that URL gets *longer* during the
        # shortening process.
        max_length=116)
    """A message configuration is a dict with at least the following keys:
       - type: Kind of service (twitter, facebook, ...). Must correspond
         to the utility name of an IPushNotifier.
       - enabled: Boolean. This allows keeping the message configuration even
         when it should not be used at the moment, e.g. for different text to
         different accounts.

    Any other keys are type-dependent. (A common additional key is ``account``,
    e.g. Twitter and Facebook support posting to different accounts.)

    """
    message_config = zope.schema.Tuple(required=False, default=())

    messages = zope.interface.Attribute(
        'List of IMessage objects, one for each enabled message_config entry')
Пример #35
0
Файл: xml.py Проект: louika/vivi
class XMLBlockFactory(zeit.content.cp.blocks.block.BlockFactory):

    produces = XMLBlock
    title = _('Raw XML block')

    def get_xml(self):
        container = super(XMLBlockFactory, self).get_xml()
        raw = lxml.objectify.E.raw(u'\n\n\n')
        lxml.objectify.deannotate(raw)
        container.append(raw)
        return container
Пример #36
0
    def action_set_copyrights(self, action, data):
        changed = []
        for name in self.context:
            obj = self.context[name]
            metadata = zeit.content.image.interfaces.IImageMetadata(obj, None)
            if metadata is None:
                continue
            zeit.cms.checkout.helper.with_checked_out(obj, lambda x: self.set_copyrights(x, data["copyrights"]))
            changed.append(name)

        self.send_message(_("Copyright changed for: ${changes}", mapping=dict(changes=", ".join(changed))))
Пример #37
0
def prevent_mismatched_checkout(context, event):
    other_iface = zeit.content.cp.interfaces.ICP2009
    current_iface = zeit.content.cp.interfaces.ICP2015
    if other_iface.providedBy(context):
        raise zeit.cms.checkout.interfaces.CheckinCheckoutError(
            context.uniqueId, _(
                'The centerpage ${uniqueId} is of type ${content_type},'
                ' but this vivi handles ${current_type}.', mapping={
                    'uniqueId': context.uniqueId,
                    'content_type': other_iface.__name__,
                    'current_type': current_iface.__name__,
                }))
Пример #38
0
 def initialize_block(self):
     content = zeit.cms.interfaces.ICMSContent(self.uniqueId, None)
     if content is None:
         raise ValueError(
             _('The object "${name}" does not exist.', mapping=dict(
                 name=self.uniqueId)))
     self.block.insert(0, content)
     if self.relateds:
         related = zeit.cms.related.interfaces.IRelatedContent(
             content, None)
         if related is not None:
             for i, related in enumerate(related.related):
                 self.block.insert(i + 1, related)
Пример #39
0
    def __init__(self, context, request):
        super(FormBase, self).__init__(context, request)
        self.form_fields = self._form_fields.omit(*self.omit_fields)

        source = zeit.content.author.interfaces.BIOGRAPHY_QUESTIONS(
            self.context)
        for name in source:
            field = zope.schema.Text(title=source.title(name), required=False)
            field.__name__ = name
            field.interface = (
                zeit.content.author.interfaces.IBiographyQuestions)
            self.form_fields += zope.formlib.form.FormFields(field)

        self.field_groups += (gocept.form.grouped.Fields(
            _("Biography"),
            ('summary', 'biography') + tuple(source),
            css_class='wide-widgets full-width'),)
Пример #40
0
    def teasers(self):
        teasers = []
        for content in self.context:
            metadata = zeit.cms.content.interfaces.ICommonMetadata(
                content, None)
            url = None
            if metadata is None:
                editable = False
                title = content.uniqueId
            else:
                editable = True
                title = metadata.teaserTitle
                try:
                    url = self.url(content)
                except TypeError:
                    # For example, IXMLTeaser cannot be viewed that way.
                    pass
            teasers.append(dict(
                css_class='edit-bar teaser',
                deletable=True,
                editable=editable,
                teaserTitle=title,
                uniqueId=content.uniqueId,
                url=url,
                viewable=bool(url),
            ))

        columns = zeit.content.cp.interfaces.ITeaserBlockColumns(self.context)
        if len(columns) == 2:
            left = columns[0]
            teasers.insert(left, dict(
                css_class='edit-bar column-separator',
                deletable=False,
                editable=False,
                teaserTitle=_('^ Left | Right v'),
                uniqueId=COLUMN_ID,
                viewable=False,
            ))

        return teasers
Пример #41
0
def warn_about_free_teasers(context, event):
    relations = zope.component.getUtility(zeit.cms.relation.interfaces.IRelations)
    relating_objects = relations.get_relations(context)
    for obj in relating_objects:
        if zeit.content.cp.interfaces.ICenterPage.providedBy(obj):
            # BBB Before the uniqueId/href convention, the content uniqueId was
            # stored in the ``{link}href`` attribute.
            blocks = obj.xml.xpath(
                "//block[@cp:free-teaser "
                "and (@href={id} or @link:href={id})]".format(id=xml.sax.saxutils.quoteattr(context.uniqueId)),
                namespaces=dict(link="http://namespaces.zeit.de/CMS/link", cp="http://namespaces.zeit.de/CMS/cp"),
            )
            if blocks:
                # Close enough
                source = zope.component.getUtility(z3c.flashmessage.interfaces.IMessageSource, name="session")
                source.send(
                    _(
                        '"${name}" is referenced by a free teaser in "${teaser}"',
                        mapping=dict(name=context.uniqueId, teaser=obj.uniqueId),
                    ),
                    "error",
                )
                break
Пример #42
0
 def doc(self):
     return _(
         u'An author with the given name already exists. '
         u'If you\'d like to create another author with the same '
         u'name anyway, check "Add duplicate author" '
         u'and save the form again.')
Пример #43
0
from zeit.cms.i18n import MessageFactory as _
import zeit.cms.content.property
import zeit.content.cp.blocks.block
import zeit.content.cp.interfaces
import zeit.edit.block
import zope.interface


class FrameBlock(zeit.content.cp.blocks.block.Block):

    zope.interface.implements(zeit.content.cp.interfaces.IFrameBlock)

    url = zeit.cms.content.property.ObjectPathProperty(
        '.url', zeit.content.cp.interfaces.IFrameBlock['url'])


zeit.edit.block.register_element_factory(
    [zeit.content.cp.interfaces.IArea],
    'frame', _('Frame block'))
Пример #44
0
 def doc(self):
     return _(u'A volume with the given name already exists.')
Пример #45
0
 def _generate_file_name(self):
     toc_file_string = _("Table of Content").lower().replace(" ", "_")
     volume_formatted = self._fill_template("{year}_{name}")
     return "{}_{}.csv".format(toc_file_string, volume_formatted)
Пример #46
0
from zeit.cms.i18n import MessageFactory as _
import zeit.cms.content.property
import zeit.content.cp.blocks.block
import zeit.content.cp.interfaces
import zeit.edit.block
import zope.interface


class HeaderImageBlock(zeit.content.cp.blocks.block.Block):

    zope.interface.implements(zeit.content.cp.interfaces.IHeaderImageBlock)

    image = zeit.cms.content.property.SingleResource('.image')


zeit.edit.block.register_element_factory(
    [zeit.content.cp.interfaces.IArea],
    'headerimage', _('Header image block'))
 def doc(self):
     return _('Text is to long. Allowed: ${maximum}, got: ${got}',
              mapping=dict(maximum=self.maximum, got=self.got))
Пример #48
0
    zope.interface.implements(zope.container.interfaces.IContained,
                              zeit.content.cp.interfaces.ICPExtraBlock)

    @property
    def cpextra(self):
        return self.xml.get('module')

    @cpextra.setter
    def cpextra(self, value):
        self.xml.set('module', value)
        self.xml['cp_extra'] = lxml.objectify.E.cp_extra(id=value)


zeit.edit.block.register_element_factory(
    zeit.content.cp.interfaces.IArea, 'cpextra', _('CP extra'), module='')


# This method only applies to "old" (lead/informatives/mosaic) centerpages
@grokcore.component.subscribe(
    zeit.content.cp.interfaces.ICenterPage,
    zeit.cms.repository.interfaces.IBeforeObjectAddEvent)
def add_blocks_to_newly_created_cp(context, event):
    # The BeforeObjectAddEvent is sent whenever an object is added or changed.
    # We need to check if this is the first add or not.
    if zeit.cms.interfaces.ICMSContent(context.uniqueId, None) is not None:
        # It's already in the repository, do nothing
        return
    if 'informatives' not in context:
        # It's a new-style centerpage, do nothing
        return
Пример #49
0
 def doc(self):
     return _('The uploaded image could not be identified.')
Пример #50
0
from zeit.cms.content.property import ObjectPathAttributeProperty
from zeit.cms.i18n import MessageFactory as _
from zeit.content.cp.interfaces import ICardstackBlock
import zeit.cms.content.property
import zeit.content.cp.blocks.block
import zeit.content.cp.interfaces
import zeit.edit.block
import zope.interface


class CardstackBlock(zeit.content.cp.blocks.block.Block):

    zope.interface.implements(ICardstackBlock)

    card_id = ObjectPathAttributeProperty(
        '.', 'card_id', ICardstackBlock['card_id'])
    is_advertorial = ObjectPathAttributeProperty(
        '.', 'is_advertorial', ICardstackBlock['is_advertorial'])


zeit.edit.block.register_element_factory(
    [zeit.content.cp.interfaces.IArea],
    'cardstack', _('Cardstack block'))