#241 — deleting a canonical folder with content breaks the translation

by Jens W. Klein last modified Jul 29, 2010 07:09 PM
State Resolved
Version: 3.x
Area Functionality
Issue type Bug
Severity Important
Submitted by Jens W. Klein
Submitted on Apr 27, 2010
Responsible Hanno Schlichting
Target release: 4.x
Create a Folder and inside a Page. Then translate both. Delete the canonical Folder. Go to the translated folder und you'll get:

AttributeError("'NoneType' object has no attribute 'getTranslations'",) (Also, the following error occurred while attempting to render the standard error message, please see the event log for full details: 'NoneType' object has no attribute 'getTranslations')

This is valid for subversion trunk with rev 36325.
Added by Jens W. Klein on Apr 27, 2010 09:02 AM
Forgot to say, tested only in Plone 4.
Added by Hanno Schlichting on Jun 03, 2010 06:14 PM
Issue state: UnconfirmedConfirmed
A full traceback would be helpful here, there's tons of getTranslations calls in the code.
Added by Karl Johan Kleist on Jul 17, 2010 12:21 PM
I just reproduced this using Plone 4 coredev buildout (rev. 37934) with LinguaPlone (svn trunk). Here the traceback:

2010-07-17 14:30:45 ERROR Zope.SiteErrorLog 1279369845.580.757498618357 http://localhost:8080/Plone/de/241/folder_listing
Traceback (innermost last):
  Module ZPublisher.Publish, line 127, in publish
  Module ZPublisher.mapply, line 77, in mapply
  Module ZPublisher.Publish, line 47, in call_object
  Module Shared.DC.Scripts.Bindings, line 324, in __call__
  Module Shared.DC.Scripts.Bindings, line 361, in _bindAndExec
  Module Products.CMFCore.FSPageTemplate, line 240, in _exec
  Module Products.CMFCore.FSPageTemplate, line 180, in pt_render
  Module Products.PageTemplates.PageTemplate, line 80, in pt_render
  Module zope.pagetemplate.pagetemplate, line 115, in pt_render
  Module zope.tal.talinterpreter, line 271, in __call__
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 888, in do_useMacro
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 533, in do_optTag_tal
  Module zope.tal.talinterpreter, line 518, in do_optTag
  Module zope.tal.talinterpreter, line 513, in no_tag
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 852, in do_condition
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 531, in do_optTag_tal
  Module zope.tal.talinterpreter, line 513, in no_tag
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 742, in do_insertStructure_tal
  Module Products.PageTemplates.Expressions, line 220, in evaluateStructure
  Module zope.tales.tales, line 696, in evaluate
   - URL: file:e:\buildout\plone4coredev\src\plonetheme.sunburst\plonetheme\sunburst\skins\sunburst_templates\main_template.pt
   - Line 65, Column 12
   - Expression: <StringExpr u'plone.portaltop'>
   - Names:
      {'container': <PloneSite at /Plone>,
       'context': <ATFolder at /Plone/de/241>,
       'default': <object object at 0x00390720>,
       'here': <ATFolder at /Plone/de/241>,
       'loop': {},
       'nothing': None,
       'options': {'args': ()},
       'repeat': <Products.PageTemplates.Expressions.SafeMapping object at 0x07763480>,
       'request': <HTTPRequest, URL=http://localhost:8080/Plone/de/241/folder_listing>,
       'root': <Application at >,
       'template': <FSPageTemplate at /Plone/folder_listing used for /Plone/de/241>,
       'traverse_subpath': [],
       'user': <PloneUser 'kleist'>}
  Module zope.contentprovider.tales, line 80, in __call__
  Module plone.app.viewletmanager.manager, line 154, in render
  Module plone.app.viewletmanager.manager, line 85, in render
  Module Products.Five.browser.pagetemplatefile, line 126, in __call__
  Module Products.Five.browser.pagetemplatefile, line 60, in __call__
  Module zope.pagetemplate.pagetemplate, line 115, in pt_render
  Module zope.tal.talinterpreter, line 271, in __call__
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 852, in do_condition
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 533, in do_optTag_tal
  Module zope.tal.talinterpreter, line 518, in do_optTag
  Module zope.tal.talinterpreter, line 513, in no_tag
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 583, in do_setLocal_tal
  Module zope.tales.tales, line 696, in evaluate
   - URL: e:\buildout\plone4coredev\src\products.linguaplone\Products\LinguaPlone\browser\selector.pt
   - Line 2, Column 0
   - Expression: <PathExpr standard:u'view/languages'>
   - Names:
      {'args': (),
       'container': <ATFolder at /Plone/de/241>,
       'context': <ATFolder at /Plone/de/241>,
       'default': <object object at 0x00390720>,
       'here': <ATFolder at /Plone/de/241>,
       'loop': {},
       'nothing': None,
       'options': {},
       'repeat': <Products.PageTemplates.Expressions.SafeMapping object at 0x075DE330>,
       'request': <HTTPRequest, URL=http://localhost:8080/Plone/de/241/folder_listing>,
       'root': <Application at >,
       'template': <Products.Five.browser.pagetemplatefile.ViewPageTemplateFile object at 0x05BDEE90>,
       'traverse_subpath': [],
       'user': <PloneUser 'kleist'>,
       'view': <Products.Five.viewlet.metaconfigure.TranslatableLanguageSelector object at 0x077549D0>,
       'views': <Products.Five.browser.pagetemplatefile.ViewMapper object at 0x07754C70>}
  Module zope.tales.expressions, line 217, in __call__
  Module Products.PageTemplates.Expressions, line 157, in _eval
  Module Products.PageTemplates.Expressions, line 119, in render
  Module Products.LinguaPlone.browser.selector, line 106, in languages
  Module Products.LinguaPlone.browser.selector, line 45, in _translations
  Module Products.LinguaPlone.I18NBaseObject, line 219, in getTranslations
AttributeError: 'NoneType' object has no attribute 'getTranslations'
2010-07-17 14:30:45 ERROR root Exception while rendering an error message
Traceback (most recent call last):
  File "e:\buildout\plone4coredev\src\zope2\src\OFS\SimpleItem.py", line 254, in raise_standardErrorMessage
    v = s(**kwargs)
  File "e:\buildout\plone4coredev\eggs\products.cmfcore-2.2.2-py2.6.egg\Products\CMFCore\FSPythonScript.py", line 130, in __call__
    return Script.__call__(self, *args, **kw)
  File "e:\buildout\plone4coredev\src\zope2\src\Shared\DC\Scripts\Bindings.py", line 324, in __call__
    return self._bindAndExec(args, kw, None)
  File "e:\buildout\plone4coredev\src\zope2\src\Shared\DC\Scripts\Bindings.py", line 361, in _bindAndExec
    return self._exec(bound_data, args, kw)
  File "e:\buildout\plone4coredev\src\zope2\src\Products\PythonScripts\PythonScript.py", line 344, in _exec
    result = f(*args, **kw)
  File "Script (Python)", line 34, in standard_error_message
  File "e:\buildout\plone4coredev\src\zope2\src\Shared\DC\Scripts\Bindings.py", line 324, in __call__
    return self._bindAndExec(args, kw, None)
  File "e:\buildout\plone4coredev\src\zope2\src\Shared\DC\Scripts\Bindings.py", line 361, in _bindAndExec
    return self._exec(bound_data, args, kw)
  File "e:\buildout\plone4coredev\eggs\products.cmfcore-2.2.2-py2.6.egg\Products\CMFCore\FSPageTemplate.py", line 240, in _exec
    result = self.pt_render(extra_context=bound_names)
  File "e:\buildout\plone4coredev\eggs\products.cmfcore-2.2.2-py2.6.egg\Products\CMFCore\FSPageTemplate.py", line 180, in pt_render
    self, source, extra_context
  File "e:\buildout\plone4coredev\src\zope2\src\Products\PageTemplates\PageTemplate.py", line 80, in pt_render
    showtal=showtal)
  File "e:\buildout\plone4coredev\eggs\zope.pagetemplate-3.5.1-py2.6.egg\zope\pagetemplate\pagetemplate.py", line 115, in pt_render
    strictinsert=0, sourceAnnotations=sourceAnnotations)()
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 271, in __call__
    self.interpret(self.program)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 343, in interpret
    handlers[opcode](self, args)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 888, in do_useMacro
    self.interpret(macro)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 343, in interpret
    handlers[opcode](self, args)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 533, in do_optTag_tal
    self.do_optTag(stuff)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 518, in do_optTag
    return self.no_tag(start, program)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 513, in no_tag
    self.interpret(program)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 343, in interpret
    handlers[opcode](self, args)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 852, in do_condition
    self.interpret(block)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 343, in interpret
    handlers[opcode](self, args)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 531, in do_optTag_tal
    self.no_tag(stuff[-2], stuff[-1])
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 513, in no_tag
    self.interpret(program)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 343, in interpret
    handlers[opcode](self, args)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 742, in do_insertStructure_tal
    structure = self.engine.evaluateStructure(expr)
  File "e:\buildout\plone4coredev\src\zope2\src\Products\PageTemplates\Expressions.py", line 220, in evaluateStructure
    text = super(ZopeContext, self).evaluateStructure(expr)
  File "e:\buildout\plone4coredev\eggs\zope.tales-3.4.0-py2.6.egg\zope\tales\tales.py", line 696, in evaluate
    return expression(self)
  File "e:\buildout\plone4coredev\eggs\zope.contentprovider-3.5.0-py2.6.egg\zope\contentprovider\tales.py", line 80, in __call__
    return provider.render()
  File "e:\buildout\plone4coredev\src\plone.app.viewletmanager\plone\app\viewletmanager\manager.py", line 154, in render
    return BaseOrderedViewletManager.render(self)
  File "e:\buildout\plone4coredev\src\plone.app.viewletmanager\plone\app\viewletmanager\manager.py", line 85, in render
    return u'\n'.join([viewlet.render() for viewlet in self.viewlets])
  File "e:\buildout\plone4coredev\src\zope2\src\Products\Five\browser\pagetemplatefile.py", line 126, in __call__
    return self.im_func(im_self, *args, **kw)
  File "e:\buildout\plone4coredev\src\zope2\src\Products\Five\browser\pagetemplatefile.py", line 60, in __call__
    sourceAnnotations=getattr(debug_flags, 'sourceAnnotations', 0),
  File "e:\buildout\plone4coredev\eggs\zope.pagetemplate-3.5.1-py2.6.egg\zope\pagetemplate\pagetemplate.py", line 115, in pt_render
    strictinsert=0, sourceAnnotations=sourceAnnotations)()
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 271, in __call__
    self.interpret(self.program)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 343, in interpret
    handlers[opcode](self, args)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 852, in do_condition
    self.interpret(block)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 343, in interpret
    handlers[opcode](self, args)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 533, in do_optTag_tal
    self.do_optTag(stuff)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 518, in do_optTag
    return self.no_tag(start, program)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 513, in no_tag
    self.interpret(program)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 343, in interpret
    handlers[opcode](self, args)
  File "e:\buildout\plone4coredev\eggs\zope.tal-3.5.2-py2.6.egg\zope\tal\talinterpreter.py", line 583, in do_setLocal_tal
    self.engine.setLocal(name, self.engine.evaluateValue(expr))
  File "e:\buildout\plone4coredev\eggs\zope.tales-3.4.0-py2.6.egg\zope\tales\tales.py", line 696, in evaluate
    return expression(self)
  File "e:\buildout\plone4coredev\eggs\zope.tales-3.4.0-py2.6.egg\zope\tales\expressions.py", line 217, in __call__
    return self._eval(econtext)
  File "e:\buildout\plone4coredev\src\zope2\src\Products\PageTemplates\Expressions.py", line 157, in _eval
    return render(ob, econtext.vars)
  File "e:\buildout\plone4coredev\src\zope2\src\Products\PageTemplates\Expressions.py", line 119, in render
    ob = ob()
  File "e:\buildout\plone4coredev\src\products.linguaplone\Products\LinguaPlone\browser\selector.py", line 106, in languages
    translations = self._translations(missing)
  File "e:\buildout\plone4coredev\src\products.linguaplone\Products\LinguaPlone\browser\selector.py", line 45, in _translations
    item_trans = item.getTranslations(review_state=False)
  File "e:\buildout\plone4coredev\src\products.linguaplone\Products\LinguaPlone\I18NBaseObject.py", line 219, in getTranslations
    return self.getCanonical().getTranslations(
AttributeError: 'NoneType' object has no attribute 'getTranslations'
Added by Hanno Schlichting on Jul 29, 2010 02:12 PM
Target release: None4.x
Hhm. Ok. So self.getCanonical() returns None. If the canonical is removed, a different item should be automatically be upgraded to become the canonical. I thought that happened implicitly by removing the references. Sounds like either something is not removing the references or some of my earlier performance work side-stepping the AT reference API's needs to be more careful.
Added by Hanno Schlichting on Jul 29, 2010 04:28 PM
Severity: MediumImportant
Ok. Looked into this some more. The translation does indeed still contain a reference in its at_references folder. This one is still pointing to the no longer existing canonical, claiming it's a translationOf that content item.
Added by Hanno Schlichting on Jul 29, 2010 04:42 PM
The problem is that the Referenceable.manage_beforeDelete method is never called.
Added by Hanno Schlichting on Jul 29, 2010 07:09 PM
Issue state: ConfirmedResolved
Responsible manager: (UNASSIGNED)hannosch
I found and fixed the culprit. The folder class in ATContentTypes had two base classes with both a manage_beforeDelete method, but failed to call both of them. As a result only the one from I18NBaseObject got called, which doesn't do much.

Fixed in ATContentTypes 2.0.2.

No responses can be added.