Metadata-Version: 1.0
Name: ice.adverlet
Version: 0.2.1
Summary: Simple way to edit any HTML snippet
Home-page: http://launchpad.net/ice.adverlet
Author: Ilshad Habibullin
Author-email: astoon.net at gmail.com
License: GPL v.3
Description: ============
        ice.adverlet
        ============
        
        .. contents::
        
        Usage
        =====
        
        This package - for Zope3 based sites - provides a simple way to edit
        any HTML snippet. It includes a WYSIWYG-editor, undo support and
        storage for images.
        
        Examples of possible uses include: advertisement portlets,
        announcements, footers, frontpages, etc.
        
        The package provides the ZCML directive `adverlet` and TALES
        expression `adverlet`.
        
        To use the package follow these 6 simple steps:
        
        1) Include the package:
        
        <include package="ice.adverlet" file="meta.zcml" />
        <include package="ice.adverlet" />
        
        2) In the ZCML configuration file define all your adverlets, for
        example:
        
        <ice:adverlet name="top" />
        
        <ice:adverlet
        name="bottom"
        description="This is an advertisement at the bottom of the frontpage"
        />
        
        <ice:adverlet
        name="footer"
        description="Footer of the site"
        default="default-footer"
        wysiwyg="False"
        />
        
        Notice:
        `name` - Required.
        `description` - Not required.
        `default` - Not required, it is name of browser view, registered b
        zcml-directives like browser:page.
        `wysiwyg' - Not required. Defines usage rich-text editor by default for this
        adverlet in management UI. User (admin) can change this in the form.
        Default value is True.
        
        3) Write `adverlet` TALES expression in to your skin:
        
        <div tal:content="structure adverlet:top" />
        
        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 provider
        in any page::
        
        <div tal:content="structure provider:ice.adverlet.manage" />
        
        5) This content provider has the permission "ice.adverlet.Manage".
        Therefore, you need to grant this permission to a role in your
        project, and allow "undo" for this user, for example::
        
        <grant permission="ice.adverlet.Manage" role="foo.blah.Blah" />
        <grant permission="zope.UndoOwnTransactions" role="foo.blah.Blah" />
        
        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/template
        and 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 <!-- templates -->.)
        
        N.B. Also, you can use default templates but not default CSS for
        management UI. For this, look in ZMI `Settings` form for
        ice.adverlet.storage.SourceStorage local utility or define attribute
        `defaultCSS=False` in your install-tool code.
        
        Tests
        =====
        
        >>> import zope.interface
        >>> import zope.component
        
        Let'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('''
        ... <h1>Default Footer</h1>
        ... ''')
        
        >>> 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('''
        ...     <configure
        ...	      xmlns="http://namespaces.zope.org/zope"
        ...	      xmlns:ice="http://namespaces.zope.org/ice"
        ...	      i18n_domain="test">
        ...
        ...	      <ice:adverlet
        ...	          name="frontpage"
        ...		  />
        ...
        ...	      <ice:adverlet
        ...             name="footer"
        ...		  description="Footer of the site"
        ...		  default="default-footer"
        ...		  />
        ...
        ...     </configure>''', context)
        
        Now we can try to call these adverlets in any view::
        
        >>> templateFileName = os.path.join(temp_dir, 'template.pt')
        >>> open(templateFileName, 'w').write('''
        ... <html>
        ... <body>
        ... <div tal:content="structure adverlet:frontpage" />
        ... <div tal:content="structure adverlet:footer" />
        ... </body>
        ... </html>
        ... ''')
        
        >>> 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()
        <html>
        <body>
        <div></div>
        <div>
        <h1>Default Footer</h1>
        </div>
        </body>
        </html>
        <BLANKLINE>
        
        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'''
        ...     <h2><a href="http://launchpad.net>Launchpad</a></h2>
        ...	  '''
        >>> storage.sources['footer'] = u'''
        ...	  <h3><a href="http://ohloh.net>OhLoh</a></h3>
        ...	  '''
        
        and register storage as utility::
        
        >>> zope.component.provideUtility(storage, ISourceStorage)
        
        Let's check the test view now::
        
        >>> print view().strip()
        <html>
        <body>
        <div>
        <h2><a href="http://launchpad.net>Launchpad</a></h2>
        </div>
        <div>
        <h3><a href="http://ohloh.net>OhLoh</a></h3>
        </div>
        </body>
        </html>
        <BLANKLINE>
        
        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)
        True
        
        Register 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 IAdverlet
        for store HTML instead of using the storage directly. Let's test
        this feature::
        
        >>> storage.sources['frontpage']
        u'\n    <h2><a href="http://launchpad.net>Launchpad</a></h2>\n    '
        
        >>> from ice.adverlet.interfaces import IAdverlet
        >>> frontpage = zope.component.getUtility(IAdverlet, 'frontpage')
        
        >>> frontpage.source = '<h2>Hi there</h2>'
        
        >>> storage.sources['frontpage']
        '<h2>Hi there</h2>'
        
        And let's check adverlet again::
        
        >>> frontpage.source
        '<h2>Hi there</h2>'
        
        We provide event for modify sources::
        
        >>> events = []
        >>> zope.component.provideHandler(events.append, (None, ))
        
        >>> frontpage.source = '''<h2>Welcome!
        ...                       You are here.</h2>
        ...			 '''
        
        >>> events
        [<ice.adverlet.events.SourceModifiedEvent instance at ...>]
        
        The event holds the name of the global `adverlet` utility::
        
        >>> events[0].name
        u'frontpage'
        
        Look up test browser class again::
        
        >>> print view().strip()
        <html>
        <body>
        <div><h2>Welcome!
        You are here.</h2>
        </div>
        <div>
        <h3><a href="http://ohloh.net>OhLoh</a></h3>
        </div>
        </body>
        </html>
        <BLANKLINE>
        
        Let's test `newlines` parameter::
        
        >>> frontpage.newlines = True
        
        >>> print view().strip()
        <html>
        <body>
        <div><h2>Welcome!
        <br />                      You are here.</h2>
        <br />                    <br /></div>
        <div>
        <h3><a href="http://ohloh.net>OhLoh</a></h3>
        </div>
        </body>
        </html>
        <BLANKLINE>
        
        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:
        
        <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`.
        
        
        =======
        CHANGES
        =======
        
        Version 0.2.1 (2007-08-01)
        --------------------------
        
        - form status
        
        
        Version 0.2.0 (2007-07-25)
        --------------------------
        
        - two modes: rech-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, but
        in `update` method).
        - removed `Use Default View` column from management UI
        
        Backward compatibility: yes, thanks to FieldProperty.
        
        
        Version 0.1.1 (2007-07-19)
        --------------------------
        
        - Correct egg-info
        
        
        Version 0.1.0 (2007-07-19)
        --------------------------
        
        - Initial release
        
Platform: UNKNOWN
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU General Public License (GPL)
Classifier: Programming Language :: Python
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
Classifier: Framework :: Zope3
