3

I am running apache and php on Ubuntu 17.04 I am using twig. I installed Twig like this.

cd /var/www/html/my-new-website
composer install twig/twig
composer require twig/twig

At this point the way I have been using Twig is: first I create a php file and do some stuff, create an array and render the template with the array data. Next I have separated sections of my page and put them in templates.

here is an example index.php that creates an array of directories then renders it with the files.html.twig located in the templates directory.

<?php
require_once 'vendor/autoload.php';
$loader = new Twig_Loader_Filesystem('templates');
$twig = new Twig_Environment($loader, array(
    'cache' => 'cache',
));

$dir = "path/to/dir";
$exclude = array( ".","..",".*","index.php" );
$files = array_diff(scandir($dir), $exclude);

/*
echo ''; print_r($files);
*/

$template = $twig->loadTemplate('files.html.twig');
echo $template->render(['files' => $files]);
?>

here is the files.html.twig, it extends "base.html.twig"

{% extends "base.html.twig" %}

{% block title %}
My Directory Listing
{% endblock %}

{% block content %}
    {% for file in files %}
      <li><a href="{{ file | url_encode }}">{{ file }}</a></li>
    {% endfor %}
{% endblock %}

and the base.html.twig contains main wrapper with navbar and footer. This all works as expected.

Right now I have the navbar in my base.html.twig, it is just html where I have to edit the items.

I have made a php function to get the navbar array that works in a template(navbar.html.twig), but the problem is I have to put or include this php function in each page I create. I want my navbar.html.twig template to get the array from the php funtion directly.

I believe I need to create a twig extension(php function) and register it. I have read the docs on this(all seem to be for a full symfony install, I am using twig only).

I think this article is on the right path but did not give me the information I needed to understand Call PHP function from Twig template

I do not get

  1. where to put my php function? Can I just create a folder called extensions and put a navbar-list-funtion.php file in there?
  2. where to register the function so it can be called from a template? some documentation say to register in the app/config/services.yml (I do not have this file or directory)
  3. after I put the php function in a recognized place, then register it properly,... how will I call the returned array in the template navbar.html.twig?
Cœur
  • 37,241
  • 25
  • 195
  • 267
jasenmichael
  • 388
  • 5
  • 17
  • If you are not using a framework like symfony, just follow the steps on the official [documentation](https://twig.symfony.com/doc/2.x/advanced.html#creating-an-extension) – DarkBee Aug 17 '17 at 05:49
  • thanks @darkbee, I have been and will continue to read the documentation. I just don't get it hence the reason I posted here. – jasenmichael Aug 17 '17 at 14:33

1 Answers1

2

from the comments

If you are not using a framework like symfony, it's a bit flavor based on how you deal with this situation. Me, myself, i'm using namespaces in my project to enable autoloading with composer. My tree structure just follows my namespace e.g. My/Project/Twig/Extensions

The "best" way to extend Twig is by using a Twig_Extension class Just place a new file in the folders you created with an appropriate name


note: As off Twig 2.X the function getName() is no longer mandator

My/Project/Twig/Extensions/ProjectTwigExtension.twig

namespace My/Project/Twig/Extensions

class ProjectTwigExtension extends Twig_Extension {

    public function getFunctions() {
        return array(
            new Twig_SimpleFunction('twig_function_name', array($this, 'getTwigFunctionName')),
            new Twig_SimpleFunction('twig_function_foo', array($this, 'getTwigFunctionFoo')),
            //and so on....,            
        );  
    }

    public function getFilters() {
        return array(
            new Twig_SimpleFilter('twig_filter_name' , array($this, 'getTwigFilterName')),
            new Twig_SimpleFilter('twig_filter_foo' , array($this, 'getTwigFilterFoo')),
            //and so on....,
        );
    }

    public function getName() {
        return 'ProjectTwigExtension'; //this is mandatory for twig < 2.0
    }        
}

By using an extension class you can easily group all your functions/filters/nodes/globals/... After you created this class all you need to do is register the class inside Twig. As I don't know the specifics you will need to look in your project where you do

$twig = new Twig_Environment($loader);

To register the class just use the following line,

$twig->addExtension(new ProjectTwigExtension());

As you can the extension class has a function getFunctions, here you can define all the functions you want.

new Twig_SimpleFunction('twig_function_name', $callable)

The first argument defines how the function will be called inside a twig template, the second argument is a callable

  • new Twig_SimpleFunction('twig_function_name', array($this, 'method'))
    Will call the function method inside the current extension class
  • new Twig_SimpleFunction('twig_function_name', 'trim')
    Will call the global function trim
  • new Twig_SimpleFunction('twig_function_name', array($obj, 'method'))
    Will call the function method of the instance $obj
  • new Twig_SimpleFunction('twig_function_name', array('MyClass', 'method'))
    Will call the static function method from MyClass
  • new Twig_SimpleFunction('twig_function_name', function($arg1, $arg2) { // ...; })
    Will execute the closure
DarkBee
  • 16,592
  • 6
  • 46
  • 58