stefanwimmer128 / html-builder
一个完全可扩展的 HTML-Builder,支持 emmet 输入
Requires
- php: ^7.4
- joshtronic/php-loremipsum: ^1.0
- symfony/polyfill-php80: ^1.18
Requires (Dev)
- ext-json: *
- phpunit/phpunit: ^9.4
- symfony/var-dumper: ^5.1
README
一个完全可扩展的 HTML-Builder,支持 emmet 输入
安装
composer require stefanwimmer128/html-builder
示例
use function Stefanwimmer128\HtmlBuilder\render;
use function Stefanwimmer128\HtmlBuilder\h;
use function Stefanwimmer128\HtmlBuilder\capture;
use function Stefanwimmer128\HtmlBuilder\map;
$test = '<p>TEST</p>';
$values = [
'a' => 0,
'b' => 1,
'c' => 2,
];
render(h('xml[version="1.0" standalone=yes]', [], [
h('doctype', 'html', [
h('html[lang=en]', [], [
h('head > title{Hello World!}'),
h('body', [], [
h('.container.container-content#container-content-main', [], [
h('a[href="#"][disabled]', 'LINK'),
'<p>TEST</p>',
capture('printf', '%s', $test)
]),
h('comment', 'COMMENT'),
h('p', ['data-values' => json_encode($values, JSON_THROW_ON_ERROR)], [
h('b', 'LIST:'),
h('br'),
map($values, fn($value, $key) => h('span', ['data-key' => $key], $value))
])
])
])
])
]));
<?xml version="1.0" standalone="yes" ?><!DOCTYPE html><html lang="en"><head><title>Hello World!</title></head><body><div class="container container-content" id="container-content-main"><a href="#" disabled>LINK</a><p>TEST</p><p>TEST</p></div><!-- COMMENT --><p data-values="{"a":0,"b":1,"c":2}"><b>LIST:</b><br /><span data-key="a">0</span><span data-key="b">1</span><span data-key="c">2</span></p></body></html>
特殊元素
以下元素是特殊的。
因此,如果您想将关键字作为简单标签使用,您必须使用特殊的 tag
函数
use function Stefanwimmer128\HtmlBuilder\render;
use function Stefanwimmer128\HtmlBuilder\h;
use function Stefanwimmer128\HtmlBuilder\tag;
render(h('comment', 'Test'));
render(tag('comment', 'Test'));
<!-- Test -->
<comment>Test</comment>
注释
生成 HTML 注释。可以使用任何字符串(或)HtmlElement
(或)作为子元素。
use function Stefanwimmer128\HtmlBuilder\render;
use function Stefanwimmer128\HtmlBuilder\h;
render(h('comment', 'Test'));
<!-- Test -->
文档类型
生成 HTML doctype。可以接收子元素,将在标签后渲染。
use function Stefanwimmer128\HtmlBuilder\render;
use function Stefanwimmer128\HtmlBuilder\h;
render(h('doctype', 'html', ...$children));
<!DOCTYPE html>...children...
lorem
/ lipsum
生成 lorem ipsum 文本(默认:30 个单词)。
要设置要生成的单词数,请将其附加到标签:lorem20
生成 20 个单词,lipsum40
生成 40 个单词。
use function Stefanwimmer128\HtmlBuilder\render;
use function Stefanwimmer128\HtmlBuilder\h;
render(h('lorem50'));
生成 50 个单词的 lorem ipsum。
xml
创建 XML 头部。与 html 标签类似。
use function Stefanwimmer128\HtmlBuilder\render;
use function Stefanwimmer128\HtmlBuilder\h;
render(h('xml[version="1.0"]', [], ...$children));
<?xml version="1.0" ?>...children...
API 文档
h(string $input, ...$args): HtmlElement
使用解析器从输入创建元素(默认:Emmet)tag(string $tag = 'div', ...$args): HtmlTag
创建标签元素text(string $text): HtmlText
创建文本元素raw(string $value): RawString
创建原始字符串capture(callable $callable, ...$args): RawString
捕获输出(echo)并将其作为原始字符串返回map(array $array, callable $callable): array
array_map 带键render(...$elements): string
将元素渲染为 HTML
h(string $input, ...$args): HtmlElement
使用解析器从输入创建元素(默认:Emmet)
也像 tag()
一样工作。
use function Stefanwimmer128\HtmlBuilder\render;
use function Stefanwimmer128\HtmlBuilder\h;
render(h('table[border=0] > thead > .row > .col', 'Content'));
render(h('div', [], 'Some text <b>with html</b>'));
<table border="0"><thead><tr class="row"><td class="col">Content</td></tr></thead></table>
<div>Some text <p>with html</b></div>
tag(string $tag = 'div', ...$args): HtmlTag
创建标签元素
use function Stefanwimmer128\HtmlBuilder\render;
use function Stefanwimmer128\HtmlBuilder\tag;
render(tag('div', ['class' => 'container'], [
'Text',
tag('p', 'Some text <b>with html</b>')
]));
<div class="container">Text<p>Some text <p>with html</b></p></div>
text(string $text): HtmlText
创建文本元素
use function Stefanwimmer128\HtmlBuilder\render;
use function Stefanwimmer128\HtmlBuilder\text;
render(text('Some text <b>with html</b>'));
Some text <p>with html</b>
raw(string $value): RawString
创建原始字符串
use function Stefanwimmer128\HtmlBuilder\render;
use function Stefanwimmer128\HtmlBuilder\raw;
render(raw('Some text <b>with html</b>'));
Some text <b>with html</b>
capture(callable $callable, ...$args): RawString
捕获输出(echo)并将其作为原始字符串返回
与直接返回标记的函数一起使用很有用(例如,Wordpress)。
use function Stefanwimmer128\HtmlBuilder\render;
use function Stefanwimmer128\HtmlBuilder\tag;
use function Stefanwimmer128\HtmlBuilder\capture;
render(tag('div', [], capture('the_widget', 'widget')));
<div>...widget markup...</div>
map(array $array, callable $callable): array
array_map 带键
use function Stefanwimmer128\HtmlBuilder\render;
use function Stefanwimmer128\HtmlBuilder\tag;
use function Stefanwimmer128\HtmlBuilder\map;
$values = [
'key0' => 'value0',
'key1' => 'value1',
];
render(tag('ul', [], map($values, fn($value, $key) => tag('li', ['id' => $key], $value))));
<ul><li id="key0">value0</li><li id="key1">value1</li></ul>
render(...$elements): string
将元素渲染为 HTML
查看所有上述内容。
编写扩展
创建自定义元素
任何自定义元素都必须扩展 \Stefanwimmer128\HtmlBuilder\HtmlElement
。
首先创建您的元素类
use Stefanwimmer128\HtmlBuilder\HtmlElement;
class CustomElement extends HtmlElement {
private string $someData;
public function __construct(string $someData) {
$this->someData = $someData;
}
public function render(): string {
return sprintf('(%s)', $this->someData);
}
}
如果您的元素类似于标签,您可能想扩展 \Stefanwimmer128\HtmlBuilder\HtmlTag
use Stefanwimmer128\HtmlBuilder\HtmlTag;
class CustomElement extends HtmlTag {
public function __construct(...$args) {
parent::__construct('custom', ...$args);
}
public function render(): string {
return sprintf('(%s)%s', $this->renderAttributes(), $this->renderChildren());
}
}
如果您的自定义元素应该接收解析信息,则您的元素必须实现 \Stefanwimmer128\HtmlBuilder\Parser\ParserCompatibleElement
。
之后,您必须通过在元素使用之前放置此代码来注册您的元素
use Stefanwimmer128\HtmlBuilder\HtmlElement;
HtmlElement::$ELEMENTS['custom'] = CustomElement::class;
创建自定义解析器
任何解析器都必须扩展 \Stefanwimmer128\HtmlBuilder\Parser\AbstractParser
。
由于创建自定义解析器与您想要解析的内容密切相关,请使用包含的 \Stefanwimmer128\HtmlBuilder\Parser\Emmet\EmmetParser
进行定位。
use Stefanwimmer128\HtmlBuilder\Parser\AbstractParser;
class CustomParser extends AbstractParser {
public function __construct(string $input) {
// your parsing logic goes here
}
public function getTag(): string {
// return tag here
}
public function getAttributes(): array {
// return attributes here
}
public function getClasses(): array {
// return classes here
}
public function getId(): ?string {
// return id here if provided or null
}
public function getText() : ?string {
// return text here if provided or null
}
public function getChild() : ?AbstractParser {
// return child here if provided or null
}
public function isSelfclosing() : ?bool{
// return whether tag self-closes if provided or null
}
}
之后,您可以通过以下方式设置您的解析器
use Stefanwimmer128\HtmlBuilder\Parser\AbstractParser;
AbstractParser::$DEFAULT_PARSER = CustomParser::class;