Just some updates to the earlier post.
As I mentioned, if you want to do model validation with Weblocks, you currently have to write it yourself. But the choice of method to specialize was sub-optimal. Ideally you would want your model to be validated no matter how you were modifying it, say with a gridedit or a dataform. So instead of hijacking dataform-submit-action, I should really have created an around method for update-object-from-request. This is below:
(defmethod weblocks:update-object-from-request :around ((data create-login)
(multiple-value-bind (success failed-slots)
(values success failed-slots))))
validate-new-login will return multiple values in the same manner as the generic update-object-from-request: a boolean value indicating success and a list of errors, if failure was indicated. It looks like this:
(defun validate-new-login (new-login)
"If the Weblocks validation succeeds, then all required values
are already there, so we only need to check the consistency. Returns
(values success errors) where success is t if there were no errors otherwise
success is nil and errors is an association list of (slot . error)"
(equal (password new-login)
"Both passwords must match!")
(values (null errors) errors)))
And validate-slot is an extremely unhygienic macro that looks like:
(defmacro validate-slot (slot-name
(push (cons (attributize-name ,slot-name)
Pretend you didn't see it.
Which brings me to my next update. Weblocks nicely renders all the errors for you. Unfortunately, I made that part really difficult. Previously, my use of continuations would always create a new dataform which would then not show any errors that needed to be displayed. Since the continuations are stored in the widgets themselves, I should have just yielded the dataform widget itself and be done with it:
(defun setup-admin-password ()
:data (make-instance 'create-login)
Have a good weekend!