preflow/view 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

preflow/view

最新稳定版本:v0.13.1

Composer 安装命令:

composer require preflow/view

包简介

Preflow view — template engine interfaces and asset pipeline

README 文档

README

Engine-agnostic template interfaces and asset pipeline for Preflow. Defines the contracts that engine adapters (preflow/twig, preflow/blade) implement. Ships a CSP-nonce-aware asset collector with deduplication.

Installation

composer require preflow/view

Requires PHP 8.4+. Install an engine adapter to render templates:

composer require preflow/twig   # Twig 3
composer require preflow/blade  # Laravel Blade

What's included

Component Description
TemplateEngineInterface Engine contract: render, exists, addFunction, addGlobal, getTemplateExtension
TemplateFunctionDefinition Value object describing a template function (name, callable, isSafe)
TemplateExtensionProvider Interface for packages that supply template functions and globals
AssetCollector Collects CSS/JS across components, deduplicates by xxh3 hash
JsPosition Enum: Head, Body, Inline
NonceGenerator Generates one random nonce per request for CSP

TemplateEngineInterface

The central contract. Engine adapters implement this to plug into Preflow.

use Preflow\View\TemplateEngineInterface;

$html = $engine->render('blog/post', ['post' => $post]);
$engine->exists('partials/nav');                          // bool
$engine->getTemplateExtension();                          // 'twig' or 'blade.php'
$engine->addGlobal('siteName', 'My App');                 // available in all templates
$engine->addFunction(new TemplateFunctionDefinition(
    name: 'greet',
    callable: fn (string $name) => "Hello, {$name}!",
    isSafe: true,                                         // skip output escaping
));

TemplateExtensionProvider

Feature packages implement this interface to register template functions without depending on a specific engine.

use Preflow\View\TemplateExtensionProvider;
use Preflow\View\TemplateFunctionDefinition;

final class MyExtensionProvider implements TemplateExtensionProvider
{
    public function getTemplateFunctions(): array
    {
        return [
            new TemplateFunctionDefinition(
                name: 'myHelper',
                callable: fn (string $arg) => strtoupper($arg),
                isSafe: true,
            ),
        ];
    }

    public function getTemplateGlobals(): array
    {
        return ['appVersion' => '1.0'];
    }
}

Built-in providers: ComponentsExtensionProvider, HtmxExtensionProvider, TranslationExtensionProvider.

AssetCollector API

// Add CSS (key is optional; defaults to xxh3 hash of content)
$assets->addCss('.btn { ... }');
$assets->addCss('.btn { ... }', key: 'btn-styles'); // explicit dedup key

// Add JS
$assets->addJs('console.log("body")', JsPosition::Body);
$assets->addJs('console.log("head")', JsPosition::Head);
$assets->addJs('console.log("inline")', JsPosition::Inline);

// Render (called by engine extensions; also usable directly)
$assets->renderHead();    // <script nonce="...">head JS</script>
$assets->renderAssets();  // <style nonce="...">CSS</style><script nonce="...">body JS</script>
$assets->renderCss();
$assets->renderJsHead();
$assets->renderJsBody();
$assets->renderJsInline();

// CSP nonce for the current request
$assets->getNonce(); // base64 random, stable within one request

Every <style> and <script> tag rendered by AssetCollector carries the same nonce attribute. Use $assets->getNonce() to add 'nonce-{value}' to your Content-Security-Policy header.

Identical blocks (same xxh3 hash) are deduplicated automatically — safe to include the same component multiple times.

Forked collectors and inspection

fork() creates an isolated child AssetCollector that shares the same nonce but collects assets independently. Use it when rendering a sub-component that should not pollute the parent collector (e.g. fragment responses).

$child = $assets->fork();
$html  = $componentRenderer->renderFragment($component, $child);
// $assets is untouched; $child holds only the fragment's CSS/JS

hasCss() and hasJs() let you check before rendering — useful to decide whether to append inline styles to a fragment response.

if ($child->hasCss() || $child->hasJs()) {
    $html .= $child->renderHead() . $child->renderAssets();
}

统计信息

  • 总下载量: 44
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 5
  • 依赖项目数: 7
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-10

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固