pug-php/pug

PHP的类似HAML模板引擎


README

Latest Stable Version Monthly Downloads License StyleCI Test Coverage Code Climate Dependencies

Pug-phpPug 模板编译器添加了内联 PHP 脚本支持。自版本 3 开始,它使用由 tale-pugpug-php 开发者创建的非常可定制的 Pug 模板引擎 Phug 作为新的 PHP Pug 引擎参考。

官方 Phug 文档
查看 Pug-php 示例
通过 Tidelift 订阅获取支持的 pug-php/pug

安装

首先,如果您还没有,则需要 composer:https://getcomposer.org.cn/download/

然后运行

composer require pug-php/pug

在您喜欢的框架中使用 Pug

Phalcon: https://github.com/pug-php/pug-phalcon

Symfony: https://github.com/pug-php/pug-symfony

Laravel: https://github.com/BKWLD/laravel-pug

CodeIgniter: https://github.com/pug-php/ci-pug-engine

Yii 2: https://github.com/rmrevin/yii2-pug

Slim 3: https://github.com/MarcelloDuarte/pug-slim

Zend Expressive: https://github.com/kpicaza/infw-pug

使用

<?php

include 'vendor/autoload.php';

$pug = new Pug([
    // here you can set options
]);

$pug->displayFile('my-pug-template.pug');

pug-php 3.1.2 版本开始,您不再需要使用 use Pug\Pug; 导入类,因为我们提供了一个别名。

主要方法包括 renderrenderFilecompilecompileFiledisplaydisplayFilesetOption,请在此处查看完整文档:phug-lang.com

您还可以使用外观调用静态方法

<?php

use Pug\Facade as PugFacade;

include 'vendor/autoload.php';

$html = PugFacade::renderFile('my-pug-template.pug');

Pug 选项

Pug 选项应传递给构造函数

$pug = new Pug([
    'pretty' => true,
    'cache' => 'pathto/writable/cachefolder/',
]);

对局部变量的支持

$pug = new Pug();
$output = $pug->renderFile('file.pug', [
    'title' => 'Hello World',
]);

新功能:pug-php 3

现在,pug-php 3 与 pugjs 2 对齐,目标是成为 JS 项目的完美实现。这就是为什么在这个新版本中有破坏性变化。

查看变更日志以了解新功能

如果您想从 pug-php 2 升级到 3,请参阅迁移指南

对自定义过滤器支持

过滤器必须是可调用的:它可以是实现 __invoke() 方法的类或匿名函数。

$pug->filter('escaped', 'My\Callable\Class');

// or

$pug->filter('escaped', function($node, $compiler) {
    foreach ($node->block->nodes as $line) {
        $output[] = $compiler->interpolate($line->value);
    }

    return htmlentities(implode("\n", $output));
});

内置过滤器

  • :css
  • :php
  • :javascript
  • :escaped
  • :cdata

使用 composer 安装其他过滤器

http://pug-filters.selfbuild.fr/

发布您自己的过滤器

https://github.com/pug-php/pug-filter-base#readme

对自定义关键字的支持

您可以添加自定义关键字,以下是一些示例

匿名函数:

$pug->addKeyword('range', function ($args) {
    list($from, $to) = explode(' ', trim($args));

    return [
        'beginPhp' => 'for ($i = ' . $from . '; $i <= ' . $to . '; $i++) {',
        'endPhp' => '}',
    ];
});

$pug->render('
range 1 3
    p= i
');

这将渲染

<p>1</p>
<p>2</p>
<p>3</p>

注意,现有的 for..in 操作符将优先于这个自定义的 for 关键字。

可调用的类:

class UserKeyword
{
    public function __invoke($arguments, $block, $keyWord)
    {
        $badges = array();
        foreach ($block->nodes as $index => $tag) {
            if ($tag->name === 'badge') {
                $href = $tag->getAttribute('color');
                $badges[] = $href['value'];
                unset($block->nodes[$index]);
            }
        }

        return [
            'begin' => '<div class="' . $keyWord . '" data-name="' . $arguments . '" data-badges="[' . implode(',', $badges) . ']">',
            'end' => '</div>',
        ];
    }
}

$pug->addKeyword('user', new UserKeyword());

$pug->render('
user Bob
    badge(color="blue")
    badge(color="red")
    em Registered yesterday
');

这将渲染

<div class="user" data-name="Bob" data-badges="['blue', 'red']">
    <em>Registered yesterday</em>
</div>

关键字必须返回一个数组(包含 begin 和/或 end 条目)或一个字符串(用作 begin 条目)。

开始和结束标签将被渲染为原始HTML,但您也可以像第一个示例中那样使用 beginPhpendPhp 来渲染将包裹渲染块的PHP代码(如果有的话)。

PHP辅助函数

如果您想在一个模板或所有模板中方便地使用PHP函数,请使用闭包并像传递任何其他变量一样传递它们。

$myClosure = function ($string) {
    return 'Hey you ' . $string . ', out there on your own, can you hear me?';
};

$pug->render('p=$myClosure("Pink")', array('myClosure' => $myClosure));

这将渲染

<p>Hey you Pink, out there on your own, can you hear me?</p>

您可以使用 share 方法让该闭包对所有模板都可用,而无需在渲染参数中传递。

// ... $pug instantiation
$pug->share('myClosure', $myClosure);
$pug->render('p=$myClosure("Pink")');

这将渲染与上一个示例相同的HTML。另外,请注意,share 允许您传递任何类型的值。

缓存

重要:为了提高生产中的性能,请通过将 cache 选项设置为可写目录来启用Pug缓存,您可以在部署期间一次性缓存所有模板。

$pug = new Pug([
    'cache' => 'var/cache/pug',
]);
[$success, $errors] = $pug->cacheDirectory('path/to/pug/templates');
echo "$success files have been cached\n";
echo "$errors errors occurred\n";

确保没有出现意外错误,并且您的模板目录中的所有模板都已缓存。

然后,在生产中使用相同的缓存目录和模板目录,将选项 upToDateCheck 设置为 false 以跳过缓存检查并自动使用缓存版本。

$pug = new Pug([
    'cache' => 'var/cache/pug',
    'basedir' => 'path/to/pug/templates',
    'upToDateCheck' => false,
]);
$pug->render('path/to/pug/templates/my-page.pug');

pug-js的模板

首先请记住,pug-php是一个PHP模板引擎。Pug-js和Pug-php都提供了类似的语法和语言背后的某些抽象(循环、条件等)。但对于表达式和原始代码,pug-js使用JS,而pug-php使用PHP。默认情况下,我们会进行一些魔法转换,将简单的JS语法转换为PHP。如果您已经有一些模板,这将有助于您更平滑地从pug-js迁移,并从中获得PHP的优势。

如果您开始一个新的项目,我们强烈建议您使用以下选项

$pug = new Pug([
    'expressionLanguage' => 'php',
]);

这将禁用所有翻译,因此您必须始终使用显式的PHP语法

- $concat = $foo . $bar
p=$concat

如果您想要非常接近JS的表达式,可以使用

$pug = new Pug([
    'expressionLanguage' => 'js',
]);

这将允许在JS-style语法中同时使用PHP和JS。但您必须坚持这种模式,您将无法在此模式下混合PHP和JS。

最后,您可以使用原生的pug-js引擎

$pug = new Pug([
    'pugjs' => true,
]);

此模式需要安装node和npm,因为它将安装 pug-cli 并直接调用它。此模式将简化本地变量(这意味着像DateTime这样的复杂对象或具有魔术方法的类将被转换为JSON的简单对象),您将无法享受一些功能,如混合缩进、预/后渲染钩子。但在此模式下,您将获得与pug-js完全相同的输出。

使用pug-js将局部对象写入JSON文件

如果您的局部对象很大,它可能会导致 RuntimeException。这是因为它将局部对象直接作为参数传递给pug-cli。要解决这个问题,您可以使用 localsJsonFile 选项。

$pug = new Pug([
    'pugjs' => true,
    'localsJsonFile' => true
]);

然后,您的局部对象将被写入JSON文件,并将文件的路径传递给编译器。

Pug CLI

Pug还提供了一款CLI工具

./vendor/bin/pug render-file dir/my-template.pug --output-file

请参阅完整的CLI文档

检查要求

要检查您的环境是否已准备好使用Pug,请使用 requirements 方法

$pug = new Pug([
    'cache' => 'pathto/writable/cachefolder/',
]);
$missingRequirements = array_keys(array_filter($pug->requirements(), function ($valid) {
    return $valid === false;
}));
$missings = count($missingRequirements);
if ($missings) {
    echo $missings . ' requirements are missing.<br />';
    foreach ($missingRequirements as $requirement) {
        switch($requirement) {
            case 'streamWhiteListed':
                echo 'Suhosin is enabled and ' . $pug->getOption('stream') . ' is not in suhosin.executor.include.whitelist, please add it to your php.ini file.<br />';
                break;
            case 'cacheFolderExists':
                echo 'The cache folder does not exists, please enter in a command line : <code>mkdir -p ' . $pug->getOption('cache') . '</code>.<br />';
                break;
            case 'cacheFolderIsWritable':
                echo 'The cache folder is not writable, please enter in a command line : <code>chmod -R +w ' . $pug->getOption('cache') . '</code>.<br />';
                break;
            default:
                echo $requirement . ' is false.<br />';
        }
    }
    exit(1);
}

贡献

欢迎所有贡献,对于任何错误、问题或合并请求(除了安全问题之外),请参阅CONTRIBUTING.md

安全

要报告安全漏洞,请使用Tidelift安全联系。Tidelift将协调修复和披露。

贡献者

本项目得益于所有贡献者。

以及所有为我们依赖项做出贡献的人们,特别是: Phug 引擎,JS 语法转换器 Js-Phpize

赞助者

感谢所有赞助者!🙏 [成为赞助者]

赞助商

通过成为赞助商来支持本项目。您的标志将在这里显示,并附带您网站的链接。 成为赞助商

并感谢 Jet Brains,它提供如此出色的 IDE