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

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

inicio da edicao do carrossel (falta concluir a interface)

File size: 6.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
25_template_factory = Environment(loader=PackageLoader(__name__))
26
27get_template = _template_factory.get_template
28
29class BoxAware(object):
30
31    ALL_BOXES_KEY = 'il.portalinterlegis.boxes'
32
33    def get_box_data(self, context, key):
34        annotations = IAnnotations(context)
35        boxes = self.get_or_create_from_dict(annotations, self.ALL_BOXES_KEY)
36        return self.get_or_create_from_dict(boxes, key)
37
38    def erase_box_data(self, context, key):
39        annotations = IAnnotations(context)
40        boxes = annotations.get(self.ALL_BOXES_KEY, None)
41        if boxes and key in boxes:
42            del boxes[key]
43
44    @classmethod
45    def get_or_create_from_dict(cls, dictionary, key, type_to_create=PersistentDict):
46        value = dictionary.get(key, None)
47        if not value:
48            dictionary[key] = value = type_to_create()
49        return value
50
51
52class BaseBox(BoxAware):
53    """Base abstract class for editable boxes.
54    """
55
56    is_link_overlay = True
57
58    def __init__(self, permission=ModifyPortalContent):
59        self.permission = permission
60
61    def __call__(self, context):
62        return get_template('basebox.html').render(
63            box=self,
64            has_permission=self.has_permission(context),
65            inner=self.inner_render(context))
66
67    def has_permission(self, context):
68        return getSecurityManager().checkPermission(self.permission, context)
69
70    @property
71    def id(self):
72        "id of the box. Used in the template."
73        raise NotImplementedError
74
75    @property
76    def edit_href(self):
77        raise NotImplementedError
78
79    def inner_render(self, context):
80        raise NotImplementedError
81
82
83class Box(BaseBox):
84
85    def __init__(self, schema, number, permission=ModifyPortalContent, form_label=None):
86        super(Box, self).__init__(permission)
87        self.schema = schema
88        self.number = number
89        self.form_label = form_label or u'Edite os valore desta caixa'  # TODO: improve this text
90
91    @property
92    def id(self):
93        return '%s_%s' % (self.schema.__name__, self.number)
94
95    def inner_render(self, context):
96        templ = get_template(self.schema.__name__.lower() + '.html')
97        return templ.render(self.get_data(context))
98
99    def get_data(self, context):
100        return self.get_box_data(context, self.id)
101
102    def erase_data(self, context):
103        self.erase_box_data(context, self.id)
104
105    @property
106    def form_name(self):
107        """Last part of form urls.
108        """
109        return 'box_%s' % self.id
110
111    edit_href = form_name  # To be overridden independently
112
113def build_box_form(box):
114
115    # the combination (form.EditForm, grok.View)
116    # is from https://mail.zope.org/pipermail/grok-dev/2008-July/005999.html
117    # (plone.directives.form.EditForm did not work well)
118    class BoxEditForm(AutoExtensibleForm, form.EditForm, grok.View):
119        grok.context(IFolderish)
120        grok.name(box.form_name)
121        grok.require('cmf.ModifyPortalContent')
122
123        label = box.form_label
124        schema = box.schema
125
126        def getContent(self):
127            return box.get_data(self.context)
128
129        def render(self):
130            # we cannot simply associtate this template in the class level
131            # because form.EditForm has a ".render()" method and grok.View
132            # assumes you cannot have both "template = ..." and ".render()".
133            # No problem, we make a method that simply renders the template
134
135            # hack to make forms appear in ajax mode even using an iframe
136            # setting ajax_load is useless, probably because of a bug in plone
137            # TODO: check later if there is a more natural way of doing this
138            self.request['disable_plone.leftcolumn'] = True
139            self.request['disable_plone.rightcolumn'] = True
140            template = ZopeTwoPageTemplate(filename="boxform.pt")
141            return template.render(self)
142
143    globals()['BoxEditForm_%s' % box.id] = BoxEditForm
144    return BoxEditForm
145
146
147def build_many_box_forms(schema, max_number):
148    for number in range(max_number):
149        build_box_form(Box(schema, number))
150
151
152def get_or_create_persistent_dict(dictionary, key):
153    value = dictionary.get(key, None)
154    if not value:
155        dictionary[key] = value = PersistentDict()
156    return value
157
158
159# ROWS
160class DtRow(object):
161
162    def __init__(self, *row_spec):
163        try:
164            for (width, renderable) in row_spec:
165                pass
166        except ValueError, e:
167            e.args += row_spec
168            raise
169        self.row_spec = row_spec
170
171    def cells(self, context):
172        """Iterates transforming each cell spec from (width, renderable) to
173           a dict of {position, width, rendered_html}
174        """
175        position = 0
176        for (width, renderable) in self.row_spec:
177            yield dict(position=position, width=width, html=renderable(context))
178            position += width
179
180    def render(self, context):
181        """Renders the html of one row.
182        `row_spec` is a sequence of cell specs: [(width, schema, number), ...]
183        """
184        return get_template('dtrow.html').render(cells=self.cells(context))
185
186
187class GridView(grok.View):
188    "Base class for all grid-like views"
189    martian.baseclass()
190
191    template = ZopeTwoPageTemplate(filename="gridview.pt")
192
193    def rows(self):
194        for row in self.grid:
195            yield row.render(self.context)
196
197################################################################
198# TODO: o unico lugar em que isto funcionou foi aqui. Entender porque e decidir lugar definitivo.
199
200# initialize all the box managers
201NUMBER_OF_PRE_CREATED_BOXES = 10
202for s in box_schemas():
203    build_many_box_forms(s, NUMBER_OF_PRE_CREATED_BOXES)
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.