TextformatterHannaCode by Ryan Cramer

Easily insert any complex HTML, Javascript or PHP output in your ProcessWire content by creating your own Hanna code tags.

Hanna Code

Easily insert any complex HTML, Javascript or PHP output in your ProcessWire content by creating your own Hanna code tags.

This module is based loosely on the WordPress Hana Code Insert plugin.

A Hanna code tag looks like [[hello_world]]. The open and close tags are user definable, [[ and ]] are just the defaults. A Hanna code tag with attributes looks like [[hello_world foo="bar" bar="foo"]] using HTML style attributes or [[hello_world foo=bar, bar=foo]] using ProcessWire selector style attributes. After installing the module, you define your Hanna codes in Setup > Hanna Code.

These Hanna codes that you define can then be entered within your body copy (or other text where you allow) and they will be replaced with the values defined or generated by your Hanna code. A common use case is to embed scripts or other bits of HTML or codes that would usually be stripped out by an editor like TinyMCE. However, Hanna codes can be more than just static snippets--they can be dynamic PHP or Javascript that outputs different things according to the request. PHP-based Hanna codes have access to the entire ProcessWire API.

Hanna code accepts named attributes in the tag that can be passed as variables to PHP and Javascript Hanna codes. These attributes can be specified either in HTML attribute format or ProcessWire selector format. In either case, quotes should be used around the attribute value when the value contains whitespace or a comma.

How to install

  1. Place the module files in /site/modules/TextformatterHannaCode/
  2. In your admin, click Modules > Check for new modules
  3. Click "install" for TextformatterHannaCode (Hanna Code Text Formatter)
  4. Now to go Setup > Fields and locate the Textarea field(s) that you want to use Hanna codes with ("body" for instance).
  5. When editing the field, click the "details" tab, and select "Hanna Code Text Formatter" as the Textformatter. Save.
  6. To add or edit Hanna Codes, ProcessWire must be in debug mode, or Hanna Code must have its “safe mode’ disabled. See the “Security” section below this for more details and instructions
  7. Now go to Setup > Hanna Code and start defining your Hanna Codes! You may want to use one of the examples from this document to get started.


There are major security implications with a tool that will let you enter unfiltered text and code from your web browser. As a result, Hanna codes are meant for definition only by superusers and we recommend keeping it that way.

Hanna Code editing is a development task and is meant only for sites in development. Access to edit PHP or JS scripts from a web browser is a big security problem when in the wrong hands. For this reason, editing features are disabled unless ProcessWire is in debug mode or you have specifically disabled Hanna Code’s “safe mode”.

ProcessWire’s debug mode can be enabled by setting $config->debug = true in your /site/config.php file. Or if you prefer, Hanna Code’s editor can be specifically enabled by setting $config->HannaCodeEdit = true; in /site/config.php. For live/production sites, be sure to reverse these changes once you are done editing or adding Hanna Codes.

These considerations are primarily to protect your server just in case a superuser account were ever to be compromised.

Tag format

Below is a Hanna code tag named hello_world with no attributes. If you pasted this into your body copy, you would get whatever the replacement value is that you defined.


Below is a Hanna code tag named hello_world being passed attributes of foo, bar and foobar. If this were a PHP-based Hanna code, it would receive the variables $foo, $bar and $foobar:

[[hello_world foo="bar" bar="foo" foobar="foo bar"]]

Below is the same Hanna code tag as above, but with attributes more like ProcessWire selectors. You can use whatever format you prefer. Just note that unlike regular ProcessWire selectors, quotes (single or double) are required around any value that has whitespace.

[[hello_world, foo=bar, bar=foo, foobar="foo bar"]]

How to use

Please make sure that you have completed the How to install section first. Then in your admin, go to Setup > Hanna Codes.

Each Hanna code that you add has a type of either: Text/HTML, Javascript or PHP. The Text/HTML type is literally self explanatory in that your [[custom-tag]] is replaced with exactly the text you paste in. Anywhere that you type your [[custom-tag]] in your body copy will be replaced with exactly the static text you defined.

More power opens up with the Javascript and/or PHP types of codes. These codes execute at runtime and thus can contain specific logic to produce different results. In fact, PHP Hanna codes have access to the entire ProcessWire API and are executed in the same manner as template files. Your PHP-based Hanna code should simply "echo" or "print" the replacement value.

PHP example

  • Create a new Hanna code with the name "children".
  • Select "PHP" as the type.
  • Paste in the following for the code:
<?php namespace ProcessWire;
foreach($page->children as $child) {
  echo "<p><a href='$child->url'>$child->title</a>";
  • Now go and edit a page that has children. In the body copy, enter [[children]] in the place where you want the output to appear.
  • View the page, and you should see the rendered list of links to children.

PHP example, part 2

Now lets take the above example further...

  • Go back and edit your "children" Hanna code, as we are going to modify it to respond to a "parent" attribute. Change the code to this:
<?php namespace ProcessWire;

if(isset($parent)) {
  // If $parent is an ID or path, lets convert it to a Page
  $parent = $pages->get($parent);
} else {
  // otherwise lets assume the current page is the parent
  $parent = $page;

foreach($parent->children as $child) {
  echo "<p><a href='$child->url'>$child->title</a>";
  • Go back and edit the page where you previously inserted the [[children]] tag, and change it to: [[children, parent=1]] (specifying the homepage) or [[children, parent=/path/to/some/parent/]] if you want to try something else.

  • View the page and you should now see it showing the children of the homepage (or of another parent you specified).

Please see the Javascript and PHP usage notes on the Hanna code entry screen.

Using Hanna Code from the API

If you want to populate Hanna Code from the API, you can do so using the render() method, like this:

$hanna = $modules->get('TextformatterHannaCode'); 
$page->body = $hanna->render($page->body);

PHP Usage Notes

  1. Your code should echo or print the value you want to appear as the replacement for the tag.

  2. It is not necessary to begin or close your statement with open/close PHP tags. However an opened PHP tag is recommended at least for syntax highlighting. I recommend using <?php namespace ProcessWire; as your opening PHP tag.

  3. Your code is executed the same way as a ProcessWire template file and all API variables are locally scoped. Meaning, you can call upon $page, $pages, or any other API variables. directly. See also the PHP Properties section.

  4. If attributes are specified in the tag, they will appear as locally scoped variables to your PHP code. For instance, in the tag [[hello_world first_name=Karena]], your code will have a $first_name variable populated with 'Karena'. To check for the presence of these attributes, use isset($first_name); for example.

  5. All attributes are also populated to an $attr array of [key=value]. For example: $attr['first_name'] == 'Karena', in case you find this syntax preferable, or necessary.

  6. If you use an attribute name that is the same as an API variable name (example: $page) then the API variable overrides the attribute name. In that case, the attribute value will only be accessible through $attr (example: $attr['page']).

  7. Your code receives an object named $hanna. This can be used for getting additional properties, or modifying the larger text value if necessary. See details in the PHP Properties section.

  8. The $page API variable available to your Hanna code represents the page where the Hanna code exists. It is possible for this to be different from wire('page'), which represents the page that originated the request.

  9. These code snippets are written to /site/assets/cache/HannaCode/[tag-name].php and directly executed rather than eval(d).

PHP Properties

  • $attr
    An array of [key=value] attributes passed to your Hanna code.

  • $page
    The page where the Hanna code exists.

  • $hanna->name
    The name (string) of the current Hanna code.

  • $hanna->field
    The Field object representing the text.

  • $hanna->value
    The larger text where the Hanna code lives. This property may also be set.

Please note that "name" is a reserved word and may not be used as an attribute name.

Javascript Usage Notes

  1. It is not necessary to include script tags in your code unless you want to. They will be automatically inserted when not already present.

  2. If attributes are specified in the tag (or in the attributes section of this page), they will appear as locally scoped variables to your Javascript code. For instance, in the tag [[hello_world first_name=Karena]], your code will have a first_name variable populated with 'Karena'.

  3. All attributes are also populated to an attr object of attr.key=value (i.e. attr.first_name == 'Karena'), in case you find this syntax preferable.

  4. If using attributes, it is recommended that you define defaults in the Attributes field in the Hanna Code editor (even if blank is the default value).

  5. Note that name is a reserved word and may not be used as an attribute name.


Hanna codes can be exported and then imported somewhere else. To export, click the Export field in the Hanna Code editor and copy the export data to your clipboard. Now you may import this data in another Hanna Code installation by clicking the Import button and pasting in the data. Here is one to get you started:

Jumplinks Hanna Code (example for import)

This Hanna code is meant to be used in your body copy. It collects all the headline tags in the text and turns them into anchor jump links while outputting a linked table of contents. It will put the table of contents wherever you type the Hanna code.

Import Data:


Usage Examples:

[[jumplinks]] Locates all h2 and h3 headlines, turns them into anchors, and generates a table of contents. This is the default behavior with no attributes.

[[jumplinks for=h2]] Here we specify a 'for' attribute. It produces the same behavior as above except only anchors h2 headlines.

[[jumplinks for="h2 h4"]] Same as above except only anchors h2 and h4 headlines.

Copyright 2021 by Ryan Cramer (Originally released in 2013)

Install and use modules at your own risk. Always have a site and database backup before installing new modules.

Latest news

  • ProcessWire Weekly #523
    In the 523rd issue of ProcessWire Weekly we'll check out what's new in the core this week, share some new module related news, and more. Read on!
    Weekly.pw / 18 May 2024
  • ProFields Table Field with Actions support
    This week we have some updates for the ProFields table field (FieldtypeTable). These updates are primarily focused on adding new tools for the editor to facilitate input and management of content in a table field.
    Blog / 12 April 2024
  • Subscribe to weekly ProcessWire news

“To Drupal, or to ProcessWire? The million dollar choice. We decided to make an early switch to PW. And in retrospect, ProcessWire was probably the best decision we made. Thanks are due to ProcessWire and the amazing system and set of modules that are in place.” —Unni Krishnan, Founder of PigtailPundits