Slim and Twig: Attribute method

Hi,

I am trying to implement DRY-approach. And have a hard-time figuring out how i can solve the following:

  • pass $var_en, $var_two and $var_three to Twig
  • pass $lang to Twig (containts: ‘en, two or three’)
In Twig i will use: {{ attribute(_context, 'var_'~lang ) }} 

// The output will be the string of $var_en, two or three

But now i am not sending a single object but a collection to twig.

  • $products
  • $lang
{% for item in products %}
    {{ attribute(_context, 'item.product.description_'~lang ) }} 
{% endfor %}

This won’t work. And i think it is because of the ’ . (dot) '.
I tried also things like

{{ attribute(_context, 'item['product']['description_'~lang~''] ) }} and
{{ attribute(_context, item.product.'description_'~lang ) }} etc

Can;t seem to make it work. Does anyone have a solution/clue?

You could make a custom twig function that would be able to handle the “translations”

Hi Marcelloh,

Do you have a example how I achieve this?

I haven’t done if in Simple (yet) , but in Silex, so to give you a rough idea:

Somewhere in your twig configuration part:

$app->extend(‘twig’, function ($twig, $app)
{
$twig->addExtension(new MyExampleTwigExtension($app));
return $twig;
});

MyExampleTwigExtension:

class MyExampleTwigExtensionextends \Twig_Extension
{
    protected $app;

    public function __construct($app)
    {
        $this->app = $app;
    }

    public function getFunctions()
    {
        return array(
            new \Twig_SimpleFunction('doMagic', array($this, 'doMagic'), array('is_safe' => array('html'))),
            new \Twig_SimpleFunction('morerMagic', array($this, 'moreMagic')),
        );
    }

   /**
    * Do magic
    *
    * Example:
    * {{ doMagic('product', 'NL') }}
    */
  public function doMagic($field, $lang)
  {
      // your magic goes inhere
  }

I tried my own idea out :slight_smile: Works like a charm!

My twig register part:

// Register twig on container
$container['view'] = function ($container) {
	$settings = $container->get('settings');
	$view = new \Slim\Views\Twig(
		$settings['view']['template_path'],
		$settings['view']['twig']
	);

	// Instantiate and add Slim specific extension
	$view->addExtension(new SpecialExtension($container));

	// global twig values
	$view->offsetSet('common', 'src/Common/views/');

	return $view;
};

So what you can do, is write a extension, that will do something like this:
{{ translate($item, ‘product.description’, $lang) }}
or something along that way.

1 Like

Thanks Marcelloh,

Have to try it still, but I see the logic:

  1. make a custom twig function (translate in your example)
  2. call the function
  3. make some php code and return the correct ‘name’

Do I still use the attribute function? Because the value that is return is only a name (string).

I think , basically you do something like the following in your template:

{% for item in products %}
    {{ translate(item, 'product.description', lang) }}
{% endfor %}

And in the translate method, you just return the right field value based upon the 2 other values.

Just a complete other direction:
if your iten is an object (a model-class), you could perhaps do:
{{ item.getDescription(lang) }}
or something along that way.
and inside the model-class, have a function that handles that call.

Thanks!

I am not quit there. Will get the correct name returned. Only now accessing this (and displaying) is something I don’t understand.

{{ go_compact('item.', 'name_', page.lang ) }}

public function goCompact($val1, $val2, $val3)
{
        $var = $val1;
        $var .= $val2;
        $var .= $val3;        

        return $var;
}
// Output =  item.name_en > that's correct. But I would like to access the array/object. 

Did try the attribute method.

{{ attribute (_context, (go_compact('item.', 'name_', page.lang )) }}
// No success

I can’t quite understand what you are doing with _context, but I think you could solve it with this:

{% for item in products %}
{{ attribute(item, go_compact(‘item.’, ‘name_’, page.lang ) ) }}
{% endfor %}

See:
https://twig.sensiolabs.org/doc/2.x/functions/attribute.html
{{ attribute(array, item) }}
Where I think, your ‘item’ is the array part, and the second value ‘item.name_en’ would be the array key.

1 Like

Or something like this:

public function goCompact($item, $val1, $val2, $val3)
{
    $var = $val1;
    $var .= $val2;
    $var .= $val3;        

    return $item[var];
}
1 Like

Thanks!

Just made a typo: but it works! :slight_smile: