svengerlach/vanillajs-template

将John Resig的微模板方法移植到PHP,用于服务器端预编译简单的JavaScript模板

0.0.3 2016-08-21 07:37 UTC

This package is auto-updated.

Last update: 2024-09-26 20:48:49 UTC


README

Build Status

将John Resig的JavaScript微模板方法移植到PHP,用于服务器端预编译简单的JavaScript模板。

背景

我在过去大量使用了John Resig的方法。它很小,易于使用,并且没有依赖。我喜欢它!

然而,这种方法有一个简单的缺点

如果你的应用程序已经为Content-Security-Policy HTTP头中的script-src设置了例如self,你将遇到问题。

Google Chrome会拒绝执行模板函数,并显示以下错误消息

未捕获的EvalError:由于'unsafe-eval'不是以下内容安全策略指令中允许的脚本源,因此拒绝评估字符串作为JavaScript:"script-src 'self'"

解决方案?

  1. 在内容安全策略头中将unsafe-eval作为script-src允许
  2. 实现一个解决方案,预先编译模板为可执行的JavaScript函数

第一个方案不可行,因为它会降低我们的安全防线。

我选择了第二个方案。因为我大部分项目都是PHP应用程序,所以我决定将John Resig的模板转换移植到PHP。

安装

建议使用composer运行以下命令进行安装

composer require svengerlach/php-vanillajs-template

使用方法

此库可以作为独立组件或作为twig扩展使用。

独立使用

请参阅examples/standalone.php

<?php

$compiler = new \Svengerlach\VanillaJSTemplate\Compiler();

$template = '<h1>Hello, <%= foo %>!</h1>';
$templateCompiled = $compiler->compile($template);
<!DOCTYPE html>
<html>
    <body>
        <!-- will contain "Hello, World!" -->
        <div id="template_container">loading...</div>
        
        <script>
        var templateFunction = <?= $templateCompiled; ?>;
        document.getElementById('template_container').innerHTML = templateFunction({ foo: 'World' });
        </script>
    </body>
</html>

Twig扩展

请参阅examples/twigextension.html.twig

<?php

require_once __DIR__ . '/../vendor/autoload.php';

// insantiate twig loader
$loader = new \Twig_Loader_Filesystem([__DIR__]);

// instantiate twig
$twig = new \Twig_Environment($loader);

// instantiate compiler
$compiler = new \Svengerlach\VanillaJSTemplate\Compiler();

// instantiate twig extension
$extension = new \Svengerlach\VanillaJSTemplate\TwigExtension($compiler);

// add extension to twig
$twig->addExtension($extension);

// see twig template below
echo $twig->render('twigextension.html.twig');

请参阅examples/twigextension.html.twig

<!DOCTYPE html>
<html>
    <body>
        <!-- will contain "Hello, foo!" -->
        <div id="template_container_1">loading...</div>
        
        <!-- will contain "Hi, bar!" -->
        <div id="template_container_2">loading...</div>
        
        <script>
            var templateFunction = {{ vanillajstemplate('<h1><% if ( hello === true ) { %>Hello, <% } else { %>Hi, <% } %><%= who %>!</h1>') }};

            "use strict";
            
            document.getElementById('template_container_1').innerHTML = templateFunction({ 
                hello: true, 
                who: 'foo' 
            });
            
            document.getElementById('template_container_2').innerHTML = templateFunction({ 
                hello: false, 
                who: 'bar' 
            });
        </script>
    </body>
</html>

改进空间

预编译模板的一个缺点是它们与JavaScript严格模式("use strict";)不兼容。现在使用的with语句被认为是不良做法。