使用 cl-who、parenscript 和 hunchentoot 生成内联 javascript
Generating inline javascript with cl-who, parenscript and hunchentoot
我正在尝试生成内联 javascript,但我必须使用 cl-who 将 parenscript 代码放入 (:script)
和 (str)
标记中。 ps
、ps*
、ps-inline
和ps-inline*
似乎对生成的js没有太大影响。
写宏是避免代码重复的常用方法,还是有更好的方法?
这是我的程序:
(in-package #:ps-test)
(defmacro standard-page ((&key title) &body body)
`(with-html-output-to-string (*standard-output* nil :prologue t :indent t)
(:html
:lang "en"
(:head
(:meta :http-equiv "Content-Type"
:content "text/html;charset=utf-8")
(:title ,title)
(:link :type "text/css"
:rel "stylesheet"
:href "/style.css"))
(:body
,@body))))
(defun main ()
(with-html-output (*standard-output* nil :indent t :prologue nil)
(standard-page (:title "Parenscript test")
(:div (str "Hello worldzors"))
(:script :type "text/javascript"
(str (ps (alert "Hello world as well")))))))
(define-easy-handler (docroot :uri "/") ()
(main))
(defun start-ps-test ()
(setf (html-mode) :html5)
(setf *js-string-delimiter* #\")
(start (make-instance 'hunchentoot:easy-acceptor :port 8080)))
(defun stop-ps-test ()
(stop *server*))
(defvar *server* (start-ps-test))
宏在此用例中很好用。
诀窍是宏按特定顺序展开。说
你定义了一个 js
宏:当宏展开遇到
with-html-output
,对宏的内部调用 (js (alert "Ho Ho Ho"))
看起来像一个函数调用,并在生成的
代码。如果你的 js
宏 then 扩展成 (:script ...)
,那么系统会抱怨 :script
是一个未知函数(假设你
实际上并没有命名这样的函数)。你应该发出一个
包含 (who:htm ...)
表达式以解释使用的代码
CL-WHO的代码walker.
(defmacro js (code)
`(who:htm
(:script :type "text/javascript" (who:str (ps:ps ,code)))))
这仅适用于封闭 with-html-output
.
的上下文
对于内联 Javascript,您不希望其周围有 <script>
标记,
你通常可以简单地使用 ps-inline
:
(who:with-html-output (*standard-output*)
(:a :href (ps:ps-inline (void 0))
"A link where the usual HREF behavior is canceled."))
;; prints:
;;
;; <a href='javascript:void(0)'>A link where the usual HREF behavior is canceled.</a>
但如果您经常做同样的事情,请随意使用宏:
(defmacro link (&body body)
`(who:htm (:a :href #.(ps:ps-inline (void 0)) ,@body)))
(who:with-html-output (*standard-output*) (link "Link"))
;; prints:
;;
;; <a href='javascript:void(0)'>Link</a>
我正在尝试生成内联 javascript,但我必须使用 cl-who 将 parenscript 代码放入 (:script)
和 (str)
标记中。 ps
、ps*
、ps-inline
和ps-inline*
似乎对生成的js没有太大影响。
写宏是避免代码重复的常用方法,还是有更好的方法?
这是我的程序:
(in-package #:ps-test)
(defmacro standard-page ((&key title) &body body)
`(with-html-output-to-string (*standard-output* nil :prologue t :indent t)
(:html
:lang "en"
(:head
(:meta :http-equiv "Content-Type"
:content "text/html;charset=utf-8")
(:title ,title)
(:link :type "text/css"
:rel "stylesheet"
:href "/style.css"))
(:body
,@body))))
(defun main ()
(with-html-output (*standard-output* nil :indent t :prologue nil)
(standard-page (:title "Parenscript test")
(:div (str "Hello worldzors"))
(:script :type "text/javascript"
(str (ps (alert "Hello world as well")))))))
(define-easy-handler (docroot :uri "/") ()
(main))
(defun start-ps-test ()
(setf (html-mode) :html5)
(setf *js-string-delimiter* #\")
(start (make-instance 'hunchentoot:easy-acceptor :port 8080)))
(defun stop-ps-test ()
(stop *server*))
(defvar *server* (start-ps-test))
宏在此用例中很好用。
诀窍是宏按特定顺序展开。说
你定义了一个 js
宏:当宏展开遇到
with-html-output
,对宏的内部调用 (js (alert "Ho Ho Ho"))
看起来像一个函数调用,并在生成的
代码。如果你的 js
宏 then 扩展成 (:script ...)
,那么系统会抱怨 :script
是一个未知函数(假设你
实际上并没有命名这样的函数)。你应该发出一个
包含 (who:htm ...)
表达式以解释使用的代码
CL-WHO的代码walker.
(defmacro js (code)
`(who:htm
(:script :type "text/javascript" (who:str (ps:ps ,code)))))
这仅适用于封闭 with-html-output
.
对于内联 Javascript,您不希望其周围有 <script>
标记,
你通常可以简单地使用 ps-inline
:
(who:with-html-output (*standard-output*)
(:a :href (ps:ps-inline (void 0))
"A link where the usual HREF behavior is canceled."))
;; prints:
;;
;; <a href='javascript:void(0)'>A link where the usual HREF behavior is canceled.</a>
但如果您经常做同样的事情,请随意使用宏:
(defmacro link (&body body)
`(who:htm (:a :href #.(ps:ps-inline (void 0)) ,@body)))
(who:with-html-output (*standard-output*) (link "Link"))
;; prints:
;;
;; <a href='javascript:void(0)'>Link</a>