Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
CBT{# ColdBox Templating Language #}
Luis Majano 

@lmajano
@ortussolutions
{{ ortussolutions.com }}
WHO AM I?
• Luis Majano - Computer Engineer
• Imported from El Salvador
• Houston,Texas
• CEO of Ortus Solutions
• Creator...
What is CBT?
Why CBT?
When to use
Getting Started
Templating System
• ColdBox Module
• Templating Engine based on Twig
• Powered by Pebble Java Engine
• Seamless integration for HMVC apps
Wh...
Why CBT
• Sponsored by IDG Media Group
• Main Goals:
• Empower their custom CMS
• Enable editors with templating
capabilit...
What is a templating engine
• A software to combine a template (simple text)
with data to produce content
• Content can be...
Why a templating engine
• Easy to learn, read and write
• Simple control flow
• Limited Constructs & Expressions
• Security...
When to use CBT
• When your users edit templates and you don’t
trust them
• Serving Dynamic Content (CMS)
• Simple DSL for...
Getting Started
Installation + IDE Support
• Using CommandBox $ install cbt
• IDE Support
• Sublime: https://packagecontrol.io/packages/Tw...
Settings
cbt = {
// If in strict mode, exceptions will be thrown for variables that do not exist, else it prints
them out ...
Usage
• Create .cbt files in:
• MVC - In views and layouts
• HMVC - Modules
• Inject the cbt engine to handlers, intercepto...
Rendering Context/Model
• Every template is bound with a model context (structure)
• Think rc/prc
• Templates cannot go ou...
Render by Conventions
    function inheritance( event, rc, prc ){
        return cbt.renderTemplate( "main/inheritance" );...
Get Funky
CBT
Render DynamicTemplates
var onDemand = "
        <h2>On-Demand Renderings</h2>
        {{ 'Rendering from OnDemand Baby' |...
Templating
Constructs
Templating System
TemplateContext/Model
{
variables
functions
expressions
tags
Template
Template
Template
<<inherit>>
{# CBT template #}
<ul>
{% for item in items %}
<li>{{ item.value }}</li>
{% endfor %}
<ul>
{% block content %}
    Hello ...
Delimiters
• {{ expression }}
• Outputs the result of an expression. A simple context variable or
complex expression
• {% ...
Expressions
• Similar to expressions in Java/CFML world:
• Can be variables from the bound context or created on the fly
• ...
Variables
• Context variable output {{ myVar }}
• You can use (.) notation or [ “key” ] notation for navigating structures...
GlobalVariables
• rc
• prc
• flash
• now
• baseURL
• currentAction
• currentEvent
• currentHandler
• currentModule
• curren...
SettingVariables
• {% set varName = “value” %}
• Use + to concatenate strings
• Set from other expressions
{% set danger =...
Filters
• Used to modify variables
• {{ name | striptags | title }} {# remove HTML and title case #}
• Separated by pipe a...
Filters
• abbreviate
• abs
• capitalize
• date
• default
• escape
• first
• join
• last
• length
• lower
• numberformat
• r...
Tags
• Written between {% %} delimiters
• Control Flows
• Execute Functions
• Define Blocks
• Macros
• EndingTag is optiona...
Tags
• autoescape
• block
• cache
• extends
• filter
• flush
• for
• if
• import
• include
• macro
• parallel
• set
• verbat...
Functions
• Called to generate content
• Called by their name followed by parentheses ()
• Arguments can be positional or ...
Functions
• block
• i18n
• max
• min
• parent
• range
http://www.mitchellbosecke.com/pebble/documentation
x()
Tests
• Tests variables against common expressions using the is operator
• The not operator negates them
{% if user.email ...
Tests
• empty
• even
• map
• null
• odd
• iterable
http://www.mitchellbosecke.com/pebble/documentation
√
Literals
• "Hello World"
• Everything between two double or single quotes is a string.You can use a
backslash to escape qu...
Collections
• Both structs and arrays can be created directly
• ["apple", "banana", "pear"]
• {"apple":"red", "banana":"ye...
Math
• CBT allows you to calculate values using some basic mathematical operators.The
following operators are supported:
•...
Logic
• You can combine multiple expressions with the following operators:
• and: Returns true if both operands are true
•...
Comparisons
• The following comparison operators are supported in any expression:
• ==, !=, <, >, >=, and <=
{% if user.ag...
Ternary Operator
• Same as CFML
{{ foo ? "yes" : "no" }}
Operators
• Supported Operators in precedence:
• .
• |
• %, /, *
• -, +
• ==, !=, >, <, >=, <=
• is, is not
• and
• or
Flows in-depth
For Loops
• Loops over each item in a list, array, query or struct
• Special else for empty sequences
{# Arrays #}
{% for ...
For : Sequences
• Iterate over sequences
{% for i in range(0, 3) %}
{{ i }},
{% endfor %}
{# outputs 0, 1, 2, 3, #}
{% for...
if / else
• Similar to Java/CFML
• Leverage expressions, operators, tests, math, etc.
{% if users is empty %}
    There ar...
Going Deep
Macros
• Reusable template fragments, think web components
• Invoked like functions
• Can have input arguments with defaul...
Whitespace
• The first newline after a template tag is removed automatically
• - is the whitespace control modifier
• It can...
Escaping
• Automatic (html) default escape strategy or custom strategy (css, html, html_attr, js, url_param)
{{ danger | r...
Includes
• Just like cfinclude(), please note that relative pathing needs the ./ prefix
{% include "advertisement" with {"fo...
Get Funky…again
CBT
Template Inheritance
• Most powerful part of cbt
• Build a layout with most common elements
• Blocks are named slots or ho...
Layout.cbt - Parent
<!DOCTYPE html>
<html lang=”en”>
<head>
{% block metatags %}
<meta charset=”utf-8”>
{% endblock %}
{% ...
Template Child
{% extends layoutsPath + "Main.twig" %}
{% block stylesheets %}
{{ parent() }}
<link href="/includes/css/th...
Template Child
• extends tag should be the first tag in the template
• By using the same block name you either
• override c...
More to come….
• Project still in its infancy
• Will explore custom parsers via Antlr
for CFML customizations
• Tag librar...
Thanks
Upcoming SlideShare
Loading in …5
×

Into The Box 2018 - CBT

Luis Majano

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to comment

  • Be the first to like this

Into The Box 2018 - CBT

  1. 1. CBT{# ColdBox Templating Language #} Luis Majano 
 @lmajano @ortussolutions {{ ortussolutions.com }}
  2. 2. WHO AM I? • Luis Majano - Computer Engineer • Imported from El Salvador • Houston,Texas • CEO of Ortus Solutions • Creator of many boxes www.ortussolutions.com 
 @ortussolutions @lmajano
  3. 3. What is CBT? Why CBT? When to use Getting Started Templating System
  4. 4. • ColdBox Module • Templating Engine based on Twig • Powered by Pebble Java Engine • Seamless integration for HMVC apps What is CBT http://www.mitchellbosecke.com/pebble/home
  5. 5. Why CBT • Sponsored by IDG Media Group • Main Goals: • Empower their custom CMS • Enable editors with templating capabilities • Restricted programming • Template Inheritance • Selfish Goal: • Get into language design, parsers and compilers.
  6. 6. What is a templating engine • A software to combine a template (simple text) with data to produce content • Content can be html, xml, json, css, js, cfml, csv, etc • Provides reusability of templates + Template Data
  7. 7. Why a templating engine • Easy to learn, read and write • Simple control flow • Limited Constructs & Expressions • Security - Automatic HTML Escaping • Cross language compatible • Great for MVC patterns • Great for CMS based systems • Template Inheritance • Generate other language files: js, css, cfml • Much More… ?
  8. 8. When to use CBT • When your users edit templates and you don’t trust them • Serving Dynamic Content (CMS) • Simple DSL for view layer • Template Reusability • Enforce Separation of Concerns • Dont’ want to bite the JS Frameworks Bullet {{?}}
  9. 9. Getting Started
  10. 10. Installation + IDE Support • Using CommandBox $ install cbt • IDE Support • Sublime: https://packagecontrol.io/packages/Twig • Atom: https://atom.io/packages/language-twig • VSCode: https://marketplace.visualstudio.com/items? itemName=bajdzis.vscode-twig-pack • CFBuilder: http://twig.dubture.com/ • Add .cbt to the twig language association "files.associations": { "*.cbt": "twig" }
  11. 11. Settings cbt = { // If in strict mode, exceptions will be thrown for variables that do not exist, else it prints them out as empty values strictVariables = false, // Sets whether or not XSS escaping should be performed automatically, defaults to true. autoEscaping = true, // Enable/disable all templating cache cacheActive = false, // By default, Pebble will trim a newline that immediately follows a Pebble tag // For example, {{key1}}n{{key2}} will have the newline removed. newLineTrimming = true, // Bind the ColdBox Flash scope bindFlash = true, // Bind the session scope to templates bindSession = true, // Bind the cgi scope to templates bindCGI = true, // Bind the request scope to templates bindRequest = true, // Bind the server scope to templates bindServer = true, // Bind to the request's HTTP Request Data elements bindHTTPRequestData = true, // The default cbt templating language template extension templateExtension = ".cbt" }
  12. 12. Usage • Create .cbt files in: • MVC - In views and layouts • HMVC - Modules • Inject the cbt engine to handlers, interceptors, models: • property name=“cbt” inject=“engine@cbt” • Render Stuff Out! • renderTemplate( template, context={}, module=“”) • renderContent( content, context={} ) • What is this context?
  13. 13. Rendering Context/Model • Every template is bound with a model context (structure) • Think rc/prc • Templates cannot go out to get data, they are provided with data (MVC) Template Context 
 / Model
  14. 14. Render by Conventions     function inheritance( event, rc, prc ){         return cbt.renderTemplate( "main/inheritance" );     } • Looks for views/main/inheritance.cbt in main conventions or module conventions // Content Variables     prc.moduleView = cbt.renderTemplate( template="home/simple", module="testing" ); • Looks for views/home/simple in the testing module
  15. 15. Get Funky CBT
  16. 16. Render DynamicTemplates var onDemand = "         <h2>On-Demand Renderings</h2>         {{ 'Rendering from OnDemand Baby' | upper }}         <br>         {{ max( 20, 100 ) }}         <br>         Today is {{ now | date( 'yyyy-MMM-dd HH:mm:ss' ) }}         <br>         BaseURL: {{ baseURL }}     ";     return cbt.renderContent( onDemand );
  17. 17. Templating Constructs
  18. 18. Templating System TemplateContext/Model { variables functions expressions tags Template Template Template <<inherit>>
  19. 19. {# CBT template #} <ul> {% for item in items %} <li>{{ item.value }}</li> {% endfor %} <ul> {% block content %}     Hello {{ name | title }} Categories {{ categories | join(‘, ‘) }} {% endblock %} {% for i in range(0,3) %} {{ i }}, {% endfor %} Templating System http://www.mitchellbosecke.com/pebble/documentation/guide/basic-usage Comments tag variables tags filter filter with args functions
  20. 20. Delimiters • {{ expression }} • Outputs the result of an expression. A simple context variable or complex expression • {% tags %} • Tag based context (control flows, blocks, function calls, setting variables etc) • {# Comment #} • Comment to your ❤ content http://www.mitchellbosecke.com/pebble/documentation/guide/basic-usage
  21. 21. Expressions • Similar to expressions in Java/CFML world: • Can be variables from the bound context or created on the fly • {{ prc.link }} • Can be variable assignments • {% set foo = 'foo' + bar %} • Can be output of literals: strings, booleans, numbers, structs, arrays or nulls • {{ ["apple", "banana", "pear"] }} • Complex mathematical operations or logical expressions • {% for item in values %} • Comparisons • {% if user.age >= 30 %} • Test evaluations • {% if user.role is null %} http://www.mitchellbosecke.com/pebble/documentation/guide/basic-usage
  22. 22. Variables • Context variable output {{ myVar }} • You can use (.) notation or [ “key” ] notation for navigating structures and queries • {{ prc[ “my-key” ] }} • All output is XSS Escaped for HTML by default • Null values will be presented as empty strings, even if deep nested • {{ foo.bar.yea }} => empty if foo and bar are null • All variables can be passed through filters using the | pipe operator • {{ var | filter1 | filter2 | filter( args ) }} http://www.mitchellbosecke.com/pebble/documentation/guide/basic-usage
  23. 23. GlobalVariables • rc • prc • flash • now • baseURL • currentAction • currentEvent • currentHandler • currentModule • currentRoute • currentRoutedURL • currentRoutedNamespace • currentView • moduleRoot • cgi • session • request • server • httpData ColdBox Centric CFML Scopes • appPath • layoutsPath • viewsPath • modulePath • moduleLayoutsPath • modulesViewsPath Pathing
  24. 24. SettingVariables • {% set varName = “value” %} • Use + to concatenate strings • Set from other expressions {% set danger = "<br>" %} {% set foo = “<p>Hello</p>” + danger %} {{ danger }} {# will output: &lt;br&gt; #}
  25. 25. Filters • Used to modify variables • {{ name | striptags | title }} {# remove HTML and title case #} • Separated by pipe and can be chained • {{ list | join(‘, ‘) }} {# list joined by commas #} • Arguments can be positional or named, just like CF (Sort of) • {{ stringDate | date("yyyy/MMMM/d", existingFormat="yyyy-MMMM-d") }} • Can also be used via tag wrapping • {% filter upper %}
 hello
 {% endfilter %} http://www.mitchellbosecke.com/pebble/documentation/guide/basic-usage
  26. 26. Filters • abbreviate • abs • capitalize • date • default • escape • first • join • last • length • lower • numberformat • raw • rsort • slice • sort • title • trim • upper • urlencode http://www.mitchellbosecke.com/pebble/documentation
  27. 27. Tags • Written between {% %} delimiters • Control Flows • Execute Functions • Define Blocks • Macros • EndingTag is optional http://www.mitchellbosecke.com/pebble/documentation/guide/basic-usage {% block stylesheets %} <link href=”/css/reset.css” rel=”stylesheet” type=”text/css” /> {% endblock %}
  28. 28. Tags • autoescape • block • cache • extends • filter • flush • for • if • import • include • macro • parallel • set • verbatim http://www.mitchellbosecke.com/pebble/documentation {% %}
  29. 29. Functions • Called to generate content • Called by their name followed by parentheses () • Arguments can be positional or named http://www.mitchellbosecke.com/pebble/documentation/guide/basic-usage {% block "post" %} content {% endblock %} {{ block("post") }} {{ max(user.age, 80) }} {{ min(user.age, 18) }} {% for i in range(0, 3) %} {{ i }}, {% endfor %}
  30. 30. Functions • block • i18n • max • min • parent • range http://www.mitchellbosecke.com/pebble/documentation x()
  31. 31. Tests • Tests variables against common expressions using the is operator • The not operator negates them {% if user.email is empty %}     ... {% endif %} {% if 2 is even or odd %}     ... {% endif %} {% if {"apple":"red", "banana":"yellow"} is map %}     ... {% endif %} {% if user.email is null %}     ... {% endif %}
  32. 32. Tests • empty • even • map • null • odd • iterable http://www.mitchellbosecke.com/pebble/documentation √
  33. 33. Literals • "Hello World" • Everything between two double or single quotes is a string.You can use a backslash to escape quotation marks within the string. • 100 * 2.5 • Integers and floating point numbers are similar to their Java counterparts. • true / false • Boolean values equivalent to their Java counterparts. • null • Represents no specific value, similar to it's Java counterpart. none is an alias for null.
  34. 34. Collections • Both structs and arrays can be created directly • ["apple", "banana", "pear"] • {"apple":"red", "banana":"yellow", “pear":"green"} • FYI: Collections can also contain expressions
  35. 35. Math • CBT allows you to calculate values using some basic mathematical operators.The following operators are supported: • +: Addition • -: Subtraction • /: Division • %: Modulus • *: Multiplication
  36. 36. Logic • You can combine multiple expressions with the following operators: • and: Returns true if both operands are true • or: Returns true if either operand is true • not: Negates an expression • (...): Groups expressions together
  37. 37. Comparisons • The following comparison operators are supported in any expression: • ==, !=, <, >, >=, and <= {% if user.age >= 18 %}     ... {% endif %}
  38. 38. Ternary Operator • Same as CFML {{ foo ? "yes" : "no" }}
  39. 39. Operators • Supported Operators in precedence: • . • | • %, /, * • -, + • ==, !=, >, <, >=, <= • is, is not • and • or
  40. 40. Flows in-depth
  41. 41. For Loops • Loops over each item in a list, array, query or struct • Special else for empty sequences {# Arrays #} {% for user in users %}     {{ loop.index }} - {{ user.id }} {% else %}     There are no users to display. {% endfor %} {# Structs #} {% for entry in map %} {{ entry.key }} - {{ entry.value }} {% endfor %} • SpecialVariables • loop.index = numeric, loop.revindex = numeric • loop.length = numeric • loop.last = boolean, loop.first = boolean
  42. 42. For : Sequences • Iterate over sequences {% for i in range(0, 3) %} {{ i }}, {% endfor %} {# outputs 0, 1, 2, 3, #} {% for i in range(0, 6, 2) %} {{ i }}, {% endfor %} {# outputs 0, 2, 4, 6, #} {% for i in 0..3 %} {{ i }}, {% endfor %} {# outputs 0, 1, 2, 3, #} {% for letter in 'a'..'z' %}  {{ letter }}, {% endfor %}
  43. 43. if / else • Similar to Java/CFML • Leverage expressions, operators, tests, math, etc. {% if users is empty %}     There are no users. {% elseif users.length == 1 %}     There is only one user. {% else %}     There are many users. {% endif %} {# null checks#} {% if users %}
  44. 44. Going Deep
  45. 45. Macros • Reusable template fragments, think web components • Invoked like functions • Can have input arguments with default values • Only works on the input provided not the bonded context • Can be imported (reusable) {% macro input(type="text", name, value) %}     <input type="{{ type }}" name="{{ name }}" value="{{ value }}" /> {% endmacro %} {{ input(name="country") }} {# will output: <input type="text" name="country" value="" /> #} {% import "form_util" %} {{ input("text", "country", "Canada") }}
  46. 46. Whitespace • The first newline after a template tag is removed automatically • - is the whitespace control modifier • It can be used in {{- -}} or {%- -%} <p>         {{- "no whitespace" -}}     </p> {# output: "<p>no whitespace</p>" #}
  47. 47. Escaping • Automatic (html) default escape strategy or custom strategy (css, html, html_attr, js, url_param) {{ danger | raw }} • autoescape tag can be used to temporarily disable/enable the auto escaper and strategy {{ danger }} {# will be escaped by default #} {% autoescape false %}     {{ danger }} {# will not be escaped #} {% endautoescape %} {{ danger }} {# will use the "html" escaping strategy #} {% autoescape "js" %}     {{ danger }} {# will use the "js" escaping strategy #} {% endautoescape %} • raw filter to output raw html {{ danger }} {{ danger | escape( "js" ) }} {{ danger | escape( "html_attr" ) }}
  48. 48. Includes • Just like cfinclude(), please note that relative pathing needs the ./ prefix {% include "advertisement" with {"foo":"bar"} %} • Dynamic includes using expressions • You can add additional variables to the context of the included template, 
 just pass a struct using the with keyword {% include "./header.cbt" %} {% include admin ? 'adminFooter' : 'defaultFooter' %} • Dynamic includes using global variables {% include appPath + "./header.cbt" %}
  49. 49. Get Funky…again CBT
  50. 50. Template Inheritance • Most powerful part of cbt • Build a layout with most common elements • Blocks are named slots or holes in a template that a child can fill • Blocks can be used in any order • Blocks can be imported from other templates • Blocks can have default content in the middle or none at all {% block header %}     <h1> Introduction </h1> {% endblock header %} {% block footer %} {% endblock footer %}
  51. 51. Layout.cbt - Parent <!DOCTYPE html> <html lang=”en”> <head> {% block metatags %} <meta charset=”utf-8”> {% endblock %} {% block title %} <title>CBT Rules!</title> {% endblock %} {% block stylesheets %} <link href=”/includes/css/bootstrap.css” rel=”stylesheet”> {% endblock %} </head> <body> {% block body %} {% block body_inner %}{% endblock %} {% endblock %} {% block javascripts %} <script src=”/includes/js/vue.js”></script> {% endblock %} </body> </html> Block = slots for content Blocks can be nested Blocks can be empty
  52. 52. Template Child {% extends layoutsPath + "Main.twig" %} {% block stylesheets %} {{ parent() }} <link href="/includes/css/theme.css" rel="stylesheet"> {% endblock %} {% block body %} {% include "./helpers/header.cbt" %} <div class=”container theme-showcase”> {% block mainView %}{% endblock %} </div> {% include ‘./helpers/footer.cbt’ %} {% endblock %} {% block javascripts %} <script src=”/includes/js/vue.js”></script> <script src=”/includes/js/app.js”></script> {% endblock %} Extend the template Position existing content Still use includes Child changes the block
  53. 53. Template Child • extends tag should be the first tag in the template • By using the same block name you either • override completely • add content to it with the parent() function • The content of the child block can go above or below existing contents • Use {{ block( name ) }} to render blocks a-la-carte
  54. 54. More to come…. • Project still in its infancy • Will explore custom parsers via Antlr for CFML customizations • Tag libraries • Input very welcomed • The future is bright….
  55. 55. Thanks

×