Has anyone connected F3 and Twig recently?

47 views
Skip to first unread message

David Rhoderick

unread,
Sep 18, 2017, 10:19:25 AM9/18/17
to Fat-Free Framework
I was able to find this post from a while back:


It only works with Twig 1.0 and F3 2.0.  I tried to figure it out but I got lost pretty quickly so I was wondering, has anyone connected these two frameworks at their current versions (2.0 and 3.2.6 respectively)?  I wouldn't have thought Twig would be so useful since F3 has its own templating engine but doing conditional logic and repeating code is so much less verbose in Twig and you can really fly when using it compared with the default F3 templating code.

ved

unread,
Sep 18, 2017, 10:58:10 AM9/18/17
to Fat-Free Framework
doing conditional logic and repeating code is so much less verbose in Twig and you can really fly when using it compared with the default F3 templating code.

Never used Twig personally. Can you present us with some examples that support this statement?

Anyway, if Twig uses composer I would guess it would be as simple as adding it to your composer.json. Assuming of course that you're also using composer for F3.

David Rhoderick

unread,
Sep 19, 2017, 3:48:06 PM9/19/17
to f3-fra...@googlegroups.com
I've been using Twig with the WordPress "Timber" theme on several projects.  I just recently went back to using F3 and was just about to create a navbar with Bootstrap and instead of writing the following in Twig:

<li class="nav-item">
  <a class="nav-link{% if item.current %} active" href="{{item.get_link}}">{{item.title}} {% if item.current %}<span class="sr-only">(current)</span>{% endif %}</a>
</li>

I have to write this:

<check if="{{@item_current}}">
  <true><li class="active"><a id="nav-{{@item_slug}}" href="/{{@item_link}}">{{@item_title}}</a></li></true>
  <false><li><a id="nav-{{@item_slug}}" href="/{{@item_link}}">{{@item_title}}</a></li></false>
</check>

I still love F3 for other reasons but since I've started using Twig, I've gotten much more used to it for templating because of the inline conditionals.  Before, I'd say Angular was more useful in that way than F3, but Twig really takes the cake.

Here is another example:

<div class="container">
  <div class="item-grid">
    {% for row in post.get_field('cottages')|batch(3) %}
       <div class="item-row {% if row|length == 2 %}double{% elseif row|length == 1 %}single{% else %}full{% endif %}">
          {% for cottage in row %}
            {% include 'cottage-listing.twig' with {cottage: cottage} %}
          {% endfor %}
        </div>
    {% endfor %}
  </div>
</div>

Don't worry about the "get.field()" call (this is from the Timber WordPress theme).  This uses the batch filter to break the repeats into groups of at most 3 and then uses the length filter to figure out how many items are in each row (in case there are less than 3) and select a class that displays them nicely.  The inline if statements might look a little odd but when you get used to it, it makes a lot of sense.  Otherwise, I'm adding a lot more lines of <check> statements.  I'd love to hear how to do this with less code in F3 if it is possible in this concise a manner.

Lastly, here's a crazy example of Twig usage:

<{{heading.type}} {% if heading.html_id %}id="{{heading.html_id}}" {% endif %}class="{{heading.alignment}} {% if heading.dark_theme %}bg-inverse text-white {% endif %} {% if heading.size %}display-{{heading.size}}{% endif %}{% if heading.top_padding %} pt-{{heading.top_padding}}{% endif %}{% if heading.right_padding %} pr-{{heading.right_padding}}{% endif %}{% if heading.bottom_padding %} pb-{{heading.bottom_padding}}{% endif %}{% if heading.left_padding %} pl-{{heading.left_padding}}{% endif %}">{{heading.text}}{% if heading.add_faded_secondary_text %}<small class="text-muted"> {{heading.faded_secondary_text}}</small>{% endif %}</{{heading.type}}>

I created a WordPress theme using Timber and Twig and the idea was to allow users to edit a lot of Bootstrap properties from the backend.  Maybe it's a bit of a crazy idea, and the code certainly looks that way, but I only have to write this snippet once and using it throughout the theme.  It gives the user the ability to change the heading type, padding in all directions, a size class, and color inversion along with other things.  Maybe I wouldn't ever really try to write this for a F3 project, but I think it illustrates the possibilities that Twig gives you.  I imagine I'd have to write a crazy amount of <check> elements to get this to work and it might not even be feasible with the basic F3 templating engine.

David Rhoderick

unread,
Sep 19, 2017, 5:04:14 PM9/19/17
to Fat-Free Framework
Funnily enough, thank you @ved for suggesting the obvious!  So far, I've been able to integrate Twig simply by setting up the environment the following way:

$twig_loader = new Twig_Loader_Filesystem('html');
$twig
= new Twig_Environment($twig_loader, array(
   
'debug' => true,
   
'cache' => 'twig_cache',
   
'auto_reload' => true
 
));
$f3
->set('twig', $twig);

Then for routes, I can use it like the following:

$f3->route('GET /',
 
function($f3) {
    echo $f3
->get('twig')->render('templates/frontend.twig', array(
           
'title' => 'Home',
           
'view' => 'views/home.twig'
         
));
 
});

The only thing I have an issue with is I think it is a bit too verbose to call "$f3->get('twig')" to access Twig.  Is there any way I can make it a global variable?  I tried using PHP $GLOBALS but it didn't work.

ved

unread,
Sep 19, 2017, 7:48:02 PM9/19/17
to Fat-Free Framework
Make sure you've read through all the examples in the guide, and also into the Template and Preview classes documentation. 

But basically you can do some simpler stuff. For example you don't really need a full check/true/false block for simple one liners. E.g.:

<a href="/somelink" class="link{{ @is_active ? ' active' : ''  }}">{{ @link.name }}</a>

You can do a lot inside F3's curly braces {{  }}. See Template Directives.

It's also possible to use the following braces format and use (semi-)regular php instructions: E.g.:

{~ if(@something === 'value'): ~}
cool
{~ else: ~}
not cool
{~ endforeach; ~}

Which I personally prefer over the xml tags like check, repeat, etc.

I'm sure I could probably replicate some of your examples but if you're used to Twig, just go ahead and use that. Still the above info may come useful in the future.

As for your other question, I think Base implements array access so you can probably also access it through $f3['twig']->something (not really sure). You can also set it as a class property and use $this->twig->something. Or you could abstract all the initializing and rendering inside some private method, use afterroute, etc.

Good luck.
Reply all
Reply to author
Forward
0 new messages