Symfony2 Sluggable множественные разделители

Используя поведение Gedmo Sluggable в Symfony2, мне нужно знать, есть способ разрешить как косую черту (/), так и тире (-) в качестве разделителей слов. Другими словами, один конкретный разделитель, как обычно, но игнорируется другой специальный символ. Я хочу сделать что-то вроде этого в качестве пули:

products/some-product

Это позволяет мне использовать слаги в URL-адресе, которые классифицируются с помощью косой черты, и разделяют пробелы с помощью тире. Но, например, если разделителем является «/», «-» также будет заменен, а не оставлен.

Я просмотрел соответствующий код класса Sluggable (Urlizer) и вижу много регулярных выражений, но я не уверен, где я должен переопределить, чтобы косая черта и/или тире НЕ заменялись вместе со всем остальным.


person metaphist    schedule 05.07.2012    source источник


Ответы (1)


Оказывается, вы можете добиться этого, создав свой собственный класс, который расширяет Urlizer, а затем установите его в качестве вызываемого для слушателя вместо класса Gedmo.

При использовании расширений доктрины STOF слабый прослушиватель создается как служба, но он устанавливается как частный, поэтому вы не можете получить к нему доступ в обычном режиме. Поэтому вы должны сначала создать псевдоним для этого слушателя в своей собственной конфигурации:

services:

    sluggable.listener:
        alias: stof_doctrine_extensions.listener.sluggable

Затем вы должны создать свой класс. Существует установщик с именем setTransliterator(), который вы можете использовать для вызова собственного транслитератора, который затем можно использовать для ввода того, что вам нужно для изменения процесса слаггинга. Функция postProccessText() — это то, что вы действительно хотите изменить, функция transliterate() — это то, что можно вызвать:

namespace My\Bundle\Util;

use Gedmo\Sluggable\Util\Urlizer as BaseUrlizer;

class Urlizer extends BaseUrlizer
{
    public static function transliterate($text, $separator = '-')
    {
        // copy the code from the parent here
    }

    private static function postProcessText($text, $separator)
    {
        // copy code from parent, but modify the following part:

        $text = strtolower(preg_replace('/[^A-Z^a-z^0-9^\/]+/', $separator,
                           preg_replace('/([a-z\d])([A-Z])/', '\1_\2',
                           preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1_\2',
                           preg_replace('/::/', '/', $text)))));
    }
}

Регулярные выражения postProcessText() — это то, что вы хотите изменить по своему вкусу. После этого вы должны сделать свою функцию вызываемой прямо перед сохранением, и все готово:

// custom transliterator
$listener = $this->get('sluggable.listener');
$listener->setTransliterator(array('My\Bundle\Util\Urlizer', 'transliterate'));
$em->flush();
person metaphist    schedule 10.07.2012