2017-12-21 6 views
2

Ich versuche, Inline-Javascript zu generieren, aber ich muss den Code perenscript in (:script) und (str) Tags mit Cl-Wer. ps, ps*, ps-inline und ps-inline* scheinen für die generierte js keinen großen Unterschied zu machen.Inline-Javascript mit cl-who, parenscript und hunchentoot erzeugen

Ist der übliche Weg, ein Makro zu schreiben, um Code-Duplikation zu vermeiden, oder gibt es einen besseren Weg?

Hier ist mein Programm:

(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)) 

Antwort

2

Makros sind in diesem Anwendungsfall in Ordnung. Der Trick besteht darin, dass Makros in einer bestimmten Reihenfolge erweitert werden. Say Makro definieren Sie eine js Makro: Wenn Makroexpansion , der innere Aufruf Ihrer Makros (js (alert "Ho Ho Ho")) sieht aus wie ein Funktionsaufruf, und bleibt wie im generierten Code . Wenn Ihr js Makro dann in (:script ...) expandiert, dann wird das System beschweren, dass :script eine unbekannte Funktion ist (vorausgesetzt, dass Sie eine solche Funktion tatsächlich nicht nennen). Sie sollten einen Ausdruck ausgeben, der (who:htm ...) Ausdruck enthält, um den Code zu interpretieren, der CL-WHOs Codewalker verwendet.

(defmacro js (code) 
    `(who:htm 
    (:script :type "text/javascript" (who:str (ps:ps ,code))))) 

Dies funktioniert nur im Zusammenhang mit einem with-html-output umschließt.

Für Inline-Javascript, Sie wollen nicht zu einem <script> Tag um ihn herum haben, und Sie können einfach im Allgemeinen ps-inline verwenden:

(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> 

Aber fühlen Sie sich frei, einen Makro zu verwenden, wenn Sie häufig das gleiche tun Sache:

(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>