On Jan 31, 11:21 am, Slobodan Milnović <[email protected]>
wrote:
> On Mon, Jan 31, 2011 at 10:27, Leslie P. Polzer <[email protected]> 
> wrote:
>
> > What do you think is the best way to proceed with this?
>
> I understand that I'm probably pain in the ass,

Haha, no. It's good that you're asking questions.

But we need to find a way to make your learning process as effective
as possible, so I'm trying not to just feed you customized code. And
that seems to be your goal as well.


> I'd really like to understand what is happening in your example and
> why. :-) For starters, I still don't understand why I can't use
> default login and navigation widgets that come with weblocks?

Because out of the box the login widget relies on a flow which in turn
triggers a navigation-related issue (which I've talked about in length
somewhere else).


> If you don't mind, I'd like to dissect your example, so that I can try
> to understand it better...
>
> (defwidget protected-navigation (lazy-navigation)
>   ((user-fn :type (or symbol function)
>             :accessor user-fn
>             :initarg :user-fn
>             :initform #'authenticatedp)
>    (login-widget :type (or widget null)
>                  :accessor login-widget
>                  :initform nil)
>    (login-widget-generator :type (or symbol function)
>                            :accessor login-widget-generator
>                            :initarg :login-widget-generator
>                            :initform (f0 (make-instance 'login))))
>   (:documentation "Lazy navigation that checks whether
> the user (as per USER-FN) is logged in. If they are then
> this widget acts as a normal lazy navigation. If not then
> the widget in the `login-widget' slot is shown or created
> by calling LOGIN-WIDGET-GENERATOR."))
>
> Ok, so :user-fn by default receives an result from authenticatedp. In
> that case, I don't understand why in your example have you used (f0
> (webapp-session-value 'user)), why would you have to set up additional
> key in webapp-session-value?

There's no setter pendant for authenticatedp. So to make sure that the
example works I rely on my own. I should probably use
weblocks:*authentication-key* instead. But in the end this seems to be
a moot point for a simple example.


> :login-widget defines what widget will be used for login? Do I put in
> there something like
> :initform 'login
> or my login widget that has my parameters (username instead of e-mail
> as the login slot)?

None of it. As a user of this class you don't need to set this slot at
all. It's just for storing the login widget after it has been created.
We could also store it in the children slot to make it a bit more
intuitive. So it's just for keeping state.


> If I do that, then I guess I could put
> login-widget-generator :initform nil ?

No, you want to write your own generator function that returns your
custom login widget. It will be called to initialize the `login-
widget' slot for the first time.


> I don't get exact specifics, but I do get that "get-widget-for-tokens"
> parses uri. I don't know why you need it, but ok.

We need it to get the actual widget that we display after the user has
been authenticated.


> (defmethod render-navigation-menu ((navigation protected-navigation) &rest 
> args)
>   (declare (ignorable args))
>   (when (funcall (user-fn navigation))
>     (call-next-method)))
>
> Ok, let's say that I do understand that this method will be called if
> the widget passed to render-navigation-menu is protected-navigation
> widget.

Yes, and it's there because we don't want to show any menu when the
user hasn't been authenticated yet. You might want to show a different
menu or indeed show the normal menu.


> Like I said before, I still don't understand the need for
> redefining navigation widget.

The flow explanation I've already given, but there's another reason.
This way of doing login is way more intuitive actually because it
works in the line of the URI dispatch. You can just think of it as a
guard that says "What's the password?" before it gives access to the
actual widget tree (as determined by navigation dispatch) behind it.
With the additional convenience that the guard remembers your face
after you've given it the password once (for the duration of the
session). I hope this analogy helps you a bit to understand how this
works.


> (defun init-user-session (root)
>   (setf (widget-children root)
>         (list
>           (make-widget (f_% (with-html (:p (esc (format nil "Current
> user: ~S" (webapp-session-value 'user)))))))
>           (make-navigation "Main nav"
>                                (list "hello" (make-widget "Hello, world"))
>                                :navigation-class 'protected-navigation
>                                :extra-args `(:user-fn
>                                                ,(f0
> (webapp-session-value 'user))
>                                              :login-widget-generator
>                                                ,(f0
>                                                   (make-widget
>                                                     (f_%
>                                                       (render-link
>                                                         (f_% (setf
> (webapp-session-value 'user) t)
>                                                              (redirect
> "/" :defer nil))
>                                                         "Login")))))))))
>
> Now, this one... I really don't understand what is going on here.
> Well, I do kind of, but I don't understand how can I modify it for my
> purposes. Why redefining :user-fn if in the widget you already have
> authenticatedp?

See above.


> login-widget-generator - create function that creates
> an widget that receives function that renders link,

That's not entirely correct. Try again to understand this bit. Read
about every function involved.


> and when that link
> is clicked, the user is set to t, so that the something,
> protected-navigation knows that it is authenticated.

Yes!


> I have tried
> putting there my login widget, but there is an lack of understanding
> on my side, so it doesn't work...

How did you try to put it there? I suppose the problem is your
misunderstanding about the `login-widget' slot, as explained above.


> > Does something keep you from debugging the problems you're seeing?
>
> I have managed to redirect backtrace into slime, which makes things
> easier when there is an backtrace. I'm about to implement logging into
> an file, because when I get an empty white web page, or an message
> that there is too much redirection, there is not much to be debugged
> from.

You can still trace functions. For redirect loops it's less obvious;
tracing helps but you also need to follow the code in your head to
understand why it loops.

See also hunchentoot:*catch-errors-p*.


> I don't know yet how to debug or at least do a step trace into
> sbcl threads.

Hint: #'sb-thread:release-foreground.

-- 
You received this message because you are subscribed to the Google Groups 
"weblocks" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/weblocks?hl=en.

Reply via email to