Express Form Custom Templating

Before diving into the attribute rendering challenges outlined in the overview, let's talk a bit about what's possible by simply creating a custom template for the Express Form block. The Express Form block view template contains the following markup:

<?php defined('C5_EXECUTE') or die('Access Denied.'); ?>
<div class="ccm-block-express-form">
    <?php if (isset($renderer)) { ?>
        <div class="ccm-form">
            <a name="form<?=$bID?>"></a>

            <?php if (isset($success)) { ?>
                <div class="alert alert-success">
                    <?=$success?>
                </div>
            <?php } ?>

            <?php if (isset($error) && is_object($error)) { ?>
                <div class="alert alert-danger">
                    <?=$error->output()?>
                </div>
            <?php } ?>


            <form enctype="multipart/form-data" class="form-stacked" method="post" action="<?=$view->action('submit')?>#form<?=$bID?>">
            <?php
            print $renderer->render();

            if ($displayCaptcha) {
                $captcha = \Core::make('helper/validation/captcha');
                ?>
                <div class="form-group captcha">
                    <?php
                    $captchaLabel = $captcha->label();
                    if (!empty($captchaLabel)) {
                        ?>
                        <label class="control-label"><?php echo $captchaLabel;
                            ?></label>
                        <?php

                    }
                    ?>
                    <div><?php  $captcha->display(); ?></div>
                    <div><?php  $captcha->showInput(); ?></div>
                </div>
            <?php } ?>

            <div class="form-actions">
                <button type="submit" name="Submit" class="btn btn-primary"><?=t($submitLabel)?></button>
            </div>

            </form>

        </div>
    <?php } else { ?>
        <p><?=t('This form is unavailable.')?></p>
    <?php } ?>
</div>

Let's walk through this template.

The $renderer object comes from the block controller. It's an instance of the Concrete\Core\Express\Form\Renderer. As you can see by the way this class works in the template, it's going to be very difficult to customize its output by working with the block's custom template – because the entirety of the form's view logic is encapsulated within $renderer->render();

We'll address customizing the output of this function later. In the meantime, though, here are the bits of form functionality that can be customized by working directly with this template:

  • The outer markup of the success messages
  • The outer markup of the error messages.
  • The outer markup of the captcha
  • Any markup before or after the form itself
  • The markup containing the form
  • The submit button.

However, if you need to customize the form elements themselves (and judging by our example, we do – our custom theme's stylesheet doesn't handle bootstrap markup well) – we have to get further into the trenches, by creating a new custom context object that tells Express where to load our site's form templates from. To better understand how to write our custom context object, let's take a look at how to render an express form programmatically, and how that rendering works.