wongyip/html-tags

HTML 标签渲染器

v1.7.9 2024-09-12 07:10 UTC

README

一个简单的具有流畅界面的 HTML 渲染器,用于生成动态组件。生成的标签会自动渲染,因此不需要在模板中构建额外的逻辑来处理它们,这有助于减少模板的复杂性,并且使某些组件与模板引擎独立。

首先阅读此内容

此包完全不关心安全性,如果您的应用程序从动态数据生成 HTML,特别是用户贡献的内容,请务必小心,以避免诸如 XSS 攻击等问题。您应始终使用自己的 HTML 过滤工具,例如 HTML Purifier

世界很危险,始终对生成的 HTML 进行清理。

安装

composer require wongyip/html-tags

使用方法

基本

$div = new Tag('div');
$div->id('some-css-class')
$div->style('font-size: 2em;')
$div->contents('Example <div> tag with class & style attributes.');
echo $div->render();
<div id="some-css-class" style="font-size: 2em;">Example &lt;div&gt; tag with class &amp; style attributes.</div>

上面的输出没有使用语法高亮来正确显示由 htmlspecialchars 函数转义的代码。

各种编码风格

标签可以以不同的方式渲染,以适应不同的场景。

// Spell out everything if you care about who read your code.
$a1 = Anchor::tag()->href('/go/1')->target('_blank')->contents('Go 1');

// When working with structural data like a data model.
$a2 = Anchor::tag('Go 2')->attributes(['href' => '/go/2', 'target' => '_blank']);

// Code a little less with tailor-made creator-function.
$a3 = Anchor::create('/go/3', 'Go 3', '_blank');

echo implode(PHP_EOL, [$a1->render(), $a2->render(), $a3->render()]);
<a href="/go/1" target="_blank">Go 1</a>
<a href="/go/2" target="_blank">Go 2</a>
<a href="/go/3" target="_blank">Go 3</a>

嵌套

$tag = Tag::make('div')->class('parent')->contents(
    Tag::make('p')->id('child1')->contents('Regular'),
    Tag::make('p')->id('child2')->contents(
        Tag::make('span')->contents(
            Tag::make('strong')->contents('Bold Face')
        )
    )
);
echo $tag->render();
<div class="parent"><p id="child1">Regular</p><p id="child2"><span><strong>Bold Face</strong></span></p></div>

内容集合

扩展 TagAbstract 的标签将具有几个 ContentsCollection 属性,这些属性在实例化时为空,并在公共范围内可访问。您可以使用它们来操作标签的所有内容。

  • TagAbstract::$siblingsBefore - 在标签嵌套级别相同的兄弟标签,在标签之前渲染。
  • TagAbstract::$contentsPrefixed - 标签上的内部内容。
  • TagAbstract::$contents - 标签的内部内容。
  • TagAbstract::$contentsSuffixed - 标签底部的内部内容。
  • TagAbstract::$siblingsAfter - 在标签嵌套级别相同的兄弟标签,在标签之后渲染。

可扩展内容

对于具有条件内部内容的标签场景,您可以扩展以下方法来处理需求

  • TagAbstract::contentsBefore(),输出一个用于在标签内容之前渲染的 ContentsCollection
  • TagAbstract::contentsAfter(),输出一个用于在标签内容之后渲染的 ContentsCollection

例如,内置的 Table 标签扩展了 contentsBefore() 方法,以在设置时插入其 captiontheadtbody

内容结构,总结

  • 标签之前的兄弟标签
    • 前缀内容
    • 可扩展内容(之前)
    • 内容
    • 可扩展内容(之后)
    • 后缀内容
  • 标签之后的兄弟标签

以下示例说明了上述结构,除了可扩展内容(之前和之后)之外

$tag = Tag::make('div');
$tag->contents->append(Tag::make('p')->contents('Content 1'), Tag::make('p')->contents('Content N'));
$tag->contentsPrefixed->append(Tag::make('h1')->contents('Prefixed 1'), Tag::make('h2')->contents('Prefixed N'));
$tag->contentsSuffixed->append(Tag::make('h3')->contents('Suffixed 1'), Tag::make('h4')->contents('Suffixed N'));
$tag->siblingsBefore->append(Tag::make('div')->contents('Sibling Before 1'));
$tag->siblingsBefore->append(Tag::make('div')->contents('Sibling Before N'));
$tag->siblingsAfter->append(Tag::make('div')->contents('Sibling After 1'));
$tag->siblingsAfter->append(Tag::make('div')->contents('Sibling After N'));
echo $tag->render();
<div>Sibling Before 1</div>
<div>Sibling Before N</div>
<div>
    <h1>Prefixed 1</h1>
    <h2>Prefixed N</h2>
    <p>Content 1</p>
    <p>Content N</p>
    <h3>Suffixed 1</h3>
    <h4>Suffixed N</h4>
</div>
<div>Sibling After 1</div>
<div>Sibling After N</div>

注释

echo Comment::make()
    ->contents('Comment ignores attributes set.')
    ->class('ignored')
    ->contentsAppend(Tag::make('div')->contents('Nested tag is fine.'))
    ->contentsAppend(Comment::make()->contents('Nested comment ending brace is escaped.'))
    ->render();
<!-- Comment ignores attributes set.<div>Nested tag is fine.</div><!-- Nested comment ending brace is escaped. --&gt; -->

上面的输出没有使用语法高亮来正确显示由 htmlspecialchars 函数转义的代码。

更多示例

  • 有关更多示例,请参阅 Demo::class
  • 在 CLI 中运行 php demo/demo.php 以进行演示。

限制

  1. 这 NOT 是一个渲染引擎。
  2. <script> 标签不受支持,显然是因为安全考虑。
  3. <style> 标签也不受支持,因为 htmlspecialchars() 可能无意中破坏样式。
  4. <!doctype> 标签也不受支持。
  5. 尚未解决 Web 内容可访问性问题。
  6. 标签将渲染成一行,如果需要格式化的 HTML,请尝试 HTML Beautify

始终对生成的HTML进行清理。