Answers.Body: <blockquote>
    <p><em>To encourage input, this is a community wiki post. Any user with at least 100 reputation points may contribute.</em> </p>
  </blockquote>
  
  <h1>Functions, filters, objects, macros and statements – when to use which</h1>
  
  <p>A <strong>function</strong> is one of the simplest constructs in Twig – it takes one or more inputs and returns a single output:</p>
  
  <pre><code>{{ round(42.9) }} will output 43
  </code></pre>
  
  <p>These are best used for simple, commonly used operations that generate or transform data, such as a Lorem-Ipsum generator: <code>{{ loremIpsum(50) }}</code>. But note that functions are often better grouped into an object to prevent name collisions (see below).</p>
  
  <p>A <strong>filter</strong> is almost identical to a function, except that it offers a different syntax, which can be more readable when chaining several filters together (they read in progressive order):</p>
  
  <pre><code>{{ 1000000 | number }} will output 1,000,000
  {{ 1000000 | number(false) }} will output 1000000
  {{ 'ABC' | lower | replace('c', 'd') }} will output abd
  </code></pre>
  
  <p>It also provides an easy way to wrap around a larger block of text:</p>
  
  <pre><code>{% filter upper %}
      This text becomes uppercase
  {% endfilter %}
  </code></pre>
  
  <p>Note that you can also do this with a function, but it requires an additional line:</p>
  
  <pre><code>{% set myText %}
      A quick brown fox
  {% endset %}
  {{ filterCurseWords(myText) }}
  </code></pre>
  
  <p>Use a filter when:</p>
  
  <ul>
  <li>It might be necessary to place it in a chain along with other filters</li>
  <li>It might be necessary to place around larger blocks of text/content</li>
  </ul>
  
  <p>A <strong>global variable</strong> is one accessible to all templates in your project automatically:</p>
  
  <pre><code>&lt;h1&gt;{{ siteName }}&lt;/h1&gt;
  </code></pre>
  
  <p>A <strong>global object</strong> is also accessible to all templates in your project, but can contain variables, functions or both:</p>
  
  <pre><code>{{ currentUser.friendlyName }}
  {{ currentUser.can('accessCp') }}
  </code></pre>
  
  <p>Objects provide a good way to neatly group variables and functions and prevent collisions.</p>
  
  <p>A Twig <strong>statement</strong> (sometimes called a "logic tag") is used to designate the flow of logic and may only execute the content inside based on certain circumstances.</p>
  
  <pre><code>{% cache %}
      {% for block in entry.myMatrixField %}
          &lt;p&gt;{{ block.text }}&lt;/p&gt;
      {% endfor %}
  {% endcache %}
  </code></pre>
  
  <p>Note that caching would not work as a filter, because the content inside a filter is always executed <em>prior</em> to being passed into the filter. By implementing the cache tag as a <em>statement</em>, it is able to only execute the content inside when appropriate.</p>
  
  <p>Finally, it's worth mentioning <strong>macros</strong>. They assist with reusing snippets of content or HTML in multiple places. Mijingo has written a <a href="https://mijingo.com/blog/using-macros-in-twig-and-craft" rel="noreferrer">great tutorial</a> that explains macros in Craft.</p>
  
  <pre><code>{% import "forms.html" as forms %}
  {{ forms.input('username') }}
  </code></pre>
  
  <p>Note, however, that the functionality of macros can sometimes be replicated via a simple include, with less code and more clarity:</p>
  
  <pre><code>{% include 'mySnippet' with { enabled: true } %}
  </code></pre>
  
  <hr>
  
  <h1>Creating a custom Twig filter</h1>
  
  <pre><code>{{ myVariable | myFilter }}
  </code></pre>
  
  <p><em>More content to come here. Feel free to contribute some instructions if you're able.</em></p>
  
  <hr>
  
  <h1>Accessing a plugin's variables and functions</h1>
  
  <pre><code>{{ craft.myPlugin.myVariable }}
  {{ craft.myPlugin.myFunction() }}
  </code></pre>
  
  <p><em>More content to come here. Feel free to contribute some instructions if you're able.</em></p>
  
  <hr>
  
  <h1>Creating a custom global function</h1>
  
  <pre><code>{{ customFunction() }}
  </code></pre>
  
  <p><em>More content to come here. Feel free to contribute some instructions if you're able.</em></p>
  
  <hr>
  
  <h1>Creating a custom global object</h1>
  
  <pre><code>{{ browser.version }}
  {{ browser.isMobile() }}
  </code></pre>
  
  <p><em>More content to come here. Feel free to contribute some instructions if you're able.</em></p>
  
  <hr>
  
  <h1>Creating a custom statement (logic tag)</h1>
  
  <pre><code>{% devOnly %}
      ...output some debugging info here...
  {% endDevOnly %}
  </code></pre>
  
  <p>Refer to <a href="http://twig.sensiolabs.org/doc/2.x/advanced.html#tags" rel="noreferrer">http://twig.sensiolabs.org/doc/2.x/advanced.html#tags</a></p>
  
  <p><em>More content to come here. Feel free to contribute some instructions if you're able.</em></p>
  
  <p>Be aware that sometimes the functionality can be achieved by creating a filter instead of a statement:</p>
  
  <pre><code>{% filter uppercase %}
      A quick brown fox
  {% endfilter %}
  </code></pre>
  
  <p>However the benefit of a statement is that the code inside is not run unless the statement permits it, whereas in a filter the code is always run, and then later sent to the filter.</p>
  
  <hr>
  
  <h1>Creating a custom operator</h1>
  
  <pre><code>{{ ! true }}
  </code></pre>
  
  <p>Refer to <a href="http://twig.sensiolabs.org/doc/2.x/advanced.html#operators" rel="noreferrer">http://twig.sensiolabs.org/doc/2.x/advanced.html#operators</a></p>
  
  <p><em>More content to come here. Feel free to contribute some instructions if you're able.</em></p>
  
  <hr>
  
  <h1>Calling a plugin service class from Twig</h1>
  
  <p>Under normal circumstances, Twig templates only have access to a plugins <em>Variable Classes</em> and not their <em>Service Classes</em>. But using a simple PHP trick, you can pass all calls on transparently:</p>
  
  <p><em>Twig > Variable Class > Service Class</em></p>
  
  <pre><code>// craft/plugins/YourPlugin/variables/YourPluginVariable.php
  class YourPluginVariable
  {
      /** 
       * If function is not found in this class, go find it in service class
       */
      function __call($method, $arguments) {
          return call_user_func_array(array(craft()-&gt;YourPlugin_YourService, $method), $arguments);
      }   
  }
  </code></pre>
  
  <p>Be sure to rename <code>YourPlugin</code> and <code>YourService</code> to reflect the names of your plugin and service class.</p>
  
  <hr>
  
  <h1>Making custom database calls from Twig</h1>
  
  <pre><code>{{ craft.myPlugin.fetchUserCount() }}
  </code></pre>
  
  <p>Firstly this requires a custom plugin. </p>
  
  <p>In Craft, database calls need to be made via a service class, however because you can only access <em>variable classes</em> from Twig, you need to pass one to the other. (See the point above for a clean way to transparently pass calls from a variable class to a service class.)</p>
  
  <p>Twig > Variable Class > Service Class > Database Query</p>
  
  <p><em>More content to come here. Feel free to contribute some instructions if you're able.</em></p>
  
  <hr>
  
  <h1>Post-processing HTML after Twig has finished rendering</h1>
  
  <p><em>More content to come here. Feel free to contribute some instructions if you're able.</em></p>
  
  <hr>
  
  <h1>Changing Twig settings</h1>
  
  <p><em>More content to come here. Feel free to contribute some instructions if you're able.</em></p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-01-11T01:11:10.207Z
Answers.LastActivityDate: 2018-02-22T14:20:34.040Z
Answers.LastEditDate: 2018-02-22T14:20:34.040Z
Answers.UserDisplayName: Simon East
Body: <p>So Craft's implementation of Twig is already very powerful and suitable to most common tasks. The Craft Docs already provide a great intro into using Twig and the handy extensions provided by Craft:</p>
  
  <ul>
  <li><a href="https://craftcms.com/docs/templating-overview" rel="noreferrer">Craft Templating Overview</a></li>
  <li><a href="https://craftcms.com/docs/twig-primer" rel="noreferrer">Craft Twig Primer</a></li>
  <li><a href="https://craftcms.com/docs/templating" rel="noreferrer">Craft Full Templating Reference</a></li>
  </ul>
  
  <p><strong>But what about when you need to go further and build in some sweet custom functionality?</strong></p>
  
  <p>This question serves to be a starting point that summarises all the different ways to extend Twig with custom functionality, including:</p>
  
  <ul>
  <li>Filters, functions, objects, macros and statements – when to use which</li>
  <li>Creating a custom Twig filter</li>
  <li>Accessing variables and functions in a plugin</li>
  <li>Creating a custom global function</li>
  <li>Creating a custom global object</li>
  <li>Creating a custom statement (or "logic tag")</li>
  <li>Creating a custom operator</li>
  <li>Calling a plugin service class from Twig </li>
  <li>Making custom database calls from Twig</li>
  <li>Post-processing HTML after Twig has finished rendering</li>
  <li>Changing Twig settings</li>
  </ul>
  
Tags: <plugin-development><templating><twigextension>
Title: The Definitive Guide to Extending Twig in Craft CMS
ThreadText: # The Definitive Guide to Extending Twig in Craft CMS
  
  (Asked by: username_0 on 2017-01-11)
  
  So Craft's implementation of Twig is already very powerful and suitable to most common tasks. The Craft Docs already provide a great intro into using Twig and the handy extensions provided by Craft:
  
  * [Craft Templating Overview](https://craftcms.com/docs/templating-overview)
  * [Craft Twig Primer](https://craftcms.com/docs/twig-primer)
  * [Craft Full Templating Reference](https://craftcms.com/docs/templating)
  
  **But what about when you need to go further and build in some sweet custom functionality?**
  
  This question serves to be a starting point that summarises all the different ways to extend Twig with custom functionality, including:
  
  * Filters, functions, objects, macros and statements – when to use which
  * Creating a custom Twig filter
  * Accessing variables and functions in a plugin
  * Creating a custom global function
  * Creating a custom global object
  * Creating a custom statement (or "logic tag")
  * Creating a custom operator
  * Calling a plugin service class from Twig
  * Making custom database calls from Twig
  * Post-processing HTML after Twig has finished rendering
  * Changing Twig settings
  
  **Tags:** plugin-development, templating, twigextension
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2017-01-11. Score: 14
  
  > *To encourage input, this is a community wiki post. Any user with at least 100 reputation points may contribute.*
  
  # Functions, filters, objects, macros and statements – when to use which
  
  A **function** is one of the simplest constructs in Twig – it takes one or more inputs and returns a single output:
  
  ```
  {{ round(42.9) }} will output 43
  
  ```
  
  These are best used for simple, commonly used operations that generate or transform data, such as a Lorem-Ipsum generator: `{{ loremIpsum(50) }}`. But note that functions are often better grouped into an object to prevent name collisions (see below).
  
  A **filter** is almost identical to a function, except that it offers a different syntax, which can be more readable when chaining several filters together (they read in progressive order):
  
  ```
  {{ 1000000 | number }} will output 1,000,000
  {{ 1000000 | number(false) }} will output 1000000
  {{ 'ABC' | lower | replace('c', 'd') }} will output abd
  
  ```
  
  It also provides an easy way to wrap around a larger block of text:
  
  ```
  {% filter upper %}
      This text becomes uppercase
  {% endfilter %}
  
  ```
  
  Note that you can also do this with a function, but it requires an additional line:
  
  ```
  {% set myText %}
      A quick brown fox
  {% endset %}
  {{ filterCurseWords(myText) }}
  
  ```
  
  Use a filter when:
  
  * It might be necessary to place it in a chain along with other filters
  * It might be necessary to place around larger blocks of text/content
  
  A **global variable** is one accessible to all templates in your project automatically:
  
  ```
  <h1>{{ siteName }}</h1>
  
  ```
  
  A **global object** is also accessible to all templates in your project, but can contain variables, functions or both:
  
  ```
  {{ currentUser.friendlyName }}
  {{ currentUser.can('accessCp') }}
  
  ```
  
  Objects provide a good way to neatly group variables and functions and prevent collisions.
  
  A Twig **statement** (sometimes called a "logic tag") is used to designate the flow of logic and may only execute the content inside based on certain circumstances.
  
  ```
  {% cache %}
      {% for block in entry.myMatrixField %}
          <p>{{ block.text }}</p>
      {% endfor %}
  {% endcache %}
  
  ```
  
  Note that caching would not work as a filter, because the content inside a filter is always executed *prior* to being passed into the filter. By implementing the cache tag as a *statement*, it is able to only execute the content inside when appropriate.
  
  Finally, it's worth mentioning **macros**. They assist with reusing snippets of content or HTML in multiple places. Mijingo has written a [great tutorial](https://mijingo.com/blog/using-macros-in-twig-and-craft) that explains macros in Craft.
  
  ```
  {% import "forms.html" as forms %}
  {{ forms.input('username') }}
  
  ```
  
  Note, however, that the functionality of macros can sometimes be replicated via a simple include, with less code and more clarity:
  
  ```
  {% include 'mySnippet' with { enabled: true } %}
  
  ```
  
  ---
  
  # Creating a custom Twig filter
  
  ```
  {{ myVariable | myFilter }}
  
  ```
  
  *More content to come here. Feel free to contribute some instructions if you're able.*
  
  ---
  
  # Accessing a plugin's variables and functions
  
  ```
  {{ craft.myPlugin.myVariable }}
  {{ craft.myPlugin.myFunction() }}
  
  ```
  
  *More content to come here. Feel free to contribute some instructions if you're able.*
  
  ---
  
  # Creating a custom global function
  
  ```
  {{ customFunction() }}
  
  ```
  
  *More content to come here. Feel free to contribute some instructions if you're able.*
  
  ---
  
  # Creating a custom global object
  
  ```
  {{ browser.version }}
  {{ browser.isMobile() }}
  
  ```
  
  *More content to come here. Feel free to contribute some instructions if you're able.*
  
  ---
  
  # Creating a custom statement (logic tag)
  
  ```
  {% devOnly %}
      ...output some debugging info here...
  {% endDevOnly %}
  
  ```
  
  Refer to <http://twig.sensiolabs.org/doc/2.x/advanced.html#tags>
  
  *More content to come here. Feel free to contribute some instructions if you're able.*
  
  Be aware that sometimes the functionality can be achieved by creating a filter instead of a statement:
  
  ```
  {% filter uppercase %}
      A quick brown fox
  {% endfilter %}
  
  ```
  
  However the benefit of a statement is that the code inside is not run unless the statement permits it, whereas in a filter the code is always run, and then later sent to the filter.
  
  ---
  
  # Creating a custom operator
  
  ```
  {{ ! true }}
  
  ```
  
  Refer to <http://twig.sensiolabs.org/doc/2.x/advanced.html#operators>
  
  *More content to come here. Feel free to contribute some instructions if you're able.*
  
  ---
  
  # Calling a plugin service class from Twig
  
  Under normal circumstances, Twig templates only have access to a plugins *Variable Classes* and not their *Service Classes*. But using a simple PHP trick, you can pass all calls on transparently:
  
  *Twig > Variable Class > Service Class*
  
  ```
  // craft/plugins/YourPlugin/variables/YourPluginVariable.php
  class YourPluginVariable
  {
      /** 
       * If function is not found in this class, go find it in service class
       */
      function __call($method, $arguments) {
          return call_user_func_array(array(craft()->YourPlugin_YourService, $method), $arguments);
      }   
  }
  
  ```
  
  Be sure to rename `YourPlugin` and `YourService` to reflect the names of your plugin and service class.
  
  ---
  
  # Making custom database calls from Twig
  
  ```
  {{ craft.myPlugin.fetchUserCount() }}
  
  ```
  
  Firstly this requires a custom plugin.
  
  In Craft, database calls need to be made via a service class, however because you can only access *variable classes* from Twig, you need to pass one to the other. (See the point above for a clean way to transparently pass calls from a variable class to a service class.)
  
  Twig > Variable Class > Service Class > Database Query
  
  *More content to come here. Feel free to contribute some instructions if you're able.*
  
  ---
  
  # Post-processing HTML after Twig has finished rendering
  
  *More content to come here. Feel free to contribute some instructions if you're able.*
  
  ---
  
  # Changing Twig settings
  
  *More content to come here. Feel free to contribute some instructions if you're able.*
  
  
  ---
  
  