Right now I feel lost. I see a bunch of code already written but I have no idea why this or that exists. It feels incomprehensible and overengineered but what do I know, it might be ingenious given the enormity of the task that I have no idea about.

Comments

Crell’s picture

Better documenting the flow within the system is on my todo list, as soon as the logic in it stops changing. :-) I think at the moment #1261156-32: what does butler return when something is not there? and following is the last major change there outstanding.

chx’s picture

I am not quite interested in the implementation internals, I am interested on what are we doing here which became so very complicated.

Crell’s picture

Assigned: Unassigned » Crell

Assigning to me to write something up during this sprint cycle.

chx’s picture

Consider the case where the request URL is foo/bar?stuff=things

Now, the bottom-most context object A has a handler bound to 'http:query' that is responsible for returning the query data. There is also another context object B stacked on top of it that does not change anything about the http information.

A caller now requests http:query:stuff. The logic is as follows:

Object B: Is there a value at http:query:stuff? No
Object B: Is there a handler at http:query:stuff? No
Object B: Is there a value at http:query? No
Object B: Is there a handler at http:query? No
Object B: Is there a value at http? No
Object B: Is there a handler at http? No
Object A: Is there a value at http:query:stuff? No
Object A: Is there a handler at http:query:stuff? No
Object A: Is there a value at http:query? No
Object A: Is there a handler at http:query? Yes!
Ojbect A: Call the handler, get back "things". Save that value to http:query:stuff, then return it.
Object B: Cache "things" to http:query:stuff here, too. Return it to the caller.

The reason for this kind of stacking is

Unit testing. Sure, this can also be done with passing in a brand new context object, and that's totally supported as well.

Context-sensitive sub-logic. Eg, nested panels panes. In which, for instance, you may want to change the node that a given block/pane sees but you do not want to change the current-user object. In that case, the pass-through stacking allows you to take "your" context object, make a new one, change the node on it, and then pass it on. The next block you call now has access to the node you specified, and to the current active user, and the current language, and all GET parameters, etc. And you don't have to do any work beyond changing the one node value you cared about.

Crell’s picture

Documentation has been added here: http://drupal.org/node/1292720

I'm leaving this issue open to discuss further improvements to it.

moshe weitzman’s picture

i think it would help to be clearer about being passed context (ideal) versus the shim way which is to call out to drupal_get_context(). the only example shown is the shim

Crell’s picture

I've added an example of an OO approach. Note that the namespace "use" directive is broken due to an issue with the code formatter. I'll file an issue for that.

webchick’s picture

Project: WSCCI » Drupal core
Version: » 8.x-dev
Component: Code » wscci

Per catch, and blessed by Larry, moving this and all other WSCCI issues to the Drupal core queue.

chx’s picture

Please add something about why do we need

Object B: Is there a value at http:query:stuff? No
Object B: Is there a handler at http:query:stuff? No
Object B: Is there a value at http:query? No
Object B: Is there a handler at http:query? No

all this. Can't we get away with allowing handlers only on the first level? Where are we using a handler on the second, third etc levels?

Crell’s picture

Status: Active » Closed (won't fix)

No longer relevant.