When using a panelizer variant in page manager any contexts manually added to the variant are not actually usable by panelizer. So contexts that are added via an argument are available, but adding additional contexts, manually or via relationships, though they do show up as a target in the 'Panelized entity' select form, do not get used.

It partially resolves the issue to modify _panelizer_panelizer_task_get_context() in plugins/task_handlers/panelizer_node.inc:

function _panelizer_panelizer_task_get_context($handler, $contexts) {
  $contexts = ctools_context_handler_get_handler_contexts($contexts, $handler);

Which allows it to select the correct context to panelize from all the available contexts instead of just the base contexts.

The remaining issue is that those contexts are not passed through to the panelized page. Panelizer does have its own set of contexts, but it does not seem unreasonable to expect that contexts defined in page manager would also be available when using a panelizer variant.

Comments

merlinofchaos’s picture

Category: bug » feature

There really is no way to know if the page manager page that the panelizer might be used on will have extra contexts or not. Once you stipulate that, you're suddenly requiring knowledge of where the panelized entity might be used. Remember that the bulk of panelizer configuration is done away from Page Manager and has no knowledge of it. Just because you made a page and used the panelizer task handler, that has to get communicated back to panelizer. but what if you made another page, added the panelizer entity, and used different contexts?

The only way I can think to do it might be to allow 'required contexts' but that's going to get kind of ugly. The basic node_view template simply won't have any other contexts, so for 99% of users, the required contexts would become very confusing and hard to use.

This is absolutely not a bug.

gilgabar’s picture

Perhaps my explanation was not clear enough. There are two components to this issue. The first is that you can add contexts in page manager and they are selectable as panelized entities, but those entities are not actually available to panelizer because it currently only looks at the base contexts (e.g. arguments). So if you manually add a node context on a panelizer variant, that node shows up in the 'Panelized entity' select form. But then you get a 404 because that context is not available to panelizer. It will also use an argument context as the panelized entity instead if one is available. The code snippet above addresses that component of the issue. You may have a better solution, but that seems to be a pretty clear bug.

The second component, which I agree conceivably falls under the category of feature request, involves passing the page manager contexts through to panelizer. That may or may not be easy, but it seems like expected behavior, so it should at least be documented to prevent confusion.

gilgabar’s picture

Regarding the question of how to pass contexts from page manager to panelizer, the approach I am considering is as follows:

In PanelizerEntityDefault.class.php add an argument to render_entity() that accepts an array of extra contexts and then add those contexts to the display context:

function render_entity($entity, $args = array(), $address = NULL, $extra_contexts = array()) {
...
$display->context = $this->get_contexts($panelizer, $entity) + $extra_contexts;

So then it is possible in panelizer_node.inc in panelizer_panelizer_task_render() to pass the page manager contexts to panelizer:

$extra_contexts = ctools_context_handler_get_handler_contexts($base_contexts, $handler);
return $entity_handler->render_entity($context->data, $args, $address, $extra_contexts);

Some clean up to remove the panelizer context from the extra contexts would need to happen, but otherwise that appears to work. Thoughts?

merlinofchaos’s picture

That makes them there on render, but they're useless if they're not there on edit.

Editing the panelizer page is completely separated from the page manager page.

Panels Everywhere has the same problem -- you often want templates to inherit context from the inner content, and it's very difficult to do.

gilgabar’s picture

I suppose our use case is a bit non-standard, so contexts being present on edit is a non-issue for us. We are using lots of custom content types that use 'all contexts' => TRUE instead of required contexts, so they are able to be placed regardless of the presence of contexts on edit. Then it is up to the content type to pick from the available contexts and behave correctly if it is placed somewhere without the required context(s). That may not be a good solution for everyone, but it works in our situation.

merlinofchaos’s picture

Oh I see. That's interested. I hadn't considered that possibility.

Can you create a proper patch?

gilgabar’s picture

Status: Active » Needs review
StatusFileSize
new3.41 KB

Sure, patch is attached.

gilgabar’s picture

StatusFileSize
new3.85 KB

Forgot to save before I diffed. Here is a more complete patch.

merlinofchaos’s picture

+function _panelizer_panelizer_task_get_extra_contexts($handler, $base_contexts, $context) {
+  $extra_contexts = ctools_context_handler_get_handler_contexts($base_contexts, $handler);
+
+  // Prevent the panelized context from appearing again in the extra contexts.
+  foreach ($extra_contexts as $id => $extra_context) {
+    if ($extra_context->identifier == $context->identifier) {
+      unset($extra_contexts[$id]);
+    }
+  }
+
+  return $extra_contexts;
+}

I don't think relying on the identifier is a good way to do this. While it probably works in most cases, I worry it might not work in all. We need to think about a better way to figure out which of the contexts from Page Manager is the entity we're using. I think that in most cases, we actually have a setting that marks this in the current code. We should use that and make sure the setting is up to date -- I believe there is already code that tries to account for task handlers created prior to the setting existing.

gilgabar’s picture

Status: Needs review » Needs work

I agree about the identifiers, though I didn't see anything better, and it does appear to work so far. Could you be more specific about the "setting that marks this in the current code"? I'm not sure what you are referring to.

merlinofchaos’s picture

gilgabar’s picture

Status: Needs work » Needs review
StatusFileSize
new4.07 KB

Updated the panelized context filtering so that it just does the same thing as _panelizer_panelizer_task_get_context(). That should hopefully be a more robust way of handling that.

Also made a small change in panelizer_panelizer_task_test(). It was preventing things from working when $base_contexts is empty. Essentially it only worked if there was an argument context present. That was breaking use cases that involve adding a context manually and then panelizing that entity when you aren't also using an argument for something else. Instead of returning in the absence of a base context, the change loads the ctools context include, which doesn't appear to be otherwise loaded when there are no base contexts.

damienmckenna’s picture

Version: 7.x-2.x-dev » 7.x-3.x-dev
Issue summary: View changes

This needs to be reviewed for v3, and probably rerolled.

damienmckenna’s picture

Status: Needs review » Needs work

Lets leave it as Needs Work for the v3 branch until someone rerolls it.

das-peter’s picture

Status: Needs work » Needs review
StatusFileSize
new4.33 KB

Here's a re-roll :)
Seems to work as expected.
I've made a slight change - I didn't understand why following include is conditional:

 function panelizer_panelizer_task_test($handler, $base_contexts) {
   if (empty($base_contexts)) {
     ctools_include('context');
   }

So I got rid of the condition.

mglaman’s picture

Status: Needs review » Needs work

This isn't working for me.

From panelizer_node.inc

    $extra_contexts = _panelizer_panelizer_task_get_extra_contexts($handler, $base_contexts);
    $info = $entity_handler->render_entity($context->data, 'page_manager', NULL, $args, $address, $extra_contexts);

Here it is passing $extra_contexts to render_entity, however \PanelizerEntityNode's render_entity expects

  function render_entity($entity, $view_mode, $langcode = NULL, $args = array(), $address = NULL) {
    $info = parent::render_entity($entity, $view_mode, $langcode, $args, $address);

Meaning that, from my debug step through, contexts get lost immediately after being retrieved.

Edit: Looks like Node is the only entity that would have this issue. Reroll incoming.

mglaman’s picture

Status: Needs work » Needs review
StatusFileSize
new842 bytes
new5.15 KB

Here's patch with updated PanelizerEntityNode

  • DamienMcKenna committed 69def23 on 7.x-3.x
    Issue #1513946 by gilgabar, das-peter, mglaman: Pass Page Manager...
damienmckenna’s picture

Status: Needs review » Fixed

Committed! Thank you all for your help in completing this!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.