Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

slug not translated #276

Open
gfrancqu opened this issue Apr 6, 2015 · 10 comments
Open

slug not translated #276

gfrancqu opened this issue Apr 6, 2015 · 10 comments

Comments

@gfrancqu
Copy link

gfrancqu commented Apr 6, 2015

Hi,

I am using the stofDoctrineExtensionsBundle in order to use the slug and translatable behavior, but i'am encountering issues about the slug translation, i need my slug to be translated for each title of my entity

    /**
     * @var string
     * @Gedmo\Translatable
     * @ORM\Column(name="title", type="string", length=255,unique=true)
     * 
     */
    private $title;

    /** 
    * @Gedmo\Translatable
    * @Gedmo\Slug(fields={"title"})
    * @ORM\Column(length=255,unique=false)
    */
    private $slug;

my title is translated but the slug only use the default locale and is not translated

here is my yamel file service configuration

i put the translatableListener after the sluggableListener

services:



    # Doctrine Extension listeners to handle behaviors
    gedmo.listener.tree:
        class: Gedmo\Tree\TreeListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]

    gedmo.listener.sluggable:
        class: Gedmo\Sluggable\SluggableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default}
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]


    # KernelRequest listener
    extension.listener:
        class: A101\Bundle\AccordMetVinBundle\Listener\DoctrineExtensionListener
        calls:
            - [ setContainer, [ @service_container ] ]
        tags:
            # translatable sets locale after router processing
            - { name: kernel.event_listener, event: kernel.request, method: onLateKernelRequest }
            # loggable hooks user username if one is in security context
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

    gedmo.listener.timestampable:
        class: Gedmo\Timestampable\TimestampableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]

    gedmo.listener.sortable:
        class: Gedmo\Sortable\SortableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]

    gedmo.listener.loggable:
        class: Gedmo\Loggable\LoggableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]

    gedmo.listener.translatable:
        class: Gedmo\Translatable\TranslatableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default}
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]
            - [ setDefaultLocale, [ %locale% ] ]
            - [ setTranslationFallback, [ false ] ]

in the documentation i can find this block

<?php
$evm = new \Doctrine\Common\EventManager();
$sluggableListener = new \Gedmo\Sluggable\SluggableListener();
$evm->addEventSubscriber($sluggableListener);
$translatableListener = new \Gedmo\Translatable\TranslationListener();
$translatableListener->setTranslatableLocale('en_us');
$evm->addEventSubscriber($translatableListener);
// now this event manager should be passed to entity manager constructor

but i clearly have no idea where to put this code, the translatable listener isn't already added to the event manager through the doctrine-extensions.yml file ?

I am using a personnalAbstractTranslation

/**
 * @ORM\Entity
 * @ORM\Table(name="plat_translations",
 *   uniqueConstraints={@ORM\UniqueConstraint(name="lookup_unique_idx", columns={
 *     "locale", "object_id", "field"
 *   })}
 * )
 */
class PlatTranslation extends AbstractPersonalTranslation
{
    /**
     * @ORM\ManyToOne(targetEntity="Plat", inversedBy="translations")
     * @ORM\JoinColumn(name="object_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $object;

}
@gfrancqu
Copy link
Author

anyone have an idea ?

@thomas2411
Copy link

I have the same problem. Although I didn't change any listeners cause as I see in #232 it should work right away. I have just added the code in YML:

    fields:
        slug:
            type: string
            length: 255
            column: 'mslug'
            gedmo:
                translatable: {}
                slug:
                  fields:
                    - title

As I understand it should work, but it doesn't. I have 4 translatable fields, all of them are translated except slug. Any idea what should I do?

@gfrancqu
Copy link
Author

You can change to another translation bundle?

@thomas2411
Copy link

Which one?

@gfrancqu
Copy link
Author

gfrancqu commented Dec 1, 2015

I use the a2lixI18nDoctrine bundle, i find it easier to use, but you'll have to create your own function in order to create a slug, with a @PrePersist annotation it is very simple

@FabianSchmick
Copy link

FabianSchmick commented Jan 2, 2018

I have searched and tried a while and found a solution for me:

Entity: the slug field gets generated from the name field

use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\Translatable\Translatable;

/**
 * @var string
 *
 * @Gedmo\Translatable
 * @ORM\Column(name="name", type="string", length=150, unique=true)
 */
private $name;

/**
 * @Gedmo\Translatable
 * @Gedmo\Slug(fields={"name"}, updatable=true)
 * @ORM\Column(type="string", unique=true)
 */
private $slug;

config.yml: here you have to set persist_default_translation: true doctrine-extensions/DoctrineExtensions#542 (comment)

parameters:
    locale: en

doctrine:
    orm:
        auto_generate_proxy_classes: '%kernel.debug%'
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true
        mappings:
            gedmo_translatable:
                type: annotation
                prefix: Gedmo\Translatable\Entity
                dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"
                alias: GedmoTranslatable # (optional) it will default to the name set for the mapping
                is_bundle: false
            gedmo_translator:
                type: annotation
                prefix: Gedmo\Translator\Entity
                dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translator/Entity"
                alias: GedmoTranslator # (optional) it will default to the name set for the mapping
                is_bundle: false

stof_doctrine_extensions:
    default_locale: '%locale%'
    translation_fallback: true
    persist_default_translation: true    # I think this does the trick
    orm:
        default:
            sluggable: true
            translatable: true

DefaultController: use ParamConverter for calling a query which returns correct entity for current locale

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;

/**
 * @Route("/entry/{slug}", name="entry_detail")
 * @ParamConverter("entry", class="AppBundle:Entry", options={"repository_method" = "findOneByCriteria"})
 */
public function entryDetailAction(Request $request, Entry $entry)
{
    return $this->render('frontend/entry.html.twig', [
        'entry' => $entry,
    ]);
}

Entity Repository: with the query method to return entity

/**
 * Find an entry by criteria
 * Need this special function, because of translatable
 * https://github.com/stof/StofDoctrineExtensionsBundle/issues/232
 *
 * @param $params
 * @return mixed
 */
public function findOneByCriteria(array $params)
{
    $query = $this->createQueryBuilder('e');
    $i = 0;
    foreach ($params as $column => $value) {
        if ($i < 1) {
            $query->where("e.$column = :$column");
        } else {
            $query->andWhere("e.$column = :$column");
        }
        $query->setParameter($column, $value);
        $i++;
    }
    $query = $query->getQuery();
    $query->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker');
    return $query->getOneOrNullResult();
}

I hope this example helps someone.

@kconde2
Copy link

kconde2 commented Sep 20, 2022

Still not working today

@benjamin-hubert
Copy link

benjamin-hubert commented Aug 22, 2023

I'm a bit confused by this problem.
I managed to translate the slugs automatically, without any special attention, on a Symfony 4 and this bundle in version 1.3.

However, I'm now trying to implement it on Symfony 6, without success.

The problem seems to be that the SluggableListener doesn't detect any change in the translated field on which the slug depends.

Example:

    #[ORM\Column(length: 255)]
    #[Assert\NotBlank()]
    #[Assert\Length(max: 255)]
    #[Gedmo\Translatable()]
    private ?string $name = null;

    #[Gedmo\Translatable()]
    #[Gedmo\Slug(fields: ['name'], updatable: true, unique: true, dateFormat: '')]
    #[ORM\Column(length: 255)]
    private ?string $slug;

Here, slug won't be translated even if we translate the "name" field because SluggableListener doesn't see it in its changeset fetching (generateSlug function).

$changeSet = $ea->getObjectChangeSet($uow, $object);

For the moment, I'm proposing a not-so-pretty hack:

#[Gedmo\Translatable()]
#[Gedmo\Slug(fields: ['name', 'updatedAt'], updatable: true, unique: true, dateFormat: '')]
#[ORM\Column(length: 255)]
private ?string $slug;

In a entity using Timestampable, it will translate and update the slug..

@mrcmorales
Copy link

hi,

Has anyone managed to get it working with symfony 6?

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants