Package: ice.adverlet
============ice.adverlet============.. contents::Usage=====This package - for Zope3 based sites - provides a simple way to editany HTML snippet. It includes a WYSIWYG-editor, undo support andstorage for images.Examples of possible uses include: advertisement portlets,announcements, footers, frontpages, etc.The package provides the ZCML directive `adverlet` and TALESexpression `adverlet`.To use the package follow these 6 simple steps:1) Include the package:&lt;include package="ice.adverlet" file="meta.zcml" /&gt;&lt;include package="ice.adverlet" /&gt;2) In the ZCML configuration file define all your adverlets, forexample:&lt;ice:adverlet name="top" /&gt;&lt;ice:adverletname="bottom"description="This is an advertisement at the bottom of the frontpage"/&gt;&lt;ice:adverletname="footer"description="Footer of the site"default="default-footer"wysiwyg="False"/&gt;Notice:`name` - Required.`description` - Not required.`default` - Not required, it is name of browser view, registered bzcml-directives like browser:page.`wysiwyg' - Not required. Defines usage rich-text editor by default for thisadverlet in management UI. User (admin) can change this in the form.Default value is True.3) Write `adverlet` TALES expression in to your skin:&lt;div tal:content="structure adverlet:top" /&gt;where `top` is name of the adverlet.4) The package provides a view to manage all registered adverlets.This view may be called by a special content providerin any page::&lt;div tal:content="structure provider:ice.adverlet.manage" /&gt;5) This content provider has the permission "ice.adverlet.Manage".Therefore, you need to grant this permission to a role in yourproject, and allow "undo" for this user, for example::&lt;grant permission="ice.adverlet.Manage" role="foo.blah.Blah" /&gt;&lt;grant permission="zope.UndoOwnTransactions" role="foo.blah.Blah" /&gt;6) Install and register 2 local utilities:1. Factory - ice.adverlet.storage.SourceStorage;Interface - ice.adverlet.interfaces.ISourceStorage;Name - empty.(into Local Site Manager)2. Factory - ice.adverlet.storage.FileStorage;Interface - ice.adverlet.interfaces.IFileStorage;Name - empty.(into local site)That's it.N.B. You can define your own templates for management UI.To do this, take a look at ice/adverlet/browser/templateand write your own adapters in your project for your own templates.You will need to:- Change @adapter(IContentProvider, IDefaultBrowserLayer)to @adapter(IContentProvider, IMyCustomLayer)- Register this adapter with the same name(take a look at ice/adverlet/browser/configure.zcml,section &lt;!-- templates --&gt;.)N.B. Also, you can use default templates but not default CSS formanagement UI. For this, look in ZMI `Settings` form forice.adverlet.storage.SourceStorage local utility or define attribute`defaultCSS=False` in your install-tool code.Tests=====>>> import zope.interface>>> import zope.componentLet's register a default view for one of our adverlets::>>> import os, tempfile>>> temp_dir = tempfile.mkdtemp()>>> templateFileName = os.path.join(temp_dir, 'default_footer.pt')>>> open(templateFileName, 'w').write('''... &lt;h1&gt;Default Footer&lt;/h1&gt;... ''')>>> from zope.publisher.interfaces import browser>>> from zope.app.pagetemplate import simpleviewclass>>> DefaultViewClass = simpleviewclass.SimpleViewClass(...     templateFileName, name='default-footer')>>> zope.component.provideAdapter(...     DefaultViewClass,...     (zope.interface.Interface, browser.IDefaultBrowserLayer),...     zope.interface.Interface,...	  name='default-footer'...	  )Let's register a few advertlets::>>> from zope.configuration import xmlconfig>>> import ice.adverlet>>> context = xmlconfig.file('meta.zcml', ice.adverlet)>>> context = xmlconfig.string('''...     &lt;configure...	      xmlns="http://namespaces.zope.org/zope"...	      xmlns:ice="http://namespaces.zope.org/ice"...	      i18n_domain="test"&gt;......	      &lt;ice:adverlet...	          name="frontpage"...		  /&gt;......	      &lt;ice:adverlet...             name="footer"...		  description="Footer of the site"...		  default="default-footer"...		  /&gt;......     &lt;/configure&gt;''', context)Now we can try to call these adverlets in any view::>>> templateFileName = os.path.join(temp_dir, 'template.pt')>>> open(templateFileName, 'w').write('''... &lt;html&gt;... &lt;body&gt;... &lt;div tal:content="structure adverlet:frontpage" /&gt;... &lt;div tal:content="structure adverlet:footer" /&gt;... &lt;/body&gt;... &lt;/html&gt;... ''')>>> PageClass = simpleviewclass.SimpleViewClass(...     templateFileName, name='index.html')>>> zope.component.provideAdapter(...     PageClass,...     (zope.interface.Interface, browser.IDefaultBrowserLayer),...     zope.interface.Interface,...	  name='index.html'...	  )>>> from zope.publisher.browser import TestRequest>>> request = TestRequest()>>> class Content(object):...     zope.interface.implements(zope.interface.Interface)>>> content = Content()>>> view = zope.component.getMultiAdapter(...     (content, request), name='index.html')>>> print view().strip()&lt;html&gt;&lt;body&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;h1&gt;Default Footer&lt;/h1&gt;&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;&lt;BLANKLINE&gt;To edit adverlets store HTML sources::>>> from ice.adverlet.storage import SourceStorage>>> from ice.adverlet.interfaces import ISourceStorage>>> storage = SourceStorage()>>> ISourceStorage.providedBy(storage)True>>> storage.sources['frontpage'] = u'''...     &lt;h2&gt;&lt;ahref="http://launchpad.net&gt;Launchpad&lt;/a&gt;&lt;/h2&gt;...	  '''>>> storage.sources['footer'] = u'''...	  &lt;h3&gt;&lt;a href="http://ohloh.net&gt;OhLoh&lt;/a&gt;&lt;/h3&gt;...	  '''and register storage as utility::>>> zope.component.provideUtility(storage, ISourceStorage)Let's check the test view now::>>> print view().strip()&lt;html&gt;&lt;body&gt;&lt;div&gt;&lt;h2&gt;&lt;a href="http://launchpad.net&gt;Launchpad&lt;/a&gt;&lt;/h2&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;&lt;a href="http://ohloh.net&gt;OhLoh&lt;/a&gt;&lt;/h3&gt;&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;&lt;BLANKLINE&gt;Then we will test image storage and image wrapper.To do this, let's register storage for the files::>>> from ice.adverlet.storage import FileStorage>>> from ice.adverlet.interfaces import IFileStorage>>> files = FileStorage()>>> IFileStorage.providedBy(files)True>>> zope.component.provideUtility(files, IFileStorage)And let's try to use the image wrapper to store images in this storage::>>> from ice.adverlet.image import ImageWrapper>>> from ice.adverlet.interfaces import IImageWrapper>>> wrapper = ImageWrapper()>>> IImageWrapper.providedBy(wrapper)TrueRegister adapter for DublinCore::>>> from zope.dublincore.annotatableadapter import ZDCAnnotatableAdapter>>> from zope.dublincore.interfaces import IZopeDublinCore>>> from zope.annotation.interfaces import IAttributeAnnotatable>>> from zope.app.file.image import Image>>> zope.interface.classImplements(Image, IAttributeAnnotatable)>>> zope.component.provideAdapter(...     factory = ZDCAnnotatableAdapter,...	  provides = IZopeDublinCore,...	  adapts = (IAttributeAnnotatable,)...	  )We use test image::>>> from ice.adverlet.tests.tests import zptlogo>>> wrapper.data = zptlogo>>> wrapper.description = u'Logo image'Now let's check file storage::>>> [key for key in files.keys()][u'Image']>>> [IZopeDublinCore(file).title for file in files.values()][u'Logo image']Note that in management UI we use named global utilities IAdverletfor store HTML instead of using the storage directly. Let's testthis feature::>>> storage.sources['frontpage']u'\n    &lt;h2&gt;&lt;ahref="http://launchpad.net&gt;Launchpad&lt;/a&gt;&lt;/h2&gt;\n    '>>> from ice.adverlet.interfaces import IAdverlet>>> frontpage = zope.component.getUtility(IAdverlet, 'frontpage')>>> frontpage.source = '&lt;h2&gt;Hi there&lt;/h2&gt;'>>> storage.sources['frontpage']'&lt;h2&gt;Hi there&lt;/h2&gt;'And let's check adverlet again::>>> frontpage.source'&lt;h2&gt;Hi there&lt;/h2&gt;'We provide event for modify sources::>>> events = []>>> zope.component.provideHandler(events.append, (None, ))>>> frontpage.source = '''&lt;h2&gt;Welcome!...                       You are here.&lt;/h2&gt;...			 '''>>> events[&lt;ice.adverlet.events.SourceModifiedEvent instance at ...&gt;]The event holds the name of the global `adverlet` utility::>>> events[0].nameu'frontpage'Look up test browser class again::>>> print view().strip()&lt;html&gt;&lt;body&gt;&lt;div&gt;&lt;h2&gt;Welcome!You are here.&lt;/h2&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;&lt;a href="http://ohloh.net&gt;OhLoh&lt;/a&gt;&lt;/h3&gt;&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;&lt;BLANKLINE&gt;Let's test `newlines` parameter::>>> frontpage.newlines = True>>> print view().strip()&lt;html&gt;&lt;body&gt;&lt;div&gt;&lt;h2&gt;Welcome!&lt;br /&gt;                      You are here.&lt;/h2&gt;&lt;br /&gt;                    &lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;&lt;a href="http://ohloh.net&gt;OhLoh&lt;/a&gt;&lt;/h3&gt;&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;&lt;BLANKLINE&gt;Cleanup::>>> import shutil>>> shutil.rmtree(temp_dir)=========Demo site=========To look the demo follow these steps:1) In setup.py file your project write:install_requires = [...'ice.adverlet',..]2) In configure.zcml of your project write:&lt;include package="ice.adverlet.demo" />3) Run zope instance, add 'DEMO SITE' in ZMI, go to thi site, look 'DEMO'The demo site has defined 4 adverlets: header, main, footer, sidebar.There are default views for `header`, 'main' and `footer` adverlets(take a look at demo/app.zcml).Also, there are user: login - `demo`, password - `demo`.Other way: download tar-archive fromhttp://http://pypi.python.org/pypi/ice.adverletor http://launchpad.net/ice.adverlet/and run buildout.=======CHANGES=======Version 0.2.3 (2008-12-22)--------------------------- fixed bug in images container name chooser to work in KGSVersion 0.2.2 (2008-08-04)--------------------------- more convenience adverlets-listing- changes in default style sheetsVersion 0.2.1 (2008-08-01)--------------------------- form statusVersion 0.2.0 (2008-07-25)--------------------------- two modes: rich-text editor or simple textarea- 'render newlines' field for simple mode- `use default CSS for management UI` system parameter- `upload` form and listing of images now is in same URL- correct redirects in the form (not in the action handler, butin `update` method).- removed `Use Default View` column from management UI- demo principal instead zope.Anonymous for using demoin zopejroject or grokprojectBackward compatibility: yes, thanks to FieldProperty.Version 0.1.1 (2008-07-19)--------------------------- Correct egg-infoVersion 0.1.0 (2008-07-19)--------------------------- Initial release