[hunchentoot-devel] Re: Boolean Form Fields
Volkan YAZICI
yazicivo at ttnet.net.tr
Sat Apr 28 18:23:55 UTC 2007
Volkan YAZICI <yazicivo at ttnet.net.tr> writes:
> Sorry, above assertion is mistaken. Hunchentoot returns T for boolean
> in all cases whenever auth-res exists in the GET parameters
> list. Therefore, it's not possible to make a distinction between a NIL
> (which means false) boolean parameter that is supplied and a parameter
> that isn't even supplied. (Please correct me if I'm wrong.)
To clarify what I try to mean, here's an example:
(define-easy-handler (auth :uri "/auth")
((result :parameter-type 'boolean :request-type :get))
(with-html
(if result
(htm (:p "Authentication succeeded."))
(htm (:p "Authentication failed!")))
(:p "Welcome!")))
Try this handler with "/auth?result=", "/auth?result=nil" URIs. In
each case, RESULT will return T. So how can I tell /auth that I tried
to authenticate the client but it's failed? (You may say that, just
don't pass the `result' argument to URI. But that's not same as
passing a boolean type of argument with NIL/FALSE value.)
Here is my suggestion for this:
<patch>
--- /tmp/easy-handlers.lisp 2007-04-28 20:56:57.000000000 +0300
+++ easy-handlers.lisp 2007-04-28 20:51:29.000000000 +0300
@@ -52,7 +52,8 @@
(char argument 0)))
(integer (ignore-errors (parse-integer argument :junk-allowed t)))
(keyword (make-keyword argument :destructivep nil))
- (boolean t)
+ (boolean (not (or (string= argument "")
+ (string= (string-upcase argument) "NIL"))))
(otherwise (funcall type argument))))
(defun compute-simple-parameter (parameter-name type parameter-reader)
</patch>
And, after that long discussion, I solved my problem again on my own:
(defmacro with-form-fields ((&key (default-parameter-type ''string)
(default-request-type :both))
(&rest fields) &body body)
"Process specified lambda list similar to DEFINE-EASY-HANDLER.
You can also use :EXISTS-P keyword to specify an extra parameter
to ensure that the value is supplied in the request URI."
`(let
;; Collect appropriate LET bindings for supplied fields.
,(nconc
(loop for field in fields
collect (hunchentoot::make-defun-parameter
(if (listp field)
(cons (first field) (delf (rest field) :exists-p))
field)
default-parameter-type
default-request-type))
;; Collect :exists-p keyword variables.
(loop for field in fields
when (and (listp field) (getf (rest field) :exists-p))
collect (getf (rest field) :exists-p)))
;; Process :exists-p keywords.
,(with-gensyms (get-params post-params both-params)
`(let* ((,get-params (get-parameters))
(,post-params (post-parameters))
(,both-params (nconc ,get-params ,post-params)))
(declare (ignorable ,get-params))
(declare (ignorable ,post-params))
(declare (ignorable ,both-params))
,@(loop for field in fields
when (and (listp field) (getf (rest field) :exists-p))
collect
`(setq
,(getf (rest field) :exists-p)
(if (rest
(assoc
(string-downcase (symbol-name (quote ,(first field))))
,(ecase (or (getf (rest field) :request-type)
default-request-type)
(:get get-params)
(:post post-params)
(:both both-params))
:test #'string=))
t)))))
, at body))
Try to run above same handler example with below code.
(with-form-fields ()
((result :parameter-type 'boolean
:request-type :get
:exists-p result-exists-p))
(with-html
(when (and result-exists-p (not result))
(htm (:p "Authentication failed!")))
(when result
(htm (:p "Authentication succeeded.")))
(:p "Welcome!")))
Excuse me if I disturb you with my own problems. Looks like everyone
is comfortable with undetermined boolean values.
Regards.
More information about the Tbnl-devel
mailing list