Creating a layout

Layouts define how forms look like within Reef. By default, Reef ships with the Bootstrap 4 layout, but any other layout can also be added and used.

Layout member functions

Layouts should extend the abstract class \Reef\Layout\Layout. Each layout should have a unique name returned by the getName() method, and the directory that the layout code resides in should be given by the getDir() method. Just as with components, the getDir() implementation should be something along the lines of:

public static function getDir() : string {
        return __DIR__.'/';
}

In addition, layouts have the possibility to use a number of different methods:

__construct()

The __construct() function is not used by the Layout base class, and hence can without limitations be used by the layout itself for initialization purposes.

init()

The init() function can be used to initialize the layout. It is called just before Reef starts checking the entire setup. The difference with the __construct() method is that init() receives the Reef setup object as first parameter, allowing you to use the entire Reef setup here.

getCSS() and getJS()

Just as with components, you can use the getCSS() and getJS() functions to add any (remote) CSS/JS assets the layout requires.

getConfig()

The getConfig() function should return the current configuration of the layout.

view()

The view() function should return an array of template variables that should be passed to the template parser. These will be available in Mustache using {{layout.the_var_name}}.

Template files

Naturally, for layouts most work will probably not be in the PHP code, but rather in the Mustache templates. Templates should be added for both the form view (when a user fills in the form) and the submission view (when a user views the filled in values). These two templates should be present for the form itself, allowing you to wrap all fields in some wrapping HTML, and for each component you wish to support (at least all Reef base components).

For each component layout, you should consider adding the following hook template keys to your template files:

  • [[form_label_before]] before the form label in form.mustache
  • [[form_label_append]] within the form label, after the text, in form.mustache
  • [[form_label_after]] after the form label in form.mustache
  • [[form_input_before]] before the form input in form.mustache
  • [[form_input_after]] before the form input in form.mustache
  • [[submission_label_before]] before the form label in submission.mustache
  • [[submission_label_after]] after the form label in submission.mustache
  • [[submission_input_before]] before the form input value in submission.mustache
  • [[submission_input_after]] before the form input value in submission.mustache

In addition, each component template file should have a base HTML tag <div class="form-group"> at least containing the following declarations:

<!-- for form.mustache: -->
<div class="form-group {{CSSPRFX}}field {{#field.hasErrors}}{{CSSPRFX}}invalid{{/field.hasErrors}} {{field.field_classes}}" data-{{CSSPRFX}}type="reef:the_component_name" data-{{CSSPRFX}}name="{{field.name}}" {{{field.visible}}}>
<!-- for submission.mustache: -->
<div class="form-group {{CSSPRFX}}field {{field.field_classes}}" data-{{CSSPRFX}}type="reef:the_component_name" data-{{CSSPRFX}}name="{{field.name}}" {{{field.visible}}}>

Of source, the errors and name parts are only required if they are applicable to the component in question.