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

lørdag den 23. august 2014

Automatic Multisite Handling By Traversing Sitecore Tree

Add automatic multisite handling to your Sitecore site by traversing the Sitecore Tree to find the available sites. You can decide to use the site name as subdomain or you can specify a hostName in a Sitecore field on the site-item.


 

 

 

 

Web.config changes

Adding a config section for configuring the multisite handler.

 <configSections>  
      <section name="Netmester.ItemResolver" type="Netmester.ItemResolver.Configuration, Netmester.ItemResolver"/>  
 </configSections>  
 <Netmester.ItemResolver SitecoreWebSiteName="subsites" UrlSyntax="{$}.mydomain.dk|www.{$}.mydomain.dk" HostNameField="hostNames" TargetHostName="targetHostName" />  

  • SitecoreWebSiteName -  The name of the site defined in tag in web.config. Is used as template when the sites are created.
  • UrlSyntax - Specifies the syntax used as hostName for each site created. 
  • HostNameField - Specifies a field on the site-element that should be used as hostName. Pipes can be used.
  • TargetHostName - Specifies a field on the site-element that should be used as targetHostName. If none is specified the first one defined as hostName is used.

Override the standard sitecore siteprovider.

 <siteManager defaultProvider="config">  
      <providers>  
           <clear/>  
           <add name="config" type="Netmester.ItemResolver.SiteProvider, Netmester.ItemResolver" siteList="sites" checkSecurity="false"/>  
      </providers>  
 </siteManager>  

Code

Configuration class

Class associated with the config section defined in web.config

onsdag den 9. december 2009

Changing control names on postback

I recently spent a whole day figuring out why my UserControl continuesly displayed inline errormessages instead of the validation summary I did tell it to use.

After af lot of investigation I found out that the controls in my UserControl did have changing control names upon postback due to inserted into sitecore placeholder.

I have failed to reproduce this scenario in a controlled matter but did find a fix to the problem.

Find the control that changes name upon postback and use this implementation of the sitecore placeholder.


 public class SCPlaceholder : Sitecore.Web.UI.WebControls.Placeholder  
   {  
     private List UsedKeys = System.Web.HttpContext.Current.Items["pckeys"] as List;  
     public SCPlaceholder()  
     {  
       if (UsedKeys == null)  
       {  
         UsedKeys = new List();  
         System.Web.HttpContext.Current.Items["pckeys"] = UsedKeys;  
       }  
     }  
     protected override void AddedControl(System.Web.UI.Control control, int index)  
     {  
       Sublayout s = control as Sublayout;  
       if (s != null && s.Controls.Count == 1)  
       {  
         string name = this.Key + "_" + s.Controls[0].GetType().Name;  
         if (UsedKeys.Contains(name))  
         {  
           for (int i = 0; i < 5; i++)  
           {  
             if (!UsedKeys.Contains(name + "_" + i))  
               name += "_" + i;  
           }  
         }  
         s.ID = name + "_sub";  
         s.Controls[0].ID = name;  
         UsedKeys.Add(name);  
       }  
       base.AddedControl(control, index);  
     }  
   }   

Experiences on how to reproduce this in a safe and clean environment is appreciated.

onsdag den 14. oktober 2009

Me and sitecore

This blog exists because I have a love/hate relationship with the CMS created by Sitecore which is a big part of my job as a web developer in Netmester A/S in Denmark.

I am always challeging Sitecore and Sitecore unfornunately often breaks to all the weird stuff Im doing to it every day.

Ill create blogs about all the weird stuff I meet and struggles to solve every day.

And this is the first in many.

Im at the moment developing a solution in Sitecore 6.1.0 which is currently the latest Sitecore release (not recommended version).

One of the new things in Sitecore 6 is that all security (rights, roles and other membership related stuff) are implemented using standard asp.net security rather than using Sitecores own security.
This should in itself be an approvement but sitecore has for one thing decided to implement the Sitecore domain functionality as part of the username which I personally think is pretty stupid.

Im using a third party member system that supplies users to the website (username, email, name etc).

In order to be able to log out this user, after login, using FormsAuthentication.SignOut() the user NEEDS to be added to the asp.net
Membership and therefore is visible in Sitecore security editor. With more than 5000 users this makes the security editor a bit crowded.
In order to put the users in a customer specific domain I need to prefix the user with the domain name followed by a backslash (\)
This makes it hard to map the sitecore user with the third pary member system or at least makes it more complicated because I now need to remove
the domain name from the sitecore user or append the domain name to the third party username.

Faste læsere