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

Last change on this file was 3361, checked in by kroman0, 12 years ago

Implemented max. number of tags to be displayed (Suresh V)

File size: 9.0 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
101    max_tags = schema.Int(
102        title=_(u'Maximum number of tags to display'),
103        description=_(u'Used when too many tags make the display ugly.'),
104        required=True,
105        default=50)
106
107class Assignment(base.Assignment):
108    """Portlet assignment.
109
110    This is what is actually managed through the portlets UI and associated
111    with columns.
112    """
113
114    implements(ICumulusPortlet)
115
116    width    = 152;
117    height   = 152;
118    tcolor   = u'5391d0'
119    tcolor2  = u'333333'
120    hicolor  = u'578308'
121    bgcolor  = u'ffffff'
122    speed    = 100
123    trans    = False
124    distr    = True
125    compmode = False
126
127    smallest = 8
128    largest  = 22
129    unit     = u'pt'
130    max_tags = 50
131
132    def __init__(self, **kw):
133        for k, v in kw.items():
134            setattr(self, k, v)
135
136    @property
137    def title(self):
138        """This property is used to give the title of the portlet in the
139        "manage portlets" screen.
140        """
141        return _("Tag Cloud (cumulus)")
142
143
144class Renderer(base.Renderer):
145    """Portlet renderer.
146    """
147
148    render = ViewPageTemplateFile('cumulusportlet.pt')
149
150    def __init__(self, context, request, view, manager, data):
151        base.Renderer.__init__(self, context, request, view, manager, data)
152        portal_state = getMultiAdapter((context, request), name=u'plone_portal_state')
153        self.portal_url = portal_state.portal_url()
154        portal_properties = getMultiAdapter((context, request), name=u'plone_tools').properties()
155        self.default_charset = portal_properties.site_properties.getProperty('default_charset', 'utf-8')
156
157    @property
158    def title(self):
159        return _("Tag Cloud")
160
161    @property
162    def compmode(self):
163        return self.data.compmode
164
165    def getScript(self):
166        params = self.getParams()
167        return """<script type="text/javascript">
168                var so = new SWFObject("%(url)s", "tagcloudflash", "%(width)s", "%(height)s", "9", "#%(bgcolor)s");
169                %(trans)s
170                so.addParam("allowScriptAccess", "always");
171                so.addVariable("tcolor", "0x%(tcolor)s");
172                so.addVariable("tcolor2", "0x%(tcolor2)s");
173                so.addVariable("hicolor", "0x%(hicolor)s");
174                so.addVariable("tspeed", "%(tspeed)s");
175                so.addVariable("distr", "%(distr)s");
176                so.addVariable("mode", "%(mode)s");
177                so.addVariable("tagcloud", "%(tagcloud)s");
178                so.write("comulus");
179            </script>""" % params
180
181    def getParams(self):
182        tagcloud = '<tags>%s</tags>' % self.getTagAnchors()
183        tagcloud = tagcloud.encode(self.default_charset)
184        tagcloud = urllib.quote(tagcloud)
185        params = {
186            'url': self.portal_url + '/++resource++tagcloud.swf',
187            'width': self.data.width,
188            'height': self.data.height,
189            'bgcolor': self.data.bgcolor,
190            'trans': self.data.trans and 'so.addParam("wmode", "transparent");' or '',
191            'tcolor': self.data.tcolor,
192            'tcolor2': self.data.tcolor2 or self.data.tcolor,
193            'hicolor': self.data.hicolor or self.data.tcolor,
194            'tspeed': self.data.speed,
195            'distr': self.data.distr and 'true' or 'false',
196            'mode': 'tags',
197            'tagcloud': tagcloud,
198        }
199        flashvars = []
200        for var in ('tcolor', 'tcolor2', 'hicolor', 'tspeed', 'distr', 'mode', 'tagcloud'):
201            flashvars.append('%s=%s' % (var, params[var]))
202        params['flashvars'] = '&'.join(flashvars)
203        return params
204
205    @memoize
206    def getTagAnchors(self):
207        tags = ''
208        for tag in self.getTags():
209            tags += '<a href="%s" title="%s entries" rel="tag" style="font-size: %.1f%s;">%s</a>\n' % \
210                (tag['url'], tag['number_of_entries'], tag['size'], self.data.unit, tag['name'])
211        return tags
212
213    def getTags(self):
214        tags = ITagsRetriever(self.context).getTags()
215        if tags == []:
216            return []
217
218        tags.sort(lambda x,y: (x[1]<y[1] and 1) or (x[1]>y[1] and -1) or 0)
219        tags = tags[:self.data.max_tags]
220
221        number_of_entries = [i[1] for i in tags]
222
223        min_number = min(number_of_entries)
224        max_number = max(number_of_entries)
225        distance = float(max_number - min_number) or 1
226        step = (self.data.largest - self.data.smallest) / distance
227
228        result = []
229        for name, number, url in tags:
230            size = self.data.smallest + step * (number - min_number)
231            result.append({
232                'name': name,
233                'size': size,
234                'number_of_entries': number,
235                'url': url
236            })
237        return result
238
239class AddForm(base.AddForm):
240    """Portlet add form.
241
242    This is registered in configure.zcml. The form_fields variable tells
243    zope.formlib which fields to display. The create() method actually
244    constructs the assignment that is being added.
245    """
246    form_fields = form.Fields(ICumulusPortlet)
247
248    def create(self, data):
249        return Assignment(**data)
250
251class EditForm(base.EditForm):
252    """Portlet edit form.
253
254    This is registered with configure.zcml. The form_fields variable tells
255    zope.formlib which fields to display.
256    """
257    form_fields = form.Fields(ICumulusPortlet)
Note: See TracBrowser for help on using the repository browser.