Программирование
Как подружить свой тип данных с Views
При разработке модулей для Drupal мы частенько создаем программно новые типы материалов (то есть нод). В процессе иногда возникает соблазн быстренько запрограммировать вывод какой-нибудь отсортированной коллекции этих материалов. Например, вывод нод-городов, отсортированных по алфавиту, или по древности, или сгруппированных по странам. Таких полезных коллекций может образоваться достаточно много и программно создавать каждую из них — не очень эффективно. Особенно если впоследствии нам захочется что-то поменять, объединить, или переделать. Гораздо аккуратнее — использовать модуль Views.
Вообще говоря, Views — один из краеугольных камней разработки на Drupal. Хотите помесячный архив нод? Views. Хотите вывести только заголовки и даты нод? Views. Хотите вывести ноды, сгруппированные по именам авторов? Views. Хотите получить список IP, с которых пользователь Василий заходил на сайт в течение Великого поста? Тоже Views. Один из самых популярных ответов на вопрос «Как в Друпале сделать…» — Views. Так что, чем быстрее разработчик подружится с этим прекрасным модулем — тем лучше.
Однако как только разработчик захочет получить с помощью Views коллекцию созданных им данных — например, из самодельной таблицы, сделанной для нового типа материала — он обнаружит, что Views еще не знает о его таблице. Так вот, раз и навсегда рассказать о своей таблице модулю Views — на мой взгляд, гораздо более правильное решение, чем программировать вручную все необходимые представления.
О том, как это сделать — под катом.
Qt и звуки
Меня всегда радовало разнообразие возможностей по работе со звуком в Линуксе.
Сегодня, например, несколько часов подряд взрывал себе мозг на тему QSound в Qt. Дело в том, что под Виндой, чтобы воспроизвести звуковой эффект без извращений, нужно просто вызвать статический метод QSound::play("имя файла")
Когда с nasd возникли какие-то проблемы, быстренько переключился на поиск альтернатив. Уже задумался о компиляции версии под Линукс с Phonon. Остановил тот факт, что фононовский учебный проект из состава Qt SDK не собрался out of the box. Попробовал учебный проект QAudioOutput оттуда же — не работает.
Уже начал было впадать в уныние, но в конце-концов осенило:
Вроде бы, ерундовая задача, а — чуть стол головой не разбил. Так жить нельзя.
Параметрический вызов формы добавления нода на разных страницах
Предположим, мы создали модуль и в нем определили новый тип нода. Пусть это будет нод «Город» с внутренним именем 'city'. В форме добавления нашего нода с адреса 'node/add/city', кроме всего прочего, мы сделаем селектор стран, чтобы можно было выбирать, в какой стране находится город:
Теперь предположим, что мы создали страницы с описаниями разных стран. И хотим чтобы пользователь мог добавить город не через меню «Создать материал» — «Город», а со страницы с описанием страны. Что логично: вот пользователь смотрит на страницу «Россия» и сразу хочет добавить свой родной город.
Первое, что мы можем по этому поводу сделать — это разместить ссылку на 'node/add/city'. Но в таком случае пользователю придется в форме добавления города выбирать страну из списка, а ведь он уже сделал этот выбор, нажав «Добавить город» именно на странице с описанием нужной страны. Очевидно, следует учесть выбор пользователя и при создании формы установить заданную страну как дефолтную в списке 'countries'.
О том, какой фокус для этого надо проделать — под катом.
Вышел Qt 4.6.0
Schema API и запись данных в Друпале
Так получилось, что еще года четыре назад я немного баловался Друпалом 4.x. Там новые записи добавлялись в таблицы базы данных через db_query()
drupal_install_schema()
И только недавно выяснил, что использовать drupal_write_record()
hook_insert()
hook_update()
Ну и, наконец, по окончании работы функции, в сохраняемом объекте появятся значения всех serial-полей вновь созданной записи, то есть вызывать n-е количество раз db_last_insert_id()
В общем, если в нашем модуле таблицы БД созданы через Schema API (а они должны быть так созданы) — использовать drupal_write_record()
Табы в Друпале
При просмотре содержимого того или иного нода в CMF Drupal можно заметить наличие вкладок «Просмотр», «Изменить» и прочих:

Выбор одной из них позволяет пользователю осуществить то или иное действие с просматриваемым нодом. Вполне естественно, что при создании новых типов нодов нам может захотеться добавить к ним новые вкладки.
Делается это через систему меню, а точнее — в hook_menu'node/$nid''node/$nid/tab1'
где _view_tab1_page_my_localtask_access
Знак % — это так называемый wildcard (он же шаблон, метасимвол, символ подстановки), использующийся для передачи элемента пути в аргумент функции. В данном случае нам нужно передать элемент пути, соответствующий arg(1)'node/64/tab1'arg(1)
Для удобства разработчики Друпала предусмотрели метасимвол с загрузкой. Запись '%node'arg(1)node_load(arg(1))node_load()
Возникает вопрос: а зачем вообще нужна функция доступа? Ведь мы можем просто передать 'access content'user_access()_my_localtask_access
С точки зрения логики это не совсем правильно: ведь мы не хотим запрещать доступ к локал таскам для других нодов, мы хотим, чтобы для них нашего таба просто не существовало. Но других вариантов нет.
Вот таким, немного странным, но коротким и аккуратным способом можно сделать табы для нодов.
Cheat Sheets для веб-разработчика
Пришел по рассылке адресок, содержащий 25 чит-шитов для веб-разработчика. Например:
Счастье мое не знает предела. Сейчас разденусь догола, обклеюсь разноцветными чит-шитами и буду танцевать при луне.
Советы по jQuery
Бороздя интернеты, случайно обнаружил статью «Совершенствуйтесь в jQuery — 25 отличных советов».
Советы действительно отличные, без дураков. Особенно для ребят, которые еще неопытны в предмете (вроде меня). Некоторые из пунктов побудили срочно бежать и переделывать всякое. Хорошая статья, стоит прочесть.
Сохранение формы в Drupal с помощью AJAX
Сегодня речь пойдет о том, как запрограммировать сохранение формы в Друпале через AJAX. В принципе, для этих целей уже существует модуль Ajax. Но вдруг у нас крайне хитрые потребности, или мы просто не хотим ради сабмита пары форм тащить за собой целый модуль?
В общем, задача такова: создать средствами Друпала простую форму, вывести ее на страницу, а затем — сохранять через AJAX-запросы, выводя на ту же страницу результаты сохранения и ошибки валидации формы, если таковые были. Без обновления страницы, естественно. Для решения задачи будем использовать Form API Друпала и jQuery с плагином Form. Оформим все в виде отдельного модуля.
Рассмотрим решение по порядку. Кому не хочется читать статью целиком, тот может сразу скачать архив с исходниками тестового модуля и поиграться с ним.
Остальных приглашаю под кат.
Создание нескольких одинаковых форм на одной странице
Недавно возникла нужда написать функцию, создающую несколько одинаковых форм на одной странице. Формы небольшие, состоят из одного текстового поля и кнопки, а также (что важно) двух переменных для внутреннего использования:
По нажатию кнопки содержимое текстового поля записывается в БД вместе с $id1$id2
Сделать хотелось примерно вот что:
Однако очевидно, что данный код работать не будет. Загвоздка в том, что все формы генерируются с одинаковым form_ID и при сохранении любой формы Друпал будет считать, что сохраняется самая первая. Поэтому $id1$id2
Порывшись изрядно по Drupal.org было найдено решение в виде хука hook_forms
Дело все в том, что в описании hook_forms$form_id$args_my_form
Но поскольку формы у нас стали с разными ID, Друпал при сохранении формы будет искать разные функции-обработчики. Так что нужно указать единый валидатор и обработчик при создании формы:
Дело сделано. Теперь остается только немного изменить генерацию данных на странице, чтобы формы создавались с разными ID:



