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.
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.
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.
[[hello_world]]
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"]]
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 namespace ProcessWire;
foreach($page->children as $child) {
echo "<p><a href='$child->url'>$child->title</a>";
}
[[children]]
in the place where you want the output to appear. Now lets take the above example further...
<?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.
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);
Your code should echo
or print
the value you want to appear as the replacement for the tag.
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.
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.
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.
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.
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']
).
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.
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.
These code snippets are written to /site/assets/cache/HannaCode/[tag-name].php
and directly executed rather than eval(d).
$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.
It is not necessary to include script tags in your code unless you want to. They will be automatically inserted when not already present.
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'.
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.
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).
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:
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:
!HannaCode:jumplinks:eyJuYW1lIjoianVtcGxpbmtzIiwidHlwZSI6IjIiLCJjb2RlIjoiXC8qaGNfYXR0clxuZm9yPVwiaDIgaDNcIlxuaGNfYXR0cipcL1xuJGZvciA9IHN0cl9yZXBsYWNlKCcs
JywgJyAnLCAkZm9yKTtcclxuJGZvciA9IGV4cGxvZGUoJyAnLCAkZm9yKTtcclxuZm9yZWFjaCgkZm9yIGFzICRrID0+ICR2KSAkZm9yWyRrXSA9IHRyaW0oJHYpO1xyXG5cclxuJGZvciA9IGltcGxvZ
GUoJ3wnLCAkZm9yKTtcclxuJGFuY2hvcnMgPSBhcnJheSgpOyBcclxuJHZhbHVlID0gJGhhbm5hLT52YWx1ZTsgXHJcblxyXG5pZihwcmVnX21hdGNoX2FsbCgnezwoJyAuICRmb3IgLiAnKVtePl0qPi
guKz8pPFwvXFwxPn1pJywgJHZhbHVlLCAkbWF0Y2hlcykpIHtcclxuICBmb3JlYWNoKCRtYXRjaGVzWzFdIGFzICRrZXkgPT4gJHRhZykge1xyXG4gICAgJHRleHQgPSAkbWF0Y2hlc1syXVska2V5XTt
cclxuICAgICRhbmNob3IgPSAkc2FuaXRpemVyLT5wYWdlTmFtZSgkdGV4dCwgdHJ1ZSk7XHJcbiAgICAkYW5jaG9yc1skYW5jaG9yXSA9ICR0ZXh0OyBcclxuICAgICRmdWxsID0gJG1hdGNoZXNbMF1b
JGtleV07IFxyXG4gICAgJHZhbHVlID0gc3RyX3JlcGxhY2UoJGZ1bGwsIFwiPGEgbmFtZT0nJGFuY2hvcicgaHJlZj0nIyc+PFwvYT4kZnVsbFwiLCAkdmFsdWUpOyBcclxuICB9ICBcclxuICAkaGFub
mEtPnZhbHVlID0gJHZhbHVlOyBcclxufVxyXG5cclxuaWYoY291bnQoJGFuY2hvcnMpKSB7XHJcbiAgZWNobyBcIjx1bCBjbGFzcz0nanVtcGxpbmtzJz5cIjtcclxuICBmb3JlYWNoKCRhbmNob3JzIG
FzICRhbmNob3IgPT4gJHRleHQpIHtcclxuICAgIGVjaG8gXCI8bGk+PGEgaHJlZj0nJHBhZ2UtPnVybCMkYW5jaG9yJz4kdGV4dDxcL2E+PFwvbGk+XCI7XHJcbiAgfVxyXG4gIGVjaG8gXCI8XC91bD5
cIjtcclxufSBlbHNlIHtcclxuICBlY2hvICcnO1xyXG59In0=/!HannaCode
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)