Регистрация
Регистрируясь, вы подтверждаете свое согласие с соглашением об использовании персональных данных.
Восстановление пароля

Формирование ЧПУ ссылок, версия 4.7

18.02.2015, 13:47
xanafi9320
ИП Журавский

Зарегистрирован:
2014-12-15
Сообщений: 4

Здравствуйте.

Имеется следующее. Сайт на версии NetCat 4.7. Есть раздел Catalog, в нём дочерний раздел Items со стандартным компонентом Магазин.Товар с именем tovar в этом разделе и все товары (объекты) сайта находятся именно в данном разделе Items. Url для этих товаров формируется соответственно из ключевых слов родительских разделов и названия компонента, получается /catalog/items/tovar_12345.html. Навигация по некоему подобию разных категорий и видов товаров происходит ссылками вида /catalog/filter/?srchPat[3]=2, т.е. попусту фильтрацией из этого единственного раздела со всеми товарами.
Теперь стоит задача сделать ЧПУ при формирование url для товара вида /назначение-товара/производитель/название-коллекции/товар_123435.html, т.е. формируется на основании значения некоторых полей товара.

Первое, что пришло в голову, создать структуру, подобную требующемуся формату ЧПУ, например, Назначение -> Производитель и т.д. c соответствующими ключевыми словами, чтобы формировались "правильные" url, и раскидать по разделам все объекты. В каждом разделе, ессно, должен быть такой же компонент товар, а для промежуточных страниц, например, /назначение-товара/производитель/, компоненты Товар с использованием в шаблоне отображения списка объектов вызова функции вида:
".s_list_class(90, 48, '&srchPat[4]=1&page='.$_GET['page']).", вывод списка товаров и всё. Это работает.

Хотя товаров не очень много (чуть менее 1к), но достаточно много вариантов производителей, коллекций товаров, видов назначений, условно говоря, много маленьких коробочек разной формы и цветов. Не хотелось бы объекты вручную перетаскивать по разделам, да ещё не разобрался с выборкой товаров со всех дочерних разделов для тех же промежуточных страниц. Хотя без перетаскивания по структуре, как я понимаю не обойтись, иначе не будет ЧПУ.

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

С NetCat знаком поверхностно, опыт на php есть. Где-то читал случайно, но сейчас не могу вспомнить где, что можно в ядре переписать/добавить свой обработчик события парсинга url и "скармливать" уровню приложения уже нужные данные. Что-то вроде портирования модуля Маршрутизация со старшей версии или, возможно, написание своего.

Много букафф, но постарался подробнее. Если есть идеи или нужна доп. информация, пожалуйста. Спасибо.

xanafi9320
19.02.2015, 15:21
Руслан Густокашин
Студия Вэлпис

Зарегистрирован:
2012-02-06
Сообщений: 962

Может быть вам посидеть подумать, написать скриптик, который будет, например, 1 раз в час запускаться и перекидывать товары из раздела /catalog/items/ в так сказать "тематические" разделы, по мере необходимости создавая автоматически новые разделы?

А сделать отображение товаров из всех вложенных разделов +текущего раздела очень просто - напишите в системных настройках:
$ignore_sub=$ignore_cc=1;
$query_where = "a.Subdivision_ID IN (".join(",",nc_get_sub_children($current_sub['Subdivision_ID'])).")";
20.02.2015, 16:03
xanafi9320
ИП Журавский

Зарегистрирован:
2014-12-15
Сообщений: 4

Да, спасибо. Переспал с задачей, в хорошем смысле, ессно, поизучал движок немного. План с разделами отвалился сам собой, есть вводные, должна также присутствовать ЧПУ адресация вида /производитель/название и т.д. То есть, как колода карт, то с туза начнём давайте, то с шестёрки и так перебором. В такой структуре заблудиться можно будет и самому, да ещё по каждому писку ворочать туда-сюда это всё. Мысль эмулировать структуру манипуляциями сущностей в БД тоже отвалилась, т.к., по мимо прочего, поковырявшись в движке обратил внимание что активно пользуется и файловая система, в папке /netcat_files ресурсы с привязкой к разделам и компонентам по id, с хешами в именах, ещё чем-то. При том, что товаров, как я говорил, не ах как много, а директория эта весит почти 2 гига, благодаря, в основном, этому самому разделу и компоненту, куда всё свалено. Вобщем, по-взрослому всё, и камней подводных, по-видимому, немало в этом направлении, костылей не хватит.
Решил взять за основу стратегию - для клиента всё должно выглядеть без изменений, пусть добавляют товары в один раздел как привыкли, пользуют списки, коллекции и т.д. Вынесу всё что нужно в отдельный модуль, проще самому парсить урл и забить один большой костыль в nc_objects_list или nc_Url и по мере надобности ещё куда-нибудь, например, транслитерацию классификаторов при изменении/добавлении сделать пришлось, те что в списочных полях объектов пользуются. Точнее сделал универсальный для списков вообще, завтра ещё что-нибудь "захочут". Формат ссылок на конечный объект и всё что относится в настройке компонента задал. Думаю, что в таком духе и доделаю. Смахивает на костыльность, но можно назвать и модификацией кода ядра, чтоб серьёзней было)
Спасибо.

xanafi9320
22.02.2015, 16:43
Руслан Густокашин
Студия Вэлпис

Зарегистрирован:
2012-02-06
Сообщений: 962

Понятно, в общем не все так просто выходит.
А на новый неткат в самом деле чересчур сложно обновиться? Не окажется ли это менее трудозатратно, чем изобретение большого универсального костыля? Я, правда, сам лично модуль "Маршрутизация" пока еще не пробовал использовать, но судя по документации, возможности у него довольно широкие.
Некоторый костыль, подобный Вашему, на одном старом проекте,где тоже не было модуля маршрутизации, мне удалось реализовать на основе .htaccess + некоторых донастроек apache, но решение получилось совсем неоптимальное, не буду рекомендовать его Вам.
Как более грамотный вариант - поставьте в .htaccess вместо e404.php какой-то свой обработчик-обертку, и уже из-под него каким-то образом запускать "родной" e404.php с откорректированными параметрами.

Еще вот какая проблема. Если вы-таки реализуете то, что задумали, через модификацию кода системы, то у вас получится, что у каждого товара будет несколько URL'ов, а это крайне плохо для SEO. Или Вы планировали сэмулировать только URL'ы разделов, а у товаров оставить "родной" урл?

Задача, подобная Вашей, кстати, у нас была в одном интернет-магазине. На сайте было много-премного веток каталога, причем товары могли дублироваться в СПИСКАХ товаров совершенно разных разделах нескольких веток и дополнительно еще в родительских разделах этих разделов. Но все разделы всех веток каталога администраторы сайта создавали сами, вручную (таким образом, отпала необходимость в костылях-генераторах URL).
А отображение товаров во всех нужных разделах я реализовал достаточно просто: в компоненте "Товар" создал специальное строковое поле, куда админы сайта через мультиселект заносили разделы, в которых должен показываться данный товар (выделяя их через ctrl-click). В базу при сохранении товара записывались номера разделов через запятую (например: 20,30,11,17).
А в системных настройках компонента уже генерировался код $query_where, немного похожий на тот, что я привел постом выше, который делал выборку товаров для текущего раздела сайта и его родителей.
Благодаря этому, у админов появилась возможность показывать товар на сайте одновременно в разных ветках каталога, причем у детальной страницы товара при этом оставался всегда один, уникальный URL - как того и требуют SEO'шники. Картинки тоже обрабатываются, конечно, корректно - пути к ним не меняются.

В вашем случае, если веток каталога получается действительно немыслимое множество - вам можно было бы реализовать вышеописанную технологию + сделать автоматический скрипт-генератор разделов/подразделов, который будет проходиться по всем нужным спискам и создавать автоматом недостающие разделы, а также привязывать к ним автоматически нужные товары.
При этом у вас появится возможность для каждого раздела или ветки каталога вручную задать необходимые title, description, keywords через стандартные SEO-поля Netcat.
И избежите необходимости лезть в системный код CMS.
24.02.2015, 16:16
xanafi9320
ИП Журавский

Зарегистрирован:
2014-12-15
Сообщений: 4

Собственно, я уже сделал так как запланировал и уже на продакшене обкатал, всё работает нормально.

Да, принцип с подменой тот же, только я не стал подменять обработчик e404, ворочать его кишочки и т.д. Я сделал, как мне кажется, ещё проще - в nc_Url добавил метод, который участвует в parse_url и мониторит урлы на предмет наличия в них "зарегистрированных" альясов. Если урл что-то представляет ценное, то генерятся и подкидываются далее на обработку стандартные параметры в том же виде, как они в nc_objectы_list и принимаются, как гет параметры с фильтрами srchPat. Т.е. движок потом сам разбирается со всем этим. Здесь же и устанавливается признак того, что нужно использовать "базовый" компонент, если урл соответствует чему-то. Альясы для классификаторов и объектов генерятся автоматически, тут удобный механизм событий подвернулся, зарегестрировал ещё события, которых не хватало для "базовых" компонентов и сабдивиженов, транслитеририровал там, где это нужно. Это всё в маленьком классе, который регистрирует события и отвечает за транслитерацию, в т.ч. создаёт поля для транслитерации имён если отсутствуют в данной сущности и т.д. Здесь же в самописном модуле добавились функции по генерации маршрута для каждого объекта или категории из альясов согласно иерархии и прочего.
Не без минусов, конечно, но костылей на самом деле не та уж и много, в nc_Subdivision буквально несколько строчек если не был получен сабдивижен стандартным способом (адреса служебных страниц или не связанных с товаром и т.д.), то делается попытка получить базовый, если парсинг урла ранее дал на это добро когда отрабатывал.
Урл конечного объекта со статическим адресом движок сам корректно отрабатывает, даже не вникал что там и куда. Остальное практически ручная работа, из админки в компоненте прописал вызов функций своего самописного модуля для генерации того или иного адреса и там по мелочи ещё чего.

С обновлением вариант у меня был изначально, но пораскинув немного, во-первых, нужно будет содержимое всё то ли перетаскивать, то ли заново создавать, поскольку читал где-то здесь про некоторые нюансы использования компонентов старых версий в новых редакциях, сразу потенциальные проблемы, при том, возможно, критические. Во-вторых, модуль маршрутизации тоже не панацея от всех бед, возможно, при частой смене вводных и не поможет, либо тоже потребует заточки, проще, грубо говоря, константы пребить/добавить. Ну а в-третьих, это платить нужно за саму редакцию, а як жеж) и потом снова за работу, бо, само всё не образуется никак, это уж точно. Что-то в таком духе.

По сео правильно замечено тоже. Об этом не упоминалось в ТЗ, но следствием явилось обязательное условие сохранения старых адресов, которые, якобы, в индексе. Само собой, пропатчил генерацию sitemap, ссылки там фигурируют только ЧПУ. Предложил как вариант редирект со страниц, коих множество, с фильтрами на уже имеющуюся статическую страницу со списком каталогов где ссылки уже ЧПУ и чёткая последовательность и далее, просто чтобы не было мёртвых адресов формата /catalog/tovar/?srchPat[0]=1 и т.д. Об индексации фильтров в параметрах, конечно же, речь не идёт, всё многообразие этих адресов имеет один о тот же адрес с точки зрения сео. У меня нет доступа к метрикам, но я почти уверен, что там только указан параметр и его роль, как у гугла, например, а адрес, если он есть, один - /catalog/tovar/ Адреса конкретных объектов уже в Sitemap, которые с течением времени и попадут в индекс. Да и при посещаемости в 50 человек в сутки это не критично, какие там доходы с продаж при такой посещаемости, не говоря уже о рекламе, тем более со временем всё перестроится, хотя этот вопрос из другой оперы. Так мне виделось. Дали на связь сео специалиста, который начал с - а при чём здесь sitemap вообще, потом неспортивное что-то залепил. Вобщем, как мне показалось, кроме сео он больше вообще ни к чему отношения не имеет и уже к неткэт тем более. По сему кроме просьбы говорить по делу особо ничего с него и не спрашивал и, соответственно, вариантов тоже никаких. Вопрос ушёл из технической плоскости в политическую) Дай редирект один в один на все пять тысяч страниц, а если ещё фильтры учитывать двойные, например, по стране производства и производителю в этой стране, то и того больше. Ну или хотя бы на половину. Т.е. адрес одной странички в браузере должен волшебным образом смениться на другой, смысл такой. Никого также не смущает, что все эти правила будет обрабатывать сервер, и будет обрабатывать постоянно, даже если только ресурсы запрашиваются, а не контент, примерно так. Спорить не стал, хотя понятно, что мера временная, даже самому интересно стало, а свалится их сервер или нет, и на сколько его хватит. Нагенерю им правил, посмотрю что будет) Во всяком случае у меня другого решения для сео нет, сказали редирект, значит редирект)

По теме топика вопрос закрыт.

По теме этого поста:
Спрашивает психотерапевт у пожилого посетителя:
- Да у вас железные нервы, как вам удалось сохранить их да в таком-то возрасте?
Посетитель:
- А я ни с кем не спорю.
- Как не спорите?
- Да вот не спорю и всё.
- Совсем совсем?
- Да, совсем совсем.
- Не может быть!!
- Ну не может быть так не может быть...
)

Да, и спасибо за советы, Руслан. Если будет ещё что-нибудь на неткэт, то пригодятся Ваши советы.

xanafi9320
24.02.2015, 19:12
Руслан Густокашин
Студия Вэлпис

Зарегистрирован:
2012-02-06
Сообщений: 962

Ого, здорово вы потрудились! Да еще так быстро задачку решили. улыбка
Жаль, конечно, что пришлось патчить код системы, но в отдельных случаях это целесообразно. Да и, действительно, нет никакой уверенности, что модуль маршрутизации решил бы задачу. Ну в общем молодцы! улыбка)
24.02.2015, 19:31
xanafi9320
ИП Журавский

Зарегистрирован:
2014-12-15
Сообщений: 4

Молодец, Вы хотели сказать)
Это я так, балдЮ по скромности) На самом деле с сео больше возни, то так не нравится, то так.
Сами, навреное, запутались немного. Сделаю окончательный костыль в обработчик и буду редиректить из пхп, так хоть гибче получится.

Спасибо. Удачи.

xanafi9320
198 196 2015-02-24 19:31:31 14020
Описание проекта