Package: collective.portlet.localcumulus
ContentsIntroductionCreditscollective.portlet.cumulus InstallationDetailed documentationThe local renderer and portlet objectsThe local custom portletTestsCustomize url with variablesChangelog1.5 - 2010-03-161.4 - 2010-03-161.3 - Unreleased1.2 - 2010-02-081.0 - 2010-01-18Introductionbased onquintagroup.portlet.cumulusThis package provides 2 new tagcloud based portletsWithcache (refresh)local path searches enhancementsAnd for the ‘custom portlet’:url customization for tag browsingUsageInstall “Local Tag cloud (cumulus) portlet” with QuickInstaller.Select Local Tag Cloud (cumulus) portlet from Add portlet drop-down menu.Provide your own values for portlet configuration if needed.Save changes.Supported Plone version3.xRepository:svnCreditsPlanet Makina CorpusContact uscollective.portlet.cumulus InstallationTo install collective.portlet.cumulus into the global Python environment (or a workingenv),
using a traditional Zope 2 instance, you can do this:When you’re reading this you have probably already run``easy_install collective.portlet.cumulus``.Find out how to install setuptools (and EasyInstall) here:http://peak.telecommunity.com/DevCenter/EasyInstallIf you are using Zope 2.9 (not 2.10), getpythonproductsand install it
via:python setup.py install --home /path/to/instanceinto your Zope instance.Create a file calledcollective.portlet.cumulus-configure.zcmlin the/path/to/instance/etc/package-includesdirectory.  The file
should only contain this:<include package="collective.portlet.cumulus" />Alternatively, if you are using zc.buildout and the plone.recipe.zope2instance
recipe to manage your project, you can do this:Addcollective.portlet.cumulusto the list of eggs to install, e.g.:[buildout]
...
eggs =
    ...
    collective.portlet.cumulusTell the plone.recipe.zope2instance recipe to install a ZCML slug:[instance]
recipe = plone.recipe.zope2instance
...
zcml =
    collective.portlet.cumulusRe-run buildout, e.g. with:$ ./bin/buildoutYou can skip the ZCML slug if you are going to explicitly include the package
from another package’s configure.zcml file.Detailed documentationThe local renderer and portlet objectsAdding some content for testing searches>>> self.setRoles(('Manager', ))
>>> self.portal['front-page'].edit(subject=['global', 'tags'])
>>> if1 = self.folder.invokeFactory('Folder', id='f1')
>>> if2 = self.folder.invokeFactory('Folder', id='f2')
>>> f1 = self.folder[if1]
>>> f2 = self.folder[if2]
>>> d1 = f1.invokeFactory('Document', id='blog-entry1')
>>> d2 = f1.invokeFactory('Document', id='blog-entry2')
>>> d3 = f2.invokeFactory('Document', id='blog-entry3')
>>> d4 = f2.invokeFactory('Document', id='blog-entry4')
>>> f1[d1].edit(subject=['blog', 'tags'])
>>> f1[d2].edit(subject=['foo', 'bar'])
>>> f2[d3].edit(subject=['toto', 'titi'])
>>> f2[d4].edit(subject=['toto', 'tutu'])Looking for our adapter to be in place>>> from collective.portlet.localcumulus.interfaces import ILocalTagsRetriever
>>> from collective.portlet.localcumulus import catalog
>>> data = catalog.DummyData()
>>> data.refreshInterval = 1This adapter takes a context and an Assigment as ‘data’ attribute>>> retriever = ILocalTagsRetriever(f1)
>>> retriever
<collective.portlet.localcumulus.catalog.LocalTags object at ...>Trying to get the local tags of the f1 folder>>> data.path = '/'.join(f1.getPhysicalPath())
>>> retriever.data = data
>>> print '\n'.join(['%s %s %s'% i for i in retriever.getTags()])
blog 1 http://nohost/plone/search?path=/plone/Members/test_user_1_/f1&Subject:list=blog
foo 1 http://nohost/plone/search?path=/plone/Members/test_user_1_/f1&Subject:list=foo
bar 1 http://nohost/plone/search?path=/plone/Members/test_user_1_/f1&Subject:list=bar
tags 1 http://nohost/plone/search?path=/plone/Members/test_user_1_/f1&Subject:list=tagsTrying to get the local tags of the f2 folder>>> data.path = '/'.join(f2.getPhysicalPath())
>>> print '\n'.join(['%s %s %s'% i for i in retriever.getTags()])
tutu 1 http://nohost/plone/search?path=/plone/Members/test_user_1_/f2&Subject:list=tutu
titi 1 http://nohost/plone/search?path=/plone/Members/test_user_1_/f2&Subject:list=titi
toto 2 http://nohost/plone/search?path=/plone/Members/test_user_1_/f2&Subject:list=totoIf we have a portlet without path, it goes system wide>>> data.path = ''
>>> print '\n'.join(['%s %s %s'% i for i in retriever.getTags(data=data)])
bar 1 http://nohost/plone/search?Subject:list=bar
blog 1 http://nohost/plone/search?Subject:list=blog
foo 1 http://nohost/plone/search?Subject:list=foo
global 1 http://nohost/plone/search?Subject:list=global
tags 2 http://nohost/plone/search?Subject:list=tags
titi 1 http://nohost/plone/search?Subject:list=titi
toto 2 http://nohost/plone/search?Subject:list=toto
tutu 1 http://nohost/plone/search?Subject:list=tutuTesting cache>>> import time
>>> data.path = '/'.join(f2.getPhysicalPath())
>>> data.refreshInterval = 10
>>> [o[0] for o in retriever.getTags()]
[u'tutu', u'titi', u'toto']
>>> f2[d4].edit(subject=['toto', 'tutu', 'tata'])
>>> [o[0] for o in retriever.getTags()]
[u'tutu', u'titi', u'toto']
>>> time.sleep(2)
>>> [o[0] for o in retriever.getTags()]
[u'tutu', u'titi', u'toto']After 11 seconds, cache life is up>>> time.sleep(9)
>>> [o[0] for o in retriever.getTags()]
[u'tutu', u'titi', u'toto', u'tata']The local custom portletThe custom portlet enables the user to format the url used to browse a tag instead to use the plonesearch_formas a default.TestsAdding some content for testing searches>>> self.setRoles(('Manager', ))
>>> self.portal['front-page'].edit(subject=['global', 'tags'])
>>> if1 = self.folder.invokeFactory('Folder', id='f1')
>>> if2 = self.folder.invokeFactory('Folder', id='f2')
>>> f1 = self.folder[if1]
>>> f2 = self.folder[if2]
>>> d1 = f1.invokeFactory('Document', id='blog-entry1')
>>> d2 = f1.invokeFactory('Document', id='blog-entry2')
>>> d3 = f2.invokeFactory('Document', id='blog-entry3')
>>> d4 = f2.invokeFactory('Document', id='blog-entry4')
>>> f1[d1].edit(subject=['blog', 'tags'])
>>> f1[d2].edit(subject=['foo', 'bar'])
>>> f2[d3].edit(subject=['toto', 'titi'])
>>> f2[d4].edit(subject=['toto', 'tutu'])Looking for our adapter to be in place>>> from collective.portlet.localcumulus.interfaces import ICustomLocalTagsRetriever
>>> from collective.portlet.localcumulus import catalog
>>> data = catalog.DummyData()
>>> data.refreshInterval = 1
>>> data.path = '/'.join(f1.getPhysicalPath())This adapter takes a context and an Assigment as ‘data’ attribute>>> retriever = ICustomLocalTagsRetriever(f1)
>>> retriever
<collective.portlet.localcumulus.catalog.CustomLocalTags object at ...>Trying to get the local tags of the f1 folder with no url, it will default to the localtag behaviour>>> data.search_url = ''
>>> retriever.data = data
>>> print '\n'.join(['%s %s %s'% i for i in retriever.getTags()])
blog 1 http://nohost/plone/search?path=/plone/Members/test_user_1_/f1&Subject:list=blog
foo 1 http://nohost/plone/search?path=/plone/Members/test_user_1_/f1&Subject:list=foo
bar 1 http://nohost/plone/search?path=/plone/Members/test_user_1_/f1&Subject:list=bar
tags 1 http://nohost/plone/search?path=/plone/Members/test_user_1_/f1&Subject:list=tagsCustomize url with variablesWe can play with some variables in python dict-string formating style.If we have an url without any parameters inside, it just appends the tag at the end>>> [bool(catalog.NOT_SIMPLE_URL_RE.match(a)) for a in ['azerty', '()', '%(azerty)s', '%()', '%()s']]
[False, False, True, False, False]
>>> data.search_url = 'http://foo'
>>> retriever.data = data
>>> print '\n'.join(['%s' % i for i in retriever.getTags()])
[u'blog', 1, u'http://foo/blog&path=/plone/Members/test_user_1_/f1']
[u'foo', 1, u'http://foo/foo&path=/plone/Members/test_user_1_/f1']
[u'bar', 1, u'http://foo/bar&path=/plone/Members/test_user_1_/f1']
[u'tags', 1, u'http://foo/tags&path=/plone/Members/test_user_1_/f1']Think that you’ll surely have to add at least%(tag)ssomewhere in your url to include the tag information ;).Variables avaiblable are:portal_path: plone site pathportal_url: plone site urlhere_url: context urlhere_path: context path inside the ZODBtag: the tagtag_weight: weight of the tag>>> data.search_url = '%(portal_url)s?path=%(portal_path)s&url=%(here_url)s&hpath=%(here_path)s&tag=%(tag)s&weight=%(tag_weight)s'
>>> retriever.data = data
>>> print '\n'.join(['%s' % i for i in retriever.getTags()])
[u'blog', 1, u'http://nohost/plone?path=/plone&url=http://nohost/plone/Members/test_user_1_/f1&hpath=/plone&tag=blog&weight=1']
[u'foo', 1, u'http://nohost/plone?path=/plone&url=http://nohost/plone/Members/test_user_1_/f1&hpath=/plone&tag=foo&weight=1']
[u'bar', 1, u'http://nohost/plone?path=/plone&url=http://nohost/plone/Members/test_user_1_/f1&hpath=/plone&tag=bar&weight=1']
[u'tags', 1, u'http://nohost/plone?path=/plone&url=http://nohost/plone/Members/test_user_1_/f1&hpath=/plone&tag=tags&weight=1']Changelog1.5 - 2010-03-16bugfix: path in custom portlet [kiorky]1.4 - 2010-03-16grok fix (remove it, useless) [kiorky]Fix tests.1.3 - Unreleasedhonour path in custom portlet [kiorky]1.2 - 2010-02-08Add customizable portlet with special url to browse when a tag is chosen [kiorky]1.0 - 2010-01-18Initial release [kiorky]