virhi
virhi

Reputation: 203

Sonata Media Bundle : acces media url

I am using sonata media bundle.

and I was wondering how can I access the media url in twig.
I just want the url, I do not need to show the media.

Any suggestions?

Upvotes: 12

Views: 19537

Answers (5)

Denys Horobchenko
Denys Horobchenko

Reputation: 539

@javigzz's is perfect in case of default context. I used custom context, so had to handle $format first taking into account context name:

$provider = $this->container->get($media->getProviderName());
$format = $provider->getFormatName($media, $format);
$url = $provider->generatePublicUrl($media, $format);

Additional Note

Since injecting container is not the best practice, it is better to get provider from the provider pool:

class Foo {
    public function __construct(Sonata\MediaBundle\Provider\Pool $pool) {
        $this->pool = $pool;
    }

    public function getUrl($media, $format) {
        $provider = $this->pool->getProvider($media->getProviderName());
        $format = $provider->getFormatName($media, $format);
        $url = $provider->generatePublicUrl($media, $format);

        return $url;
    }
}

Upvotes: 9

Krewetka
Krewetka

Reputation: 99

You can use: {% path media, 'reference' %}

@Blauesocke - tried your solution and had exactly the same result for file provider with using both

{% set img_url = media_public_url(media, 'reference') %}
{{ dump(img_url) }}

and

{%  path sonata_admin.value, 'reference' %}

Upvotes: 3

Thomas Kekeisen
Thomas Kekeisen

Reputation: 4406

Since @javigzz's answer did not work for me, here is a twig extension that works with the latest version of sonata_media:

namespace Socialbit\SonataMediaTwigExtensionBundle\Twig;

use Sonata\CoreBundle\Model\ManagerInterface;
use Symfony\Component\DependencyInjection\Container;

Class:
/**
 * Description of MediaPathExtension
 *
 * @author thomas.kekeisen
 */
class MediaPathExtension extends \Twig_Extension
{
    /**
     *
     * @var type Container
     */
    protected $container;

    /**
     *
     * @var type ManagerInterface
     */
    protected $mediaManager;

    public function __construct(Container $container, $mediaManager)
    {
        $this->container = $container;
        $this->mediaManager = $mediaManager;
    }

    public function getFunctions()
    {
        return array
        (
            'media_public_url' => new \Twig_Function_Method($this, 'getMediaPublicUrl')
        );
    }

    /**
     * @param mixed $media
     *
     * @return null|\Sonata\MediaBundle\Model\MediaInterface
     */
    private function getMedia($media)
    {
        $media = $this->mediaManager->findOneBy(array(
            'id' => $media
        ));

        return $media;
    }

    public function getMediaPublicUrl($media, $format)
    {
        $media = $this->getMedia($media);

        $provider = $this->container->get($media->getProviderName());

        return $provider->generatePublicUrl($media, $format);
    }

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

services.yml:

services:
    socialbit.sonatamediatwigextensionbundle.mediapathextension:
        class: Socialbit\SonataMediaTwigExtensionBundle\Twig\MediaPathExtension
        public: false
        arguments:
            - @service_container
            - @sonata.media.manager.media
        tags:
            - { name: twig.extension }

The usage will be the same:

{% set img_url = media_public_url(media, 'reference') %}
{{ dump(img_url) }}

Upvotes: 4

javigzz
javigzz

Reputation: 942

But if you do not want to render the media right there and just store the url in a variable, you need to ask the media provider for the public url. This was my case, that I needed to pass the url to another template. I did it creating a custom function in my Twig Extension (see here: http://symfony.com/doc/current/cookbook/templating/twig_extension.html).

Provided that you have the container available in your extension service with $this->container, you can do like this:

public function getMediaPublicUrl($media, $format)
{
    $provider = $this->container->get($media->getProviderName());

    return $provider->generatePublicUrl($media, $format);
}

Register the function in the extension:

public function getFunctions() {
     ....
    'media_public_url' => new \Twig_Function_Method($this, 'getMediaPublicUrl'),
     ....
    );
}

And call your new helper form your template:

{% set img_url = media_public_url(media, 'small') %}

for instance

regards

Upvotes: 12

Francesco Casula
Francesco Casula

Reputation: 27130

You have to use the path media helper:

{% path media, 'small' %}

In the above code, media is an instance of the media entity, and small is the chosen format.

http://sonata-project.org/bundles/media/master/doc/reference/helpers.html#twig-usage

Upvotes: 14

Related Questions