PHPackages                             preflow/view - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. preflow/view

ActiveLibrary[Templating &amp; Views](/categories/templating)

preflow/view
============

Preflow view — template engine interfaces and asset pipeline

v0.13.1(1mo ago)0445MITPHPPHP &gt;=8.4

Since Apr 10Pushed 1mo agoCompare

[ Source](https://github.com/getpreflow/view)[ Packagist](https://packagist.org/packages/preflow/view)[ RSS](/packages/preflow-view/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (3)Versions (31)Used By (5)

preflow/view
============

[](#preflowview)

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
------------

[](#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
---------------

[](#whats-included)

ComponentDescription`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 CSPTemplateEngineInterface
-----------------------

[](#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
-------------------------

[](#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
------------------

[](#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();    // head JS
$assets->renderAssets();  // CSSbody JS
$assets->renderCss();
$assets->renderJsHead();
$assets->renderJsBody();
$assets->renderJsInline();

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

Every `` and `` 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

[](#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();
}
```

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance90

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

30

Last Release

53d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6d8b54efbc79683c32645e3fa8d3590037fa003963a16e0ed989104c6f4a2723?d=identicon)[smyr](/maintainers/smyr)

---

Top Contributors

[![smeyerme](https://avatars.githubusercontent.com/u/1925560?v=4)](https://github.com/smeyerme "smeyerme (18 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/preflow-view/health.svg)

```
[![Health](https://phpackages.com/badges/preflow-view/health.svg)](https://phpackages.com/packages/preflow-view)
```

###  Alternatives

[appwrite/sdk-generator

Appwrite PHP library for generating API SDKs for multiple programming languages and platforms

319193.2k2](/packages/appwrite-sdk-generator)[sebastienheyd/boilerplate

Laravel Boilerplate based on AdminLTE 3 with blade components, user management, roles, permissions, logs viewer, ...

29019.5k3](/packages/sebastienheyd-boilerplate)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

9017.2k55](/packages/open-dxp-opendxp)[cbl/blade-script

4818.3k2](/packages/cbl-blade-script)[cbl/blade-style

1918.3k3](/packages/cbl-blade-style)[chameleon-system/chameleon-base

The Chameleon System core.

1027.9k4](/packages/chameleon-system-chameleon-base)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
