Humblee

A humble PHP framework & CMS

Templates

A template is the CMS record that connects a URL to a view file and declares which content blocks are editable on pages that use it. Every page in Humblee is assigned exactly one template.

Templates are managed in Admin > Templates.


Step 1: Create the view file

Create a PHP file in application/views/. This is the HTML structure of your page. It receives a $content variable — an associative array of content block objects — and uses Draw::content() to output each block in the right place.

<?php
declare(strict_types=1);

use Humblee\Foundation\Draw;
?>

<article class="content">
    <h1><?php Draw::content($content, 'page_title') ?></h1>
    <div class="intro">
        <?php Draw::content($content, 'intro_text') ?>
    </div>
    <div class="body-copy">
        <?php Draw::content($content, 'pagebody') ?>
    </div>
</article>

The second argument to Draw::content() is the object key of a block type. It must exactly match the object key of a block that is selected in this template's block list. If the key does not match, the helper outputs nothing silently.

Available Draw helpers

Helper Purpose
Draw::content($content, 'objectkey') Outputs the live content for a named block
Draw::metaTags($content) Outputs <title> and <meta> tags from the built-in meta_tags block

Draw::metaTags() is already called in application/views/templates/template.php for every page, so you do not need to include it in individual view files.

Inline editing

When a user with the content, publish, or admin role views the page, Draw::content() automatically wraps each block in a <div class="cms_block"> with data attributes the CMS toolbar uses to enable inline editing. Your view requires no changes to support this.


Step 2: Register the template in the CMS

Navigate to Admin > Templates and create a new template record. The two most important settings are the page type and the content blocks.

Page type: view

Use this for the majority of pages. The CMS renders your view file directly, with the page's content already loaded and passed in as $content.

Set the path field to the path of your view file relative to application/views/, without the .php extension:

about

For a file in a subdirectory like application/views/marketing/landing.php:

marketing/landing

The framework resolves this as application/views/{path}.php.

Page type: controller

Use this when the page needs to load its own data before rendering — for example, fetching records from the database, checking a condition, or preparing variables the view depends on.

You provide a controller class name and a method name. The framework instantiates App\Controller\{ClassName} and calls the specified method, passing an array of the current page state ($page, $content, $template). The method returns an HTML string which becomes the rendered page body.

In the CMS, set the controller name and action (method) in the template's path fields.

In code, create application/Controller/YourController.php:

<?php
declare(strict_types=1);

namespace App\Controller;

use Humblee\Foundation\Core;

class YourController
{
    public function index(array $templateData): string
    {
        $content = $templateData['content'];
        $page    = $templateData['page'];

        $items = \ORM::for_table('your_table')->find_many();

        return Core::view(
            _app_server_path . 'application/views/your-view.php',
            ['content' => $content, 'page' => $page, 'items' => $items]
        );
    }
}

The view file receives whatever variables you pass to Core::view(). The $content array is still available for Draw::content() calls — pass it through as shown above.

When to use each: if the page is purely content-driven, use view. If the page needs to query the database or run application logic before rendering, use controller.


Content blocks in a template

The blocks selection on a template determines which block types are editable on pages that use it. This matters for two reasons:

  1. The editor UI. When an admin opens a page's content editor, they see only the blocks listed in the template. If a block is not in the list, there is no way to populate it through the admin interface.

  2. Your view. Draw::content() can only output a block if that block has content saved in the database. A block that was never shown to editors will never have content.

The rule is: every object key you call in your view must have a corresponding block selected in the template. If your view calls Draw::content($content, 'sidebar'), the sidebar block type must be in the template's block list.

For adding multiple instances of the same block type to a single template, see Block slots.