yetii / html-element
根据图示生成HTML(元素)
Requires
- php: ^7.2
Requires (Dev)
- phpunit/phpunit: ^8.2.4
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">
子元素
您可以通过提供 node
或 nodes
"属性" 来指定子元素,这是一个添加子节点或多个子节点节点的快捷方式。或者,您可以选择:$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><b>Text</b></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><b>Text</b><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><b>Text</b><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 ]; }