def validate_xml_block(xml): if xml.tag != 'container': raise zeit.cms.interfaces.ValidationError( _("The root element must be <container>.")) if xml.get('{http://namespaces.zeit.de/CMS/cp}type') != 'xml': raise zeit.cms.interfaces.ValidationError( _("cp:type must be 'xml'.")) if not xml.get('{http://namespaces.zeit.de/CMS/cp}__name__'): raise zeit.cms.interfaces.ValidationError( _("No or empty cp:__name__ attribute.")) return True
def hex_literal(value): try: int(value, base=16) except ValueError: raise zeit.cms.interfaces.ValidationError(_("Invalid hex literal")) else: return True
def valid_feed_url(uri): zope.schema.URI().fromUnicode(uri) # May raise InvalidURI if urlparse.urlparse(uri).scheme in ('http', 'https', 'file'): return True # NOTE: we hide the fact that we support (some) file urls. raise zeit.cms.interfaces.ValidationError( _('Only http and https are supported.'))
def update(self): content = zeit.cms.interfaces.ICMSContent(self.uniqueId) if not zeit.content.video.interfaces.IPlaylist.providedBy(content): raise ValueError( _("Only playlists can be dropped on a playlist block.")) self.context.referenced_playlist = content zope.lifecycleevent.modified(self.context) self.reload()
def automatic_type_required_arguments(data): if (data.automatic and not automatic_area_can_read_teasers_automatically(data)): if data.automatic_type == 'centerpage': error_message = _( 'Automatic area with teaser from centerpage ' 'requires a referenced centerpage.') if data.automatic_type == 'channel': error_message = _( 'Automatic area with teaser from solr channel ' 'requires a channel query.') if data.automatic_type == 'query': error_message = _( 'Automatic area with teaser from solr query ' 'requires a raw query.') raise zeit.cms.interfaces.ValidationError(error_message) return True
def __init__(self, context, xml): super(TeaserBlock, self).__init__(context, xml) if self.xml.get('module') == 'teaser': if self.layout is None: raise ValueError(_( 'No default teaser layout defined for this area.')) self.layout = self.layout assert self.xml.get('module') != 'teaser' if 'text_color' not in self.xml.attrib: self.text_color = zeit.content.cp.interfaces.ITeaserBlock[ 'text_color'].default if 'overlay_level' not in self.xml.attrib: self.overlay_level = zeit.content.cp.interfaces.ITeaserBlock[ 'overlay_level'].default
def update(self): content = zeit.cms.interfaces.ICMSContent(self.uniqueId) if not zeit.content.video.interfaces.IVideoContent.providedBy( content): raise ValueError(_( "Only videos and playlists can be dropped on a video block.")) # There is the assumption that the __name__ is unique for all videos # and playlists. This is true for the current brightcove implementation # but might change at some point (unlikely though). self.context.id = content.__name__ if zeit.content.video.interfaces.IVideo.providedBy(content): self.context.player = u'vid' self.context.expires = content.expires else: self.context.player = u'pls' self.context.expires = None zope.lifecycleevent.modified(self.context) self.reload()
id = zeit.cms.content.property.ObjectPathAttributeProperty( '.video', 'videoID') player = zeit.cms.content.property.ObjectPathAttributeProperty( '.video', 'player') media_type = 'video' def __init__(self, context, xml): super(VideoBlock, self).__init__(context, xml) if len(self.xml.getchildren()) == 0: self.xml.append(lxml.objectify.E.video()) zeit.edit.block.register_element_factory( [zeit.content.cp.interfaces.IArea], 'video', _('Videoblock')) class AudioBlock(AVBlock): zope.interface.implements(zeit.content.cp.interfaces.IAVBlock) id = zeit.cms.content.property.ObjectPathAttributeProperty( '.audio', 'audioID') media_type = 'audio' def __init__(self, context, xml): super(AudioBlock, self).__init__(context, xml) if len(self.xml.getchildren()) == 0: self.xml.append(lxml.objectify.E.audio())
def get_error_message(self, mapping): return _('Could not publish ${id} since it has validation errors.', mapping=mapping)
- set(zeit.cms.content.interfaces.IXMLRepresentation) ) def update(self, other): if not zeit.content.cp.interfaces.ITeaserBlock.providedBy(other): raise ValueError('%r is not an ITeaserBlock' % other) # Copy teaser contents. for content in other: self.append(content) # Copy block properties (including __name__ and __parent__) for name in self.TEASERBLOCK_FIELDS: setattr(self, name, getattr(other, name)) zeit.edit.block.register_element_factory( zeit.content.cp.interfaces.IArea, 'teaser', _('List of teasers')) @grok.adapter(zeit.content.cp.interfaces.ITeaserBlock) @grok.implementer(zeit.content.cp.interfaces.ICMSContentIterable) def cms_content_iter(context): for teaser in context: yield teaser if zeit.content.cp.interfaces.IXMLTeaser.providedBy(teaser): yield zeit.cms.interfaces.ICMSContent(teaser.original_uniqueId) @grok.adapter(zeit.content.cp.interfaces.ICenterPage) @grok.implementer(zeit.content.cp.interfaces.ITeaseredContent) def extract_teasers_from_cp(context): for region in context.values():
referenced_object = zeit.cms.content.property.SingleResource( '.block', xml_reference_name='related', attributes=('href',)) image = zeit.cms.content.property.SingleResource( '.image', xml_reference_name='related', attributes=('href',)) @property def layout(self): return self.xml.get('layout') @layout.setter def layout(self, layout): if layout != self.layout: self._p_changed = True self.xml.set('layout', layout) @grokcore.component.adapter(zeit.content.cp.interfaces.IFullGraphicalBlock) @grokcore.component.implementer(zeit.content.cp.interfaces.ICMSContentIterable) def cms_content_iter(context): if context.referenced_object is not None: yield context.referenced_object if context.image is not None: yield context.image zeit.edit.block.register_element_factory( [zeit.content.cp.interfaces.IArea], 'fullgraphical', _('Fullgraphical Block'))
@url.setter def url(self, url): self.xml.set('url', url) self._p_changed = True self.xml.replace(self.xml.getchildren()[0], create_xi_include(self.feed, '/feed/rss')) @property def feed(self): return zope.component.getUtility( zeit.content.cp.interfaces.IFeedManager).get_feed(self.url) zeit.edit.block.register_element_factory( [zeit.content.cp.interfaces.IArea], 'rss', _('RSS block')) def make_path_for_unique_id(uniqueId): return uniqueId.replace( zeit.cms.interfaces.ID_NAMESPACE, '/var/cms/work/') INCLUDE_MAKER = lxml.objectify.ElementMaker( annotate=False, namespace='http://www.w3.org/2003/XInclude', nsmap={'xi': 'http://www.w3.org/2003/XInclude'}, ) def create_xi_include(context, xpath, name_maker=make_path_for_unique_id):
def __init__(self): self.titles = dict((x, _(self.prefix.format(x))) for x in self.values)
def getTitle(self, context, value): # XXX Hard-code language, since we don't have a request here. return zope.i18n.translate( _("${kind} area ${title}", mapping=dict( kind=value.kind, title=value.title or _("no title"))), target_language='de')
class ICP2009(ICenterPage): """Marker interfaces for CPs edited by the old 2.x CP-Editor branch.""" class ICP2015(ICenterPage): """Marker interfaces for CPs edited by the current CP-Editor (master).""" class IStoryStream(ICP2015): """CP with a specific ``type``.""" IStoryStream.setTaggedValue( 'zeit.cms.addform', 'zeit.content.cp.AddStoryStream') IStoryStream.setTaggedValue( 'zeit.cms.title', _('Add storystream')) class CenterPageSource(zeit.cms.content.contentsource.CMSContentSource): name = 'zeit.content.cp' check_interfaces = (ICenterPage,) centerPageSource = CenterPageSource() class IBody(zeit.edit.interfaces.IArea): """Container of the CenterPage that actually contains the children."""
from zeit.content.cp.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 QuizBlock(zeit.content.cp.blocks.block.Block): zope.interface.implements(zeit.content.cp.interfaces.IQuizBlock) quiz_id = zeit.cms.content.property.ObjectPathProperty( '.quiz_id', zeit.content.cp.interfaces.IQuizBlock['quiz_id']) zeit.edit.block.register_element_factory( [zeit.content.cp.interfaces.IArea], 'quiz', _('Quiz block'))
from zeit.content.cp.i18n import MessageFactory as _ import grokcore.component as grok import zeit.cms.content.property import zeit.content.cp.blocks.block import zeit.content.cp.interfaces import zeit.edit.block import zope.interface class PlaylistBlock(zeit.content.cp.blocks.block.Block): zope.interface.implements(zeit.content.cp.interfaces.IPlaylistBlock) referenced_playlist = zeit.cms.content.property.SingleResource( '.block', xml_reference_name='related', attributes=('href',)) zeit.edit.block.register_element_factory( [zeit.content.cp.interfaces.IArea], 'playlist', _('Video Bar')) @grok.adapter(zeit.content.cp.interfaces.IPlaylistBlock) @grok.implementer(zeit.content.cp.interfaces.ICMSContentIterable) def cms_content_iter(context): playlist = context.referenced_playlist if playlist is not None: yield playlist