Bootsole
A nestable, object-oriented templating engine for generating beautiful Bootstrap-themed pages, forms, tables, and other components in PHP.
Install / Use
/learn @alexweissman/BootsoleREADME
Bootsole 0.2.0
Attention: I have decided to cease development of Bootsole, at least in it's current form. I still like the concept, but I feel that it is too complicated for most purposes. The new version of UserFrosting will use Twig, a more widely accepted and simpler templating language.
By Alex Weissman
Copyright (c) 2015
A nestable, object-oriented templating engine for generating beautiful Bootstrap-themed pages, forms, tables, and other components in PHP.
https://alexweissman.github.io/bootsole/
What is it?
Bootsole is a templating engine for web development in PHP.
Why do we need another templating engine? Why don't you use Smarty or Twig?! >:o
The purpose of a templating engine is to separate the presentation of your content from the business logic (i.e., your data model). Smarty and Twig solve this problem with the following line of reasoning:
- We need a way to separate presentation from the model.
- ...PHP is too verbose, so it should be reserved for dealing with the model.
- ...Let's build a less powerful, but more concise meta-language for the presentation.
- ...Developers will be mindful of building too much business logic with the meta-language, and reserve it for presentation logic as much as possible.
This approach makes sense, especially if you run a large operation and have "web developer" and "web designer" as two separate jobs (or departments). But what if you are a general-purpose web programmer running a small operation, and your main concern is rapid development and reusable, maintainable code? It would be nice if instead, your templating system actually makes it faster to design and assemble real web pages. Enter Bootsole.
Bootsole's focus is on developing a DRY (Don't Repeat Yourself) design paradigm for rapid development. It models the way that a human designer thinks about a web page - a page contains a header, body, and footer; the body might contain some forms and tables; each form will contain fields and buttons, and so forth. Bootsole's line of reasoning is:
- We need a way to separate presentation from the model.
- ...Let's keep the "presentation" side as minimal as possible.
- ...Templates should be simple, fill-in-the-blank HTML documents.
- ...PHP is verbose but powerful, and can be used to transform our model into a presentable format.
- ...Just tell me where to stick these transformed objects in the HTML templates when you're ready to render them.
- ...We can minimize the amount of presentation logic that developers need to write in the first place, by providing common functionality through components. Developers can extend our components for project-specific needs.
Through an extensive class hierarchy, Bootsole lets you explicitly declare pages, forms, tables, and more as PHP objects. These objects can be configured to set the content and layout, modified, and reused throughout your project. Where appropriate, they can be nested inside each other. When ready, you simply call render on the top-level object, and it recursively generates the appropriate HTML for itself and all its children.
Dependencies
PHP
Javascript/CSS (included in this repository)
- jQuery 1.10.2
- Bootstrap 3.3.1
- Tablesorter 2.17.7 with the pager and filter widgets
- FormValidation v0.6.1
- FontAwesome 4.1
- Bootstrap Switch 3
- Select2 3.5.1
- Bootstrapradio 0.1
Installation
It is possible to install Bootsole via Composer, or as a standalone library.
To install with composer:
- If you haven't already, get Composer and install it - preferably, globally.
- Require Bootsole, either by running
php composer.phar require alexweissman/bootsole, or by creating acomposer.jsonfile:
{
"require": {
"php": ">=5.4.0",
"alexweissman/bootsole": "0.2.0"
}
}
and running composer install.
- Include the
vendor/autoload.phpfile in your project. For an example of how this can be done, seepublic/site-config.php.
Note: The core Bootsole library is contained entirely in vendor/alexweissman/bootsole/bootsole/. You don't need the public directory - it just contains examples for how Bootsole can be used in a PHP project.
To install manually:
Copy the bootsole/ subdirectory to wherever you usually keep your site's non-public resources. If you don't know what "non-public resources" means, see Organize Your Next PHP Project the Right Way.
If you want to run the premade examples, you can copy the contents of public to your site's public directory.
Without Composer, you will need to manually include Bootsole's source files. The public/config-site.php file will do this automatically for you - feel free to move that code to your project's main config file.
Configuration
Bootsole relies on a number of predefined constants to properly find and render templates, JS and CSS includes, etc. You can find these in the bootsole/config-bootsole.php file. Most of the default values should work out of the box, except for the following:
PATH_PUBLIC_ROOT
This is the local (file) path to the public directory of your site. It is recommended that you declare it relative to the location of your config-bootsole.php file. For example, if your directory structure looks like this:
- public_html/ // This is where we want PATH_PUBLIC_ROOT to point
- js/
- css/
- <public-facing content>
- resources/
- bootsole/
- config-bootsole.php // This is where PATH_PUBLIC_ROOT is defined
- ...
- <other libraries>
you could set PATH_PUBLIC_ROOT as:
define ("Bootsole\PATH_PUBLIC_ROOT", realpath(dirname(__FILE__) . "/../../public_html") . "/");
URI_PUBLIC_ROOT
As you should know, file paths != URL paths (though there is often a strong relationship between them, especially if you aren't using a URL routing system). So, Bootsole needs to know what the public URL will be for your site.
For a development environment, this might be something like:
http://localhost/myproject/.
For a production environment, this might look like:
https://mysite.com/.
Basic usage
If you have autoloaded the library with Composer, all you should need is:
<?php
require_once "path/to/autoload.php";
use \Bootsole as BS;
...
Otherwise, you will need include the files manually, in the correct order. See public/config-site.php for an example of how this is done.
Then, you can start defining and deploying templates:
Bootsole uses the {{double handlebar}} notation for representing placeholders in a template.
Create a template:
$template = "
<div class='media'>
<a class='media-left' href='#'>
<img src='{{img_src}}' alt='{{img_alt}}' width='64' height='64'>
</a>
<div class='media-body'>
<h4 class='media-heading'>{{heading}}</h4>
{{body}}
</div>
</div>";
Then, assign content to the placeholders:
$content = [
"img_src" => "http://avatars1.githubusercontent.com/u/5004534?v=3&s=400",
"img_alt" => "Lord of the Fries",
"heading" => "Alex Weissman",
"body" => "Alex has many years of experience in software development, including web development using MySQL, PHP, and Javascript frameworks including jQuery and Twitter Bootstrap. Alex maintains the frontend website for Bloomington Tutors, as well as a backend site..."
];
Construct a new HtmlBuilder object, set the template, and render:
use \Bootsole as BS;
$hb = new BS\HtmlBuilder($content);
$hb->setTemplate($template);
echo $hb->render();
Output:

<div class='media'>
<a class='media-left' href='#'>
<img src='http://avatars1.githubusercontent.com/u/5004534?v=3&s=400 alt='Lord of the Fries' width='64' height='64'>
</a>
<div class='media-body'>
<h4 class='media-heading'>Alex Weissman</h4>
Alex has many years of experience in software development, including web development using MySQL, PHP, and Javascript frameworks including jQuery and Twitter Bootstrap. Alex maintains the frontend website for Bloomington Tutors, as well as a backend site for managing tutor and client data and activity.
</div>
</div>
Wow, amazing! So far, this is just simple find-and-replace. But we can also nest HtmlBuilder objects in the content of other HtmlBuilder objects:
Nested template objects:
$jumbotron_template = "
<div class='jumbotron'>
<h1>{{heading}}</h1>
{{body}}
</div>";
$jumbotron_content = [
"heading" => "Developers",
"body" => $hb
];
$jumbotron = new BS\HtmlBuilder($jumbotron_content);
$jumbotron->setTemplate($jumbotron_template);
echo $jumbotron->render();
Output:

<div class='jumbotron'>
<h1>Developers</h1>
<div class='media'>
<a class='media-left' href='#'>
<img src='http://avatars1.githubusercontent.com/u/5004534?v=3&s=400 alt='Lord of the Fries' width='64' height='64'>
</a>
<div class='media-body'>
<h4 class='media-heading'>Alex Weissman</h4>
Alex has many years of experience in software development, including web development using MySQL, PHP, and Javascript frameworks including jQuery and Twitter Bootstrap. Alex maintains the frontend website for Bloomington Tutors, as well as a backend site...
</div>
</div>
</div>
Alright, that's kind of cool. But what if I need a whole list of developers? Do I need a placeholder for each one?
Of course not! You can also assign an array of HtmlBuilder objects to a pla
Related Skills
node-connect
337.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
337.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.2kCommit, push, and open a PR
