For now, the handler should probably just replicate menu_get_object's functionality, more or less, but cleaned up to assume we're talking about a node.

Note that nodes as stdclass objects technically are not supported by context, but since we don't have the conversion of nodes to real classes yet we'll live with it for now so that we can make some progress.

Comments

fgm’s picture

Assigned: Unassigned » fgm

Working on it.

Current problem: menu_get_item() is invoked before the hook_init() implementations, but the hook_context_init() invocation happens in system_init(), which is one of the hook_init() implementations.

DjebbZ’s picture

fgm’s picture

Status: Active » Needs review
StatusFileSize
new0 bytes

First attempt..

fgm’s picture

Oopsie wrong git diff.

Crell’s picture

Status: Needs review » Needs work
+++ b/includes/theme.inc
@@ -2275,7 +2276,8 @@ function template_preprocess_page(&$variables) {
-  if ($node = menu_get_object()) {
+  $context = drupal_get_context();
+  if ($node = $context['menu:object:node']) {

As discussed at the code sprint, we don't want a context key that says that the node came from the menu. Ideally it should just be "node", since whether or not the node came from the menu system or not is irrelevant.

fgm’s picture

I've been working on it differently, but I have a problem setting the context: this works on butler D7, but not on the WSCCI sandbox.

What is happening is that when I addLayer() to add a new value before locking it, the new version of addLayer returns a tracker, and it is released at the end of the function adding it, causing the destructor to trigger, and remove the layer just added. Of course, going like this works around the problem:

$context = drupal_get_context().
$tracker = $context->addLayer();
// add value and lock
unset($tracker->context); // __destruct() checks whether context is set to delete it
return;

But this feels just silly, since the whole point of the added tracker, which was not present in butler, seems to be to remove added contexts.

The somehow-funny bit is that even just adding a dsm($tracker); will prevent php from unsetting it and make the code work, which is an unexpected side-effect.

Crell’s picture

I'm not sure why the behavior should be any different. Although I do need to do a bit of cleanup to ensure that the code is easier to keep in sync. Expect that this week.

But, the destructor behavior is desired. We want it to be impossible to modify the context "above" you in the call stack. What are you doing exactly that requires the node object to be overridden and for those overrides to propagate to the rest of the page?

fgm’s picture

This is when the loaders are being called in menu.inc: at this point, the loader for the leftmost wildcard in the page arguments loads an object from the db, and defines what will (in current drupal) be the result of menu_get_object(), i.e. the entity (node, user, taxonomy_term...) context which menu_get_object will return later.

So what I do it use this object while it has just been loaded, and push it to the context so that later references to $context[$entity] will trigger a getValue() that will only fetch values pushed once from the context definition point instead of going to pull them at the time of reference. Which seems to be the whole point of the mechanism in the first place: compute the context data initially, and just fetch them later, sure that they have not changed, instead of having to requery or access a cached result. Or am I misguided ?

fgm’s picture

Status: Needs work » Needs review
StatusFileSize
new9.19 KB

So here is a new version. It handles all current cases of menu_set_object() in core, not just menu_get_object('node'), and all unit tests I've checked pass

Still, I'm under the impression I'm doing things backwards, even though everything works.

Note that it applies on top of commit 3ebcfee, apparently not on top of the current head, the reason being that it uses module_invoke_all('entity_info'); which is not available after commit 39f6f3, which converts hook_context_init() to a bootstrap hook.

fgm’s picture

Assigned: fgm » Unassigned
Status: Needs review » Postponed

Postponed until the HTTP handling is in.

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.

DjebbZ’s picture

I tried to re-roll fgm's patch #10, but I encountered a problem. Basically, fgm told me that I only needed to change $context['node'] to $context->getValue('node'), and modify the paths in the patch file so it could apply. But there's a missing function : system_context_init() is not anymore in the system module. As I didn't follow wscii's development, I don't really know what replaced it. And fgm's comment #10 confuses me as it says hook_context_init() has been replaced, but as I see it in the code it stills exists...

Important, I tried to apply this patch against Crell's big merge patch #33 in #1233232: Add unified context system to core.

Crell’s picture

system_context_init() was removed because all of the handlers that were in there made more sense right in core. It will likely get added back later. I'm not 100% sure where the "current node" handler should go; possibly in the node module, actually. We may want to sit on that until the main patch goes in.

DjebbZ’s picture

Thanks for the explanation. We'll wait until the main patch goes in, it will be easier indeed.

Crell’s picture

Status: Postponed » Closed (won't fix)

No longer relevant.