• First off, you'll have to add this in one of your own Plone products.  I will not go through creating a product in this tutorial.
  • Next, create a few files. Remember you can customize these to your liking.  I will call this BrowserView "tool."
    • tool.py
    • interfaces.py
  • In the tool.py file do something like this,
    from zope.interface import implements
    from zope.component import getMultiAdapter
    from plone.memoize.view import memoize, memoize_contextless
    
    from Acquisition import aq_inner
    from Products.CMFCore.utils import getToolByName
    from Products.Five.browser import BrowserView
    
    from interfaces import ITool
    
    class Tool(BrowserView): 
    
      implements(IUWOshTools)
    
      @memoize_contextless
      def hello_world(self):
        return "Hello, World!"
  • Now in interfaces.py do something like this,
    from zope.interface import Interface
    
    class ITool(Interface):
      def hello_world(self):
        pass
  • In the interfaces.py file you'll need to declare each method you'll create in the Tool BrowserView
  • Now add this to your configure.zcml
    <browser:page
      name="tool"
      for="*"
      permission="zope2.View"
      class=".tool.Tool"
      allowed_interface=".interfaces.ITool"
      />
    
    <!-- We need to make the request annotatable for this to work -->
      <class class="ZPublisher.BaseRequest.BaseRequest">
        <implements interface="zope.annotation.interfaces.IAttributeAnnotatable" />
      </class>
  • Now in a tal expression you can do things like this,
    here/@@tool/hello_world
    python: here.restrictedTraverse("@@tool").hello_world()
  • Or in code you can do something like this,
    from zope.component import getMultiAdapter
    
    tool = getMultiAdapter((self.context, self.request), name=u'tool')
  • and you're done.  SWEET!