torsdag den 18. september 2014

Sublayout caching disabled when sublayout is hidden by serverside code

Issue

I have a leftmenu that can be configured on the page-template to be hidden using a Sitecore field. When the editor sets a checkmark in the HideLeftMenu field the placeholder containing the sc:Sublayout control is hidden. This seems to result in that caching of the Sublayout is ignored.
The code looks like this

Markup

 <asp:PlaceHolder runat="server" ID="phLeftColumn">  
   <div class="col-sm-4 col-md-3">  
     <asp:ContentPlaceHolder runat="server" ID="cphPageContentLeft">  
       <dom:Sublayout runat="server" ID="submenu" Path="/layouts/LeftMenu.ascx" Cacheable="True" VaryByData="True" />  
     </asp:ContentPlaceHolder>  
   </div>  
 </asp:PlaceHolder>  

Code behind

 phLeftColumn.Visible = Sitecore.Context.Item["HideLeftMenu"] != "1";   

How to reproduce

You have following code in your layout
 <asp:PlaceHolder runat="server" Visible="true">  
   <sc:Sublayout runat="server" Path="Sublayout.ascx" Cacheable="true" />  
 </asp:PlaceHolder>  

And you have following code in your Sublayout.ascx
 protected void Page_Load(object sender, EventArgs e)  
 {  
     Response.Write("Sitecore Cache is not in play");  
 }  

When refreshing the page you will see that "Sitecore Cache is not in play" is only shown the first time due to Sitecore caching which serves the persisted html after the first load resulting in Page_Load not being called.

I now change Visible attribute of the asp:Placeholder to false.
When refreshing the page you will see that "Sitecore Cache is not in play" will be displayed everytime.
This points in the direction that Sitecore caching is for some reason disabled when the Sublayout is hidden.

 

Solutions

1. Setting Path="" of the sc:Sublayout when the Sublayout is hidden

 phLeftColumn.Visible = !HideLeftColumn;  
 // If leftmenu is not shown we reset the path  
 // hidden sublyouts are not cached.  
 if (!phLeftColumn.Visible)  
     submenu.Path = "";  

2. Write code in the Sublayout.ascx that tests if the control is hidden and do nothing if it is

 protected override void OnLoad(EventArgs e)  
 {  
     base.OnLoad(e);  
     if (!Visible)  
       return;  
     // Your code here  
 }  

Ingen kommentarer:

Send en kommentar