Parliamo del progetto
Partitech Sonata Extra Bundle

Sonata Extra Bundle: modulo di blog

Sonata Extra Bundle fornisce un modulo blog integrato in Sonata Page, con percorsi personalizzabili e una resa adatta ai siti multilingue. Integrazione delle strade principali Aggiornamento delle principali rotte del blog Integra le pagine del tuo sito con...

Contrôles de compatibilité Symfony et Sonata

Sonata Extra Bundle fornisce un modulo blog integrato in Sonata Page, con percorsi personalizzabili e una resa adatta ai siti multilingue.

Integrazione delle strade principali

Aggiornamento delle principali rotte del blog

Integra le pagine del tuo sito con il controller del blog eseguendo il update-core-route ordine:

php bin/console sonata:page:update-core-routes --site={id}

L'esecuzione di questo comando sincronizza la pagina Sonata con i seguenti itinerari ibridi:

  • Categoria del blog: /blog-category/{category}
  • Etichetta del blog: /blog-tag/{tag}
  • Articolo del blog : /blog-article/{article}

Queste rotte corrispondono a delle pagine generate dinamicamente che sono collegate ai rispettivi controller.

Personalizzazione delle rotte

Personalizza i modelli di rotta predefiniti per localizzare o modificare la struttura del tuo URL pur mantenendo il collegamento con il controllore modificando i dettagli della pagina:

  • Un ascoltatore di eventi su routing.loader viene aggiunto automaticamente.
  • Una nuova rotta è creata con il tuo modello personalizzato a partire dal campo custom_url.

Blog_UrlPersonalizzata.png

Fate riferimento al modello seguente per generare percorsi URL in Twig:

{{  path('sonata_extra_blog_category', {'category': category.getSlug()}) }}
{{  path('sonata_extra_blog_tag', {'tag': tag.getSlug()}) }}
{{  path('sonata_extra_blog_article', {'article': article.getSlug()}) }}

Modelli e resa

Collegate la produzione di contenuti del vostro blog alla configurazione del vostro modello usando il Blog page type. Questo tipo di servizio di pagina è spiegato in dettaglio in Documentazione di SonataPageBundle.

Variabili Twig disponibili

Il Blog page Il servizio fornisce le seguenti variabili al tuo modello per un'integrazione senza soluzione di continuità:

Blog_TipoDiServizio.png

  • content : Il contenuto HTML del tuo blog.
  • page : Il SonataPagePage istanza di entità.
  • site : Il SonataPageSite istanza di entità.

Visualizza il contenuto del tuo blog nel tuo modello Twig come segue:

{{ content|raw }}

Per l'articolo della pagina, la categoria e i tag, il servizio metterà inoltre a disposizione dei parametri SEO:

  • ogTitle
  • ogDescription
  • ogImage : Il percorso dell'immagine sarà già calcolato. Assicurati di avere un formato immagine nominato og_image altrimenti reference sarà utilizzato. Poiché i social network hanno una larghezza/altezza massima, non è consigliabile utilizzare il reference formato.
  • seoTitle
  • seoKeyword
  • seoDescription

Nel vostro modello, potete usarlo in questo modo

{% block sonata_seo_title %}
    {% apply spaceless %}
        <title>{{ seoTitle|default('Titre par défaut') }}</title>
    {% endapply %}
{% endblock %}

{% block sonata_seo_metadatas %}
    {% apply spaceless %}
        {% if seoDescription is defined %}
            <meta name="description" content="{{ seoDescription }}">
        {% endif %}
        {% if seoKeyword is defined %}
            <meta name="keywords" content="{{ seoKeyword }}">
        {% endif %}
    {% endapply %}
{% endblock %}

{% block app_og_metadatas %}
    {% apply spaceless %}
        {% if ogTitle is defined %}
            <meta property="og:title" content="{{ ogTitle }}">
        {% endif %}
        {% if ogDescription is defined %}
            <meta property="og:description" content="{{ ogDescription }}">
        {% endif %}
        {% if ogImage is  defined %}
            <meta property="og:image" content="{{ absolute_url(ogImage) }}">
        {% endif %}
        <meta property="og:type" content="article">
    {% endapply %}
{% endblock %}

e nel vostro modello di base

    {% block sonata_seo_title %}
        {{ sonata_seo_title() }}
    {% endblock %}
    {% block sonata_seo_metadatas %}
        {{ sonata_seo_metadatas() }}
    {% endblock %}
    {% block app_og_metadatas %}
        {{ app_og_metadatas() }}
    {% endblock %}

L'entità Categoria e Etichetta dovrebbe avere i campi di riferimento

  • App\Entyty\SonataClassificationCategory.php :
<?php
namespace App\Entity;

use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Sonata\ClassificationBundle\Entity\BaseCategory;
use Partitech\SonataExtra\Traits\EntityTranslationTrait;
use Partitech\SonataExtra\Contract\MediaInterface;

#[ORM\Entity]
#[ORM\Table(name: 'classification__category')]
class SonataClassificationCategory extends BaseCategory
{
    use EntityTranslationTrait;
    #[ORM\Id]
    #[ORM\Column(type: Types::INTEGER)]
    #[ORM\GeneratedValue]
    protected ?int $id = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    #[ORM\ManyToOne(targetEntity: MediaInterface::class, cascade: ["persist"])]
    #[ORM\JoinColumn(name: "featured_image__media_id", referencedColumnName: "id", nullable: true, onDelete: "SET NULL")]
    private $featured_image = null;


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

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

    #[ORM\Column(type: 'text', nullable: true)]
    private ?string $seo_description = null;

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

    #[ORM\Column(type: 'text', nullable: true)]
    private ?string $seo_og_description = null;

    #[ORM\ManyToOne(targetEntity: MediaInterface::class, cascade: ["persist"])]
    #[ORM\JoinColumn(name: "seo_og_image__media_id", referencedColumnName: "id", nullable: true, onDelete: "SET NULL")]
    private $seo_og_image = null;

    public function getFeaturedImage()
    {
        return $this->featured_image;
    }

    public function setFeaturedImage($featured_image): self
    {
        $this->featured_image = $featured_image;

        return $this;
    }

    public function getSeoTitle(): ?string {
        return $this->seo_title;
    }

    public function setSeoTitle(?string $seo_title): self {
        $this->seo_title = $seo_title;
        return $this;
    }

    public function getSeoKeywords(): ?string {
        return $this->seo_keywords;
    }

    public function setSeoKeywords(?string $seo_keywords): self {
        $this->seo_keywords = $seo_keywords;
        return $this;
    }

    public function getSeoDescription(): ?string {
        return $this->seo_description;
    }

    public function setSeoDescription(?string $seo_description): self {
        $this->seo_description = $seo_description;
        return $this;
    }

    public function getSeoOgTitle(): ?string {
        return $this->seo_og_title;
    }

    public function setSeoOgTitle(?string $seo_og_title): self {
        $this->seo_og_title = $seo_og_title;
        return $this;
    }

    public function getSeoOgDescription(): ?string {
        return $this->seo_og_description;
    }

    public function setSeoOgDescription(?string $seo_og_description): self {
        $this->seo_og_description = $seo_og_description;
        return $this;
    }

    public function getSeoOgImage() {
        return $this->seo_og_image;
    }

    public function setSeoOgImage($seo_og_image): self {
        $this->seo_og_image = $seo_og_image;
        return $this;
    }
}
  • App\Entyty\SonataClassificationTag :
<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\DBAL\Types\Types;
use App\Repository\SonataClassificationTagRepository;
use Sonata\ClassificationBundle\Entity\BaseTag;
use Partitech\SonataExtra\Traits\EntityTranslationTrait;
use Partitech\SonataExtra\Contract\MediaInterface;

#[ORM\Entity(repositoryClass: SonataClassificationTagRepository::class)]
#[ORM\Table(name: 'classification__tag')]
#[ORM\HasLifecycleCallbacks]

class SonataClassificationTag extends BaseTag
{
    use EntityTranslationTrait;

    #[ORM\Id]
    #[ORM\Column(type: Types::INTEGER)]
    #[ORM\GeneratedValue]
    protected ?int $id = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    #[ORM\ManyToOne(targetEntity: MediaInterface::class, cascade: ["persist"])]
    #[ORM\JoinColumn(name: "featured_image__media_id", referencedColumnName: "id", nullable: true, onDelete: "SET NULL")]
    private $featured_image = null;


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

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

    #[ORM\Column(type: 'text', nullable: true)]
    private ?string $seo_description = null;

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

    #[ORM\Column(type: 'text', nullable: true)]
    private ?string $seo_og_description = null;

    #[ORM\ManyToOne(targetEntity: MediaInterface::class, cascade: ["persist"])]
    #[ORM\JoinColumn(name: "seo_og_image__media_id", referencedColumnName: "id", nullable: true, onDelete: "SET NULL")]
    private $seo_og_image = null;

    public function getFeaturedImage()
    {
        return $this->featured_image;
    }

    public function setFeaturedImage($featured_image): self
    {
        $this->featured_image = $featured_image;

        return $this;
    }

    public function getSeoTitle(): ?string {
        return $this->seo_title;
    }

    public function setSeoTitle(?string $seo_title): self {
        $this->seo_title = $seo_title;
        return $this;
    }

    public function getSeoKeywords(): ?string {
        return $this->seo_keywords;
    }

    public function setSeoKeywords(?string $seo_keywords): self {
        $this->seo_keywords = $seo_keywords;
        return $this;
    }

    public function getSeoDescription(): ?string {
        return $this->seo_description;
    }

    public function setSeoDescription(?string $seo_description): self {
        $this->seo_description = $seo_description;
        return $this;
    }

    public function getSeoOgTitle(): ?string {
        return $this->seo_og_title;
    }

    public function setSeoOgTitle(?string $seo_og_title): self {
        $this->seo_og_title = $seo_og_title;
        return $this;
    }

    public function getSeoOgDescription(): ?string {
        return $this->seo_og_description;
    }

    public function setSeoOgDescription(?string $seo_og_description): self {
        $this->seo_og_description = $seo_og_description;
        return $this;
    }

    public function getSeoOgImage() {
        return $this->seo_og_image;
    }

    public function setSeoOgImage($seo_og_image): self {
        $this->seo_og_image = $seo_og_image;
        return $this;
    }
}

Adattare l’esempio alla versione installata

Gli esempi Symfony e Sonata rimangono legati alle versioni indicate nell’articolo. Symfony 4.x e Symfony 6.2 non sono più supportati: per un progetto attuale, utilizzate un ramo mantenuto e la documentazione corrispondente esattamente alle vostre dipendenze.

php bin/console about
composer show symfony/framework-bundle sonata-project/admin-bundle

Prima di riprendere il codice, controllate le firme, i servizi, le rotte e i template interessati. Aggiungete poi un test funzionale che copra le autorizzazioni, il codice HTTP e il risultato visibile.

Riferimento : versioni di Symfony supportate.

Condividi questo articolo