6.3.1 How Custom Tags Work

To understand how the Custom Tags API can be used, you need to know how the PSE parser handles custom tags. Whenver the opening tag of first custom tag is encountered in the template, the constructor for the CustomTag class is called, creating an object. When the parser reaches the closing tag, the parser causes code to be generated that displays the output of a str() on the object, i.e. the object's __str__ method is called. The default __str__ method returns a string composed by joining the str() of each object contained in the object's _contents attribute. What gets put in the _contents list is explained below.

If a custom tag object is contained inside another custom tag in the template, instead of printing the output of __str__ when the closing tag is encountered, the object is passed to the containing custom tag object's add method. The default action of the add method is to add to the containing object's _contents list whatever was passed as an argument. The add method has the following signature:

add( self, thing)
The argument thing is the custom tag object being passed to be added to the self._contents list.

If bare HTML is encountered inside the custom tag, then the object's addString method is called, which appends the string to the object's _contents list. The addString method has the following signature:

addString( self, text)
The argument text is the bare HTML being added to the self._contents list.

To use the Custom Tag API, you need to subclass CustomTag from the pse_handler.api module and override the methods described above. Usually your overridden methods will eventually call the base methods.

Finally, when using the Custom Tag API you will usually want to override the __init__ method to initialize the object. The __init__ method has the following signature:

__init__( self, id = None, *arg, **kw)
id is the id attribute from the tag in the template file. It is also the way to refer to the same tag in the Python code module. In the base implementation, *arg and **kw are ignored.

Note: Parameters are passed from PSE templates in all lower case. Therefore, the named parameters for the constructor should all be in lower case.

Since objects created using the Custom Tag API are cached and reused, your overridden __init__ method should look something like this:

    def __init__(self, id = None, *arg, **kw):
        if self.needs_init:
            CustomTag.__init__(self, id)
            # put other initialization here

This way, if the custom tag object is created twice using the same id, the object will only be registered and initialized on the first call. You could allow overriding of certain attributes regardless of how many times the custom tag object was created, and that would appear outside the if statement. This is an advanced usage of the API and special care should be taken when doing so.

In order to make your custom tags usable in your application, you need to make a module that defines all your custom tag classes. By default, the corresponding tag in the template will have the same name as the class itself, but you can override this by setting the _name class attribute. In the pse.conf file in the [Parser] section, set TagHooksModule to the full path of your custom tags module. The TagHooksModule parameter can be a list of modules if you want to use more than one module containing custom tag classes. You will need to restart apache for the changes to take effect.

Finally, sometimes it is desirable to suspend PSE's processing of data contained between the start and end of a custom tag within a PSE template. This can be done by setting the _suspend_processing class attribute to False. This value is True by default. New in version 3.0.