Text::...ompiler(3pm)

πŸ“¦
version 2.05 Β· 3 versions
, in ubuntu stonking

πŸ’– Text::Hogan::Compiler β€” a.k.a. Text::...ompiler(3pm) πŸ’–

okay bestie, sit down, hydrate, because we're about to talk about the manual page for Text::Hogan::Compiler, a Perl user-contributed doc situation, and it's genuinely so good. ✨


🌸 NAME 🌸

Text::Hogan::Compiler</p> β€” she parses templates and spits out Perl code. That's it, that's the whole job. No cap. πŸ’…


πŸŽ€ VERSION πŸŽ€

version 2.05 β€” yes she's on 2.05, we love an updated queen. πŸ‘‘


✨ SYNOPSIS ✨

here's the whole vibe in one go, look at her go:

use Text::Hogan::Compiler;

my $compiler = Text::Hogan::Compiler->new;

my $text = "Hello, {{name}}!";

my $tokens   = $compiler->scan($text);
my $tree     = $compiler->parse($tokens, $text);
my $template = $compiler->generate($tree, $text);

say $template->render({ name => "Alex" });

literally the pipeline: scan β†’ parse β†’ generate β†’ render. four steps, one slay. πŸ”₯


πŸ¦‹ METHODS πŸ¦‹

🌈 new

takes absolutely nothing. gives you back a Compiler object. low maintenance, iconic.

my $compiler = Text::Hogan::Compiler->new;

🌈 scan

you hand her some template text, she hands you back an arrayref β€” a whole list of tokens. 🧚

my $tokens = $compiler->scan("Hello, {{name}}!");

she can also take a hashref of options, if you're feeling extra:

  • delimiters β€” a string representing different delimiters, split by white-space. ngl you should never need to pass this directly; it's used to implement the in-template delimiter-switching functionality. so like, it's a backstage thing. πŸ™ˆ
# equivalent to the above call with mustaches
my $tokens = Text::Hogan::Compiler->new->scan("Hello, <% name %>!", { delimiters => "<% %>" });
  • allow_whitespace_before_hashmark β€” a boolean. if it's true, tags are allowed to have space(s) between the delimiters and the opening sigil ('#', '/', '^', '<', etc.). she's flexible like that. πŸ’…
my $tokens = Text::Hogan::Compiler->new->scan("Hello{{ # foo }}, again{{ / foo }}.", { allow_whitespace_before_hashmark => 1 });

🌈 parse

takes the tokens that scan gave you, plus the original text, and returns a tree structure that's all ready to be turned into Perl code. 🌱

my $tree = $compiler->parse($tokens, $text);

optionally she takes a hashref that can have a key called "section_tags" which should be an arrayref. and honestly? I don't know what it does. probably something internal related to recursive calls that you don't need to worry about. not me being honest on main. 😭

⚠️ heads up bestie: a lot of the error checking on your input happens in this method, and it is pretty much the only place exceptions might be thrown. the exceptions that may be thrown include: "Closing tag without opener", "Missing closing tag", "Nesting error" and "Illegal content in < super tag".

🌈 generate

takes the parsed tree plus the original text, and returns a Text::Hogan::Template object that you can call render on. 🫢

my $template = $compiler->generate($tree, $text);

optionally takes a hashref, and that hashref can have:

  • a key "as_string". if you pass that, then instead of getting a template object back you get some stringified Perl code that you can cache somewhere on disk as part of your build process. build-time girlies rise. πŸ—οΈ
my $perl_code_as_string = $compiler->generate($tree, $text, { 'as_string' => 1 });
  • a key "numeric_string_as_string". if you pass that, output that looks like a number is NOT converted into a number (ie "01234" is NOT converted to "1234"). protect your leading zeros!! πŸ›‘οΈ
my $perl_code_as_string = $compiler->generate($tree, $text, { 'numeric_string_as_string' => 1 });

the options hashref can have other keys too, and those will get passed to Text::Hogan::Template::new among other places. she shares the wealth. πŸ’Έ

🌈 compile

drop a template string in, and she calls scan, parse and generate on it and hands you back the Text::Hogan::Template object. one-stop shop, main character energy.

my $template = $compiler->compile("Hello, {{name}}!");

she also caches templates by a sensible cache key, which is useful if you're not stringifying and storing on disk or in memory anyway. efficiency icon. ⚑

optionally takes a hashref that will be passed on to scan, parse, and generate.

my $perl_code_as_string = $compiler->compile(
    $text,
    {
        delimiters => "<% %>",
        as_string => 1,
        allow_whitespace_before_hashmark => 1,
    },
);

🧚 ENCODING 🧚

as long as you're consistent with your use of encoding in your template variables and your context variables, everything should just work. fr fr. byte strings or character strings, you pick β€” you'll get what you expect. ✨

the only danger would be if you use byte strings of a multi-byte encoding and you happen to get a clash with your delimiters, eg. if your 4 byte kanji character happens to contain the ASCII '<' and '%' characters next to each other. 😬

bestie I have no idea what the likelihood of that is, but hopefully if you're working with non-ASCII character sets you're also using Perl's unicode character strings features. πŸ’œ

also, tea time β˜•: compiling long character string inputs with Text::Hogan used to be extremely slow, but an optimisation added in version 2.00 has made the overhead much more manageable. glow up fr. 🌟


πŸ‘‘ AUTHORS πŸ‘‘

started out statement-for-statement copied from hogan.js by Twitter! (the origin story, we love a remix 🎧)

  • initial translation by Alex Balhatchet (alex@balhatchet.net)
  • further improvements from:
    • Ed Freyfogle
    • Mohammad S Anwar
    • Ricky Morse
    • Jerrad Pierce
    • Tom Hukins
    • Tony Finch
    • Yanick Champoux

and that's the whole page, bestie!! πŸŽ€ this little doc situation came to you from perl v5.40.1, dated 2026-07-31, and it lives under the name Text::...ompiler(3pm) β€” yes the name is literally truncated in the header, she's mysterious like that. πŸ’…βœ¨ mwah, go compile something cute. πŸŒˆπŸ’–

πŸ“¦ where this page comes from