Error adding external method (working through training exercise)

Hello-
I'm new w/ this community and to Plone. We're considering using Plone for our institutional CMS (multilingual and security are two features that brought us to Plone).

I'm working through the transmogrifier training pages at: https://training.plone.org/5/transmogrifier/export.html

When trying to add an external method, I'm getting the following zope.location.interfaces.LocationError:

Request URL	http://157.7.20.180:8080/Plone_test/manage_addProduct/ExternalMethod/manage_addExternalMethod
Exception Type	LocationError
Exception Value	zope.location.interfaces.LocationError: (<App.ProductContext.ProductContext.registerClass.<locals>.__FactoryDispatcher__ object at 0x7f8420024e80>, 'colophon')

 - Expression: "python:path(path_expression)"
 - Filename:   ... s-4.4.5-py3.8.egg/plone/app/portlets/portlets/classic.pt
 - Location:   (line 9: col 32)
 - Source:     ... replace="structure python:path(path_expression)" />
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 - Arguments:  template: <Products.Five.browser.pagetemplatefile.ViewPageTemplateFile object at 0x7f8423ea9520>
               options: {}
               args: ()
               nothing: None
               modules: <Products.PageTemplates.ZRPythonExpr._SecureModuleImporter object at 0x7f842aea72b0>
               request: <WSGIRequest, URL=http://157.7.20.180:8080/Plone_test/manage_addProduct/ExternalMethod/manage_addExternalMethod>
               view: <plone.app.portlets.portlets.classic.Renderer object at 0x7f8420076550>
               context: <App.ProductContext.ProductContext.registerClass.<locals>.__FactoryDispatcher__ object at 0x7f8420024e80>
               views: <Products.Five.browser.pagetemplatefile.ViewMapper object at 0x7f8420076790>
               here: <App.ProductContext.ProductContext.registerClass.<locals>.__FactoryDispatcher__ object at 0x7f8420024e80>
               container: <App.ProductContext.ProductContext.registerClass.<locals>.__FactoryDispatcher__ object at 0x7f8420024e80>
               root: <Application at >
               traverse_subpath: []
               user: <PloneUser 'egrant'>
               default: <DEFAULT>
               repeat: <Products.PageTemplates.engine.RepeatDictWrapper object at 0x7f8424a92240>
               loop: {}
               target_language: None
               translate: <function BaseTemplate.render.<locals>.translate at 0x7f8423dd0550>
               attrs: {}
               use_macro: False
               path_expression: 'context/colophon'
Traceback (innermost last):

Module plone.app.portlets.manager, line 54, in safe_render
Module Products.Five.browser.pagetemplatefile, line 126, in __call__
Module Products.Five.browser.pagetemplatefile, line 58, in __call__
Module zope.pagetemplate.pagetemplate, line 133, in pt_render
Module Products.PageTemplates.engine, line 367, in __call__
Module z3c.pt.pagetemplate, line 176, in render
Module chameleon.zpt.template, line 307, in render
Module chameleon.template, line 214, in render
Module chameleon.utils, line 75, in raise_with_traceback
Module chameleon.template, line 192, in render
Module 18d788f9a529d5c76cec306fcc435a47, line 192, in render
Module zope.tales.pythonexpr, line 73, in __call__
__traceback_info__: (path(path_expression))
Module <string>, line 1, in <module>
Module zope.tales.pythonexpr, line 90, in __call__
Module zope.tales.expressions, line 250, in __call__
Module Products.PageTemplates.Expressions, line 188, in _eval
Module zope.tales.expressions, line 153, in _eval
Module Products.PageTemplates.Expressions, line 104, in trustedBoboAwareZopeTraverse
Module zope.traversing.adapters, line 156, in traversePathElement
__traceback_info__: (<App.ProductContext.ProductContext.registerClass.<locals>.__FactoryDispatcher__ object at 0x7f8420024e80>, 'colophon')
Module zope.traversing.adapters, line 61, in traverse
__traceback_info__: (<App.ProductContext.ProductContext.registerClass.<locals>.__FactoryDispatcher__ object at 0x7f8420024e80>, 'colophon', [])
zope.location.interfaces.LocationError: zope.location.interfaces.LocationError: (<App.ProductContext.ProductContext.registerClass.<locals>.__FactoryDispatcher__ object at 0x7f8420024e80>, 'colophon')

 - Expression: "python:path(path_expression)"
 - Filename:   ... s-4.4.5-py3.8.egg/plone/app/portlets/portlets/classic.pt
 - Location:   (line 9: col 32)
 - Source:     ... replace="structure python:path(path_expression)" />
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 - Arguments:  template: <Products.Five.browser.pagetemplatefile.ViewPageTemplateFile object at 0x7f8423ea9520>
               options: {}
               args: ()
               nothing: None
               modules: <Products.PageTemplates.ZRPythonExpr._SecureModuleImporter object at 0x7f842aea72b0>
               request: <WSGIRequest, URL=http://157.7.20.180:8080/Plone_test/manage_addProduct/ExternalMethod/manage_addExternalMethod>
               view: <plone.app.portlets.portlets.classic.Renderer object at 0x7f8420076550>
               context: <App.ProductContext.ProductContext.registerClass.<locals>.__FactoryDispatcher__ object at 0x7f8420024e80>
               views: <Products.Five.browser.pagetemplatefile.ViewMapper object at 0x7f8420076790>
               here: <App.ProductContext.ProductContext.registerClass.<locals>.__FactoryDispatcher__ object at 0x7f8420024e80>
               container: <App.ProductContext.ProductContext.registerClass.<locals>.__FactoryDispatcher__ object at 0x7f8420024e80>
               root: <Application at >
               traverse_subpath: []
               user: <PloneUser 'egrant'>
               default: <DEFAULT>
               repeat: <Products.PageTemplates.engine.RepeatDictWrapper object at 0x7f8424a92240>
               loop: {}
               target_language: None
               translate: <function BaseTemplate.render.<locals>.translate at 0x7f8423dd0550>
               attrs: {}
               use_macro: False
               path_expression: 'context/colophon'

I have successfully rebuilt the "buildout.cfg" for several addons (pas.plugins.ldap; collective.dexteritytextindexer; collective.jsonify), so I've got the very basics working. I think it is probably an installation issue as it appears this is dying in the portlets.classic.Renderer object (which I understand is no longer used except in some legacy circumstances).

I'll also note, that if I simply go to the sidebar as an administrator, click on the "manage portlets" and try to add a classic portlet (using the classic.pt template), basically the same error is being thrown.

I couldn't find anything recent about this in the forum/google (sorry if I missed it). I'm running the following:

  • Plone 5.2.2 (5209)
  • CMF 2.4.8
  • Zope 4.5.1
  • Python 3.8.5 (default, Sep 24 2020, 16:51:01) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
  • PIL 6.2.2 (Pillow)
  • WSGI: On
  • Server: waitress 1.4.4

Many thanks!
Eric

I expect that the problem is related to a classic portlet.

First, I would check whether the problem disappears with a newer Plone (you are using 5.2.2, current is 5.2.4). If this should be too difficult, I would check if an upgrade of plone.app.portlets fixes the problem.

If newer versions do not fix the problem, I would analyze classic.pt to find out where path_expression comes from. Apparently, colophon should be accessed via it and it not accessible. If it comes from the portlet definition (i.e. is passed in to the template as argument), delete the portlet (as it references objects which do not exist in your setup). If it is defined in the template itself, change the definition.

Hi Eric, welcome to Plone!

I'm curious what you are trying to accomplish with the export, because you may not need to do this step. The export is needed if you need to get content out of an existing Plone site, to then import into a new Plone site. If your goal is to connect a new Plone site's content to third party systems, there are better ways to do that.

I'm also trying to figure out the error you are getting, it mentions the colophon. Are there any customizations you have done to the colophon in this site?

Thank you both for responding.

Dieter,
The zope interface at @@plone-upgrade says I'm "Up to date" (though I see that I am at 5.2.2 rather than 5.2.4). Not sure why it says that but I'm so new I don't know how to manually do the upgrade. So I left that alone. I did update plone.app.portlets from 4.4.6 to 4.4.7 but no change in behavior. the path_expression appears to be passed in (or read from another location), it is not explicitly defined within the file.

The strange thing is that the classic portlet code is being called at all. My guess is code is only called in a 'last ditch' situation after all the normal error catching has been tried; the initial problem is likely upstream--but that is simply my guess.

Chrissy,
I was intrigued by the transmogrify.sqlalchemy package. We would like to migrate a bunch of SQL database tables from our current setup to create pages in plone. I was just starting at the beginning of your [saw your youtube videos] training program (I'm very new to all of this). Taking baby steps and trying to get things to work. It was my first time trying to 'add an external method' and I got tripped up. I could bail on this and try something else if you have a different suggestion.

The fact that I can't add an external method using 'canned' code from your example indicates to me that I have an installation problem or possibly a permissions problem. I have full administrative rights to the plone installation (in ~/Plone) and python modules in ~/.local. I can also 'sudo' on this machine but I didn't pay much attention when I was doing the installation on where things were being installed. Maybe I should start from the beginning again...

We haven't done any customizations (too new to do anything crazy). We are using an ldap server for authentication--that is probably the most non-vanilla thing we've done. Also, we've turned on the multi-lingual abilities.

My thanks to all,
Eric

For migrating content from your current setup, you would be better off looking into something like plone.restapi ยท PyPI

External methods aren't used much anymore, but work great for things like the collective.jsonify export that works across many versions of Plone. In your case, you don't need to do this step.

Chrissy,

Many thanks. I'll look into that. -Eric