Back to index

plone3  3.1.7
form.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2006 Zope Corporation and Contributors. All Rights Reserved.
00004 #
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE.
00011 #
00012 ##############################################################################
00013 """Formlib form base classes.
00014 
00015 $Id: form.py 76996 2007-06-24 00:18:49Z hannosch $
00016 """
00017 
00018 from datetime import datetime
00019 from sets import Set
00020 
00021 from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
00022 from Products.Five.formlib.formbase import PageDisplayForm
00023 from Products.Five.formlib.formbase import PageForm
00024 from zope.datetime import parseDatetimetz
00025 from zope.formlib import form
00026 from zope.i18n.interfaces import IUserPreferredLanguages
00027 from zope.i18n.locales import LoadLocaleError
00028 from zope.i18n.locales import locales
00029 from ZTUtils import make_query
00030 
00031 from Products.CMFDefault.utils import Message as _
00032 from Products.CMFDefault.utils import translate
00033 from Products.CMFDefault.browser.utils import ViewBase
00034 
00035 
00036 # from zope.publisher.http.HTTPRequest
00037 def getLocale(request):
00038     envadapter = IUserPreferredLanguages(request, None)
00039     if envadapter is None:
00040         return None
00041 
00042     langs = envadapter.getPreferredLanguages()
00043     for httplang in langs:
00044         parts = (httplang.split('-') + [None, None])[:3]
00045         try:
00046             return locales.getLocale(*parts)
00047         except LoadLocaleError:
00048             # Just try the next combination
00049             pass
00050     else:
00051         # No combination gave us an existing locale, so use the default,
00052         # which is guaranteed to exist
00053         return locales.getLocale(None, None, None)
00054 
00055 
00056 class EditFormBase(PageForm, ViewBase):
00057 
00058     template = ViewPageTemplateFile('editform.pt')
00059 
00060     def __init__(self, context, request):
00061         self.context = context
00062         self.request = request
00063         self.request.locale = getLocale(request)
00064 
00065     def _setRedirect(self, provider_id, action_path, keys=''):
00066         provider = self._getTool(provider_id)
00067         try:
00068             target = provider.getActionInfo(action_path, self.context)['url']
00069         except ValueError:
00070             target = self._getPortalURL()
00071 
00072         kw = {}
00073         if self.status:
00074             message = translate(self.status, self.context)
00075             if isinstance(message, unicode):
00076                 message = message.encode(self._getBrowserCharset())
00077             kw['portal_status_message'] = message
00078         for k in keys.split(','):
00079             k = k.strip()
00080             v = self.request.form.get(k, None)
00081             if v:
00082                 kw[k] = v
00083 
00084         query = kw and ( '?%s' % make_query(kw) ) or ''
00085         self.request.RESPONSE.redirect( '%s%s' % (target, query) )
00086 
00087         return ''
00088 
00089     def handle_failure(self, action, data, errors):
00090         if self.status:
00091             message = translate(self.status, self.context)
00092             self.request.other['portal_status_message'] = message
00093 
00094 
00095 class ContentEditFormBase(EditFormBase):
00096 
00097     actions = form.Actions(
00098         form.Action(
00099             name='change',
00100             label=_(u'Change'),
00101             validator='handle_validate',
00102             success='handle_change_success',
00103             failure='handle_failure'),
00104         form.Action(
00105             name='change_and_view',
00106             label=_(u'Change and View'),
00107             validator='handle_validate',
00108             success='handle_change_and_view_success',
00109             failure='handle_failure'))
00110 
00111     description = u''
00112 
00113     def setUpWidgets(self, ignore_request=False):
00114         self.adapters = {}
00115         self.widgets = form.setUpEditWidgets(
00116             self.form_fields, self.prefix, self.context, self.request,
00117             adapters=self.adapters, ignore_request=ignore_request
00118             )
00119 
00120     @property
00121     def label(self):
00122         obj_type = translate(self.context.Type(), self.context)
00123         return _(u'Edit ${obj_type}', mapping={'obj_type': obj_type})
00124 
00125     def handle_validate(self, action, data):
00126         if self.context.wl_isLocked():
00127             return (_(u'This resource is locked via webDAV.'),)
00128         return None
00129 
00130     def _handle_success(self, action, data):
00131         # normalize set and datetime
00132         for k, v in data.iteritems():
00133             if isinstance(v, Set):
00134                 data[k] = set(v)
00135             elif isinstance(v, datetime) and v.tzname() is None:
00136                 data[k] = parseDatetimetz(str(v))
00137         changed = form.applyChanges(self.context, self.form_fields, data,
00138                                     self.adapters)
00139         if changed:
00140             self.context.reindexObject()
00141             obj_type = translate(self.context.Type(), self.context)
00142             self.status = _(u'${obj_type} changed.',
00143                             mapping={'obj_type': obj_type})
00144         else:
00145             self.status = _(u'Nothing to change.')
00146         return changed
00147 
00148     def handle_change_success(self, action, data):
00149         self._handle_success(action, data)
00150         return self._setRedirect('portal_types', 'object/edit')
00151 
00152     def handle_change_and_view_success(self, action, data):
00153         self._handle_success(action, data)
00154         return self._setRedirect('portal_types', 'object/view')
00155 
00156 
00157 class DisplayFormBase(PageDisplayForm, ViewBase):
00158 
00159     template = ViewPageTemplateFile('viewform.pt')
00160 
00161     def __init__(self, context, request):
00162         self.context = context
00163         self.request = request
00164         self.request.locale = getLocale(request)
00165 
00166     @property
00167     def label(self):
00168         return self.context.Type()