1

It seems that toolset.xml goes only half way. Ideally it should be able to do away with the ToolInit call in initialize() in __init__.py. But I could not get the tool icon to show in the ZMI without the ToolInit call.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
sureshvv
  • 4,234
  • 1
  • 26
  • 32

2 Answers2

3

The ToolInit call in the initialize function registers the tool class as something that can be added to OFS based folders in the database - primarily it register a factory for creating instances of the class. This is basically the same that ContentInit does for normal content classes.

Once the class is registered and its meta_type is known, instances of the class can be added to OFS based Folders. GenericSetup steps are responsible for managing persistent content and can be used to add tool instances to the database.

If we wanted to avoid the code in the initialize function, we would need to create some custom ZCML directives instead and use these in a configure.zcml to register the type and its factory. Dexterity has gone this route, but its not available for Archetypes based content types or general classes like tools.

  • What I found was calling Toolinit from initialize() was not necessary if we use toolset.xml. The tool gets created on the site. Except for one thing - it is missing the icon. So just to get the icon looking right, I had to create the body for the initialize function and call ToolInit there. If toolset.xml had a way to specify the icon, even this wouldn't be necessary. – sureshvv Apr 10 '11 at 04:55
  • @sureshvv: The fact that this works at all is a happy coincidence; there is nothing in toolset.xml that registers a factory, for instance. It certainly never was the goal of toolset.xml to support this usecase. – Martijn Pieters Apr 11 '11 at 07:54
  • @martijn: Unfortunately the developer experience is less than ideal if we have to touch 3 or 4 places in a seemingly unrelated way to make something happen. – sureshvv Apr 13 '11 at 17:35
  • @sureshvv: Hence my explanation of what role toolset.xml does. Registering tools is still a Zope-level task (the icons only appear in the ZMI) and thus you use Zope-level APIs to do so. CMF (of which GenericSetup is a part) and Plone are later add-ons built on top of this. – Martijn Pieters Apr 13 '11 at 17:48
2

The goal of toolset.xml is to instantiate tools into the database. It can also be used to remove tools; this is very useful in upgrade steps for example.

Example toolset.xml:

<?xml version="1.0"?>
<tool-setup>
  <required tool_id="portal_foo" class="dotted.path.to.FooTool" />
  <forbidden tool_id="portal_spam" />
</tool-setup>

This example toolset.xml would instantiate the FooTool class as portal_foo in it's context, and remove any object with id portal_spam if present.

Note that you can use a toolset.xml in any GenericSetup profile, not just in the package that defines the tool in the first place, for example, in general policy packages for a site you develop.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Using with a tool_id that was previously marked as required raises an exception: ValueError: Tool [tool_id] is required! How do I actually remove a tool? – David Glick Oct 19 '13 at 04:24
  • @DavidGlick: interesting; that exception is only raised if the tool is listed both as required *and* forbidden within a profile dependency chain. You'd have to force deletion with a custom step if you cannot get rid of the dependency in your profile. – Martijn Pieters Oct 19 '13 at 15:21