z1ffy / htmlgen
PHP中HTML生成的轻量级DSL。
This package is not auto-updated.
Last update: 2024-09-23 13:31:40 UTC
README
PHP中HTML生成的轻量级DSL
2.0版更新了什么?
- 所有的魔法都消失了
- 版本1 API已完全过时
- 不再有自动输出
- 不再有输出缓冲
- 不再有子元素闭包
- 不再有显式的数据存储/检索
- 不再有格式化输出(至少现在是这样)
- 代码库缩小了25%
- 单元测试
- 命名空间
- 使用
htmlentities
安全地编码所有文本节点 - 通过原生PHP
require
实现“模板化”(请参阅提供的示例) - 自定义元素
- 对类似Zen的元素的轻量级支持
还记得所有的闭包吗?
// version 1.0 required closures for all children ... h::html(function(){ h::head(function(){ h::meta(array("charset"=>"UTF-8")); h::link(array("rel"=>"stylesheet", "type"=>"text/css", "href"=>"global.css")); }); h::body(function(){ ... // version 2.0 variadic interface allows passing as many children as you want h('html', h('head', h('meta', ['charset'=>'UTF-8']), h('link', ['rel'=>'stylesheet', 'type'=>'text/css', 'href'=>'global.css']) }) h('body', ...
还记得将数据传递给子元素有多难吗?
// version 1.0 required `global` unless `use` was specified on every closure h::table(function(){ // icky global state global $table_data; h::tr(array("class"=>"header"), function(){ h::th("key"); h::th("value"); }); foreach($table_data as $k => $v){ // verbose function use($k,$v) ... h::tr(array("class"=>h::cycle(array("odd", "even"))), function() use($k,$v){ h::td($k); h::td($v); }); } }); // version 2.0 has no problem accessing data in child nodes h('table', h('tr', ['class'=>'header'], h('th', 'key'), h('th', 'value') ), map($table_data, function ($v,$k) { return h('tr', h('td', $k), h('td', $v) ) }) );
还记得指定每个元素的id
和class
有多麻烦吗?
h('#sidebar.column', h('.section', h('h2.section-title', 'Cat Links'), h('button.btn.btn-large', 'Adopt a cat now !') ) );
现在将渲染
<div id="sidebar" class="column"> <div class="section"> <h2 class="section-title">Cat Links</h2> <button class="btn btn-large">Adopt a cat now !</button> </div> </div>
需求
抱歉,目前需要 PHP >= 7
。目前唯一真正导致这种情况的是类型提示。我最终会制作一个PHP 5.x
版本。最终。可能。
API
html ( string
tag [, assoc
attributes], mixed
...children ) : RawString
这是你的基础。请参阅示例以获取更多帮助。提醒:htmlgen\RawString
是一个实现细节,应予以忽略。永远不要针对此类型编写测试或检查$html instanceof RawString
。只需将其视为字符串即可。
map ( array
xs , callable
λ(mixed
v , mixed
k ): string
) : array
此函数对于从现有数据构建节点列表非常有帮助。它存在是因为array_map
默认不传递数组键。注意此函数的参数顺序与原生array_map
相比。请参阅下面的代码示例以获取更多详细信息。
raw ( string
html ): RawString
传递给html
的所有子字符串将自动使用htmlentities($str, ENT_HTML5)
进行HTML实体编码。如果您想绕过编码,可以使用此函数包裹字符串。
render ( resource
writableStream , mixed
...children ) : int
大多数人可能只会使用echo html(...)
,这是完全可以的,但render
更灵活,允许您将内容渲染到任何可写流。这意味着render(STDOUT, html(...))
与echo html(...)
相同。用于将HTML写入文件render($fd, ...)
或内存$mem = fopen('php://memory'); render($mem, ...)
,或者完全跳过render
并直接$html = html(...); doSomething($html);
PHP就是这样,你可以自己弄明白。
capture ( callable
f[, ...xs] ) : RawString
在您有一个无法操控、难以处理、笨拙、不纯的函数时使用此功能,例如WordPress中找到的100%的函数。这将方便地劫持任何原本写入STDOUT
的函数,并将其存放在string
中。使用capture('the_title')
将返回字符串而不是输出。如果您需要传递参数,可以使用capture('the_title', $postId)
,或者甚至可以使用lambda,capture(function($id) { the_title($id); }, $postId)
或capture(function() use($postId) { the_title($postId); })
。记住,我之前说过这只是PHP吗?它确实只是PHP。而且我知道get_the_title
存在。这是一个示例。
哦,是的,应该不用我说,capture
既不是魔术师也不是心灵感应者。不会自动对从可调用函数返回的HTML实体进行编码。它(并且确实)承诺不会双重编码HTML实体。
警告:
- htmlgen仅显示HTML实体。输出原始HTML字符串需要特殊的字符串包装器。猜猜这个助手叫什么?它叫做
raw
。我已经在上面说过这个了。快说。
代码示例
example/index.js
require '../htmlgen.php'; require './htmlgen.extensions.php'; use function htmlgen\html as h; use function htmlgen\render; render(STDOUT, h('doctype'), h('html', ['lang'=>'en'], h('head', h('meta', ['charset'=>'utf-8']), h('meta', ['http-equiv'=>'X-UA-Compatible', 'content'=>'IE=edge']), h('meta', ['name'=>'viewport', 'content'=>'width=device-width, initial-scale=1']), h('link', ['rel'=>'stylesheet', 'type'=>'text/css', 'href'=>'/main.css']), h('condition', 'lt IE 9', h('script', ['src'=>'ie.js']) ) ), h('body', h('header', require './navigation.php' ), h('main', require './body.php' ), h('footer', require './footer.php' ), h('script', ['src'=>'/main.js']) ) ) );
example/navigation.php
use function htmlgen\html as h; use function htmlgen\map as map; $links = [ 'home' => '/', 'cats' => '/cats', 'milk' => '/milk', 'honey' => '/honey', 'donuts' => '/donuts', 'bees' => '/bees' ]; return h('nav', h('ul', map($links, function($href, $text) { return h('li', h('a', ['href'=>$href], $text) ); }) ) );
example/body.php
use function htmlgen\html as h; use function htmlgen\map; use function htmlgen\raw; $beeData = [ 'pop' => 'yup', 'candy' => 'sometimes', 'flowers' => 'so much', 'water' => 'not really', 'sand' => 'indifferent', 'donuts' => 'most definitely' ]; return [ h('h1', 'Hello from HtmlGgen'), h('comment', 'really cool and thought-provoking article'), h('article', h('h2', 'All about honey'), h('img', ['src'=>'/busybeehive.png', 'alt'=>'bees like to keep busy!', 'width'=>300, 'height'=>100]), h('p', 'Did you know that bees are responsible for making honey ?'), h('p', 'It\'s a wonder more people don\'t like bees !'), h('p', 'Bees are > htmlentities'), // if you really must output HTML, you can use the `raw` utility h('p', raw('Raw honey is the <strong>best</strong>')), h('table', h('thead', h('tr', h('td', 'item'), h('td', 'do bees like it?') ) ), h('tbody', map($beeData, function($value, $key) { return h('tr', h('td', $key), h('td', $value) ); }) ) ), h('aside', 'Did you know that queen bees come from larvae that are overfed with royal jelly ?') ), h('comment', 'newsletter signup form'), h('form', ['action'=>'#subscribe'], h('input', ['name'=>'email', 'autofocus']), h('input', ['type'=>'button', 'value'=>'Get Bee News !']) ) ];
example/footer.php
use function htmlgen\html as h; // notice "&" will automatically be converted to "&" // this behavior protects you from malicious user input return h('p', 'Thanks for your interest in cats & donuts and stuff !');
输出
换行(实际输出不包含换行符)
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" type="text/css" href="/main.css"><!--[if lt IE 9]><script src="ie.js"></script> <![endif]--></head><body><header><nav><ul><li><a href="/">home</a></li><li> <a href="/cats">cats</a></li><li><a href="/milk">milk</a></li><li> <a href="/honey">honey</a></li><li><a href="/donuts">donuts</a></li><li> <a href="/bees">bees</a></li></ul></nav></header><main><h1>Hello from HtmlGgen </h1><!-- really cool and thought-provoking article --><article><h2> All about honey</h2><img src="/busybeehive.png" alt="bees like to keep busy!" width="300" height="100"><p>Did you know that bees are responsible for making honey ?</p><p>It's a wonder more people don't like bees !</p><p>Bees are > htmlentities</p><p>Raw honey is the <strong>best</strong></p><table> <thead><tr><td>item</td><td>do bees like it?</td></tr></thead><tbody><tr> <td>pop</td><td>yup</td></tr><tr><td>candy</td><td>sometimes</td></tr><tr><td> flowers</td><td>so much</td></tr><tr><td>water</td><td>not really</td></tr><tr> <td>sand</td><td>indifferent</td></tr><tr><td>donuts</td><td>most definitely </td></tr></tbody></table><aside>Did you know that queen bees come from larvae that are overfed with royal jelly ?</aside></article><!-- newsletter signup form --><form action="#subscribe"><input name="email" autofocus><input type="button" value="Get Bee News !"></form></main><footer><p>Thanks for your interest in cats & donuts and stuff !</p></footer><script src="/main.js"></script></body></html>
试试看吧!
$ cd htmlgen/example
$ php index.php