The New Myth family: SprintPHP Bonfire Practical CodeIgniter 3

New Myth Media Blog

Serving the New Myth Media Family.

Practical CodeIgniter 3 Released

My new book about making the most of CodeIgniter 3 is out!

One thing the community has wanted has always been a template engine designed specifically for CodeIgniter. After a lot of discussion and back and forth during the planning phase, it was decided that we would not be bundling a template engine in, but we would make it fairly simple to integrate third-party choices. In part this was due to the wide variety of engines already available and preferences of the many developers that use the framework. Being interface-driven, that goal has been met.

However, we also decided to keep the simple Parser that we've always had. One thing that came up, though, was that if we were going to keep it, it needed to be much more useful than it has been in previous versions. Work on this is nearing completion, so I thought I would take a moment to highlight some of the new changes it brings.

The More Things Change

Looping and variable substitution work just like they always have. Variables wrapped in curly braces will be substituted with the variable's value. You can still loop over arrays of data by simply using opening and closing curly braces.

<h1>{blog_title} - {blog_heading}</h1>
{blog_entry}
    <div>
        <h2>{title}</h2>
        <p>{body}{/p}
    </div>
{/blog_entry}

The one major change here, though, is that PHP is no longer executed when parsing views.

The Little Things

Since you can no longer use any PHP, you need more tools to make the templates work for you.

Conditional Logic

Simple conditional logic is now available with the if, elseif, and else tags.

{if role=='admin'}
    <h1>Welcome, Admin</h1>
{elseif role=='moderator'}
    <h1>Welcome, Moderator</h1>
{else}
    <h1>Welcome, User</h1>
{endif}

While they syntax might look a little cleaner, it is treated exactly like a standard PHP conditional, and all standard PHP rules would apply here. You can use any of the comparison operators you would normally, like ==, ===, !==, <, >, etc.

No-Parse Blocks

If you have a section of your template that you don't want the Parser to touch, you can do that easily by wrapping it in noparse tags.

{noparse}
    ... Your un-parsed content lives here ...
{/noparse}

Comments

It's a tiny thing, but sometimes you just have to leave yourself notes in the templates, so it now supports comments that are never displayed in the final HTML.

{# This is a comment #}

Automatic Escaping

All variable substitutions are automatically escaped for safer views, greatly reducing the chance of XSS attacks and more. You can choose a different escaping context (html, attr, css, or js) depending on where the variable is appearing. It defaults to html so most of the time you won't need to do anything special to make it happen.

// Defaults to basic HTML escaping
{ some_var }
// Escape within HTML attributes
{ some_var|esc(attr) }
// Escape within Javascript code
{ some_var|esc(js) }
// Escape within CSS style blocks
{ some_var|esc(css) }

If you don't want it escaped at all, you can use {! and !} braces instead of plain curly braces and that one variable will not be escaped.

{! not_escaped_var !}

This one is still being finalized, so it's possible the syntax might change, but this is the current plan.

The Bigger Things

These next two items bring a fair amount of power to what used to be an almost pointless parser.

Filters

You saw a hint of this above when I was talking about escaping, but the parser now supports filtering the variable to affect its final display. Filters are separated by pipes (|).

// Output: FILTERED
{ filtered | upper }
// Output: Filtered
{ FILTERED | title }

Filters can have one or more parameters to specify options.

// Output: 2017-10-03
{ myDate | date(Y-m-d) }

Multiple filters can be chained together.

// Output: 2018-10-03
{ myDate | date_modify(+1 year) | date(Y-m-d) }

Filters typically only work on strings, but CodeIgniter will still ship with a number of helpful filters. And it's very simple to create your own custom ones. The built-in ones are currently:

  • abs
  • capitalize
  • date
  • date_modify
  • default
  • esc
  • excerpt
  • highlight
  • highlight_code
  • limit_words
  • limit_chars
  • lower
  • nl2br
  • number_format
  • prose
  • round
  • strip_tags
  • title
  • upper

Plugins

Word of Warning: This feature is a concept only at this time, and actually implementation hasn't started, yet, but this is what's kicking around in my head. Syntax likely to change.

Plugins are a nod to Expression Engine's syntax that allows you to extend the capability of the Parser to fit most any need that you might have. Heck, you could probably flesh out any missing features needed for a template engine through plugins.

Basically, plugins allow you to specify an alias tag that a library's features can be called from. They are very similar in concept to View Cells, though I believe they'll be able to do some things that Cells can't. The only plugin expected to ship with the framework is the View Cell feature, actually.

This probably best makes sense with an example. Let's just use the View Cell feature to demonstrate, then. With Cells you can specify a class/method to generate and return HTML that is rendered in the Cell's place. It's tag might look something like this:

// A Simple version
{ cell: Acme\Blog\Posts::recentPosts }
// With Parameters
{ cell: Acme\Blog\Posts::recentPosts category=codeigniter limit=5 }

If the Acme\Blog package wanted to make things a little cleaner and create some View plugins, they might provide something like the following:

{ blog:recentPosts category=codeigniter limit=5 }

Again, all of this plugin syntax is preliminary and subject to change, but it's coming.


Hopefully, this type of Parser can be useful to some of you.