Skip to main content

Simple way to edit any HTML snippet

Project 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`.

Other way: download tar-archive from
http://http://pypi.python.org/pypi/ice.adverlet
or 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 KGS


Version 0.2.2 (2008-08-04)
--------------------------

- more convenience adverlets-listing
- changes in default style sheets

Version 0.2.1 (2008-08-01)
--------------------------

- form status


Version 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, but
in `update` method).
- removed `Use Default View` column from management UI
- demo principal instead zope.Anonymous for using demo
in zopejroject or grokproject

Backward compatibility: yes, thanks to FieldProperty.


Version 0.1.1 (2008-07-19)
--------------------------

- Correct egg-info


Version 0.1.0 (2008-07-19)
--------------------------

- Initial release

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ice.adverlet-0.2.3.tar.gz (38.6 kB view details)

Uploaded Source

Built Distribution

ice.adverlet-0.2.3-py2.4.egg (70.2 kB view details)

Uploaded Source

File details

Details for the file ice.adverlet-0.2.3.tar.gz.

File metadata

File hashes

Hashes for ice.adverlet-0.2.3.tar.gz
Algorithm Hash digest
SHA256 10085666a681be32f95ded3c9c5579cec2576c2f2ef560ed10460c3fbc3b65b1
MD5 bc4d87ac78690d04ddea93423eed860d
BLAKE2b-256 bf11cfa3775a1ff8f4dfe241dd54105e8b5b618d1154f3016fbb6f03461b2c27

See more details on using hashes here.

File details

Details for the file ice.adverlet-0.2.3-py2.4.egg.

File metadata

File hashes

Hashes for ice.adverlet-0.2.3-py2.4.egg
Algorithm Hash digest
SHA256 5fbc6632a684ba861dbc851430a349353ed497777f48189124c0e55ba2ea9a5b
MD5 58cbd74be0bb3ee5d5870425c5cf7f3d
BLAKE2b-256 43876d97e7fb1b574ab97a1131202bdfd6c27013949d1d4154373f12452d718b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page