A faster, safer templating library for PHP

Related tags

Templating brainy

Build Status Latest Stable Version Project Status Total Downloads License



Brainy is a replacement for the popular Smarty templating language. It is a fork from the Smarty 3 trunk.

Brainy is still very new and it's likely that you will encounter some issues. Please report any problems that you encounter.

Why Brainy?

  • Brainy generates clean and fast code by default.
  • Brainy has security defaults that align better with best practices.
  • Brainy does not include features that are infrequently used and increase code bloat.

Because Brainy is a fork of Smarty 3, it shares much of the same syntax and features while eliminating dangerous footguns and making it hard to write bad code.

Getting Started

Check out the Getting Started page on the wiki.

Minimum Requirements

  • PHP 5.4+ or HHVM 3.7+
  • mbstring PHP extension

The mbstring extension is required in order to properly support Unicode in templates and user-provided content. Brainy 3 cannot be run in a mode that does not handle Unicode properly.

Contributing to Brainy

For information on how to set up a local dev environment and run the tests, see the wiki page on Hacking on Brainy.

Where is Brainy headed?

See the project roadmap for information on upcoming releases.

Requested Contributions

If you're interested in helping out, pull requests for the following tasks will be warmly welcomed:

  • Convert all non-public methods to use camel case.
  • Add proper PHPDoc annotations to all functions and methods.
  • Refactoring:
    • Eliminate dead code
    • @ error suppression
    • Increase code coverage
    • etc.
  • Help identify and resolve potential security issues, or find ways to help developers avoid security issues.
  • Performance optimization of generated code

At the time of writing, the project has approximately 68% line coverage.


Need to contact us directly? Email [email protected] and be sure to include the name of this project in the subject.

Copyright and License

Copyright 2014-2015 Box, Inc. All rights reserved.

Copyright 2002 – 2014 New Digital Group, Inc.

This library is licensed under the GNU Lesser Public License. A copy of the license should have been provided.

  • Windows support

    Windows support

    You recommend dropping the constant DIRECTORY_SEPARATOR and always use a forward slash. The code will be easier to read and the library will work on any system, including Windows. It currently fails on Windows because it tried to remove compiled template files without escaping the backslash, thus not forming correct paths.

    P.S. The quick start guide is outdated. It took me a while to find out "new Box\Brainy\Brainy()".

    opened by filerun 14
  • Ternary operator pls

    Ternary operator pls

    It would be really darn cool if the ternary operator was a thing.

    Right now:

    {if $condition} 
        {$var = $true_option}   
        {$var = $false_option}  

    Super premium: {$var = $condition ? $true_option : $false_option}

    opened by knewkirk 4
  • Eliminate deprecation errors

    Eliminate deprecation errors

    The flags parameter of preg_match no longer accepts null and instead defaults to 0. Changing this eliminates the deprecation warnings raised by the use of preg_match in the lexer, which eliminates many hundreds of noisy messages when running the tests (and probably improves runtime performance in newer versions of PHP).

    Edit: I've also updated this PR to eliminate deprecation warnings related to strftime() usage in html_select_date. strftime is deprecated in favor of date. The current use for strftime is to translate a configurable date format for both the value and the label of a select box (that is, the content and value="" attribute of the generated <option> tags). My change preserves all possible strftime month formatting values, though it does create a minor backwards-incompatible change where someone who may have been abusing the month_format or month_value_format arguments to render non-month dates (e.g., rendering the current year for the value) would start seeing exceptions. This is pretty unlikely, since the rendered output doesn't make a whole lot of sense.

    When bumping versions after this PR, there should be a minor version bump, not just a patch version.

    opened by mattbasta 2
  • Variable Variable prohibition in strict mode causes failures where it should not (as late as release 2.1.1)

    Variable Variable prohibition in strict mode causes failures where it should not (as late as release 2.1.1)

    {for $i=0 to $foo.bar.baz-1} {for $i=0 to count($foo)-1} {for $i=0 to count($foo)-1 step 2} {for $i=1 to $foo} {for $i=count($foo)-1 to 0 step -1} {for $i=0 to 5 step 2}

    opened by vctrshn 2
  • Upgrade dev dependencies

    Upgrade dev dependencies

    r? @DavidSchnepper

    This upgrades all of the dev dependencies, which are on old versions and I don't have confidence are doing the right thing in a modern PHP environment. A few notes:

    1. Eliminating warnings and errors in a stock PHP environment requires adding class member annotations (specifically, $line on SmartyException). If a member is overridden in a child class, it must have the same signature as the ancestor. In new PHP versions, $line is typed int on Exception. This makes this version incompatible with PHP <7.4, which added support for typing for class members.
    2. I'm noting that HHVM support is dropped, since I don't believe it is supported by Box anymore. I have not deleted the test harness for HHVM, just updated the README.
    3. Upgrading PHPUnit requires adding some method signatures to tests, which requires PHP 7.3.
    4. Modern PHPUnit dropped the PHPDoc annotations for expected exceptions, so I converted these to the imperative methods.
    5. I've committed composer.lock, which was previously .gitignored. This should be committed for reproducible builds.
    6. One test was removed, but I believe it was not actually testing anything. It did not make any assertions, and the description implied that it was testing an error case.

    As of now, the full tests suite passes on my machine.

    Regarding compatibility, the minimum PHP version for Brainy after this PR is 7.4. My previous PR necessitated a minor semver version bump, but this will require a major version bump (e.g., to Brainy 4.0.0).

    opened by mattbasta 1
  • Contributor permissions

    Contributor permissions

    It would be nice to have contributor permissions again. After all, I've got the most knowledge around how the code works and how it's used in practice.

    screen shot 2016-04-07 at 12 21 24 pm
    opened by mattbasta 1
  • `$_valid` check in compiled templates should be wrapped in a function

    `$_valid` check in compiled templates should be wrapped in a function

    This is for HHVM support. Currently it's in the root of the compiled file, which hh_client isn't happy about (because $_smarty_tpl is undefined when the template is inspected statically).

    opened by mattbasta 1
  • Allow nested subscripts in LHS of assignments when in safe mode

    Allow nested subscripts in LHS of assignments when in safe mode

    r? @DavidSchnepper

    This PR fixes a codegen bug where the LHS of the sugared assignment syntax can contain function calls, which cannot be on the LHS of an assignment.

    The fix involves making SafeLookupWrapper abstract and specializing it into four subclasses which have extra bookkeeping for the recursively unsafe versions of each base (that is, the unsafe version of the value being subscripted) in addition to the safe version of the value being subscripted and the member name in the subscript. This allows the LHS of an assignment to be unwrapped such that the entirely unsafe version is assigned to.

    This is necessary, because even lookup($tpl_vars, 'foo')['bar'] is invalid (that is, preserving safe lookups to the variable), because PHP returns arrays as value rather than references to those arrays.

    This PR also fixes the parser generator, which was generating invalid PHP due to output being changed from null to 0 in new PHP versions. This can be tested with make parsers test.

    opened by mattbasta 0
  • Support modifier plugins that take arguments by reference when in safe mode

    Support modifier plugins that take arguments by reference when in safe mode

    r? @DavidSchnepper

    This PR updates the modifier construct compiler to support functions that take arguments by reference when safe mode is active. The PRs incrementally refactor before adding the new behavior, and may be easier to review in-order rather than together.

    The mechanism of this change is wrapping modifiers in self-executing closures. That is:


    previously compiled to the equivalent of


    In safe mode, it now compiles to

    (function($p1) use ($_smarty_tpl) {
      return array_pop($p1);
      (function($p1) use ($_smarty_tpl) {
        return foo($p1);
        \Box\Brainy\Runtime\Lookups::safeArrayLookup($_smarty_tpl, 'var')

    Self-executing closures take the arguments, which may be the result of non-variable lookups, and assign them to the parameter variables, which are always variables. This allows methods like array_pop to execute correctly when safe mode is enabled.

    One notable backwards-incompatible change: compiler modifiers (that is, plugins that run at compile time) will always take precedence over plugins which execute at runtime. This only affects folks who have registered two modifiers (one compiler and one runtime) with the exact same name. In this case, previously only the runtime modifier would have been invoked. After this change, only the compiler modifier would be invoked. I suspect nobody has this problem, since why would you register two plugins with identical names. This would require a minor version bump.

    opened by mattbasta 0
  • Optimization: Compile safe lookups to individual methods

    Optimization: Compile safe lookups to individual methods

    Currently, the safe lookup operation is compiled as a param to Lookups::safeLookup(). Removing the param and having one method per safe lookup type would cut down on branches and make it easier for HHVM to warm up.

    opened by mattbasta 0
  • Brainy 3 feature tracker

    Brainy 3 feature tracker

    • [x] {assign}
    • [x] {block}
    • [x] {break}
    • [x] {call}
    • [x] {capture}
    • [x] {continue}
    • [x] {extends}
    • [x] {function}
    • [x] {for}
    • [x] {forelse}
    • [x] {foreach}
    • [x] {foreachelse}
    • [x] {if}
    • [x] {elseif}
    • [x] {else}
    • [x] {include}
    • [x] {ldelim}
    • [x] {rdelim}
    • [x] {literal}
    • [x] {strip}
    • [x] {while}
    • Smarty variable
      • [x] $smarty.foreach
      • [x] $smarty.capture
      • [x] $smarty.now
      • [x] $smarty.template
      • [x] $smarty.version
      • [x] $smarty.ldelim
      • [x] $smarty.rdelim
    opened by mattbasta 0
  • 4.0.0 Roadmap

    4.0.0 Roadmap

    Please update this issue with more.


    • Delete the html_* plugins for good, because they're scary
    • Delete the count_* plugins, because they're mostly unused
    • Delete the strip_tags plugin, since it's most likely not safe
    • Delete all plugins banned in strict mode
    • Delete the following plugins, because they violate web best practices:
      • capitalize: Use text-transform in CSS instead.
      • truncate: Use overflow and text-overflow in CSS instead.
      • date_format: Does not support proper localization, out of scope of Brainy.
    • Remove the make_timestamp and escape_special_chars shared plugins, as they're only depended on by the plugins being removed above.
    • Remove $smarty->template, which is banned in strict mode.
    • Remove syntax features banned by strict mode.
    • Remove support for built-in functions with side effects that are banned in strict mode: reset(), current(), etc.
    • Remove SmartyBC.
    • Remove the inline param from {include}.
    • {* set stricter *} that requires all included templates to be strict


    • AST-based parser and compiler
    • Make it impossible to {include} or fetch a file outside of one of the recognized template directories.
    • Mode that reports which assigned variables were not accessed
      • API should be similar to fetchedTemplate() overridable method
      • Should be enabled with a static flag
      • May be possible to implement by making the scope array inside TemplateData be an object implementing PHP's ArrayAccess interface with zero overhead while mode is off (no new code branches)
    • Make buildFilepath not be insane.


    • 80% code coverage
    • ~100% code coverage for bundled plugins
    • Cut compilation times by 25%
    • Reduce IO-related PHP calls (filemtime, getcwd, etc.) by 25%
    opened by mattbasta 11
  • 3.2.1(Jun 15, 2022)

  • 3.2.0(Mar 19, 2016)

    Fixed an issue where if changes were made to a source template, making its timestamp out of sync with the timestamp stored as its dependency, the compiled template would fail to decode properly and throw an exception.

    Source code(tar.gz)
    Source code(zip)
  • 3.1.1(Feb 18, 2016)

  • 3.1.0(Feb 17, 2016)

    Changed usage of the constants SMARTY_DIR and SMARTY_PLUGINS_DIR to BRAINY_DIR and BRAINY_PLUGINS_DIR. This should be a minor change, since these constants should not be used by anyone else.

    Also fixed a warning on Windows caused by unlinking a file that did not exist.

    Source code(tar.gz)
    Source code(zip)
  • 3.0.0(Dec 17, 2015)

    The final 3.0.0 release! See the changelog for full information on what's changed.

    Notable Changes

    • Fully namespaced under \Box\Brainy
    • Substantially faster performance than Brainy 2 and Smarty 3.1 (tested with brain-bench). Oodles of performance optimizations.
    • Better error messages
    • Removed lots of cruft
    • Fixed weird syntax, like using negative numbers in modifiers: {$foo|bar:(-1)} -> {$foo|bar:-1}
    • More concise generated code
    • Support for dynamic values passed to {extends}
    Source code(tar.gz)
    Source code(zip)
  • 2.1.3(Nov 9, 2015)

  • 2.1.2(Nov 2, 2015)

  • 2.1.1(Aug 12, 2015)

    This release rolls up the changes from 2.0.2 onto 2.1.

    • Fix for strict mode being too strict
    • Changes to whitespace rules to be more aggressive
    Source code(tar.gz)
    Source code(zip)
  • 2.0.2(Aug 12, 2015)

    This release fixes a number of problems with 2.0.

    • Fixes issues with strict mode being too strict
    • Changes whitespace rules to avoid removing too much whitespace
    • Fixes double backslash bug inside {literal}
    Source code(tar.gz)
    Source code(zip)
  • 2.1.0(Aug 4, 2015)

  • 2.0.0(Apr 23, 2015)

    Brainy 2.0 offers a whole suite of new security features, and contains heavily-refactored code. Improvements in this release remove many potentially unsafe or otherwise unmaintained features to help pare the project to its fundamental components.

    • Strict Mode is now available!
    • New {load} and {store} functions to help eliminate security risk.
    • Better security defaults, like enforce_expression_modifier.
    • Fixes for whitespace stripping inside {strip}
    • Performance enhancements
    • Lots of code cleanup, refactoring, and removal of unused or broken features.

    You can see the full changelog here: https://github.com/box/brainy/wiki/Brainy-2.0-Changelog

    Plans for upcoming releases:

    • Namespacing and exclusive use of Composer's autoloader
    • Giving classes sane names
    • Removal of SmartyBC
    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Jan 15, 2015)

Box, Inc.
Standalone Skeltch templating engine for PHP

SkeltchGo is a standalone version of Glowie Skeltch templating engine for PHP, intented to use from outside the framework.

glowie 1 Nov 5, 2021
Simple PHP templating system for user editable templates.

Simple template Simple PHP templating system for user editable templates. Idea Most applications need to render templates that insert safely treated v

Baraja packages 1 Jan 23, 2022
The Templating component provides all the tools needed to build any kind of template system.

Templating Component The Templating component provides all the tools needed to build any kind of template system. It provides an infrastructure to loa

Symfony 999 Dec 25, 2022
SwitchBlade: Custom Directives for the Laravel Blade templating engine

SwitchBlade: Custom Directives for the Laravel Blade templating engine

Awkward Ideas 10 Nov 29, 2022
Experimental ActiveRecord layer on top of Doctrine2 using the Twig templating engine

This is an experiment for building ActiveRecord functionality on top of Doctrine2 using the Twig templating engine. Whether it is called Propel2 or not is irrelevant.

Francois Zaninotto 85 Dec 5, 2022
FyreView is a free, open-source template rendering library for PHP.

FyreView FyreView is a free, template rendering library for PHP. Table Of Contents Installation Methods Layouts Paths Helper Registry Helpers CSP Form

Elusive 1 Jul 30, 2022
PHP template engine for native PHP templates

FOIL PHP template engine, for PHP templates. Foil brings all the flexibility and power of modern template engines to native PHP templates. Write simpl

Foil PHP 167 Dec 3, 2022
A PHP project template with PHP 8.1, Laminas Framework and Doctrine

A PHP project template with PHP 8.1, Laminas Framework and Doctrine

Henrik Thesing 3 Mar 8, 2022
Twig, the flexible, fast, and secure template language for PHP

Twig, the flexible, fast, and secure template language for PHP Twig is a template language for PHP, released under the new BSD license (code and docum

Twig 7.7k Jan 1, 2023
A Mustache implementation in PHP.

Mustache.php A Mustache implementation in PHP. Usage A quick example: <?php $m = new Mustache_Engine(array('entity_flags' => ENT_QUOTES)); echo $m->re

Justin Hileman 3.2k Dec 24, 2022
Smarty is a template engine for PHP, facilitating the separation of presentation (HTML/CSS) from application logic.

Smarty 3 template engine smarty.net Documentation For documentation see www.smarty.net/docs/en/ Requirements Smarty can be run with PHP 5.2 to PHP 7.4

Smarty PHP Template Engine 2.1k Jan 1, 2023
Native PHP template system

Plates Plates is a native PHP template system that's fast, easy to use and easy to extend. It's inspired by the excellent Twig template engine and str

The League of Extraordinary Packages 1.3k Jan 7, 2023
☕ Latte: the intuitive and fast template engine for those who want the most secure PHP sites.

Latte: amazing template engine for PHP Introduction Latte is a template engine for PHP which eases your work and ensures the output is protected again

Nette Foundation 898 Dec 25, 2022
Multi target HAML (HAML for PHP, Twig, )

Multi target HAML MtHaml is a PHP implementation of the HAML language which can target multiple languages. Currently supported targets are PHP and Twi

Arnaud Le Blanc 363 Nov 21, 2022
PHP Template Attribute Language — template engine for XSS-proof well-formed XHTML and HTML5 pages

PHPTAL - Template Attribute Language for PHP Requirements If you want to use the builtin internationalisation system (I18N), the php-gettext extension

PHPTAL 175 Dec 13, 2022
View template engine of PHP extracted from Laravel

Blade 【简体中文】 This is a view templating engine which is extracted from Laravel. It's independent without relying on Laravel's Container or any others.

刘小乐 143 Dec 13, 2022
PHP 5.3 Mustache implementation

Phly\Mustache MOVED! This package has moved to phly/phly-mustache, and the package name has changed to phly/phly-mustache. I have updated packagist to

phly 123 Jan 11, 2022
A complete and fully-functional implementation of the Jade template language for PHP

Tale Jade for PHP Finally a fully-functional, complete and clean port of the Jade language to PHP — Abraham Lincoln The Tale Jade Template Engine brin

Talesoft 91 Dec 27, 2022
TextGenerator is a PHP package that aims to generate automated texts from data.

TextGenerator TextGenerator is a PHP package that aims to generate automated texts from data. Feel free to comment and contribute. Features Text gener

Vincent Brouté 89 Dec 26, 2022