[Symfony2][DoctrineExtension] Créer des slugs pour les caractéres non latin (Arabe particulièrement).

Le comportement Sluggable de la bibliothèque Doctrine extensions permet de créer facilement des URLs SEO-Friendly.
La mise en place du bundle est facile et ne nécessite pas beaucoup de configuration.

Dans le cas des url non-latin tel que l’arabe, le chinois, ou le japonais, le behavior Sluggable translittère les mots en latin, par exemple le mot « إقتصاد » sera translittéré en « qtsd » ce qui n’a aucun sens.

Dans cet article, nous allons voir comment installer et configurer le Bundle StofDoctrineExtensions pour bien créer des slugs pour les langues non-latin.

Installation du StofDoctrineExtensionsBundle

Le bundle StofDoctrineExtensionsBundle intègre la bibliothèque DoctrineExtensions .
L’installation se fait à travers le gestionnaire des dépendances composer :

composer require "doctrine/doctrine-fixtures-bundle:dev-master"
composer require "stof/doctrine-extensions-bundle:dev-master"

Par la suite, nous activons le bundle dans le fichier AppKernel.php

// app/AppKernel.php
// ...

public function registerBundles()
{
    $bundles = array(
        // ...
        new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),
    );

    // ...
}

À la fin, nous ajoutons la configuration de bundle à la fin de notre fichier config.yml :

stof_doctrine_extensions:
    default_locale: en_US
    orm:
        default:
            sluggable:   true

Utilisation du comportement Sluggable

Dans notre exemple, nous allons créer un slug pour la propriété « name » de notre entity Post.

// src/Nm/CoreBundle/Entity/Post.php
// ...

use Gedmo\Mapping\Annotation as Gedmo;
// ...

class Post
{
    // ...

    /**
     * @Gedmo\Slug(fields={"name"}, updatable=false)
     * @ORM\Column(length=255, unique=true)
     */
    protected $slug;
}

Ce code permet de créer automatiquement des slugs sur la propriété « name ».
En ajoutant « updatable=false », cela indiquera que le slug ne sera jamais mis à jour une fois créée, même si nous changons la valeur de « name ».
C’est une bonne idée parce que le slug sera utilisé dans l’URL de l’événement, que nous ne voulons pas changer.

Par la suite nous mettons à jour notre base de données :

php app/console  doctrine:schema:update --force

Si vous avez des anciennes données vous allez vous trouver avec une erreur de contrainte d’intégrité, il faut donc vider la table de ces données et relancer la mise à jour, pour cela on peut supprimer toutes les tables et les recréer à nouveau à travers la console de symfony pour contourner ce problème :

php app/console doctrine:schema:drop
php app/console doctrine:schema:create

À ce niveau, l’installation et la configuration du comportement sluggable sont terminées. Vous pouvez faire les tests et voir que tout est fonctionnel.

Adaptation du comportement Sluggable pour les url non-latin

Comme je vous ai dit au début, le but de cet article est d’adapter ce behavior pour créer des slugs pour les langues non-latin.

Beaucoup de CMS, tel-que Drupal et WordPress possède un système de slugify puissant.
Pour notre cas, nous allons utiliser les fonctions utf8_uri_encode et slugify de wordpress.

Nous commencons par créer un service personnalisé et par la suite nous l’activons pour surcharger celui par défaut de DoctrineExtensions.

Maintenant vous pouvez slugify votre url facilement en gardant votre langue par défaut. Dans le cas de l’Arabe le mot « مال و أعمال » sera « مال-و-أعمال ».

Publicités

12 réflexions sur “[Symfony2][DoctrineExtension] Créer des slugs pour les caractéres non latin (Arabe particulièrement).

  1. Hi Rmed19,

    I am exactly in that case! I would like to test your service, but i have a services.yml… Is it possible for you to adapt it from xml to yml? I’m not very good in that.

    Sorry for my english 🙂

    Cheers,
    David

      • Merci énormément Mohammed pour le code en yml, ton code fonctionne parfaitement, c’est magique quand tu vois apparaître ton premier slug chinois 😀 !
        Je n’ai pas eu à galérer car je suis très vite tombé sur ta page quand j’ai découvert ce problème, sinon je sens que le mandarin n’aurait plus figuré à la liste des langues de mon site.
        Encore une fois 10.000 merci !!!
        Tu as du y passer du temps ?

    • Salut David,
      Tu peux essayer avec cette configuration :
      stof_doctrine_extensions.listener.sluggable :
      class: « %stof_doctrine_extensions.listener.sluggable.class% »
      public: false
      tags:
      – { name: doctrine.event_subscriber, connection: default }
      calls:
      – [ setAnnotationReader, [ @annotation_reader ] ]
      – [ setTransliterator, [ Nm\CoreBundle\Service\Slugger, transliterate] ]
      – [ setUrlizer, [ Nm\CoreBundle\Service\Slugger, urlize ] ]

      • Salut Mohammed,
        MERCI pour ta réponse super rapide :). Je viens de mettre ta config en place et j’ai une erreur : « ParseException: Unable to parse at line 54 (near « – [ setAnnotationReader, [ @annotation_reader ] ] ») ». Je n’ai pas de tabulation, j’ai fait quelques recherches sur la doc de symfony pour voir comment fonctionnaientt les calls, ils ont l’air d’être bon dans ta config… Une idée ?

  2. Bonsoir,

    Votre script fonctionne avec symfony2 et orm mais lorsque j’utilise le meme code avec un autre projet sous symfony 3 avec odm ca ne marche pas, le slug reste vide quelques soit la langue. Pouvez-vous m’aider SVP ?

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s