Динамические блоки в Простой странице с помощью виджетов
Была поставлена задача: сделать на сайте возможность вывода позиций прайс-листа на страницах сайта со следующими особенностями:
- возможность выводить прайс-лист в любом месте текстовой страницы,
- возможность выводить любой набор позиций из прайс-листа,
- возможность выводить любое количество таких наборов в разных местах страницы.
В терминах Нетката получается задача вывода произвольного набора объектов компонента внутри текстовой страницы. Разумеется, сделать это нужно как можно более удобно, чтобы для вставки объектов тратилось как можно меньше времени и телодвижений.
Учитывая наличие чудесной кнопочки "Вставить виджет" в текстовом редакторе, способ исполнения такого функционала логично решился сам собой. Оставалось дело за реализацией. В данном случае у нас в распоряжении Netcat 4.7. Как обстоят дела в 5-м не знаю. Надеюсь, лучше.
Итак, что нам нужно для реализации поставленной задачи? Нам нужно вывести виджет, передать в него каким-либо способом указание на то место, где он выводится, и получить на выходе нужные объекты. Что есть в нашем распоряжении? В общем случае, пока только id раздела, куда мы хотим вставить виджет. Ну и то хорошо. Идем варить кофе.
Часть 1. Мечты.
На первом этапе мы надеемся обойтись одним виджетом на все случае жизни. Создаем виджет-компонент, пишем туда код для вывода объектов, в нашем случае это таблица с ценами из прайс-листа. Я сразу отказался от s_list_class по какому-нибудь шаблону и написал все вручную. Не знаю, почему, это было спонтанным решением и никак не повлияло на итоговый результат. Дальше, в разделе Инструменты->Виджеты создаем сам виджет и прикрепляем к нему созданный ранее компонент. Теперь нужно придумать, как хранить и доставать нужный нам набор id объектов в зависимости от локализации виджета. Пытаемся сначала обойтись средствами Netcat. Имея id раздела, можно использовать дополнительные поля в настройках раздела. В данном случае нам подойдет текстовое поле. Для выбора позиций делаем форму с чекпоинтами, выводящую объекты компонента и открывающуюся во фронт-энде из блока самого виджета (разумеется, под админом). Учитывая, что наборов объектов может быть несколько, мы можем присваивать каждому блоку id и писать в текстовое поле массив. Итак, создаем текстовое поле...
Виджеты, как известно, можно выводить двумя способами: динамически, с заданными параметрами ($nc_core->widget->generate())
, и статическй html-код виджета ($nc_core->widget->show())
. Разумеется, выяснилось, что в текстовую страницу можно вставить только второй вариант, в тексте это делается в таком виде %NC_WIDGET_SHOW()%
. Ок, пытаемся передать в виджет какие-либо параметры извне. Объявляем переменные как global в системных настройках виджет-компонента. И... выясняем, что некоторые переменные передаются вроде бы нормально (хотя в какой-то момент уверенность в этом тоже пропала), другие - нет. В общем, не решив эту проблему за короткий срок, от идеи "все в одном" пришлось отказаться, так как помимо удобства важна и безотказность работы, а уверенности в этом на данный момент не было. Позже, когда все было готово, я понял, в чем было дело, но об этом ниже.
Часть 2. Реальность.
Второй вариант заключался в следующем. Создаем в нашем виджет-компоненте текстовое поле (строку) для хранения id объектов и такую же форму для выбора объектов с чекпоинтами, как ранее, но в шаблонах действия. При выборе объектов будем писать id объектов в поле с помощью jquery. Тогда для каждого случая надо будет создавать отдельный виджет и вставлять его в нужное место. То есть, если на странице нужно вставить три прайс-листа, то нужно создать три виджета. Чуть менее удобно, виджетов со временем станет много, но зато более надежно, чем первый вариант. В конце концов, если давать виджетам грамотные названия, то найти их в списке при необходимости будет не проблема.
Итак, создаем поле для id, идем в шаблоны действий и... Выясняем, что там каким-то неведомым образом не работает jquery, при подключенной библиотеке, ну вот не работает и все. То есть сделать совсем все удобно не получится. Ок, в данном случае это не большая проблема. Создаем еще один компонент, помещаем туда нашу форму выбора объектов и обработку get параметров, прикрепляем к служебному разделу. В альтернативной форме изменения нашего виджет-компонента делаем ссылку для выбора объектов на этот раздел и передаем с ней в качестве параметра id созданного виджета, благо что в данном случае все передается нормально.
Теперь все работает, все вроде довольны. Однако, редактируем исходные объекты, смотрем на сайте - реакции никакой. Тут мы, разумеется, лезем в документацию и с ее помощью вспоминаем про неприметное поле "Обновлять виджеты каждые N минут" в виджет-компоненте. Ставим какое-нибудь значение, и через это время виджет обновляется. Все работает.
А теперь снова идем в документацию и читаем про это поле подробнее: "Эта настройка применима к таким виджетам как RSS-лента, позволяет наполнять ваш виджет актуальной информацией. Если значение равно 0, то обновление не происходит". И ни слова про то, что виджет впринципе так работает всегда. Как в итоге выяснилось, он так работает и в режиме разработки, написания кода, тестирования. То есть эта настройка касается реакции выходных данных не только на изменение входных данных в виджете, но и на изменение кода в виджет-компоненте. То, что я писал выше про неправильную передачу параметров, как раз и явилось следствием такой работы. Поэтому, для того, чтобы все работало, нужно сразу поставить время обновления, скажем, 1 минуту. Но вот почему и зачем так сделано, для меня по-прежнему загадка. Одна из загадок Неткат.
Итоги.
Что же в итоге. В итоге все работает как надо, виджеты выводятся, обновляются, не глючат. Счастье. Проверять работоспособность первого варианта я не стал. От добра добра не ищут. Работает - не трогай. Ну итд. Если будет необходимость, проверим это уже на 5м Неткате.