ebullient·works

[ About · Archive ]

TXP Hack: MT-Macro like function in textpattern

This is a simple hack to add one of my favorite MT-plugins, Brad Choate's MTMacros [bradchoate.com], to textpattern.

Granted, I didn't pull the entire kaboodle. This doesn't do fun container logic and acronym matching, etc. But it does do simple string replacement, which is what I used it for (e.g. smilies and pretty attributions).

[Based on Textpattern 1.0rc1]

Using macros with original lib/classTextile.php

I add one method to lib/classTextile.php (either the original, or the modified version provided by Colin Brown1 that provides extended blocks, escaped blocks, and better handling of <pre> tags).

    /**
     * Performs string replacement based on a provided 
     * array containing 'pattern' => 'replacement' pairs.
     * 
     * @parameter string $text Text to process
     * @parameter string $list Name of global variable containing
     *                         array of pattern/replacement pairs.
     */
    function customMacros($text, $list)
    {
        $macros = $GLOBALS[$list];

        if ( isset($macros) && is_array($macros) )
        {
            $patterns = array_keys($macros);
            $replace = array_values($macros);
            $text = str_replace($patterns, $replace, $text);
        }
        return $text;
    }

I added two calls to this method within the TextileThis method of lib/classTextile.php.

The first is just after we mark that text which should not be textiled:

    $text = $this->customMacros($text, 'pre_macros');

This expands macros before other textile substitutions.

The second is just before the <notextile> tags are replaced (it could also be just after):

    $text = $this->customMacros($text, 'post_macros');

The second parameter passed to the textileMacros method is the name of a global environment variable holding an array of macro definitions (e.g. pre_macros or post_macros). You can change these names to suit, but the array declaration (given what is above) should look something like this:

  global $pre_macros, $post_macros;

  $pre_macros = array(
    '=&#41;'  => '&lt;img src="/cheesy.gif" />',
   '&lt;/z>' => ' &lt;/q>',
          );


  $post_macros = array( 
    '&lt;z>'  => '&lt;span class="attribute">[',
   ' &lt;/q>' => ']&lt;/span>',
           );

I use a custom tag to generate formatted attribution text, e.g. <z>"link.com":http://link.com</z> generates <span class="attribute>[<a href="link.com">link.com<a>]</span>.

The combination of pre/post tags adjusts spacing to allow textpattern to properly work around my custom tag.

Using macros with original TextilePHP

This also works with TextilePHP [jimandlissa.com].

I made the following updates to their class:

  • Added TextileThis, as others have done2, to make it TXP compatible.
  • Added customMacros method, as above, with two calls for pre-textile processing, and post-textile processing.
    • $str = $this->customMacros($str, 'pre_macros');
      'pre_macros' are used just before the check for disabled html
    • $out = $this->customMacros($str, 'post_macros');
      'post_macros' are used just before the cleanup to
      restore preserved blocks.
  /**
   * Wrapper function for compatibility with TXP
   */
  function TextileThis($text, $lite='', $encode='', $noimage='', $strict='')
  {
    if (get_magic_quotes_gpc())
           $text = stripslashes($text);

    if ( $encode )
        return $this->encode_html_basic($text);
        
    if ( $lite )
        $this->disable_html(true);

    return $this->process($text);
  } // function TextileThis

Footnotes

1 Unofficial Textile 2.0 beta [solarorange.com], from this thread [forum.textpattern.com].

2 TextilePHP for TXP [greenrift.textdrive.com], as mentioned in this thread [forum.textpattern.com].