What: undo transactions in grok

Problem: does not work with ZODB-3.10 and grok-1.10.3

Solutions (all these are workarounds, use them at your own risk):

as result of adding to following error appears:

ConfigurationError: ('Unknown directive', u'', u'menuItem')


and delete the menuItem-Sections; menuItem is used bei ZMI and implemented bei zc.forms or other but not by zope.formlib; I use zope.formlib in grok apps

2. ZODB has changed the api

Error after submit the transaction ID's:

"Duplicate tpc_begin calls for same transaction"

The undo API has changed with ZODB 3.10. As noted in the changelog:

      "The API for undoing multiple transactions has changed. To undo
      multiple transactions in a single transaction, pass a list of
      transaction identifiers to a database's undoMultiple method. Calling a
      database's undo method multiple times in the same transaction now
      raises an exception."
      Your code calls undo multiple times, and needs to be changed accordingly.

edit in

the last def:


    def _undo(self, ids):
        for id in ids:
        transaction.get().setExtendedInfo('undo', True)


    def _undo(self, ids):
        transaction.get().setExtendedInfo('undo', True)

Demo grok View

from import ZODBUndoManager
from import IUndoManager
from zope.component import getUtility
from zope.interface import Interface
class Undo(grok.View):
  def getPrincipalTransactions(self, first=0, last=-20, showall=False):
        context = None
        if not showall:
            context = self.context
        undo = getUtility(IUndoManager)
        return undo.getPrincipalTransactions(self.request.principal, context,
                                             first, last)

and the

<html i18n:domain="zope">
<form action="@@undoPrincipalTransactions.html" method="post">
  <tal:var define="global batch_size python:10;
                   global first      python:int(request.get('first', 0));
                   global showall    python:bool(request.get('showall', False))"
  <span tal:condition="showall">
      <span i18n:translate="">You are looking at transactions
      regardless of location.</span> <a href="?"
      i18n:translate="">View only transactions in this location</a>.
  <span tal:condition="not:showall">
      <span i18n:translate="">You are looking only at transactions
      from this location.</span> <a href="?showall=true"
      i18n:translate="">View transactions regardless of location</a>.
    <table style="width: 100%; border: none;">
        <th i18n:translate="heading-location">Location</th>
        <th i18n:translate="heading-request-info">Request info</th>
        <th i18n:translate="heading-principal">Principal</th>
        <th i18n:translate="heading-date">Date</th>
        <th i18n:translate="heading-description">Description</th>
      <tal:block repeat="item python:view.getPrincipalTransactions(first=first, 
      <tr tal:attributes="class python:repeat['item'].odd() and
                                       'content odd' or 'content even'">
        <td width="16">
          <input type="checkbox" name="ids:list" value="-1"
                 tal:attributes="value item/id" />
    <td tal:define="location item/location | nothing">
          <tal:location replace="location" />
          <tal:if condition="not:location"
                  i18n:translate="label-not-available">not available</tal:if>
          <tal:request_info replace="item/request_type | nothing" /><br />
          <tal:request_info replace="item/request_info | nothing" />
          <tal:if condition="python:not item.get('request_type', '') and
                                    not item.get('request_info', '')"
                  i18n:translate="label-not-available">not available</tal:if>
          <tal:principal replace="item/principal/id | nothing" />
          <tal:if condition="not:exists:item/principal/id"
                  i18n:translate="label-not-available">not available</tal:if>
        <td tal:define="formatter python:request.locale.dates.getFormatter(
                                         'dateTime', 'medium')"
          <tal:description i18n:translate=""
            replace="item/description | nothing" />
          <tal:if condition="not:item/description"
                  i18n:translate="label-not-available">not available</tal:if>
  <a tal:define="showall python:showall and '&showall=true' or ''"
     tal:attributes="href python:'?first=%s%s'%(first+batch_size, showall)">
    <tal:text i18n:translate="">
      View <tal:num replace="batch_size" i18n:name="number" />
      earlier transactions
  <a tal:define="showall python:showall and '&showall=true' or ''"
     tal:condition="python:first >= batch_size"
     tal:attributes="href python:'?first=%s%s'%(first-batch_size, showall)">
    <tal:text i18n:translate="">
      View <tal:num tal:replace="batch_size" i18n:name="number" />
      later transactions
  <input type="submit" value="Undo"
         i18n:attributes="value undo-button" />
python/ · Zuletzt geändert: 2012/09/12 14:08 von 2007