View
Foundation View provides a small contract for rendering named views and a default PhpView implementation that renders trusted PHP templates from an explicit directory. It keeps markup in view files while application services remain responsible for selecting the view and preparing its data.
PhpView uses ordinary PHP templates without introducing custom template syntax. It captures their output and returns it as a string instead of echoing it automatically. A configured renderer can also create an immutable renderer for another trusted directory at runtime.
Installation
Section titled “Installation”Install the split package:
Prepare the application
Section titled “Prepare the application”Foundation View uses the shared application configuration and provider architecture established in these guides:
Configuration
Section titled “Configuration”Choose the default view directory
Section titled “Choose the default view directory”Create a views/ directory at the application root. In the root config.php, provide its absolute path:
view.directory is required and must identify an existing, readable directory. Foundation resolves it to its canonical path before rendering.
Register the view provider
Section titled “Register the view provider”In src/App.php, add ViewProvider before feature providers that consume the View contract:
ViewProvider binds one shared PhpView instance to StellarWP\Foundation\View\Contracts\View and StellarWP\Foundation\View\Contracts\DirectoryAwareView.
Create a view before rendering it
Section titled “Create a view before rendering it”View names are relative to the configured directory and omit the .php extension. For the name admin/product-summary, first create views/admin/product-summary.php:
Render the view from a service
Section titled “Render the view from a service”In src/Admin/Product_Summary_Notice.php, inject the View contract and return or echo the rendered string at the application boundary:
Register the WordPress callback from src/Admin/Provider.php:
Select another directory at runtime
Section titled “Select another directory at runtime”Inject DirectoryAwareView instead of the base View contract when a service must select another trusted template root, such as a theme override directory:
withDirectory() returns a new renderer. It does not mutate the shared renderer or affect other services using the configured directory.
Supply another renderer
Section titled “Supply another renderer”The base View contract requires only named rendering. A renderer that does not use PHP files or directories can implement it without supporting withDirectory():
Bind the replacement from the application’s feature provider instead of registering ViewProvider:
Use a separate capability contract when a custom renderer supports optional behavior such as runtime directory selection. Application services that only call render() should continue depending on View.
Handle missing views
Section titled “Handle missing views”The renderer throws ViewNotFoundException when a view is missing, unreadable, or resolves outside the selected directory. Empty names, absolute paths, null bytes, and parent traversal such as ../private are rejected with InvalidArgumentException.
Exceptions thrown by the view itself are propagated after Foundation removes any removable buffers opened while rendering. A view may use balanced buffers of its own, but it must not clean, flush, close, or replace Foundation’s rendering buffer. Invalid buffer state is rejected instead of returning incomplete output. Let application-level error handling record or present those failures rather than returning a partial template.
Testing
Section titled “Testing”Place small PHP view fixtures under the test data directory. For example, create tests/_data/views/message.php:
Render the fixture with the concrete class:
Test feature services through the View contract when the rendered markup is part of their observable behavior. Use a temporary directory under tests/_data/temp for path-containment or runtime-directory tests that must create files.