Rationale: I am not happy with the current navigation system and I think the one that landed in modern-dispatching is unnecessarily complex and hard to understand and maintain.
Here are my thoughts on how I think navigation should work. Please also take a look at the figure at: http://screech.rychter.com/files/weblocks-new-nav-design-20081210.pdf Comments are very, very welcome. In particular, if you find anything is hard to understand, does not make sense, or (most importantly) if your application won't fit in it, I'd like to know. I read Ian's post in detail and I agree with what he said to an amazing extent, with a few small exceptions (mostly noted below in the design notes). I intend to implement whatever results in the next few days. --J. General notes: I think the initial dispatcher/selector naming was right-on, we just got confused later. What I'm describing is mostly about separation of concerns, I've kept the naming, because it fits perfectly. I haven't addressed actions and flows at all -- but I believe that is an orthogonal problem and we need to get navigation sorted out first. I do not believe we should strive for URLs to reflect the current widget hierarchy or state. I think the mapping should be restricted to URIs -> application entry points. You can't reflect the entire application state in an URI anyway, and nobody really expects that. You just want people to be able to pass on URLs to your sites so that they point to existing and known entry points (locations) in your application. ----------------------------------------------------------------------- Dispatcher is responsible for mapping from URIs to selector/pane pairs. Aside from its dispatching table, the dispatcher is stateless. It does not know what is currently selected. It does not maintain caches, it does not generate pages. It only dispatches. Dispatcher knows about URIs, selector objects and pane names (symbols). When an URI is matched, it calls the select-content method with the selector object and pane-name parameters. There can be multiple dispatchers in a widget tree and not all arrangements of dispatchers and selectors will make sense. Also, usually dispatchers will want to dispatch on a fixed number of URI tokens, but that is not enforced. Dispatchers should have multiple strategies -- simple string matching, regexp matching and wildcard matches come to mind. When thinking of dispatch strategies, keep in mind that we do not want to extract parameters here, we only dispatch to a particular selector with a particular pane-name that it registered with us. For wildcard matches, we pass on the uri-token that was matched as the pane-name. It is the selector's job to understand this. ----------------------------------------------------------------------- Selector is a container that can select particular content based on a name (pane name). The selector has state: it knows what is currently selected. That state can be updated either by the dispatcher (when someone lands via an URL) or by any other widget (e.g. from actions). That makes the selector useful also for some AJAX work, even without involving the dispatcher. Selectors need to be registered with Dispatchers. When registered, the Dispatcher remembers the URI->selector/pane-name mappings. Dispatcher references Selector objects directly. I do not think there is a need to introduce another naming scheme, when we have a perfectly valid widget tree. ----------------------------------------------------------------------- Dynamic Selector is a Selector that implements a dynamic content creation strategy. It creates widgets on demand, and usually gets registered with a dispatcher using a wildcard URI match. The "widget cache" belongs in the dynamic selector, not in the dispatcher. ----------------------------------------------------------------------- Navigation Content is a Selector specifically designed for being navigated from a Menu. ----------------------------------------------------------------------- Navigation Menu is both a Dispatcher and a Selector. Dispatcher, because it reacts to URIs and changes other widgets' state based on URIs. Selector, because it has to update its own state to highlight the currently selected menu item. ----------------------------------------------------------------------- Navigation is a Navigation Menu that also contains Navigation Content. It *is* a Navigation Menu because it needs to be placed in the widget hierarchy (because of dispatching), but it contains its content, because of the loose relation between dispatchers and selectors. If you just use Navigation objects, you can forget about the whole Dispatcher/Selector separation of concerns business. ----------------------------------------------------------------------- The scheme, as described, lets you address the following scenarios: dynamic URLs (wiki): dispatcher does not create any content, it only dispatches a wildcard token (or multiple tokens) to a dynamic-selector. It is the dynamic-selector's job to actually create content, maintain a cache, and select it. user-interface/admin-interface: the main dispatcher object knows about the user navigation (registered by the user navigation selector) and the "/admin" URI registered by the admin interface selector. The admin interface selector is placed (normally invisible) above the user-interface navigation content in the widget tree. This means that the admin interface selector can "choose" whether to render the user interface or the admin interface, based on updates from the dispatcher, or (in the future) based on updates from an action. multi-level navigation: you can have multiple dispatchers in a widget tree. For convenience, there will be a register-with-nearest-dispatcher method that will walk up the tree, find the closest dispatcher object and register there. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
