dgifford / tag
Utility class for creating HTML tags.
Requires
- php: >=5.5
- dgifford/hooks-trait: 0.*
README
Introduction
This class provides a framework for generating and manipulating HTML elements. It can be used where a single HTML tag needs to be generated, or to generated multiple nested elements.
Basic Usage
$div = new Tag('div');
$div->render(); // outputs <div></div>
Attributes and content can also be defined in the constructor:
$div = new Tag('div', ['class' => 'my_class', 'id' => 'my_id'], 'Here is some content');
$div->render(); // outputs <div class="my_class" id="my_id">Here is some content</div>
Or set/ changed after the object is instantiated with the set
method:
$div = new Tag;
$div->set('div', ['class' => 'my_class', 'id' => 'my_id'], 'Here is some content');
$div->render(); // outputs <div class="my_class" id="my_id">Here is some content</div>
Or set by the setAttribute
and setContent
methods:
$div = new Tag;
$div->setAttribute( ['class' => 'my_class', 'id' => 'my_id'] );
$div->setContent( 'Here is some content' );
$div->render(); // outputs <div class="my_class" id="my_id">Here is some content</div>
The content of a tag can be simple text, a HTML string, another Tag object or multiple arguments to create a nested Tag.
Text content is escaped, unless an additional boolean false parameter is passed when setting the content:
$div = new Tag;
$div->setAttribute( ['class' => 'my_class', 'id' => 'my_id'] );
$div->setContent( 'some <strong>content</strong>' );
$div->render(); // outputs <div>some <strong>content</strong></div>
$div->setContent( 'some <strong>content</strong>', false );
$div->render(); // outputs <div>some <strong>content</strong></div>
$div = new Tag( 'div' );
$div->setContent( 'div', ['class' => 'inner'], 'some content' );
$div->render(); // outputs <div><div class="inner">some content</div></div>
$div = new Tag( 'div' );
$inner = new Tag( 'div', ['class' => 'inner'], 'some content' );
$div->setContent( $inner );
$div->render(); // outputs <div><div class="inner">some content</div></div>
Multiple content items can be added using a multi-dimensional array:
$div = new Tag( 'div' );
$inner = new Tag( 'div', ['class' => 'inner'], 'some content' );
$div->setContent([
[$inner],
['<div>More content</div>', false],
[ 'div', 'even more content' ],
]);
$div->render(); // outputs <div><div class="inner">some content</div><div>More content</div><div>even more content</div></div>
Modifying Content
Content can be appended, prepended and inserted into an existing Tag:
$tag = new Tag( 'div', 'my content' );
$tag->append( 'div', 'appended content' );
$tag->render(); // outputs <div>my content<div>appended content</div></div>
$tag->prepend( 'div', 'prepended content' );
$div->render(); // outputs <div><div>prepended content</div>my content<div>appended content</div></div>
The insert
method requires the index number (zero-indexed) of an existing content item to insert before:
$tag = new Tag( 'div', 'my content' );
$tag->append( 'div', 'appended content' );
$tag->insert( 1, ['div', 'inserted content'] );
$tag->render(); // outputs <div>my content<div>inserted content</div><div>appended content</div></div>
Using an index of 0 is the equivalent of the prepend
method.
Nested Structures
Nested HTML can be generated at instantiation:
$tag = new Tag('div', [], [
['Level 1'],
new Tag('div', [], [
['Level 2'],
new Tag('div', 'Level 3'),
['Level 2'],
]),
['Level 1'],
]);
$tag->render();
/*
Outputs:
<div>
Level 1
<div>
Level 2
<div>Level 3</div>
Level 2
</div>
Level 1
</div>
*/
Note that the attributes array must be included in the constructor (even if empty) when using an array to add multiple content items.
When a Tag object has been constructed with Tag objects as content, the find
and filter
methods can be used to target the nested tags.
The find
method accepts a Tag name and array of attributes. It works recursively and returns an array of all Tag objects that match the provided parameters.
The filter
method accepts similar parameters and applies them to subsequent actions until cleared.
$tag = new Tag('section', [], [
new Tag('div', ['class' => 'wrapper' ], [
new Tag('span', 'Some content'),
new Tag('span', 'Some more content'),
]),
]);
$tag->render(); // Outputs <section><div class="wrapper"><span>Some content</span><span>Some more content</span></div></section>
foreach( $tag->find( '', ['class' => 'wrapper'] ) as $obj )
{
$obj->setAttribute( 'id', 'my_id' );
}
$tag->render(); // Outputs <section><div class="wrapper" id="my_id"><span>Some content</span><span>Some more content</span></div></section>
$tag->filter( 'span' );
$tag->setContent( 'Foo bar' );
$tag->render(); // Outputs <section><div class="wrapper" id="my_id"><span>Foo bar</span><span>Foo bar</span></div></section>
$tag->clear();
$tag->render(); // Filter still applied, so outputs <section><div class="wrapper" id="my_id"><span></span><span></span></div></section>
$tag->clearFilters();
$tag->clear();
$tag->render(); // Outputs <section></section>