NAME
HTML::Inject - inject content from one HTML file into another
SYNOPSIS
use HTML::Inject;
my $template = HTML::Inject::->new(dom => <<'TARGET');
© 2012 Acme Inc
TARGET
my $result = $template->inject(<<'SOURCE');
Hello World
A greeting to the planet!
SOURCE
print $result->toString;
#
#
#
# Hello World
#
#
# A greeting to the planet!
# © 2012 Acme Inc
#
#
DESCRIPTION
`HTML::Inject` is a "template system lite". It allows you to inject
content from one HTML file (the "source") into another HTML file (the
"target") that has placeholders for that content.
Constructor
`new(%attr)`
Moose-style constructor, accepting a hash of attributes. (Actually
this package uses Moo.)
Attributes
`target`
The target HTML to inject. May be provided as an XML::LibXML::Document
object, a file handle, a URL, a filename or a plain string of HTML.
(To disambiguate between a string of HTML, and a filename/URL which is
also a string, strings of HTML must contain at least one line break
character!!) Whatever is provided, it will be coerced into an
XML::LibXML::Document.
`head_element_test`
A coderef which takes an XML::LibXML::Element object and returns a
boolean. The default is probably fairly sane, matching all ``,
`<link>`, `<meta>` and `<style>` elements.
See "Injection Technique" for an explanation of the head element test.
`body_element_test`
A coderef which takes an XML::LibXML::Element object and returns a
boolean. The default is probably fairly sane, matching all `<script>`
and `<map>` elements.
See "Injection Technique" for an explanation of the body element test.
`missing_nodes`
An arrayref of XML::LibXML::Node objects. You should probably not set
this attribute in the constructor, or indeed at all. It's intended as
a place for HTML::Inject to pass back problem nodes to the caller.
Methods
`inject($source)`
Injects content from the source into the target returning an
XML::LibXML::Document as the result. The result is generated by deep
cloning the target, thus the same target can be reused again and again
with different source data.
Like the target passed to the constructor, the source data can be
provided as an XML::LibXML::Document object, a file handle, a URL, a
filename or a plain string of HTML. It may also be an arrayref of any
of the above.
See "Injection Technique" for more details.
`inject_and_new($source)`
As per `inject`, but returns the result as a new HTML::Inject target.
That is, this:
my $template2 = $template->inject_and_new($content);
is equivlent to:
my $template2 = HTML::Inject::->new(
$template->inject($content),
);
This is vaguely useful for some chanined operations.
Injection Technique
Before beginning the injection, the `missing_nodes` list is cleared.
As a first step, HTML::Inject finds a list of potentially injectable nodes
in the source document. Potentially injectable things are any nodes which
are direct children of the HTML `<head>` and `<body>` elements.
It then loops through the potentially injectable nodes.
For elements which have an @id attribute, the injection technique is to
find the element with the corresponding @id in the target document, and
then clone the source element's contents and attributes onto the target
element. If the target element already has contents, these will not be
removed, and the new content is added after the existing content.
Nodes without an @id attribute are handled differently: they are added to
the *end* of the target document's HTML `<head>` or `<body>` element, but
only if the element passes the `head_element_test` or `body_element_test`.
(Elements which pass both tests will be added to the `<head>`.) This
allows certain elements from the source document like `<meta>`, `<title>`
and `<script>` to be injected to the target document without having to
worry too much about exactly where they're injected. They won't be
injected in any especially predictable order.
Any potentially injectable nodes which have not been injected will be
pushed onto the `missing_nodes` list. You may wish to loop through this
list yourself, adding them to the result document using some sort of logic
of your choice.
HTML Parsing
HTML parsing is via HTML::HTML5::Parser which supports some nicely
idiomatic HTML. The example in the "SYNOPSIS" could have used:
my $result = $template->inject(<<'SOURCE');
<title>Hello World
A greeting to the planet!
SOURCE
That is, for the source content, you only really need to include the
actual elements that you wish to inject. You can ignore the "skeletal
parts" of the HTML.
HTML Output
The result of `inject` is an XML::LibXML::Document element. This can be
stringified using its `toString` method. See XML::LibXML::Node for
details.
If serving the output as `text/html`, then you may be better off
stringifying it using HTML::HTML5::Writer which makes special effort to
stringify documents in a way browsers can actually cope with.
If you want your HTML nicely indented, try XML::LibXML::PrettyPrint.
(Indenting is nice when you're debugging, but you may wish to switch it
off for deployment, as it imposes a performance penalty.)
BUGS
Please report any bugs to
.
SEE ALSO
Cindy, Apache2::Layout, Template::Semantic.
AUTHOR
Toby Inkster .
COPYRIGHT AND LICENCE
This software is copyright (c) 2012 by Toby Inkster.
This is free software; you can redistribute it and/or modify it under the
same terms as the Perl 5 programming language system itself.
DISCLAIMER OF WARRANTIES
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.