[Решение] Формируем красивые адреса для иерархии терминов
Прислано: 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 как раз служит для определения алиаса термина.
Также, как видно из скриншота, модуль отключает возможность выбора нескольких родителей для термина.
Модуль 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 голосов
- Stutzer's blog
- Для комментирования войдите или зарегистрируйтесь
Добавьте в опрос еще один пункт "Интересный модуль. Возьму на заметку"
Я бы выбрал именно этот пункт. :)
Ваш модуль использует хук hook_term_path?
- Для комментирования войдите или зарегистрируйтесь
Была мысль использовать его, но для большей гибкости решил создать несколько новых Token-шаблонов и переложить генерацию алиасов на PathAuto.
- Для комментирования войдите или зарегистрируйтесь
Если надумаете выкладывать модуль на drupal.org, советую задуматься над переводом (локализацией) своих alias-ов.
Для кириллицы это бессмысленно, но для тех, чей язык основан на латинском алфавите это определено будет полезным функционалом при построении многоязычных сайтов.
- Для комментирования войдите или зарегистрируйтесь
Не совсем понял идею. Адреса то вроде как по-английски все задают
- Для комментирования войдите или зарегистрируйтесь
К примеру, сайт на английском и немецком. Можно ли делать ссылки на обоих языках?
Всегда можно сделать два словаря, но если они будут очень большие по размерам, то может получится двойная нагрузка по производительности.
Такая ситуация имеет право на жизнь?
- Для комментирования войдите или зарегистрируйтесь
Понял вашу мысль. Выкладывать на org собираюсь, но сначала базовый функционал до ума доведу.
- Для комментирования войдите или зарегистрируйтесь
Коллеги, у меня возник вопрос.
Задача — предоставить Token-шаблон для материалов (node), чтобы формировать пути до нод (типа docs/laws/accepted/doc1.html).
Дело в том, что к материалу могут быть привязаны несколько словарей, а для составления пути используется определенный.
Здесь я вижу два решения:
1. При создании/редактировании типов материалов (content types) добавить набор радиобатонов для выбора словаря, который будет использоваться для составления алисов.
2. Брать самый первый термин из массива $node['taxonomy']. Для того, чтобы словарь был первым, ему нужно присвоить меньший вес на странице admin/content/taxonomy.
Как думаете, какой способ предпочтительнее? Не возникнет ли при втором способе неожиданных глюков?
- Для комментирования войдите или зарегистрируйтесь
Я бы пошел немного другим путем.
В закладке настроек Pathauto нужно выводить список алиасов для каждого из словарей, которые использует данный тип материалов. К примеру, в ноде используется два словаря, значит должно отображаться две пары term-handy-alias и term-handy-alias-path.
Человек, который будет настраивать pathauto, сам определит какой из словарей ему нужно использовать в пути к ноде.
При этом он(а) может сделать так, чтобы в пути в определенной очередности находились термины из разных словарей.
Но при этом я не совсем понимаю, как в этом случае может повести себя шаблон alias-path. Это скорее вопрос к Вам. :-)
Но у меня возник другой вопрос. Как будет поступать Ваш модуль, если в типе материалов будет позволено выбирать несколько терминов из одного словаря?
- Для комментирования войдите или зарегистрируйтесь
Интересный способ, но слишком уж мудреный и излишний на мой взгляд. По-моему это довольно редкий случай, чтобы в пути могло понадобится несколько терминов из разных словарей.
Но у меня возник другой вопрос. Как будет поступать Ваш модуль, если в типе материалов будет позволено выбирать несколько терминов из одного словаря?
В форме создания словаря есть галочка «Enable Handy alias for this vocabulary». Если она выбрана, опция «Множественный выбор» и «Теги» становятся disable. Это видно на первом скриншоте в самом посте.
Также, если поставить галочку «Enable Handy alias for this vocabulary», словарь не позволяет создавать термин с двумя и более родителями (рис. 2)
- Для комментирования войдите или зарегистрируйтесь
Интересный способ, но слишком уж мудреный и излишний на мой взгляд.
Мой способ был взят из логики самого pathauto.
Просто я в связку type-alias-path добавил новый пункт type-vocabulary-alias-path. Получилось то, что получилось. ИМХО это правильный путь.
Собственно Вы спросили, я предложил. Вам решать.
- Для комментирования войдите или зарегистрируйтесь
Модуль так и не появился???
- Для комментирования войдите или зарегистрируйтесь
Разработка модуля временно заморожена в связи с острой нехваткой времени. В октябре надеюсь выпустить первую версию.
Раз есть инетерс к модулу, обязательно доделаю ASAP.
- Для комментирования войдите или зарегистрируйтесь
Дело в том, что к материалу могут быть привязаны несколько словарей, а для составления пути используется определенный.
Я писал токены для формирования путей из терминов таксономии. Для решения проблемы нескольких словарей, привязанных к материалу, сделал токен 'term-vid?-synonym?', где 'vid?' - номер словаря (vid1,vid2,...), а 'synonym?' - номер синонима (аналогично) - в синонимах я хранил альтернативные пути.
Модуль - 15 строчек, без использования своих таблиц в БД. Но передо мной не стояла задача формирования иерархических путей, хотя, думаю, решить можно аналогично.
- Для комментирования войдите или зарегистрируйтесь
Разработка модуля временно заморожена в связи с острой нехваткой времени. В октябре надеюсь выпустить первую версию.
Судя по всему свободного времени так и не появилось?
Жаль.... модуль обещал быть интересным и полезным...
- Для комментирования войдите или зарегистрируйтесь
Стали бы вы пользоваться модулем Handy alias
Уже пользуюсь-)
- Для комментирования войдите или зарегистрируйтесь
Это вы конечно хорошо привели пример, но чаще всего все обстоит несколько сложнее, а именно:
Например:
База товара
|— Автотранспорт
| |— Новые
| |— Б/У
|— Недвижимость
| |- У моря
| | |— Новая
| | |— Вторичка
| |- В горах
| | |— Новая
| | |— Вторичка
| |- СПА
| | |— Новая
| | |— Вторичка
База регионов и нас. пунктов
|- Расположение
| |- Область
| |- Город
Соответственно мы имеем два, а то и более словарей таксономии для одного объекта
и объект должен принадлежать как первому словарю так и второму, а иногда может принадлежать сразу нескольким подразделам в одном словаре.
Т.е. квартира может быть и у моря и СПА, быть новой. И находится в определенной области и городе.
и нужны ссылки вида:
хттп://регион/Моск.обл/Ногинск
хттп://регион/Моск.обл/Москва
хттп://квартиры/СПА/Новые
хттп://квартиры/У_моря/Новые
а еще лучше:
хттп://квартиры/У_моря/Новые/Моск.обл/Москва
хттп://квартиры/У_моря/Моск.обл/Москва
хттп://квартиры/У_моря/Новые/Моск.обл
и этот объект должен попадать во все списки, а следовательно нужно разрешать в словарях "множественный выбор".
И тут натыкаемся на грабли, что ваш модуль не может сделать алиасы при множественном выборе.
- Для комментирования войдите или зарегистрируйтесь
Интересный способ, но слишком уж мудреный и излишний на мой взгляд. По-моему это довольно редкий случай, чтобы в пути могло понадобится несколько терминов из разных словарей.
Вижу уже обсуждалось это =)
Смею вас заверить это довольно не редкий случай, а ОЧЕНЬ частый.
Еще ни разу не попадался столь легкий проект как описываете вы, всегда необходим множественный выбор, для тех или иных категорий.
- Для комментирования войдите или зарегистрируйтесь
ок, давайте попробуем разобраться.
что делает модуль? модуль позволяет автоматизировать создание алиасов для
1. Непосредственно нод (материалов)
2. Для листингов нод (терминов)
Всем нам известно, что дублирование контента на сайте - это плохо, поисковики за это вас не полюбят. Т.е. сайт, где страница одной и той же ноды доступна по двум разным адресам - непраильный сайт. Для этого, кстати, был изобретен модуль Глобал Редирект. В случае с множественным выбором нам придется генерить или всевозможные адреса или ...(впишите, как вы себе это представляете). Это что касается адресов для нод
Теперь по адресам словарей. В вашем примере на мой взгляд словарь составлен неграмотно. Очевидно, логичнее создать несколько словарей, чем лепить все в один.
"возраст" : [новый, бу]
"расположение" : [море, горы, пустыня]
и т.д.
Поскольку в таком случае стратегия составления адресов усложняется, думаю, следует использовать какие-то иные подходы, нежели модуль handyalias
- Для комментирования войдите или зарегистрируйтесь
Очевидно, логичнее создать несколько словарей, чем лепить все в один.
А тут другие грабли у модуля аутопас нету связи между словарями, и если объект принадлежит двум.. трем словарям, путь он может создать только используя один.
- Для комментирования войдите или зарегистрируйтесь








Комментарии