source: products/quintagroup.portlet.cumulus/trunk/quintagroup/portlet/cumulus/cumulusportlet.py @ 1041

Last change on this file since 1041 was 1041, checked in by koval, 15 years ago

tag cloud now has good links when not rendered in blog; changed default width and height for better look

File size: 8.6 KB
Line 
1import urllib
2
3from zope.interface import implements
4from zope.component import getMultiAdapter
5from zope.component import getAdapter
6
7from plone.portlets.interfaces import IPortletDataProvider
8from plone.app.portlets.portlets import base
9from plone.memoize.instance import memoize
10
11from zope import schema
12from zope.formlib import form
13from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
14
15from quintagroup.portlet.cumulus import CumulusPortletMessageFactory as _
16from quintagroup.portlet.cumulus.interfaces import ITagsRetriever
17
18class ICumulusPortlet(IPortletDataProvider):
19    """ A cumulus tag cloud portlet.
20    """
21    # options for generating <embed ... /> tag
22    width = schema.Int(
23        title=_(u'Width of the Flash tag cloud'),
24        description=_(u'Width in pixels (500 or more is recommended).'),
25        required=True,
26        default=152)
27
28    height = schema.Int(
29        title=_(u'Height of the Flash tag cloud'),
30        description=_(u'Height in pixels (ideally around 3/4 of the width).'),
31        required=True,
32        default=152)
33
34    tcolor = schema.TextLine(
35        title=_(u'Color of the tags'),
36        description=_(u'This and next 3 fields should be 6 character hex color values without the # prefix (000000 for black, ffffff for white).'),
37        required=True,
38        default=u'5391d0')
39
40    tcolor2 = schema.TextLine(
41        title=_(u'Optional second color for gradient'),
42        description=_(u'When this color is available, each tag\'s color will be from a gradient between the two. This allows you to create a multi-colored tag cloud.'),
43        required=False,
44        default=u'333333')
45
46    hicolor = schema.TextLine(
47        title=_(u'Optional highlight color'),
48        description=_(u'Color of the tag when mouse is over it.'),
49        required=False,
50        default=u'578308')
51
52    bgcolor = schema.TextLine(
53        title=_(u'Background color'),
54        description=_(u'The hex value for the background color you\'d like to use. This options has no effect when \'Use transparent mode\' is selected.'),
55        required=True,
56        default=u'ffffff')
57
58    trans = schema.Bool(
59        title=_(u'Use transparent mode'),
60        description=_(u'Switches on Flash\'s wmode-transparent setting.'),
61        required=True,
62        default=False)
63
64    speed = schema.Int(
65        title=_(u'Rotation speed'),
66        description=_(u'Speed of the sphere. Options between 25 and 500 work best.'),
67        required=True,
68        default=100)
69
70    distr = schema.Bool(
71        title=_(u'Distribute tags evenly on sphere'),
72        description=_(u'When enabled, the movie will attempt to distribute the tags evenly over the surface of the sphere.'),
73        required=True,
74        default=True)
75
76    compmode = schema.Bool(
77        title=_(u'Use compatibility mode?'),
78        description=_(u'Enabling this option switches the plugin to a different way of embedding Flash into the page. Use this if your page has markup errors or if you\'re having trouble getting tag cloud to display correctly.'),
79        required=True,
80        default=False)
81
82    # options for generating tag cloud data
83    smallest = schema.Int(
84        title=_(u'Smallest tag size'),
85        description=_(u'The text size of the tag with the smallest count value (units given by unit parameter).'),
86        required=True,
87        default=8)
88
89    largest = schema.Int(
90        title=_(u'Largest tag size'),
91        description=_(u'The text size of the tag with the highest count value (units given by the unit parameter).'),
92        required=True,
93        default=22)
94
95    unit = schema.TextLine(
96        title=_(u'Unit of measure'),
97        description=_(u'Unit of measure as pertains to the smallest and largest values. This can be any CSS length value, e.g. pt, px, em, %.'),
98        required=True,
99        default=u'pt')
100
101class Assignment(base.Assignment):
102    """Portlet assignment.
103
104    This is what is actually managed through the portlets UI and associated
105    with columns.
106    """
107
108    implements(ICumulusPortlet)
109
110    width    = 152;
111    height   = 152;
112    tcolor   = u'5391d0'
113    tcolor2  = u'333333'
114    hicolor  = u'578308'
115    bgcolor  = u'ffffff'
116    speed    = 100
117    trans    = False
118    distr    = True
119    compmode = False
120
121    smallest = 8
122    largest  = 22
123    unit     = u'pt'
124
125    def __init__(self, **kw):
126        for k, v in kw.items():
127            setattr(self, k, v)
128
129    @property
130    def title(self):
131        """This property is used to give the title of the portlet in the
132        "manage portlets" screen.
133        """
134        return _("Tag Cloud (cumulus)")
135
136
137class Renderer(base.Renderer):
138    """Portlet renderer.
139    """
140
141    render = ViewPageTemplateFile('cumulusportlet.pt')
142
143    def __init__(self, context, request, view, manager, data):
144        base.Renderer.__init__(self, context, request, view, manager, data)
145        portal_state = getMultiAdapter((context, request), name=u'plone_portal_state')
146        self.portal_url = portal_state.portal_url()
147        portal_properties = getMultiAdapter((context, request), name=u'plone_tools').properties()
148        self.default_charset = portal_properties.site_properties.getProperty('default_charset', 'utf-8')
149
150    @property
151    def title(self):
152        return _("Tag Cloud")
153
154    @property
155    def compmode(self):
156        return self.data.compmode
157
158    def getScript(self):
159        params = self.getParams()
160        return """<script type="text/javascript">
161                var so = new SWFObject("%(url)s", "tagcloudflash", "%(width)s", "%(height)s", "9", "#%(bgcolor)s");
162                %(trans)s
163                so.addParam("allowScriptAccess", "always");
164                so.addVariable("tcolor", "0x%(tcolor)s");
165                so.addVariable("tcolor2", "0x%(tcolor2)s");
166                so.addVariable("hicolor", "0x%(hicolor)s");
167                so.addVariable("tspeed", "%(tspeed)s");
168                so.addVariable("distr", "%(distr)s");
169                so.addVariable("mode", "%(mode)s");
170                so.addVariable("tagcloud", "%(tagcloud)s");
171                so.write("comulus");
172            </script>""" % params
173
174    def getParams(self):
175        tagcloud = '<tags>%s</tags>' % self.getTagAnchors()
176        tagcloud = tagcloud.encode(self.default_charset)
177        tagcloud = urllib.quote(tagcloud)
178        params = {
179            'url': self.portal_url + '/++resource++tagcloud.swf',
180            'width': self.data.width,
181            'height': self.data.height,
182            'bgcolor': self.data.bgcolor,
183            'trans': self.data.trans and 'so.addParam("wmode", "transparent");' or '',
184            'tcolor': self.data.tcolor,
185            'tcolor2': self.data.tcolor2 or self.data.tcolor,
186            'hicolor': self.data.hicolor or self.data.tcolor,
187            'tspeed': self.data.speed,
188            'distr': self.data.distr and 'true' or 'false',
189            'mode': 'tags',
190            'tagcloud': tagcloud,
191        }
192        flashvars = []
193        for var in ('tcolor', 'tcolor2', 'hicolor', 'tspeed', 'distr', 'mode', 'tagcloud'):
194            flashvars.append('%s=%s' % (var, params[var]))
195        params['flashvars'] = '&'.join(flashvars)
196        return params
197
198    @memoize
199    def getTagAnchors(self):
200        tags = ''
201        for tag in self.getTags():
202            tags += '<a href="%s" title="%s entries" rel="tag" style="font-size: %.1f%s;">%s</a>\n' % \
203                (tag['url'], tag['number_of_entries'], tag['size'], self.data.unit, tag['name'])
204        return tags
205
206    def getTags(self):
207        tags = ITagsRetriever(self.context).getTags()
208        if tags == []:
209            return []
210
211        number_of_entries = [i[1] for i in tags]
212
213        min_number = min(number_of_entries)
214        max_number = max(number_of_entries)
215        distance = float(max_number - min_number) or 1
216        step = (self.data.largest - self.data.smallest) / distance
217
218        result = []
219        for name, number, url in tags:
220            size = self.data.smallest + step * (number - min_number)
221            result.append({
222                'name': name,
223                'size': size,
224                'number_of_entries': number,
225                'url': url
226            })
227        return result
228
229class AddForm(base.AddForm):
230    """Portlet add form.
231
232    This is registered in configure.zcml. The form_fields variable tells
233    zope.formlib which fields to display. The create() method actually
234    constructs the assignment that is being added.
235    """
236    form_fields = form.Fields(ICumulusPortlet)
237
238    def create(self, data):
239        return Assignment(**data)
240
241class EditForm(base.EditForm):
242    """Portlet edit form.
243
244    This is registered with configure.zcml. The form_fields variable tells
245    zope.formlib which fields to display.
246    """
247    form_fields = form.Fields(ICumulusPortlet)
Note: See TracBrowser for help on using the repository browser.