erikvv/hyperscript

此包的最新版本(dev-master)没有可用的许可信息。

dev-master 2023-03-22 12:17 UTC

This package is auto-updated.

Last update: 2024-09-22 14:40:40 UTC


README

纯PHP生成HTML,替代模板引擎。

优势

与模板引擎相比的优势

  • 易于创建组件,使用类和函数
  • 无需学习DSL
  • 防止XSS攻击
  • IDE支持

配置

composer require erikvv/hyperscript
use DOMDocument;
use Erikvv\Hyperscript\Hyperscript;

require './vendor/autoload.php';

$h = new Hyperscript(new DOMDocument());

背景

PHP的Hyperscript建立在DOM扩展之上。

它受到类似库的启发,如HyperScript for JSHiccup for ClojureElm

Erikvv/hyperscript在spatie/html-element的基础上进行了改进,因为该库容易受到XSS攻击。

示例

文本片段

$fragment = $h->fragment(
    $h->h1('.welcome-header', 'Welcome'),
    $h->p('Write some hyperscript'),
);

echo $h->render($fragment);
<h1 class="welcome-header">Welcome</h1>
<p>Write some Hyperscript</p>

表单

$error = 'Cartoon birds not allowed';
$birdName = 'Donald Duck';

$element =
    $h->form(
        '#bird-form', [
            'method' => 'post',
            'action' => '/bird/submit',
        ],
        $error ? $h->div('.error', $error) : null,
        $h->div(
            $h->label(['for' => 'bird-name'], 'Name'),
            $h->input(
                '.bird-name', [
                    'name' => 'bird-name',
                    'value' => $birdName
                ]
            )
        ),
        $h->button('Submit')
    );

echo $h->render($element);
<form id="bird-form" method="post" action="/bird/submit">
    <div class="error">Cartoon birds not allowed</div>
    <div>
        <label for="bird-name">Name</label>
        <input id="bird-name" name="bird-name" value="Donald Duck">
    </div>
    <button>Submit</button>
</form>

默认转义

$element = $h->div('<script>alert(1)</script>');

echo $h->render($element);
<div>&lt;script&gt;alert(1)&lt;/script&gt;</div>

禁用转义

$element = $h->div(
    $h->unsafe('<script>alert(1)</script>')
);

echo $h->render($element);
<div><script>alert(1)</script></div>

自定义元素

$element = $h('my-custom-element', 'my-content')

echo $h->render($element);
<my-custom-element>my-content</my-custom-element>

自定义组件

/**
 * You can improve this class with object-oriented 
 * or functional techniques to fit your usecase.
 */
class RoundedMillimeterTable
{
    public static function row(Hyperscript $h, string $rowHeader, float ...$values): DOMElement 
    {
        $cells = [
            $h->td($rowHeader)
        ];

        foreach ($values as $value) {
            $cells[] = $h->td(number_format($value, 1) . ' mm');
        }

        return $h->tr(...$cells);
    }
}

$row = RoundedMillimeterTable::row($h, 'displacement', 1.8, 2.0);

echo $h->render($row);
<tr>
    <td>displacement</td>
    <td>1.8 mm</td>
    <td>2.0 mm</td>
</tr>