Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Functions, Filters and Debugging with dump

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

Just like PHP or JavaScript, Twig has functions that can be used once we're inside either a say something or do something Twig delimiter. To see the built-in functions, once again check out the bottom of the Twig Documentation page. In your application - especially if you're using Twig inside something like Symfony or Drupal - you may have even more functions available to you. Fortunately, the syntax to use a function is always the same: just check out your project's documentation to see what other goodies you have.

Using a Function

Let's check out the random() function... which gives us, shockingly, a random number! If we want to print out that random number, we can do it using the "say something" syntax:

{# templates/homepage.twig #}

<div class="price">
    {{ random() }}
</div>

You can also use a function inside a "do something" tag, like checking to see if the random number is less than 5:

{# templates/homepage.twig #}

<div class="price">
    {{ random() }}

    {# random(10) returns a number from 0 to 10 #}
    {% if random(10) < 5 %}
        Really cheap!
    {% endif %}
</div>

This works exactly the same, except that it lives inside the if statement. Like we've done here, a function can have zero or many arguments, each separated by a comma.

Using Filters

This is nice, but Twig has something even cooler: filters! Like with everything, you can find a filter list in the Twig Documentation, though you may have even more in your project. Let's check out the upper filter. We can use the upper filter to uppercase each product by placing a pipe (|) to the right of the variable and using the filter:

{# ... #}
<h2>{{ product|upper }}</h2>

This works just like a function, except with a different syntax. Whatever you have to the left of the pipe is passed to the filter, which in this example, upper-cases everything.

Heck, you can use as many filters as you want!

{# ... #}
<h2>{{ product|upper|reverse }}</h2>

Now we're upper-casing the name and then reversing the text.

Using Functions, Filters and Math

Filters can be used after functions too. Instead of printing out the random number, let's divide it by 100 to get a decimal, then use the number_format to show only one decimal place:

{{ (random() / 100)|number_format(1) }}

Getting the Length of a Collection

In fact, functions and filters can be used anywhere. Let's use the length filter to print a message if there are no penguin products for sale:

{% if products|length == 0 %}
    <div class="alert alert-error span12">
        It looks like we're out of really awesome-looking penguin clothes :/.
    </div>
{% endif %}

This filter takes an array or collection to the left and transforms it into a number, which represents the number of items in the collection. We can use this to see if there are no products. I'll temporarily pass in zero so we can check this out.

Filters and Arguments using "date"

Just like functions, sometimes a filter has one or more arguments. A really common filter is date. This takes a date string or PHP DateTime object and changes it into a string. We can go to date() to look up the letters used in the date format. To try this out, we can just hardcode a string to start:

{# templates/homepage.twig #}

<div class="sale-ends-at">
    {{ 'tomorrow noon'|date('D M jS ga') }}
</div>

The "tomorrow noon" part is just a valid input to PHP's strtotime() function, which accepts all sorts of interesting strings as valid dates. The Twig date filter takes that string and renders it in the new format that we want. Of course, we can also send a variable through the date filter. Let's pass in a saleEndsAt variable into the template and render it the same way:

// index.php
// ...

echo $twig->render('homepage.twig', array(
    // ...
    'saleEndsAt' => new \DateTime('+1 month')
));
{# templates/homepage.twig #}

<div class="sale-ends-at">
    {{ saleEndsAt|date('D M jS ga') }}
</div>

We can even use the date filter to print out the current year. For the value to the left of the filter, I'll use now. I'll use the Y string to print out the 4-digit year. Sweet!

{{ 'now'|date('Y') }}

Use functions and especially filters to do cool stuff in Twig, and look at the documentation for each to see if what you're using has any arguments.

The dump Function for Debugging

Before we move on, let's talk about the dump() function. If you don't know what a variable looks like, use the dump() function to see its details:

{{ dump(products) }}

Even better, use the dump() function with no arguments to see all the variables that you have access to:

{{ dump() }}

With this function, there's not much you won't be able to do!

We experimented a lot in this section. I'll use the {# syntax to comment out some of the things we've done so that our page makes a bit more sense.

To clean things up, we removed the upper and reverse filters, the entire spot where we print the random numbers, and the printing of the current year.

Leave a comment!

12
Login or Register to join the conversation
Benoit L. Avatar
Benoit L. Avatar Benoit L. | posted 3 years ago

I think that Twig has trouble guessing the getter name, is have a boolean property in DB called is_active, the getter (generated) is getIsActive():?bool , Twig says it cannot find a method [list of guessed names], like I had to rename the getter to a proposed one like getis_active() to make it work. However Symfony has no problem with this. Do I have to conform to a naming convention with Twig?

Reply

Hey Benoit L.!

Hmmm. If you have a getIsActive method, would expect that you could use {{ object.isActive }}. Is that not working? Or were you using something like {{ object.is_active }}> The second would indeed not work with getIsActive()... but let me know what your situation is :).

Cheers!

Reply
Benoit L. Avatar

Yeah it works thanks! I was expecting Twig to literally access the object property directly, in fact it guesses it from the getter method name.

Reply
Default user avatar
Default user avatar Shairyar Baig | posted 4 years ago

Hi Ryan,

Do you know if it is possible to clear cache of a particular twig file rather than clearing the entire cache. Suppose on a login page i add a hyperlink to the registration page, now for this change to be seen by the user should not require me to clear the entire cache directory so thats why i am asking if it is possible to clear the cache of a single file? or setup symfony in a way that if it detects a change in view then recreate the cache.

Reply

Hey Shairyar!

Obviously, the "dev" environment already detects cache changes, but that's not something you'll want to activate for the "prod" environment - it just has too much performance impact. The best answer to your question is - don't try this :). Symfony's cache is meant to be completely cleared and warmed up. I assume you're making changes on production and don't want to run cache:clear? Is there a reason why clearing the full cache is a problem? Technically, you could probably do something like this (but no guarantees!)


$twigClass = $this->get('twig')->getTemplateClass('foo/bar.html.twig');
$cacheKey = $this->get('twig')->getCache()->generateKey('foo/bar.html.twig', $twigClass);
unlink($this->getParameter('kernel.cache_dir').'/twig/'.$cacheKey;

That almost certainly won't work yet - but *if* it's possible, this is the general idea. But mostly, you shouldn't do it ;).

Cheers!

Reply
Default user avatar
Default user avatar Shairyar Baig | weaverryan | posted 4 years ago

Thanks, I am working on a project where the admin wants a way to be able to edit email templates and right now the templates are twig files in bundle so I was wondering if I allow them to update twig files then cache has to be cleared and that's why I asked if we can clear a single file cache in this case the email templates. Right now it is clearing the entire cache, my only concern while clearing the entire cache is if the users on website will face problem surfing the website while admin is making the changes.

If this is a bad idea then I am thinking to save email templates in DB this way no cache clear will be required.

Reply

Hey Shairyar!

Ah, yea - that's a cool use for Twig. Yes, save them to the database (it's just easier anyways - no need to worry about file permissions on your web server, etc). Then, create your *own* twig service (instead of the core Twig service) and use *it* to render the templates. Literally, in service.yml, you'll have a new entry called something like 'email_template_twig' and you'll set the class to Twig_Environment and configure as needed. For this service, I wouldn't even use caching - you'll be rendering these templates so rarely, it won't matter much. And if you do use caching, you can set it to a specific directory (away from the normal Twig cache) and then delete that entire directory when one of the templates is updated.

Good luck - sounds cool!

Reply
Default user avatar
Default user avatar Shairyar Baig | weaverryan | posted 4 years ago

Hi Ryan,

Thanks alot. I ended up creating a service and a twig extension that will give me access to all the emails content that admin has set in admin panel, it worked out pretty well.

Thanks alot.

Reply
Default user avatar
Default user avatar Matthew Appleton | posted 4 years ago

Hello — just wondering how come the dump function in the tutorial shows a clearly formatted chunk of info, whereas I get a non-formatted string (same info) on my setup?
(macosx browsers running off MAMP)

— what is generating the styled dump in the tutorial screenshot at 5'25" mins into the tutorial? Perhaps a different software tool / browser?

thanks!

Reply

Hey Matthew,

Yes, it's a special PHP extension called Xdebug. While it's installed - you'll get more nice output for var_dump() function. You can install it easily with Homebrew MacOS package manager if you're handling your PHP version with Homebrew in console, but if you're using MAMP - probably you can activate it somewhere in its preferences, or, just Google for how to do it properly for MAMP.

P.S. Also take a look at VarDumper Symfony Component: https://symfony.com/doc/cur... - you can install this library with Composer in your project and use it. So even if you do not have Xdebug, with dump() function you'll get much more nice output and even can easily search inside it ;)

Cheers!

Reply
Default user avatar
Default user avatar Matthew Appleton | victor | posted 4 years ago

Hi Victor — many thanks, great tip, and now I know what it does, it is a simple toggle in the PHP settings in MAMP Pro to get this running — big improvement!

Reply

Hey Matthew,

Glad to know you MAMP Pro has this option. Thanks for sharing this information with others.

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial uses Twig 1. There are newer versions of Twig, but they don't contain significant differences. So, Twig on!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": []
}