>  dispatcher you proposed at http://github.com/nunb/resty-weblocgks/

That has now been updated to do a facsimile of what you wanted: a
dynamically expanding menu (it should probably have been done by
subclassing navigation though).

Adding to posts using /admin will change the "menu" at / to reflect
all posts .. there is also a sketch of code to implement a login only
for /admin ..

> When I just started with hunchentoot a while ago and wrote a little
> web site I had never had problems with displaying menu and making REST-
> style urls.

Weblocks tries to do "more than" REST style urls :-)

> I think Weblocks should give a user an easy way to get down to the
> hunchentoot dispatcher (maybe Weblocks already has it, I just couldn't

You can do this directly (but you probably shouldn't) [1]:

(push (hunchentoot-create-prefix-dispatcher "/custom-
url" (lambda ....)    hunchentoot:*dispatch-table*)
(push (hunchentoot-create-prefix-dispatcher "/another-custom-url"
#'some-fn  hunchentoot:*dispatch-table* )
(push (hunchentoot-create-regex-dispatcher "*foo?
bar*" (lambda ....)         hunchentoot:*dispatch-table*)

In fact weblocks creates a prefix-dispatcher for / in server.lisp

Explanatino for [1] --  This why you probably shouldn't use
hunchentoot dispatchers directly: if you are using weblocks to run
several webapps on 1 server, then even though it looks to the user
like he is using /, he's actually using /webapp1/ etc., so setting up
a hunchentoot-level handler for /custom-url/ when what you really need
is /webapp1/custom-url is asking for trouble. The selector class
abstracts this for you.

If your webapp-prefix is "/" then I guess it's not an issue. But I
have no clue if running a single webapp at / precludes you from
running others at /webapp2/ etc. (I guess it doesn't).

> figure it out) and map any widget to any url regular expression or
> function.

selector does this .. you can write a small macro to get the syntax
you want (eg, syntax similar to cond)

> I think that navigation control should be extended so that it would
> allow some kind of regex-url to widget mapping (or funcall-widget to
> widget mapping) and the ability to redraw itself based on the
> currently selected url.

But this is exactly what selector and on-demand-selector accomplish.
You can "match" the tokens however you want: by number --  /foo/bar/
baz is 3 tokens; or by type -- 2010/10/2 etc, or even by regex. In
addition they give you caching builtin etc. Some examples of "more
complex" matching were added to init-session.lisp on github.

>  funcall-widget to widget mapping

does not compute :-)

A funcall-widget is just a shorthand to create a widget and put its
rendering function (analogue of render-widget-body) inline -- it's
just a shortcut, the equivalent of closure-syntax like (lambda (&rest
args) ...) .

Finally, it is perfectly possible to build a weblocks site with url's
decided by hunchentoot dispatchers (with the caveat that you can only
run 1 webapp per weblocks instance) and use weblocks for the widgets
and render-link functionality. Someone correct me if I'm wrong!

We've built a completely RESTy app, and it works well, and fast :-)
That is to say our top level interface is REST, and then per-url
widgets are created, which in turn use ajax/single-window semantics.
We allow for file-uploads (but they're through the YUI file uploader,
and so we don't expose that URL) at different urls, /confirm/
confirmation-code etc.

Also consider that if you use selector, you have a great advantage
over hunchentoot-level dispatchers: different users will get different
"allowed-URL" policies. imho, this itself is worth the price of entry.
IOW an app built with "rails-routing" or similar is a hack-job, either
you have to authenticate/check at each url (wasting time/resources) or
you risk someone reverse engineering your URLs and getting say /list/
users to leak privileged info -- that's basically what all the fuss
about facebook photo id/user hacks was all about. With selectors you
can early-bind that decision and then not worry about it later.

Here's the code I use:


;;;; Widget tree setup
(defun make-main-page ()
  "Calls appropriate page based on type of logged in user"
  (unless (authenticatedp)
    (warn "User is not logged in")
    (logout-and-return-user) ;; resets session
    (redirect "/")
    (fill-template-widget "login-error")
    (return-from make-main-page))
  ;; (make-simple-message "Hello")
  ;;#+nomore
  (let ((widget (fill-template-widget "login-error")))
    (when (authenticatedp)
      (set-session-preferred-language)
      ;; (break "test")
      (setf widget
            (make-instance 'lagru-default-dispatcher
                           :default-widget
                           (ecase (user-type)
                             (adminsetup   (make-main-page-admin))
                             (co-agent     (make-main-page-agent))
                             (co-employee  (make-main-page-handler))
                             #+nomore(weblocks-group
                              ;; (make-main-page-agent)
                              (make-main-page-lagru))
                             (lagru-employee (make-main-page-
lagru))))))
    widget))

Each of the make-main-pages creates a different selector widget (some
don't even create a selector widget, they use a single-page
interface).

Before this stage is reached there is no question of url /foo/bar
leaking data because none of the selectors are set up yet in that
session. And after this fn. runs, while a user of type lagru-employee
may be able to access, say /clowns and /horses, a user of type say co-
agent will never be able to access those resources, the decision of
which resources are accessible in this session has been made.

Short version: stick with selectors, they're great :-)

-- 
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