четверг, 3 марта 2011 г.

Прозрачное использование Parenscript

Я использую Parenscript в реализации cl-closure-template. Но обычный код предпочитаю писать на JavaScript. На то есть несколько причин и одна из самых существенных - возникающие инфраструктурные трудности. На самом деле я бы хотел просто размещать файлы с кодом на Parenscript среди других статических файлов и больше ни о чём не думать, а оно пусть там как-нибудь само обрабатывается. После добавления в RESTAS декораторов реализовать такое поведение оказалось очень просто:
(defclass ps-compile-route (routes:proxy-route) ())

(defmethod restas:process-route ((route ps-compile-route) bindings)
(let ((result (call-next-method)))
(cond
((and (pathnamep result)
(string= (pathname-type result) "parenscript"))
(setf (hunchentoot:content-type*)
"text/javascript")
(let ((*package* (find-package '#:ps)))
(ps:ps-compile-file result)))
(t result))))

(defun @ps-compile (origin)
(make-instance 'ps-compile-route :target origin))
В случае если основной обработчик маршрута возвращает pathname с расширением ".parenscript", то данный декоратор компилирует его содержимое в код на JavaScript и отправляет клиенту, иначе возвращает результат без какой-либо обработки. Теперь я просто публикую статические файлы
(restas:mount-submodule -static- (#:restas.directory-publisher @ps-compile)
(restas.directory-publisher:*directory* #P"/path/to/static/")
И если мой Parenscript-код находится в файле "/path/to/static/js/core.parenscript", то в HTML он подключается как
<script src="/js/test.parenscript"></script>

2 комментария:

  1. Красиво. Я бы предпочел название ps-compile-decorator.
    Можно например, в частности, добавить что-нибудь в тег head по нужным маршрутам. А вообще, надо включать фантазию по полной ибо фича крутая:) Главное, чтобы подводных камней небыло ...

    ОтветитьУдалить
  2. > ps-compile-decorator

    Длинно ) А в Python стандартный синтаксис декораторов как раз начинается с @, так что это как бы аналог.

    ОтветитьУдалить