Hi,
How do you use boolean type variables with DEFINE-EASY-HANDLER? (Or more generally how do you gather the results of boolean form fields?) Because, DEFINE-EASY-HANDLER binds related variable to nil even it doesn't exist. Therefore, it becomes impossible to learn if the parameter is supplied and its value is nil, or the parameter doesn't supplied within the request.
Regards.
On Sat, 28 Apr 2007 00:13:33 +0300, Volkan YAZICI yazicivo@ttnet.net.tr wrote:
How do you use boolean type variables with DEFINE-EASY-HANDLER?
Usually with checkboxes. There's an example in the demo that comes with Hunchentoot.
Edi Weitz edi@agharta.de writes:
How do you use boolean type variables with DEFINE-EASY-HANDLER?
Usually with checkboxes. There's an example in the demo that comes with Hunchentoot.
Yep, I have read test.lisp. But wouldn't it be better if we have some kind of exists-p key (as an available key in D-E-H lambda list, or returned by GET-PARAMETER and POST-PARAMETER) instead of using a hash table just for a single boolean?
Regards.
On Sat, 28 Apr 2007 01:21:58 +0300, Volkan YAZICI yazicivo@ttnet.net.tr wrote:
Yep, I have read test.lisp. But wouldn't it be better if we have some kind of exists-p key (as an available key in D-E-H lambda list, or returned by GET-PARAMETER and POST-PARAMETER) instead of using a hash table just for a single boolean?
I don't understand that question. There's a hash table in the demo because there are several checkboxes grouped together. If you only have one checkbox, you can of course just use 'BOOLEAN.
Edi Weitz edi@agharta.de writes:
On Sat, 28 Apr 2007 01:21:58 +0300, Volkan YAZICI yazicivo@ttnet.net.tr wrote: I don't understand that question. There's a hash table in the demo because there are several checkboxes grouped together. If you only have one checkbox, you can of course just use 'BOOLEAN.
If I'd use 'BOOLEAN, how can I know when the value of a boolean is NIL and when a boolean isn't supplied?
Consider (foo :parameter-type :boolean :request-type :get) example. Both "foo.html" and "foo.html?foo=" returns NIL for FOO variable. IMHO, for the formal case, there should be an exist-p switch.
Regards.
On Sat, 28 Apr 2007 02:01:30 +0300, Volkan YAZICI yazicivo@ttnet.net.tr wrote:
If I'd use 'BOOLEAN, how can I know when the value of a boolean is NIL and when a boolean isn't supplied?
Consider (foo :parameter-type :boolean :request-type :get) example. Both "foo.html" and "foo.html?foo=" returns NIL for FOO variable. IMHO, for the formal case, there should be an exist-p switch.
Which browser sends requests that look like "foo.html?foo="?
Edi Weitz edi@agharta.de writes:
Which browser sends requests that look like "foo.html?foo="?
Consider I want to redirect client to auth.html with auth-res boolean parameter turned on. What should I pass as the URI? If I use "?auth-res=NIL" or "?auth-res=0", both of them returns T, because neither "NIL", nor "0" is NIL. Hence, I prefer to use "?auth-res=" But in this case, I cannot know if the boolean parameter is supplied and it's value is NIL, or the parameter isn't even supplied. (Because, in both situations it returns NIL.)
I can cope with this problem, by making an extra (assoc 'auth-res (get-parameters)) probe everytime I need that verbosity. But wouldn't it be better just to specify a ":exist-p auth-res-exist-p" option in the lambda list of D-E-H.
Regards.
Volkan YAZICI yazicivo@ttnet.net.tr writes:
Edi Weitz edi@agharta.de writes:
Which browser sends requests that look like "foo.html?foo="?
Consider I want to redirect client to auth.html with auth-res boolean parameter turned on. What should I pass as the URI? If I use "?auth-res=NIL" or "?auth-res=0", both of them returns T, because neither "NIL", nor "0" is NIL. Hence, I prefer to use "?auth-res=" But in this case, I cannot know if the boolean parameter is supplied and it's value is NIL, or the parameter isn't even supplied. (Because, in both situations it returns NIL.)
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.)
Regards.
Lispworks 5.02, WinXP
Everything working in the listener:
| (postmodern:with-connection ("web_access" | "web_access" | "xxx" | "localhost") | (postmodern:query | "select * from merkmale limit 10")) | (("g5p7327541ptj4diy19363553jh3yx " | "de" | "5yt732754w29gt8xhve36355ormaci | ... | 70 | " . hohe Kontaktsicherheit bei niedrigen Strömen " | .......^.........................................^ | ...
But the same thing in the web using an easy-handler
| (define-easy-handler (test :uri (prefixed "test"))() | (with-html-output-to-string (out) | (postmodern:with-connection ("web_access" | "web_access" | "xxx" | "localhost") | (htm | (:html (:head (:title "Testpage")) | (:body (:p (fmt "~a" | (postmodern:query | "select * from merkmale limit 10")))))))))
works fine unless higher unicode characters are involved.
Empty page in the browser then, no error. Simply a blank page.
-jens
On Mon, 30 Apr 2007 13:41:00 +0200, "Jens Teich" info@jensteich.de wrote:
But the same thing in the web using an easy-handler
| (define-easy-handler (test :uri (prefixed "test"))() | (with-html-output-to-string (out) | (postmodern:with-connection ("web_access" | "web_access" | "xxx" | "localhost") | (htm | (:html (:head (:title "Testpage")) | (:body (:p (fmt "~a" | (postmodern:query | "select * from merkmale limit 10")))))))))
Where do you set the content type header?
works fine unless higher unicode characters are involved.
Empty page in the browser then, no error. Simply a blank page.
Log file? Did you try *CATCH-ERRORS-P*?
Volkan YAZICI yazicivo@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))))) ,@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.
Excuse me if I disturb you with my own problems. Looks like everyone is comfortable with undetermined boolean values.
Is it just me or there is no way to tell if the "checkbox was in the form and was not checked" vs "checkbox was not present in the form", browsers give identical requests in both cases. Most of the web frameworks I have seen seem to add a hidden field for such checkboxes that indicates whether there was a checkbox in the form being submitted. Which I am afraid you can only do on your own with hunchentoot.
Ignas
On Sun, 29 Apr, 2007 at 21:24:00 +0300, Ignas Mikalajunas wrote:
Is it just me or there is no way to tell if the "checkbox was in the form and was not checked" vs "checkbox was not present in the form", browsers give identical requests in both cases.
http://www.w3.org/TR/PR-html40-971107/interact/forms.html#h-17.8.2
For INPUT elements with type="radio" or type="checkbox", and SELECT elements, only the selected values should be submitted.
-- Registered Linux User #124759
On Sat, 28 Apr 2007 21:23:55 +0300, Volkan YAZICI yazicivo@ttnet.net.tr wrote:
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.)
Sorry for the delay. My take is that the BOOLEAN parameter type of DEFINE-EASY-HANDLERS was made to work with checkboxes and such as submitted by browsers. I agree that it can't work with arbitrary ways to pass GET parameters, but that's similar to the problem in databases where in addition to "true" and "false" you also have a "NULL" value.
I'd prefer not to change the existing code, but I'm prepared to be overruled if several users think it should be changed and come up with a reasonable alternative.