[Решение] Формируем красивые адреса для иерархии терминов

Прислано: Stutzer

сб, 25/07/2009 - 14:22

Другие статьи по теме:

В этом посте я расскажу об одной распространенной проблеме, своих попытках её решения и о том, чем это все закончилось.

В процессе разработки лучшего сайта по психиатрии я решил создать раздел со статьями и возможностью их простой иерархической классификации. Создал тип материала «Статья» со всеми необходимыми полями, создал словарь «Категории статей», в котором создал иерархию термнов следующего вида:

Категории статей
|— Автотранспорт
|  |— Мнонографии
|  |— Автобиографии
|— Документы
|  |— Законы РФ
|  |— Приказы
|  |— Законопроекты
|     |— Принятые
|     |— На рассмотрении
|— Публикации
   |— Журнальные
   |— Эссе

Разумеется мне понадобилось соответствующее меню, которое я смог получить аж двумя способами: при помощи модуля taxonomy_menu и при помощи модуля edit_term. Однако в силу своего перфекционизма мне нужны были красивые URL для категорий. И тут начались проблемы.

Модуль PathAuto с помощью шаблона [catpath-raw] позволял создавать уродливые алиасы типа knigi/monografii.

Просмотрев весь каталог модулей я не нашел ничего, что имело хоть какое-то отношение к таксономии, терминам и алиасам, кроме двух уже упомянутых выше модулей.

Модуль term_edit позволял решить эту проблему путем определения для каждого термина полного произвольного алиаса (к примеру, для термина «Монографии» мы можем задать articles/books/monography).
На мой взгляд, максимум, для чего годится такой подход, — это для плоских одноуровневых списков (не иерархичных). В противном случае, при приличном количестве терминов и разветвленной иерархической структуре это порождает существенную избыточность и обещает большой объем работы в случае реорганизации словаря или желании изменить алиасы терминов, находящихся ближе к вершине иерархии.

Модуль taxonomy_menu комплектуется двумя дополнительными модулями, имеющими, судя по названию, отношение к алиасам терминов: Taxonomy Menu Custom Path и Taxonomy Menu Hierarchy. Первый предлагает создать хитрое представление (views) с аргументами и тогда... Я, честно говоря, так и не понял, что тогда. А что делает второй я и вовсе не уловил. Переключение в режим «Hierarchy» не приводило ровным счетом ни к чему. Возможно, я поленился разобраться в сути вопроса.

Итак решено было написать модуль, решающий следующую задачу:
Формирование пути для терминов на основе алиасов терминов. Поясню.
Возмем термин «Принятые»:

Документы
  |— Законопроекты
     |— Принятые

Максимум что, мы можем получить — это dokumenty/zakonoproekty/prinyatie, в то время, когда нам требуется docs/law/accepted.
При этом каждая часть этого пути должна задаваться при редактировании соответствующего термина.

Собственно, этот функционал и реализует модуль «Handy alias», который я написал и сейчас активно тестирую.

Приведу несколько скриншотов для наглядности:


Форма создания/редактирования нового словаря

Галочка Enable handy alias for this dictionary включает для словаря возможность создания алиасов для терминов, а кроме того отключает возможность создать словарь с множественным выбором терминов (тегов) и выбора нескольких родителей для термина. Это необходимо для работы модуля с точки зрения его логики.


Форма создания/редактирования нового термина

Поле Term alias как раз служит для определения алиаса термина.
Также, как видно из скриншота, модуль отключает возможность выбора нескольких родителей для термина.


Новые Token-шаблоны в форме модуля PathAuto

Модуль Handy Alias создает два Token-шаблона [term-handy-alias] и [term-handy-alias-path], которые позволяют решить нашу задачу.
[term-handy-alias] возвращает непосредственно алиас термина.
[term-handy-alias-path] возвращает цепочку алисов, разделенных слэшами, соответствующую родительским терминам.

Сейчас работаю над созданием Token-шаблонов для нод.

Хотелось бы услышать ваше мнение об актуальности подобного модуля и ваши пожелания относительно функционала.

Attached poll "Стали бы вы пользоваться модулем Handy alias".
Register or login to poll
Results:
Да, это то, чего мне так не хватало!: 5 голосов
Интересный модуль. Возьму на заметку: 7 голосов
Нет, спасибо. Я знаю, как решить эту проблему проще.: 0 голосов

Комментарии


Настройки просмотра комментариев

Выберите нужный метод показа комментариев и нажмите "Применить"
Опубликовано dimedrol в сб, 25/07/2009 - 16:27.

Добавьте в опрос еще один пункт "Интересный модуль. Возьму на заметку"
Я бы выбрал именно этот пункт. :)

Ваш модуль использует хук hook_term_path?


Опубликовано Stutzer в сб, 25/07/2009 - 16:35.

Была мысль использовать его, но для большей гибкости решил создать несколько новых Token-шаблонов и переложить генерацию алиасов на PathAuto.


Опубликовано dimedrol в сб, 25/07/2009 - 19:13.

Если надумаете выкладывать модуль на drupal.org, советую задуматься над переводом (локализацией) своих alias-ов.
Для кириллицы это бессмысленно, но для тех, чей язык основан на латинском алфавите это определено будет полезным функционалом при построении многоязычных сайтов.


Опубликовано Stutzer в вс, 26/07/2009 - 06:48.

Не совсем понял идею. Адреса то вроде как по-английски все задают


Опубликовано dimedrol в вс, 26/07/2009 - 07:41.

К примеру, сайт на английском и немецком. Можно ли делать ссылки на обоих языках?
Всегда можно сделать два словаря, но если они будут очень большие по размерам, то может получится двойная нагрузка по производительности.

Такая ситуация имеет право на жизнь?


Опубликовано Stutzer в вс, 26/07/2009 - 08:32.

Понял вашу мысль. Выкладывать на org собираюсь, но сначала базовый функционал до ума доведу.


Опубликовано Stutzer в вс, 26/07/2009 - 10:08.

Коллеги, у меня возник вопрос.

Задача — предоставить Token-шаблон для материалов (node), чтобы формировать пути до нод (типа docs/laws/accepted/doc1.html).
Дело в том, что к материалу могут быть привязаны несколько словарей, а для составления пути используется определенный.
Здесь я вижу два решения:
1. При создании/редактировании типов материалов (content types) добавить набор радиобатонов для выбора словаря, который будет использоваться для составления алисов.
2. Брать самый первый термин из массива $node['taxonomy']. Для того, чтобы словарь был первым, ему нужно присвоить меньший вес на странице admin/content/taxonomy.

Как думаете, какой способ предпочтительнее? Не возникнет ли при втором способе неожиданных глюков?


Опубликовано dimedrol в вс, 26/07/2009 - 14:16.

Я бы пошел немного другим путем.

В закладке настроек Pathauto нужно выводить список алиасов для каждого из словарей, которые использует данный тип материалов. К примеру, в ноде используется два словаря, значит должно отображаться две пары term-handy-alias и term-handy-alias-path.
Человек, который будет настраивать pathauto, сам определит какой из словарей ему нужно использовать в пути к ноде.
При этом он(а) может сделать так, чтобы в пути в определенной очередности находились термины из разных словарей.
Но при этом я не совсем понимаю, как в этом случае может повести себя шаблон alias-path. Это скорее вопрос к Вам. :-)

Но у меня возник другой вопрос. Как будет поступать Ваш модуль, если в типе материалов будет позволено выбирать несколько терминов из одного словаря?


Опубликовано Stutzer в вс, 26/07/2009 - 18:05.

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

dimedrol написал(а):

Но у меня возник другой вопрос. Как будет поступать Ваш модуль, если в типе материалов будет позволено выбирать несколько терминов из одного словаря?

В форме создания словаря есть галочка «Enable Handy alias for this vocabulary». Если она выбрана, опция «Множественный выбор» и «Теги» становятся disable. Это видно на первом скриншоте в самом посте.
Также, если поставить галочку «Enable Handy alias for this vocabulary», словарь не позволяет создавать термин с двумя и более родителями (рис. 2)


Опубликовано dimedrol в вс, 26/07/2009 - 20:37.

"Stutzer" написал(а):

Интересный способ, но слишком уж мудреный и излишний на мой взгляд.

Мой способ был взят из логики самого pathauto.
Просто я в связку type-alias-path добавил новый пункт type-vocabulary-alias-path. Получилось то, что получилось. ИМХО это правильный путь.

Собственно Вы спросили, я предложил. Вам решать.


Опубликовано Bios в пн, 14/09/2009 - 19:30.

Модуль так и не появился???


Опубликовано Stutzer в вт, 22/09/2009 - 00:47.

Разработка модуля временно заморожена в связи с острой нехваткой времени. В октябре надеюсь выпустить первую версию.
Раз есть инетерс к модулу, обязательно доделаю ASAP.


Опубликовано Dan в сб, 03/10/2009 - 18:12.

"Stutzer" написал(а):

Дело в том, что к материалу могут быть привязаны несколько словарей, а для составления пути используется определенный.

Я писал токены для формирования путей из терминов таксономии. Для решения проблемы нескольких словарей, привязанных к материалу, сделал токен 'term-vid?-synonym?', где 'vid?' - номер словаря (vid1,vid2,...), а 'synonym?' - номер синонима (аналогично) - в синонимах я хранил альтернативные пути.
Модуль - 15 строчек, без использования своих таблиц в БД. Но передо мной не стояла задача формирования иерархических путей, хотя, думаю, решить можно аналогично.


Опубликовано yexel в вт, 24/11/2009 - 03:07.

"Stutzer" написал(а):

Разработка модуля временно заморожена в связи с острой нехваткой времени. В октябре надеюсь выпустить первую версию.

Судя по всему свободного времени так и не появилось?
Жаль.... модуль обещал быть интересным и полезным...


Опубликовано Stan.Ezersky в сб, 20/11/2010 - 18:29.

"Stutzer" написал(а):

Стали бы вы пользоваться модулем Handy alias

Уже пользуюсь-)


Опубликовано divined в пн, 29/11/2010 - 14:37.

Это вы конечно хорошо привели пример, но чаще всего все обстоит несколько сложнее, а именно:
Например:

База товара
|— Автотранспорт
| |— Новые
| |— Б/У
|— Недвижимость
| |- У моря
| | |— Новая
| | |— Вторичка
| |- В горах
| | |— Новая
| | |— Вторичка
| |- СПА
| | |— Новая
| | |— Вторичка

База регионов и нас. пунктов
|- Расположение
| |- Область
| |- Город

Соответственно мы имеем два, а то и более словарей таксономии для одного объекта
и объект должен принадлежать как первому словарю так и второму, а иногда может принадлежать сразу нескольким подразделам в одном словаре.

Т.е. квартира может быть и у моря и СПА, быть новой. И находится в определенной области и городе.
и нужны ссылки вида:

хттп://регион/Моск.обл/Ногинск

хттп://регион/Моск.обл/Москва
хттп://квартиры/СПА/Новые
хттп://квартиры/У_моря/Новые

а еще лучше:
хттп://квартиры/У_моря/Новые/Моск.обл/Москва
хттп://квартиры/У_моря/Моск.обл/Москва
хттп://квартиры/У_моря/Новые/Моск.обл

и этот объект должен попадать во все списки, а следовательно нужно разрешать в словарях "множественный выбор".
И тут натыкаемся на грабли, что ваш модуль не может сделать алиасы при множественном выборе.


Опубликовано divined в пн, 29/11/2010 - 14:31.

Stutzer написал(а):

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

Вижу уже обсуждалось это =)
Смею вас заверить это довольно не редкий случай, а ОЧЕНЬ частый.
Еще ни разу не попадался столь легкий проект как описываете вы, всегда необходим множественный выбор, для тех или иных категорий.


Опубликовано Stutzer в пн, 29/11/2010 - 14:49.

ок, давайте попробуем разобраться.

что делает модуль? модуль позволяет автоматизировать создание алиасов для
1. Непосредственно нод (материалов)
2. Для листингов нод (терминов)

Всем нам известно, что дублирование контента на сайте - это плохо, поисковики за это вас не полюбят. Т.е. сайт, где страница одной и той же ноды доступна по двум разным адресам - непраильный сайт. Для этого, кстати, был изобретен модуль Глобал Редирект. В случае с множественным выбором нам придется генерить или всевозможные адреса или ...(впишите, как вы себе это представляете). Это что касается адресов для нод

Теперь по адресам словарей. В вашем примере на мой взгляд словарь составлен неграмотно. Очевидно, логичнее создать несколько словарей, чем лепить все в один.
"возраст" : [новый, бу]
"расположение" : [море, горы, пустыня]
и т.д.

Поскольку в таком случае стратегия составления адресов усложняется, думаю, следует использовать какие-то иные подходы, нежели модуль handyalias


Опубликовано divined в пн, 29/11/2010 - 14:55.

Stutzer написал(а):

Очевидно, логичнее создать несколько словарей, чем лепить все в один.

А тут другие грабли у модуля аутопас нету связи между словарями, и если объект принадлежит двум.. трем словарям, путь он может создать только используя один.


Ссылки партнёров