NAME

HTML::Composer - Compose validated HTML from Perl data structures

SYNOPSIS

HTML::Composer is inspired by TyXML and Hiccup to provide a data-driven HTML builder for Perl that allows developers to compose data to validated HTML in an efficient, intuitive, high-performance way.

use HTML::Composer;

my $h = HTML::Composer->new();
my $html = $h->html([
        head => [
            title  => ["My Site"],
            script => {
                src  => "/js/myScript.js",
                type => "text/javascript"
            }
        ],
        body => [
            h1  => ["Hello World!"],
            br  => {},
            div => { class => [ "p-3", "background-red" ] } => [
                "Hello World!", h2 => ["Test 123"]
            ]
        ]
    ]
);

This will output the following HTML:

<!DOCTYPE html>
<html>
  <head>
    <title>My Site</title>
    <script src="/js/myScript.js" type="text/javascript"></script>
  </head>
  <body>
    <h1>Hello World</h1>
    <br>
    <div class="p-3 background-red">
      Hello World!
      <h2>Test 123</h2>
    </div>
  </body>
</html>

HTML elements that allow children are created like:

[div => ["Text!", h1 => ["Text!"]]] # <div>Text!<h1>Text!</h1></div>

To provide attributes to a tag:

[div => { class => ["p-3", "m-2"] } => ["Text!", h1 => ["Text!"]]] # <div class="p-3 m-2">Text!<h1>Text!</h1></div>

If a tag doesn't have any children, ie a <link> tag:

[link => { href => "www.google.com" }] # <link href="www.google.com">

If a tag doesn't have any attributes:

[br => {}] # <br>

To render just text, make sure it isn't followed up by an array, or hash:

["Text!"]

new(%ARGS)

Create a new instance of HTML::Composer. Optionally, pass a cache argument, to tell HTML::Hash to cache the result against the hash you pass. (Caching defaults to true).

my $h = HTML::Composer->new(); # Cached instance of HTML::Composer
$h->html(...);

my $hc = HTML::Composer->new(cache => 0); # Don't cache templates
$hc->html(...);

html(ARRAY)

Create a string containing the HTML described in ARRAY. Croaks if HTML validation fails.

my $h = HTML::Composer->new();
my $html = $h->html([
        head => [
            title  => ["My Site"],
            script => {
                src  => "/js/myScript.js",
                type => "text/javascript"
            }
        ],
        body => [
            h1  => ["Hello World!"],
            br  => {},
            div => { class => [ "p-3", "background-red" ] } => [
                "Hello World!", h2 => ["Test 123"]
            ]
        ]
    ]
);

If you need to pass attributes to the root <html> tag you can do so with:

my $h = HTML::Composer->new();
my $html = $h->html({lang => 'en'} => [
        head => [
            title  => ["My Site"],
            script => {
                src  => "/js/myScript.js",
                type => "text/javascript"
            }
        ],
        body => [
            h1  => ["Hello World!"],
            br  => {},
            div => { class => [ "p-3", "background-red" ] } => [
                "Hello World!", h2 => ["Test 123"]
            ]
        ]
    ]
);

unsafe(SCALAR)

Create an instance of HTML::Composer::Unsafe, these objects encapsulate the value you provide, and are not escaped by HTML::Composer when the HTML is rendered.

use HTML::Composer;

my $h = HTML::Composer->new;
my $unsafe_text = $h->unsafe(q[document.body.addEventListener('htmx:configRequest', (event) => {})]);

ref($unsafe_text) # HTML::Composer::Unsafe

my $html = $h->html([
  head => [
    title => ["My Site!"],
    script => [$unsafe_text]
  ],
  body => [
    div => [
      "Hello World!"
    ]
  ]
]);