Hello,

I have encountered the problem when using Authcache to cache content panes within Panels Mini Panels.

When I configure caching on the blocks within Page Manager's content panes, everything works as expected.
However, when I do the same thing within Mini Panel content pane, i'm getting following error:
"Canceled: No client for fragment panels/[my block name]"

When I go into /admin/config/system/authcache/p13n to see personalization configuration of my panes, I can see the pane that I configured within the Page Manager, but not the one that was configured in Mini Panel.

I guess what is missing is similar glue as for "Panels (by Page Manager)" that would work for Mini Panels.
Would it be possible to consider adding this extension into the package ?

Thanks

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

znerol’s picture

I guess what is missing is similar glue as for "Panels (by Page Manager)" that would work for Mini Panels.

Yes exactly.

Would it be possible to consider adding this extension into the package ?

I don't know, needs further investigation.

Drupa1ish’s picture

We are planning to implement Mini Panels support, but some tips from @znerol would be helpful.

1) Mini Panels are rendered via Panelizer. Node Panelizer are also rendered by Ctools Page Manager.
So the problem is more complicated. First, we need to fix the integration AutchCache Panelizer #2417419: Authcache_panels vs panels_hash_cache

2) Is enough to use Implements hook_authcache_p13n_fragment() and similar code from Panels (by Page Manager), or we need to implement also class like AuthcachePanelsPaneFragment implements AuthcacheP13nFragmentInterface, AuthcacheP13nFragmentAccessInterface { ?

3) New modules name should be authcache_panelizer and authcache_panels_mini?

Thanks.

znerol’s picture

I think basic support for Mini Panels is not too hard to implement. There is panels_mini_load_all() which can be used to implement hook_authcache_p13n_fragment(). Basically the code needs to loop over every pane in every display defined by Mini Panels (similar to the implementation in authcache_panels_page_manager). The syntax for the fragment array is documented in AuthcacheP13nObjectFactory.inc.

Then it is necessary to implement a loader class based on AuthcachePanelsAbstractDisplayLoader which wraps around panels_mini_load(). Look at (AuthcachePanelsPageManagerDisplayLoader for reference). Then use that loader in the fragment.

If everything worked well, panes placed in mini panels now should work. Configured fragments should show up in Administration » Configuration » System » Authcache » Personalization.

The problem with this very basic version is that at this point panes rendered by Authcache Ajax/ESI inside mini panels will not have any ctools context passed into them. Admittedly I do not see the big picture here, maybe this is where Panelizer enters the picture.

znerol’s picture

I did skim through Panelizer also. It seems to use Page Manager and hence we might get away with reusing the existing classes which are capable of restoring ctools context in the Ajax/ESI callback.

hook_authcache_p13n_fragments() could probably be implemented by looping over all entities/bundles and collecting at least the default panels per view_mode. I'm not sure whether it makes sense to support per-node panels. @EuroDomenii: Do you have a use-case for that?

If per-node panels support is necessary, then we might need to scan the panelizer_entity table for panel displays which contain authcache enabled panes. This could be expensive/uncontrollable on big sites. Also it likely would be necessary to hook into the entity forms in order to be notified when nodes/terms/users are updated such that we can rebuild the authcache router entries. I would like to avoid that.

I expect the loader class to be relatively easy to implement, since panelizer implements hook_entity_load(), where the panelizer instance variable on the loaded entity is populated. Hence it might be enough to call entity_load($entity_type, $ids) and then retrieve the displays from the entity.

Ctools context again might be a bit tricky, because panelizer not only inherits the context from page manager but also adds its own context/relationship parameters.

That said, I'm confident that it could work, and I may be able to give support needed to get such a project completed. Developers willing to work on this probably will need to read/step through a considerable amount of source code though. None of the involved projects are documented well, in those parts.

Drupa1ish’s picture

Thanks for the tips. My use case is OpenAtrium.

znerol’s picture

My use case is OpenAtrium.

Does OpenAtrium rely on per-node panels?

Drupa1ish’s picture

For the moment, we focus to make mini panels work inside Page Manager. Got a first working patch, but is messy, needs cleanup. Waiting for #2442837: Loading mini panels with panels_panel_context_get_display($handler)

Does OpenAtrium rely on per-node panels?

We didn't dive in panelizez yet, but it should be at node type level. See printscreen.

Drupa1ish’s picture

Status: Active » Needs review
FileSize
1.95 KB

At first glance, we wanted to setup a new extension, like advised in #3. After hard debugging, we realized that the the most elegant solution is patch in Authcache Panels by Page Manager, to include all panes recursive, otherwise a lot of redundant code would be required.

The testing was done when using Pane Cache settings to Authcache, and inside never cache ( use case OpenAtrium user badge blocks inside mini Panels), via Ajax ( not ESI).

There are 4 use cases for Minipanels

1) When using as mini panels as blocks, no patch required, because authcache_block does the job ( this is a rare use case).

2) When you setup the Pane Cache settings to Authcache for the whole minipanel included with Page Manager, it works out of the box, no patch required ( but this is a stupid use case, because the whole minipanel won’t be cached)

3) When you setup Pane Cache settings to Authcache, never cache for a pane inside Mini Panels, included with Page manager. This is very useful, because only a pane inside mini panels is not cached, dynamically delivered.

Important tips:

3a) For the whole MiniPanels, let the Pane Caching option to NoCache, and AuthCache will take care to cache it by default, during the general page load( except the dynamic page inside)

3b) After setting up a pane inside the Minipanels to Autcache, write down the machine name and check it later at admin/config/system/authcache/p13n/frontcontroller. It should be something like frag/panels/machine-name. If at Route exists is NO, it won’t work. All you have to do is to go to the Page Manager that includes that MiniPanels, and click update and save, to make it aware of the new changes inside the MiniPanel. Then clear cache, and recheck if Route exists is set to YES. This trick was the most time consuming during developing this patch.
I doubt that this could be done automatically. Anyway, it would be expensive, because that MiniPanel could be included in different contexts on the site.

4) In MiniPanel is included via Panelizer, doesn't work yet. WIP.

P.S. After final setup, we shall post printscreens to better explain the workflow.

Drupa1ish’s picture

BTW, in the function _authcache_panels_page_manager_collect_fragments_from_handlers($handlers) you do a nice test

if (!authcache_panels_pane_fragment_enabled($pane)) {
 continue;
}

Is necessary test before loading all panes in protected function loadDisplay() in AuthcachePanelsPageManagerDisplayLoader.inc ?
We did it for mini panels, but we didn’t modify the default code.

Status: Needs review » Needs work

The last submitted patch, 8: authcache-mini-panels-2231701.patch, failed testing.

Drupa1ish’s picture

Status: Needs work » Needs review
FileSize
2.25 KB

Status: Needs review » Needs work

The last submitted patch, 11: authcache-mini-panels-2231701-1.patch, failed testing.

Drupa1ish’s picture

Version: 7.x-2.0-beta2 » 7.x-2.x-dev
SocialNicheGuru’s picture

In #3 there was a mention that the mini-panel would not get context

"The problem with this very basic version is that at this point panes rendered by Authcache Ajax/ESI inside mini panels will not have any ctools context passed into them. "

Will this patch solve this so that mini-panels will have a context?

Drupa1ish’s picture

@SocialNicheGuru, we didn't test extensively. With 2 panels page oa_user_badge and oa_notifications from OpenAtrium distribution it works ( In our test, those panels were included in mini panels via page manager, different from default config of OpenAtrium, because Panelizer doesn't work yet).
Feel free to test more!

cgove’s picture

If someone get this working with the standard OA config, I would love to see the steps taken to configure it.

Drupa1ish’s picture

@cgove, the job is not completed yet... OA uses panelizer to include minipanels. The present patch solves the issue only for MiniPanels included by Page Manager.
Anyway, even with this patch, there is an workaround from interface to make minipanels work with panelizer, but is ugly.
I pledge to document all this, but is complex, and we are too busy in the following 2 weeks.
The best solution is to solve also the panelizer issue, and document afterwards. Unfortunately, we need to postpone this also in the above term.

candelas’s picture

@EuroDomenii I am also interested because I also use Open Atrium. Would you have time to document, please? Thanks

katrien_w’s picture

Also very interested for usecase Open Atrium. Did you find any time to document your workaround? Thanks for your effort

DamienMcKenna’s picture

This is the same as the patch from #11 with a coding violation fixed and a docblock comment added to the new function.

znerol’s picture

  1. +++ b/modules/authcache_panels_page_manager/authcache_panels_page_manager.module
    @@ -102,3 +102,22 @@ function _authcache_panels_page_manager_collect_fragments_from_handlers($handler
    +function panels_mini_panel_context_get_display($handler){
    

    This function is part of authcache, hence needs to have an appropriate prefix. I propose authcache_panels_page_manager_get_displays. Also I suggest to return a list of displays instead of mini panel panes shoehorned into the content property of the parent display. Btw. what happens with mini panels inside mini panels?

  2. +++ b/modules/authcache_panels_page_manager/authcache_panels_page_manager.module
    @@ -102,3 +102,22 @@ function _authcache_panels_page_manager_collect_fragments_from_handlers($handler
    +      if ($possible_mini->type == 'panels_mini') {
    

    Use identity operator (===)

  3. +++ b/modules/authcache_panels_page_manager/authcache_panels_page_manager.module
    @@ -102,3 +102,22 @@ function _authcache_panels_page_manager_collect_fragments_from_handlers($handler
    +        $objMini = panels_mini_load($possible_mini->subtype);
    +        $panes = $objMini->display->content;
    +        foreach ($panes as $pane) {
    

    Looking through mini panels source code, I think that we should check the return value of panels_mini_load, otherwise we might generate a fatal error here. Also variables should be lowercase, so maybe use $panel_mini. Also $panes is only used once, therefore maybe just write foreach ($panel_mini->display->content as $pane) and drop the assignment.

  4. +++ b/modules/authcache_panels_page_manager/authcache_panels_page_manager.module
    @@ -102,3 +102,22 @@ function _authcache_panels_page_manager_collect_fragments_from_handlers($handler
    +          if (!authcache_panels_pane_fragment_enabled($pane)) {
    +            continue;
    +          }
    +          $return->content[$pane->pid] = $pane;
    

    Only do early continue if the condition is followed by a lot of code. Here it would be better to do the opposite:

    if (authcache_panels_pane_fragment_enabled($pane)) {
      $return->content[$pane->pid] = $pane;
    }
    
  5. +++ b/modules/authcache_panels_page_manager/includes/AuthcachePanelsPageManagerDisplayLoader.inc
    @@ -31,6 +31,6 @@ protected function loadDisplay() {
    -    return panels_panel_context_get_display($handler);
    +    return panels_mini_panel_context_get_display($handler);
    

    Note, a mini panel is a display. Hence, this change should not be necessary if the suggestion above is implemented.

medinasod’s picture

@ Drupa1ish I was having this problem with the OA User Badge as well. I ended up putting the badge into a custom module and just displaying the block in a theme region:
https://github.com/medinasod/auth-user-badge

NWOM’s picture

As a workaround, I managed to keep page caching enabled, and set the pane's caching to Lazy Pane caching. This way the pages loads from page cache, and the personalized pane is then lazy-loaded. This replaced the need to have Authcache Ajax or Authcache ESI for personalization in panels as well. This works for mini-paneled content as well.

SocialNicheGuru’s picture

lazy_pane did not work for me:
1. breaks contextual links on chrome
2. for anonymous user/login was blank

I am using OpenAtrium so panels_everywhere, panels, and panelizer

jedihe’s picture

I am needing this functionality for node_view pages, so applied #20 and tested; unfortunately, it didn't work for me. Some troubleshooting got me to think the problem is the required contexts are not being injected into the mini panel pane and display, which is critical for me since the nested panel pane requires one context to be present both for visibility and proper rendering.

I spent a couple hours trying to see if the contexts could be injected in some way but didn't manage to do it. My best finding is that there already are some context providers, and the authcache_p13n route is properly set to use the one for node_view (the correct for my scenario). Further attempts to find exactly where the context provider is called to do its job failed.

Another potential issue I noticed was that the handler declared by the authcache_p13n route was for another variant where the same mini panel is being used (probably found first?) instead of the one for the variant I was testing for. Please note authcache caching is enabled in a panel pane inside the mini panel, so not explicitly under any variant. So, it looks like the handler value may get connected to other variant than the one we expect to be used if the mini panel itself is instanced in multiple variants (handlers, if my understanding is correct).

I ended up using this workaround:

- Add an empty div with a special class in the tpl for the mini panel layout.
- Define a new region in the layout used by the variant (top-level panels page definition):
-- Instance the panel pane there, enable authcache as needed.
- In preprocess for the layout used by the variant, str_replace()'d the special empty div in the region where the mini panel is rendered with the content currently rendered in the new region. Then unset the content in the new region.

This effectively got the panel pane's authcache route to work flawlessly (it is not nested inside a mini panel), but rendering somewhere inside the markup generated for the mini panel.

Hope it helps.

SocialNicheGuru’s picture

How can I tell if my mini-panel is being served via authcache_esi?
authcache_esi_debug is all green for an authenticated user
varnish says that the page is a hit
authcache_debug says that the page is a miss though

should I be seeing the esi include statement in page source? I am not seeing it.

znerol’s picture

Status: Needs review » Needs work
ron_s’s picture

Status: Needs work » Needs review
FileSize
5.42 KB

I've re-written this patch taking into account the feedback in #21. I think there's a better way to do this, and have verified it is working as expected.

@znerol, you asked, "Btw. what happens with mini panels inside mini panels?". This is a great question.

The approach of patch #20 is not going to work. There needs to be a recursive function that takes each mini panel, sets it as the parent, and reviews all children for new mini panels. My new patch resolves this issue.

@Damian, @znerol, I've also written a patch for Panelizer support that I will post shortly (and will cross-reference with a link here). I've written Mini Panels support into the Panelizer patch too.

Both the Mini Panels and Panelizer patches work, but I'm certainly not an expert in all Panelizer functions, so would appreciate any feedback Damian might have. I'm sure there are ways to streamline it.

I look forward to the feedback, thanks.

ron_s’s picture

Related issues: +#2703789: Support Panelizer

Here is a link to the Panelizer patch that also contains Mini Panels support:
https://www.drupal.org/project/authcache/issues/2703789#comment-13109678

As mentioned, both patches include a shared function called authcache_panels_page_manager_mini_panel_get_displays.

Once we are able to get to a point where one of these patches can be committed, the other patch can be re-written to remove the shared code. Thanks.

znerol’s picture

Status: Needs review » Needs work

Thanks for all this hard work. Unless I misread all the information in this issue, the current approach (patch #28) is capable of discovering cache settings on panes nested inside a mini panel on page manager pages. It also is capable of generating the necessary fragments and router entries. Also markup substitution is working, i.e., the markup of a panel rendered on a cachable page is replaced by a placeholder pointing to the authcache front-controller.

In order to test all those things I came up with the following reproduction:

drush dl authcache cacheobject ctools devel panels
drush en authcache_builtin authcache_user authcache_panels_page_manager authcache_panels authcache_page_manager authcache_p13n authcache_node_history authcache_menu authcache_form authcache_debug authcache_ajax authcache cacheobject page_manager devel devel_generate panels_mini
drush generate-users 5
drush generate-content 20 10
chmod 755 sites/default
chmod 644 sites/default/settings.php
cat <<'EOF' >> sites/default/settings.php 
$conf['cache_backends'][] = 'sites/all/modules/authcache/authcache.cache.inc';
$conf['cache_backends'][] = 'sites/all/modules/authcache/modules/authcache_builtin/authcache_builtin.cache.inc';
EOF
cat <<'EOF' >> sites/default/settings.php 
$conf['cache_backends'][] = 'sites/all/modules/cacheobject/cacheobject.inc';
$conf['cache_class_cache_form'] = 'CacheObjectAPIWrapper';
EOF

Navigate to admin/config/system/authcache and enable authcache for anonymous and authenticated roles. Enable debug for all roles if you like.

Verify that authcache is working by logging out and checking authcache debug output (or response headers).

Apply the patch.

cd sites/all/modules/authcache
wget https://www.drupal.org/files/issues/2019-05-16/authcache-mini_panels_support-2231701-28.patch
patch -p1 < authcache-mini_panels_support-2231701-28.patch
cd -

Login again and navigate to admin/structure/mini-panels. Add a new mini panel, choose Author last login as the panels administrative title, click continue. Add node as a required context and a user from node relationship, click continue. Choose any layout (e.g., lingle column) and click continue. Choose "add content" from the panel menu, add "Last login" from "User (tokens)". Set caching settings on the newly added pane to Authcache, leave authcache settings at the defaults. Save the mini panel.

Navigate to admin/structure/pages, enable the node view template, edit it, add a variant (e.g., page), choose the layout (e.g., single column), click through the wizard leaving things at the defaults until you get to "content". Add the "Author last login" mini panel, and some node fields. Click update and save.

Navigate to admin/structure/block and place the switch user block somewhere. Navigate to admin/people/permissions and allow everybody to use the switch user functionality (you do not do this on a public server, right!?)

Logout and navigate around the page. If you hit a node page, authcache debug will report "Cache Status: cancelled" with the mesage "No client for fragment panels/author-last-comment". This has been reported in #8, routes probably need to be rebuilt after changes to the mini-panel.

Logout and navigate around the page. If you hit a node page, authcache debug will now turn green. Pull up the browser developer tools and look at the network panel. Filter for XHR and check calls to authcache.php. Regrettable the call to the author-last-login fragment fails with 404. This originates from AuthcachePanelsAbstractDisplayLoader.inc because it fails to find the requested pane.

The reason is that the current patch only implements half of the changes necessary to get this to work. It is not enough to recursively discover nested panes and generate authcache fragments for them. In order to make it work, some mechanism needs to be implemented in the authcache frontcontroller to also recursively dig into the structure, extract the pane to be rendered, find the right display to do so and render/return it.

ron_s’s picture

In order to make it work, some mechanism needs to be implemented in the authcache frontcontroller to also recursively dig into the structure, extract the pane to be rendered, find the right display to do so and render/return it.

Hmm... ok, need to give this some thought. Thanks for sharing a detailed example of how it's failing, this is very helpful.

semjuel’s picture

Hi @znerol
Please try patch attached.
I've modified patch #28 and it works for me.

philsward’s picture

Receive the following when patching #32 against 2.3. Haven't updated to latest dev and tried...

patching file modules/authcache_panels_page_manager/authcache_panels_page_manager.info
Hunk #1 FAILED at 6.
1 out of 1 hunk FAILED -- saving rejects to file modules/authcache_panels_page_manager/authcache_panels_page_manager.info.rej
patching file modules/authcache_panels_page_manager/authcache_panels_page_manager.module
patching file modules/authcache_panels_page_manager/includes/AuthcacheMiniPanelsPageManagerDisplayLoader.inc

Looking at the patch, I'm not exactly sure why it wouldn't add the one line... I ended up adding it by hand.

ron_s’s picture

Title: Authcache not working on content in Mini Panels » Support Mini Panels
Status: Needs work » Needs review
FileSize
8.74 KB
6.73 KB

I reviewed patch #32 against the latest 7.x-2.x-dev and seems like a worthwhile approach. Did some tests and looks to be working as expected. I was able to nest a mini panel inside a mini panel, and returned successful results with Authcache Debug. Would be good to have someone else validate what I've seen.

Also created a new version that has a few minor adjustments -- added function comments, changed the class name to be more consistent with the rest of Authcache, and modified to PHP5-style arrays. Even though it's end-of-life, Drupal 7 technically still supports PHP5, and no where else in Authcache are PHP7-style arrays used. Please review the attached patch.

As well, I compared the code with the Panelizer support patch: https://www.drupal.org/project/authcache/issues/2703789

There is a lot of overlap between the two, so I'm going to post an updated version of the Panelizer patch that follows the same structure as Mini Panels. I'm also going to include a new patch that is Mini Panels + Panelizer in one, so it's easier to see how the two fit together.

Would appreciate any feedback, thanks.

ron_s’s picture

Have posted the Mini Panels + Panelizer support patch for reference on the Panelizer issue thread:
https://www.drupal.org/project/authcache/issues/2703789#comment-14097101