{
"info": {
"author": "Grok Team",
"author_email": "grok-dev@zope.org",
"bugtrack_url": null,
"classifiers": [
"Development Status :: 6 - Mature",
"Intended Audience :: Developers",
"License :: OSI Approved :: Zope Public License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy"
],
"description": "This package provides base classes of basic component types for the\nZope Component Architecture, as well as means for configuring and\nregistering them directly in Python (without ZCML).\n\n.. contents::\n\nHow to set up ``grokcore.component``\n====================================\n\nIn the following we assume you're writing or extending an application\nthat does bootstrap configuration using ZCML. There's always a single\nZCML file that is executed when the application is started, which then\nincludes everything else. Let's assume this file is called\n``site.zcml`` (that's what it's called in Zope), so that file is what\nwe'll be editing.\n\nIn order to register the components that you wrote using the base\nclasses and directives available from ``grokcore.component``, we'll\nuse the ``
Hello World!
'\n\n\nGlobal utility\n--------------\n\nHere's a simple named utility, again from the Zope world. It's a\ntranslation domain. In other words, it contains translations of user\nmessages and is invoked when the i18n machinery needs to translate\nsomething::\n\n import grokcore.component\n from zope.i18n.interfaces import ITranslationDomain\n\n class HelloWorldTranslationDomain(grokcore.component.GlobalUtility):\n grokcore.component.implements(ITranslationDomain)\n grokcore.component.name('helloworld')\n\n domain = u'helloworld'\n\n def translate(self, msgid, mapping=None, context=None,\n target_language=None, default=None):\n if target_language is None:\n preferred = IUserPreferredLanguages(context)\n target_language = preferred.getPreferredLanguages()[0]\n\n translations = {'de': u'Hallo Welt',\n 'nl': u'Hallo Wereld'}\n return translations.get(target_language, u'Hello World')\n\nOf course, it's silly to implement your own translation domain utility\nif there are already implementations available in ``zope.i18n`` (one\nthat reads translations from a GNU gettext message catalog and a\nsimple implementation for tests). Let's try to reuse that\nimplementation and register an instance::\n\n import grokcore.component\n from zope.i18n.interfaces import ITranslationDomain\n from zope.i18n.simpletranslationdomain import SimpleTranslationDomain\n\n messages = {('de', u'Hello World'): u'Hallo Welt',\n ('nl', u'Hello World'): u'Hallo Wereld'}\n helloworld_domain = SimpleTranslationDomain(u'helloworld', messages)\n\n grokcore.component.global_utility(helloworld_domain,\n provides=ITranslationDomain,\n name='helloworld',\n direct=True)\n\nGlobal adapter\n--------------\n\nSometimes, you may have an object that should be registered as an adapter\nfactory. It may have come from some other framework that configured that\nadapter for you, say, or you may have a class that you instantiate many\ntimes to get different variations on a particular adapter factory. In these\ncases, subclassing grokcore.component.Adapter or MultiAdapter is not\npossible. Instead, you can use the global_adapter() directive. Here is an\nexample drawing on the ``z3c.form`` library, which provides an adapter factory\nfactory for named widget attributes::\n\n import zope.interface\n import zope.schema\n import grokcore.component\n import z3c.form.widget import ComputedWidgetAttribute\n\n class ISchema(Interface):\n \"\"\"This schema will be used to power a z3c.form form\"\"\"\n\n field = zope.schema.TextLine(title=u\"Sample field\")\n\n ...\n\n label_override = z3c.form.widget.StaticWidgetAttribute(\n u\"Override label\", field=ISchema['field'])\n\n grokcore.component.global_adapter(label_override, name=u\"label\")\n\nIn the example above, the provided and adapted interfaces are deduced from the\nobject returned by the ``StaticWidgetAttribute`` factory. The full syntax\nfor global_adapter is::\n\n global_adapter(factory, (IAdapted1, IAdapted2,), IProvided, name=u\"name\")\n\nThe factory must be a callable (the adapter factory). Adapted interfaces are\ngiven as a tuple. You may use a single interface instead of a one-element\ntuple for single adapters. The provided interface is given as shown. The name\ndefaults to u\"\" (an unnamed adapter).\n\nHandling events\n---------------\n\nHere we see an event handler much like it occurs within Zope itself. It\nsubscribes to the modified event for all annotatable objects (in other words,\nobjects that can have metadata associated with them). When invoked, it updates\nthe Dublin Core 'Modified' property accordingly::\n\n import datetime\n import grokcore.component\n from zope.annotation.interfaces import IAnnotatable\n from zope.lifecycleevent.interfaces import IObjectModifiedEvent\n from zope.dublincore.interfaces import IZopeDublinCore\n\n @grokcore.component.subscribe(IAnnotatable, IObjectModifiedEvent)\n def updateDublinCoreAfterModification(obj, event):\n \"\"\"Updated the Dublin Core 'Modified' property when a modified\n event is sent for an object.\"\"\"\n IZopeDublinCore(obj).modified = datetime.datetime.utcnow()\n\nSubscriptions\n-------------\n\nSubscriptions look similar to Adapter, however, unlike regular adapters,\nsubscription adapters are used when we want all of the adapters that adapt an\nobject to a particular adapter.\n\nAnalogous to MultiAdapter, there is a MultiSubscription component that \"adapts\"\nmultiple objects.\n\nChanges\n=======\n\n3.1 (2018-05-09)\n----------------\n\n- Expose ``martian.ignore`` through our API.\n\n3.0.2 (2018-01-17)\n------------------\n\n- Replace the use of `grok.implements()` with the `@grok.implementer()`\n directive throughout.\n\n3.0.1 (2018-01-12)\n------------------\n\n- Rearrange tests such that Travis CI can pick up all functional tests too.\n\n3.0 (2017-10-19)\n----------------\n\n- Add support for Python 3.5, 3.6, PyPy2 and PyPy3.\n\n- Drop support for Python 2.6 and 3.3.\n\n2.7 (2016-02-16)\n----------------\n\n- Add ability to exclude more than one module or package using\n ``