z1ffy/htmlgen

此包最新版本(dev-master)没有提供许可证信息。

PHP中HTML生成的轻量级DSL。

维护者

详细信息

github.com/z1FFy/htmlgen

源代码

dev-master 2016-10-24 13:37 UTC

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)
    )
  })
);

还记得指定每个元素的idclass有多麻烦吗?

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 &excl;</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 "&amp;"
// 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 &quest;</p><p>It's a wonder more people don't like bees &excl;</p><p>Bees
are &gt; htmlentities</p><p>Raw honey is the <strong>best</strong></p><table>
<thead><tr><td>item</td><td>do bees like it&quest;</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 &quest;</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 &amp; donuts and stuff &excl;</p></footer><script
src="/main.js"></script></body></html>

试试看吧!

$ cd htmlgen/example
$ php index.php

许可证

BSD 3-clause