def handle_views(self, **kwargs): """ Sort views """ mutator = queryAdapter(self.context, IVisualizationConfig) order = kwargs.get('order', []) ajax = (kwargs.get('daviz.views.save') == 'ajax') if not order: return self._redirect(_('Views settings not saved: Nothing to do'), ajax) if not isinstance(order, list): return self._redirect(_('Views order not saved: Nothing to do'), ajax) if len(order) == 1: return self._redirect(_('Views order not saved: Nothing to do'), ajax) views = mutator.views views = dict((view.get('name'), dict(view)) for view in views) mutator.delete_views() for name in order: properties = views.get(name, {}) if not properties: continue mutator.add_view(**properties) return self._redirect(_('Views order changed'), ajax)
def handle_facets(self, **kwargs): """ Update facets position """ mutator = queryAdapter(self.context, IVisualizationConfig) order = kwargs.get('order', []) ajax = (kwargs.get('daviz.facets.save') == 'ajax') if not order: return self._redirect( _('Exhibit facets settings not saved: Nothing to do'), ajax) if not isinstance(order, list): return self._redirect( _('Exhibit facets settings not saved: Nothing to do'), ajax) if len(order) == 1: return self._redirect( _('Exhibit facets settings not saved: Nothing to do'), ajax) facets = mutator.facets facets = dict((facet.get('name'), dict(facet)) for facet in facets) mutator.delete_facets() for name in order: properties = facets.get(name, {}) if not properties: logger.exception('Unknown facet id: %s', name) continue mutator.add_facet(**properties) return self._redirect(_('Exhibit facets settings saved'), ajax)
class IAlphabeticalProperties(IVisualizationEditFacet): """ Edit facet """ ex_height = schema.TextLine( title=_(u"Height"), description=_(u"height of the facet's body, e.g., '20em', '200px'"), required=False, default=u"") ex_scroll = schema.Bool( title=_(u"Scroll"), description=_(u"if true, facet values are in a scrollable window " "of fixed size. If false, all facet values are shown " "in as much space as needed, without a scroll bar."), required=False, default=True) ex_interval = schema.Int(title=_(u'Interval'), description=_(u"The interval in number ranges"), required=True, default=10) ex_collapsible = schema.Bool(title=_(u"Collapsible"), description=_(u"Collapsible"), required=False, default=False) ex_collapsed = schema.Bool(title=_(u"Collapsed"), description=_(u"Collapsed"), required=False, default=False)
def handle_views(self, **kwargs): """ Sort views """ mutator = queryAdapter(self.context, IVisualizationConfig) order = kwargs.get('order', []) ajax = (kwargs.get('daviz.views.save') == 'ajax') if not order: return self._redirect( _('Views settings not saved: Nothing to do'), ajax) if not isinstance(order, list): return self._redirect( _('Views order not saved: Nothing to do'), ajax) if len(order) == 1: return self._redirect( _('Views order not saved: Nothing to do'), ajax) views = mutator.views views = dict((view.get('name'), dict(view)) for view in views) mutator.delete_views() for name in order: properties = views.get(name, {}) if not properties: continue mutator.add_view(**properties) return self._redirect(_('Views order changed'), ajax)
class IDataEdit(Interface): """ Data settings Edit """ json = schema.Text( title=_(u"Data table"), description=_(u"<ul>" "<li>Click on the top-left pencil to " "inspect and edit generate JSON.</li>" "<li>Click on the table's columns headers to adjust " "their labels (user friendly-names)</li>" "</ul>"), required=False) json.order = 20 sources = schema.List( title=_(u'Additional sources'), required=False, description=_( u"(Simile-Exhibit only) " "Add additional external exhibit sources to be merged. " "Supported formats: " "'Exhibit JSON', 'Google Spreadsheet' and 'RDF/XML'. " "See more details " "http://www.simile-widgets.org/wiki/Exhibit/Creating" "%2C_Importing%2C_and_Managing_Data#Conversion_at_Load_Time"), value_type=schema.TextLine(title=u'URL')) sources.order = 30
class ExhibitSection(object): """ Simile Exhibit Settings Section """ implements(IDavizSection) prefix = 'exhibit' title = 'Simile Exhibit Settings' form_fields = FormFields( schema.Choice( __name__='exhibit.framework', title=_(u'Version'), description=_(u"use the following version of Simile Exhibit " "Framework"), required=True, default=3, vocabulary=SimpleVocabulary([ SimpleTerm(2, 2, u"2.2.0"), SimpleTerm(3, 3, u"3.0.0"), ]) ), schema.Bool( __name__='exhibit.ieForceExhibit2', title=_(u"Force Exhibit 2 for Internet Explorer"), description=_(u"force Simile Exhibit 2 for " "Internet Explorer users as Simile Exhibit 3 is not " "stable on this browser, yet. " "Leave this option selected if you're unsure."), required=False, default=True ) )
def __init__(self): self.form_fields = FormFields( schema.Text(__name__='data.annotations', title=_(u"Annotations"), description=_( "Data annotations - lowercase - to be " "ignored/handled as annotations when processing " "data tables. One per line " "(e.g. 'n/a', 'n.a.', ':')"), required=False), )
def __init__(self): self.form_fields = FormFields( schema.Text( __name__='data.annotations', title=_(u"Annotations"), description=_("Data annotations - lowercase - to be " "ignored/handled as annotations when processing " "data tables. One per line " "(e.g. 'n/a', 'n.a.', ':')"), required=False), )
class ITextProperties(IVisualizationEditFacet): """ Edit facet """ ex_queryParamName = schema.TextLine(title=_(u"Query param name"), description=_(u"query param name"), required=False, default=u"") ex_requiresEnter = schema.Bool(title=_(u"Requires Enter"), description=_(u"requires enter"), required=False, default=False)
class ICloudProperties(IVisualizationEditFacet): """ Edit facet """ ex_height = schema.TextLine( title=_(u"Height"), description=_(u"height of the facet's body, e.g., '20em', '200px'"), required=False, default=u"") ex_showMissing = schema.Bool( title=_(u"Show missing"), description=_(u"whether to provide a selection for items missing " "the facet -- this will suppress the " "'(missing this field)' text"), required=False, default=True) ex_missingLabel = schema.TextLine(title=_(u"Missing label"), description=_(u"missing label"), required=False, default=u"") ex_minimumCount = schema.Int(title=_("Minimum count"), description=_(u"minimum count"), required=False, default=1)
class IVisualizationViewResources(Interface): """ CSS/JS to be included by daviz-view.html """ extcss = schema.List( title=_(u'External or required stylesheets'), description=_(u'List of CSS resources to be included in view mode ' 'before CSS reources provided by css attribute'), value_type=schema.TextLine(title=u'ExtCSS'), readonly=True ) css = schema.List( title=_(u'Stylesheets'), description=\ _(u'List of CSS resources to be included by daviz-view.html'), value_type=schema.TextLine(title=u'CSS'), readonly=True ) extjs = schema.List( title=_(u'External or required javascripts'), description=_(u'List of JS resources to be included in view mode ' 'before JS reources provided by js attribute'), value_type=schema.TextLine(title=u'ExtJS'), readonly=True ) js = schema.List( title=_(u'Javascripts'), description=\ _(u'List of JS resources to be included by daviz-view.html'), value_type=schema.TextLine(title=u'JS'), readonly=True )
def ViewDirective(_context, name, permission=None, for_=Interface, layer=IDefaultBrowserLayer, template=None, class_=None, allowed_interface=None, allowed_attributes=None, attribute='__call__', menu=None, title=None): """ Daviz View """ if not name: raise TypeError(_("No name provided")) label = title if title and not menu: title = None page(_context=_context, name=name, permission=permission, for_=for_, layer=layer, template=template, class_=class_, allowed_interface=allowed_interface, allowed_attributes=allowed_attributes, attribute=attribute, menu=menu, title=title) VisualizationViews._views[name] = label or name
def save(self, saction, data): """ Handle save action """ name = saction.__name__.encode('utf-8') value = self.request.form.get(name, '') widgetName = self.request.form.get('name', '') widgets = self.dashboard.get('widgets', []) data = self.prepare(data) changed = False for widget in widgets: if widget.get('name', '') == widgetName: widget.update(data) changed = True break if changed: self.dashboards = 'Changed' if value == 'ajax': return _('Changes saved') return self.nextUrl
def nextUrl(self): """ Redirect to daviz-edit.html as next_url """ IStatusMessage(self.request).addStatusMessage(_('Changes saved'), type='info') next_url = self.context.absolute_url() + '/daviz-edit.html' self.request.response.redirect(next_url)
def nextUrl(self): """ Next URL """ status = queryAdapter(self.request, IStatusMessage) if status: status.addStatusMessage(_('Changes saved'), type='info') to = self.context.absolute_url() + '/daviz-edit.html' self.request.response.redirect(to)
def nextURL(self): """ Next """ status = queryAdapter(self.request, IStatusMessage) if status: status.addStatusMessage(_('Facet added'), type='info') nexturl = self.context.absolute_url() + '/daviz-edit.html' self.request.response.redirect(nexturl)
class EditForm(SubPageForm): """ Common Edit form for widgets """ def prepare(self, data): """ Update data dict """ return data @action(_('Save')) def save(self, saction, data): """ Handle save action """ name = saction.__name__.encode('utf-8') value = self.request.form.get(name, '') widgetName = self.request.form.get('name', '') widgets = self.dashboard.get('widgets', []) data = self.prepare(data) changed = False for widget in widgets: if widget.get('name', '') == widgetName: widget.update(data) changed = True break if changed: self.dashboards = 'Changed' if value == 'ajax': return _('Changes saved') return self.nextUrl @property def _data(self): """ Return view """ widgets = self.dashboard.get('widgets', []) for widget in widgets: if widget.get('name', '') == self.widget_name: return widget return {} def setUpWidgets(self, ignore_request=False): """ Sets up widgets """ self.adapters = {} self.widgets = setUpWidgets(self.form_fields, self.prefix, self.context, self.request, form=self, data=self._data, adapters=self.adapters, ignore_request=ignore_request)
def render(self): """ Render """ if self._finished_add: ajax = (self.request.form.get(self._action, '') == 'ajax') if ajax: return _('Facet added') self.request.response.redirect(self.nextURL()) return "" return super(AddForm, self).render()
def disable(self, saction, data): """ Handle disable action """ mutator = queryAdapter(self.context, IVisualizationConfig) mutator.delete_view(self.prefix) name = saction.__name__.encode('utf-8') value = self.request.form.get(name, '') if value == 'ajax': return _('View disabled') return self.nextUrl
class View(ViewForm): """ Tile view """ label = _('Data settings') implements(IDataView) @property def tabs(self): """ Tab(s) headers to be displayed in view mode """ return []
def save(self, saction, data): """ Handle save action """ mutator = queryAdapter(self.context, IVisualizationConfig) mutator.edit_view(self.prefix, **data) name = saction.__name__.encode('utf-8') value = self.request.form.get(name, '') if value == 'ajax': return _('Changes saved') return self.nextUrl
def render(self): """ Render """ if self._finished_add: ajax = self.request.form.get(self._action, "") == "ajax" if ajax: return _("Facet added") self.request.response.redirect(self.nextURL()) return "" return super(AddForm, self).render()
def save(self, saction, data): """ Handle save action """ mutator = queryAdapter(self.context, IVisualizationConfig) mutator.edit_view(self.prefix, **data) invokeFactory = getattr(self.context, 'invokeFactory', None) if invokeFactory and self.previewname: if not self.context.get(self.previewname, None): img = self.context.restrictedTraverse( "++resource++" + self.previewname) invokeFactory('Image', id=self.previewname, title=self.previewname, image=img.GET()) name = saction.__name__.encode('utf-8') value = self.request.form.get(name, '') if value == 'ajax': return _('Changes saved') return self.nextUrl
class AddForm(SubPageForm): """ Common add form for widgets """ def prepare(self, data): """ Prepare data to be saved """ chooser = queryAdapter(self.context, INameChooser) if not chooser: chooser = queryAdapter(self.context.getParentNode(), INameChooser) name = data.get('name', 'widget') data.setdefault('title', name) data['name'] = chooser.chooseName(name, self.context) data['wtype'] = self.__name__.replace('.add', '', 1) data['dashboard'] = { 'width': 800, 'height': 600, 'order': 997, 'hidden': False } return data @action(_('Save')) def save(self, saction, data): """ Handle save action """ self.dashboard.setdefault('widgets', []) data = self.prepare(data) for widget in self.dashboard.get('widgets', []): if data.get('name', '') == widget.get('name', '') and \ data.get('wtype', '') == widget.get('wtype', ''): return u'Invalid name. Widget not added' self.dashboard['widgets'].append(data) self.dashboards = 'Changed' name = saction.__name__.encode('utf-8') value = self.request.form.get(name, '') if value == 'ajax': return 'Changes saved' return self.nextUrl
def save(self, saction, data): """ Handle save action """ mutator = queryAdapter(self.context, IVisualizationConfig) mutator.edit_view(self.prefix, **data) invokeFactory = getattr(self.context, 'invokeFactory', None) if invokeFactory and self.previewname: if not self.context.get(self.previewname, None): img = self.context.restrictedTraverse("++resource++" + self.previewname) invokeFactory('Image', id=self.previewname, title=self.previewname, image=img.GET()) name = saction.__name__.encode('utf-8') value = self.request.form.get(name, '') if value == 'ajax': return _('Changes saved') return self.nextUrl
class IVisualizationEditFacet(Interface): """ Edit facet """ label = schema.TextLine(title=_(u'Friendly name'), description=_(u'Label for exhibit facet')) show = schema.Bool(title=_(u'Visible'), description=_(u'Is this facet visible?'), required=False) type = schema.Choice( title=_(u"Facet type"), description=_('Exhibit facet type'), default=u'daviz.list.facet', required=True, vocabulary=u"eea.daviz.vocabularies.FacetTypesVocabulary")
class ForbiddenVisualizations(object): """ Enable / disable visualizations per content-type """ implements(IDavizSection) prefix = 'forbidden' title = _('Enable / Disable') def __init__(self): voc = queryUtility(IVocabularyFactory, name=u'eea.daviz.vocabularies.ViewsVocabulary') value_type = schema.Choice( vocabulary="plone.app.vocabularies.UserFriendlyTypes") fields = [] for term in voc(): field = schema.List(__name__='.'.join((self.prefix, term.value)), title=u'Disable ' + term.title, description=(u"Disable %s for the " "following content-types" % term.title), required=False, value_type=value_type) fields.append(field) self.form_fields = FormFields(*fields)
class IVisualizationAddFacet(Interface): """ Add facet """ name = schema.TextLine(title=_(u'Id'), description=_( u"Facet id. Same as the key id in your JSON. " "(e.g. publishDate)")) label = schema.TextLine( title=_(u'Friendly name'), description=_(u"Label for facet (e.g. Effective Date)"), required=False) type = schema.Choice( title=_(u"Facet type"), description=_('Exhibit facet type'), default=u'daviz.list.facet', required=True, vocabulary=u"eea.daviz.vocabularies.FacetTypesVocabulary")
class IVisualizationView(IBrowserView): """ Access / update visualization view configuration """ label = TextLine(title=_(u'Label for visualization view'))
def handle_facetDelete(self, **kwargs): """ Delete facet """ mutator = queryAdapter(self.context, IVisualizationConfig) name = kwargs.get('name', '') ajax = (kwargs.get('daviz.facet.delete') == 'ajax') try: mutator.delete_facet(name) except KeyError, err: logger.exception(err) return self._redirect(err, ajax) else: event.notify( VisualizationFacetDeletedEvent(self.context, facet=name)) return self._redirect(_('Exhibit facet deleted'), ajax) def handle_viewEnable(self, **kwargs): """ Enable view """ mutator = queryAdapter(self.context, IVisualizationConfig) name = kwargs.get('name', '') ajax = (kwargs.get('daviz.view.enable') == 'ajax') try: mutator.add_view(name) except Exception, err: logger.exception(err) return self._redirect(err, ajax) return self._redirect(_('View enabled'), ajax) def handle_views(self, **kwargs):
class IListProperties(IVisualizationEditFacet): """ Edit numeric facet """ ex_height = schema.TextLine( title=_(u"Height"), description=_(u"height of the facet's body, e.g., '20em', '200px'"), required=False, default=u"" ) ex_sortMode = schema.Choice( title=_(u"Sort mode"), description=_(u"how to sort the choices in the facet"), required=False, default=u"value", vocabulary=SimpleVocabulary([ SimpleTerm(u"value", u"value", u"Value"), SimpleTerm(u"count", u"count", u"Count"), ]) ) ex_sortDirection = schema.Choice( title=_(u"Sort direction"), description=_(u"whether to reverse the sort direction"), required=False, default=u"forward", vocabulary=SimpleVocabulary([ SimpleTerm(u"forward", u"forward", u"Forward"), SimpleTerm(u"reverse", u"reverse", u"Reverse"), ]) ) ex_showMissing = schema.Bool( title=_(u"Show missing"), description=_(u"whether to provide a selection for items missing " "the facet -- this will suppress the " "'(missing this field)' text"), required=False, default=True ) ex_missingLabel = schema.TextLine( title=_(u"Missing label"), description=_(u"missing label"), required=False, default=u"" ) ex_selection = schema.TextLine( title=_(u"Selection"), description=_(u"semicolon-separated list of default selections"), required=False, default=u"" ) ex_fixedOrder = schema.TextLine( title=_(u"Fixed Order"), description=_(u"semicolon-separated list of values specifying a " "fixed order for sorting the choices in the facet, " "e.g., 'Mo;Tu;We;Th;Fr' for weekdays"), required=False, default=u"" ) ex_scroll = schema.Bool( title=_(u"Scroll"), description=_(u"if true, facet values are in a scrollable window " "of fixed size. If false, all facet values are shown " "in as much space as needed, without a scroll bar."), required=False, default=True ) ex_collapsible = schema.Bool( title=_(u"Collapsible"), description=_(u"collapsible"), required=False, default=False ) ex_collapsed = schema.Bool( title=_(u"Collapsed"), description=_(u"collapsed"), required=False, default=False ) ex_colorCoder = schema.TextLine( title=_(u"Color coder"), description=_(u"color coder"), required=False, default=u"" ) ex_formatter = schema.TextLine( title=_(u"Formatter"), description=_(u"formatter"), required=False, default=u"" )
mutator.add_source(**properties) @property def annotations(self): """ Global annotations from portal_daviz """ tool = queryUtility(IDavizSettings) annotations = tool.settings.get('data.annotations', '') annotations = [{ 'name': key, 'title': key } for key in annotations.splitlines()] return simplejson.dumps(annotations) @formaction(_('Save'), condition=haveInputWidgets) def save(self, action, data): """ Handle save action """ self.handle_json(data) self.handle_sources(data) # Return name = action.__name__.encode('utf-8') value = self.request.form.get(name, '') if value == 'ajax': return self.message return self.nextUrl @formaction(_('Disable')) def disable(self, saction, data):
class EditForm(SubPageForm): """ Basic layer to edit daviz views. For more details on how to use this, see implementation in eea.exhibit.views.map.edit.Edit. Assign these attributes in your subclass: - form_fields: Fields(Interface) """ form_fields = None previewname = None def __init__(self, context, request): """ EditForm init """ super(EditForm, self).__init__(context, request) name = self.__name__ if isinstance(name, unicode): name = name.encode('utf-8') self.prefix = name.replace('.edit', '', 1) @property def _data(self): """ Return view """ accessor = queryAdapter(self.context, IVisualizationConfig) return accessor.view(self.prefix, {}) def setUpWidgets(self, ignore_request=False): """ Sets up widgets """ self.adapters = {} self.widgets = setUpWidgets(self.form_fields, self.prefix, self.context, self.request, form=self, data=self._data, adapters=self.adapters, ignore_request=ignore_request) @action(_('Save')) def save(self, saction, data): """ Handle save action """ mutator = queryAdapter(self.context, IVisualizationConfig) mutator.edit_view(self.prefix, **data) invokeFactory = getattr(self.context, 'invokeFactory', None) if invokeFactory and self.previewname: if not self.context.get(self.previewname, None): img = self.context.restrictedTraverse("++resource++" + self.previewname) invokeFactory('Image', id=self.previewname, title=self.previewname, image=img.GET()) name = saction.__name__.encode('utf-8') value = self.request.form.get(name, '') if value == 'ajax': return _('Changes saved') return self.nextUrl @action(_('Disable')) def disable(self, saction, data): """ Handle disable action """ mutator = queryAdapter(self.context, IVisualizationConfig) mutator.delete_view(self.prefix) name = saction.__name__.encode('utf-8') value = self.request.form.get(name, '') if value == 'ajax': return _('View disabled') return self.nextUrl @property def nextUrl(self): """ Redirect to daviz-edit.html as next_url """ status = queryAdapter(self.request, IStatusMessage) if status: status.addStatusMessage(_('Changes saved'), type='info') next_url = self.context.absolute_url() + '/daviz-edit.html' self.request.response.redirect(next_url)
properties['type'] = 'rdf+xml' mutator.add_source(**properties) @property def annotations(self): """ Global annotations from portal_daviz """ tool = queryUtility(IDavizSettings) annotations = tool.settings.get('data.annotations', '') annotations = [{'name': key, 'title': key} for key in annotations.splitlines()] return simplejson.dumps(annotations) @formaction(_('Save'), condition=haveInputWidgets) def save(self, action, data): """ Handle save action """ self.handle_json(data) self.handle_sources(data) # Return name = action.__name__.encode('utf-8') value = self.request.form.get(name, '') if value == 'ajax': return self.message return self.nextUrl @formaction(_('Disable')) def disable(self, saction, data):
def handle_facetDelete(self, **kwargs): """ Delete facet """ mutator = queryAdapter(self.context, IVisualizationConfig) name = kwargs.get('name', '') ajax = (kwargs.get('daviz.facet.delete') == 'ajax') try: mutator.delete_facet(name) except KeyError, err: logger.exception(err) return self._redirect(err, ajax) else: event.notify(VisualizationFacetDeletedEvent( self.context, facet=name)) return self._redirect(_('Exhibit facet deleted'), ajax) def handle_viewEnable(self, **kwargs): """ Enable view """ mutator = queryAdapter(self.context, IVisualizationConfig) name = kwargs.get('name', '') ajax = (kwargs.get('daviz.view.enable') == 'ajax') try: mutator.add_view(name) except Exception, err: logger.exception(err) return self._redirect(err, ajax) return self._redirect(_('View enabled'), ajax) def handle_views(self, **kwargs):
class Edit(EditForm): """ Edit view """ label = _(u"Data settings") form_fields = Fields(IDataEdit) previewname = "daviz.properties.preview.png" message = _('Changes saved') @property def _data(self): """ Form data """ accessor = queryAdapter(self.context, IVisualizationConfig) json = simplejson.dumps(dict(accessor.json), indent=2) utils = queryUtility(IVisualizationJsonUtils) return { 'name': self.prefix, 'json': utils.sortProperties(json, indent=2), 'views': [view.get('name') for view in accessor.views], 'sources': [source.get('name') for source in accessor.sources], } def setUpWidgets(self, ignore_request=False): """ Setup widgets """ self.adapters = {} for key, value in self.request.form.items(): if isinstance(value, str): value = value.decode('utf-8') self.request.form[key] = value self.widgets = setUpWidgets(self.form_fields, self.prefix, self.context, self.request, form=self, data=self._data, adapters=self.adapters, ignore_request=ignore_request) def handle_json(self, data): """ Handle json property """ mutator = queryAdapter(self.context, IVisualizationConfig) old_columns = set(mutator.json.get('properties', {}).keys()) json = data.get('json', None) if json is None: return try: json = dict(simplejson.loads(json)) except Exception, err: logger.exception(err) self.message = "ERROR: %s" % err return properties = json.get('properties', {}) new_columns = set(properties.keys()) for _name, props in properties.items(): columnType = props.get('columnType', props.get('valueType', 'text')) util = queryUtility(IGuessType, columnType) if not util: continue props['columnType'] = columnType props['valueType'] = util.valueType # Columns deleted for column in old_columns.difference(new_columns): notify(VisualizationFacetDeletedEvent(self.context, facet=column)) mutator.json = json notify(ObjectModifiedEvent(self.context))
def handle_facetDelete(self, **kwargs): """ Delete facet """ mutator = queryAdapter(self.context, IVisualizationConfig) name = kwargs.get("name", "") ajax = kwargs.get("daviz.facet.delete") == "ajax" try: mutator.delete_facet(name) except KeyError, err: logger.exception(err) return self._redirect(err, ajax) else: event.notify(VisualizationFacetDeletedEvent(self.context, facet=name)) return self._redirect(_("Exhibit facet deleted"), ajax) def handle_viewEnable(self, **kwargs): """ Enable view """ mutator = queryAdapter(self.context, IVisualizationConfig) name = kwargs.get("name", "") ajax = kwargs.get("daviz.view.enable") == "ajax" try: mutator.add_view(name) except Exception, err: logger.exception(err) return self._redirect(err, ajax) return self._redirect(_("View enabled"), ajax) def handle_views(self, **kwargs):