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