Bootsole comes with many classes, called components, that extend the basic HtmlBuilder class for additional functionality. For simplicity, we denote inheritance with the ← symbol, composition with the ♦ symbol, and traits with the + symbol. Of course the relationships are not a strictly linear hierarchy; see the documentation for each class for more details.
DropdownBuilder represents a basic dropdown menu. Typically, you will want to construct it implicitly in a parent object, such as a DropdownButtonBuilder or NavDropdownBuilder object. It uses the ItemCollection trait to implement a generic group of MenuItem objects.
| Class method | Directive | Description |
|---|---|---|
| addItem | @items | Optional. An array of MenuItemBuilder objects, defined explicitly or implicitly as arrays. |
| align | @align | Optional. The alignment of the menu, relative to the parent object. Set to inherit (default), left, or right. |
MenuItemBuilder represents a generic menu item, such as that which would be found in a navigation menu or button dropdown. It renders as an <li> HTML element.
| Class method | Directive | Description |
|---|---|---|
| label | @label | Optional. The content to be displayed on this menu item. |
| url | @url | Optional. The URI that this menu item should link to. |
| active | @active | Optional. Render this item with the active class. Set to false (default) or true. |
| display | @display | Optional. Set to show (default), hidden, or disabled. |
ButtonBuilder objects create HTML5 <button> elements. In addition to the @css_classes and @data directives, they support the following class-specific directives:
| Class method | Directive | Description |
|---|---|---|
| type | @type | Optional. The type of button. There are currently four types of buttons: submit, launch, cancel, and button. submit renders a button with the type='submit' attribute. launch renders a regular button with an additional data-toggle=modal attribute, and cancel adds a data-dismiss=modal attribute. These are used primarily for buttons that launch and close Bootstrap modals. |
| name | @name | Optional. The name of the button. Used to populate the name attribute in the <button> tag. |
| label | @label | Optional. The label to be displayed on this button. |
| active | @active | Optional. Render this button with the active class. Set to false (default) or true. |
| display | @display | Optional. Set to show (default), hidden, or disabled. |
Similar to ButtonBuilder, but also contains a DropdownBuilder child object to achieve a Bootstrap button dropdown. The DropdownBuilder directives can be set directly in the definition of the DropdownButtonBuilder object.
Example:
$dbb = new BS\DropdownButtonBuilder([
"@align" => "right",
"@label" => "Press me!",
"@css_classes" => ["btn-success"],
"@items" => [
"algebra" => [
"@label" => "Algebra",
"@url" => BS\URI_PUBLIC_ROOT. "courses/algebra"
],
"calculus" => [
"@label" => "Calculus",
"@url" => BS\URI_PUBLIC_ROOT. "courses/calculus"
]
]
]);
echo $dbb->render();
Outputs:

<div class='btn-group'>
<button type='button' name='' class='btn btn-success dropdown-toggle' data-toggle='dropdown' aria-expanded='false'>
Press me! <span class='caret'></span>
</button>
<ul class='dropdown-menu dropdown-menu-right' role='menu'>
<li class=' '><a role='menuitem' class='' href='http://localhost/bootsole/public/courses/algebra'>Algebra</a></li>
<li class=' '><a role='menuitem' class='' href='http://localhost/bootsole/public/courses/calculus'>Calculus</a></li>
</ul>
</div>
ButtonDropdownAddonBuilder is identical to DropdownButtonBuilder, except that it generates a "split" dropdown menu. This allows the associated button to perform a distinct action, beyond simply opening the dropdown menu.
ButtonGroupBuilder generates a Bootstrap button group. It contains a collection of ButtonBuilder, DropdownButtonBuilder, or ButtonDropdownAddonBuilder objects, implemented via the ItemCollection trait.
Use the @items directive to define the buttons contained in the button group.
Example:
$bgb = new BS\ButtonGroupBuilder([
"@items" => [
[
"@type" => "button",
"@label" => "Do it!",
"@css_classes" => ["btn-warning"],
"@name" => "action1",
"@display" => "disabled"
],
[
"@type" => "button",
"@label" => "Do it again!",
"@css_classes" => ["btn-danger"],
"@name" => "action2"
],
[
"@type" => "button",
"@css_classes" => ["btn-danger"],
"@name" => "dropdown_addon",
"@align" => "inherit",
"@items" => [
"algebra" => [
"@label" => "Algebra",
"@url" => BS\URI_PUBLIC_ROOT. "courses/algebra"
],
"calculus" => [
"@label" => "Calculus",
"@url" => BS\URI_PUBLIC_ROOT. "courses/calculus",
"@display" => "disabled"
]
]
]
]
]);
echo $bgb->render();
Outputs:

<div class='btn-group ' >
<button type='button' name='action1' class='btn btn-warning ' disabled >
Do it!
</button>
<button type='button' name='action2' class='btn btn-danger ' >
Do it again!
</button>
<button type='button' name='dropdown_addon' class='btn btn-danger dropdown-toggle' data-toggle='dropdown' aria-expanded='false'>
<span class='caret'></span>
</button>
<ul class='dropdown-menu ' role='menu'>
<li class=' '><a role='menuitem' class='' href='http://localhost/bootsole/public/courses/algebra'>Algebra</a></li>
<li class=' disabled'><a role='menuitem' class='' href='http://localhost/bootsole/public/courses/calculus'>Calculus</a></li>
</ul>
</div>
Many components have a top-level HTML tag, such as table, form, button, etc. You can add CSS classes and data-* attributes to these components using the following directives:
@css_classes: An array of CSS class names to be applied to the component (usually the top-level tag of the component, but may be applied to other components that are more typically styled. See source code for the component.)@data: A hash of data-* attributes, mapping <name> => <value>. For example, [ "id" => "1" ] will create a data attribute data-id=1 for the component.The PageBuilder class builds a fully renderable HTML document. This will usually be your "top-level" templating object when developing websites and web applications. A PageBuilder object, in addition to the user-defined placeholders, accepts four directives: @name, @schema, @header, and @footer.
@name
Every page must have a unique name. This is used to reference the page, for example, when using the PageSchema class to automatically include relevant CSS and JS files.
@schema
The @schema directive takes a path to a JSON schema file. The schema file for pages consists of groups of pages, called manifests, and a corresponding list of paths to javascript and css files (relative to the PATH_JS_ROOT and PATH_CSS_ROOT directories):
{
"terran" : {
"pages": [
"marine",
"firebat",
"ghost"
],
"css": [
"bootstrap-3.3.1.css",
"font-awesome.min.css",
"terran.css"
],
"js": [
"jquery-1.10.2.min.js",
"bootstrap-3.3.1.js"
],
"min_css": "min/terran.min.css",
"min_js": "min/terran.min.js"
},
"zerg" : {
"pages": [
"zergling",
"hydralisk",
"ultralisk"
],
"css": [
"bootstrap-3.3.1.css",
"font-awesome.min.css",
"zerg.css"
],
"js": [
"jquery-1.10.2.min.js",
"bootstrap-3.3.1.js"
],
"min_css": "min/zerg.min.css",
"min_js": "min/zerg.min.js"
},
"default" : {
"pages": [
"about",
"contact"
],
"css": [
"bootstrap-3.3.1.css",
"font-awesome.min.css"
],
"js": [
"jquery-1.10.2.min.js",
"bootstrap-3.3.1.js"
],
"min_css": "min/default.min.css",
"min_js": "min/default.min.js"
}
}
When a PageBuilder object is rendered, the schema file will be searched for a manifest group that matches the page's name. If found, it will automatically include the specified CSS and JS files into the <head> and <footer> elements, respectively. If a manifest is not found, the default manifest will be used. The default schema file is in schema/pages/pages.json.
Schemas can also be used to quickly toggle minified/merged Javascript and CSS for production environments. When the global constant JS_DEV in bootsole/config-bootsole.php is set to false, the single javascript file specified in min_js will be used instead of the files specified in js. Likewise, the CSS file specified in min_css will be used if CSS_DEV is set to false. To automatically generate the minified CSS and JS for each manifest group, use the script provided in build/build.php. The build script should only be used on the development server, immediately before pushing to the production server. This script requires write access to the directories in which the minified JS and CSS files are to be written; consult your server manual for more information on setting directory permissions for PHP.
For more information about minified Javascript and CSS, see Minification.
@header
Objects of type PageHeaderBuilder are used to represent the <head> block of a page. PageBuilder will look for a special placeholder in the page template, _header, to insert the rendered header. Therefore, any custom templates you write for PageBuilder should have a _header placeholder!
PageHeaderBuilder objects themselves have one directive, @css_includes, which represent the manifest group to be used in rendering the CSS. Typically there is no need to specify this directive explicitly - PageBuilder will do it automatically for you when it constructs the page!
@footer
Objects of type PageFooterBuilder are used to represent the <footer> block of a page. PageBuilder will look for a special placeholder in the page template, _footer, to insert the rendered footer.
They have one directive, @js_includes, which represent the manifest group to be used in rendering the JS. Typically there is no need to specify this directive explicitly - PageBuilder will do it automatically for you when it constructs the page!
pages/page-default.html
<!DOCTYPE html>
<html lang="en">
{{_header}}
<body>
<div class="container" role="main">
<h1>{{heading_main}}</h1>
<p>{{content}}</p>
</div>
{{_footer}}
</body>
</html>
...
require_once("config-site.php");
$header_content = [
"author" => "Alex Weissman",
"site_title" => SITE_TITLE,
"page_title" => "Simple, nested templating for rendering Bootstrap themed pages with PHP",
"description" => "A sample page for Bootsole",
"favicon_path" => BS\URI_PUBLIC_ROOT . "css/favicon.ico"
];
$content = [
"@header" => $header_content,
"@name" => "test",
"heading_main" => "Welcome to Bootsole",
"content" => "Hey, I'm the content!"
];
$pb = new BS\PageBuilder($content);
echo $pb->render();
Output:

<!DOCTYPE html>
<html lang="en">
<!-- Common header includes for all account pages -->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="A sample page for Bootsole">
<meta name="author" content="Alex Weissman">
<title>Bootsole | Simple, nested templating for rendering Bootstrap themed pages with PHP</title>
<!-- Favicon -->
<link rel="icon" type="image/x-icon" href="/bootsole/css/favicon.ico" />
<link href='/bootsole/css/bootstrap-3.3.1.css' rel='stylesheet'>
<link href='/bootsole/css/bootstrap-custom.css' rel='stylesheet'>
<link href='/bootsole/css/font-awesome.min.css' rel='stylesheet'>
<link href='/bootsole/css/tablesorter/theme.bootstrap.css' rel='stylesheet'>
<link href='/bootsole/css/tablesorter/jquery.tablesorter.pager.css' rel='stylesheet'>
<!-- Conditional formatting -->
</head>
<body>
<div class="container" role="main">
<h1>Welcome to Bootsole</h1>
<p>Hey, I'm the content!</p>
</div>
<footer>
<div class="container">
<p>
<a href="https://github.com/alexweissman/bootsole">Bootsole</a>, 2015
</p>
</div>
</footer>
<script src='/bootsole/js/jquery-1.10.2.min.js'></script>
<script src='/bootsole/js/bootstrap-3.3.1.js'></script>
<script src='/bootsole/js/bootsole.js'></script>
<script src='/bootsole/js/tablesorter/jquery.tablesorter.min.js'></script>
<script src='/bootsole/js/tablesorter/tables.js'></script>
<script src='/bootsole/js/tablesorter/jquery.tablesorter.pager.min.js'></script>
<script src='/bootsole/js/tablesorter/jquery.tablesorter.widgets.min.js'></script>
</body>
</html>
The NavbarBuilder class constructs a Bootstrap navbar for a page. A navbar contains a list of components, specified by the @components directive:
$nb = new BS\NavbarBuilder([
"brand_label" => "Bootsole is Great!",
"brand_url" => "http://github.com/alexweissman/bootsole",
"@components" => [
"destroy" => [
"@type" => "button",
"@css_classes" => ["btn-danger"],
"@label" => "Self-Destruct!"
],
// Implicitly declaring a NavBuilder object
"main-menu" => [
"@type" => "nav",
"@align" => "right",
"@items" => [
"home" => [
"@active" => "true",
"@label" => "Home",
"@url" => BS\URI_PUBLIC_ROOT
],
"about" => [
"@label" => "About",
"@url" => BS\URI_PUBLIC_ROOT. "about"
],
"contact" => [
"@label" => "Contact",
"@url" => BS\URI_PUBLIC_ROOT. "contact"
]
]
]
]
]);
Outputs:

<!-- Fixed navbar -->
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#main-nav-default" aria-expanded="false" aria-controls="main-nav-default">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class='navbar-brand' href='http://github.com/alexweissman/bootsole'>Bootsole is Great!</a>
</div>
<div id="main-nav-default" class="navbar-collapse collapse">
<button type='button' class='btn btn-danger navbar-btn '>Self-Destruct!</button>
<ul class='nav navbar-nav navbar-right'>
<li class='active'><a href='/bootsole/'>Home</a></li>
<li class=''><a href='/bootsole/about'>About</a></li>
<li class=''><a href='/bootsole/contact'>Contact</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
The default navbar is a fixed top navbar specified in templates/navs/main-nav-default, but you may adapt this template to your own design needs.
@components
NavbarBuilder currently supports the following types of Bootstrap components:
NavBuilder class.NavFormBuilder class.NavButtonBuilder classNavTextBuilder classNavLinkBuilder classEach component is built off of the abstract NavComponentBuilder class. To declare a component implicitly, rather than explicitly defining NavBuilder, NavFormBuilder, etc objects, use an array containing the @type directive:
| @type | object created |
|---|---|
| nav | NavBuilder |
| form | NavFormBuilder |
| button | NavButtonBuilder |
| text | NavTextBuilder |
| link | NavLinkBuilder |
All NavComponentBuilder objects support the @align directive, which describes how the component will be aligned within the navbar. Permitted values include left, right, and inherit. All templates for classes derived from NavComponentBuilder should use a _align placeholder, where the corresponding component will try to place the CSS classes for alignment.
All NavComponentBuilder objects support the @css_classes and @data directives.
NavBuilder builds a collection of navigation items, which will be structured as an unordered list. The items are an array of NavItemBuilder objects, specified using the @items directive. Each NavItemBuilder object may be declared explicitly, or you can implicitly define them in nested subarrays:
$navb = new BS\NavBuilder([
"@align" => "right",
"@items" => [
"home" => [
"@active" => "true",
"@label" => "Home",
"@url" => BS\URI_PUBLIC_ROOT
],
"about" => [
"@label" => "About",
"@url" => BS\URI_PUBLIC_ROOT. "about"
],
"contact" => [
"@label" => "Contact",
"@url" => BS\URI_PUBLIC_ROOT. "contact"
]
]
]);
Output:
<ul class='nav navbar-nav navbar-right'>
<li class='active'><a href='/bootsole/'>Home</a></li>
<li class=''><a href='/bootsole/about'>About</a></li>
<li class=''><a href='/bootsole/contact'>Contact</a></li>
</ul>
Every item in a NavBuilder has a name. This is automatically drawn from the keys in the @items array, or specified when you add the item via the addItem($name, $content) function.
Call the function setActiveItem($name) on a NavBuilder object to set the a nav item as active. All other items in the nav will automatically become inactive, so that only one menu item will be active at any time.
Use the function getItem($name) to get an item by name.
The items in a NavBuilder are represented using the NavItemBuilder and NavDropdownBuilder classes.
@active: Optional. Make the specified item be highlighted as active in the nav. Set to false (default) or true.@display: Optional. Setting @display to disabled will make the specified item be disabled, while setting it to hidden will make it not show up at all.A NavDropdownBuilder builds a dropdown with submenu items. It is called in the same way as NavBuilder, with an @items directive specifying the child NavItemBuilder objects.
NavFormBuilder wraps a form in a simple div with the navbar-form class. Bootstrap will automatically render the content as an inline form:
$navform = new BS\NavFormBuilder([
"@align" => "right",
"@form" => '<form role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>*
<button type="submit" class="btn btn-default">Submit</button>
</form>'
]);
Output:
<div class='navbar-form navbar-right'>
<form role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>*
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
@form: The form, as a string or a FormBuilder object.NavButtonBuilder renders a button with the navbar-btn CSS class. Bootstrap will automatically align the button in the navbar:
$navbtn = new BS\NavButtonBuilder([
"@css_classes" => ["btn-danger"],
"@label" => "Self-Destruct!"
]);
Output:
<button type='button' class='btn navbar-btn btn-danger '>Self-Destruct!</button>
@label: The text for this button. Required.NavTextBuilder wraps the specified text in a <p> tag with the navbar-text CSS class. This formats it for display in the navbar:
$navtext = new BS\NavTextBuilder([
"@text" => "Whazzup!!!"
]);
Output:
<p class='navbar-text '>Whazzup!!!</p>
@text: The text for this item. Required.NavLinkBuilder creates a non-nav link in your navbar, using the navbar-link CSS class:
$navlink = new BS\NavLinkBuilder([
"@label" => "UserFrosting",
"@url" => "https://www.userfrosting.com"
]);
Output:
<p class='navbar-text '><a href='https://www.userfrosting.com' class='navbar-link'>UserFrosting</a></p>
@label: The text for this link. Required.@url : The url for this link. Required.The TableBuilder class allows you to set templates for each column of a table, via the @columns directive. The content of the table is then supplied with an array of HtmlBuilder objects via the @rows directive. The column templates will then be used to render each data row.
The default table template, templates/tables/table-tablesorter-default, uses the tablesorter jQuery library to render dynamic, sortable, filterable, paginated tables.
A TableBuilder object is constructed as follows:
$content = [
"@columns" => [...]
"@rows" => [...]
];
Each member of the @columns array is a TableColumnBuilder object. A TableColumnBuilder object is a special templating class that renders the column header, but also maintains information about their corresponding cells in each row. It can be declared in the same way as any other HtmlBuilder object:
$column_content = [
'@label' => 'Students',
'@sorter' => 'metanum',
'@sort_field' => 'num_students',
'@intial_sort_direction' => 'asc',
'@cell_template' => "<a class='btn btn-success' href='students.php?teacher_id={{teacher_id}}'>{{num_students}}</a>",
'@empty_field' => 'num_students',
'@empty_value' => '0',
'@empty_template' => "Zero"
];
$column_template = "<h4>{{_label}}</h4>";
$column = new BS\TableColumnBuilder($column_content);
$column->setTemplate($column_template);
Thus when $column->render() is called, the template <h4>{{_label}}</h4> will be rendered with the supplied value of the @label directive. To set a template for the actual cell content of this column, use the @cell_template directive. When the parent TableBuilder object is rendered, it will attempt to replace the placeholders in @cell_template with the corresponding values in each row as specified by the @rows directive. In this way, TableBuilder can construct the entire table.
You can also specify an alternative template to use when a certain field in a row matches a certain value. This is useful when you want a cell to render differently when a value is 0 or empty. This is done using the @empty_template, @empty_field, and @empty_value directives. When a row has a field, as specified by @empty_field, whose value is equal to @empty_value, the @empty_template will be used instead of the usual @cell_template template.
For tablesorter tables, you can also specify sorting rules, using the @sorter and @sort_field directives. The field specified in @sort_field specifies which row field to sort on, and the @sorter specifies the sorting rule to be used. Use metatext for sorting alphabetically, and metanum to sort numerically. One easy way to sort by time is to use the metanum sorter in conjunction with a UTC timestamp as the @sort_field. Note that the field specified in @sort_field does not actually need to be rendered by the templates.
To set an initial sort direction, set the @initial_sort_direction directive to asc or desc. This will cause the table to be automatically sorted on the column in the specified direction upon page load.
You can of course define @columns and @rows directly in the table content array, without explicitly creating TableColumnBuilder and HtmlBuilder objects:
$table_content = [
"@columns" => [
"info" => [
"@label" => "Teacher",
"@sorter" => "metatext",
"@sort_field" => "user_name",
"@initial_sort_direction" => "asc",
"@cell_template" => "
<div class='h4'>
<a href='user_details.php?id={{teacher_id}}'>{{display_name}} ({{user_name}})</a>
</div>
<div>
<i>{{title}}</i>
</div>
<div>
<i class='fa fa-envelope'></i> <a href='mailto:{{email}}'>{{email}}</a>
</div>"
],
"num_students" => [
"@label" => "Students",
"@sorter" => "metanum",
"@sort_field" => "num_students",
"@cell_template" => "<a class='btn btn-success' href='students.php?teacher_id={{teacher_id}}'>{{num_students}}</a>",
"@empty_field" => "num_students",
"@empty_value" => "0",
"@empty_template" => "Zero"
],
"students" => [
"@label" => "Student List",
"@sorter" => "metanum",
"@sort_field" => "num_students",
"@cell_template" => "{{students}}",
"@empty_field" => "students",
"@empty_value" => [],
"@empty_template" => "<i>None</i>"
]
],
"@rows" => [
"1" => [
"teacher_id" => "1",
"user_name" => "socrizzle",
"display_name" => "Socrates",
"title" => "Big Cheese",
"email" => "socrates@athens.gov",
"num_students" => "2",
"students" => [
"@template" => "<a class='btn btn-success' href='student_details.php?student_id={{student_id}}'>{{display_name}}</a>",
"@array" => [
"A" => [
"student_id" => "1",
"display_name" => "Xenophon"
],
"B" => [
"student_id" => "2",
"display_name" => "Plato"
]
]
]
],
"2" => [
"teacher_id" => "2",
"user_name" => "seamus",
"display_name" => "Seamus",
"title" => "Beanmaster",
"email" => "seamus@cardboardbox.com",
"num_students" => "0",
"students" => []
],
"3" => [
"teacher_id" => "3",
"user_name" => "plato",
"display_name" => "Plato",
"title" => "Idealist",
"email" => "plato@athens.gov",
"num_students" => "1"
]
]
];
$table = new BS\TableBuilder($table_content);
Output:

The core FormComponentCollectionBuilder class allows building forms of arbitrary complexity. A FormComponentCollectionBuilder is basically a collection of form components (derived classes of the abstract FormComponentBuilder class), and/or other FormComponentCollectionBuilder objects. In this way components can be grouped, reused, and repeated in the same form without the need for separate placeholders for each group. The FormBuilder class is simply the highest-level (and often, only) collection of form components. For example, a form might be structured as such:
Components can be added to a FormComponentCollectionBuilder object via the @components directive (array), or via the addComponent method. Each component can be a derived type of FormComponentBuilder object, or another FormComponentCollectionBuilder object. Many component objects can be declared implicitly via a subarray.
FormComponentCollectionBuilder also provides for some collection-wide properties, which can be set via the class methods or through array directives:
| Class method | Directive | Description |
|---|---|---|
labelWidth |
@label_width | Optional. The width of form group labels, in columns (1-12), for horizontal forms |
layout |
@layout | Optional. The layout for the form. 'vertical' (default), 'horizontal', or 'inline'. |
name |
@name | Optional. The name of the collection. Used to populate the name attribute in the top-level HTML tag. |
validators |
@validators | Optional. An array mapping field names to strings containing data-* FormValidation rules. |
values |
@values | Optional. An array mapping field names to their initial values. |
When a FormComponentCollectionBuilder is rendered, the layout and label_width will be passed along to its components. To mix and match layouts, you can use separate FormComponentCollectionBuilder components in a parent FormComponentCollectionBuilder or FormBuilder object.
Also on rendering, the appropriate validator and value will be passed along to the component with the corresponding name. This allows you to set the values and validators for all the components in one convenient array. This is especially useful when you want to load a set of data into a pre-existing form (for example, to update a database record), and for loading validation information from a validation schema. To load validation rules from a schema, you can use the Fortress package and create a ClientSideValidator object.
The FormBuilder class extends the FormComponentCollectionBuilder class, and inherits all the functionality of that class. It also includes two additional directives, @method and @action, which correspond to the attributes of the top-level <form> tag.
Example
$csv = new Fortress\ClientSideValidator(BS\PATH_SCHEMA . "forms/form-login.json", "en_US");
$fb = new BS\FormBuilder([
"@action" => "https://mysite.com/login/auth",
"@layout" => "horizontal",
"@label_width" => 2,
"@components" => [
'user_name' => [
'@type' => 'text',
'@label' => 'Username',
'@placeholder' => 'Please enter the user name'
],
'password' => [
'@type' => 'password',
'@label' => 'Password',
'@placeholder' => 'Please enter your password'
],
'submit' => new BS\FormButtonBuilder([
"@type" => "submit",
"@label" => "Log In",
"@css_classes" => ["btn-primary", "btn-lg"]
])
],
"@validators" => $csv->clientRules()
], "forms/form-login.html") ;
$fb->render();
Outputs:

<form name='' method='post' action='https://mysite.com/login/auth' class='form-horizontal'>
<div class='row'>
<div class='col-md-6 col-md-offset-3'>
<div class='form-group '>
<label class='control-label col-sm-2'>Username</label>
<div class='col-sm-10'>
<input type='text' class='form-control ' name='user_name' autocomplete='off' value='' placeholder='Please enter the user name' data-fv-notempty=true data-fv-notempty-message="'User name' is required." >
</div>
</div>
<div class='form-group '>
<label class='control-label col-sm-2'>Password</label>
<div class='col-sm-10'>
<input type='password' class='form-control ' name='password' autocomplete='off' value='' placeholder='Please enter your password' data-fv-notempty=true data-fv-notempty-message="'Password' is required." >
</div>
</div>
<div class='vert-pad'>
<button type='submit' name='submit' class='btn btn-primary btn-lg ' data-loading-text='Please wait...' >
Log In
</button>
</div>
</div>
</div>
</form>
| Class method | Directive | Description |
|---|---|---|
action |
@action | The URI to which this form should submit. |
method |
@method | Optional. Specifies the HTTP method to use when sending form data (get (default) or post). |
FormComponentBuilder is an abstract class that represents a form component. Form components include input fields, checkboxes, buttons, and more. As it is an abstract class, you cannot instantiate a FormComponentBuilder object directly. Instead you must instantiate one of its derived classes, which include FormGroupBuilder, FormFieldBuilder, and FormButtonBuilder.
A generic FormComponentBuilder object has four directives:
| Class method | Directive | Description |
|---|---|---|
| name | @name | Required. The name of the component. Used to populate the name attribute in the appropriate HTML tag (<input>, <select>, etc.) |
| value | @value | Optional. The current value of the field. |
| default | @default | Optional. The default value of the field. Used as the value if value has not been set before rendering. |
| validator | @validator | Optional. The FormValidation validator for the field, as a string of data-* attributes. |
The @name directive can be set explicitly when instantiating an object, or implicitly from an array key if it is defined implicitly. In the previous example, notice that the components did not have their @name directives set. Thus, they automatically took their names from the keys of the @components array (user_name, password, and submit).
The FormGroupBuilder class inherits from FormComponentBuilder. It serves as a wrapper for FormFieldBuilder objects, and implements Bootstrap's form groups. It also allows for associating a label with the field.
In most cases, you should create fields using the FormGroupBuilder class for optimal spacing and alignment. However if you really need to, you can still use naked FormFieldBuilder object as as components.
FormGroupBuilder objects have five directives, in addition to the ones they inherit from FormComponentBuilder:
| Class method | Directive | Description |
|---|---|---|
| --- | @type | Required. Specifies what type of FormFieldBuilder object to create for this group. Can be any of text, password, number, email, url, color, select, select2, selecttime, hidden, textarea, checkbox, radio, switch, toggle, bootstrapradio. |
| label | @label | Optional. The label for the field. Automatically displayed above the field (vertical forms), to the left (horizontal forms), or hidden (inline forms). |
| display | @display | Optional. Display mode for the field. Can be show (default), disabled, readonly, or hidden. If set to hidden, the entire group will render as a null string. Useful for dynamically specifying which fields to render. |
| labelWidth | @label_width | Optional. The width of the form group label, in columns (1-12), for horizontal forms. Inherits from the parent FormFieldCollectionBuilder object if not explicitly set. |
| layout | @layout | Optional. The layout for the group. 'vertical' (default), 'horizontal', or 'inline'. Inherits from the parent FormFieldCollectionBuilder object if not explicitly set. |
Every FormGroupBuilder object contains exactly one field object (derived classes of FormFieldBuilder). When a FormGroupBuilder is instantiated, the field object is automatically created using the @type directive of the FormGroupBuilder parent object, along with any additional content. It is possible to manually override the field object using the field method.
FormFieldBuilder is an abstract class that represents a form field object. These include all fields based on the HTML <input> tag (including checkboxes and radio buttons), as well as <textarea> and <select> fields. Bootsole does not currently support fields based on the <datalist>, <keygen>, or <output> tags (instead of <datalist>, we provide templating for the extremely popular select2 widget).
In addition to the directives that it inherits from FormComponentBuilder, FormFieldBuilder includes the following directives:
| Class method | Directive | Description |
|---|---|---|
| display | @display | Optional. Display mode for the field. Can be show (default), disabled, readonly, or hidden. If set to hidden, the entire group will render as a null string. Useful for dynamically specifying which fields to render. Inherits from the parent FormGroupBuilder object if not explicitly set. |
| placeholder | @placeholder | Optional. A placeholder for the field. Used to populate the placeholder attribute of the HTML tag. |
| prepend | @prepend | Optional. Only available for fields that use the FormFieldAddonable trait. Sets the content for an input group addon in front of the field, and tells the FormFieldBuilder object to automatically wrap the field and addon in an input group. |
| append | @append | Optional. Only available for fields that use the FormFieldAddonable trait. Sets the content for an input group addon after the field and tells the FormFieldBuilder object to automatically wrap the field and addon in an input group. |
Although FormFieldBuilder is an abstract class, it provides the static "factory" method generate for generating different types of derived classes. This is mainly used
by FormGroupBuilder objects to determine what kind of field to create based on the @type directive. It takes two parameters, $type and $content, and returns the appropriate kind of FormFieldBuilder object. $type can be any of the types mentioned in the FormGroupBuilder documentation. $content is an array containing directives and placeholders for the new object.
FormTextFieldBuilder is the most generic type of <input>-based field that can be instantiated. It simply generates an HTML <input> element of type text, and uses the relevant FormComponentBuilder and FormFieldBuilder directives to populate the attributes.
Example:
$ftfb = new BS\FormTextFieldBuilder([
'@name' => 'user_name',
'@display' => 'disabled',
'@placeholder' => 'Please enter the user name'
]);
$ftfb->render();
Outputs:
<input type='text' class='form-control ' name='user_name' autocomplete='off' value='' placeholder='Please enter the user name' disabled>
If you define it implicitly within a FormGroupBuilder, you can add a label and wrap it in a form group:
$ftfb = new BS\FormGroupBuilder([
'@type' => 'text',
'@name' => 'user_name',
'@display' => 'disabled',
'@label' => 'Username',
'@placeholder' => 'Please enter the user name'
]);
$ftfb->render();
Outputs:

<div class='form-group '>
<label class='control-label '>Username</label>
<input type='text' class='form-control ' name='user_name' autocomplete='off' value='' placeholder='Please enter the user name' disabled>
</div>
FormPasswordFieldBuilder renders an <input> tag with the type='password' attribute. It is otherwise identical to a FormTextFieldBuilder object.
FormNumberFieldBuilder renders an <input> tag with the type='number' (integer only) attribute. It is otherwise identical to a FormTextFieldBuilder object.
FormEmailFieldBuilder renders an <input> tag with the type='email' attribute. It is otherwise identical to a FormTextFieldBuilder object.
FormUrlFieldBuilder renders an <input> tag with the type='url' attribute. It is otherwise identical to a FormTextFieldBuilder object.
FormColorFieldBuilder renders an <input> tag with the type='color' attribute. It is otherwise identical to a FormTextFieldBuilder object. Note that the built-in color picker is not supported by all browsers.
FormSearchFieldBuilder renders an <input> tag with the type='search' attribute. It is otherwise identical to a FormTextFieldBuilder object.
FormHiddenFieldBuilder renders an <input> tag with the type='hidden' attribute. It is otherwise identical to a FormTextFieldBuilder object, except that it does not support the @prepend, @append, or @placeholder directives.
FormTextAreaFieldBuilder creates a <textarea> field. The API is basically the same as for FormTextFieldBuilder, except that it offers the @rows directive and rows method. This is used to set the number of text rows to display in the field. Note that we do not offer the cols method, because Bootstrap by default renders textareas to take up the entire width of the container. For a narrower field, you should use a container class, for example a Bootstrap grid element.
FormSelectFieldBuilder renders a <select> element, along with one or more child <option> elements.
Each child item is represented using a FormFieldOptionBuilder object. These can be defined explicitly, or implicitly as arrays. Items can be set through the @items directive or through the items method. FormSelectFieldBuilder uses the FormFieldSelectable trait to implement adding, getting, and selecting items.
Options can be selected in three ways: via the selectItem method, the selectItems method, or by the value method. selectItem takes the name of the option (based on its array key in @items, and selects exactly one item. selectItems takes a value, and selects all options that have that value. value serves as a wrapper for selectItems, but also sets the field multiple attribute if an array of values is specified.
In addition to the directives that it inherits from FormComponentBuilder, FormSelectBuilder includes the following directives:
| Class method | Directive | Description |
|---|---|---|
| multiple | @multiple | Optional. Set to false (default) or true. Determines whether it is possible select more than one option. |
| items | @items | Optional. An array of FormFieldOptionBuilder objects, defined explicitly or as arrays. |
| itemClasses | @item_classes | Optional. An array of additional CSS classes to be applied to each child option. A shortcut for applying CSS classes individually to each element. |
Example:
$fsfb = new BS\FormSelectFieldBuilder([
'@type' => 'select',
'@layout' => 'horizontal',
'@label_width' => '2',
'@label' => 'Title',
'@items' => [
'ta' => [
'@label' => 'Teaching Assistant'
],
'street_lord' => [
'@label' => 'Street Lord'
],
'adjunct' => [
'@label' => 'Adjunct Instructor'
],
'assistant' => [
'@label' => 'Assistant Professor'
],
'associate' => [
'@label' => 'Associate Professor'
],
'professor' => [
'@label' => 'Professor'
],
'emeritus' => [
'@label' => 'Professor Emeritus'
]
],
'@default' => 'emeritus',
'@prepend' => "<span class='input-group-addon'><i class='fa fa-fw fa-mortar-board'></i></span>"
]);
Outputs:

<div class='form-group '>
<label class='control-label col-sm-2'>
Title
</label>
<div class='col-sm-10'>
<div class='input-group'>
<span class='input-group-addon'><i class='fa fa-fw fa-mortar-board'></i></span>
<select class='form-control ' name='title' autocomplete='off' placeholder=''>
<option class='' value='ta' >Teaching Assistant</option>
<option class='' value='street_lord' >Street Lord</option>
<option class='' value='adjunct' >Adjunct Instructor</option>
<option class='' value='assistant' >Assistant Professor</option>
<option class='' value='associate' >Associate Professor</option>
<option class='' value='professor' >Professor</option>
<option class='' value='emeritus' selected>Professor Emeritus</option>
</select>
</div>
</div>
</div>
This class builds a selectable item in a FormSelectFieldBuilder, FormSelect2FieldBuilder, FormSelectTimeFieldBuilder, FormToggleFieldBuilder, or FormBootstrapRadioBuilder object. It uses the FormFieldSelectableItem trait to implement the following directives:
| Class method | Directive | Description |
|---|---|---|
| itemValue | @item_value | Optional. The value associated with this particular item. If not specified, will be automatically taken from the key in the @items array of the parent object. |
| label | @label | Optional. The label to display for this option. If not specified, will default to the item value. |
| title | @title | Optional. Sets the title attribute for this option. Useful for creating tooltips for the FormFieldBootstrapRadioBuilder components. |
| selected | @selected | Optional. Specifies whether this item should be set as a currently selected item. Set to false (default) or true. |
There is typically no need to define these objects explicitly. Instead, they can be defined implicitly in the @items directive of a parent object. Items with an item_value that matches the parent value will be automatically selected upon construction.
This class is identical to FormSelectFieldBuilder, except that it adds the select2 class to the <select> tag. The select2 class tells Bootsole to initialize the field as a select2 element. If you aren't familiar with Select2, it is a extremely popular enhancement for standard <select> elements. From their website:
Select2 gives you a customizable select box with support for searching, tagging, remote data sets, infinite scrolling, and many other highly used options.
Note: to use FormSelect2FieldBuilder, you will need the relevant CSS and JS files. You can download them from the Select2 website, or use the version included with this repository in the public directory. You will also need the following JS code to perform basic initialization:
// Initialize select2 dropdowns, if enabled
if (jQuery().select2){
$('.select2').select2();
} else {
console.error("The select2 plugin has not been added.");
}
This code is included already in public/js/bootsole.js.
FormSelectTimeFieldBuilder is a special modification of FormSelectFieldBuilder that generates a list of times in a specific range, with a specified increment. It will try to render as a select2 field, if the library is available. It uses the following additional directives:
| Class method | Directive | Description |
|---|---|---|
| timeStart | @time_start | Optional. The start time. Should be a time that can be parsed by strtotime. Default is 12:00 am. |
| timeEnd | @time_end | Optional. The end time. Should be a time that can be parsed by strtotime. Default is 11:45 pm. |
| timeIncrement | @time_increment | Optional. The time increment, in minutes. Default is 15. |
Example:
$fstb = new BS\FormGroupBuilder([
'@type' => 'selecttime',
'@layout' => 'horizontal',
'@label' => 'Wakeup Call',
'@prepend' => "<span class='input-group-addon'><i class='fa fa-fw fa-clock-o'></i></span>",
'@time_start' => '5:00 am',
'@time_end' => '12:00 pm',
'@time_increment' => 30,
'@placeholder' => 'When?',
'@default' => '11:00 am'
]);
echo $fstb->render();
Outputs:

<div class='form-group '>
<label class='control-label col-sm-2'>Wakeup Call</label>
<div class='col-sm-10'>
<div class='input-group'>
<span class='input-group-addon'><i class='fa fa-fw fa-clock-o'></i></span>
<select class='form-control select2 ' name='wakeup' autocomplete='off' placeholder='When?' >
<option></option>
<option class='' value='5:00 am' >5:00 am</option>
<option class='' value='5:30 am' >5:30 am</option>
<option class='' value='6:00 am' >6:00 am</option>
<option class='' value='6:30 am' >6:30 am</option>
<option class='' value='7:00 am' >7:00 am</option>
<option class='' value='7:30 am' >7:30 am</option>
<option class='' value='8:00 am' >8:00 am</option>
<option class='' value='8:30 am' >8:30 am</option>
<option class='' value='9:00 am' >9:00 am</option>
<option class='' value='9:30 am' >9:30 am</option>
<option class='' value='10:00 am' >10:00 am</option>
<option class='' value='10:30 am' >10:30 am</option>
<option class='' value='11:00 am' selected>11:00 am</option>
<option class='' value='11:30 am' >11:30 am</option>
<option class='' value='12:00 pm' >12:00 pm</option>
</select>
</div>
</div>
</div>
FormToggleFieldBuilder generates a set of checkboxes or radio buttons, styled as Bootstrap toggle buttons. It extends the FormSelectFieldBuilder class, so each item is a FormFieldOptionBuilder object. However, the items are rendered as <input> elements rather than <option> elements.
The @multiple directive determines whether the items are rendered as <input> elements with type=checkbox or type=radio . The @display and @name directives are automatically passed down to the child elements upon rendering.
Example:
$ftfb = new BS\FormGroupBuilder([
'@type' => 'toggle',
`@name' => 'beard',
'@label' => 'Beard',
'@multiple' => "true",
'@prepend' => "<span class='input-group-addon'><i class='fa fa-fw fa-trophy'></i></span>",
'@item_classes' => [
'btn-primary'
],
'@items' => [
'fluffy' => [
'@label' => 'Fluffy'
],
'scraggly' => [
'@label' => 'Scraggly'
],
'pointy' => [
'@label' => 'Pointy'
]
],
'@display' => 'disabled'
]);
echo $ftfb->render();
Outputs:

<div class='form-group '>
<label class='control-label '>Beard</label>
<div class='input-group'>
<span class='input-group-addon'><i class='fa fa-fw fa-trophy'></i></span>
<div class='btn-group' data-toggle='buttons'>
<label class='btn btn-primary disabled'>
<input class='form-control' type='checkbox' name='beard' value='fluffy' disabled> Fluffy
</label>
<label class='btn btn-primary disabled'>
<input class='form-control' type='checkbox' name='beard' value='scraggly' disabled> Scraggly
</label>
<label class='btn btn-primary active disabled'>
<input class='form-control' type='checkbox' name='beard' value='pointy' disabled checked> Pointy
</label>
</div>
</div>
</div>
Note: Bootstrap toggle buttons require some custom CSS to properly render options that are both selected and disabled. Please see public/css/bootstrap-custom.css.
FormCheckboxFieldBuilder renders an <input> tag with the type='checkbox' attribute. It uses the same directives as FormFieldBuilder, but includes the following additional directives:
| Class method | Directive | Description |
|---|---|---|
| itemValue | @item_value | Required. The value associated with this particular checkbox. |
| text | @text | Optional. The text to display to the right of the checkbox. |
| title | @title | Optional. Sets the title attribute for this option. |
| selected | @selected | Optional. Specifies whether this item should be set as a currently selected item. Set to false (default) or true. |
You can use the value method on a checkbox as well. However, it works differently from the way value would work on say, a text field. For checkboxes (and radios), the value function will check whether the parameter is equal to the item_value for the checkbox. If so, it will set the checkbox to selected. If not, it will deselect the checkbox. This allows you to preset checkboxes in the same way as you would other fields.
FormRadioFieldBuilder renders an <input> tag with the type='radio' attribute. It is otherwise identical to a FormCheckboxFieldBuilder object.
FormSwitchFieldBuilder is the same as FormCheckboxFieldBuilder, but adds the switch class to the <input> element. The switch class tells Bootsole to initialize the field as a Bootstrap Switch element. This allows you to graphically style the checkbox as an on-off toggle switch:
$fsfb = new BS\FormGroupBuilder([
'@type' => 'switch',
'@name' => "tos",
'@label' => "TOS",
'@text' => "I agree to the Terms and Conditions",
'@text_on' => "Yes",
'@text_off' => "No",
'@item_value' => "yessir"
]);
echo $fsfb->render();
Outputs:

<div class='form-group '>
<label class='control-label col-sm-4'>TOS</label>
<div class='col-sm-8'>
<div>
<input type='checkbox' class='form-control bootstrapswitch ' name='tos' value='yessir' title='' checked data-on-text='Yes' data-off-text='No'>
I agree to the Terms and Conditions
</div>
</div>
</div>
| Class method | Directive | Description |
|---|---|---|
| textOn | @text_on | Optional. The text to display for the switch in 'on' (checked) mode. |
| textOff | @text_off | Optional. The text to display for the switch in 'off' (unchecked) mode. |
Note: to use FormSwitchFieldBuilder, you will need the relevant CSS and JS files. You can download them from the Bootstrap Switch website, or use the version included with this repository in the public directory. You will also need the following JS code to perform basic initialization:
// Initialize bootstrap switches, if enabled
if (jQuery().bootstrapSwitch){
$('.bootstrapswitch').bootstrapSwitch();
} else {
console.error("The bootstrap-switch plugin has not been added.");
}
This code is included already in public/js/bootsole.js.
This class uses the Bootstrap Radio plugin to tie a group of buttons to a hidden <input> element, simulating a group of radio buttons. Thus, you can read the selected value from an ordinary <input> element.
Example:
$fbrfb = new BS\FormGroupBuilder([
'@type' => 'bootstrapradio',
'@name' => 'school',
'@label' => 'School',
'@items' => [
'epicurist' => [
'@title' => 'Epicurist. Relax and enjoy life.',
'@label' => "<i class='fa fa-cutlery'></i>"
],
'futurist' => [
'@title' => 'Futurist. Cyborgs unite!',
'@label' => "<i class='fa fa-space-shuttle'></i>"
],
'stoic' => [
'@title' => 'Stoic. Grin and bear it.',
'@label' => "<i class='fa fa-tree'></i>"
]
]
]);
echo $fbrfb->render();
Outputs:

<div class='form-group '>
<label class='control-label '>School</label>
<div>
<input value="epicurist" name="school" type="hidden">
<button type='button' class='bootstrapradio ' name='school' value='epicurist' title='Epicurist. Relax and enjoy life.' data-selected='true' data-size='xs'>
<i class='fa fa-cutlery'></i>
</button>
<button type='button' class='bootstrapradio ' name='school' value='futurist' title='Futurist. Cyborgs unite!' data-selected='false' data-size='xs'>
<i class='fa fa-space-shuttle'></i>
</button>
<button type='button' class='bootstrapradio ' name='school' value='stoic' title='Stoic. Grin and bear it.' data-selected='false' data-size='xs'>
<i class='fa fa-tree'></i>
</button>
</div>
</div>
| Class method | Directive | Description |
|---|---|---|
| multiple | @multiple | Optional. Set to false (default) or true. Determines whether it is possible select more than one option. |
| items | @items | Optional. An array of FormFieldOptionBuilder objects, defined explicitly or as arrays. |
| size | @size | Optional. The size of the options. Can be any of the Bootstrap button size classes: (xs, sm, lg, or block). |
| itemClasses | @item_classes | Optional. An array of additional CSS classes to be applied to each child option. A shortcut for applying CSS classes individually to each element. |
This class builds an HTML <button> element to associate with the form. It is simply a wrapper for a ButtonBuilder or ButtonGroupBuilder object. It will automatically generate a ButtonBuilder object from the supplied content.