I think that separating out dispatch so we have clear semantics for  
what URLs mean and what state exists at different points in the  
pipeine is essential to cleaning up the conceptual model that users  
need to internalize.

Much of the following discussion may overlap with recent features or  
existing features, which is all to the good.  I'm trying to create a  
single coherent model that is easy to think about, addresses the  
common confusions/complexities I've been encountering, and is not too  
different from the existing system.

My pipeline upgrade proposal:

State: ORIGINAL TREE

1) Actions side effect DB and widget state on the current tree.  This  
includes invoking flows on specific widgets within the current  
hierarchy.

State: ORIGINAL TREE MODIFIED BY FLOWS w/ DB and WIDGET SIDE EFFECTS

2) Dispatching updates the state of the widget tree from the URL  
including navs, etc.  Perhaps some hooks here for extracting  
parameters and applying them to widgets in a transparent manner.   
Dispatching is skipped during AJAX calls.

State: NEW TREE w/ WIDGET SIDE EFFECTS.

3) Rendering the tree.  Should be a simple static operation based on  
the state of the widget hierarchy.

State: NEW TREE (rendered)

Trees must have a fully connected parent/child hierarchy so we can  
find the appropriate dispatchers.  If we have multiple child  
dispatchers, the dispatch routine will simply catch mapping failures  
and try the other path.  It's more flexible, but of course you can get  
yourself into trouble if you have name conflicts at a given level of  
the dispatcher hierarchy...

However, we can easily create a routine to dump the entire dispatching  
tree/namespace to a text file or to graphviz!

===========================

Problem: Flows conflicting with URLs.  Managing a mapping of URL to  
tree state can easily conflict with flows invoked on a given state of  
the tree.  Flows that happen higher in the hierarchy fail due to  
failing to handle tokens of a given URL.

Solution 1: Default flows insert a dispatcher widget around the root  
of the flow.  If there is an error in dispatch, it can, by a global or  
local policy, simply consume the offending tokens.

Solution 2: Make it easy to do an action-link where you link to a URL  
and also perform an action so after the flow is placed into the tree,  
the result tokens line up with it.  Further, the call/answer protocol  
can remember the old URL, so you can redirect on an answer.  This  
would be an optional facility as it requires thinking carefully about  
namespaces.

============================

Problem: Long distance connection of widgets in the tree.  I have a  
whole set of hacks I've been playing with that connect one widget to  
another (build tree with slot reference, have a naming scheme that  
searches the widget tree under some 'workspace' widget which resolves  
names, etc.  This is a general version of the navigation/menu  
separation problem.

Solution 1: Explicit namespace, not unlike HTML (class = class, name =  
id).  Widgets can have a global name that is added to a lookup table  
to get to that element (like IDs in HTML).  You can simply say (get- 
widget 'name) to get a reference to that widget.  This allows us to be  
agnostic to changes and avoid all the complex linking hacks I've been  
using.

Solution 2: Support for searching the tree for paths, class instances,  
etc.  Probably too general...

Implications:

The new navigation element falls out of this model as two objects:  
selector and dispatch-container.  The selector object simply keeps a  
reference to a dispatch-container which only renders one sub-widget at  
a time based on the URL state.  The selector object renders a menu  
that computes URL links to the dispatch-container's state via method  
described below.  When the dispatch-container updates it's state in  
response to the URL, it can call a callback (or you can have a  
subclass with a slot) to update the menu object in the URL rendering  
pipeline.

============================

Problem: Generating a URL link to a new configuration of the tree  
(e.g. generating friendly URLs from one subtree that points to another  
tree state).

Solution: This falls out nicely from the namespace solution.  (link-to- 
widget name/ref &rest params) => URL that links to that widget state +  
arguments for sub-state.  The arguments to this function are keywords  
that are processed by the target widget which generates the rest of  
the URL for you (mapping keywords to path tokens and/or uri  
parameters).  Only widgets implementing the dispatch interface can be  
linked to.

=============================

Problem: Conflation of dispatching elements and structural elements  
(like the dispatch-container above).  The current navigation element  
is simply a way of specifying sub-tree structure based on URLs.  We  
should be able to do this from the widget hierarchy or in the  
traditional table-like fashion.

I thought about a separate 'controller-like' interface which separates  
dispatchers out as instances with references to things like  
containers, etc but I can't think of a big win that justifies the  
increased complexity.

My opinion is that the dispatcher maintains a simple interface which  
does the following:

- Turns URLs into widget state (basically what it does now)
- Generates URLs to widget state by calling 'generate' url on it's  
parent dispatcher (recursively) and then adding its own tokens based  
on the argument list

This enables a variety of models: you can have a global URL->state  
model simply by having a master dispatcher at the root which maps all  
URLs explicitly to widget state (user-designed, no significant support  
from weblocks).

For example, I can have a dispatcher that kept a list of singleton  
widgets (blog archive, blog view, blog cover).  The dispatcher looks  
at the url and returns one of the singletons with its internal state  
appropriately updated to reflect the parameters of the URL.  It's easy  
to write a little regex dispatch routine that is django-like.  widgets  
= pages, URLs map to widgets + arguments.  The current ephemeral  
widget model basically support this, but we could create a wrapper  
which makes this trivial to implement, giving people a comfortable  
page-oriented metaphor to fall back on in when they don't need all the  
ajax/application logic.  Ephemeral widgets, of course, can't have  
state so the linking happens at the level of the dispatcher for, in  
this case, the blog app + args.

============================

Problem: Flow on generic 'places' and dispatchers

The flow-wrapper is implemented as a simple dispatcher that does  
nothing except on an error condition (we should create an explicit  
condition for invalid URL mapping).  I think that the current model of  
enabling flows in any 'place' that widgets can reside is fine This is  
the reason for the funny API Leslie asked about the other day (make- 
widget-place-writer).  I sometimes have object that renders widgets  
from slots rather than from containers so I don't have container  
objects and the resulting divs everywhere.  When I want to do a flow  
on a slot, all that object has to do is implement make-widget-place- 
writer which maps a (do-widget old new ) request to the old object  
place and updates that place with the new widget and a continuation to  
replace that state later.

(FYI - we should have a silent-container object which doesn't generate  
a div, but just writes its objects inline...)

=============================

I think that captures most of the complexity/problems I've had with  
flows, URLs, hierarchies, etc.  Any other major areas people think I'm  
missing?  Any truly negative reactions to the above proposals (or  
observations about holes?)


Getting this done:

- I will volunteer, given a clean -dev tree to fork from or sync to,  
to rewrite the dispatching/URL logic and the flow wrapper.  (I think/ 
hope it's only 2-3 days).  However, my time is extremely tight  
(ongoing PhD general exams on a horribly accelerated schedule), so  
I'll need others to volunteer for some or all of the following before  
I commit.

- Create the new navigation model (if necessary) including one that is  
backward compatible with modern-dispatching. (Jan?)

- Help with some updating/expanding the tests (Leslie/Yarek - you're  
already up to speed here)

- Utilities:
   - Dump the complete URL static namespace along with parameters names
     / - blog - front
              - detail <article>
              - archive <year> <month> <day>
              -
       - news
       - about
   - Routine to dump/inspect the dispatch hierarchy (full tree, a  
particular path)
     for example, a graphviz output.
   - Identify flows that are active in the hierarchy
   - Easy debugging tools
        - Get a reference to an object or a path/list of dispatcher objects  
from *last-session* based on a URL or via a widget name

- Integration
        - At least two people who volunteer to update their systems to the  
new model to work out the bugs and document an upgrade procedure.

- Examples of the new model
        - A URL mapping implementation of a blog (?)
        - A simple workspace object where a sidebar element can easily update  
a main widget using the naming mechanism.  We can also do a flow+link  
demo here if someone can think of a good example (Jan?)

- Documentation
        I can hack up a conceptual introduction that builds from Slava's  
original blog articles that tries to frame the model.  I'll need help/ 
backup to expand and complete this.


I think we should attack this as a 'sprint' style effort where a core  
group gets together on a roughly planned schedule over a weekend via  
IM and e-mail and just gets the bulk of this done and a few others  
upgrade their existing systems to integrate the new functionality.   I  
can dedicate a Friday/Saturday to the first pass on Dec. 19th/20th  
with clean up on the 22nd.  This presumes there exists a stable -dev  
tree that I can update my current system to by mid next week.  I'm  
almost certain I will be unable to dedicate any time to this after the  
end of December.

I'm very open to suggestions and revisions, but this is my 2^8 cents  
on the matter.

Cheers,
Ian



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