Sonata Page 5: Adding Open Graph Tags with SonataPage and SonataMediaSonata

If you have already used SonataPage and SonataMedia, you know how powerful they are for managing content and media on your site. In this article, I am going to show you how to extend these tools to easily add Open Graph tags to your pages to enhance their sharing on social networks.

Why Open Graph tags?

Open Graph (OG) tags are meta-tags that you can add to your pages to define titles, descriptions, images, and other information that will be used when the page is shared on platforms like Facebook. With these tags, you have precise control over how your content is presented.

Integration with Sonata

With our extension OGAdminExtension, we will add three new fields to SonataPage's administration interface: ogTitle, ogDescription, and ogImage.

1. Modifying the entity

First, let's modify the SonataPagePage entity to include three new fields: ogTitle, ogDescription, and ogImage.

<?php
namespace App\Entity;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Sonata\PageBundle\Entity\BasePage;

#[ORM\Entity]
#[ORM\Table(name: 'page__page')]
class SonataPagePage extends BasePage
{
    #[ORM\Id]
    #[ORM\Column(type: Types::INTEGER)]
    #[ORM\GeneratedValue]
    protected $id;


    #[ORM\Column(type: 'string', length: 255, nullable: true)]
    private string $ogTitle;

    #[ORM\Column(type: 'text', nullable: true)]
    private string $ogDescription;


    #[ORM\ManyToOne(targetEntity: "SonataMediaMedia")]
    #[ORM\JoinColumn(name: "media__media_id", referencedColumnName: "id", nullable: true)]
    private ?SonataMediaMedia $ogImage = null;

    public function getOgTitle(): string
    {
        return $this->ogTitle;
    }

    public function setOgTitle(string $ogTitle): self
    {
        $this->ogTitle = $ogTitle;
        return $this;
    }

    public function getOgDescription(): string
    {
        return $this->ogDescription;
    }

    public function setOgDescription(string $ogDescription): self
    {
        $this->ogDescription = $ogDescription;
        return $this;
    }

    public function getOgImage(): ?SonataMediaMedia
    {
        return $this->ogImage;
    }

    public function setOgImage(?SonataMediaMedia $ogImage): self
    {
        $this->ogImage = $ogImage;

        return $this;
    }
}

Here, we've added three properties and their associated getters and setters.

2. Creating the extension

Next, let's create an extension to customize the administration form of the page:

<?php
namespace App\Admin\Extension;

use Sonata\AdminBundle\Admin\AbstractAdminExtension;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Form\Type\ModelListType;
use Sonata\MediaBundle\Provider\ImageProvider;
use Sonata\MediaBundle\Entity\MediaManager;

class OGAdminExtension extends AbstractAdminExtension
{
    private $mediaManager;
    private $providerImage;

    public function __construct(MediaManager $mediaManager, ImageProvider $providerImage)
    {
        $this->mediaManager = $mediaManager;
        $this->providerImage = $providerImage;
    }

    public function configureFormFields(FormMapper $form): void
    {

        $admin = $form->getAdmin();
        if ($admin->hasSubject() && null !== $admin->getSubject()->getOgImage()) {
            $media = $this->mediaManager->findOneBy([
                'id' => $admin->getSubject()->getOgImage()->getId()
            ]);
            $mediaUrl = $this->providerImage->generatePublicUrl($media, 'default_small');
        } else {
            $mediaUrl = null;
        }

        $imageHtml = $mediaUrl ? '<img src="' . $mediaUrl . '" alt="' . $media->getName() . '" class="img-thumbnail" />' : 'Aucune image sélectionnée';



        $form
            ->with('seo')
            ->add('ogTitle', null, [
                'label' => 'og:title',
            ])
            ->add('ogDescription', null, [
                'label' => 'og:description',
            ])
            /*->add('ogImage', null, [
                'label' => 'og:image',
            ])*/
            ->add('ogImage', ModelListType::class, [
                'label'=>"og:image",
                'required' => false,
                'btn_add'=>true,
                'btn_edit'=>true,
                'btn_list'=>false,
                'btn_delete'=>false,
                'class'=>"App\Entity\SonataMediaMedia",
                'help' => $imageHtml,
                'help_html'=>true

            ],
                ['link_parameters' =>[
                    'context' => 'default',
                    'provider' => 'sonata.media.provider.image'
                ]]
            )
            ->end();
    }
}

Here, the extension will customize the administration form to add the required fields.

Selection_017

3. Configuring services

After creating the extension, it's necessary to declare it as a service in the service configuration file:

    App\Admin\Extension\OGAdminExtension:
        arguments:
            $mediaManager: '@sonata.media.manager.media'
            $providerImage: '@sonata.media.provider.image'
        tags:
            - { name: 'sonata.admin.extension', target: 'sonata.page.admin.page' }

4. Updating the template

In your Twig template, add Open Graph tags using the properties you've added to your entity:

<meta property="og:title" content="{{ page.ogTitle }}" />
<meta property="og:description" content="{{ page.ogDescription }}" />
<meta property="og:image" content="{{ sonata_path(page.ogImage, 'reference') }}" />

With these steps, you have successfully integrated Open Graph tags to your Sonata Page entity, thereby improving the search engine optimization of your website on social platforms like Facebook, Twitter, and LinkedIn.

image