Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Twig tag or function inside PHP String

Tags:

php

twig

symfony

Is there any way to use something like this?

$foo = "{{ object|filter }}";

Because I'm trying to write a dynamic image converter that needs to output something like the example, but when in my twig I use {{ foo }}, it just outputs a raw string {{ object|filter }} instead of executhing the filter on the object as intended.

I've tried to use {{ foo | raw }} but same result.

What I'm trying to do exactly

CONTROLLER

$image = $em->getRepository('AcmeDemo:Media')->find($id);
$image_src = sprintf("{{ %s | imagine_filter('%s') }}", $image->getWebPath(), 'front_small');
return $this->render('image.html.twig', array(
    'image_src' => $image_src
));

TWIG

<img src="{{ image_src }}"/>

So, I have a twig function inside a PHP variable $image_src, that Twig function could be, once formatted with sprintf {{ '/uploads/foo.jpg' | imagine_filter('front_small') }}.

That is a string for now, because it's inside a php variable $image_src, that variable is sent to my Twig template with the name image_src so, for now it is a string as I've said, if I do

My variable contains "{{ image_src }}" It will output a string that says:

My variable contains "{{ '/uploads/foo.jpg' | imagine_filter('front_small') }}"

Because, as I've said, image_src is just a string, but I want to acutally execute inside my Twig, the string that contains image_src, because yes, it is a string (to the eyes of the compiler) but we all know it is or it is pretended to be a Twig function (because of the syntax).

So, why | raw will not work?, because it is inteded to be used with strings containing HTML code, if it were HTML syntax it would work, but it's a Twig syntax, so It doesn't work.

Resuming, there should be a | compile twig function that executes Twig code inside a variable like | raw does with HTML, but, as this function doesn't exists, I'm wondering if there's a way to achieve it...

As @joshua said, it's like a Javascript eval.

I hope I've explained good what is the problem and what I need.

EDIT

I've used my own twig extension Compile in order to achieve what I needed.

class CompileExtension extends \Twig_Extension
{
    public function getFilters()
    {
        return array(
            'compile'   => new \Twig_Filter_Method($this, 'compile', array(
                'needs_environment' => true,
                'needs_context'     => true,
                'is_safe'   => array('compile' => true)
            )),
        );
    }

    public function compile(\Twig_Environment $environment, $context, $string)
    {
        $loader = $environment->getLoader();

        $compiled = $this->compileString($environment, $context, $string);

        $environment->setLoader($loader);
        return $compiled;
    }

    public function compileString(\Twig_Environment $environment, $context, $string)
    {
        $environment->setLoader(new \Twig_Loader_String());
        return $environment->render($string, $context);
    }

    public function getName()
    {
        return 'compile';
    }
}

UPDATE Accepting @Benjamin Paap answer because it does exactly what I wanted in this case with better code, but my custom Twig class works for every situation.

like image 355
Robert W. Hunter Avatar asked Mar 27 '26 12:03

Robert W. Hunter


1 Answers

What you want to do is not possible in twig without a TwigExtension which renders your string separately.

But looking at your code you're trying to use the LiipImagineBundle the wrong way. It seems tempting to use it this way, but the correct way to generate a url for your thumbnails would be this:

class MyController extends Controller
{
    public function indexAction()
    {
        // RedirectResponse object
        $imagemanagerResponse = $this->container
            ->get('liip_imagine.controller')
            ->filterAction(
                $this->request,         // http request
                'uploads/foo.jpg',      // original image you want to apply a filter to
                'my_thumb'              // filter defined in config.yml
            );

        // string to put directly in the "src" of the tag <img>
        $cacheManager = $this->container->get('liip_imagine.cache.manager');
            $srcPath = $cacheManager->getBrowserPath('uploads/foo.jpg', 'my_thumb');

        // ..
    }
}

https://github.com/liip/LiipImagineBundle#using-the-controller-as-a-service

like image 62
Benjamin Paap Avatar answered Mar 29 '26 00:03

Benjamin Paap