View
Triangle View turns templates and data into HTTP responses. It provides view/raw_view/blade_view/think_view/twig_view and request-scoped variables. Supported adapters target Raw PHP, Twig, Blade and ThinkPHP; third-party engines are installed separately.
Installation and configuration
Section titled “Installation and configuration”composer require triangle/viewRequirements are PHP ^8.1 and triangle/engine ^8.1. View.php selects its handler using VIEW_HANDLER: raw by default, blade, think or twig. Unknown values cause a match error. The package does not install the corresponding Twig Environment, Jenssegers Blade or think Template dependency automatically.
Returning a page
Section titled “Returning a page”return view('account/profile', ['displayName' => 'Reader']);For an ordinary application with no app namespace, Raw resolves this to app/view/account/profile.phtml. The suffix comes from view.options.view_suffix; the shipped default is phtml.
<h1><?= htmlspecialchars($displayName, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?></h1>Raw executes PHP and does not escape output. Escape untrusted data for its output context. Keep template/app/plugin paths under application control rather than accepting arbitrary user paths.
Template resolution
Section titled “Template resolution”Relative names use app/view or app/{app}/view. A plugin uses plugin/{plugin}/app as its base. Leading / means relative to the project root, not the filesystem root.
A null template is inferred from the current controller/action, mapping controller to view and CamelCase to snake_case. Supply an explicit template outside a controller; an empty string is not the automatic-template marker.
Blade uses its engine’s naming rules rather than simply appending view_suffix. Twig and Blade cache engine instances by view path. Changing options at runtime does not necessarily recreate an existing instance.
Request variables
Section titled “Request variables”use Triangle\View\Support\View;
View::assign('displayName', 'Reader');$variables = View::vars();The class is Triangle\View\Support\View, not support\View. Variables are stored on request->_view_vars. Twig, Blade and ThinkPHP merge them with explicit vars, with explicit values taking precedence.
Raw render does not obtain its local request variable before checking _view_vars, so assigned values are not imported through that path. Pass data explicitly to view/raw_view when using Raw. Vars still returns the values stored on the current request.
Layouts and failures
Section titled “Layouts and failures”Raw pre_renders/post_renders accumulate in static lists. The post getter reads the pre list, and array_unique on render descriptor arrays can emit Array-to-string warnings. Do not rely on this mechanism for per-request layouts until corrected; use trusted template includes or the external engine’s layout facilities.
Raw skips a missing template using file_exists and may return an empty string without throwing. Check the resolved app/plugin path and suffix. Exceptions inside include clean the output buffer and propagate. External engines raise their own loader/syntax/runtime errors; do not mask these as successful empty responses.
Response helpers
Section titled “Response helpers”view(template = null, vars = [], app = null, plugin = null, http_code = 200) returns a Triangle Response through the configured handler. Raw_view, blade_view, think_view and twig_view take the first four arguments and return status 200.
An array as the first argument becomes vars and enables automatic template inference. ResponseView(data, status = null, headers = []) renders a system success/error template. Success is selected only for status 200. A numeric data.status from 100 through 599 overrides an initial status of 200 or 500. Pass the intended status explicitly.
Render contract
Section titled “Render contract”RenderInterface::render(string $template, array $vars, string $app = null): string is the minimal interface. Built-in adapters also accept plugin. Assign/vars, pre/post rendering and plugin support are not specified by that interface; a custom handler must implement the methods its callers use.
AbstractRender exposes assign, vars, build, addPreRender/getPreRenders and addPostRender/getPostRenders. Assign accepts name/value or an array. Its merge_recursive option uses array_merge_recursive, which can turn colliding scalar values into arrays.
Build combines template/app/plugin and view_suffix without proving the result remains inside an allowed directory. Treat those path inputs as trusted configuration.
Adapters
Section titled “Adapters”| Adapter | Behavior |
|---|---|
| Raw | PHP include; options.vars and explicit vars; no automatic escaping |
| Twig | FilesystemLoader/Environment; options and extension callback on cached instance creation |
| Blade | Jenssegers Blade; compiled templates in runtime/views; extension callback on cached instance creation |
| ThinkPHP | New think Template per render; merged view_path/cache_path/view_suffix options |
Plugin configuration normally uses plugin.{name}.view. Some automatic-template resolution uses the literal plugin prefix rather than the configurable alias, so custom aliases require separate verification.
System templates
Section titled “System templates”Raw::renderSys(template, vars) obtains the current request and imports assigned values. It resolves view.templates.system.{template}, falling back to Templates/{template}.phtml inside the package. A fallback path is not a guarantee that the file is included in the installed package.