3
votes

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.

1
Are you trying to use a twig filter in PHP or want html output from your custom filter? Any code?Rooneyl
you should read this, and {{ foo|raw }} should work : twig.sensiolabs.org/doc/filters/raw.htmlJC Sama
you want something like javascript's eval, don't you? I don't think that the twig guys put a feature that possibly dangerous as eval into their project.Joshua
JCSama As I've said, {{ foo|raw }} doesn't work neither. @Rooneyl I'm trying to use a twig filter inside twig but using the string from PHP. I've updated my code with an example.Robert W. Hunter
Yeah @Joshua that's exactly what I want, kind of.Robert W. Hunter

1 Answers

1
votes

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