[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