2017 © Pedro Peláez
 

library endobox

A clean PHP template engine.

image

younishd/endobox

A clean PHP template engine.

  • Wednesday, December 27, 2017
  • by younishd
  • Repository
  • 2 Watchers
  • 6 Stars
  • 491 Installations
  • PHP
  • 2 Dependents
  • 0 Suggesters
  • 0 Forks
  • 9 Open issues
  • 11 Versions
  • 0 % Grown

The README.md

endobox, (*1)

endobox

minimal template engine., (*2)

Build Status Code Climate Latest Stable Version Total Downloads License, (*3)

endobox, (*4)

:seedling: Native PHP syntax :pencil: Markdown on-board  :rocket: Minimal API
Write templates in vanilla PHP. No need to learn a new syntax. A full-blown Markdown parser is built right in. Yes, it can be combined with PHP! Do powerful things with just a handful of elementary methods.

Documentation

Installation

Install endobox is via Composer:, (*5)

composer require younishd/endobox

You will need PHP 7.0+., (*6)

Get started

The typical way to configure endobox to load templates for an application looks like this:, (*7)

require_once '/path/to/vendor/autoload.php';

use endobox\Endobox;

$endobox = Endobox::create('path/to/templates');

You can add additional template locations:, (*8)

$endobox->addFolder('another/path/to/templates');

Render templates

Instantiate a Box for your template:, (*9)

$welcome = $endobox('welcome');

Render the template with some variables by calling render():, (*10)

echo $welcome->render([ 'name' => "Alice" ]);

The template file itself could look like this:, (*11)

welcome.php
<h1>Hello, <?= $name ?>!</h1>

File extensions

endobox decides how to render a template based on the file extension., (*12)

When you instantiate the template Box however, the extension is omitted., (*13)

$members = $endobox('members'); // no file extension

PHP: .php

PHP templates are processed by evaluating the code between PHP tags (i.e., <? … ?>) and returning the result., (*14)

members.php
<h1>Members</h1>
<ul>
    <?php foreach ($users as $u): ?>
        <li><?= $u->name ?></li>
    <?php endforeach ?>
</ul>

:information_source: Protip: The <?= is syntactic sugar for <?php echo., (*15)

Markdown: .md

Markdown templates are processed by a Markdown parser (Parsedown) which produces the corresponding HTML code. This can be used for static content., (*16)

members.md
# Members

- Alice
- Bob
- Carol

PHP+Markdown: .md.php

As the name suggests, this template type combines both PHP and Markdown: The template gets evaluated as PHP first, then parsed as Markdown. Pretty neat., (*17)

members.md.php
# Members


    - <?= $u->name ?>

HTML: .html

HTML templates are always printed as is. No further processing takes place., (*18)

members.html
<h1>Members</h1>
<ul>
    <li>Alice</li>
    <li>Bob</li>
    <li>Carol</li>
</ul>

Data

Data is accessible inside a template as simple __variables__ (e.g., $foo) where the variable name corresponds to the assigned array key or property., (*19)

<h1>Hello, <?= $username ?>!</h1>

Assign data

There are several ways to assign data to a template box:, (*20)

// via assign(…)
$welcome->assign([ "username" => "eve" ]);

// via object property
$welcome->username = "eve";

// via render(…)
$welcome->render([ "username" => "eve" ]);

// implicitly
$welcome([ "username" => "eve" ]);

Shared data

Usually, template boxes are isolated from each other. Data that's been assigned to one box, will not be visible from another., (*21)

$welcome->username = "eve";          // not accessible to 'profile'
$profile->email = "eve@example.com"; // not accessible to 'welcome'

If they should share their data however, you can link them together:, (*22)

$welcome->link($profile);

Now, these template boxes are linked and they share the same data., (*23)

welcome.php
<h1>Hello, <?= $username ?>!</h1>
<p>Your email address is: <code><?= $email ?></code></p>
profile.php
<h1>Profile</h1>
<ul>
    <li>Username: <strong><?= $username ?></strong></li>
    <li>Email: <strong><?= $email ?></strong></li>
</ul>

Notice how welcome.php prints out $email which was initially assigned to $profile and profile.php echoes $username even though it was assigned to $welcome., (*24)

:information_source: Protip: You can create template boxes using an existing Box object (instead of using the BoxFactory object) with $box->create('template') which has the advantage of linking the two boxes together by default., (*25)

Default values

Sometimes it can be useful to supply a default value to be printed in case a variable has not been assigned. You can easily achieve that using PHP 7's null coalescing operator: ??, (*26)

<title><?= $title ?? "Default" ?></title>

Escaping

Escaping is a form of data filtering which sanitizes unsafe, user supplied input prior to outputting it as HTML., (*27)

endobox provides two shortcuts to the htmlspecialchars() function: $escape() and its shorthand version $e(), (*28)



Hello, = $escape($username) ?>!

Hello, = $e($username) ?>!

Escaping HTML attributes

:warning: Warning: It's VERY important to always double quote HTML attributes that contain escaped variables, otherwise your template will still be open to injection attacks (e.g., XSS)., (*29)


<img src="portrait.jpg" alt="<?= $e($name) ?>">


<img src="portrait.jpg" alt='<?= $e($name) ?>'>


<img src="portrait.jpg" alt=<?= $e($name) ?>>

Chaining & Nesting

Since you're rarely dealing with just a single template you might be looking for a method that combines multiple templates in a meaningful way., (*30)

Chaining

By chaining we mean concatenating templates without rendering them., (*31)

Chaining two templates is as simple as:, (*32)

$header($article);

Now, calling ->render() on either $header or $article will render both templates and return the concatenated result., (*33)

:information_source: Protip: The benefit of not having to render the templates to strings right away is flexibility: You can define the layout made out of your templates before knowing the concrete values of their variables., (*34)

The general syntax for chaining a bunch of templates is simply:, (*35)

$first($second)($third)($fourth); // and so on

Neat., (*36)

The more explicit (and strictly equivalent) form would be using append() or prepend() as follows:, (*37)

$first->append($second)->append($third)->append($fourth);

Or…, (*38)

$fourth->prepend($third)->prepend($second)->prepend($first);

:information_source: Protip: Note that the previously seen Box::__invoke() is simply an alias of Box::append()., (*39)

You have now seen how you can append (or prepend) Boxes together., (*40)

Notice however that the variables $first, $second, $third, and $fourth were objects of type Box which means they needed to be brought to life at some point — probably using the BoxFactory object created in the very beginning (which we kept calling $endobox in this document)., (*41)

In other words the complete code would probably look something like this:, (*42)

$first = $endobox('first');
$second = $endobox('second');
$third = $endobox('third');

echo $first($second)($third);

It turns out there is a way to avoid this kind of boilerplate code: You can directly pass the name of the template (a string) to the append() method instead of the Box object!, (*43)

So, instead you could just write:, (*44)

echo $endobox('first')('second')('third');

It looks trivial, but there is a lot going on here. The more verbose form would look as follows:, (*45)

echo $endobox->create('first')->append('second')->append('third');

This is – in turn – equivalent to the following lines:, (*46)

echo ($_ = $endobox->create('first'))
        ->append($endobox->create('second')->link($_))
        ->append($endobox->create('third')->link($_));

Notice that unlike before these (implicitly created) boxes are now all linked together automatically, meaning they share the same data., (*47)

The rule of thumb is: Boxes created from other boxes are linked by default., (*48)

Nesting

A fairly different approach (probably the template designer rather than the developer way) would be to define some sort of layout template instead:, (*49)

layout.php
<html>
<head></head>
<body>
<header><?= $header ?></header>
<article><?= $article ?></article>
<footer><?= $footer ?></footer>

Then somewhere in controller land:, (*50)

$layout = $endobox('layout');
$header = $endobox('header');   // header.html
$article = $endobox('article'); // article.php
$footer = $endobox('footer');   // footer.html

echo $layout->render([
    'header' => $header,
    'article' => $article->assign([ 'title' => "How to make Lasagna" ]),
    'footer' => $footer
]);

This should be fine, but we can get rid of some boilerplate code here: $header and $footer really don't need to be variables., (*51)

That's where nesting comes into play!, (*52)

Use the $box() function to instantiate a template Box from inside another template:, (*53)

layout.php
<html>
<head></head>
<body>
<header><?= $box('header') ?></header>
<article><?= $article ?></article>
<footer><?= $box('footer') ?></footer>

Then simply…, (*54)

echo $endobox('layout')->render([
    'article' => $endobox('article')->assign([ 'title' => "How to make Lasagna" ])
]);

This is already much cleaner, but it gets even better: By using $box() to nest a template Box inside another these two boxes will be linked by default!, (*55)

That allows us to condense this even further. Check it out:, (*56)

layout.php
<html>
<head></head>
<body>
<header><?= $box('header') ?></header>
<article><?= $box('article') ?></article>
<footer><?= $box('footer') ?></footer>

All three templates are now nested using $box() and therefore linked to their parent (i.e., $layout)., (*57)

This reduces our controller code to one line:, (*58)

echo $endobox('layout')->render([ 'title' => "How to make Lasagna" ]);

Notice how we are assigning a title to the layout template even though the actual $title variable occurs in the nested article template., (*59)

:information_source: Protip: The $box() function is also available as a method of Box objects (i.e., outside templates): You can instantiate new boxes with $box->create('template') where $box is some Box object that has already been created., (*60)

Functions

Functions are a cool and handy way of adding reusable functionality to your templates (e.g., filters, URL builders…)., (*61)

Registering functions

You can register your own custom function (i.e., closure) by simply assigning it to a template Box just like data!, (*62)

Here is a simple function $day() which returns the day of the week:, (*63)

$calendar->day = function () { return date('l'); };

Inside your template file you can then use it in the same fashion as any variable:, (*64)

<p>Today is <?= $day ?>.</p>

This would look like this (at least sometimes):, (*65)

<p>Today is Tuesday.</p>

You can go even further and actually invoke the variable just like any function and actually pass some arguments along the way., (*66)

Below is a simple closure $a() that wraps and escapes some text in a hyperlink tag:, (*67)

$profile->a = function ($text, $href) {
    return sprintf('<a href="%s">%s</a>',
            htmlspecialchars($href),
            htmlspecialchars($text));
};

Calling this function inside your template would look like this:, (*68)

<p>Follow me on <?= $a("GitHub", "https://github.com/younishd") ?></p>

This would produce something like this:, (*69)

<p>Follow me on <a href="https://github.com/younishd">GitHub</a></p>

Default functions

There are a couple of default helper functions that you can use out of the box (some of which you may have already seen):, (*70)

Function Description Example
$box() or $b() Instantiate a Box from within another template. (See Nesting.) <article><?= $box('article') ?></article>
$markdown() or $m() Render some text as Markdown. Useful when the text is user input/stored in a database. <?= $markdown('This is some _crazy comment_!') ?>
$escape() or $e() Sanitize unsafe user input using htmlspecialchars(). (See Escaping.) <img src="portrait.jpg" alt="<?= $e($name) ?>">

Cloning

You can easily clone a template Box using the built-in clone keyword., (*71)

$sheep = $endobox('sheep');

$cloned = clone $sheep;

The cloned box will have the same content and data as the original one. However, chained or linked boxes are discarded., (*72)

License

endobox is open-sourced software licensed under the MIT license., (*73)

The Versions

27/12 2017

dev-master

9999999-dev https://github.com/younishd/endobox

A clean PHP template engine.

  Sources   Download

MIT

The Requires

 

The Development Requires

template php markdown simple php7 box parsedown closure template-engine php-template cute

24/11 2017

dev-facemeltingacid

dev-facemeltingacid https://github.com/younishd/endobox

A clean PHP template engine.

  Sources   Download

MIT

The Requires

 

The Development Requires

template php markdown simple php7 box parsedown closure template-engine php-template cute

23/09 2017

3.0.1

3.0.1.0 https://github.com/younishd/endobox

Awww this PHP template engine is so cute.

  Sources   Download

MIT

The Requires

 

The Development Requires

template php markdown simple php7 box parsedown closure template-engine php-template cute

23/09 2017

3.0.0

3.0.0.0 https://github.com/younishd/endobox

Awww this PHP template engine is so cute.

  Sources   Download

MIT

The Requires

 

The Development Requires

template php markdown simple php7 box parsedown closure template-engine php-template cute

02/03 2017

2.4.0

2.4.0.0 https://github.com/younishd/endobox

Awww this PHP template engine is so cute.

  Sources   Download

MIT

The Requires

 

The Development Requires

template php markdown php7 box parsedown closure template-engine php-template cute

01/03 2017

2.3.2

2.3.2.0 https://github.com/younishd/endobox

Awww this PHP template engine is so cute.

  Sources   Download

MIT

The Requires

 

The Development Requires

template php markdown php7 box parsedown closure template-engine php-template cute

01/03 2017

2.3.1

2.3.1.0 https://github.com/younishd/endobox

Simple PHP7 template engine.

  Sources   Download

MIT

The Requires

 

The Development Requires

template markdown engine box

26/02 2017

2.3.0

2.3.0.0 https://github.com/younishd/endobox

Simple PHP7 template engine.

  Sources   Download

MIT

The Requires

 

The Development Requires

template markdown engine box

26/02 2017

2.2.0

2.2.0.0 https://github.com/younishd/endobox

Simple PHP7 template engine.

  Sources   Download

MIT

The Requires

 

The Development Requires

template markdown engine box

20/08 2016

2.1.0

2.1.0.0 https://github.com/younishd/endobox

Simple PHP template engine.

  Sources   Download

MIT

The Requires

 

The Development Requires

template engine box

18/07 2015

1.0.0

1.0.0.0 https://github.com/younishd/endobox

A useful toolkit for building PHP template-based dynamic web pages.

  Sources   Download

MIT

The Requires

 

framework template view box toolkit