def handle_diff_version(self, action, data): self.status = _("Displaying differences") selected = getSelected(self.selection_column, self.request) if len(selected) not in (1, 2): self.status = _("Select one or two items to show differences") return context = removeSecurityProxy(self.context) source = self._versions.get(selected[0]) try: target = self._versions.get(selected[1]) if source.version_id > target.version_id: t = source source = target target = t except IndexError: target = context diff_view = DiffView(source, target, self.request) self.diff_view = diff_view( *filter(IIModelInterface.providedBy, interface.providedBy(context))) log.debug("handle_diff_version: source=%s target=%s \n%s" % ( source, target, self.diff_view))
def _get_items(self): formatter = self.get_date_formatter("date", "long") trusted = removeSecurityProxy(self.context) user_id = trusted.user_id office_list = [] if interfaces.IMemberOfParliament.providedBy(self.context): parliament_id = trusted.group_id else: parliament = get_parliament_for_group_id(trusted.group_id) if parliament: parliament_id = parliament.parliament_id else: return office_list for oh in get_groups_held_for_user_in_parliament(user_id, parliament_id): title = {} # !+FULL_NAME(mr, oct-2010) this should probably make use of # the GroupDescriptor (combined) listing Field full_name title["group"] = "%s - %s" % (_(oh[0]), oh[1] and _(oh[1]) or "") title["group_type"] = _(oh[2]) if oh[3]: title["member_title"] = _(oh[3]) else: title["member_title"] = _(u"Member") title["start_date"] = None if oh[4]: title["start_date"] = formatter.format(oh[4]) elif oh[6]: title["start_date"] = formatter.format(oh[6]) title["end_date"] = None if oh[5]: title["end_date"] = formatter.format(oh[5]) elif oh[7]: title["end_date"] = formatter.format(oh[7]) office_list.append(title) return office_list
def getMessage(self): """Check signatories validator and generate status message of the form {"level": <level> , "message_text": "<i18n_message>"} """ message = {"level": "info", "message_text": u""} validator = ISignatoriesValidator(self.context, None) if validator is None: return message if validator.requireSignatures(): if validator.validateConsentedSignatories(): message["message_text"] = _("signature_requirement_met", default=(u"This document has the required number of " u"signatories. ${signed_members} member(s) have signed" u". ${required_members} signature(s) required." ), mapping = { "signed_members": validator.consented_signatories, "required_members": validator.min_signatories } ) else: message["level"] = "warning" message["message_text"] = _("signature_requirements_not_met", default=(u"This document does not have the required " u"number of signatories. Requires " u"${required_members} signature(s). " u"${signed_members} member(s) have signed." ), mapping={ "required_members": validator.min_signatories, "signed_members": validator.consented_signatories } ) return message
def form_name(self): if IVersion.providedBy(self.context): context = self.context.head else: context = self.context props = IDCDescriptiveProperties.providedBy(context) and context or IDCDescriptiveProperties(context) if self.is_translation: language = get_language_by_name(self.context.language)["name"] return _( u"edit_translation_legend", default=u"Editing $language translation of '$title'", mapping={"title": translate(props.title, context=self.request), "language": language}, ) elif IVersion.providedBy(self.context): return _( u"edit_version_legend", default=u'Editing "$title" (version $version)', mapping={"title": translate(props.title, context=self.request), "version": self.context.version_id}, ) return _( u"edit_item_legend", default=u'Editing "$title"', mapping={"title": translate(props.title, context=self.request)}, )
def handle_filter(self, action, data): start_date = data.get("range_start_date") end_date = data.get("range_end_date") params = {} if start_date and end_date: if start_date > end_date: self.status = _("Invalid Date Range") cookies.unset_date_range(self.request) return start, end = self.get_start_end_restictions(self.context) if start_date and end: if start_date > end: self.status = (_("Start date must be before %s") % end.strftime("%d %B %Y")) cookies.unset_date_range(self.request) return if end_date and start: if end_date < start: self.status = (_("End date must be after %s") % start.strftime("%d %B %Y")) cookies.unset_date_range(self.request) return cookies.set_date_range(self.request, start_date, end_date) self.request.response.redirect( "?portal_status_message=%s" % translate( _(u"Date range set")))
def validate(self, action, data): errors = super(ReportView, self).validate(action, data) time_span = self.time_span(data) if IGroupSitting.providedBy(self.context): if not self.context.items: errors.append(interface.Invalid( _(u"The sitting has no scheduled items"))) else: start_date = data["date"] if "date" in data else \ datetime.datetime.today().date() end_date = self.get_end_date(start_date, time_span) try: ctx = ISchedulingContext(self.context) except: errors.append(interface.Invalid( _(u"You are trying to generate a report " "outside scheduling") ) ) sittings = ctx.get_sittings(start_date, end_date).values() if not sittings: errors.append(interface.Invalid( _(u"The period selected has no sittings"), "date")) parliament = queries.get_parliament_by_date_range( start_date, end_date ) if parliament is None: errors.append(interface.Invalid( _(u"A parliament must be active in the period"), "date")) return errors
def tabledDocumentOptions(context): items = (_(u"Title"), _(u"Number"), _(u"Text"), _(u"Owner"), ) return SimpleVocabulary.fromValues(items)
def action_message(self): if self._can_sign_document(None): return _("Please confirm that you wish to sign" " this document") elif self._can_review_signature(None): return _(u"You have already signed this document") else: return _(u"You may not sign this document")
def update(self, transition_id=None): if IWorkspaceContainer.providedBy(self.context.__parent__): self._old_url = WorkspaceAbsoluteURLView( self.context, self.request)() workflow = interfaces.IWorkflow(self.context) if transition_id: transition = workflow.get_transition(transition_id) title = translate(_(transition.title), context=self.request) self.status = translate( _(u"Confirmation required for workflow transition: '${title}'", mapping={"title": title} ), context=self.request) self.setupActions(transition_id) if (IBungeniParliamentaryContent.providedBy(self.context) and get_mask(self.context) == "manual" and not self.context.registry_number ): self.form_fields = self.form_fields.omit("note", "date_active") else: self.form_fields = self.form_fields.omit("registry_number") if not self.actions: self.form_fields = self.form_fields.omit("note", "date_active") elif not IFeatureAudit.providedBy(self.context): self.form_fields = self.form_fields.omit("note", "date_active") # !+SUPERFLUOUS_ObejctModifiedEvent(mr, nov-2011) the following update() # is causing a ModifiedEvent to be fired, causing a modify change to be # logged (while this workflow change should be just that). super(WorkflowActionViewlet, self).update()
def update(self, transition=None): self.adapters = {self.IWorkflowComment: WorkflowComment()} wf = interfaces.IWorkflow(self.context) if transition is not None: state_transition = wf.getTransitionById(transition) self.status = _( u"Confirmation required for workflow transition: '${title}'", mapping={"title": _(state_transition.title)}, ) self.setupActions(transition) super(WorkflowActionViewlet, self).update() # after we transition we have different actions self.setupActions(transition) # only display the notes field to comment if there is an action # and a log table auditor = audit.getAuditor(self.context) if len(self.actions) == 0: self.form_fields = self.form_fields.omit("note") elif auditor is None: self.form_fields = self.form_fields.omit("note") else: note_widget = TextAreaWidget note_widget.height = 1 self.form_fields["note"].custom_widget = note_widget self.setUpWidgets()
def validate(self, action, data): # submitted data is actually updated in following call to super.validate # !+PASTDATAENTRY(mr, jun-2011) enhancement? see Issue 612 Comment 6: # unrequire, allow active_date=None, # get_effective_active_date -> last workflow non-None active_date errors = super(WorkflowActionViewlet, self).validate(action, data) if "date_active" in data.keys(): min_date_active = self.get_min_date_active() if data.get("date_active") < min_date_active: errors.append(zope.interface.Invalid( _("Active Date is in the past."))) elif data.get("date_active") > datetime.datetime.now(): errors.append(zope.interface.Invalid( _("Active Date is in the future."))) if "registry_number" in data.keys(): reg_number = data.get("registry_number") if reg_number: session = Session() num = session.query(ParliamentaryItem).filter(ParliamentaryItem.registry_number==reg_number).count() if num != 0: errors.append(zope.interface.Invalid( _("This regisrty number is already taken."))) return errors
def billOptions(context): items = (_(u"Title"), _(u"Summary"), _(u"Text"), _(u"Owner"), _(u"Signatories"), ) return SimpleVocabulary.fromValues(items)
def motionOptions(context): items = (_(u"Title"), _(u"Number"), _(u"Text"), _(u"Owner"), _(u"Signatories"), ) return SimpleVocabulary.fromValues(items)
def availableItems(context): items = (_(u"Bills"), _(u"Agenda Items"), _(u"Motions"), _(u"Questions"), _(u"Tabled Documents"), ) return SimpleVocabulary.fromValues(items)
def __init__(self, context, request): browser.BungeniBrowserView.__init__(self, context, request) AuditLogMixin.__init__(self) if hasattr(self.context, "short_name"): self._page_title = "%s: %s" % ( _(self._page_title), _(self.context.short_name)) else: self._page_title = _(self.__class__._page_title)
def questionOptions(context): items = (_(u"Title"), _(u"Number"), _(u"Text"), _(u"Owner"), #"Response", _(u"Type"), ) return SimpleVocabulary.fromValues(items)
def validate_recurring_sittings(action, data, context, container): """Validate recurring sittings. This validator determines the sittings that will be created and confirms the validity of them. """ start = data.get("start_date") end = data.get("end_date") weekdays = data.get("weekdays") monthly = data.get("monthly") repeat = data.get("repeat") repeat_until = data.get("repeat_until") exceptions = data.get("exceptions", ()) session = Session() group_id = container.__parent__.group_id group = session.query(domain.Group).get(group_id) errors = [] if weekdays or monthly: # this should be an invariant, but due to formlib's requirement # that invariant methods pertain to a single schema, it's not # possible if repeat_until is not None and repeat_until < start.date(): #session.close() return [Invalid( _(u"If recurrence is limited by date, it " "must lie after the starting date"), "repeat_until")] # verify that dates do not violate group's end date for date in generate_recurring_sitting_dates( start.date(), repeat, repeat_until, weekdays, monthly, exceptions): if group.end_date is not None and date > group.end_date: errors.append(Invalid( _(u"One or more events would be scheduled for $F, which is " "after the scheduling group's end date", mapping={"F":datetimedict.fromdate(date)}), "repeat" if repeat else "repeat_until")) break event_data = { "start_date": datetime.datetime( date.year, date.month, date.day, start.hour, start.minute), "end_date": datetime.datetime( date.year, date.month, date.day, end.hour, end.minute), } errors.extend(validate_non_overlapping_sitting( action, event_data, context, container, "weekdays" if weekdays else "monthly")) if errors: break errors.extend(validate_venues( action, data, context, container)) if errors: break return logged_errors(errors, "validate_recurring_sittings")
def handle_revert_version(self, action, data): selected = getSelected(self.selection_column, self.request) if len(selected) != 1: self.status = _("Select one item to revert to") return version = self._versions.get(selected[0]) message = data["commit_message"] self._versions.revert(version, message) self.status = (_(u"Reverted to Previous Version %s") %(version.version_id))
def _format_description_workflow(change): # !+ workflow transition change log stores the (unlocalized) # human title for the transition's destination workflow state extras = _eval_as_dict(change.notes) return ('%s <span class="workflow_info">%s</span> ' '%s <span class="workflow_info">%s</span>' % ( _("from"), _(extras.get("source", None)), _("to"), _(extras.get("destination", None)) ))
def validate_chamber_dates(action, data, context, container): """Chambers start must be after start of the Legislature. The start and end date of *chambers of same type* may not overlap. """ errors = [] start_date = data["start_date"] end_date = data.get("end_date") parliament_type = data["parliament_type"] if interfaces.IParliament.providedBy(context): chamber = context else: chamber = None # whether uni- or bicameral, chamber dates may NOT overlap with those of # another chamber of the SAME TYPE def get_others_overlapping_date(chamber, date): return [ result for result in queries.validate_date_in_interval(chamber, domain.Parliament, date) if result.parliament_type == parliament_type ] legislature = capi.legislature if start_date: for res in get_others_overlapping_date(chamber, start_date): errors.append(Invalid( _("Start date overlaps with (%s)") % res.short_name, "start_date")) if start_date < legislature.start_date: errors.append(Invalid( _("Start date preceeds legislature start (%s)") % ( legislature.start_date), "start_date")) if end_date: for res in get_others_overlapping_date(chamber, end_date): errors.append( Invalid(_("End date overlaps with (%s)") % res.short_name, "end_date")) if legislature.end_date: if end_date > legislature.end_date: errors.append(Invalid( _("End date later legislature end (%s)") % ( legislature.end_date), "end_date")) if chamber is None: results = queries.validate_open_interval(chamber, domain.Parliament) for result in results: if result.parliament_type == parliament_type: errors.append(Invalid( _("Another chamber is not yet dissolved (%s)") % ( result.short_name), "election_date")) return logged_errors(errors, "validate_chamber_dates")
def columns(self): return [ column.GetterColumn(title=_("file"), getter=lambda i,f: "%s" % (i.title), cell_formatter=lambda g,i,f: '<a href="%s/files/obj-%d">%s</a>' % (f.url, i.attachment_id, g)), column.GetterColumn(title=_("status"), getter=lambda i,f: i.status), column.GetterColumn(title=_("modified"), getter=lambda i,f: self.date_formatter.format(i.status_date)), ]
def generate_preview(self): sitting = removeSecurityProxy(self.context) wf = IWorkflow(sitting) sittings = [data.ExpandedSitting(sitting)] generator = generators.ReportGeneratorXHTML(self.get_template()) if sitting.status in wf.get_state_ids(tagged=["publishedminutes"]): title = generator.title = _(u"Sitting Votes and Proceedings") else: title = generator.title = _(u"Sitting Agenda") generator.context = data.ReportContext(sittings=sittings, title=title) return generator.generateReport()
def validate(self, action, data): # submitted data is actually updated in following call to super.validate errors = super(WorkflowActionViewlet, self).validate(action, data) if "date_active" in data.keys(): min_date_active = self.get_min_date_active() if data.get("date_active") < min_date_active: errors.append(zope.interface.Invalid( _("Active Date is too old."))) elif data.get("date_active") > datetime.now(): errors.append(zope.interface.Invalid( _("Active Date is in the future."))) return errors
def validate_email_availability(action, data, context, container): session = Session() users = session.query(domain.User ).filter(domain.User.email==data.get("email", "")) if users.count() > 1: return [Invalid(_(u"Email already taken!"), "email")] if context: if users.count() == 1 and users.first().user_id != context.user_id: return [Invalid(_(u"Email already taken!"), "email")] elif users.count() > 0: return [Invalid(_(u"Email already taken!"), "email")] return []
def __init__(self, context, request): super(FileListingView, self).__init__(context.__parent__, request) formatter = date.getLocaleFormatter(self.request, "dateTime", "short") self.columns = [ column.GetterColumn( title=_(u"file"), getter=lambda i, f: '<a href="%s/files/obj-%d">%s</a>' % (f.url, i.attached_file_id, i.file_title), ), column.GetterColumn(title=_(u"status"), getter=lambda i, f: i.status), column.GetterColumn(title=_(u"modified"), getter=lambda i, f: formatter.format(i.status_date)), ]
def __init__(self, context, request, view, manager): self.context = context self.request = request self.__parent__ = view self.manager = manager self.wf_status = u"new" self.has_status = False # table to display the workflow history self.columns = [ column.GetterColumn(title=_(u"date"), getter=lambda i, f: i["date"].strftime("%Y-%m-%d %H:%M")), column.GetterColumn(title=_(u"user"), getter=lambda i, f: i["user_id"]), column.GetterColumn(title=_(u"description"), getter=lambda i, f: i["description"]), ]
def generate_preview(self): sitting = removeSecurityProxy(self.context) sittings = [data.ExpandedSitting(sitting)] generator = generators.ReportGeneratorXHTML(self.get_template()) #!+TAGS(mb, Feb-2013) Deprecate with tags. Configure as wf/feature. if "minutes" in sitting.status: title = generator.title = _(u"Sitting Votes and Proceedings") else: title = generator.title = _(u"Sitting Agenda") generator.context = data.ReportContext( sittings=sittings, title=title ) return generator.generateReport()
def columns(self): def attachment_version_uri(i): # !+ bungeni.models.domain.Version return "obj-%d/version-log/%s" % (i.attachment_id, i.__name__) return [ column.GetterColumn(title=_("file"), getter=lambda i,f:"%s" % (i.title), cell_formatter=lambda g,i,f:'<a href="%s/files/%s">%s</a>' % (f.url, attachment_version_uri(i), g)), column.GetterColumn(title=_("status"), getter=lambda i,f:i.status), column.GetterColumn(title=_("modified"), getter=lambda i,f:self.date_formatter.format(i.status_date)), ]
def validate(self, action, data): # submitted data is actually updated in following call to super.validate # !+PASTDATAENTRY(mr, jun-2011) enhancement? see Issue 612 Comment 6: # unrequire, allow active_date=None, # get_effective_active_date -> last workflow non-None active_date errors = super(WorkflowActionViewlet, self).validate(action, data) if "date_active" in data.keys(): min_date_active = self.get_min_date_active() if data.get("date_active") < min_date_active: errors.append(zope.interface.Invalid( _("Active Date is too old."))) elif data.get("date_active") > datetime.datetime.now(): errors.append(zope.interface.Invalid( _("Active Date is in the future."))) return errors
def form_description(self): language = get_language_by_name(self.language)["name"] props = IDCDescriptiveProperties.providedBy(self.context) \ and self.context or IDCDescriptiveProperties(self.context) if self.is_translation: return _(u"edit_translation_legend", default=u'Editing $language translation of "$title"', mapping={"title": translate(props.title, context=self.request), "language": language}) else: return _( u"translate_item_help", default=u'The document "$title" has not yet been translated into $language. Use this form to add the translation', mapping={"title": translate(props.title, context=self.request), "language": language})
class TIME_SPAN: daily = _(u"Daily") weekly = _(u"Weekly")
def substituted_end_date(obj): """If a person is substituted he must have an end date.""" if not obj.end_date and obj.replaced_id: raise Invalid(_("If a person is substituted End Date must be set"), "replaced_id", "end_date")
def parliament_start_after_election(obj): """Start Date must be after Election Date.""" if obj.election_date >= obj.start_date: raise Invalid( _("The life of a parliament must start after its election"), "election_date", "start_date")
class LibraryViewlet(viewlet.ViewletBase): render = ViewPageTemplateFile("templates/attached-files.pt") form_name = _("attached files") for_display = True weight = 50 def __init__(self, context, request, view, manager): self.context = [] trusted = removeSecurityProxy(context) # !+(murithi, mar-2010 )Attached file versions implement IVersion # but have no attached files - an adapter on all content # might make sense to fetch attachments. # here we conditionaly skip attachment versions if not IAttachedFileVersion.providedBy(trusted): for f in trusted.attached_files: if IAttachedFileVersion.providedBy(f): self.context.append(f) else: if f.attached_file_type != "system": self.context.append(f) self.request = request self.__parent__ = context self.manager = manager self.query = None self.for_display = len(self.context) > 0 self.interaction = getInteraction() self.formatter = utils.date.getLocaleFormatter(self.request, "date", "long") def results(self): for data in self.context: yield { "title": data.file_title, "url": "./files/obj-%i" % data.attached_file_id, "name": data.file_name, "type": _(data.attached_file_type), "status_date": self.formatter.format(data.status_date), "menu": self.generate_file_manipulation_menu(data) } def generate_file_manipulation_menu(self, context): menu_items = [] view_item = self.create_view_menu_item(context) if view_item: menu_items.append(view_item) edit_item = self.create_edit_menu_item(context) if edit_item: menu_items.append(edit_item) delete_item = self.create_delete_menu_item(context) if delete_item: menu_items.append(delete_item) download_item = self.create_download_menu_item(context) if download_item: menu_items.append(download_item) return menu_items def create_view_menu_item(self, context): permission_name = "bungeni.fileattachment.View" if self.interaction.checkPermission(permission_name, self.__parent__): return { "title": _("VIEW"), "url": "./files/obj-%i" % context.attached_file_id, "active": True } return None def create_edit_menu_item(self, context): permission_name = "bungeni.fileattachment.Edit" if self.interaction.checkPermission(permission_name, self.__parent__): return { "title": _("EDIT"), "url": "./files/obj-%i/edit" % context.attached_file_id, "active": True } return None def create_delete_menu_item(self, context): permission_name = "bungeni.fileattachment.Delete" if self.interaction.checkPermission(permission_name, self.__parent__): return { "title": _("DELETE"), "url": "./files/obj-%i/deactivate" % context.attached_file_id, "active": context.status != "inactive" } return None def create_download_menu_item(self, context): permission_name = "bungeni.fileattachment.View" if self.interaction.checkPermission(permission_name, self.__parent__): return { "title": _("DOWNLOAD"), "url": "./files/obj-%i/download" % context.attached_file_id, "active": True } return None
class ItemArchiveViewlet(OwnedItemsInStageViewlet): name = _("archived items") states = get_archived_states() list_id = "items-archived"
class SpeakersClerkItemActionRequiredViewlet(ClerkItemActionRequiredViewlet): name = _("pending with the clerk") list_id = "clerks-items-action-required"
def get_wf_state(self): """Get the human readable, and localized, workflow state title. """ return _(misc.get_wf_state(removeSecurityProxy(self.context)))
class DeleteForm(PageForm): """Delete-form for Bungeni content. Confirmation The user is presented with a confirmation form which details the items that are going to be deleted. Subobjects Recursively, a permission check is carried out for each item that is going to be deleted. If a permission check fails, an error message is displayed to the user. Will redirect back to the container on success. """ # evoque template = z3evoque.PageViewTemplateFile("delete.html") # zpt # !+form_template(mr, jul-2010) this is unused here, but needed by # some adapter of this "object delete" view #form_template = NamedTemplate("alchemist.form") #template = ViewPageTemplateFile("templates/delete.pt") _next_url = None form_fields = formlib.form.Fields() def _can_delete_item(self, action): return True def nextURL(self): return self._next_url def update(self): self.subobjects = self.get_subobjects() super(DeleteForm, self).update() def get_subobjects(self): return () def delete_subobjects(self): return 0 @formlib.form.action(_(u"Delete"), condition=_can_delete_item) def handle_delete(self, action, data): count = self.delete_subobjects() container = self.context.__parent__ trusted = removeSecurityProxy(self.context) session = Session() session.delete(trusted) count += 1 try: session.commit() except IntegrityError, e: # this should not happen in production; it's a critical # error, because the transaction might have failed in the # second phase of the commit session.rollback() log.critical(e) self.status = _(u"Could not delete item due to " "database integrity error") return self.render() # !+SESSION_CLOSE(taras.sterch, july-2011) there is no need to close the # session. Transaction manager will take care of this. Hope it does not # brake anything. #session.close() #TODO: check that it is removed from the index! notify(ObjectRemovedEvent( self.context, oldParent=container, oldName=self.context.__name__)) # we have to switch our context here otherwise the deleted object will # be merged into the session again and reappear magically self.context = container next_url = self.nextURL() if next_url is None: next_url = url.absoluteURL(container, self.request) + \ "/?portal_status_message=%d items deleted" % count self.request.response.redirect(next_url)
def title(self): language = get_language_by_name(self.language)["name"] return _(u"translate_item_title", default=u"Adding $language translation", mapping={"language": language} )
def form_name(self): language = get_language_by_name(self.language)["name"] return _(u"translate_item_legend", default=u"Add $language translation", mapping={"language": language} )
class TranslateForm(AddForm): """Custom translate-form for Bungeni content. """ is_translation = False @property def side_by_side(self): return True def __init__(self, *args): # !+view/viewlet(mr, jul-2011) super(TranslateForm, self).__init__(*args) self.language = self.request.get("language", get_default_language()) def translatable_field_names(self): trusted = removeSecurityProxy(self.context) table = rdb.orm.object_mapper(trusted).mapped_table names = ["language"] for column in table.columns: if type(column.type) in [rdb.Unicode, rdb.UnicodeText]: names.append(column.name) return names def set_untranslatable_fields_for_display(self): md = queryModelDescriptor(self.context.__class__) for field in self.form_fields: if field.__name__ not in self.translatable_field_names(): field.for_display = True field.custom_widget = md.get(field.__name__).view_widget def validate(self, action, data): return formlib.form.getWidgetsData(self.widgets, self.prefix, data) @property def form_name(self): language = get_language_by_name(self.language)["name"] return _(u"translate_item_legend", default=u"Add $language translation", mapping={"language": language} ) @property def form_description(self): language = get_language_by_name(self.language)["name"] props = ( (IDCDescriptiveProperties.providedBy(self.context) and self.context) or IDCDescriptiveProperties(self.context) ) if self.is_translation: return _(u"edit_translation_legend", default=u'Editing $language translation of "$title"', mapping={ "title": translate(props.title, context=self.request), "language": language } ) else: return _(u"translate_item_help", default=u'The document "$title" has not yet been translated ' \ u"into $language. Use this form to add the translation", mapping={ "title": translate(props.title, context=self.request), "language": language } ) @property def title(self): language = get_language_by_name(self.language)["name"] return _(u"translate_item_title", default=u"Adding $language translation", mapping={"language": language} ) @property def domain_model(self): return type(removeSecurityProxy(self.context)) def setUpWidgets(self, ignore_request=False): self.set_untranslatable_fields_for_display() #get the translation if available language = self.request.get("language") translation = get_translation_for(self.context, language) if translation: self.is_translation = True else: self.is_translation = False context = copy(removeSecurityProxy(self.context)) for field_translation in translation: setattr(context, field_translation.field_name, field_translation.field_text) self.widgets = formlib.form.setUpEditWidgets( self.form_fields, self.prefix, context, self.request, adapters=self.adapters, ignore_request=ignore_request) if language is not None: widget = self.widgets["language"] try: self.language = language widget.vocabulary = CurrentLanguageVocabulary().__call__(self) widget.vocabulary.getTermByToken(language) except LookupError: raise BadRequest("No such language token: '%s'" % language) # if the term exists in the vocabulary, set the value on # the widget widget.setRenderedValue(language) # for translations, add a ``render_original`` method to each # widget, which will render the display widget bound to the # original (HEAD) document head = self.context form_fields = ui.setUpFields(self.context.__class__, "view") for widget in self.widgets: form_field = form_fields.get(widget.context.__name__) if form_field is None: form_field = formlib.form.Field(widget.context) # bind field to head document field = form_field.field.bind(head) # create custom widget or instantiate widget using # component lookup if form_field.custom_widget is not None: display_widget = form_field.custom_widget( field, self.request) else: display_widget = component.getMultiAdapter( (field, self.request), IDisplayWidget) display_widget.setRenderedValue(field.get(head)) # attach widget as ``render_original`` widget.render_original = display_widget @formlib.form.action( _(u"Save translation"), condition=formlib.form.haveInputWidgets) def handle_add_save(self, action, data): """After succesful creation of translation, redirect to the view.""" #url = url.absoluteURL(self.context, self.request) #language = get_language_by_name(data["language"])["name"] session = Session() trusted = removeSecurityProxy(self.context) mapper = rdb.orm.object_mapper(trusted) pk = getattr(trusted, mapper.primary_key[0].name) current_translation = get_translation_for(self.context, data["language"]) if current_translation: for translation in current_translation: session.delete(translation) for form_field in data.keys(): if form_field == "language": continue translation = domain.ObjectTranslation() translation.object_id = pk translation.object_type = trusted.__class__.__name__ translation.field_name = form_field translation.lang = data["language"] translation.field_text = data[form_field] session.add(translation) session.flush() # !+SESSION_CLOSE(taras.sterch, july-2011) there is no need to close the # session. Transaction manager will take care of this. Hope it does not # brake anything. #session.commit() #session.close() # !+EVENT_DRIVEN_CACHE_INVALIDATION(mr, mar-2011) no translate event # invalidate caches for this domain object type invalidate_caches_for(trusted.__class__.__name__, "translate") #versions = IVersioned(self.context) #version = versions.create("'%s' translation added" % language) # reset workflow state #version.status = None #IWorkflowController(version).fireTransition("-draft_translation") # redefine form context and proceed with edit action #self.setUpAdapters(version) #handle_edit_action(self, action, data) # commit version such that it gets a version id #transaction.commit() #if not self._next_url: # self._next_url = ( \ # "%s/versions/%s" % (url, stringKey(version)) + \ # "?portal_status_message=Translation added") self._finished_add = True
def form_description(self): if self.is_translation: language = get_language_by_name(self.context.head.language)["name"] return _(u"edit_translation_help", default=u"The original $language version is shown on the left", mapping={"language": language})
class AddForm(BaseForm, catalyst.AddForm): """Custom add-form for Bungeni content. Additional actions are set up to allow users to continue editing an object, or add another of the same kind. """ interface.implements(ILocation, IDCDescriptiveProperties) description = None def getDomainModel(self): return getattr(self.context, "domain_model", self.context.__class__) def validate(self, action, data): errors = super(AddForm, self).validate(action, data) errors += self.validateUnique(action, data) descriptor = queryModelDescriptor(self.domain_model) for validator in getattr(descriptor, "custom_validators", ()): errors += validator(action, data, None, self.context) return errors def validateUnique(self, action, data): """Validate unique. Since this class always adds a single object, we can safely return an empty list of errors. """ errors = [] domain_model = removeSecurityProxy(self.getDomainModel()) # find unique columns in data model.. TODO do this statically mapper = rdb.orm.class_mapper(domain_model) ucols = list(ui.unique_columns(mapper)) # query out any existing values with the same unique values, session = Session() # find data matching unique columns for key, col in ucols: if key in data: # on edit ignore new value if its the same as the previous value if isinstance(self.context, domain_model) \ and data[key] == getattr(self.context, key, None): continue value = session.query(domain_model ).filter(col == data[key]).count() if not value: continue widget = self.widgets[ key ] error = formlib.form.WidgetInputError( widget.name, widget.label, _(u"A record with this value already exists")) widget._error = error errors.append(error) return errors def filter_fields(self): return filterFields(self.context, self.form_fields) def update(self): super(AddForm, self).update() # set humanized default value for choice fields with no defaults for widget in self.widgets: field = widget.context if IChoice.providedBy(field): if IGenenerateVocabularyDefault.providedBy(widget): field.default = widget.getDefaultVocabularyValue() if IChoice.providedBy(field) and field.default is None: widget._messageNoValue = _("bungeni_widget_no_value", "choose ${title} ...", mapping = {"title": field.title} ) @property def domain_model(self): return removeSecurityProxy(self.context).domain_model @property def context_class(self): return self.domain_model @property def type_name(self): descriptor = queryModelDescriptor(self.domain_model) if descriptor: name = getattr(descriptor, "display_name", None) if not name: name = getattr(self.domain_model, "__name__", None) return name @property def form_name(self): return _(u"add_item_legend", default=u"Add $name", mapping={ "name": translate(self.type_name.lower(), context=self.request)}) @property def title(self): return _(u"add_item_title", default=u"Adding $name", mapping={ "name": translate(self.type_name.lower(), context=self.request)}) def finishConstruction(self, ob): """Adapt the custom fields to the object.""" adapts = self.Adapts if adapts is None: adapts = self.model_schema self.adapters = { adapts : ob } def createAndAdd(self, data): added_obj = super(AddForm, self).createAndAdd(data) return added_obj @formlib.form.action( _(u"Save and view"), condition=formlib.form.haveInputWidgets) def handle_add_save(self, action, data): ob = self.createAndAdd(data) name = self.domain_model.__name__ if not self._next_url: self._next_url = url.absoluteURL(ob, self.request) + \ "?portal_status_message=%s added" % name @formlib.form.action(_(u"Cancel"), validator=ui.null_validator) def handle_cancel(self, action, data): """Cancelling redirects to the listing.""" session = Session() if not self._next_url: self._next_url = url.absoluteURL(self.__parent__, self.request) self.request.response.redirect(self._next_url) # !+SESSION_CLOSE(taras.sterch, july-2011) there is no need to close the # session. Transaction manager will take care of this. Hope it does not # brake anything. #session.close() @formlib.form.action(_(u"Save"), condition=formlib.form.haveInputWidgets) def handle_add_edit(self, action, data): ob = self.createAndAdd(data) name = self.domain_model.__name__ if not self._next_url: self._next_url = url.absoluteURL(ob, self.request) + \ "/edit?portal_status_message=%s Added" % name @formlib.form.action( _(u"Save and add another"), condition=formlib.form.haveInputWidgets) def handle_add_and_another(self, action, data): self.createAndAdd(data) name = self.domain_model.__name__ if not self._next_url: self._next_url = url.absoluteURL(self.context, self.request) + \ "/add?portal_status_message=%s Added" % name
def title(self): return _(u"add_item_title", default=u"Adding $name", mapping={ "name": translate(self.type_name.lower(), context=self.request)})
class MinistryItemsViewlet(ViewletBase): list_id = "ministry-items" name = _("questions to the ministry") states = None response_types = ["O", "W"] def _getItems(self, ministry): session = Session() date_formatter = date.getLocaleFormatter(self.request, "date", "long") def _q_data_item(q): item = {} item["qid"] = "q_%s" % q.question_id if q.question_number: item["subject"] = u"Q %s %s (%s)" % (q.question_number, q.short_name, q.status) else: item["subject"] = u"%s (%s)" % (q.short_name, q.status) item["title"] = u"%s (%s)" % (q.short_name, q.status) item["result_item_class"] = "workflow-state-%s" % q.status item["url"] = url.set_url_context("questions/obj-%s" % q.question_id) item["status"] = misc.get_wf_state(q) item["status_date"] = date_formatter.format(q.status_date) item["owner"] = "%s %s" % (q.owner.first_name, q.owner.last_name) item["type"] = _(q.type) if type(q) == domain.Question: item["to"] = q.ministry.short_name else: item["to"] = u"" return item # prepare query for this ministry's questions mq_query = session.query(domain.Question).filter( sql.and_(domain.Question.ministry_id == ministry.group_id, domain.Question.status.in_(self.states), domain.Question.response_type.in_(self.response_types))) return [_q_data_item(question) for question in mq_query.all()] def _setData(self): """ template calls this to get the data of the query setup in update() """ self._data = [ item for ministry in self.query.all() for item in self._getItems(ministry) ] def update(self): """ refresh the query """ session = Session() try: ministry_ids = [m.group_id for m in self.__parent__.ministries] except (Exception, ): debug.log_exc_info(sys.exc_info(), log_handler=log.info) ministry_ids = [] qfilter = domain.Ministry.group_id.in_(ministry_ids) ministries = session.query(domain.Ministry).filter(qfilter).order_by( domain.Ministry.start_date.desc()) self.query = ministries self._setData()
class FailedRegexMatch(zope.schema.ValidationError): """"Regex error initialized with a message displayed to user""" e_message = None def __init__(self, e_message=_(u"Invalid value"), *args, **kwargs): self.e_message = e_message super(FailedRegexMatch, self).__init__(*args, **kwargs) def doc(self): return self.e_message class RegexChecker: """Regex constraint factory""" def __init__(self, regex, e_message): assert type(regex) in [str, unicode] self.regex = regex self.e_message = e_message def __call__(self, value): if type(value) in [str, unicode]: if re.match(self.regex, value) is None: raise FailedRegexMatch(self.e_message) return False return True check_email = RegexChecker(EMAIL_RE, _(u"This is not a valid email address")) check_login = RegexChecker(LOGIN_RE, _(u"Invalid login name"))
class AllItemArchiveViewlet(AllItemsInStageViewlet): types = ["motion", "question", "agendaitem", "tableddocument"] name = _("Archived Items") states = get_archived_states() list_id = "items-archived"
def __init__(self, e_message=_(u"Invalid value"), *args, **kwargs): self.e_message = e_message super(FailedRegexMatch, self).__init__(*args, **kwargs)
class MyGroupsViewlet(ViewletBase): name = _("My Groups") list_id = "my_groups" render = ViewPageTemplateFile("templates/workspace_group_viewlet.pt") def _setData(self): """Return the data of the query """ formatter = date.getLocaleFormatter(self.request, "date", "long") data_list = [] results = self.query.all() # if no current parliament, no data try: parliament_id = model_utils.get_current_parliament().parliament_id except: return data_list # government_id = self.__parent__.government_id for result in results: data = {} data["qid"] = "g_%s" % (result.group_id) data["subject"] = result.short_name data["title"] = "%s (%s)" % (result.short_name, result.type) data["result_item_class"] = "workflow-state-%s" % (result.status) _url = "/archive/browse/parliaments/obj-%s" % (parliament_id) if type(result) == domain.Parliament: data["url"] = url.set_url_context(_url) continue elif type(result) == domain.Committee: #data["url"] = url + "/committees/obj-" + str(result.group_id) data["url"] = url.set_url_context( "/groups/%s/%s" % (result.parent_group.group_principal_id, result.group_principal_id)) elif type(result) == domain.PoliticalGroup: data["url"] = url.set_url_context("%s/politicalgroups/obj-%s" % (_url, result.group_id)) elif type(result) == domain.Ministry: data["url"] = url.set_url_context( "%s/governments/obj-%s/ministries/obj-%s" % (_url, government_id, result.group_id)) else: data["url"] = "#" data["status"] = misc.get_wf_state(result) data["status_date"] = formatter.format(result.status_date) data["owner"] = "" data["type"] = _(result.type) data["to"] = "" data_list.append(data) self._data = data_list def update(self): """refresh the query """ session = Session() #user_id = self.__parent__.user_id #parliament_id = self.__parent__.context.parliament_id group_ids = self.__parent__.user_group_ids gfilter = sql.and_(domain.Group.group_id.in_(group_ids), domain.Group.status == "active") groups = session.query(domain.Group).filter(gfilter) self.query = groups self._setData()
(context:domain.Entity) -> any $Id$ """ log = __import__("logging").getLogger("bungeni_custom.forms") from bungeni.utils.misc import describe from bungeni.ui.i18n import _ # derived fields based on doc workflow dates -- see: # models.domain.Doc._get_workflow_date @describe(_(u"Submission Date")) def submission_date(context): return context._get_workflow_date("submitted") @describe(_(u"Admissible Date")) def admissible_date(context): return context._get_workflow_date("admissible") @describe(_(u"Gazetted Date")) def gazetted_date(context): return context._get_workflow_date("gazetted") @describe(_(u"Scheduled Date"))
def active_and_substituted(obj): """A person cannot be active and substituted at the same time.""" if obj.active_p and obj.replaced_id: raise Invalid( _("A person cannot be active and substituted at the same time"), "active_p", "replaced_id")
class DraftSittingsViewlet(ViewletBase): """The "agendas/minutes" tab in the workspace/pi view for the Clerk. """ # evoque render = z3evoque.ViewTemplateFile("workspace_viewlets.html#sittings") # zpt #render = ViewPageTemplateFile("templates/workspace_sitting_viewlet.pt") name = _("agendas/minutes") states = get_states("groupsitting", tagged=["workspace"]) list_id = "sitting-draft" def _setData(self): """Get the data of the query """ data_list = [] results = self.query.all() formatter = date.getLocaleFormatter(self.request, "date", "long") time_formatter = date.getLocaleFormatter(self.request, "time", "short") for result in results: data = {} data["subject"] = result.short_name # this tab appears in the workspace pi/ view... data["url"] = url.set_url_context( "../calendar/sittings/obj-%i/schedule" % result.sitting_id) # Note: same UI is also displayed at: # /business/sittings/obj-%i/schedule % result.sitting_id data["items"] = "" data["status"] = misc.get_wf_state(result) data["status_date"] = formatter.format(result.status_date) data["owner"] = "" data["type"] = result.group.type data["group"] = u"%s %s" % (result.group.type.capitalize(), result.group.short_name) data["time_from_to"] = (time_formatter.format(result.start_date), time_formatter.format(result.end_date)) data["date"] = formatter.format(result.start_date) if result.venue: data["venue"] = _(result.venue.short_name) #else: # date["venue"] = "" if type(result) == domain.Question: data["to"] = result.ministry.short_name else: data["to"] = "" # past, present, future today = datetime.datetime.today().date() startday = result.start_date.date() if today == startday: data["css_class"] = "present" elif today > startday: data["css_class"] = "past" else: data["css_class"] = "future" data_list.append(data) self._data = data_list def update(self): """Refresh the query """ session = Session() qfilter = domain.GroupSitting.status.in_(self.states) sittings = session.query(domain.GroupSitting).filter(qfilter).order_by( domain.GroupSitting.start_date.desc()).options(eagerload("group")) self.query = sittings self._setData()
def inactive_no_end_date(obj): """If you set a person inactive you must provide an end date.""" if not obj.active_p: if not (obj.end_date): raise Invalid(_("If a person is inactive End Date must be set"), "end_date", "active_p")
class WrittenMinistryQuestionsViewlet(MinistryItemsViewlet): list_id = "ministry-written-questions" name = _("written questions") states = get_states("question", tagged=["written"]) response_types = ["W"]
class RegexChecker(object): """Regex constraint factory""" def __init__(self, regex, e_message): assert isinstance(regex, basestring) self.regex = regex self.e_message = e_message def __call__(self, value): if isinstance(value, basestring): if re.match(self.regex, value) is None: raise FailedRegexMatch(self.e_message) return False return True check_email = RegexChecker(EMAIL_RE, _(u"This is not a valid email address")) check_login = RegexChecker(LOGIN_RE, _(u"Invalid login name")) # schema invariants @describe(_(u"End Date must be after Start Date")) def end_after_start(obj): """End Date must be after Start Date.""" if obj.end_date is None: return if obj.end_date <= obj.start_date: raise Invalid(_("End Date must be after Start Date"), "start_date", "end_date") @describe(
class SaveReportView(form.PageForm): def __init__(self, context, request): super(SaveReportView, self).__init__(context, request) class ISaveReportForm(interface.Interface): start_date = schema.Date( title=_(u"Date"), description=_(u"Choose a starting date for this report"), required=True) end_date = schema.Date( title=_(u"Date"), description=_(u"Choose an end date for this report"), required=True) note = schema.TextLine(title=u"Note", description=u"Optional note regarding this report", required=False) short_name = schema.TextLine(title=u"Report Type", description=u"Report Type", required=True) body = schema.Text(title=u"Report Text", description=u"Report Type", required=True) sittings = schema.TextLine(title=_(u"Sittings included in this report"), description=_(u"Sittings included in this report"), required=False) template = namedtemplate.NamedTemplate("alchemist.form") form_fields = form.Fields(ISaveReportForm) def setUpWidgets(self, ignore_request=False): class context: start_date = None end_date = None body = None note = None short_name = None sittings = None self.adapters = {self.ISaveReportForm: context} self.widgets = form.setUpEditWidgets( self.form_fields, self.prefix, self.context, self.request, adapters=self.adapters, ignore_request=ignore_request ) @form.action(_(u"Save"), name="save") def handle_save(self, action, data): report = domain.Report() session = Session() report.body = data["body"] report.start_date = data["start_date"] report.end_date = data["end_date"] report.note = data["note"] report.short_name = data["short_name"] report.owner_id = get_db_user_id() # !+GROUP_AS_OWNER report.language = get_default_language() report.created_date = datetime.datetime.now() if not hasattr(self.context, "group_id"): report.group_id = ISchedulingContext(self.context).group_id else: report.group_id = self.context.group_id session.add(report) session.flush() notify(ObjectCreatedEvent(report)) if "sittings" in data.keys(): try: ids = data["sittings"].split(",") for id_number in ids: sit_id = int(id_number) sitting = session.query(domain.Sitting).get(sit_id) sr = domain.SittingReport() sr.report = report sr.sitting = sitting session.add(sr) notify(ObjectCreatedEvent(report)) except: #if no sittings are present in report or some other error occurs pass session.flush() if ISitting.providedBy(self.context): back_link = "./schedule" else: back_link = "./" self.request.response.redirect(back_link)
class ReportBuilder(form.Form, DateTimeFormatMixin): template = namedtemplate.NamedTemplate("alchemist.form") form_fields = form.fields(IReportBuilder) form_fields["start_date"].custom_widget = widgets.SelectDateWidget sittings = [] publication_date = datetime.datetime.today().date() publication_number = "" title = _(u"Report Title") generated_content = None show_preview = False language = None def __init__(self, context, request): self.context = context self.request = request interface.declarations.alsoProvides(removeSecurityProxy(self.context), IWorkspaceReportGeneration ) super(ReportBuilder, self).__init__(context, request) def get_end_date(self, start_date, hours): end_date = start_date + datetime.timedelta(seconds=hours*3600) return end_date def buildSittings(self, start_date, end_date): if ISitting.providedBy(self.context): trusted = removeSecurityProxy(self.context) order="real_order" trusted.item_schedule.sort(key=operator.attrgetter(order)) self.sittings.append(trusted) else: sittings = ISchedulingContext(self.context).get_sittings( start_date, end_date ).values() self.sittings = map(removeSecurityProxy, sittings) self.sittings = [ ExpandedSitting(sitting) for sitting in self.sittings ] def generateContent(self, data): self.start_date = (data.get("start_date") or datetime.datetime.today().date() ) generator = generators.ReportGeneratorXHTML(data.get("report_type")) self.language = generator.language self.title = generator.title self.language = generator.language self.publication_number = data.get("publication_number") self.end_date = self.get_end_date(self.start_date, generator.coverage) self.buildSittings(self.start_date, self.end_date) generator.context = self return generator.generateReport() @form.action(_(u"Preview"), name="preview") def handle_preview(self, action, data): """Generate preview of the report """ self.show_preview = True self.generated_content = self.generateContent(data) self.status = _(u"See the preview of the report below") return self.template() @form.action(_(u"Publish"), name="publish") def handle_publish(self, action, data): self.generated_content = self.generateContent(data) if not hasattr(self.context, "group_id"): context_group_id = ISchedulingContext(self.context).group_id else: context_group_id = self.context.group_id report = domain.Report( short_title=self.title, start_date=self.start_date, end_date=self.end_date, body=self.generated_content, owner_id=get_db_user_id(), # !+GROUP_AS_OWNER language=self.language, group_id=context_group_id ) session = Session() session.add(report) session.flush() notify(ObjectCreatedEvent(report)) self.status = _(u"Report has been processed and saved") return self.template()
class OralMinistryQuestionsViewlet(MinistryItemsViewlet): list_id = "ministry-oral-questions" name = _("oral questions") states = get_states("question", tagged=["oral"]) response_types = ["O"]
class EditForm(BaseForm, catalyst.EditForm): """Custom edit-form for Bungeni content. """ def __init__(self, *args): # !+view/viewlet(mr, jul-2011) super(EditForm, self).__init__(*args) # For bungeni content, mark the request that we are in edit mode e.g. # useful for when editing a question's response, but not wanting to # offer option to submit the response while in response edit mode. if IBungeniContent.providedBy(self.context): # and self.mode=="edit" interface.alsoProvides(self.request, IFormEditLayer) @property def is_translation(self): return is_translation(self.context) @property def side_by_side(self): return self.is_translation @property def form_name(self): if IVersion.providedBy(self.context): context = self.context.head props = IDCDescriptiveProperties.providedBy(context) \ and context or IDCDescriptiveProperties(context) if self.is_translation: language = get_language_by_name(self.context.language)["name"] return _(u"edit_translation_legend", default=u"Editing $language translation of '$title'", mapping={"title": translate(props.title, context=self.request), "language": language}) elif IVersion.providedBy(self.context): return _(u"edit_version_legend", default=u'Editing "$title" (version $version)', mapping={"title": translate(props.title, context=self.request), "version": self.context.version_id}) return _(u"edit_item_legend", default=u'Editing "$title"', mapping={"title": translate(props.title, context=self.request)}) @property def form_description(self): if self.is_translation: language = get_language_by_name(self.context.head.language)["name"] return _(u"edit_translation_help", default=u"The original $language version is shown on the left", mapping={"language": language}) def validate(self, action, data): errors = super(EditForm, self).validate(action, data) descriptor = queryModelDescriptor(self.context.__class__) for validator in getattr(descriptor, "custom_validators", ()): errors += validator(action, data, self.context, self.context.__parent__) return errors def filter_fields(self): return filterFields(self.context, self.form_fields) def setUpWidgets(self, ignore_request=False): super(EditForm, self).setUpWidgets(ignore_request=ignore_request) # for translations, add a ``render_original`` method to each # widget, which will render the display widget bound to the # original (HEAD) document if self.is_translation: head = self.context.head form_fields = ui.setUpFields(self.context.__class__, "view") for widget in self.widgets: form_field = form_fields.get(widget.context.__name__) if form_field is None: form_field = formlib.form.Field(widget.context) # bind field to head document field = form_field.field.bind(head) # create custom widget or instantiate widget using # component lookup if form_field.custom_widget is not None: display_widget = form_field.custom_widget( field, self.request) else: display_widget = component.getMultiAdapter( (field, self.request), IDisplayWidget) display_widget.setRenderedValue(field.get(head)) # attach widget as ``render_original`` widget.render_original = display_widget def _do_save(self, data): formlib.form.applyChanges(self.context, self.form_fields, data) # !+EVENT_DRIVEN_CACHE_INVALIDATION(mr, mar-2011) no modify event # invalidate caches for this domain object type notify(ObjectModifiedEvent(self.context)) invalidate_caches_for(self.context.__class__.__name__, "edit") @formlib.form.action(_(u"Save"), condition=formlib.form.haveInputWidgets) def handle_edit_save(self, action, data): """Saves the document and goes back to edit page""" self._do_save(data) @formlib.form.action( _(u"Save and view"), condition=formlib.form.haveInputWidgets) def handle_edit_save_and_view(self, action, data): """Saves the document and redirects to its view page""" self._do_save(data) if not self._next_url: self._next_url = url.absoluteURL(self.context, self.request) + \ "?portal_status_message= Saved" self.request.response.redirect(self._next_url) @formlib.form.action(_(u"Cancel"), validator=ui.null_validator) def handle_edit_cancel(self, action, data): """Cancelling redirects to the listing.""" session = Session() if not self._next_url: self._next_url = url.absoluteURL(self.context, self.request) self.request.response.redirect(self._next_url)
def form_name(self): return _(u"add_item_legend", default=u"Add $name", mapping={ "name": translate(self.type_name.lower(), context=self.request)})