Get the FREE Ultimate OpenClaw Setup Guide →

Customizing Express Form

npx machina-cli add skill MacareuxDigital/concretecms-skills/customizing-express-form --openclaw
Files (1)
SKILL.md
4.1 KB

Customizing Express Form

The Express Form is a core block type in Concrete CMS. You can customize the appearance of Express Forms by creating custom templates and overriding the default form context.

Creating a Form Context Class

To define custom template locations for Express Forms, start by creating a custom FrontendFormContext class. This class allows you to specify a custom attribute context.

<?php

namespace Application\Express\Form\Context;

use Concrete\Core\Express\Form\Context\FrontendFormContext as CoreFrontendFormContext;

class FrontendFormContext extends CoreFrontendFormContext
{   
    public function getAttributeContext()
    {
        return new \Application\Attribute\Context\FrontendFormContext();
    }
}

Applying the Custom Form Context Class

To use your custom Form Context, you must create a custom FormController class and register it within the context registry.

<?php

namespace Application\Express\Controller;

use Application\Express\Form\Context\FrontendFormContext;
use Concrete\Core\Express\Controller\StandardController;
use Concrete\Core\Express\Form\Context\FrontendFormContext as CoreFrontendFormContext;
use Concrete\Core\Form\Context\Registry\ContextRegistry;

class FormController extends StandardController
{
    public function getContextRegistry()
    {
        return new ContextRegistry([
            CoreFrontendFormContext::class => new FrontendFormContext()
        ]);
    }
}

Register your custom controller as the standard controller for Express by adding the following code to your application's bootstrap or a package's on_start method:

$app->make(\Concrete\Core\Express\Controller\Manager::class)
    ->setStandardController(\Application\Express\Controller\FormController::class);

Customizing the Attribute Form

By using the custom FrontendFormContext class, you can define custom search paths for attribute templates.

<?php

namespace Application\Attribute\Context;

use Concrete\Core\Attribute\Context\FrontendFormContext as CoreFrontendFormContext;
use Concrete\Core\Filesystem\TemplateLocator;

class FrontendFormContext extends CoreFrontendFormContext
{
    public function __construct()
    {
        parent::__construct();
        $this->preferTemplateIfAvailable('custom');
    }
    
    public function setLocation(TemplateLocator $locator)
    {
        $locator->setTemplate('custom');
        return $locator;
    }
}

Template Overrides

With the configuration above, the following overrides become active:

  • application/attributes/attribute_handle/custom.php overrides the default concrete/attributes/attribute_handle/form.php.
  • application/elements/form/custom.php overrides the default concrete/elements/form/bootstrap5.php.

Using Custom Templates in a Package

If you are developing a package, you can point the locator to your package directory in the Attribute FrontendFormContext class:

    public function __construct()
    {
        parent::__construct();
        // Look for 'custom.php' in the package first
        $this->preferTemplateIfAvailable('custom', 'your_package_handle');
    }
    
    public function setLocation(TemplateLocator $locator)
    {
        // Enables packages/your_package_handle/elements/form/custom.php
        $locator->setTemplate(['custom', 'your_package_handle']);
        return $locator;
    }

Also, you can enable overriding elements/express/form/form/form.php in your package by adding setLocation method in the Express Form FrontendFormContext class.

    public function setLocation(TemplateLocator $locator)
    {
        $locator = parent::setLocation($locator);
        $locator->prependLocation([
            DIRNAME_ELEMENTS .
            '/' .
            DIRNAME_EXPRESS .
            '/' .
            DIRNAME_EXPRESS_FORM_CONTROLS .
            '/' .
            DIRNAME_EXPRESS_FORM_CONTROLS, // not a typo
            'your_package_handle' // Package Handle
        ]);

        return $locator;
    }

Source

git clone https://github.com/MacareuxDigital/concretecms-skills/blob/main/customizing-express-form/SKILL.mdView on GitHub

Overview

Express Form is a core block in Concrete CMS. You customize its appearance by creating a custom FrontendFormContext and a matching FormController, then overriding templates. This lets you change attribute inputs and form markup without touching core code.

How This Skill Works

You extend the core FrontendFormContext to define where templates are loaded and which attribute context to use. Then you build a FormController that returns a ContextRegistry mapping the core FrontendFormContext class to your custom one, and register this controller as the standard Express controller during startup. With template overrides in place (for example application/attributes/attribute_handle/custom.php and application/elements/form/custom.php), your custom templates are used when rendering forms.

When to Use It

  • You need a custom look for Express forms without editing core templates.
  • Building a package that ships its own Express form templates.
  • You want a custom attribute form context to control attribute templates.
  • You want to override specific Express form templates like attributes and elements.
  • You need a centralized way to activate a custom form context via a FormController.

Quick Start

  1. Step 1: Create a FrontendFormContext that extends the core context and call preferTemplateIfAvailable('custom').
  2. Step 2: Implement a FormController that returns a ContextRegistry mapping CoreFrontendFormContext::class to your FrontendFormContext, then register it as the standard Express controller in bootstrap/on_start.
  3. Step 3: Add your templates at application/attributes/attribute_handle/custom.php and application/elements/form/custom.php (and package equivalents if using a package).

Best Practices

  • Create a dedicated FrontendFormContext class in your app.
  • Use preferTemplateIfAvailable('custom') to choose your template name.
  • Implement setLocation on a TemplateLocator to point to your templates.
  • Register your FormController in the ContextRegistry and set it as the standard controller on startup.
  • Test overrides in both application and package contexts to avoid conflicts.

Example Use Cases

  • Override application/attributes/attribute_handle/custom.php to replace the default form template.
  • Override application/elements/form/custom.php to replace bootstrap5 form markup.
  • Ship package templates by placing custom.php under packages/your_package_handle/elements/form/ and configuring the locator.
  • Use preferTemplateIfAvailable and setLocation to point to package templates when packaged with a distribution.
  • Register the FormController in on_start to activate the custom context across requests.

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers