You are here

Pet token

Submitted by Peter on Fri, 2011-07-15 18:15

Pet token is my design for an improved token support in Drupal. I wrote something more extensive for a document processor many years ago and Pet token is based on the most useful parts of the earlier work.

Drupal token processing does not work in content and, where it does work, it works only during content creation. There is a need for content token processing during content updates and again during content viewing. There is also a need to process tokens within tokens.

Tokens in tokens

Start with the following diagram.
[____[----]____]

[________] represents a token that could be handled by existing token processing. [----] represents a token that could be handled by existing token processing. placing one token inside another token requires a process where the inside token is expanded first then the outside token is expanded.

You could make token processing recursive. Scan the whole document for simple tokens, including [----], expand the simple tokens, then scan the document again for tokens and loop around until there are no unexpanded tokens left. A more complex and potentially faster approach would be to extract the complex tokens then scan the extracted tokens for simpler tokens. You would reduce the total text scanning time. Each level of processing could be implemented as a child object.

Efficiency

There is a processing overhead required to find the right process for a token. Some tokens would be used multiple times in a document. The code could easily accumulate links to the processing for each token and access that right process direct without repeating the discovery process.

Consider the following token.
[a b c]

The code should look for a process accepting [a b c]. If the code cannot find a process for token [a b c], the code should look for a process accepting [a b and pass c as a parameter. If the code cannot find a process for token [a b, the code should look for a process accepting [a and pass b, c as parameters.

Module name

[a would typically be a module name.

A simple first cut

[a b c] would load a class named a_b_c from a file named a_b_c.class.php. Drupal makes .php files public and .inc files private so, for Drupal, we could make it a_b_c.class.inc. The class would start with the following code.

class a_b_c
    {
    function __construct()

If class a_b_c is missing, [a b c] would load a class named a_b from a file named a_b.class.inc and starting start with the following code.

class a_b
    {
    function __construct($c)

If class a_b is missing, [a b c] would load a class named a from a file named a.class.inc and starting start with the following code.

class a
    {
    function __construct($b, $c)

A second cut

You would have to pass a variety of other things to the processing object and it is easier to pass them using methods. Inheriting a template makes sense. Create a template class:

class pet_token_template
    {
    function __construct()

Create your class by extending the template class.

class a_b_c extends pet_token_template
    {
    function __construct()

The template can provide code for passing parameters and other standard data. Some of the standard information could be Drupal functions.

Conversion during save or view?

One of the best parts of the processing is the separation of substitution into two phases, one when a content update is saved and another when content is viewed. All the tokens would be processed when the content is saved. if there are valid tokens not expanded during the save, the unprocessed tokens would be processed when the content is viewed. Each content node would have a field to indicate the presence of tokens requiring processing during viewing. The indicator would save repeated processing of content not needing processing.

How do we set the indicator? During the save, we process all potential tokens. If a token has no process, we forget it. If a token is expanded at save time, we forget it. Any token that has a process, but is not expanded during the save, is marked for expansion during the view phase.