The grok module defines a set of base classes for creating new components of different types, that provide basic Zope 3 functionality in a convenient way. Grok applications are built by subclassing these components.
Components in Grok and Zope 3 are any plain Python object, that declare they provide one or more Interface(s). The inclusion of these Grok base classes in your own class inheritance automatically handles the component registration with the Zope Component Architecture. This process of introspecting your Grok code during initialization and wiring together components based on common conventions that you follow in the structure of your source code is called “grokking”.
Applications are top-level objects. They are typically used to hold global configuration and behaviour for an application instance, as well as holding data objects such as grok.Container and grok.Model object instances.
Mixin for creating Grok application objects.
When a grok.Container (or a grok.Model, though most developers use containers) also inherits from grok.Application, it not only gains the component registration abilities of a grok.Site, but will also be listed in the Grok admin control panel as one of the applications that the admin can install directly at the root of their Zope database.
Model objects provide persistence and containment. Model in Grok refers to an applications data model - that is data which is persistently saved to disk, by default in the Zope Object Database (ZODB).
The base class for models in Grok applications.
When an application class inherits from grok.Model, it gains the ability to persist itself in the Zope object database along with all of its attributes, and to remember the container in which it has been placed (its “parent”) so that its URL can be computed. It also inherits the IContext marker interface, which can make it the default context for views in its module; the rule is that if a module contains grok.View classes or other adapters that do not define a grok.context(), but the module also defines exactly one class that provides the IContext interface, then that class will automatically be made the grok.context() of each of the views.
- __parent__¶
The parent in the location hierarchy.
If you recursively follow the __parent__ attribute, you will always reach a reference to a top-level grok.Application object instance.
Objects in a container are manipulated using the same syntax as you would with a standard Python Dictionary object. The container implements the zope.container.interfaces.IContainer interface using a BTree, providing reasonable performance for large collections of objects.
The base class for containers in Grok applications.
When an application class inherits from grok.Container, it not only has the features of a grok.Model (persistance, location, and the ability to serve as a default context for other classes), but it also behaves like a persistent dictionary. To store items inside a container, simply use the standard Python getitem/setitem protocol:
mycontainer['counter'] = 72
mycontainer['address'] = mymodel
mycontainer['subfolder'] = another_container
By default, the URL of each item inside a container is the container’s own URL followed by a slash and the key (like ‘counter’ or ‘address’) under which that item has been stored.
The parent in the location hierarchy.
If you recursively follow the __parent__ attribute, you will always reach a reference to a top-level grok.Application object instance.
The name within the parent.
Traverse the parent with this name to get the object.
Name in Grok means “human-readable identifier” as the __name__ attribute is used to reference the object within an URL.
Return an iterator over the key-value pairs in the container.
If None is passed as key, this method behaves as if no argument were passed.
If key is in the container, the first item provided by the iterator will correspond to that key. Otherwise, the first item will be for the key that would come next if key were in the container.
Return an iterator over the keys in the container.
If None is passed as key, this method behaves as if no argument were passed.
If key is in the container, the first key provided by the iterator will be that key. Otherwise, the first key will be the one that would come next if key were in the container.
Return an iterator over the values in the container.
If None is passed as key, this method behaves as if no argument were passed.
If key is in the container, the first value provided by the iterator will correspond to that key. Otherwise, the first value will be for the key that would come next if key were in the container.
Get a value for a key
A KeyError is raised if there is no value for the key.
Get a value for a key
The default is returned if there is no value for the key.
Tell if a key exists in the mapping.
Return an iterator for the keys of the mapping object.
Return the values of the mapping object.
Return the items of the mapping object.
Return the number of items.
Tell if a key exists in the mapping.
Add the given object to the container under the given name.
Raises a TypeError if the key is not a unicode or ascii string. Raises a ValueError if key is empty.
The container might choose to add a different object than the one passed to this method.
If the object doesn’t implement IContained, then one of two things must be done:
The object’s __parent__ and __name__ attributes are set to the container and the given name.
If the old parent was None, then an IObjectAddedEvent is generated, otherwise, an IObjectMovedEvent is generated. An IContainerModifiedEvent is generated for the container.
If the object replaces another object, then the old object is deleted before the new object is added, unless the container vetos the replacement by raising an exception.
If the object’s __parent__ and __name__ were already set to the container and the name, then no events are generated and no hooks. This allows advanced clients to take over event generation.
Delete the named object from the container.
Raises a KeyError if the object is not found.
If the deleted object’s __parent__ and __name__ match the container and given name, then an IObjectRemovedEvent is generated and the attributes are set to None. If the object can be adapted to IObjectMovedEvent, then the adapter’s moveNotify method is called with the event.
Unless the object’s __parent__ and __name__ attributes were initially None, generate an IContainerModifiedEvent for the container.
If the object’s __parent__ and __name__ were already set to None, then no events are generated. This allows advanced clients to take over event generation.
Example 1: Perform Create, Read, Update and Delete (CRUD) on a container
# define a container and a model and then create them
class BoneBag(grok.Container): pass
class Bone(grok.Model): pass
bag = BoneBag()
skull = Bone()
# ... your classes are then "grokked" by Grok ...
# store an object in a container
bag['bone1'] = skull
# test for containment
bag.has_key('bone1')
# retrieve an object from a container
first_bone = bag['bone1']
# iterate through objects in a container with .values()
# you can also use .keys() and .items()
for bone in bag.values():
bone.marks = 'teeth'
# delete objects using the del keyword
del bag['bone1']
OrderedContainers act just like Containers, but also support the ability to maintain order on the items within the container. This implementation maintains a persistent list of keys on a private attribute, so it’s important to note that OrderedContainers will have poorer performance than a normal Container.
A Grok container that remembers the order of its items.
This straightforward extension of the basic grok.Container remembers the order in which items have been inserted, so that keys(), values(), items(), and iteration across the container can all return the items in the order they were inserted. The only way of changing the order is to call the updateOrder() method.
Impose a new order on the items in this container.
Items in this container are, by default, returned in the order in which they were inserted. To change the order, provide an argument to this method that is a sequence containing every key already in the container, but in a new order.
Indexes are local utilities for holding a set of indexes alongside a grok.Site or grok.Application. An index is a data structure that provides a way of quickly finding certain types of objects, i.e. it provides catalog functionality for attributes/contents of stored objects.
Base class for index collections in a Grok application.
A grok.Indexes utility provides one or more Zope Database content indexes for use in a grok.Site or grok.Application. The site or application that the indexes are intended for should be named with the grok.site() directive, and the kind of object to index should be named with a grok.context() directive.
Inside their class, the developer should specify one or more grok.index.Field, grok.index.Text, or grok.index.Set instances naming object attributes that should be indexed (and therefore searchable).:
class ArticleIndex(grok.Indexes):
grok.site(Newspaper)
grok.context(Article)
author = index.Field()
title = index.Field()
body = index.Text()
See the grok.index module for more information on field types.
Note
Indexes are persistent: they are stored in the Zope database alongside the site or application that they index. They are created when the site or application is first created (and made persistent), and so an already-created site will not change just because the definition of one of its grok.Indexes changes; it will either have to be deleted and re-created, or some other operation performed to bring its indexes up to date.
Directives:
Required. Identifies the type of objects that should be catalogued. The context type can also be set module-wide.
See also
Required. Identifies the type of site or application in which objects should be catalogued.
See also
Grok index definitions
A grok.Indexes index that matches against an entire field.
alias of FieldIndex
The definition of a particular index in a grok.Indexes class.
This base class defines the actual behavior of grok.index.Field and the other kinds of attribute index that Grok supports. Upon our instantiation, we save every parameter that we were passed; later, if an index actually needs to be created (which is typically at the moment when a new grok.Application object is added to the Zope Database), then our setup() method gets called.
The only parameter that is actually significant to us is attribute which (optionally) defines the attribute we should index. All other parameters are simply passed along to the Zope index we create, which interprets them as configuration details of its own.
Note that, since index creation (and thus a call to our setup() method) currently occurs only during the creation of a new Grok Application object in the Zope Database, the presence of this declaration in Grok application code is nearly always a no-op.
A grok.Indexes index supporting keyword searches of a field.
alias of SetIndex
A grok.Indexes index supporting full-text searches of a field.
alias of TextIndex
A grok.Indexes index similar to, but more flexible than grok.Field index.
The index allows searches for documents that contain any of a set of values; between a set of values; any (non-None) values; and any empty values.
alias of ValueIndex
Example 1: Index the Mammoths in a Herd
Imagine you have a herd of mammoths, and you wish to quickly find a mammoth based on their last name. First we will create a simple Grok application that defines a Herd and some Mammoths:
import grok
import grok.index
import zope.interface
import zope.schema
class Herd(grok.Container, grok.Application):
pass
class IMammoth(zope.interface.Interface):
full_name = zope.schema.TextLine(title=u'Full Name')
class MammothIndexes(grok.Indexes):
grok.site(Herd)
grok.context(IMammoth)
full_name = grok.index.Text()
class Mammoth(grok.Model):
grok.implements(IMammoth)
def __init__(self, full_name):
self.full_name = full_name
We can now create a Herd application, add some Mammoths to the Herd, and query for those Mammoths by their last name.
Imagine root is our ZODB root as provided for instance by a debugger:
>>> herd = Herd()
>>> root['herd'] = herd # <-- the indexes are created here
We manually set the ‘site’ to search. This happens automatically when we do for instance regular browser requests:
>>> from zope.site.hooks import setSite
>>> setSite(herd)
Populate the herd:
>>> herd['one'] = Mammoth('Manfred Mammoth')
>>> herd['two'] = Mammoth('Joe Mammoth')
>>> herd['three'] = Mammoth('Marty the Wooly')
Search the herd:
>>> import zope.component
>>> from zope.catalog.interfaces import ICatalog
>>> catalog = zope.component.getUtility(ICatalog)
>>> mammoths = catalog.searchResults(full_name='Mammoth')
mammoths would be a list containing 'Manfred Mammoth' and 'Joe Mammoth' but not 'Marty the Wooly'
An Adapter takes an object providing an existing interface and extends it to provide a new interface.
The object providing the existing interface is passed to the Adapter in the constructor, and is stored in an attribute named ‘context. The source code for the grok.Adapter base class is simply:
class Adapter(object):
def __init__(self, context):
self.context = context
Base class for an adapter that adapts a single object (commonly referred to as the context).
Use the context directive to specify which object to adapt and the implements directive to specify which interface the adapter will provide. If it’s a named adapter, you may use the name directive to specify the name.
The adapted object.
Base class to define an adapter. Adapters are automatically registered when a module is “grokked”.
The adapted object.
Directives:
See also
See also
Optional. Identifies the name used for the adapter registration. If ommitted, no name will be used.
When a name is used for the adapter registration, the adapter can only be retrieved by explicitely using its name.
See also
See also
Example 1: Simple adaptation example
import grok
from zope import interface
class Cave(grok.Model):
"Cave is the class being adapted (the adaptee)"
def __init__(self, size=100):
self.size = size
class IHome(interface.Interface):
"IHome is the interface we want to add to a Cave"
def renovate():
"Enlarge Cave"
class CaveHome(grok.Adapter):
"Turns a Cave into a Home"
grok.context(Cave)
grok.implements(IHome) # the new interface provided by the adapter
def renovate(self):
# the adaptee is an attribute named 'context'
# and is passed in to the constructor
self.context.size += 10
# Adapation (component look-up) is invoked by passing the adaptee
# to the interface as a constructor and returns the component adapted to
home = IHome(cave)
home.renovate()
# Multiple adapters can exist that adapt and provide the same interfaces.
# They can be distinguished by name.
import zope.component
class LargeCaveHome(grok.Adapater):
"Turns a Cave in a large Home"
grok.context(Cave)
grok.implements(IHome)
grok.name('largehome')
def renovate(self):
self.context.size += 200
largehome = zope.component.getAdapter(cave, IHome, name='largehome')
largehome.renovate()
A MultiAdapter takes multiple objects providing existing interface(s) and extends them to provide a new interface.
The grok.MultiAdapter base class does not provide a default constructor implementation, it’s up to the individual multi-adapters to determine how to handle the objects being adapted.
Base class for an adapter that adapts n objects (where n>=1).
Use the adapts directive to specify which kinds of objects are adapted and the implements directive to specify which interface the adapter will provide. If it’s a named multi-adapter, you may use the name directive to specify the name.
Note that contrary to the Adapter, the MultiAdapter base class does not provide an __init__ method. An __init__ needs to accept the same number of arguments as are used in the adapts directive.
Base class to define a Multi Adapter.
Directives:
- grok.adapts(*objects_or_interfaces)
- Required. Identifies the combination of types of objects or interfaces for the adaptation.
- grok.implements(*interfaces)
- Required. Identifies the interfaces(s) the adapter implements.
- grok.name(name)
Optional. Identifies the name used for the adapter registration. If ommitted, no name will be used.
When a name is used for the adapter registration, the adapter can only be retrieved by explicitely using its name.
- grok.provides(name)
- Only required if the adapter implements more than one interface. grok.provides() is required to disambiguate for which interface the adapter will be registered for.
Example: A home is made from a cave and a fireplace.
import grok
import zope.component
import zope.interface
class Fireplace(grok.Model): pass
class Cave(grok.Model): pass
class IHome(zope.interface.Interface): pass
class Home(grok.MultiAdapter):
grok.adapts(Cave, Fireplace)
grok.implements(IHome)
def __init__(self, cave, fireplace):
self.cave = cave
self.fireplace = fireplace
home = zope.component.getMultiAdapter((cave, fireplace), IHome)
Example: A Grok View is a MultiAdapter
In Grok, MultiAdapters are most commonly encountered in the form of Views. A View is a MultiAdapter which adapts the request and the context to provide the IGrokView interface. You can lookup a View component using the getMultiAdapter function.
class FireplaceView(grok.View):
grok.context(Fireplace)
grok.name('fire-view')
class AlternateFireplaceView(grok.View):
grok.context(Fireplace)
def render(self):
fireplaceview = zope.component.getMultiAdapter(
(self.context, self.request), IGrokView, name='fire-view'
)
return fireplaceview.render()
Annotation components are persistent writeable adapters.
The base class for annotation classes in Grok applications.
Inherits from the persistent.Persistent class.
Example: Storing annotations on model objects
import grok
from zope import interface
# Create a model and an interface you want to adapt it to
# and an annotation class to implement the persistent adapter.
class Mammoth(grok.Model):
pass
class ISerialBrand(interface.Interface):
unique = interface.Attribute("Brands")
class Branding(grok.Annotation):
grok.implements(IBranding)
unique = 0
# Grok the above code, then create some mammoths
manfred = Mammoth()
mumbles = Mammoth()
# creating Annotations work just like Adapters
livestock1 = ISerialBrand(manfred)
livestock2 = ISerialBrand(mumbles)
# except you can store data in them, this data will transparently persist
# in the database for as long as the object exists
livestock1.unique = 101
livestock2.unique = 102
# attributes not listed in the interface will also be persisted
# on the annotation
livestock2.foo = "something"
A global utility is an object which provides an interface, and can be looked-up by that interface and optionally the component name. The attributes provided by a global utility are not persistent.
Examples of global utilities are database connections, XML parsers, and web service proxies.
Base class to define a globally registered utility.
Base class for a globally registered utility. Unless you use the direct directive to indicate that the class itself should be registered as a utility, the class will automatically be instantiated, therefore the constructor may not take any arguments. Use the implements directive to specify which interface the utility provides, or if that is not unambiguous, also use the provides directive to specify which of the implemented interfaces should be used when registering the utility. If it’s a named utility, you may use the name directive to specify the name.
Base class to define a globally registered utility. Global utilities are automatically registered when a module is “grokked”.
Directives:
- grok.implements(*interfaces)
- Required. Identifies the interfaces(s) the utility implements.
- grok.name(name)
Optional. Identifies the name used for the adapter registration. If ommitted, no name will be used.
When a name is used for the global utility registration, the global utility can only be retrieved by explicitely using its name.
- grok.provides(name)
- Maybe required. If the global utility implements more than one interface, grok.provides() is required to disambiguate for what interface the global utility will be registered.
A local utility is an object which provides an interface, and can be looked-up by that interface and optionally the component name. The attributes provided by a local utility are transparently stored in the database (ZODB). This means that configuration changes to a local utility lasts between server restarts.
An example is for database connections or web service proxies, where you need to dynamically provide the connection settings so that they can be edited through-the-web.
The base class for local utilities in Grok applications.
Defines a utility that will be registered local to a Site or grok.Application.
Although application developers can create local utilies without actually subclassing LocalUtility, they gain three benefits from doing so. First, their code is more readable because their classes “look like” local utilities to casual readers. Second, their utility will know how to persist itself to the Zope database, which means that they can set its object attributes and know that the values are getting automatically saved. Third, they can omit the grok.provides() directive naming the interface that the utility provides, if their class only grok.implements() a single interface (unless the interface is one that the grok.LocalUtility already implements, in which case Grok cannot tell them apart, and grok.provides() must be used explicitly anyway).
Defines utilities that will be registered local to a grok.Site or grok.Application object by using the grok.local_utility() directive.
Directives:
- grok.implements(*interfaces)
- Optional. Identifies the interfaces(s) the utility implements.
- grok.name(name)
Optional. Identifies the name used for the adapter registration. If ommitted, no name will be used.
When a name is used for the local utility registration, the local utility can only be retrieved by explicitely using its name.
- grok.provides(name)
Maybe required. If the local utility implements more than one interface or if the implemented interface cannot be determined, grok.provides() is required to disambiguate for what interface the local utility will be registered.
See also
Local utilities need to be registered in the context of grok.Site or grok.Application using the grok.local_utility() directive.
Contains a Site Manager. Site Managers act as containers for registerable components.
If a Site Manager is asked for an adapter or utility, it checks for those it contains before using a context-based lookup to find another site manager to delegate to. If no other site manager is found they defer to the global site manager which contains file based utilities and adapters.
Mixin for creating sites in Grok applications.
When an application grok.Model or grok.Container also inherits from grokcore.site.Site, then it can additionally support the registration of local Component Architecture entities like grokcore.site.LocalUtility and grok.Indexes objects; see those classes for more information.
Views handle interactions between the user and the model. The are constructed with context and request attributes, are responsible for providing a response. The request attribute in a View will always be for a normal HTTP Request.
The determination of what View gets used for what Model is made by walking the URL in the HTTP Request object sepearted by the / character. This process is called “Traversal”.
The base class for views with templates in Grok applications.
Implements the grokcore.view.interfaces.IGrokView interface.
Each class that inherits from grok.View is designed to “render” a category of content objects by reducing them to a document (often an HTML document). Every view has a name, and is invoked when users visit the URL of an eligible context object followed by the name of the view itself:
http://example.com/app/folder/object/viewname
If the view name might conflict with actual content inside of the context (in the above URL, the context might already contain an attribute or item named viewname), then the URL can be explicit that it is asking for a view by preceding its name with @@:
http://example.com/app/folder/object/@@viewname
Instead of returning a full document, views are sometimes used to provide only a snippet of information for inclusion in some larger document; the view can then be called from inside of another view’s page template:
<li tal:content="context/@@viewname">snippet goes here</li>
A view class can specify the category of objects that it can render by calling the grok.context() directive with either a class or an interface. Otherwise, Grok will attempt to determine the context automatically by searching the view’s module for exactly one grok.Model or grok.Container class (or some other class providing the interface IContext) and using that class, if found.
Grok normally creates a view’s name (the name used in URLs) by downcasing the name of the view class itself. The developer can override this by supplying the grok.name() directive instead.
The view name index is special (this works whether the view class itself is named Index, or whether grok.name('index') is used instead). A view named index is used to render an object when the user visits its URL without appending a view name.
Each view needs to generate and return a document. There are two ways of doing so: either the view can provide a render() method that returns a document, or the view can be associated with a page template that Grok will. Page templates can be associated with a view in three different ways:
Before a page template is rendered, Grok will call the update() method on the view, if one is supplied, which can pre-compute values that the template will need to display. Both render() methods and update() methods will find the context for which the view is being rendered under self.context.
The object that the view is presenting. This is often an instance of a grok.Model class, but can be a grok.Application, grok.Container object or any type of Python object.
The HTTP Request object.
The HTTP Response object that is associated with the request.
This is also available as self.request.response, but the response attribute is provided as a convenience.
The HTTP Response object that is associated with the request.
This is also available as self.request.response, but the response attribute is provided as a convenience.
Directory resource containing the static files of the view’s package.
The text of the request body.
Get the body of the associated request.
Redirect to url.
The headers of the response are modified so that the calling browser gets a redirect status code. Please note, that this method returns before actually sending the response to the browser.
url is a string that can contain anything that makes sense to a browser. Also relative URIs are allowed.
status is a number representing the HTTP status code sent back. If not given or None, 302 or 303 will be sent, depending on the HTTP protocol version in use (HTTP/1.0 or HTTP/1.1).
trusted is a boolean telling whether we’re allowed to redirect to ‘external’ hosts. Normally redirects to other hosts than the one the request was sent to are forbidden and will raise a ValueError.
Redirect to url.
The headers of the response are modified so that the calling browser gets a redirect status code. Please note, that this method returns before actually sending the response to the browser.
url is a string that can contain anything that makes sense to a browser. Also relative URIs are allowed.
status is a number representing the HTTP status code sent back. If not given or None, 302 or 303 will be sent, depending on the HTTP protocol version in use (HTTP/1.0 or HTTP/1.1).
trusted is a boolean telling whether we’re allowed to redirect to ‘external’ hosts. Normally redirects to other hosts than the one the request was sent to are forbidden and will raise a ValueError.
Return string for the URL based on the obj and name.
If no arguments given, construct URL to view itself.
If only obj argument is given, construct URL to obj.
If only name is given as the first argument, construct URL to context/name.
If both object and name arguments are supplied, construct URL to obj/name.
Optionally pass a data keyword argument which gets added to the URL as a CGI query string.
If no arguments given, construct URL to view itself.
If only obj argument is given, construct URL to obj.
If only name is given as the first argument, construct URL to context/name.
If both object and name arguments are supplied, construct URL to obj/name.
Returns a dictionary of namespaces that the template implementation expects to always be available.
This method is not intended to be overridden by application developers.
Returns a dictionary of namespaces that the template implementation expects to always be available.
This method is not intended to be overridden by application developers.
Returns a dictionary that is injected in the template namespace in addition to the default namespace.
This method is intended to be overridden by the application developer.
Returns a dictionary that is injected in the template namespace in addition to the default namespace.
This method is intended to be overridden by the application developer.
This method is meant to be implemented by subclasses. It will be called before the view’s associated template is rendered and can be used to pre-compute values for the template.
update() accepts arbitrary keyword parameters which will be filled in from the request (in that case they must be present in the request).
This method is meant to be implemented by grok.View subclasses. It will be called before the view’s associated template is rendered and can be used to pre-compute values for the template.
update() can take arbitrary keyword parameters which will be filled in from the request (in that case they must be present in the request).
A view can either be rendered by an associated template, or it can implement this method to render itself from Python. This is useful if the view’s output isn’t XML/HTML but something computed in Python (plain text, PDF, etc.)
render() can take arbitrary keyword parameters which will be filled in from the request (in that case they must be present in the request).
A view can either be rendered by an associated template, or it can implement this method to render itself from Python. This is useful if the view’s output isn’t XML/HTML but something computed in Python (plain text, PDF, etc.)
render() can take arbitrary keyword parameters which will be filled in from the request (in that case they must be present in the request).
Return the URL of the closest grok.Application object in the hierarchy or the URL of a named object (name parameter) relative to the closest application object.
Send a short message to the user.
A ViewletManager is a component that provides access to a set of content providers (Viewlets). The ViewletManager’s responsibilities are:
- Aggregation of all viewlets registered for the manager.
- Apply a set of filters to determine the availability of the viewlets.
- Sort the viewlets based on some implemented policy. The default is to numerically sort accoring to the grok.order([number]) directive on a Viewlet.
- Provide an environment in which the viewlets are rendered.
- Render itself containing the HTML content of the viewlets.
ViewletManager’s also implement a read-only mapping API, so the Viewlet’s that they contain can be read like a normal Python dictionary.
Typically the Model object for which this ViewletManager is being rendered in the context of.
The Request object.
Reference to the View that the ViewletManager is being provided in.
Returns a dictionary of namespaces that the template implementation expects to always be available.
This method is not intended to be overridden by application developers.
Returns a dictionary that is injected in the template namespace in addition to the default namespace.
This method is intended to be overridden by the application developer.
See zope.contentprovider.interfaces.IContentProvider
This method is called before the ViewletManager is rendered, and can be used to perform pre-computation.
See zope.contentprovider.interfaces.IContentProvider
This method renders the content provided by this ViewletManager. Typically this will mean rendering and concatenating all of the Viewlets managed by this ViewletManager.
Example: Register a ViewletManager and Viewlet and use them from a template for a View
This is a very simple example, ViewletManagers and Viewlets can be used to support more complex HTML layout use cases, such as discriminating on the view or context in which a particular ViewletManager will be rendered. For example, a web site about caves and herds might want to show information in the sidebar specific to either a cave or a herd, depending upon whether a page is displaying information about a cave or a herd.
class ViewForACave(grok.View):
def render():
return grok.PageTemplate("""
<html><body>
<div tal:content="structure provider:cave" />
</body></html>
""")
class CaveManager(grok.ViewletManager):
grok.view(ViewForACave)
grok.name('cave')
class CaveViewlet(grok.Viewlet):
grok.order(30)
grok.viewletmanager(CaveManager)
def render(self):
return "Cave"
Viewlets are a flexible way to compound HTML snippets.
Viewlets are typically used for the layout of the web site. Often all the pages of the site have the same layout with header, one or two columns, the main content area and a footer.
Batteries included viewlet.
- context¶
Typically the Model object for which this Viewlet is being rendered in the context of.
- request¶
The Request object.
- view¶
Reference to the View that the Viewlet is being provided in.
- viewletmanager¶
Reference to the ViewletManager that is rendering this Viewlet.
- default_namespace()¶
Returns a dictionary of namespaces that the template implementation expects to always be available.
This method is not intended to be overridden by application developers.
- namespace()¶
Returns a dictionary that is injected in the template namespace in addition to the default namespace.
This method is intended to be overridden by the application developer.
- update()¶
This method is called before the Viewlet is rendered, and can be used to perfrom pre-computation.
- render()¶
This method renders the content provided by this Viewlet.
Specialized View that returns data in JSON format.
Python data returned is automatically converted into JSON format using the simplejson library. Every method name in a grok.JSON component is registered as the name of a JSON View. The exceptions are names that begin with an _ or special names such as __call__. The grok.require decorator can be used to protect methods with a permission.
Base class for JSON views in Grok applications.
Object that the JSON handler presents.
Request that JSON handler was looked up with.
The HTTP Response object that is associated with the request.
This is also available as self.request.response, but the response attribute is provided as a convenience.
The response sent back to the client.
The text of the request body.
Redirect to url.
The headers of the response are modified so that the calling browser gets a redirect status code. Please note, that this method returns before actually sending the response to the browser.
url is a string that can contain anything that makes sense to a browser. Also relative URIs are allowed.
status is a number representing the HTTP status code sent back. If not given or None, 302 or 303 will be sent, depending on the HTTP protocol version in use (HTTP/1.0 or HTTP/1.1).
trusted is a boolean telling whether we’re allowed to redirect to ‘external’ hosts. Normally redirects to other hosts than the one the request was sent to are forbidden and will raise a ValueError.
Redirect to url.
The headers of the response are modified so that the calling browser gets a redirect status code. Please note, that this method returns before actually sending the response to the browser.
url is a string that can contain anything that makes sense to a browser. Also relative URIs are allowed.
status is a number representing the HTTP status code sent back. If not given or None, 302 or 303 will be sent, depending on the HTTP protocol version in use (HTTP/1.0 or HTTP/1.1).
trusted is a boolean telling whether we’re allowed to redirect to ‘external’ hosts. Normally redirects to other hosts than the one the request was sent to are forbidden and will raise a ValueError.
Return string for the URL based on the obj and name.
If no arguments given, construct URL to view itself.
If only obj argument is given, construct URL to obj.
If only name is given as the first argument, construct URL to context/name.
If both object and name arguments are supplied, construct URL to obj/name.
Optionally pass a data keyword argument which gets added to the URL as a CGI query string.
Lookup a name and return an object with self.context as its parent. The method can use the request to determine the correct object.
The request argument is the publisher request object. The name argument is the name that is to be looked up. It must be an ASCII string or Unicode object.
If a lookup is not possible, raise a NotFound error.
Returns an object and a sequence of names.
The publisher calls this method at the end of each traversal path. If the sequence of names is not empty, then a traversal step is made for each name. After the publisher gets to the end of the sequence, it will call browserDefault on the last traversed object.
The default behaviour in Grok is to return self.context for the object and 'index' for the default view name.
Note that if additional traversal steps are indicated (via a nonempty sequence of names), then the publisher will try to adjust the base href.
Example 1: Create a public and a protected JSON view.
class MammothJSON(grok.JSON):
"""
Returns JSON from URLs in the form of:
http://localhost/stomp
http://localhost/dance
"""
grok.context(zope.interface.Interface)
def stomp(self):
return {'Manfred stomped.': ''}
@grok.require('zope.ManageContent')
def dance(self):
return {'Manfred does not like to dance.': ''}
Specialized View for making web services that conform to the REST style. These Views can define methods named GET, PUT, POST and DELETE, which will be invoked based on the Request type.
Base class for REST views in Grok applications.
Object that the REST handler presents.
Request that REST handler was looked up with.
The HTTP Response object that is associated with the request.
This is also available as self.request.response, but the response attribute is provided as a convenience.
The response sent back to the client.
The text of the request body.
The text of the request body.
Return string for the URL based on the obj and name.
If no arguments given, construct URL to view itself.
If only obj argument is given, construct URL to obj.
If only name is given as the first argument, construct URL to context/name.
If both object and name arguments are supplied, construct URL to obj/name.
Optionally pass a data keyword argument which gets added to the URL as a CGI query string.
Redirect to url.
The headers of the response are modified so that the calling browser gets a redirect status code. Please note, that this method returns before actually sending the response to the browser.
url is a string that can contain anything that makes sense to a browser. Also relative URIs are allowed.
status is a number representing the HTTP status code sent back. If not given or None, 302 or 303 will be sent, depending on the HTTP protocol version in use (HTTP/1.0 or HTTP/1.1).
trusted is a boolean telling whether we’re allowed to redirect to ‘external’ hosts. Normally redirects to other hosts than the one the request was sent to are forbidden and will raise a ValueError.
Redirect to url.
The headers of the response are modified so that the calling browser gets a redirect status code. Please note, that this method returns before actually sending the response to the browser.
url is a string that can contain anything that makes sense to a browser. Also relative URIs are allowed.
status is a number representing the HTTP status code sent back. If not given or None, 302 or 303 will be sent, depending on the HTTP protocol version in use (HTTP/1.0 or HTTP/1.1).
trusted is a boolean telling whether we’re allowed to redirect to ‘external’ hosts. Normally redirects to other hosts than the one the request was sent to are forbidden and will raise a ValueError.
Specialized View that responds to XML-RPC.
Base class for XML-RPC endpoints in Grok applications.
When an application creates a subclass of grok.XMLRPC, it is creating an XML-RPC view. Like other Grok views, each grok.XMLRPC component can either use an explicit grok.context() directive to specify the kind of object it wraps, or else Grok will look through the same module for exactly one grok.Model or grok.Container (or other IGrokContext implementor) and make that class its context instead.
Every object that is an instance of the wrapped class or interface becomes a legitimate XML-RPC server URL, offering as available procedures whatever methods have been defined inside of that grok.XMLRPC component. When a method is called over XML-RPC, any parameters are translated into normal Python data types and supplied as normal positional arguments. When the method returns a value or raises an exception, the result is converted back into an XML-RPC response for the client. In both directions, values are marshalled transparently to and from XML-RPC data structures.
During the execution of an XML-RPC method, the object whose URL was used for the XML-RPC call is available as self.context.
Object that the REST handler presents.
Request that REST handler was looked up with.
The HTTP Response object that is associated with the request.
This is also available as self.request.response, but the response attribute is provided as a convenience.
The response sent back to the client.
The text of the request body.
The text of the request body.
Return string for the URL based on the obj and name.
If no arguments given, construct URL to view itself.
If only obj argument is given, construct URL to obj.
If only name is given as the first argument, construct URL to context/name.
If both object and name arguments are supplied, construct URL to obj/name.
Optionally pass a data keyword argument which gets added to the URL as a CGI query string.
Redirect to url.
The headers of the response are modified so that the calling browser gets a redirect status code. Please note, that this method returns before actually sending the response to the browser.
url is a string that can contain anything that makes sense to a browser. Also relative URIs are allowed.
status is a number representing the HTTP status code sent back. If not given or None, 302 or 303 will be sent, depending on the HTTP protocol version in use (HTTP/1.0 or HTTP/1.1).
trusted is a boolean telling whether we’re allowed to redirect to ‘external’ hosts. Normally redirects to other hosts than the one the request was sent to are forbidden and will raise a ValueError.
Example 1: Create a public and a protected XML-RPC view.
The grok.require decorator can be used to protect methods with a permission.
import grok
import zope.interface
class MammothRPC(grok.XMLRPC):
grok.context(zope.interface.Interface)
def stomp(self):
return 'Manfred stomped.'
@grok.require('zope.ManageContent')
def dance(self):
return 'Manfred doesn\'t like to dance.'
A Traverser is used to map from a URL to an object being published (Model) and the View used to interact with that object.
Base class for traversers in Grok applications.
Override the traverse() method to supply the desired custom traversal behaviour.
The object that is being traversed.
The HTTP Request object.
You must provide your own implementation of this method to do what you want. If you return None, Grok will use the default traversal behaviour.
Returns an object and a sequence of names.
The publisher calls this method at the end of each traversal path. If the sequence of names is not empty, then a traversal step is made for each name. After the publisher gets to the end of the sequence, it will call browserDefault on the last traversed object.
The default behaviour in Grok is to return self.context for the object and 'index' for the default view name.
Note that if additional traversal steps are indicated (via a nonempty sequence of names), then the publisher will try to adjust the base href.
Lookup a name and return an object with self.context as its parent. The method can use the request to determine the correct object.
The request argument is the publisher request object. The name argument is the name that is to be looked up. It must be an ASCII string or Unicode object.
If a lookup is not possible, raise a NotFound error.
Example 1: Traverse into a Herd Model and return a Mammoth Model
import grok
class Herd(grok.Model):
def __init__(self, name):
self.name = name
class HerdTraverser(grok.Traverser):
grok.context(Herd)
def traverse(self, name):
return Mammoth(name)
class Mammoth(grok.Model):
def __init__(self, name):
self.name = name
Page Templates are the default templating system for Grok, they are an implementation of the Template Attribute Language (TAL). Page Templates are typically created from a string.
grok.PageTemplate("<h1>Hello World!</h1>")
Creates a Page Template from a filename.
grok.PageTemplateFile("my_page_template.pt")
Forms inherit from the grok.View class. They are a specialized type of View that renders an HTML Form.
The base class for forms in Grok applications.
A class that inherits from grok.Form is a grok.View whose template will be given information about the fields in its context, and use that information to render an HTML form for adding or editing the form. Generally developers use one of the subclasses:
Template used to display the form
The object for which the form is rendered.
Page-element prefix. All named or identified page elements in a subpage should have names and identifiers that begin with a subpage prefix followed by a dot.
Update the subpage prefix
A label to display at the top of a form.
An update status message. This is normally generated by success or failure handlers.
Sequence of errors encountered during validation.
Return from action result method.
Boolean indicating whether the form needs to be reset.
The form’s form field definitions.
This attribute is used by many of the default methods.
The form’s widgets.
The text of the request body.
The text of the request body.
The HTTP Response object that is associated with the request.
This is also available as self.request.response, but the response attribute is provided as a convenience.
The response sent back to the client.
Set up the form’s widgets.
The default implementation uses the form definitions in the form_fields attribute and setUpInputWidgets().
The function should set the widgets attribute.
The default form validator
If an action is submitted and the action doesn’t have it’s own validator then this function will be called.
Reset any cached data because underlying content may have changed.
Return views of any errors.
The errors are returned as an iterable.
Save form data to an object.
This returns a dictionary with interfaces as keys and lists of field names as values to indicate which fields in which schemas had to be changed in order to save the data. In case the method works in update mode (e.g. on EditForms) and doesn’t have to update an object, the dictionary is empty.
Return the URL of the closest grok.Application object in the hierarchy or the URL of a named object (name parameter) relative to the closest application object.
Deprecated since version 0.13: Use applyData() instead.
Returns a dictionary of namespaces that the template implementation expects to always be available.
This method is not intended to be overridden by application developers.
Send a short message to the user.
Returns a dictionary that is injected in the template namespace in addition to the default namespace.
This method is intended to be overridden by the application developer.
Redirect to url.
The headers of the response are modified so that the calling browser gets a redirect status code. Please note, that this method returns before actually sending the response to the browser.
url is a string that can contain anything that makes sense to a browser. Also relative URIs are allowed.
status is a number representing the HTTP status code sent back. If not given or None, 302 or 303 will be sent, depending on the HTTP protocol version in use (HTTP/1.0 or HTTP/1.1).
trusted is a boolean telling whether we’re allowed to redirect to ‘external’ hosts. Normally redirects to other hosts than the one the request was sent to are forbidden and will raise a ValueError.
Render the form, either using the form template or whatever the actions returned in form_result.
Subclasses can override this method just like on regular grok.Views. It will be called before any form processing happens.
Update the form, i.e. process form input using widgets.
On zope.formlib forms, this is what the update() method is. In grok views, the update() method has a different meaning. That’s why this method is called update_form() in grok forms.
Return string for the URL based on the obj and name.
If no arguments given, construct URL to view itself.
If only obj argument is given, construct URL to obj.
If only name is given as the first argument, construct URL to context/name.
If both object and name arguments are supplied, construct URL to obj/name.
Optionally pass a data keyword argument which gets added to the URL as a CGI query string.
Add forms are used for creating new objects. The widgets for this form are not bound to any existing content or model object.
Edit forms are used for editing existing objects. The widgets for this form are bound to the object set in the context attribute.
Display forms are used to display an existing object. The widgets for this form are bound to the object set in the context attribute.
Permissions are used to protect Views so that they can only be called by an authenticated principal. If a View in Grok does not have a grok.require() directive declaring a permission needed to use the View, then the default anonymously viewable zope.View permission used.
Base class for permissions. You must specify a unique name for every permission using the grok.name() directive. The convention for ensuring uniqueness is to prefix your permission name with the name of your Grok package followed by a dot, e.g. 'mypackage.MyPermissionName'.
Id as which this permission will be known and used. This is set to the value specified in the grok.name() directive.
Human readable identifier for this permission.
Description of the permission.
Directives:
grok.name(name)
Required. Identifies the unique name (also used as the id) of the permission.
grok.title(title)
Optional. Stored as the title attribute for this permission.
grok.description(description)
Optional. Stored as the description attribute for this permission.
Example 1: Define a new Permission and use it to protect a View
import grok
import zope.interface
class Read(grok.Permission):
grok.name('mypackage.Read')
class Index(grok.View):
grok.context(zope.interface.Interface)
grok.require('mypackage.Read')
Roles provide a way to group together a collection of permissions. Principals (aka Users) can be granted a Role which will allow them to access all Views protected by the Permissions that the Role contains.
Base class for roles in Grok applications.
A role is a description of a class of users that gives them a machine-readable name, a human-readable title, and a set of permissions which users belong to that role should possess:
class Editor(grok.Role):
grok.name('news.Editor')
grok.title('Editor')
grok.permissions('news.EditArticle', 'news.PublishArticle')
Id as which this role will be known and used. This is set to the value specified in the grok.name() directive.
Human readable identifier for this permission.
Description of the permission.
Directives:
grok.name(name)
Required. Identifies the unique name (also used as the id) of the role.
grok.permissions(permissions)
Required. Declare the permissions granted to this role. These can refer by permission class or by name.
grok.title(title)
Optional. Stored as the title attribute for this role.
grok.description(description)
Optional. Stored as the description attribute for this role.
Example 1: Define a new ‘paint.Artist’ Role and assign it to the ‘paint.grok’ principal
import grok
import zope.interface
class ViewPermission(grok.Permission):
grok.name('paint.ViewPainting')
class EditPermission(grok.Permission):
grok.name('paint.EditPainting')
class ErasePermission(grok.Permission):
grok.name('paint.ErasePainting')
class ApprovePermission(grok.Permission):
grok.name('paint.ApprovePainting')
class Artist(grok.Role):
"""
An Artist can view, create and edit paintings. However, they can
not approve their painting for display in the Art Gallery Cave.
"""
grok.name('paint.Artist')
grok.title('Artist')
grok.description('An artist owns the paintings that they create.')
grok.permissions(ViewPermission, EditPermission, ErasePermission)
# alternatively, use permission names
# grok.permissions(
# 'paint.ViewPainting', 'paint.EditPainting', 'paint.ErasePainting')
class CavePainting(grok.View):
grok.context(zope.interface.Interface)
grok.require(ViewPermission)
def render(self):
return 'What a beautiful painting.'
class EditCavePainting(grok.View):
grok.context(zope.interface.Interface)
grok.require(EditPermission)
def render(self):
return 'Let\'s make it even prettier.'
class EraseCavePainting(grok.View):
grok.context(zope.interface.Interface)
grok.require(ErasePermission)
def render(self):
return 'Oops, mistake, let\'s erase it.'
class ApproveCavePainting(grok.View):
grok.context(zope.interface.Interface)
grok.require(ApprovePermission)
def render(self):
return 'Painting owners cannot approve their paintings.'
# The app variable will typically be your Application instance,
# but could also be a container within your application.
from zope.securitypolicy.interfaces import IPrincipalRoleManager
IPrincipalRoleManager(app).assignRoleToPrincipal(
'paint.Artist', 'paint.grok')