source: publico/PortalInterlegis/produtos/il.portalinterlegis/trunk/src/il/portalinterlegis/browser/boxes/manager.py @ 6497

Última Alteração nesse arquivo desde 6497 foi 6497, incluída por mazza, 9 anos atrás

usando callables para generalizar boxes

File size: 5.4 KB
Linha 
1import martian
2from AccessControl import getSecurityManager
3from Products.CMFCore.interfaces import IFolderish
4from Products.CMFCore.permissions import ModifyPortalContent
5from five import grok
6from five.grok.components import ZopeTwoPageTemplate
7from jinja2 import Environment, PackageLoader
8from persistent.dict import PersistentDict
9from plone.autoform.form import AutoExtensibleForm
10from z3c.form import form, datamanager
11from z3c.form.interfaces import IDataManager
12from zope.annotation import IAnnotations
13from zope.component import adapts, provideAdapter
14from zope.interface import implements
15from zope.schema.interfaces import IField
16
17from interfaces import box_schemas
18
19
20class PersistentDictionaryField(datamanager.DictionaryField):
21    adapts(PersistentDict, IField)
22    implements(IDataManager)
23provideAdapter(PersistentDictionaryField)
24
25templates = Environment(loader=PackageLoader(__name__))
26
27class BoxManager(object):
28
29    ALL_BOXES_KEY = 'il.portalinterlegis.boxes'
30
31    def __init__(self, schema, label=None):
32        self.schema = schema
33        #TODO: improve this text
34        self.form_label = label or u'Edite os valore desta caixa'
35
36    def build_form(self, number):
37
38        # the combination (form.EditForm, grok.View)
39        # is from https://mail.zope.org/pipermail/grok-dev/2008-July/005999.html
40        # (plone.directives.form.EditForm did not work well)
41        class BoxEditForm(AutoExtensibleForm, form.EditForm, grok.View):
42            grok.context(IFolderish)
43            grok.name(self._box_name_for_url(number))
44            grok.require('cmf.ModifyPortalContent')
45
46            label = self.form_label
47            schema = self.schema
48
49            def getContent(form_self):
50                return self.box_content(form_self.context, number)
51
52            def render(self):
53                # we cannot simply associtate this template in the class level
54                # because form.EditForm has a ".render()" method and grok.View
55                # assumes you cannot have both "template = ..." and ".render()".
56                # No problem, we make a method that simply renders the template
57                template = ZopeTwoPageTemplate(filename="boxform.pt")
58                return template.render(self)
59
60        globals()['BoxEditForm_%s' % self._box_key(number)] = BoxEditForm
61        return BoxEditForm
62
63    def build_n_forms(self, max_number):
64        for number in range(1, max_number+1):
65            self.build_form(number)
66
67    def box_content(self, context, number): # maybe this method should be private
68        annotations = IAnnotations(context)
69        boxes = get_or_create_persistent_dict(annotations, BoxManager.ALL_BOXES_KEY)
70        return get_or_create_persistent_dict(boxes, self._box_key(number))
71
72    def html(self, context, number):
73        template = templates.get_template(self.schema.__name__.lower() + '.html')
74        return template.render(self.box_content(context, number))
75
76    def _box_key(self, number):
77        return '%s_%s' % (self.schema.__name__, number)
78
79    def _box_name_for_url(self, number):
80        return 'box_%s' % self._box_key(number)
81
82
83def get_or_create_persistent_dict(dictionary, key):
84    value = dictionary.get(key, None)
85    if not value:
86        dictionary[key] = value = PersistentDict()
87    return value
88from exceptions import ValueError
89# ROWS
90class DtRow(object):
91
92    ROW_TEMPLATE = '''
93  <div class="dt-row">%s
94  </div>'''
95
96    CELL_TEMPLATE = '''
97    <div class="dt-cell dt-position-%s dt-width-%s">%s
98    </div>'''
99
100    def __init__(self, *row_spec):
101        try:
102            for (width, template) in row_spec: pass
103        except ValueError, e:
104            e.args += row_spec
105            raise
106        self.row_spec = row_spec
107
108    def _cells(self, context):
109        """Iterates transforming each cell spec from (width, template) to
110           (position, width, rendered_html)
111        """
112        position = 0
113        for (width, template) in self.row_spec:
114            yield (position, width, template(context))
115            position += width
116
117    def render(self, context):
118        """Renders the html of one row.
119        `row_spec` is a sequence of cell specs: [(width, schema, number), ...]
120        """
121        return self.ROW_TEMPLATE % ''.join(
122            [self.CELL_TEMPLATE % cell for cell in self._cells(context)])
123
124
125class Box(object):
126
127    BOX_TEMPLATE = '''
128      <div id="%s"%s>%s
129      </div>'''
130
131    def __init__(self, schema, number, permission=ModifyPortalContent):
132        self.schema = schema
133        self.number = number
134        self.permission = permission
135
136    def __call__(self, context):
137        boxmanager = BoxManager(self.schema)
138        is_editable = getSecurityManager().checkPermission(self.permission, context)
139        return self.BOX_TEMPLATE % (boxmanager._box_key(self.number),
140                                    ' class ="editable-box"' if is_editable else '',
141                                    boxmanager.html(context, self.number))
142
143
144class GridView(grok.View):
145    "Base class for all grid-like views"
146    martian.baseclass()
147
148    template = ZopeTwoPageTemplate(filename="gridview.pt")
149
150    def rows(self):
151        for row in self.grid:
152            yield row.render(self.context)
153
154################################################################
155# TODO: o unico lugar em que isto funcionou foi aqui. Entender porque e decidir lugar definitivo.
156
157# initialize all the box managers
158
159for s in box_schemas():
160    BoxManager(s).build_n_forms(10)
161
Note: Veja TracBrowser para ajuda no uso do navegador do trac.
 

The contents and data of this website are published under license:
Creative Commons 4.0 Brasil - Atribuir Fonte - Compartilhar Igual.