Luminova Framework

Template View Rendering

Last updated: 2024-08-07 12:47:08

The View class serves as the central controller for presenting templates in Luminova. It is designed to compile, present, and cache application views efficiently. The class is highly adaptable, capable of handling various content types, and offers customizable rendering modes to fit different coding styles and business logic needs.

In Luminova, the View class is automatically inherited by the BaseApplication class, ensuring seamless access to its methods throughout your application.

Core Functionalities

  1. Compiling Views: The View class processes template files, transforming them into optimized content for rendering.
  2. Presenting Views: It controls the display of templates, ensuring that the correct content is shown to the user.
  3. Caching Views: To enhance performance, the View class can cache compiled templates, reducing the need for repeated processing.
  4. Content Adaptability: It can handle various content types, making it versatile for different presentation needs.
  5. Customizable Rendering: The rendering mode can be customized to match your specific coding style and business logic requirements Template Configuration.

  • Class namespace: \Luminova\Template\View

Class Access

  • Within the App\Application Class: Access methods using $this->foo().
  • Within View Controller Classes: Access methods through the application object using $this->app->foo().
  • Within Routing Context Files: Access methods via the global application variable $app->foo().
  • Within View Files: Access methods using $this->foo() only if template isolation is disabled and the default template engine is used.
  • Other Global Scope: Use the global helper function app() to access methods with app()->foo().

Note:Avoid re-initializing the Application class multiple times, as this may lead to unintended errors. Instead, always use the app() helper function to return a shared instance of your application object.


codeblock

The codeblock method enables you to disable minification for HTML code blocks enclosed within <pre><code></code></pre> tags during view content minification. This feature is particularly useful when you need to display code on your webpage. If minification is applied, the removal of new lines can make the code difficult for users to read.

public codeblock(bool $minify, bool $button = false): self

Parameters:

ParameterTypeDescription
$minifyboolIndicate if code-blocks should be minified (default: false).
$buttonboolIndicate if code-block tags should include a copy button (default: false).

Return Value:

self - Return instance of of View class or BaseApplication depending where its called.

Enabling the codeblock button option adds a copy button to your HTML code blocks, allowing easy code copying for users. However, implementing the copy functionality requires JavaScript integration.


setFolder

The setFolder method can be used to achieve a Hierarchical Model-View-Controller (HMVC) structure. It allows you to organize your application's view files into subdirectories.This method informs the framework's template engine where to look for view files for an entire controller class, a specific controller method, or an entire route context.

public setFolder(string $path): self

Parameters:

ParameterTypeDescription
$pathstringDirectory path to search for view.

Return Value:

self - Return instance of of View class or BaseApplication depending where its called.

Note:Ensure the sub-folder exists within resources/views/ for setFolder to work properly.

Controller Methods: If setFolder is called in a controller's onCreate or __construct method, the specified folder will be used to search for all views related to that controller.Application Scope: If setFolder is called in the application's onCreate or __construct method, the specified folder will be used to search for all application views.Method-Specific: If setFolder is called before rendering a view within a controller method, only the view for that specific method will be searched in the specified folder.

Example

Specify a custom directory within the views folder where the controller's view handling methods will search for view files. For example, use resources/views/example/ to set a custom path.

// /app/Controllers/ExampleController.php
<?php 
namespace App\Controllers;

use \Luminova\Base\BaseController;

class ExampleController extends BaseController
{
    protected function onCreate(): void
    {
        $this->app->setFolder('example');
    }

    public function show(): int
    {
        return $this->view('show');
    }

    //...
}

In this example, the setFolder method is used to set the view folder to example, so when you call the show method, it will look for the view file in resources/views/example/show.php.

This approach helps maintain a clear and organized structure for your view files, especially in large applications with many views.


noCaching

By default when page.caching = true is enabled in env file, all views will be cached and reused. The noCaching method allows you to specify views that should be excluded from page caching making it useful for selectively excluding views from page caching, ensuring that dynamic content is always up-to-date.This can be configured either in your routes/context.php file, Application class or your view Controller class, but the recommended way is to call it within the application onCreate or __construct method.

public noCaching(string|array<int,string> $viewName): self

Parameters:

ParameterTypeDescription
$viewNamestring|array<int,string>The view name or array list of view names to exclude.

Return Value:

self - Return instance of of View class or BaseApplication depending where its called.

Example

To disable caching for specific a route method, e,g in this API example insert and edit will be excluded while allowing cache for other route methods.

<?php
$router->post('/fetch', 'ApiController::fetch');
$router->post('/insert', 'ApiController::insert');
$router->post('/edit', 'ApiController::edit');

Controller Implementation

In your Application class, within the onCreate or __construct method.

// /app/Application.php
<?php
namespace App;

use \Luminova\Base\BaseApplication;
class Application extends BaseApplication
{
    protected function onCreate(): void
    {
        $this->noCaching(['insert_view', 'edit_view']);
    }
}

Now in your controller class, when excluded views are rendered it won't be cached.

// /app/Controllers/ApiController.php
<?php
namespace App\Controllers;

use \Luminova\Base\BaseController;
class ApiController extends BaseController
{
    public function insert(): int 
    {
        return $this->view('insert_view');
    }

    public function edit(): int 
    {
        return $this->view('edit_view');
    }

    public function fetch(): int 
    {
        return $this->view('fetch_view');
    }

    // Other methods...
}

cacheOnly

Unlike noCaching method, the cacheOnly method allows you to specify which views should be exclusively cached. This is useful when you want to ensure that only certain views are stored in the cache, while all other views are excluded from caching.

public cacheOnly(string|array<int,string> $viewName): self

Parameters:

ParameterTypeDescription
$viewNamestring|array<int,string>A single view name or an array of view names to cache.

Return Value:

self - Returns the instance of the View class or BaseApplication, depending on where it's called.

Applicable Usage:

Let assume you have 100 views but want to cache only three specific views, home, about, and contact, using the noCaching method would require listing all 97 other views individually. Instead, you can simplify this by using the cacheOnly method. This method allows you to specify only the views you want to cache, while automatically ignoring the rest. By listing just the three views you want to cache, you ensure that only these are cached, and all others are excluded.


Example:

Enable caching for only 'home', 'about', and 'contact' views

// /app/Application.php
<?php 
namespace App;

use Luminova\Base\BaseApplication;

class Application extends BaseApplication
{
    protected function onCreate(): void 
    {
        $this->cacheOnly(['home', 'about', 'contact']);
    }
}

cacheable

Unlike the noCaching method that disables caching for selected views, the cacheable method allows you to disable view caching for the entire application or controller views.

If called in a controller's onCreate or __construct method, view caching will be disabled for all views within that controller.
If called in the application's onCreate or __construct method, view caching will be disabled for the entire application.

public cacheable(bool $allow): self

Parameters:

ParameterTypeDescription
$allowboolWeather to allow caching of views.

Return Value:

self - Return instance of of View class or BaseApplication depending where its called.


Example

The cacheable method can be called in the controller's or application's onCreate or __construct method.But in this example we will use Controller method to disable caching for all API routes.

// /app/Controllers/ApiController.php
<?php
namespace App\Controllers;

use \Luminova\Base\BaseController;
class ApiController extends BaseController
{
    protected function onCreate(): void
    {
        $this->app->cacheable(false);
    }

    // Other methods...
}

The cacheable method provides a straightforward way to control view caching by setting the caching status globally or for specific controllers, you can ensure that dynamic content remains current without being cached.


export

The export method allows you to inject dependencies making them accessible within your template files, controllers, and anywhere you have access to Application object.

Injections should be performed in your App\Application controller class, either after calling parent::__construct() in the constructor or within the onCreate method of your application class depending on your choice.

public export(string|object $class, ?string $alias = null, bool $initialize =true): true

Parameters:

ParameterTypeDescription
$classclass-string<\T>|class-object<\T>The class name or instance of a class to register.
$aliasstring|nullOptional class alias to use in accessing class object (default: null).
$initializeboolWhether to initialize class-string or leave it as static class (default: true).

Return Value:

true - Returns true on success, otherwise, an exception will be thrown if an error occurs.

Throws:

Examples

  1. Exporting Class without Alias

    <?php 
    $this->export(new FooClass());
  2. Exporting Class by Namespace

    If you do not want the class to be initialized, pass false as the third argument.

    <?php
    $this->export(FooClass::class);
  3. Exporting Class with Alias

    <?php 
    $this->export(FooClass::class, 'foo');

Accessing Properties

Accessing Class within the Template Files

To access class within your template files, you must use either $this or $self when view isolation is enabled.

  1. Direct Access

    <?php
    $this->FooClass->myMethod();
  2. Accessing Class by Alias

    <?php
    $this->foo->myMethod();
  3. Accessing Static Class Method

    <?php
    $this->foo::myMethod();

Accessing Class Properties within Your Controller Class

To access class properties within your controller class, use the application object.

<?php
$this->app->foo->myMethod();

Globally you can access properties anywhere that application object is available or using global helper function app().


cache

The cache method allows you to manually manage view caching, updating the view with new content or reusing the cached version on subsequent requests.The cache key generation for caches is handled automatically, so you don't need to specify cache keys manually.

Optionally, you can specify cache expiry if you don't want to use the global expiration set in the .env file.

public cache(\DateTimeInterface|int|null $expiry = null): self

Parameters:

ParameterTypeDescription
$expiry\DateTimeInterface|int|nullThe cache expiration, set to null to use default expiration from .env file.

Return Value:

self - Return instance of of View class or BaseApplication depending where its called.

Example

In this example we check if cache exist and not expired before processing heavy database operation.

*Note:* Passing different expiration other than the expiration used during cache will not take effect in checking the expiration.

// /app/Controllers/ExampleController.php
<?php
namespace App\Controllers;

use \Luminova\Base\BaseController;

class ExampleController extends BaseController
{
    protected function show(): int
    {
        $cache = $this->app->cache(60); 

        if($cache->expired()){
            $heavy = $db->doHeavyProcess();
            return $this->view('show_view', ['data' => $heavy]);
        }

        return $cache->reuse();
    }
}

The cache method offers fine-grained control over view caching, by specifying cache expiration and checking for cached content, you can optimize performance by avoiding redundant processing and ensuring that users receive the most up-to-date content when necessary.


expired

The expired method checks whether a cached item has expired, allowing you to decide whether to renew the view or reuse the cached version.

public expired(string|null $viewType = 'html'): bool

Parameters:

ParameterTypeDescription
$viewTypestring|nullThe view content extension type (default: html).

Return Value:

bool - Returns true if the cache doesn't exist or has expired.

Throws

Note:

Before calling this method, you must first call cache method instantiate it for use.

For the expiration check, we use the expiration set in env while saving cache, also don't worry about the cache key as it handled internally to save your precious time.


reuse

The reuse method renders the cached version of view content if it exists.

public reuse(): int

Return Value:

int - Returns a status code: SUCCESS if the cache exists and is rendered successfully, otherwise ERROR.

Throws


header

To optionally set customer headers which will be included in response header.

public header(string $key, mixed $value): self 

Parameters:

ParameterTypeDescription
$keystringThe header key.
$valuemixedThe header value for key.

Return Value:

self - Return instance of of View class or BaseApplication depending where its called.


headers

To optionally set customer headers at once which will be included in response header.

public headers(array $headers): self 

Parameters:

ParameterTypeDescription
$headersarray<string,mixed>The headers key-pair.

Return Value:

self - Return instance of of View class or BaseApplication depending where its called.


view

The view method allows you to specify the name and type of the view content to be rendered or returned.This method must be called before using the respond or render method.

Additionally, do not include the extension type for argument $viewName (e.g, .php, .tpl, .twg), only the file name.

public view(string $viewName, string $viewType = 'html'): self

Parameters:

ParameterTypeDescription
$viewNamestringThe view file name without extension type (e.g, index).
$viewTypestringThe view content type (default: html).

Return Value:

self - Return instance of of View class or BaseApplication depending where its called.

Throws

Supported View Content Types:

TypeDescription
htmlThe view contents is HTML format.
jsonThe view contents is JSON format.
text\|txtThe view contents is Plain text (use txt if you want to serve static content).
xmlThe view contents is XML format.
jsThe view contents is JavaScript.
cssThe view contents is CSS.
rdfThe view contents is RDF format.
atomThe view contents is Atom format.
rssThe view contents is RSS feed format.

Example

In your controller class.

// /app/Controllers/FooController.php
<?php
namespace App\Controllers;

use \Luminova\Base\BaseController;

class FooController extends BaseController
{
    public function show(): int
    {
        return $this->app->view('show_view', 'html')->render(['foo' => 'bar'], 200);
    }
}

The view method is crucial for defining the view template and content type before rendering or responding with the view content.By setting the view name and type, you ensure that the correct content is prepared and handled appropriately.


render

The render method allows you to present your application's view content to users, with additional options provided as an array of key-value pairs.These options can be accessed within the template view file using $this->_myVar or $_myVar when view isolation is enabled.If variable prefixing is disabled in /app/Config/Template.php, then you can access your options directly as variables $this->myVar or $myVar.

public render(array&lt;string,mixed&gt; $options = [], int $status = 200): int

Parameters:

ParameterTypeDescription
$optionsarray<string,mixed>Additional parameters to pass in the template file.
$statusintThe HTTP status code (default: 200 OK).

Return Value:

int - Return status code STATUS_SUCCESS or STATUS_ERROR on failure.

Throws:


respond

Unlike the render method, the respond method returns the compiled view content as a string instead of presenting it. If caching is enabled, it will store the content for later use.

public respond(array<string,mixed> $options = [], int $status = 200): string

Parameters:

ParameterTypeDescription
$optionsarray<string,mixed>Additional parameters to pass in the template file.
$statusintThe HTTP status code (default: 200 OK).

Return Value:

string - Return the compiled view contents.

Throws:


Example

In your controller class.

// /app/Controllers/FooController.php
<?php
namespace App\Controllers;

use \Luminova\Base\BaseController;
use \App\Services\Mailer;

class FooController extends BaseController
{
    public function foo(): int
    {
        $content = $this->respond(['foo' => 'bar']);
        Mailer::to('[email protected]')->send($content);
        return STATUS_SUCCESS;
    }
}

The respond method allows for greater flexibility in handling view content by returning it as a string.This is particularly useful for scenarios such as downloading, sending emails or processing the view content further before presenting it.


redirect

To transit from one view URI to another.

public redirect(string $view, int $response_code = 0): void

Parameters:

ParameterTypeDescription
$viewstringThe view name or view path to redirect to.
$response_codeintThe redirect response status code (default: 0).

Creates a relative URLs to views or files, ensure the url starts from the public root directory.These method automatically handle the base path and avoid common pitfalls with relative URLs.

For example, if the current view URL is https://example.com/some/view/foo/bar/baz and you have a link like <a href='./bra'>Bra</a>, this can lead to broken links, particularly during development.

Reason: Relative URLs like ./bra are resolved relative to the current path. In development or different directory levels, this may not point to the correct location, leading to broken links.

Recommended Practices:

  • Use predefined variables within your view files such as $this->_href or $this->_asset.
  • Utilize global functions for generating links, like href('foo') for view URLs and asset('foo') for asset URLs.
public static link(string $filename = ''): string 

Parameters:

ParameterTypeDescription
$filenamestringOptional view, path or file to prepend to root URL.

Return Value:

string - Return full URL to view or file.

Examples

To ensure links, images or asset links are not broken, you can use below method:

<?php
$this->app->link('bra'); 
//Returns: /bra

viewInfo

Retrieves information about a view file.

public viewInfo(): array

Return Value:

array<string,mixed> - Return an associative array containing information about the view file.

Return Keys:

  • location: - The full path to the view file.
  • engine: - The template engine.
  • size: - The size of the view file in bytes.
  • timestamp: - The last modified timestamp of the view file.
  • modified: - The last modified date and time of the view file (formatted as Y-m-d H:i:s).
  • dirname: - The directory name of the view file.
  • extension: - The extension of the view file.
  • filename: - The filename (without extension) of the view file.

Default View Options

When rendering views within the Luminova application, certain default view options are automatically set by default. These default options provide foundational settings for view rendering and can be leveraged to control various aspects of the rendered content.

Immutable Options

The following view options are considered immutable and cannot be overridden when rendering views:

  1. viewType (string) - Indicates the view type being rendered.
  2. active (string) - Indicate the view name which is currently been rendered.
  3. asset (string) - Alternative to create a link to asset folder <img src="<?= $this->_asset;?>images/file.png">.
  4. href (string) - Alternative to create a link to another view <a href="<?= $this->_href;?>foo">Foo</a>.
  5. ALLOW_ACCESS (true) - Constant, use this to deny access to files that only template should have access to

Mutable Options

The remaining view options can be customized and overridden based on specific rendering requirements.

  1. nocache (bool) - Optionally define view cache control to exclude view from caching.
  2. title (string) - Specifies the title of the view. If not explicitly set, the default title is derived from the active view and application name .
  3. subtitle (string) - Sets the subtitle of the view. If not provided, the subtitle is automatically generated based on the active view.