yetii/html-element

根据图示生成HTML(元素)

1.1.3 2019-07-16 23:54 UTC

This package is auto-updated.

Last update: 2024-09-19 10:39:53 UTC


README

提供生成HTML的更健壮的替代方案

要求

  • PHP >= 7.2

使用方法

使用方法相当简单。首先,在 YeTii\HtmlElement\Elements 命名空间下有不同类型的 Element,例如一个 <div> 元素是 YeTii\HtmlElement\Elements\HtmlDiv,一个 <input> 元素是 YeTii\HtmlElement\Elements\HtmlInput,等等。这是除 YeTii\HtmlElement\TextNode 之外的情况。下面是类别的完整列表。

基本使用

Element 的第一个参数是一个属性数组(键 => 值)。

第二个参数是一个可选参数(目前未实际使用),用于覆盖默认名称。默认名称是小写的类名,移除了 Html 前缀,例如 HtmlInput 使用 input 名称渲染。此参数可能在未来的版本中删除,其目的是支持类似Vue的组件名称。或者,您可以使用 $element->setName($name); 来设置名称(并使用 $element->getName(); 来检索它)

$element = new HtmlInput([
    'type' => 'date',
    'id' => 'dob_field',
    'name' => 'dob',
]);

$element->render(); // <input type="date" id="dob_field" name="dob">

// Or try a custom element name (if generating Vue, for example)
$element->setName('dob-picker');

$element->render(); // <dob-picker type="date" id="dob_field" name="dob">

子元素

您可以通过提供 nodenodes "属性" 来指定子元素,这是一个添加子节点或多个子节点节点的快捷方式。或者,您可以选择:$parent->addChild(Element $child);$parent->addChildren(array $children);

$child1 = new HtmlSpan([
    'class' => 'test',
    'nodes' => [
        new HtmlSpan([
            'class' => 'span-here',
            'node' => 'what?',
        ]),
        new HtmlBold([
            'title' => 'This is bold',
            'node' => 'Just text here'
        ])
    ]
]);

$child2 = new HtmlSpan([
    'class' => 'test-node',
    'nodes' => [
        new HtmlSpan([
            'class' => 'a-class',
            'node' => 'who?',
        ])
    ]
]);
$child2->addChild(new HtmlBold([
    'title' => 'Bold text',
    'node' => 'Stuff here'
]));

$div = new HtmlDiv([
    'id' => 'section',
    'class' => 'class-name',
]);
$div->addChildren([
    $child1,
    $child2
]);

文本节点

如果您提供字符串作为子元素,它将自动转换为文本节点元素。

文本节点 Element 只能具有文本子元素,这些子元素在渲染时连接在一起。您可以手动指定一个 TextNode 实例

$text = new \Html\HtmlElement\TextNode([
    'node' => 'This is some text',
]);

$text->render(); // This is some text

$div = new HtmlDiv([
    'node' => $text
]);

$div->render(); // <div>This is some text</div>

$div = new HtmlDiv([
    'node' => 'So is this'
]);

$div->render(); // <div>So is this</div>

注意事项

您指定的属性顺序与它们渲染的顺序相关。

$div = new HtmlDiv([
    'id' => 'a',
    'title' => 'b',
    'class' => 'c',
    'data-id' => 'd',
]);

$div->render(); // <div id="a" title="b" class="c" data-id="d"></div>

$div = new HtmlDiv([
    'title' => 'b',
    'data-id' => 'd',
    'class' => 'c',
    'id' => 'a',
]);

$div->render(); // <div title="b" data-id="d" class="c" id="a"></div>

htmlspecialchars

您还可以指定是否要编码HTML特殊字符,如下所示

$div = new HtmlDiv([
    'node' => '<b>Text</b>',
]);
$div->escapeHtml();

$div->render(); // <div>&lt;b&gt;Text&lt;/b&gt;</div>

目前,继承不适用于HTML转义,这意味着如果父 Element 转义HTML,并且您提供了一个子 Element,并且该子 Element 有一个包含HTML的文本节点,它将不会转义。您必须针对每个 Element 定义是否转义HTML。以下是一个示例

$child = new HtmlSpan([
    'node' => '<i>Some text</i>',
]);
$parent = new HtmlDiv([
    'nodes' => [
        '<b>Some text</b>',
        $child
    ]
]);
$parent->escapeHtml();

$parent->render(); // <div>&lt;b&gt;Text&lt;/b&gt;<i>Some text</i></div>

直接子节点的文本节点会被转义,但 $child 不会继承这一点,因此它不会在文本节点中转义HTML。

如果您希望子 Element 不转义HTML,但希望直接父元素转义,您可以通过以下方式实现

$child1 = new HtmlSpan([
    'node' => '<i>Some text</i>',
]);
$child1->escapeHtml(false);
$child2 = new HtmlSpan([
    'node' => '<i>Some text</i>',
]);
$parent = new HtmlDiv([
    'nodes' => [
        '<b>Some text</b>',
        $child2,
    ]
]);
$parent->escapeHtml(true);

$parent->render(); // <div>&lt;b&gt;Text&lt;/b&gt;<i>Some text</i></div>

Element类完整列表

  • <a>: HtmlA
  • <abbr>: HtmlAbbr
  • <address>: HtmlAddress
  • <area>: HtmlArea
  • <article>: HtmlArticle
  • <aside>: HtmlAside
  • <audio>: HtmlAudio
  • <b>: HtmlB
  • <bdi>: HtmlBdi
  • <bdo>: HtmlBdo
  • <blockquote>: HtmlBlockquote
  • <body>: HtmlBody
  • <br>: HtmlBr
  • <button>: HtmlButton
  • <canvas>: HtmlCanvas
  • <caption>: HtmlCaption
  • <cite>: HtmlCite
  • <code>: HtmlCode
  • <col>: HtmlCol
  • <colgroup>: HtmlColgroup
  • <command>: HtmlCommand
  • <datalist>: HtmlDatalist
  • <dd>: HtmlDd
  • <del>: HtmlDel
  • <details>: HtmlDetails
  • <dfn>: HtmlDfn
  • <div>: HtmlDiv
  • <dl>: HtmlDl
  • <dt>: HtmlDt
  • <em>: HtmlEm
  • <embed>: HtmlEmbed
  • <fieldset>: HtmlFieldset
  • <figcaption>: HtmlFigcaption
  • <figure>: HtmlFigure
  • <footer>: HtmlFooter
  • <form>: HtmlForm
  • <h1>: HtmlH1
  • <h2>: HtmlH2
  • <h3>: HtmlH3
  • <h4>: HtmlH4
  • <h5>: HtmlH5
  • <h6>: HtmlH6
  • <head>: HtmlHead
  • <header>: HtmlHeader
  • <hr>: HtmlHr
  • <html>: HtmlHtml
  • <i>: HtmlI
  • <iframe>: HtmlIframe
  • <img>: HtmlImg
  • <input>: HtmlInput
  • <ins>: HtmlIns
  • <kbd>: HtmlKbd
  • <keygen>: HtmlKeygen
  • <label>: HtmlLabel
  • <legend>: HtmlLegend
  • <li>: HtmlLi
  • <main>: HtmlMain
  • <map>: HtmlMap
  • <mark>: HtmlMark
  • <menu>: HtmlMenu
  • <meter>: HtmlMeter
  • <nav>: HtmlNav
  • <object>: HtmlObject
  • <ol>: HtmlOl
  • <optgroup>: HtmlOptgroup
  • <option>: HtmlOption
  • <output>: HtmlOutput
  • <p>: HtmlP
  • <param>: HtmlParam
  • <pre>: HtmlPre
  • <progress>: HtmlProgress
  • <q>: HtmlQ
  • <rp>: HtmlRp
  • <rt>: HtmlRt
  • <ruby>: HtmlRuby
  • <s>: HtmlS
  • <samp>: HtmlSamp
  • <section>: HtmlSection
  • <select>: HtmlSelect
  • <small>: HtmlSmall
  • <source>: HtmlSource
  • <span>: HtmlSpan
  • <strong>: HtmlStrong
  • <sub>: HtmlSub
  • <summary>: HtmlSummary
  • <sup>: HtmlSup
  • <table>: HtmlTable
  • <tbody>: HtmlTbody
  • <td>: HtmlTd
  • <textarea>: HtmlTextarea
  • <tfoot>: HtmlTfoot
  • <th>: HtmlTh
  • <thead>: HtmlThead
  • <time>: HtmlTime
  • <tr>: HtmlTr
  • <track>: HtmlTrack
  • <u>: HtmlU
  • <ul>: HtmlUl
  • <var>: HtmlVar
  • <video>: HtmlVideo
  • <wbr>: HtmlWbr

接口

这些接口改变了元素渲染的方式。

  • YeTii\HtmlElement\Interfaces\HasTextChild 将带有子元素的元素渲染为纯文本(例如 <textarea>此处为文本子元素</textarea>
  • YeTii\HtmlElement\Interfaces\IsSingleton 将没有结束标签的元素渲染(例如 <input />
  • YeTii\HtmlElement\Interfaces\IsTextNode 将元素渲染为文本节点(即原始文本或经过htmlspecialchar处理的文本)

自定义元素

您可能想要创建一些自定义元素,特别是当生成类似vue组件模板的内容时。使用上述接口,并扩展基本的 Element 类,这将变得非常简单。假设您想要一个单例元素,如 <dob-picker type="date" {customAttributesHere} />

<?php

namespace YeTii\VueGenerator\Component;

use YeTii\HtmlElement\Element;
use YeTii\HtmlElement\Interfaces\IsSingleton;

class DobPicker extends Element implements IsSingleton
{

    protected $name = 'dob-picker';

    protected $attributes = [
        'type' => 'date', // all <dob-pickers> should have this
    ];

}