We'll use
s
as the query key name. And it can be repeated multiple times. What we want is to write an SHP script that looks like the following:
;; js
;; loading javascripts
;; default to using s key, but can be customized
(javascript!) ;; or (javascript! ($query* "s"))
The definition of javascript!
will roughly look like the following:
(define (javascript! (scripts ($query "s")) #:base (base (current-directory)))
(http-client-response->response
(make-http-client-response "1.1"
200
"OK"
'(("Content-Type" . "text/javascript; charset=utf-8"))
(apply javascript-loader #:base base
scripts)) ;; this is a mismatch
(lambda (x) x)))
And we encounter our first mismatch - our original loader was a closure over the base path. While we can still create the closure as previously designed, the closure is wasted since we are not keeping it around. It's simpler to have a new interface that takes in the base path - and we'll take the opportunity to refactor the code a bit:
(define (yui-compress! path min-path)
(system (string-join
(list "java"
"-jar"
(path->string (build-path (this-expression-source-directory)
"yuicompressor.jar"))
"-o" (path->string min-path) (path->string path))
" ")))
(define (open-javascript-files paths (compress! yui-compress!))
(define (min-path-helper path)
(string->path (string-append (path->string path) ".min")))
(define (helper path)
(let ((min-path (min-path-helper path)))
(when (or (not (file-exists? min-path))
(> (file-or-directory-modify-seconds path)
(file-or-directory-modify-seconds min-path)))
(compress! path min-path))
(open-input-file min-path)))
(apply input-port-append #t (map helper paths)))
(define (open-javascript-files/base base paths (compress! yui-compress!))
(define (helper path)
(build-path base path))
(open-javascript-files (map helper paths) compress!))
Now yui-compress!
is extracted from the loader, and two versions of the loader are exposed: open-javascript-files
and open-javascript-files/base
, which takes in an additional base
argument. And they both take in an optional compress!
argument that you can use to switch out yui-compress!
if you want to use another javascript compressor.Now the
javascript!
handler would look like:
;; the javascript! loader will depend on a having a paticular setting
(define (javascript! (scripts ($query* "s")) (base (current-directory)))
(raise
(http-client-response->response
(make-http-client-response "1.1"
200
"OK"
'(("Content-Type" . "text/javascript; charset=utf-8"))
(open-javascript-files/base scripts base)
(lambda (x) x)))))
And we now can add the module (we are calling this bzlib/jsmgr/shp
) to our SHP instance:
;; required.shp
(require (planet bzlib/jsmgr/shp))
And the
script.shp
should contain the following:
;; script.shp
(javascript! #:base "some-path-here...")
Testing it out give us a cryptic error:
Exception
The application raised an exception with the message:
open-input-file: cannot open input file: "../collects/planet/main.ss" (The system cannot find the file specified.; errno=2)
Although the error is cryptic, we know it arises from our SHP handler's
require-modules!
procedure. It turns out that because the procedure calls flatten
, we have flattened (planet bzlib/jsmgr)
into two separate collections and hence caused the error. Below fixes the error:
(define (require-modules! terms)
(define (require! module)
(namespace-require module))
(define (helper listof-modules)
(parameterize ((current-namespace handler-namespace))
(for-each (lambda (modules)
(for-each require! modules))
listof-modules)))
(helper (map cdr (filter require-exp? terms))))
Now the Javascript Manager is available through SHP.
No comments:
Post a Comment