Skip to content

Instantly share code, notes, and snippets.

@brandonkelly
Last active March 11, 2025 21:41

Revisions

  1. brandonkelly revised this gist Nov 16, 2016. 1 changed file with 6 additions and 6 deletions.
    12 changes: 6 additions & 6 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -7,12 +7,12 @@ Here are a few common tasks you might do in your templates, as they would be wri
    1. [Comments](#1-comments)
    2. [Conditionals](#2-conditionals)
    3. [Loops](#3-loops)
    4. [Looping through entries](#4-looping-through-entries)
    5. [Single-entry pages](#5-single-entry-pages)
    6. [Looping through Matrix rows](#6-looping-through-matrix-rows)
    7. [Looping through assets](#7-looping-through-assets)
    8. [Template inheritance](#8-template-inheritance)
    9. [Template includes](#9-template-includes)
    4. [Looping Through Entries](#4-looping-through-entries)
    5. [Single-Entry Pages](#5-single-entry-pages)
    6. [Looping Through Matrix Rows](#6-looping-through-matrix-rows)
    7. [Looping Through Assets](#7-looping-through-assets)
    8. [Template Inheritance](#8-template-inheritance)
    9. [Template Includes](#9-template-includes)
    10. [Stuff You Can Only Do in Craft](#10-stuff-you-can-only-do-in-craft)
    11. [Other Resources](#11-other-resources)

  2. brandonkelly revised this gist Nov 16, 2016. 1 changed file with 95 additions and 95 deletions.
    190 changes: 95 additions & 95 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,6 @@
    # Templating in EE vs. Craft
    # Templating in EE vs. Craft CMS.

    Lots of people have asked, so here are a few common tasks you might do in your templates, as they
    would be written in ExpressionEngine vs. Craft.
    Here are a few common tasks you might do in your templates, as they would be written in ExpressionEngine vs. Craft CMS.

    ### Table of Contents

    @@ -12,10 +11,10 @@ would be written in ExpressionEngine vs. Craft.
    5. [Single-entry pages](#5-single-entry-pages)
    6. [Looping through Matrix rows](#6-looping-through-matrix-rows)
    7. [Looping through assets](#7-looping-through-assets)
    8. [DRY site header and footer](#8-dry-site-header-and-footer)
    8. [Template inheritance](#8-template-inheritance)
    9. [Template includes](#9-template-includes)
    10. [Stuff you can only do in Craft](#10-stuff-you-can-only-do-in-craft)
    11. [Stuff you can only do in EE](#11-stuff-you-can-only-do-in-ee)
    10. [Stuff You Can Only Do in Craft](#10-stuff-you-can-only-do-in-craft)
    11. [Other Resources](#11-other-resources)

    ----------------------------------------------------------------------------------------------------

    @@ -80,7 +79,7 @@ Resources:

    #### ExpressionEngine

    EE loops are always done with a tag pair, named after what we’re looping through.
    EE loops are always done with tag pairs, named after what we’re looping through.

    ```
    {exp:channel:entries channel="news"}
    @@ -104,10 +103,7 @@ through, as well as what you want to call each item within the loop.
    {% endfor %}
    ```

    There are pros and cons to both ways: EE’s is more elegant for simple things, but you can quickly
    run into tag name conflicts and other gotcha’s when dealing with more complex templates. That’s
    never an issue with Craft, but it’s at the expense of a more verbose and less straightforward
    syntax.
    There are pros and cons to both ways: EE’s is arguably more elegant for simple things, but you can quickly run into tag name conflicts and other gotchas when dealing with more complex templates with nested loops. That’s never an issue with Craft.

    Both CMSes have various tags that are available within the loops, as well:

    @@ -132,17 +128,17 @@ Both CMSes have various tags that are available within the loops, as well:
    </tr>
    <tr>
    <td>0-based index</td>
    <td><em>SOL</em></td>
    <td>-</td>
    <td>{{ loop.index0 }}</td>
    </tr>
    <tr>
    <td>Number of items left</td>
    <td><em>SOL</em></td>
    <td>-</td>
    <td>{{ loop.revindex0 }}</td>
    </tr>
    <tr>
    <td>Number of ites left, inc. this one</td>
    <td><em>SOL</em></td>
    <td>-</td>
    <td>{{ loop.revindex }}</td>
    </tr>
    <tr>
    @@ -172,7 +168,7 @@ Both CMSes have various tags that are available within the loops, as well:
    </tr>
    <tr>
    <td>The parent loop’s index</td>
    <td><em>SOL</em></td>
    <td>-</td>
    <td>{{ loop.parent.loop.index }}</td>
    </tr>
    </tbody>
    @@ -184,12 +180,11 @@ Resources:

    ----------------------------------------------------------------------------------------------------

    ## 4. Looping through entries
    ## 4. Looping Through Entries

    #### ExpressionEngine

    ExpressionEngine’s `{exp:channel:entries}` tag is optimized for this task (assuming you’re not on a
    single-entry page!). Just tell it which channel, how many, and so on.
    ExpressionEngine’s `{exp:channel:entries}` tag is optimized for this task. Just tell it which channel, how many, and so on. (And don’t forget `dynamic="no"` on single-entry pages!)

    ```
    {exp:channel:entries channel="news" limit="10"}
    @@ -201,7 +196,7 @@ single-entry page!). Just tell it which channel, how many, and so on.
    #### Craft

    In Craft you grab the entries using
    [craft.entries](http://buildwithcraft.com/docs/templating/craft.entries) and loop through them with
    [craft.entries](https://craftcms.com/docs/templating/craft.entries) and loop through them with
    a [for-loop](http://twig.sensiolabs.org/doc/tags/for.html). You get to choose a variable name that
    each entry is going to be set to. In this case we’re going with `newsEntry` so it’s clear which
    ‘title’ we’re outputting, etc..
    @@ -215,17 +210,16 @@ each entry is going to be set to. In this case we’re going with `newsEntry` so

    Resources:

    - [craft.entries docs](http://buildwithcraft.com/docs/templating/craft.entries)
    - [EntryModel docs](http://buildwithcraft.com/docs/templating/entrymodel)
    - [craft.entries docs](https://craftcms.com/docs/templating/craft.entries)
    - [EntryModel docs](https://craftcms.com/docs/templating/entrymodel)

    ----------------------------------------------------------------------------------------------------

    ## 5. Single-entry pages
    ## 5. Single-Entry Pages

    #### ExpressionEngine

    Assuming everything’s in the right place, this is the one time the `dynamic` parameter will actually
    help you out, saving you from having to type `url_title="{segment_2}" limit="1"` (Whew!).
    On templates EE thinks are for displaying a single entry, `{exp:channel:entries}` will only return that one entry by default – based on a URL Title match with the second URI segment.

    ```
    {exp:channel:entries channel="news"}
    @@ -236,10 +230,7 @@ help you out, saving you from having to type `url_title="{segment_2}" limit="1"`

    #### Craft

    Entries in Craft have their own URLs, so Craft knows for a fact which entry you’re trying to access,
    and which template it should load. In the process it will pass an `entry` variable, pre-set to the
    entry you’re accessing. (In this case you don’t get a choice on what the `entry` variable name is
    going to be called.)
    Entries in Craft can have explicit URLs, so when one of those URLs is requested, Craft can confidently know which entry you’re trying to access, and which template it should load. In the process it will pass an `entry` variable, pre-set to the entry you’re accessing. (Note that in this case the `entry` variable name is not customizable.)

    ```jinja
    <h1>{{ entry.title }}</h1>
    @@ -248,11 +239,11 @@ going to be called.)

    Resources:

    - [Craft Routing docs](http://buildwithcraft.com/docs/routing)
    - [Craft Routing docs](https://craftcms.com/docs/routing)

    ----------------------------------------------------------------------------------------------------

    ## 6. Looping through Matrix rows
    ## 6. Looping Through Matrix Rows

    #### ExpressionEngine

    @@ -283,33 +274,29 @@ If you have multiple block types, you can add conditionals for them:
    ```jinja
    {% for block in entry.matrixField %}
    {% if block.type == "text" %}
    {{ block.textField }}
    {% elseif block.type == "quote" %}
    <blockquote>{{ block.quoteField }}</blockquote>
    <p>– {{ block.authorField }}</p>
    {% endif %}
    {% endfor %}
    ```

    Resources:

    - [MatrixBlockModel docs](http://buildwithcraft.com/docs/templating/matrixblockmodel)
    - [MatrixBlockModel docs](https://craftcms.com/docs/templating/matrixblockmodel)

    ----------------------------------------------------------------------------------------------------

    ## 7. Looping through assets
    ## 7. Looping Through Assets

    #### ExpressionEngine

    Like Matrix/EE, Assets uses a tag pair based on the field’s short name:

    ```
    {assets_field}
    <img src="{url:image_manipulation_name}" alt="{title}"> {filename}
    <img src="{url:image_manipulation_name}" alt="{title}"> {filename}
    {/assets_field}
    ```

    @@ -326,30 +313,26 @@ Like entries and Matrix fields in Craft, we once again use the

    Resources:

    - [AssetFileModel docs](http://buildwithcraft.com/docs/templating/assetfilemodel)
    - [AssetFileModel docs](https://craftcms.com/docs/templating/assetfilemodel)

    ----------------------------------------------------------------------------------------------------

    ## 8. DRY site header and footer
    ## 8. Template Inheritance

    #### ExpressionEngine

    In EE you would do this with two embedded templates, which you’d manually include in every normal
    template.
    EE 2.8 introduced [Template Layouts](https://docs.expressionengine.com/latest/templates/layouts.html), which makes it possible for templates to extend other templates, via the `{layout=}` tag:

    ###### includes/_header
    ###### site/.site-layout

    ```
    <html>
    <head>
    <title>{if embed:page_name}{embed:page_name} - {/if}{site_name}</title>
    <title>{layout:title}</title>
    </head>
    <body>
    ```

    ###### includes/_footer
    {layout:contents}
    ```
    <p class="copyright">
    &copy; {current_time format='%Y'} {site_name}
    </p>
    @@ -360,25 +343,25 @@ template.
    ###### news/index

    ```
    {embed="includes/_header" page_name="News"}
    <h1>News</h1>
    ...
    {embed="includes/_footer"}
    {layout="site/.site-layout"}
    {layout:set name="title" value="News"}
    {exp:channel:entries channel="news"}
    <h2>{title}</h2>
    {summary}
    {/exp:channel:entries}
    ```

    #### Craft

    Craft has the concept of
    [Template Inheritance](http://twig.sensiolabs.org/doc/templates.html#template-inheritance), which
    lets you define all of the common site elements in a single template, and extend it with
    sub-templates where necessary.
    The same is also possible in Twig:

    ###### \_site_layout.html

    ```jinja
    <html>
    <head>
    <title>{% if pageName is defined %}{{ pageName }} - {% endif %}{{ siteName }}</title>
    <title>{{ title }}</title>
    </head>
    <body>
    @@ -397,28 +380,29 @@ sub-templates where necessary.

    ```jinja
    {% extends "_site_layout" %}
    {% set pageName = "News" %}
    {% set title = "News" %}
    {% block body %}
    <h1>News</h1>
    ...
    {% endblock %}
    ```

    There is one key difference between EE and Twig here: In Twig, if a template extends another, all of its HTML output must be placed within `{% block %}...{% endblock %}` tags. If the template attepmts to output anything outside of block tags, Twig will complain about it. Whereas in EE, all of the HTML that is output gets sucked into a single “block” called `contents`, which is output in the layout template with `{layout:contents}`.

    Resources:

    - [Twig’s Template Inheritance docs](http://twig.sensiolabs.org/doc/templates.html#template-inheritance)

    ----------------------------------------------------------------------------------------------------

    ## 9. Template includes
    ## 9. Template Includes

    #### ExpressionEngine

    As demonstrated [above](#8-dry-site-header-and-footer), you can include other templates in EE using
    the `{embed}` tag, passing any variables you want available to the embedded template as parameters:
    You can include other templates in EE using the `{embed}` tag, passing any variables you want available to the embedded template as parameters:

    ###### Parent template:
    ###### Parent Template:

    ```
    {embed="includes/_photo_gallery" entry_id="{entry_id}"}
    @@ -438,11 +422,11 @@ the `{embed}` tag, passing any variables you want available to the embedded temp

    #### Craft

    Craft has a similar tag, called [{% include %}](http://twig.sensiolabs.org/doc/tags/include.html).
    Twig has a similar tag, called [`{% include %}`](http://twig.sensiolabs.org/doc/tags/include.html).
    Unlike `{embed}`, all variables that are already defined in the template leading up to the
    `{% include %}` tag will automatically be available to the included template.

    ###### Parent template:
    ###### Parent Template:

    ```jinja
    {% include "_includes/photo_gallery" %}
    @@ -466,7 +450,7 @@ defined in the parent. In the above example, we might not want the include templ
    the entry variable’s name, and just be passed the array of images directly. We could do do that with
    this syntax:

    ###### Parent template:
    ###### Parent Template:

    ```jinja
    {% include "_includes/photo_gallery" with {
    @@ -488,19 +472,51 @@ Now the include template is expecting to be passed a `photos` variable, and it
    including it to ensure that `photos` is set properly. Thanks to that `with` parameter, we can do
    that without having to make a `photos` variable available to the parent template.

    ### The {% embed %} Tag

    Twig also has an [`{% embed %}`](http://twig.sensiolabs.org/doc/tags/embed.html) tag, which you can think of as a more dynamic version of `{% include %}`. In addition to including a template into the parent template, it also allows the parent template to override aspects of the included template, using `{% block %}` tags.

    Here’s a simple example, where a photo gallery include template allows its parent templates to override a header area:

    ###### Parent Template:

    ```jinja
    {% embed "_includes/photo_gallery" %}
    {% block header %}
    <h3>The Best Photo Gallery</h3>
    {% endblock %}
    {% endembed %}
    ```

    ###### \_includes/photo_gallery:

    ```jinja
    {% block header %}
    <h3>Photo Gallery</h3>
    {% endblock %}
    <div class="gallery">
    {% for photo in entry.assetsField %}
    <img src="{{ photo.url('transformHandle') }}">
    {% endfor %}
    </div>
    ```


    Resources:

    - [Twig’s {% include %} docs](http://twig.sensiolabs.org/doc/tags/include.html)
    - [Twig’s {% embed %} docs](http://twig.sensiolabs.org/doc/tags/embed.html)

    ----------------------------------------------------------------------------------------------------

    ## 10. Stuff you can only do in Craft
    ## 10. Stuff You Can Only Do in Craft

    All of the above examples have been focused on things that are relatively easy to do in both EE and
    Craft. But thanks to Twig, there are a ton of things you can easily do in Craft that aren’t even
    possible in EE out of the box.

    #### Set variables in the templates
    #### Set Custom Variables

    You’re not stuck with a limited set of variable tags in Craft. Thanks to Twig, you can define new
    variables right in your templates, manipulate them, and output them as you see fit.
    @@ -523,22 +539,11 @@ Resources:
    - [Twig’s {% set %} tag docs](http://twig.sensiolabs.org/doc/tags/set.html)
    - [Twig’s filter docs ](http://twig.sensiolabs.org/doc/templates.html#filters)

    #### Mathmatical operations

    There are plenty of times where it’s nice to be able to do a little math in your templates.
    #### Advanced Math

    ```jinja
    {{ 2 + 2 }}
    {% set total = 2 + 2 %}
    {{ total }}
    ```

    Resources:

    - [Twig’s Math docs](http://twig.sensiolabs.org/doc/templates.html#math)
    All sorts of advanced math operations are possible in Twig thanks to its rich support of [mathematical operators](http://twig.sensiolabs.org/doc/templates.html#math)

    #### String manipulations
    #### String Manipulations

    You can concatenate strings, modify them, split them into arrays, or pretty much anything else you
    can think of.
    @@ -562,7 +567,7 @@ Resources:
    - [Twig’s {% set %} tag docs](http://twig.sensiolabs.org/doc/tags/set.html)
    - [Twig’s filter docs ](http://twig.sensiolabs.org/doc/templates.html#filters)

    #### Create arrays
    #### Create Arrays

    You aren’t limited to creating simple numbers and strings. You can even create full-blown arrays:

    @@ -594,24 +599,19 @@ There’s also a shorthand syntax for creating arrays of consecutive numbers:
    </select>
    ```

    #### So much more
    ----------------------------------------------------------------------------------------------------

    Twig has _tons_ of useful features that make developing templates a breeze, and Craft adds even more
    features on top of that!
    ## 11. Other Resources

    If you want to learn more, here are a few helpful templating resources:

    - [Twig for Template Designers](http://twig.sensiolabs.org/doc/templates.html) (the official docs)
    - [Twig for Template Designers](http://twig.sensiolabs.org/doc/templates.html) – the official Twig documentation
    - [Twig Templates in Craft](https://mijingo.com/products/screencasts/twig-templates-in-craft/) – Video course by Mijingo
    - [Control Flow in Twig](https://mijingo.com/products/screencasts/control-flow-in-twig/) – Video course by Mijingo
    - [Twig’s core tags](http://twig.sensiolabs.org/doc/tags/index.html)
    - [Twig’s core filters](http://twig.sensiolabs.org/doc/filters/index.html)
    - [Twig’s core functions](http://twig.sensiolabs.org/doc/functions/index.html)
    - [Craft-added tags](http://buildwithcraft.com/docs/templating/tags)
    - [Craft-added filters](http://buildwithcraft.com/docs/templating/filters)
    - [Craft-added functions](http://buildwithcraft.com/docs/templating/functions)
    - [Global template variables in Craft](http://buildwithcraft.com/docs/templating/global-variables)

    ----------------------------------------------------------------------------------------------------

    ## 11. Stuff you can only do in EE

    *Cough*
    - [Craft-added tags](https://craftcms.com/docs/templating/tags)
    - [Craft-added filters](https://craftcms.com/docs/templating/filters)
    - [Craft-added functions](https://craftcms.com/docs/templating/functions)
    - [Global template variables in Craft](https://craftcms.com/docs/templating/global-variables)
  3. brandonkelly revised this gist Apr 28, 2015. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -158,12 +158,12 @@ Both CMSes have various tags that are available within the loops, as well:
    <tr>
    <td>Odd?</td>
    <td>{if count % 2 == 1}</td>
    <td>{% if loop.odd %}</td>
    <td>{% if loop.index is odd %}</td>
    </tr>
    <tr>
    <td>Even?</td>
    <td>{if count % 2 == 0}</td>
    <td>{% if loop.even %}</td>
    <td>{% if loop.index is even %}</td>
    </tr>
    <tr>
    <td>Cycle through values for each item</td>
  4. brandonkelly revised this gist Dec 12, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion templating.md
    Original file line number Diff line number Diff line change
    @@ -97,7 +97,7 @@ Looping through things in Craft is always done with a
    through, as well as what you want to call each item within the loop.

    ```jinja
    {% for entry in craft.entries.channel('news') %}
    {% for entry in craft.entries.section('news') %}
    {% for block in entry.matrixField %}
    ...
    {% endfor %}
  5. brandonkelly revised this gist Dec 1, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion templating.md
    Original file line number Diff line number Diff line change
    @@ -168,7 +168,7 @@ Both CMSes have various tags that are available within the loops, as well:
    <tr>
    <td>Cycle through values for each item</td>
    <td>{switch='odd|even'}</td>
    <td>{{ cycle(['odd','even'], loop.index0 }}</td>
    <td>{{ cycle(['odd','even'], loop.index0) }}</td>
    </tr>
    <tr>
    <td>The parent loop’s index</td>
  6. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion templating.md
    Original file line number Diff line number Diff line change
    @@ -438,7 +438,7 @@ the `{embed}` tag, passing any variables you want available to the embedded temp

    #### Craft

    Craft has a similar tag, called [{% includ %}](http://twig.sensiolabs.org/doc/tags/include.html).
    Craft has a similar tag, called [{% include %}](http://twig.sensiolabs.org/doc/tags/include.html).
    Unlike `{embed}`, all variables that are already defined in the template leading up to the
    `{% include %}` tag will automatically be available to the included template.

  7. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion templating.md
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@ would be written in ExpressionEngine vs. Craft.
    8. [DRY site header and footer](#8-dry-site-header-and-footer)
    9. [Template includes](#9-template-includes)
    10. [Stuff you can only do in Craft](#10-stuff-you-can-only-do-in-craft)
    11. [Stuff you can only do in EE](#11-stuff-you-can-only-do-in-craft)
    11. [Stuff you can only do in EE](#11-stuff-you-can-only-do-in-ee)

    ----------------------------------------------------------------------------------------------------

  8. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 7 additions and 0 deletions.
    7 changes: 7 additions & 0 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -15,6 +15,7 @@ would be written in ExpressionEngine vs. Craft.
    8. [DRY site header and footer](#8-dry-site-header-and-footer)
    9. [Template includes](#9-template-includes)
    10. [Stuff you can only do in Craft](#10-stuff-you-can-only-do-in-craft)
    11. [Stuff you can only do in EE](#11-stuff-you-can-only-do-in-craft)

    ----------------------------------------------------------------------------------------------------

    @@ -608,3 +609,9 @@ If you want to learn more, here are a few helpful templating resources:
    - [Craft-added filters](http://buildwithcraft.com/docs/templating/filters)
    - [Craft-added functions](http://buildwithcraft.com/docs/templating/functions)
    - [Global template variables in Craft](http://buildwithcraft.com/docs/templating/global-variables)

    ----------------------------------------------------------------------------------------------------

    ## 11. Stuff you can only do in EE

    *Cough*
  9. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion templating.md
    Original file line number Diff line number Diff line change
    @@ -563,7 +563,7 @@ Resources:

    #### Create arrays

    You aren’t limited to creating simple numbers and strings. You can ever create full-blown arrays:
    You aren’t limited to creating simple numbers and strings. You can even create full-blown arrays:

    ```jinja
    {% set nav = [
  10. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion templating.md
    Original file line number Diff line number Diff line change
    @@ -495,7 +495,7 @@ Resources:

    ## 10. Stuff you can only do in Craft

    All of the above examples have been focussed on things that are relatively easy to do in both EE and
    All of the above examples have been focused on things that are relatively easy to do in both EE and
    Craft. But thanks to Twig, there are a ton of things you can easily do in Craft that aren’t even
    possible in EE out of the box.

  11. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 12 additions and 12 deletions.
    24 changes: 12 additions & 12 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -35,7 +35,7 @@ that never make it to the browser.
    {# You can’t see me! #}
    ```

    ##### Resources
    Resources:

    - [Twig’s comment tag docs](http://twig.sensiolabs.org/doc/templates.html#comments)

    @@ -67,7 +67,7 @@ that never make it to the browser.
    {% endif %}
    ```

    ##### Resources
    Resources:

    - [Twig’s {% if %} tag docs](http://twig.sensiolabs.org/doc/tags/if.html)
    - [Twig’s logical operator docs](http://twig.sensiolabs.org/doc/templates.html#logic)
    @@ -177,7 +177,7 @@ Both CMSes have various tags that are available within the loops, as well:
    </tbody>
    </table>

    ##### Resources
    Resources:

    - [Twig’s {% for %} tag docs](http://twig.sensiolabs.org/doc/tags/for.html)

    @@ -212,7 +212,7 @@ each entry is going to be set to. In this case we’re going with `newsEntry` so
    {% endfor %}
    ```

    ##### Resources
    Resources:

    - [craft.entries docs](http://buildwithcraft.com/docs/templating/craft.entries)
    - [EntryModel docs](http://buildwithcraft.com/docs/templating/entrymodel)
    @@ -245,7 +245,7 @@ going to be called.)
    {{ entry.body }}
    ```

    ##### Resources
    Resources:

    - [Craft Routing docs](http://buildwithcraft.com/docs/routing)

    @@ -294,7 +294,7 @@ If you have multiple block types, you can add conditionals for them:
    {% endfor %}
    ```

    ##### Resources
    Resources:

    - [MatrixBlockModel docs](http://buildwithcraft.com/docs/templating/matrixblockmodel)

    @@ -323,7 +323,7 @@ Like entries and Matrix fields in Craft, we once again use the
    {% endfor %}
    ```

    ##### Resources
    Resources:

    - [AssetFileModel docs](http://buildwithcraft.com/docs/templating/assetfilemodel)

    @@ -404,7 +404,7 @@ sub-templates where necessary.
    {% endblock %}
    ```

    ##### Resources
    Resources:

    - [Twig’s Template Inheritance docs](http://twig.sensiolabs.org/doc/templates.html#template-inheritance)

    @@ -487,7 +487,7 @@ Now the include template is expecting to be passed a `photos` variable, and it
    including it to ensure that `photos` is set properly. Thanks to that `with` parameter, we can do
    that without having to make a `photos` variable available to the parent template.

    ##### Resources
    Resources:

    - [Twig’s {% include %} docs](http://twig.sensiolabs.org/doc/tags/include.html)

    @@ -517,7 +517,7 @@ variables right in your templates, manipulate them, and output them as you see f
    </html>
    ```

    ##### Resources
    Resources:

    - [Twig’s {% set %} tag docs](http://twig.sensiolabs.org/doc/tags/set.html)
    - [Twig’s filter docs ](http://twig.sensiolabs.org/doc/templates.html#filters)
    @@ -533,7 +533,7 @@ There are plenty of times where it’s nice to be able to do a little math in yo
    {{ total }}
    ```

    ##### Resources
    Resources:

    - [Twig’s Math docs](http://twig.sensiolabs.org/doc/templates.html#math)

    @@ -556,7 +556,7 @@ can think of.
    {{ greeting | upper }}
    ```

    ##### Resources
    Resources:

    - [Twig’s {% set %} tag docs](http://twig.sensiolabs.org/doc/tags/set.html)
    - [Twig’s filter docs ](http://twig.sensiolabs.org/doc/templates.html#filters)
  12. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 135 additions and 40 deletions.
    175 changes: 135 additions & 40 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,7 @@
    # Templating in EE vs. Craft

    Lots of people have asked, so here are a few common tasks you might do in your templates, as they would be written in ExpressionEngine vs. Craft.
    Lots of people have asked, so here are a few common tasks you might do in your templates, as they
    would be written in ExpressionEngine vs. Craft.

    ### Table of Contents

    @@ -15,11 +16,12 @@ Lots of people have asked, so here are a few common tasks you might do in your t
    9. [Template includes](#9-template-includes)
    10. [Stuff you can only do in Craft](#10-stuff-you-can-only-do-in-craft)

    ---
    ----------------------------------------------------------------------------------------------------

    ## 1. Comments

    Let’s start simple! Both CMSes support comment tags, enabling you to make notes in the template code that never make it to the browser.
    Let’s start simple! Both CMSes support comment tags, enabling you to make notes in the template code
    that never make it to the browser.

    #### ExpressionEngine

    @@ -33,7 +35,11 @@ Let’s start simple! Both CMSes support comment tags, enabling you to make note
    {# You can’t see me! #}
    ```

    ---
    ##### Resources

    - [Twig’s comment tag docs](http://twig.sensiolabs.org/doc/templates.html#comments)

    ----------------------------------------------------------------------------------------------------

    ## 2. Conditionals

    @@ -61,9 +67,13 @@ Let’s start simple! Both CMSes support comment tags, enabling you to make note
    {% endif %}
    ```

    See [Twig’s {% if %} docs](http://twig.sensiolabs.org/doc/tags/if.html) for more info.
    ##### Resources

    ---
    - [Twig’s {% if %} tag docs](http://twig.sensiolabs.org/doc/tags/if.html)
    - [Twig’s logical operator docs](http://twig.sensiolabs.org/doc/templates.html#logic)
    - [Twig’s comparrisson operator docs](http://twig.sensiolabs.org/doc/templates.html#comparisons)

    ----------------------------------------------------------------------------------------------------

    ## 3. Loops

    @@ -81,7 +91,9 @@ EE loops are always done with a tag pair, named after what we’re looping throu

    #### Craft

    Looping through things in Craft is always done with a [for-loop](http://twig.sensiolabs.org/doc/tags/for.html), where you pass in what you want to loop through, as well as what you want to call each item within the loop.
    Looping through things in Craft is always done with a
    [for-loop](http://twig.sensiolabs.org/doc/tags/for.html), where you pass in what you want to loop
    through, as well as what you want to call each item within the loop.

    ```jinja
    {% for entry in craft.entries.channel('news') %}
    @@ -91,7 +103,10 @@ Looping through things in Craft is always done with a [for-loop](http://twig.sen
    {% endfor %}
    ```

    There are pros and cons to both ways: EE’s is more elegant for simple things, but you can quickly run into tag name conflicts and other gotcha’s when dealing with more complex templates. That’s never an issue with Craft, but it’s at the expense of a more verbose and less straightforward syntax.
    There are pros and cons to both ways: EE’s is more elegant for simple things, but you can quickly
    run into tag name conflicts and other gotcha’s when dealing with more complex templates. That’s
    never an issue with Craft, but it’s at the expense of a more verbose and less straightforward
    syntax.

    Both CMSes have various tags that are available within the loops, as well:

    @@ -162,15 +177,18 @@ Both CMSes have various tags that are available within the loops, as well:
    </tbody>
    </table>

    See [Twig’s {% for %} docs](http://twig.sensiolabs.org/doc/tags/for.html) for more info.
    ##### Resources

    - [Twig’s {% for %} tag docs](http://twig.sensiolabs.org/doc/tags/for.html)

    ---
    ----------------------------------------------------------------------------------------------------

    ## 4. Looping through entries

    #### ExpressionEngine

    ExpressionEngine’s `{exp:channel:entries}` tag is optimized for this task (assuming you’re not on a single-entry page!). Just tell it which channel, how many, and so on.
    ExpressionEngine’s `{exp:channel:entries}` tag is optimized for this task (assuming you’re not on a
    single-entry page!). Just tell it which channel, how many, and so on.

    ```
    {exp:channel:entries channel="news" limit="10"}
    @@ -181,7 +199,11 @@ ExpressionEngine’s `{exp:channel:entries}` tag is optimized for this task (ass

    #### Craft

    In Craft you grab the entries using [craft.entries](http://buildwithcraft.com/docs/templating/craft.entries) and loop through them with a [for-loop](http://twig.sensiolabs.org/doc/tags/for.html). You get to choose a variable name that each entry is going to be set to. In this case we’re going with `newsEntry` so it’s clear which ‘title’ we’re outputting, etc..
    In Craft you grab the entries using
    [craft.entries](http://buildwithcraft.com/docs/templating/craft.entries) and loop through them with
    a [for-loop](http://twig.sensiolabs.org/doc/tags/for.html). You get to choose a variable name that
    each entry is going to be set to. In this case we’re going with `newsEntry` so it’s clear which
    ‘title’ we’re outputting, etc..

    ```jinja
    {% for newsEntry in craft.entries.section('news').limit(10) %}
    @@ -190,15 +212,19 @@ In Craft you grab the entries using [craft.entries](http://buildwithcraft.com/do
    {% endfor %}
    ```

    See [EntryModel](http://buildwithcraft.com/docs/templating/entrymodel) for more info on those entry variables.
    ##### Resources

    ---
    - [craft.entries docs](http://buildwithcraft.com/docs/templating/craft.entries)
    - [EntryModel docs](http://buildwithcraft.com/docs/templating/entrymodel)

    ----------------------------------------------------------------------------------------------------

    ## 5. Single-entry pages

    #### ExpressionEngine

    Assuming everything’s in the right place, this is the one time the `dynamic` parameter will actually help you out, saving you from having to type `url_title="{segment_2}" limit="1"` (Whew!).
    Assuming everything’s in the right place, this is the one time the `dynamic` parameter will actually
    help you out, saving you from having to type `url_title="{segment_2}" limit="1"` (Whew!).

    ```
    {exp:channel:entries channel="news"}
    @@ -209,20 +235,28 @@ Assuming everything’s in the right place, this is the one time the `dynamic` p

    #### Craft

    Entries in Craft have their own URLs, so Craft knows for a fact which entry you’re trying to access, and which template it should load. In the process it will pass an `entry` variable, pre-set to the entry you’re accessing. (In this case you don’t get a choice on what the `entry` variable name is going to be called.)
    Entries in Craft have their own URLs, so Craft knows for a fact which entry you’re trying to access,
    and which template it should load. In the process it will pass an `entry` variable, pre-set to the
    entry you’re accessing. (In this case you don’t get a choice on what the `entry` variable name is
    going to be called.)

    ```jinja
    <h1>{{ entry.title }}</h1>
    {{ entry.body }}
    ```

    ---
    ##### Resources

    - [Craft Routing docs](http://buildwithcraft.com/docs/routing)

    ----------------------------------------------------------------------------------------------------

    ## 6. Looping through Matrix rows

    #### ExpressionEngine

    Matrix follows the standard EE fieldtype convention of parsing a tag pair based on the field’s short name:
    Matrix follows the standard EE fieldtype convention of parsing a tag pair based on the field’s short
    name:

    ```
    {matrix_field}
    @@ -233,7 +267,8 @@ Matrix follows the standard EE fieldtype convention of parsing a tag pair based

    #### Craft

    As with looping through entries, we loop through Matrix blocks using a [for-loop](http://twig.sensiolabs.org/doc/tags/for.html).
    As with looping through entries, we loop through Matrix blocks using a
    [for-loop](http://twig.sensiolabs.org/doc/tags/for.html).

    ```jinja
    {% for block in entry.matrixField %}
    @@ -259,9 +294,11 @@ If you have multiple block types, you can add conditionals for them:
    {% endfor %}
    ```

    See [MatrixBlockModel](http://buildwithcraft.com/docs/templating/matrixblockmodel) for more info on those Matrix block variables.
    ##### Resources

    - [MatrixBlockModel docs](http://buildwithcraft.com/docs/templating/matrixblockmodel)

    ---
    ----------------------------------------------------------------------------------------------------

    ## 7. Looping through assets

    @@ -277,23 +314,27 @@ Like Matrix/EE, Assets uses a tag pair based on the field’s short name:

    #### Craft

    Like entries and Matrix fields in Craft, we once again use the [for-loop](http://twig.sensiolabs.org/doc/tags/for.html) to loop through assets:
    Like entries and Matrix fields in Craft, we once again use the
    [for-loop](http://twig.sensiolabs.org/doc/tags/for.html) to loop through assets:

    ```jinja
    {% for asset in entry.assetsField %}
    <img src="{{ asset.url('transformHandle') }}" alt="{{ asset.title }}"> {{ asset.filename }}
    {% endfor %}
    ```

    See [AssetFileModel](http://buildwithcraft.com/docs/templating/assetfilemodel) for more info on those asset variables.
    ##### Resources

    ---
    - [AssetFileModel docs](http://buildwithcraft.com/docs/templating/assetfilemodel)

    ----------------------------------------------------------------------------------------------------

    ## 8. DRY site header and footer

    #### ExpressionEngine

    In EE you would do this with two embedded templates, which you’d manually include in every normal template.
    In EE you would do this with two embedded templates, which you’d manually include in every normal
    template.

    ###### includes/_header

    @@ -326,7 +367,10 @@ In EE you would do this with two embedded templates, which you’d manually incl

    #### Craft

    Craft has the concept of [Template Inheritance](http://twig.sensiolabs.org/doc/templates.html#template-inheritance), which lets you define all of the common site elements in a single template, and extend it with sub-templates where necessary.
    Craft has the concept of
    [Template Inheritance](http://twig.sensiolabs.org/doc/templates.html#template-inheritance), which
    lets you define all of the common site elements in a single template, and extend it with
    sub-templates where necessary.

    ###### \_site_layout.html

    @@ -360,13 +404,18 @@ Craft has the concept of [Template Inheritance](http://twig.sensiolabs.org/doc/t
    {% endblock %}
    ```

    ---
    ##### Resources

    - [Twig’s Template Inheritance docs](http://twig.sensiolabs.org/doc/templates.html#template-inheritance)

    ----------------------------------------------------------------------------------------------------

    ## 9. Template includes

    #### ExpressionEngine

    As demonstrated [above](#8-dry-site-header-and-footer), you can include other templates in EE using the `{embed}` tag, passing any variables you want available to the embedded template as parameters:
    As demonstrated [above](#8-dry-site-header-and-footer), you can include other templates in EE using
    the `{embed}` tag, passing any variables you want available to the embedded template as parameters:

    ###### Parent template:

    @@ -388,7 +437,9 @@ As demonstrated [above](#8-dry-site-header-and-footer), you can include other te

    #### Craft

    Craft has a similar tag, called [{% includ %}](http://twig.sensiolabs.org/doc/tags/include.html). Unlike `{embed}`, all variables that are already defined in the template leading up to the `{% include %}` tag will automatically be available to the included template.
    Craft has a similar tag, called [{% includ %}](http://twig.sensiolabs.org/doc/tags/include.html).
    Unlike `{embed}`, all variables that are already defined in the template leading up to the
    `{% include %}` tag will automatically be available to the included template.

    ###### Parent template:

    @@ -406,9 +457,13 @@ Craft has a similar tag, called [{% includ %}](http://twig.sensiolabs.org/doc/ta
    </div>
    ```

    Note how `entry` was already available to \_includes/photo_gallery, since it was presumably already defined by the parent template.
    Note how `entry` was already available to \_includes/photo_gallery, since it was presumably already
    defined by the parent template.

    You also have the option to pass additional variables to the included template that weren’t already defined in the parent. In the above example, we might not want the include template to worry about the entry variable’s name, and just be passed the array of images directly. We could do do that with this syntax:
    You also have the option to pass additional variables to the included template that weren’t already
    defined in the parent. In the above example, we might not want the include template to worry about
    the entry variable’s name, and just be passed the array of images directly. We could do do that with
    this syntax:

    ###### Parent template:

    @@ -428,15 +483,44 @@ You also have the option to pass additional variables to the included template t
    </div>
    ```

    Now the include template is expecting to be passed a `photos` variable, and it’s up to whoever’s including it to ensure that `photos` is set properly. Thanks to that `with` parameter, we can do that without having to make a `photos` variable available to the parent template.
    Now the include template is expecting to be passed a `photos` variable, and it’s up to whoever’s
    including it to ensure that `photos` is set properly. Thanks to that `with` parameter, we can do
    that without having to make a `photos` variable available to the parent template.

    ##### Resources

    See [Twig’s {% include %} docs](http://twig.sensiolabs.org/doc/tags/include.html) for more info.
    - [Twig’s {% include %} docs](http://twig.sensiolabs.org/doc/tags/include.html)

    ---
    ----------------------------------------------------------------------------------------------------

    ## 10. Stuff you can only do in Craft

    All of the above examples have been focussed on things that are relatively easy to do in both EE and Craft. But thanks to Twig, there are a ton of things you can easily do in Craft that aren’t even possible in EE out of the box.
    All of the above examples have been focussed on things that are relatively easy to do in both EE and
    Craft. But thanks to Twig, there are a ton of things you can easily do in Craft that aren’t even
    possible in EE out of the box.

    #### Set variables in the templates

    You’re not stuck with a limited set of variable tags in Craft. Thanks to Twig, you can define new
    variables right in your templates, manipulate them, and output them as you see fit.

    ```jinja
    {% set title = "About Us" %}
    <html>
    <head>
    <title>{{ title }} - {{ siteName }}</title>
    </head>
    <body>
    <h1>{{ title | upper }}</h1>
    </body>
    </html>
    ```

    ##### Resources

    - [Twig’s {% set %} tag docs](http://twig.sensiolabs.org/doc/tags/set.html)
    - [Twig’s filter docs ](http://twig.sensiolabs.org/doc/templates.html#filters)

    #### Mathmatical operations

    @@ -449,9 +533,14 @@ There are plenty of times where it’s nice to be able to do a little math in yo
    {{ total }}
    ```

    ##### Resources

    - [Twig’s Math docs](http://twig.sensiolabs.org/doc/templates.html#math)

    #### String manipulations

    You can concatenate strings, modify them, split them into arrays, or pretty much anything else you can think of.
    You can concatenate strings, modify them, split them into arrays, or pretty much anything else you
    can think of.

    ```jinja
    {% if currentUser %}
    @@ -467,9 +556,14 @@ You can concatenate strings, modify them, split them into arrays, or pretty much
    {{ greeting | upper }}
    ```

    ##### Resources

    - [Twig’s {% set %} tag docs](http://twig.sensiolabs.org/doc/tags/set.html)
    - [Twig’s filter docs ](http://twig.sensiolabs.org/doc/templates.html#filters)

    #### Create arrays

    Not all arrays have to come from the DB-based content. You can create your own right in the templates!
    You aren’t limited to creating simple numbers and strings. You can ever create full-blown arrays:

    ```jinja
    {% set nav = [
    @@ -482,8 +576,8 @@ Not all arrays have to come from the DB-based content. You can create your own r
    <nav>
    <ul>
    {% for item in nav %}
    {% set selected = (craft.request.path == item.uri) %}
    <li><a {{ selected ? 'class="sel"' }} href="{{ url(item.uri) }}">{{ item.title }}</a></li>
    {% set sel = (craft.request.path == item.uri) %}
    <li><a {{ sel ? 'class="sel"' }} href="{{ url(item.uri) }}">{{ item.title }}</a></li>
    {% endfor %}
    </ul>
    </nav>
    @@ -501,7 +595,8 @@ There’s also a shorthand syntax for creating arrays of consecutive numbers:

    #### So much more

    Twig has _tons_ of useful features that make developing templates a breeze, and Craft adds even more features on top of that!
    Twig has _tons_ of useful features that make developing templates a breeze, and Craft adds even more
    features on top of that!

    If you want to learn more, here are a few helpful templating resources:

  13. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion templating.md
    Original file line number Diff line number Diff line change
    @@ -463,7 +463,7 @@ You can concatenate strings, modify them, split them into arrays, or pretty much
    {% set totalWords = greeting | split(' ') | length %}
    {% set greeting = greeting ~ ' (That was '~totalWords~' words!)' %}
    {# Output the greeting in all caps %}
    {# Output the greeting in all caps #}
    {{ greeting | upper }}
    ```

  14. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion templating.md
    Original file line number Diff line number Diff line change
    @@ -17,7 +17,7 @@ Lots of people have asked, so here are a few common tasks you might do in your t

    ---

    1. Comments
    ## 1. Comments

    Let’s start simple! Both CMSes support comment tags, enabling you to make notes in the template code that never make it to the browser.

  15. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 190 additions and 15 deletions.
    205 changes: 190 additions & 15 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -4,17 +4,38 @@ Lots of people have asked, so here are a few common tasks you might do in your t

    ### Table of Contents

    1. [Conditionals](#1-conditionals)
    2. [Loops](#2-loops)
    3. [Looping through entries](#3-looping-through-entries)
    4. [Single-entry pages](#4-single-entry-pages)
    5. [Looping through Matrix rows](#5-looping-through-matrix-rows)
    6. [Looping through assets](#6-looping-through-assets)
    7. [DRY site header and footer](#7-dry-site-header-and-footer)
    1. [Comments](#1-comments)
    2. [Conditionals](#2-conditionals)
    3. [Loops](#3-loops)
    4. [Looping through entries](#4-looping-through-entries)
    5. [Single-entry pages](#5-single-entry-pages)
    6. [Looping through Matrix rows](#6-looping-through-matrix-rows)
    7. [Looping through assets](#7-looping-through-assets)
    8. [DRY site header and footer](#8-dry-site-header-and-footer)
    9. [Template includes](#9-template-includes)
    10. [Stuff you can only do in Craft](#10-stuff-you-can-only-do-in-craft)

    ---

    ## 1. Conditionals
    1. Comments

    Let’s start simple! Both CMSes support comment tags, enabling you to make notes in the template code that never make it to the browser.

    #### ExpressionEngine

    ```
    {!-- You can’t see me! --}
    ```

    #### Craft

    ```jinja
    {# You can’t see me! #}
    ```

    ---

    ## 2. Conditionals

    #### ExpressionEngine

    @@ -44,7 +65,7 @@ See [Twig’s {% if %} docs](http://twig.sensiolabs.org/doc/tags/if.html) for mo

    ---

    ## 2. Loops
    ## 3. Loops

    #### ExpressionEngine

    @@ -145,7 +166,7 @@ See [Twig’s {% for %} docs](http://twig.sensiolabs.org/doc/tags/for.html) for

    ---

    ## 3. Looping through entries
    ## 4. Looping through entries

    #### ExpressionEngine

    @@ -173,7 +194,7 @@ See [EntryModel](http://buildwithcraft.com/docs/templating/entrymodel) for more

    ---

    ## 4. Single-entry pages
    ## 5. Single-entry pages

    #### ExpressionEngine

    @@ -197,7 +218,7 @@ Entries in Craft have their own URLs, so Craft knows for a fact which entry you

    ---

    ## 5. Looping through Matrix rows
    ## 6. Looping through Matrix rows

    #### ExpressionEngine

    @@ -242,7 +263,7 @@ See [MatrixBlockModel](http://buildwithcraft.com/docs/templating/matrixblockmode

    ---

    ## 6. Looping through assets
    ## 7. Looping through assets

    #### ExpressionEngine

    @@ -268,7 +289,7 @@ See [AssetFileModel](http://buildwithcraft.com/docs/templating/assetfilemodel) f

    ---

    ## 7. DRY site header and footer
    ## 8. DRY site header and footer

    #### ExpressionEngine

    @@ -337,4 +358,158 @@ Craft has the concept of [Template Inheritance](http://twig.sensiolabs.org/doc/t
    <h1>News</h1>
    ...
    {% endblock %}
    ```
    ```

    ---

    ## 9. Template includes

    #### ExpressionEngine

    As demonstrated [above](#8-dry-site-header-and-footer), you can include other templates in EE using the `{embed}` tag, passing any variables you want available to the embedded template as parameters:

    ###### Parent template:

    ```
    {embed="includes/_photo_gallery" entry_id="{entry_id}"}
    ```

    ###### includes/\_photo_gallery:

    ```
    {exp:channel:entries entry_id="{embed:entry_id}" dynamic="no"}
    <div class="gallery">
    {assets_field}
    <img src="{url:manipulation_name}">
    {/assets_field}
    </div>
    {/exp:channel:entries}
    ```

    #### Craft

    Craft has a similar tag, called [{% includ %}](http://twig.sensiolabs.org/doc/tags/include.html). Unlike `{embed}`, all variables that are already defined in the template leading up to the `{% include %}` tag will automatically be available to the included template.

    ###### Parent template:

    ```jinja
    {% include "_includes/photo_gallery" %}
    ```

    ###### \_includes/photo_gallery:

    ```jinja
    <div class="gallery">
    {% for photo in entry.assetsField %}
    <img src="{{ photo.url('transformHandle') }}">
    {% endfor %}
    </div>
    ```

    Note how `entry` was already available to \_includes/photo_gallery, since it was presumably already defined by the parent template.

    You also have the option to pass additional variables to the included template that weren’t already defined in the parent. In the above example, we might not want the include template to worry about the entry variable’s name, and just be passed the array of images directly. We could do do that with this syntax:

    ###### Parent template:

    ```jinja
    {% include "_includes/photo_gallery" with {
    photos: entry.assetsField
    } %}
    ```

    ###### \_includes/photo_gallery:

    ```jinja
    <div class="gallery">
    {% for photo in photos %}
    <img src="{{ photo.url('transformHandle') }}">
    {% endfor %}
    </div>
    ```

    Now the include template is expecting to be passed a `photos` variable, and it’s up to whoever’s including it to ensure that `photos` is set properly. Thanks to that `with` parameter, we can do that without having to make a `photos` variable available to the parent template.

    See [Twig’s {% include %} docs](http://twig.sensiolabs.org/doc/tags/include.html) for more info.

    ---

    ## 10. Stuff you can only do in Craft

    All of the above examples have been focussed on things that are relatively easy to do in both EE and Craft. But thanks to Twig, there are a ton of things you can easily do in Craft that aren’t even possible in EE out of the box.

    #### Mathmatical operations

    There are plenty of times where it’s nice to be able to do a little math in your templates.

    ```jinja
    {{ 2 + 2 }}
    {% set total = 2 + 2 %}
    {{ total }}
    ```

    #### String manipulations

    You can concatenate strings, modify them, split them into arrays, or pretty much anything else you can think of.

    ```jinja
    {% if currentUser %}
    {% set greeting = "Hello, " ~ currentUser.name %}
    {% else %}
    {% set greeting = "Nice to meet you." %}
    {% endif %}
    {% set totalWords = greeting | split(' ') | length %}
    {% set greeting = greeting ~ ' (That was '~totalWords~' words!)' %}
    {# Output the greeting in all caps %}
    {{ greeting | upper }}
    ```

    #### Create arrays

    Not all arrays have to come from the DB-based content. You can create your own right in the templates!

    ```jinja
    {% set nav = [
    { uri: '', title: 'Home' },
    { uri: 'about', title: 'About' },
    { uri: 'products', title: 'Products' },
    { uri: 'blog', title: 'Blog' }
    ] %}
    <nav>
    <ul>
    {% for item in nav %}
    {% set selected = (craft.request.path == item.uri) %}
    <li><a {{ selected ? 'class="sel"' }} href="{{ url(item.uri) }}">{{ item.title }}</a></li>
    {% endfor %}
    </ul>
    </nav>
    ```

    There’s also a shorthand syntax for creating arrays of consecutive numbers:

    ```jinja
    <select name="cc_exp_year">
    {% for year in now.year .. now.year+10 %}
    <option>{{ year }}</option>
    {% endfor %}
    </select>
    ```

    #### So much more

    Twig has _tons_ of useful features that make developing templates a breeze, and Craft adds even more features on top of that!

    If you want to learn more, here are a few helpful templating resources:

    - [Twig for Template Designers](http://twig.sensiolabs.org/doc/templates.html) (the official docs)
    - [Twig’s core tags](http://twig.sensiolabs.org/doc/tags/index.html)
    - [Twig’s core filters](http://twig.sensiolabs.org/doc/filters/index.html)
    - [Twig’s core functions](http://twig.sensiolabs.org/doc/functions/index.html)
    - [Craft-added tags](http://buildwithcraft.com/docs/templating/tags)
    - [Craft-added filters](http://buildwithcraft.com/docs/templating/filters)
    - [Craft-added functions](http://buildwithcraft.com/docs/templating/functions)
    - [Global template variables in Craft](http://buildwithcraft.com/docs/templating/global-variables)
  16. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 9 additions and 9 deletions.
    18 changes: 9 additions & 9 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -18,7 +18,7 @@ Lots of people have asked, so here are a few common tasks you might do in your t

    #### ExpressionEngine

    ```html
    ```
    {if something == 'value'}
    ...
    {if:elseif something_else == 'other_value'}
    @@ -50,7 +50,7 @@ See [Twig’s {% if %} docs](http://twig.sensiolabs.org/doc/tags/if.html) for mo

    EE loops are always done with a tag pair, named after what we’re looping through.

    ```html
    ```
    {exp:channel:entries channel="news"}
    {matrix_field}
    ...
    @@ -151,7 +151,7 @@ See [Twig’s {% for %} docs](http://twig.sensiolabs.org/doc/tags/for.html) for

    ExpressionEngine’s `{exp:channel:entries}` tag is optimized for this task (assuming you’re not on a single-entry page!). Just tell it which channel, how many, and so on.

    ```html
    ```
    {exp:channel:entries channel="news" limit="10"}
    <h2><a href="{path='news/{url_title}'}">{title}</a></h2>
    <p>{summary}</p>
    @@ -179,7 +179,7 @@ See [EntryModel](http://buildwithcraft.com/docs/templating/entrymodel) for more

    Assuming everything’s in the right place, this is the one time the `dynamic` parameter will actually help you out, saving you from having to type `url_title="{segment_2}" limit="1"` (Whew!).

    ```html
    ```
    {exp:channel:entries channel="news"}
    <h1>{title}</h1>
    {body}
    @@ -203,7 +203,7 @@ Entries in Craft have their own URLs, so Craft knows for a fact which entry you

    Matrix follows the standard EE fieldtype convention of parsing a tag pair based on the field’s short name:

    ```html
    ```
    {matrix_field}
    {column_one}
    {column_two}
    @@ -248,7 +248,7 @@ See [MatrixBlockModel](http://buildwithcraft.com/docs/templating/matrixblockmode

    Like Matrix/EE, Assets uses a tag pair based on the field’s short name:

    ```html
    ```
    {assets_field}
    <img src="{url:image_manipulation_name}" alt="{title}"> {filename}
    {/assets_field}
    @@ -276,7 +276,7 @@ In EE you would do this with two embedded templates, which you’d manually incl

    ###### includes/_header

    ```html
    ```
    <html>
    <head>
    <title>{if embed:page_name}{embed:page_name} - {/if}{site_name}</title>
    @@ -286,7 +286,7 @@ In EE you would do this with two embedded templates, which you’d manually incl

    ###### includes/_footer

    ```html
    ```
    <p class="copyright">
    &copy; {current_time format='%Y'} {site_name}
    </p>
    @@ -296,7 +296,7 @@ In EE you would do this with two embedded templates, which you’d manually incl

    ###### news/index

    ```html
    ```
    {embed="includes/_header" page_name="News"}
    <h1>News</h1>
    ...
  17. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 9 additions and 9 deletions.
    18 changes: 9 additions & 9 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -30,7 +30,7 @@ Lots of people have asked, so here are a few common tasks you might do in your t

    #### Craft

    ```html
    ```jinja
    {% if something == 'value' %}
    ...
    {% elseif somethingElse == 'otherValue' %}
    @@ -62,7 +62,7 @@ EE loops are always done with a tag pair, named after what we’re looping throu

    Looping through things in Craft is always done with a [for-loop](http://twig.sensiolabs.org/doc/tags/for.html), where you pass in what you want to loop through, as well as what you want to call each item within the loop.

    ```html
    ```jinja
    {% for entry in craft.entries.channel('news') %}
    {% for block in entry.matrixField %}
    ...
    @@ -162,7 +162,7 @@ ExpressionEngine’s `{exp:channel:entries}` tag is optimized for this task (ass

    In Craft you grab the entries using [craft.entries](http://buildwithcraft.com/docs/templating/craft.entries) and loop through them with a [for-loop](http://twig.sensiolabs.org/doc/tags/for.html). You get to choose a variable name that each entry is going to be set to. In this case we’re going with `newsEntry` so it’s clear which ‘title’ we’re outputting, etc..

    ```html
    ```jinja
    {% for newsEntry in craft.entries.section('news').limit(10) %}
    <h2><a href="{{ newsEntry.url }}">{{ newsEntry.title }}</a></h2>
    <p>{{ newsEntry.summary }}</p>
    @@ -190,7 +190,7 @@ Assuming everything’s in the right place, this is the one time the `dynamic` p

    Entries in Craft have their own URLs, so Craft knows for a fact which entry you’re trying to access, and which template it should load. In the process it will pass an `entry` variable, pre-set to the entry you’re accessing. (In this case you don’t get a choice on what the `entry` variable name is going to be called.)

    ```html
    ```jinja
    <h1>{{ entry.title }}</h1>
    {{ entry.body }}
    ```
    @@ -214,7 +214,7 @@ Matrix follows the standard EE fieldtype convention of parsing a tag pair based

    As with looping through entries, we loop through Matrix blocks using a [for-loop](http://twig.sensiolabs.org/doc/tags/for.html).

    ```html
    ```jinja
    {% for block in entry.matrixField %}
    {{ block.fieldOne }}
    {{ block.fieldTwo }}
    @@ -223,7 +223,7 @@ As with looping through entries, we loop through Matrix blocks using a [for-loop

    If you have multiple block types, you can add conditionals for them:

    ```html
    ```jinja
    {% for block in entry.matrixField %}
    {% if block.type == "text" %}
    @@ -258,7 +258,7 @@ Like Matrix/EE, Assets uses a tag pair based on the field’s short name:

    Like entries and Matrix fields in Craft, we once again use the [for-loop](http://twig.sensiolabs.org/doc/tags/for.html) to loop through assets:

    ```html
    ```jinja
    {% for asset in entry.assetsField %}
    <img src="{{ asset.url('transformHandle') }}" alt="{{ asset.title }}"> {{ asset.filename }}
    {% endfor %}
    @@ -309,7 +309,7 @@ Craft has the concept of [Template Inheritance](http://twig.sensiolabs.org/doc/t

    ###### \_site_layout.html

    ```html
    ```jinja
    <html>
    <head>
    <title>{% if pageName is defined %}{{ pageName }} - {% endif %}{{ siteName }}</title>
    @@ -329,7 +329,7 @@ Craft has the concept of [Template Inheritance](http://twig.sensiolabs.org/doc/t

    ###### news/index.html

    ```html
    ```jinja
    {% extends "_site_layout" %}
    {% set pageName = "News" %}
  18. brandonkelly revised this gist Jan 24, 2014. No changes.
  19. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 25 additions and 15 deletions.
    40 changes: 25 additions & 15 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -2,11 +2,21 @@

    Lots of people have asked, so here are a few common tasks you might do in your templates, as they would be written in ExpressionEngine vs. Craft.

    ### Table of Contents

    1. [Conditionals](#1-conditionals)
    2. [Loops](#2-loops)
    3. [Looping through entries](#3-looping-through-entries)
    4. [Single-entry pages](#4-single-entry-pages)
    5. [Looping through Matrix rows](#5-looping-through-matrix-rows)
    6. [Looping through assets](#6-looping-through-assets)
    7. [DRY site header and footer](#7-dry-site-header-and-footer)

    ---

    ## 1. Conditionals

    ### ExpressionEngine
    #### ExpressionEngine

    ```html
    {if something == 'value'}
    @@ -18,7 +28,7 @@ Lots of people have asked, so here are a few common tasks you might do in your t
    {/if}
    ```

    ### Craft
    #### Craft

    ```html
    {% if something == 'value' %}
    @@ -36,7 +46,7 @@ See [Twig’s {% if %} docs](http://twig.sensiolabs.org/doc/tags/if.html) for mo

    ## 2. Loops

    ### ExpressionEngine
    #### ExpressionEngine

    EE loops are always done with a tag pair, named after what we’re looping through.

    @@ -48,7 +58,7 @@ EE loops are always done with a tag pair, named after what we’re looping throu
    {/exp:channel:entries}
    ```

    ### Craft
    #### Craft

    Looping through things in Craft is always done with a [for-loop](http://twig.sensiolabs.org/doc/tags/for.html), where you pass in what you want to loop through, as well as what you want to call each item within the loop.

    @@ -137,7 +147,7 @@ See [Twig’s {% for %} docs](http://twig.sensiolabs.org/doc/tags/for.html) for

    ## 3. Looping through entries

    ### ExpressionEngine
    #### ExpressionEngine

    ExpressionEngine’s `{exp:channel:entries}` tag is optimized for this task (assuming you’re not on a single-entry page!). Just tell it which channel, how many, and so on.

    @@ -148,7 +158,7 @@ ExpressionEngine’s `{exp:channel:entries}` tag is optimized for this task (ass
    {/exp:channel:entries}
    ```

    ### Craft
    #### Craft

    In Craft you grab the entries using [craft.entries](http://buildwithcraft.com/docs/templating/craft.entries) and loop through them with a [for-loop](http://twig.sensiolabs.org/doc/tags/for.html). You get to choose a variable name that each entry is going to be set to. In this case we’re going with `newsEntry` so it’s clear which ‘title’ we’re outputting, etc..

    @@ -163,9 +173,9 @@ See [EntryModel](http://buildwithcraft.com/docs/templating/entrymodel) for more

    ---

    ## 4. Outputting an entry on a single-entry page
    ## 4. Single-entry pages

    ### ExpressionEngine
    #### ExpressionEngine

    Assuming everything’s in the right place, this is the one time the `dynamic` parameter will actually help you out, saving you from having to type `url_title="{segment_2}" limit="1"` (Whew!).

    @@ -176,7 +186,7 @@ Assuming everything’s in the right place, this is the one time the `dynamic` p
    {/exp:channel:entries}
    ```

    ### Craft
    #### Craft

    Entries in Craft have their own URLs, so Craft knows for a fact which entry you’re trying to access, and which template it should load. In the process it will pass an `entry` variable, pre-set to the entry you’re accessing. (In this case you don’t get a choice on what the `entry` variable name is going to be called.)

    @@ -189,7 +199,7 @@ Entries in Craft have their own URLs, so Craft knows for a fact which entry you

    ## 5. Looping through Matrix rows

    ### ExpressionEngine
    #### ExpressionEngine

    Matrix follows the standard EE fieldtype convention of parsing a tag pair based on the field’s short name:

    @@ -200,7 +210,7 @@ Matrix follows the standard EE fieldtype convention of parsing a tag pair based
    {/matrix_field}
    ```

    ### Craft
    #### Craft

    As with looping through entries, we loop through Matrix blocks using a [for-loop](http://twig.sensiolabs.org/doc/tags/for.html).

    @@ -234,7 +244,7 @@ See [MatrixBlockModel](http://buildwithcraft.com/docs/templating/matrixblockmode

    ## 6. Looping through assets

    ### ExpressionEngine
    #### ExpressionEngine

    Like Matrix/EE, Assets uses a tag pair based on the field’s short name:

    @@ -244,7 +254,7 @@ Like Matrix/EE, Assets uses a tag pair based on the field’s short name:
    {/assets_field}
    ```

    ### Craft
    #### Craft

    Like entries and Matrix fields in Craft, we once again use the [for-loop](http://twig.sensiolabs.org/doc/tags/for.html) to loop through assets:

    @@ -260,7 +270,7 @@ See [AssetFileModel](http://buildwithcraft.com/docs/templating/assetfilemodel) f

    ## 7. DRY site header and footer

    ### ExpressionEngine
    #### ExpressionEngine

    In EE you would do this with two embedded templates, which you’d manually include in every normal template.

    @@ -293,7 +303,7 @@ In EE you would do this with two embedded templates, which you’d manually incl
    {embed="includes/_footer"}
    ```

    ### Craft
    #### Craft

    Craft has the concept of [Template Inheritance](http://twig.sensiolabs.org/doc/templates.html#template-inheritance), which lets you define all of the common site elements in a single template, and extend it with sub-templates where necessary.

  20. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 26 additions and 16 deletions.
    42 changes: 26 additions & 16 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -2,8 +2,9 @@

    Lots of people have asked, so here are a few common tasks you might do in your templates, as they would be written in ExpressionEngine vs. Craft.

    ---

    ## Conditionals
    ## 1. Conditionals

    ### ExpressionEngine

    @@ -31,7 +32,9 @@ Lots of people have asked, so here are a few common tasks you might do in your t

    See [Twig’s {% if %} docs](http://twig.sensiolabs.org/doc/tags/if.html) for more info.

    ## Loops
    ---

    ## 2. Loops

    ### ExpressionEngine

    @@ -130,9 +133,9 @@ Both CMSes have various tags that are available within the loops, as well:

    See [Twig’s {% for %} docs](http://twig.sensiolabs.org/doc/tags/for.html) for more info.

    ---


    ## Looping through entries
    ## 3. Looping through entries

    ### ExpressionEngine

    @@ -156,9 +159,11 @@ In Craft you grab the entries using [craft.entries](http://buildwithcraft.com/do
    {% endfor %}
    ```

    See [EntryModel](http://buildwithcraft.com/docs/templating/entrymodel) to see what you can do with those entry variables.
    See [EntryModel](http://buildwithcraft.com/docs/templating/entrymodel) for more info on those entry variables.

    ---

    ## Outputting an entry on a single-entry page
    ## 4. Outputting an entry on a single-entry page

    ### ExpressionEngine

    @@ -180,7 +185,9 @@ Entries in Craft have their own URLs, so Craft knows for a fact which entry you
    {{ entry.body }}
    ```

    ## Looping through Matrix rows
    ---

    ## 5. Looping through Matrix rows

    ### ExpressionEngine

    @@ -221,9 +228,11 @@ If you have multiple block types, you can add conditionals for them:
    {% endfor %}
    ```

    See [MatrixBlockModel](http://buildwithcraft.com/docs/templating/matrixblockmodel) to see what you can do with those Matrix block variables.
    See [MatrixBlockModel](http://buildwithcraft.com/docs/templating/matrixblockmodel) for more info on those Matrix block variables.

    ---

    ## Looping through assets
    ## 6. Looping through assets

    ### ExpressionEngine

    @@ -245,16 +254,17 @@ Like entries and Matrix fields in Craft, we once again use the [for-loop](http:/
    {% endfor %}
    ```

    See [AssetFileModel](http://buildwithcraft.com/docs/templating/assetfilemodel) to see what you can do with those asset variables.
    See [AssetFileModel](http://buildwithcraft.com/docs/templating/assetfilemodel) for more info on those asset variables.

    ---

    ## DRY site header and footer
    ## 7. DRY site header and footer

    ### ExpressionEngine

    In EE you would do this with two embedded templates, which you’d manually include in every normal template.

    #### includes/_header
    ###### includes/_header

    ```html
    <html>
    @@ -264,7 +274,7 @@ In EE you would do this with two embedded templates, which you’d manually incl
    <body>
    ```

    #### includes/_footer
    ###### includes/_footer

    ```html
    <p class="copyright">
    @@ -274,7 +284,7 @@ In EE you would do this with two embedded templates, which you’d manually incl
    </html>
    ```

    #### news/index
    ###### news/index

    ```html
    {embed="includes/_header" page_name="News"}
    @@ -287,7 +297,7 @@ In EE you would do this with two embedded templates, which you’d manually incl

    Craft has the concept of [Template Inheritance](http://twig.sensiolabs.org/doc/templates.html#template-inheritance), which lets you define all of the common site elements in a single template, and extend it with sub-templates where necessary.

    #### \_site_layout.html
    ###### \_site_layout.html

    ```html
    <html>
    @@ -307,7 +317,7 @@ Craft has the concept of [Template Inheritance](http://twig.sensiolabs.org/doc/t
    </html>
    ```

    #### news/index.html
    ###### news/index.html

    ```html
    {% extends "_site_layout" %}
  21. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -86,12 +86,12 @@ Both CMSes have various tags that are available within the loops, as well:
    <td>{{ loop.index0 }}</td>
    </tr>
    <tr>
    <td>How many items are left?</td>
    <td>Number of items left</td>
    <td><em>SOL</em></td>
    <td>{{ loop.revindex0 }}</td>
    </tr>
    <tr>
    <td>How many items are left, including this one?</td>
    <td>Number of ites left, inc. this one</td>
    <td><em>SOL</em></td>
    <td>{{ loop.revindex }}</td>
    </tr>
  22. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion templating.md
    Original file line number Diff line number Diff line change
    @@ -121,7 +121,7 @@ Both CMSes have various tags that are available within the loops, as well:
    <td>{{ cycle(['odd','even'], loop.index0 }}</td>
    </tr>
    <tr>
    <td>What’s the parent’s index (in a nested loop)?</td>
    <td>The parent loop’s index</td>
    <td><em>SOL</em></td>
    <td>{{ loop.parent.loop.index }}</td>
    </tr>
  23. brandonkelly revised this gist Jan 24, 2014. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -115,6 +115,11 @@ Both CMSes have various tags that are available within the loops, as well:
    <td>{if count % 2 == 0}</td>
    <td>{% if loop.even %}</td>
    </tr>
    <tr>
    <td>Cycle through values for each item</td>
    <td>{switch='odd|even'}</td>
    <td>{{ cycle(['odd','even'], loop.index0 }}</td>
    </tr>
    <tr>
    <td>What’s the parent’s index (in a nested loop)?</td>
    <td><em>SOL</em></td>
  24. brandonkelly revised this gist Jan 23, 2014. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -82,17 +82,17 @@ Both CMSes have various tags that are available within the loops, as well:
    </tr>
    <tr>
    <td>0-based index</td>
    <td>SOL</td>
    <td><em>SOL</em></td>
    <td>{{ loop.index0 }}</td>
    </tr>
    <tr>
    <td>How many items are left?</td>
    <td>SOL</td>
    <td><em>SOL</em></td>
    <td>{{ loop.revindex0 }}</td>
    </tr>
    <tr>
    <td>How many items are left, including this one?</td>
    <td>SOL</td>
    <td><em>SOL</em></td>
    <td>{{ loop.revindex }}</td>
    </tr>
    <tr>
    @@ -117,8 +117,8 @@ Both CMSes have various tags that are available within the loops, as well:
    </tr>
    <tr>
    <td>What’s the parent’s index (in a nested loop)?</td>
    <td>SOL</td>
    <td>{{ loop.parent.loop.inedx }}</td>
    <td><em>SOL</em></td>
    <td>{{ loop.parent.loop.index }}</td>
    </tr>
    </tbody>
    </table>
  25. brandonkelly revised this gist Jan 23, 2014. 1 changed file with 16 additions and 16 deletions.
    32 changes: 16 additions & 16 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -72,53 +72,53 @@ Both CMSes have various tags that are available within the loops, as well:
    <tbody>
    <tr>
    <td>How many items?</td>
    <td><code>{total_results}</code></td>
    <td><code>{{ loop.length }}</code></td>
    <td>{total_results}</td>
    <td>{{ loop.length }}</td>
    </tr>
    <tr>
    <td>1-based index</td>
    <td><code>{count}</code></td>
    <td><code>{{ loop.index }}</code></td>
    <td>{count}</td>
    <td>{{ loop.index }}</td>
    </tr>
    <tr>
    <td>0-based index</td>
    <td>SOL</td>
    <td><code>{{ loop.index0 }}</code></td>
    <td>{{ loop.index0 }}</td>
    </tr>
    <tr>
    <td>How many items are left?</td>
    <td>SOL</td>
    <td><code>{{ loop.revindex0 }}</code></td>
    <td>{{ loop.revindex0 }}</td>
    </tr>
    <tr>
    <td>How many items are left, including this one?</td>
    <td>SOL</td>
    <td><code>{{ loop.revindex }}</code></td>
    <td>{{ loop.revindex }}</td>
    </tr>
    <tr>
    <td>First item?</td>
    <td><code>{if count == 1}</code></td>
    <td><code>{% if loop.first %}</code></td>
    <td>{if count == 1}</td>
    <td>{% if loop.first %}</td>
    </tr>
    <tr>
    <td>Last item?</td>
    <td><code>{if count == total_results}</code></td>
    <td><code>{% if loop.last %}</code></td>
    <td>{if count == total_results}</td>
    <td>{% if loop.last %}</td>
    </tr>
    <tr>
    <td>Odd?</td>
    <td><code>{if count % 2 == 1}</code></td>
    <td><code>{% if loop.odd %}</code></td>
    <td>{if count % 2 == 1}</td>
    <td>{% if loop.odd %}</td>
    </tr>
    <tr>
    <td>Even?</td>
    <td><code>{if count % 2 == 0}</code></td>
    <td><code>{% if loop.even %}</code></td>
    <td>{if count % 2 == 0}</td>
    <td>{% if loop.even %}</td>
    </tr>
    <tr>
    <td>What’s the parent’s index (in a nested loop)?</td>
    <td>SOL</td>
    <td><code>{{ loop.parent.loop.inedx }}</code></td>
    <td>{{ loop.parent.loop.inedx }}</td>
    </tr>
    </tbody>
    </table>
  26. brandonkelly revised this gist Jan 23, 2014. 1 changed file with 16 additions and 16 deletions.
    32 changes: 16 additions & 16 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -72,53 +72,53 @@ Both CMSes have various tags that are available within the loops, as well:
    <tbody>
    <tr>
    <td>How many items?</td>
    <td>`{total_results}`</td>
    <td>`{{ loop.length }}`</td>
    <td><code>{total_results}</code></td>
    <td><code>{{ loop.length }}</code></td>
    </tr>
    <tr>
    <td>1-based index</td>
    <td>`{count}`</td>
    <td>`{{ loop.index }}`</td>
    <td><code>{count}</code></td>
    <td><code>{{ loop.index }}</code></td>
    </tr>
    <tr>
    <td>0-based index</td>
    <td>SOL</td>
    <td>`{{ loop.index0 }}`</td>
    <td><code>{{ loop.index0 }}</code></td>
    </tr>
    <tr>
    <td>How many items are left?</td>
    <td>SOL</td>
    <td>`{{ loop.revindex0 }}`</td>
    <td><code>{{ loop.revindex0 }}</code></td>
    </tr>
    <tr>
    <td>How many items are left, including this one?</td>
    <td>SOL</td>
    <td>`{{ loop.revindex }}`</td>
    <td><code>{{ loop.revindex }}</code></td>
    </tr>
    <tr>
    <td>First item?</td>
    <td>`{if count == 1}`</td>
    <td>`{% if loop.first %}`</td>
    <td><code>{if count == 1}</code></td>
    <td><code>{% if loop.first %}</code></td>
    </tr>
    <tr>
    <td>Last item?</td>
    <td>`{if count == total_results}`</td>
    <td>`{% if loop.last %}`</td>
    <td><code>{if count == total_results}</code></td>
    <td><code>{% if loop.last %}</code></td>
    </tr>
    <tr>
    <td>Odd?</td>
    <td>`{if count % 2 == 1}`</td>
    <td>`{% if loop.odd %}`</td>
    <td><code>{if count % 2 == 1}</code></td>
    <td><code>{% if loop.odd %}</code></td>
    </tr>
    <tr>
    <td>Even?</td>
    <td>`{if count % 2 == 0}`</td>
    <td>`{% if loop.even %}`</td>
    <td><code>{if count % 2 == 0}</code></td>
    <td><code>{% if loop.even %}</code></td>
    </tr>
    <tr>
    <td>What’s the parent’s index (in a nested loop)?</td>
    <td>SOL</td>
    <td>`{{ loop.parent.loop.inedx }}`</td>
    <td><code>{{ loop.parent.loop.inedx }}</code></td>
    </tr>
    </tbody>
    </table>
  27. brandonkelly revised this gist Jan 23, 2014. 1 changed file with 10 additions and 10 deletions.
    20 changes: 10 additions & 10 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -71,52 +71,52 @@ Both CMSes have various tags that are available within the loops, as well:
    </thead>
    <tbody>
    <tr>
    <th>How many items?</th>
    <td>How many items?</td>
    <td>`{total_results}`</td>
    <td>`{{ loop.length }}`</td>
    </tr>
    <tr>
    <th>1-based index</th>
    <td>1-based index</td>
    <td>`{count}`</td>
    <td>`{{ loop.index }}`</td>
    </tr>
    <tr>
    <th>0-based index</th>
    <td>0-based index</td>
    <td>SOL</td>
    <td>`{{ loop.index0 }}`</td>
    </tr>
    <tr>
    <th>How many items are left?</th>
    <td>How many items are left?</td>
    <td>SOL</td>
    <td>`{{ loop.revindex0 }}`</td>
    </tr>
    <tr>
    <th>How many items are left, including this one?</th>
    <td>How many items are left, including this one?</td>
    <td>SOL</td>
    <td>`{{ loop.revindex }}`</td>
    </tr>
    <tr>
    <th>First item?</th>
    <td>First item?</td>
    <td>`{if count == 1}`</td>
    <td>`{% if loop.first %}`</td>
    </tr>
    <tr>
    <th>Last item?</th>
    <td>Last item?</td>
    <td>`{if count == total_results}`</td>
    <td>`{% if loop.last %}`</td>
    </tr>
    <tr>
    <th>Odd?</th>
    <td>Odd?</td>
    <td>`{if count % 2 == 1}`</td>
    <td>`{% if loop.odd %}`</td>
    </tr>
    <tr>
    <th>Even?</th>
    <td>Even?</td>
    <td>`{if count % 2 == 0}`</td>
    <td>`{% if loop.even %}`</td>
    </tr>
    <tr>
    <th>What’s the parent’s index (in a nested loop)?</th>
    <td>What’s the parent’s index (in a nested loop)?</td>
    <td>SOL</td>
    <td>`{{ loop.parent.loop.inedx }}`</td>
    </tr>
  28. brandonkelly revised this gist Jan 23, 2014. 1 changed file with 61 additions and 12 deletions.
    73 changes: 61 additions & 12 deletions templating.md
    Original file line number Diff line number Diff line change
    @@ -61,18 +61,67 @@ There are pros and cons to both ways: EE’s is more elegant for simple things,

    Both CMSes have various tags that are available within the loops, as well:

    | Thing | ExpressionEngine | Craft |
    | --------------------------------------------- | ----------------------------- | ---------------------- ------- |
    | How many items? | `{total_results}` | `{{ loop.length }}` |
    | 1-based index | `{count}` | `{{ loop.index }}` |
    | 0-based index | SOL | `{{ loop.index0 }}` |
    | How many items are left? | SOL | `{{ loop.revindex0 }}` |
    | How many items are left, including this one? | SOL | `{{ loop.revindex }}` |
    | First item? | `{if count == 1}` | `{% if loop.first %}` |
    | Last item? | `{if count == total_results}` | `{% if loop.last %}` |
    | Odd? | `{if count % 2 == 1}` | `{% if loop.odd %}` |
    | Even? | `{if count % 2 == 0}` | `{% if loop.even %}` |
    | What’s the parent’s index (in a nested loop)? | SOL | `{{ loop.parent.loop.inedx }}` |
    <table>
    <thead>
    <tr>
    <th>Thing</th>
    <th>ExpressionEngine</th>
    <th>Craft</th>
    </tr>
    </thead>
    <tbody>
    <tr>
    <th>How many items?</th>
    <td>`{total_results}`</td>
    <td>`{{ loop.length }}`</td>
    </tr>
    <tr>
    <th>1-based index</th>
    <td>`{count}`</td>
    <td>`{{ loop.index }}`</td>
    </tr>
    <tr>
    <th>0-based index</th>
    <td>SOL</td>
    <td>`{{ loop.index0 }}`</td>
    </tr>
    <tr>
    <th>How many items are left?</th>
    <td>SOL</td>
    <td>`{{ loop.revindex0 }}`</td>
    </tr>
    <tr>
    <th>How many items are left, including this one?</th>
    <td>SOL</td>
    <td>`{{ loop.revindex }}`</td>
    </tr>
    <tr>
    <th>First item?</th>
    <td>`{if count == 1}`</td>
    <td>`{% if loop.first %}`</td>
    </tr>
    <tr>
    <th>Last item?</th>
    <td>`{if count == total_results}`</td>
    <td>`{% if loop.last %}`</td>
    </tr>
    <tr>
    <th>Odd?</th>
    <td>`{if count % 2 == 1}`</td>
    <td>`{% if loop.odd %}`</td>
    </tr>
    <tr>
    <th>Even?</th>
    <td>`{if count % 2 == 0}`</td>
    <td>`{% if loop.even %}`</td>
    </tr>
    <tr>
    <th>What’s the parent’s index (in a nested loop)?</th>
    <td>SOL</td>
    <td>`{{ loop.parent.loop.inedx }}`</td>
    </tr>
    </tbody>
    </table>

    See [Twig’s {% for %} docs](http://twig.sensiolabs.org/doc/tags/for.html) for more info.

  29. brandonkelly revised this gist Jan 23, 2014. 1 changed file with 77 additions and 1 deletion.
    78 changes: 77 additions & 1 deletion templating.md
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,82 @@

    Lots of people have asked, so here are a few common tasks you might do in your templates, as they would be written in ExpressionEngine vs. Craft.


    ## Conditionals

    ### ExpressionEngine

    ```html
    {if something == 'value'}
    ...
    {if:elseif something_else == 'other_value'}
    ...
    {if:else}
    ...
    {/if}
    ```

    ### Craft

    ```html
    {% if something == 'value' %}
    ...
    {% elseif somethingElse == 'otherValue' %}
    ...
    {% else %}
    ...
    {% endif %}
    ```

    See [Twig’s {% if %} docs](http://twig.sensiolabs.org/doc/tags/if.html) for more info.

    ## Loops

    ### ExpressionEngine

    EE loops are always done with a tag pair, named after what we’re looping through.

    ```html
    {exp:channel:entries channel="news"}
    {matrix_field}
    ...
    {/matrix_field}
    {/exp:channel:entries}
    ```

    ### Craft

    Looping through things in Craft is always done with a [for-loop](http://twig.sensiolabs.org/doc/tags/for.html), where you pass in what you want to loop through, as well as what you want to call each item within the loop.

    ```html
    {% for entry in craft.entries.channel('news') %}
    {% for block in entry.matrixField %}
    ...
    {% endfor %}
    {% endfor %}
    ```

    There are pros and cons to both ways: EE’s is more elegant for simple things, but you can quickly run into tag name conflicts and other gotcha’s when dealing with more complex templates. That’s never an issue with Craft, but it’s at the expense of a more verbose and less straightforward syntax.

    Both CMSes have various tags that are available within the loops, as well:

    | Thing | ExpressionEngine | Craft |
    | --------------------------------------------- | ----------------------------- | ---------------------- ------- |
    | How many items? | `{total_results}` | `{{ loop.length }}` |
    | 1-based index | `{count}` | `{{ loop.index }}` |
    | 0-based index | SOL | `{{ loop.index0 }}` |
    | How many items are left? | SOL | `{{ loop.revindex0 }}` |
    | How many items are left, including this one? | SOL | `{{ loop.revindex }}` |
    | First item? | `{if count == 1}` | `{% if loop.first %}` |
    | Last item? | `{if count == total_results}` | `{% if loop.last %}` |
    | Odd? | `{if count % 2 == 1}` | `{% if loop.odd %}` |
    | Even? | `{if count % 2 == 0}` | `{% if loop.even %}` |
    | What’s the parent’s index (in a nested loop)? | SOL | `{{ loop.parent.loop.inedx }}` |

    See [Twig’s {% for %} docs](http://twig.sensiolabs.org/doc/tags/for.html) for more info.



    ## Looping through entries

    ### ExpressionEngine
    @@ -118,7 +194,7 @@ Like entries and Matrix fields in Craft, we once again use the [for-loop](http:/
    See [AssetFileModel](http://buildwithcraft.com/docs/templating/assetfilemodel) to see what you can do with those asset variables.


    ## DRY Site header and footer
    ## DRY site header and footer

    ### ExpressionEngine

  30. brandonkelly revised this gist Jan 23, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion templating.md
    Original file line number Diff line number Diff line change
    @@ -157,7 +157,7 @@ In EE you would do this with two embedded templates, which you’d manually incl

    Craft has the concept of [Template Inheritance](http://twig.sensiolabs.org/doc/templates.html#template-inheritance), which lets you define all of the common site elements in a single template, and extend it with sub-templates where necessary.

    #### _site_layout.html
    #### \_site_layout.html

    ```html
    <html>