The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Valiant::HTML::Util::TagBuilder - Utility class to generate HTML tags

SYNOPSIS

    use Valiant::HTML::Util::TagBuilder;
    my $tag_builder = Valiant::HTML::Util::TagBuilder->new(view => $view);
    my $tag = $tag_builder->tag('div', { class => 'container' });

DESCRIPTION

Valiant::HTML::Util::TagBuilder is a utility class for generating HTML tags. It wraps a view or template object which must provide methods for html escaping and for marking strings as safe for display.

ATTRIBUTES

This class has the following initialization attributes

view

Object, Required. This should be an object that provides methods for creating escaped strings for HTML display. Many template systems provide a way to mark strings as safe for display, such as Mojo::Template. You will need to add the following proxy methods to your view / template to adapt it for use in creating safe strings that work in the way it expects. If you're view doesn't need this you can just use Valiant::HTML::Util::View.

raw

given a string return a single tagged object which is marked as safe for display. Do not do any HTML escaping on the string. This is used when you want to pass strings straight to display and that you know is safe. Be careful with this to avoid HTML injection attacks.

safe

given a string return a single tagged object which is marked as safe for display. First HTML escape the string as safe unless its already been done (no double escaping).

safe_concat

Same as safe but instead works an an array of strings (or mix of strings and safe string objects) and concatenates them all into one big safe marked string.

html_escape

Given a string return string that has been HTML escaped.

read_attribute

Given an attribute name return the value that the view has defined for it.

attribute_exists

Given an attribute name return true if the view has defined a value for it.

Both raw, safe and safe_concat should return a 'tagged' object which is specific to your view or template system. However this object must 'stringify' to the safe version of the string to be displayed. See Valiant::HTML::SafeString for example API. We use Valiant::HTML::SafeString internally to provide safe escaping if you're view doesn't do automatic escaping, as many older template systems like Template Toolkit.

METHODS

new

Create a new instance of the TagBuilder.

  my $tag_builder = Valiant::HTML::Util::TagBuilder->new(view => $view);

tags

Returns a reference to a blessed hash that provides shortcut methods for all HTML tags.

  my $tags = $tag_builder->tags;
  my $img_tag = $tags->img({src => '/path/to/image.jpg'});
  # <img src="/path/to/image.jpg" />
  
  my $div_tag = $tags->div({id=>'top}, "Content");
  # <div id="top">Content<div>

tag

Generates a HTML tag of the specified type and with the specified attributes.

content_tag

Generates a HTML content tag of the specified type, with the specified attributes, and with the specified content.

    my $tag = $tag_builder->content_tag('p', { class => 'lead' }, 'Lorem ipsum dolor sit amet');

The content can also be generated by a code block, as shown in the following example.

    my $tag = $tag_builder->content_tag('ul', { class => 'list-group' }, sub {
      $tag_builder->content_tag('li', 'Item 1') .
      $tag_builder->content_tag('li', 'Item 2') .
      $tag_builder->content_tag('li', 'Item 3')
    });

join_tags

Joins multiple tags together and returns them as a single string.

    my $tags = $tag_builder->join_tags(
      $tag_builder->tag('div', { class => 'container' }),
      $tag_builder->content_tag('p', 'Lorem ipsum dolor sit amet')
    );

text

Generates a safe string of text.

   my $text = $tag_builder->text('Lorem ipsum dolor sit amet');

Helper method to generate a link tag.

  my $link = $tag_builder->link_to($url, \%attrs, $content);

$url is the URL to link to and is required. Both %attrs and c<$content> are optional. If $content is not provided, the link text will be the URL.

to_string

Returns the generated HTML tag as a string.

    my $tag = $tag_builder->tag('div', { class => 'container' });
    my $tag_string = $tag->to_string;

PROXY METHODS

The following methods are proxied from the enclosed view object. You should refer to your view for more.

safe

raw

escape_html

safe_concat

LOGIC AND FLOW CONTROL

Valiant::HTML::Util::TagBuilder builds in some basic logic and control flow to make it easier to use in small places where a full on template system would be too much but you don't want ugly string concatenation. This system works by adding a handful of custom html attributes to your tag declarations. These custom tags are removed from the final output.

omit

    my $t = $tag_builder->tags;
    say $t->hr({omit=>1}) +
      $t->div({omit=>1}, 'Hello World!');

If the value is true the tag is removed from the final output. However any content is preserved.

Value can be a scalar which will be evaluated as a boolean, or a coderef which will be called and passed the current $view as an argument).

    say $t->hr({omit => sub ($view) { 1 }}); # is empty
    my $bool = 1;
    say $t->div({id=>'one', if=>$bool}, sub {
      my ($view) = @_;
      $t->p('hello');
    }): # '<div id="one"><p>hello</p></div>';

    $bool = 0;
    say $t->div({id=>'one', if=>$bool}, sub {
      my ($view) = @_;
      $t->p('hello');
    }): # '';

If the processed value of the tag is false, the tag and any of its contents are removed from the output. Value can be a scalar value or a coderef (which gets the $view as its one argument).

Create content with a new local context.

    say $t->div({id=>'one', with=>'two'}, sub {
      my ($view, $var) = @_;
      $t->p($var);
    }); # '<div id="one"><p>two</p></div>';

Useful if you need a local value in your template

repeat

map

Used to loop over a tags contents (for content tags) or the tag itself (for both content and empty tags). Examples:

    say $t->div({id=>'one', repeat=>[1,2,3]}, sub {
      my ($view, $item, $idx) = @_;
      $t->p("hello[$idx] $item");
    }); # '<div id="one"><p>hello[0] 1</p><p>hello[1] 2</p><p>hello[2] 3</p></div>';

    say $t->div({id=>sub {"one_${_}"}, map=>[1,2,3]}, sub {
      my ($view) = @_;
      $t->p('hello');
    }); # '<div id="one_1"><p>hello</p></div><div id="one_2"><p>hello</p></div><div id="one_3"><p>hello</p></div>';

Values for the looping attributes can be an arrayref, an object that does '->next' (for example a DBIx::Class resultset) or a coderef that receives the current view object and returns either of the above.

If your object also does reset that method will be called automatically after the last loop item.

In the case of map if you want to modify the attributes of the enclosing tag you can use coderefs for those attributes. They will be called with the current view object and current loop item value and index. When also localize $_ to be to the current loop item value for ease of use.

    say $t->hr({ id => sub { my ($view, $val, $i) = @_; "rule_${val}" }, map => [1,2,3] });

returns

    <hr id='rule_2' /><hr id='rule_2' /><hr id='rule_3' />

and this does the same:

    say $t->hr({ id => sub { "rule_${_}" }, map =>[1,2,3] });

given / when

Given / When 'switchlike' conditional. Example:

    say $t->div({id=>'one', given=>'one'}, sub {
      my ($view) = @_;
      $t->p({when=>'one'}, "hello one"),
      $t->p({when=>'two'}, "hello two"),
      $t->hr({when=>'three'}),
      $t->p({when_default=>1}, "hello four")
    }); # '<div id="one"><p>hello one</p></div>';

When a content tag has the given attribute, its content must be a coderef which will get the current $view as its one argument. Inside the coderef we will render a tag with a matching when attribute or if there are no matches a tag with the when_default attribute.

The value of given= may be a scalar or a coderef. If its a coderef we will call it with the current view object and expect a scalar.

AUTHOR

See Valiant

SEE ALSO

Valiant, Valiant::HTML::FormBuilder

AUTHOR

See Valiant

COPYRIGHT & LICENSE

See Valiant

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 534:

Unknown directive: =head

Around line 552:

Unknown directive: =head