(defgeneric restas:render-object (designer object)который теперь всегда вызывается для обработки данных, возвращаемых обработчиками маршрутов (задаваемых через define-route). Здесь видно, что для генерации контента используется два объекта: designer и данные, так что можно говорить о полноценном разделении логики и представления, ну а мультиметоды в CL, как мне кажется, делают её значительной более мощной, чем механизм разделения логики и представления в тех же RoR или Django. Дефолтовый designer указывается в переменной модуля |module-name|:*default-render-method* и по-умолчанию установлен в nil. В RESTAS определены дефолтовые реализации restas:render-object, которые в качестве данных могу принимать
(:documentation "Render object via designer"))
- строку или массив octets - данные просто отдаются клиенту без какой-либо дополнительной обработки
- pathname - файл отдаётся клиенту с помощью hunchentoot:handle-static-file
- integer - результат интерпретируется как HTTP-статус и клиенту отдаётся соответствующая специальная страница
- В прочих случаях сообщается об ошибке
- pathname или integer - вызывается дефолтовый обработчик
- В прочих случаях с помощью funcall вызывается указанная функция для обработки переданных данных и результат отдаётся клиенту
- Каждый маршрут является именованным и связан с символом
- Почти всегда для логики представления я использую cl-closure-template, которая компилирует шаблоны в функции, для которых создаётся отдельный пакет
(restas:define-default-render-method (obj)Здесь задаётся *default-render-method* в виде функции (для упрощения и наглядности используется специальный макрос), которая с помощью "пакета с шаблонами" генерирует содержательную часть страницы:
(closure-template.standard:xhtml-strict-frame
(list :title (getf obj :title)
:body (restas.colorize.view:with-main-menu
(list :href-all (restas:genurl 'list-pastes)
:href-create (restas:genurl 'create-paste)
:body (restas:render-object (find-package '#:restas.colorize.view)
obj)))
:css (iter (for item in '("style.css" "colorize.css"))
(collect (restas:genurl 'css :file item))))))
(restas:render-object (find-package '#:restas.colorize.view) obj)которую затем использует для генерации законченного html-кода.
Ну и конечно, разработчик может определить собственные специализации restas:render-object для своего типа designer. Например, в restas-wiki нельзя решить проблему генерации разметки только за счёт шаблонов (ибо нужно конвертировать сложный формат в html). Поэтому, я сейчас рассматриваю возможность разработки отдельного класса wiki-designer, который будет отвечать за генерацию разметки и будет производить основную обработку с помощью generic-методов. Это даёт возможность приложению, использующему модуль restas-wiki (например, lisper.ru), определить собственный designer, наследующий от wiki-designer и затем с помощью динамического связывания в restas:define-submodule (почитать об этом можно здесь) указать свой способ отображения wiki-страниц: т.е. можно будет полностью изменить способ отображения wiki-страниц не изменив при этом ни строчки оригинального кода. И это как раз тот уровень модульности, к которому я стремлюсь при разработке RESTAS.
А почему designer называется designer, а не какой-нибудь renderer?
ОтветитьУдалитьНу, слово designer более романтичное что-ли :) А есть причины, почему оно не очень хорошо подходит?
ОтветитьУдалитьdesigner я воспринимаю как что-то позволяющее и редактировать и отображать данные. А, например, renderer только отображает.
ОтветитьУдалитьРечь идет в основном про отображение, да и метод называется restas:render-object; этот объект может хранится в переменной |module-name|:*default-render-method*. Поэтому designer неожиданно чуть-чуть.
Кстати, *default-render-method* мог бы быть *default-renderer*.
Но это дело вкуса.
Слово renderer мне не нравится, как-то коряво...
ОтветитьУдалитьНарод пользуется таким словом, например в java server faces: http://dsc.sun.com/docs/jscreator/apis/jsf/javax/faces/render/Renderer.html
ОтветитьУдалитьНе, ну там для URL, я бы тоже не стал использовать designer, но тут таки идёт генерация целых web-страниц, так что designer кажется мне нормальным словом, и выглядит красиво :)
ОтветитьУдалитьА по-моему renderer (по-русски "отрисовщик") лучше. Designer у меня больше с вёб-дизайном ассоциируется.
ОтветитьУдалитьЕсли нужен перевод уроков по Restas на английский, напишите мне на почту.
> Designer у меня больше с вёб-дизайном ассоциируется.
ОтветитьУдалитьНу так он как бы и имеет самое непосредственное отношение к веб-дизайну.
> Если нужен перевод уроков по Restas на английский, напишите мне на почту
Хм, очень интересное предложение! Я имею план в обозримом будущем собрать всю инфу о RESTAS, которой сейчас владею (гы) в неком мануале. Он, конечно (ибо мой английский того, не звучит), будет на русском. Вот перевести это дело на english было бы очень интересно. Но только я не понял куда писать, профиль закрыт :(
valeriy.fedotov на гмыле
ОтветитьУдалитьИли laser123 в lisp@
Странно, я думал, что в профиле видно...
@Valeriy Fedotov
ОтветитьУдалитьOk. Что бы было видно почту надо профиль открыть на настройках акаунта Google.