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

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

added "compatibility" mode of tag cloud

File size: 8.3 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=550)
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=375)
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    = 550;
111    height   = 375;
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
148    @property
149    def title(self):
150        return _("Tag Cloud")
151
152    @property
153    def compmode(self):
154        return self.data.compmode
155
156    def getScript(self):
157        params = self.getParams()
158        return """<script type="text/javascript">
159            var so = new SWFObject("%(url)s", "tagcloudflash", "%(width)s", "%(height)s", "9", "#%(bgcolor)s");
160            %(trans)s
161            so.addParam("allowScriptAccess", "always");
162            so.addVariable("tcolor", "0x%(tcolor)s");
163            so.addVariable("tcolor2", "0x%(tcolor2)s");
164            so.addVariable("hicolor", "0x%(hicolor)s");
165            so.addVariable("tspeed", "%(tspeed)s");
166            so.addVariable("distr", "%(distr)s");
167            so.addVariable("mode", "%(mode)s");
168            so.addVariable("tagcloud", "%(tagcloud)s");
169            so.write("comulus");
170        </script>""" % params
171
172    def getParams(self):
173        params = {
174            'url': self.portal_url + '/++resource++tagcloud.swf',
175            'width': self.data.width,
176            'height': self.data.height,
177            'bgcolor': self.data.bgcolor,
178            'trans': self.data.trans and 'so.addParam("wmode", "transparent");' or '',
179            'tcolor': self.data.tcolor,
180            'tcolor2': self.data.tcolor2 or self.data.tcolor,
181            'hicolor': self.data.hicolor or self.data.tcolor,
182            'tspeed': self.data.speed,
183            'distr': self.data.distr and 'true' or 'false',
184            'mode': 'tags',
185            'tagcloud': urllib.quote('<tags>%s</tags>' % self.getTagAnchors()),
186        }
187        flashvars = []
188        for var in ('tcolor', 'tcolor2', 'hicolor', 'tspeed', 'distr', 'mode', 'tagcloud'):
189            flashvars.append('%s=%s' % (var, params[var]))
190        params['flashvars'] = '&'.join(flashvars)
191        return params
192
193    @memoize
194    def getTagAnchors(self):
195        tags = ''
196        for tag in self.getTags():
197            tags += '<a href="%s" title="%s entries" rel="tag" style="font-size: %.1f%s;">%s</a>\n' % \
198                (tag['url'], tag['number_of_entries'], tag['size'], self.data.unit, tag['name'])
199        return tags
200
201    def getTags(self):
202        tags = ITagsRetriever(self.context).getTags()
203        if tags == []:
204            return []
205
206        number_of_entries = [i[1] for i in tags]
207
208        min_number = min(number_of_entries)
209        max_number = max(number_of_entries)
210        distance = float(max_number - min_number) or 1
211        step = (self.data.largest - self.data.smallest) / distance
212
213        result = []
214        for name, number, url in tags:
215            size = self.data.smallest + step * (number - min_number)
216            result.append({
217                'name': name,
218                'size': size,
219                'number_of_entries': number,
220                'url': url
221            })
222        return result
223
224class AddForm(base.AddForm):
225    """Portlet add form.
226
227    This is registered in configure.zcml. The form_fields variable tells
228    zope.formlib which fields to display. The create() method actually
229    constructs the assignment that is being added.
230    """
231    form_fields = form.Fields(ICumulusPortlet)
232
233    def create(self, data):
234        return Assignment(**data)
235
236class EditForm(base.EditForm):
237    """Portlet edit form.
238
239    This is registered with configure.zcml. The form_fields variable tells
240    zope.formlib which fields to display.
241    """
242    form_fields = form.Fields(ICumulusPortlet)
Note: See TracBrowser for help on using the repository browser.