Tuesday, December 22, 2009

Publish to pre-production web database


In my experience with enterprise level implementations, there is often a need for a separate “stage environment” for final content preview or a pre-production phase of workflow.

It is also often the case that the environmental limitations or restrictions make the content delivery part of the authoring environment suitable for such purpose. For example, your e-commerce infrastructure could not be available from the authoring instance. One of the possible ways to approach such a requirement is to configure a stand-alone staging instance of Sitecore which will be used for content delivery instance and is commonly configured exactly like one of the servers in the web farm. There is one exception though – the database that is used for content delivery is generally different from the one that is used in production content delivery.

With this approach, now the question is how to plug in workflow in a way that content could go via this “stage” environment and then only upon final approval will be able to get to “production”.

Now there is a problem that you cannot get get items published until they are in final workflow state. You could have two workflow states “Staged” and “Published”, both marked as final and with auto publish actions connected.
I don’t like this approach since it goes against the workflow nature – only one state should be marked as final.

Alternatively, you can plug in a “copy item” workflow action to the “Staged” workflow state where you can programmatically copy an item from master database to stage web.

While this approach does seem legitimate, it works around the need of publishing thus any additional processing you may be having in publish(item) pipeline would not work.

I looked into the option of having publishing process ignore workflow when publishing to stage. While this seemed like a dangerous path to go, I have soon discovered that the PublishHelper’s GetVersionToPublish method already accepts this notion of passing a “requireapproval” flag to the underlying publishing mechanism. Since it is always passes “true”, I started looking into ways to make this flag dynamic and figured that setting it on the level of PublishOptions could be a good idea. For example, from the code of my workflow action I would be able to define whether I want to have workflow respected or not.

Here is what you will need to do to make it work.

First, override the default PipelinePublishProvider and plug it into the web.config:

<publishManager defaultProvider="default" enabled="true">
    <providers>
        <clear />
         <!--<add name="default" type="Sitecore.Publishing.PipelinePublishProvider, Sitecore.Kernel" />-->
         <add name="default" type="SCUSAINC.Publishing.ExtendedPublishProvider, SCUSAINC.Publishing" />
     </providers>
</publishManager>

Secondly, you will need to override the CreatePublishHelper class:

public class ExtendedPublishProvider : PipelinePublishProvider
    {
        public override PublishHelper CreatePublishHelper(PublishOptions options)
        {
            Assert.ArgumentNotNull(options, "options");
            if (options is ExtendedPublishOptions)
                return new ExtendedPublishHelper(options as ExtendedPublishOptions);

            return new PublishHelper(options);
        }
    }

After that, introduce two more classes – ExtendedPublishHelper and ExtendedPublishOptions:

public class ExtendedPublishHelper : PublishHelper
    {
        private readonly ExtendedPublishOptions _options;

        public ExtendedPublishHelper(ExtendedPublishOptions options)
            : base(options)
        {
            _options = options;
        }

        public override Item GetVersionToPublish(Item sourceItem)
        {
            Assert.ArgumentNotNull(sourceItem, "sourceItem");
            if (Options is ExtendedPublishOptions)
            {
                return sourceItem.Publishing.GetValidVersion(Options.PublishDate, _options.RequireApproval);
            }

            return sourceItem.Publishing.GetValidVersion(Options.PublishDate, true);
        }
    }

public class ExtendedPublishOptions : PublishOptions
    {
        public ExtendedPublishOptions(Database sourceDatabase, Database targetDatabase, PublishMode mode, Language language, DateTime publishDate, bool requireApproval)
            : base(sourceDatabase, targetDatabase, mode, language, publishDate)
        {
            RequireApproval = requireApproval;
        }

        public bool RequireApproval { get; set; }
    }

Now you are ready to launch publishing with workflow settings completely ignored. For example, this is how you can do it from the workflow action:

var database = Factory.GetDatabase(databaseName);

var options = new ExtendedPublishOptions(dataItem.Database, database, PublishMode.SingleItem, dataItem.Language, DateTime.Now, true)
{
         RootItem = dataItem,
         Deep = true;
};

new Publisher(options).PublishAsync();

That’s it!

Tested on Sitecore 6.1. Expected to work with 6.2.

Monday, December 14, 2009

Get all published items in Sitecore 6.1/6.2


You may need to get all items that were processes by a publishing operation for different reasons, for example, pull certain information for each item and notify CDN of a change so cache could be purged. AKAMAI can be configured to behave that way.
Currently we have two articles on the subject. This one describes how to use the PublishEngine, second article suggests approach with custom PublishLog. Both are not compatible with 6.x. So I’ve looked into the options for the latest Sitecore with tech support. Our findings included introduction of a new PublishProcessor which examines the Queue property of PublishContext, but this did not work properly for smart publishing and I wanted a bulletproof yet simple approach applicable to all possible publishing modes.
Then I remembered that we are already doing similar things for indexing. The update index job processes only changed items and gets that information from the History storage.

Sunday, December 13, 2009

WFFM 2.0 module: Form Reports Viewer throws exception


If you are like me who enjoys stripping down Sitecore solution as much as possible, you may stumble across this as well.

On Sitecore 6.1/6.2 install with awesome Web Forms for Marketers module 2.0, you may get the following exception if your bin folder is missing SQLite assemblies (Sitecore.SQLite.dll and System.Data.SQLite.DLL). Even if you are not using SQLite, apparently, there is a dependency on these guys from the module’s assemblies. Putting them back obviously solves the problem.

Server Error in '/' Application.


Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.]

System.Reflection.Module._GetTypesInternal(StackCrawlMark& stackMark) +0

System.Reflection.Assembly.GetTypes() +111

System.Data.Metadata.Edm.AssemblyCacheEntry.LoadTypesFromAssembly(LoadingContext context) +28

System.Data.Metadata.Edm.AssemblyCacheEntry.InternalLoadAssemblyFromCache(LoadingContext context) +290

System.Data.Metadata.Edm.AssemblyCacheEntry.LoadAssemblyFromCache(Assembly assembly, Boolean loadReferencedAssemblies, Dictionary`2 knownAssemblies, Dictionary`2& typesInLoading, List`1& errors) +137

System.Data.Metadata.Edm.ObjectItemCollection.LoadAssemblyFromCache(ObjectItemCollection objectItemCollection, Assembly assembly, Boolean loadReferencedAssemblies) +284

System.Data.Metadata.Edm.ObjectItemCollection.LoadAssemblyForType(Type type) +33

System.Data.Metadata.Edm.MetadataWorkspace.LoadAssemblyForType(Type type, Assembly callingAssembly) +80

System.Data.Common.Utils.MetadataHelper.TryDetermineCSpaceModelType(MetadataWorkspace workspace, EntityType& modelEntityType) +67

System.Data.Objects.ObjectContext.ExecuteFunction(String functionName, ObjectParameter[] parameters) +238

Sitecore.Forms.Data.SitecoreWebFormsContext.GetFormsByMainParams(Nullable`1 formId, String storageName, Nullable`1 pageIndex, Nullable`1 pageSize, Nullable`1 asc, ObjectParameter returnValue) +593

Sitecore.Forms.Data.DataProviders.WFMDataProvider.GetForms(QueryParams queryParams, Int32& total) +911

Sitecore.Forms.Data.DataProvider.GetPage(PageCriteria page, IList`1 sort, IList`1 filters) +534

Sitecore.Form.DataViewer.SortedFilterable`1.GetPage(PageCriteria page, IList`1 sort, IList`1 filter) +55

Sitecore.Form.Core.DataViewer.FormGridSource`1.GetEntries(Int32 pageIndex, Int32 pageSize) +104

Sitecore.Form.DataViewer.ComponentArtGridHandler`1.GetDataSource(Int32 pageIndex, Int32 pageSize) +56

Sitecore.Form.DataViewer.ComponentArtGridHandler`1.ApplyDataSource() +76

Sitecore.Form.DataViewer.ComponentArtGridHandler`1.Grid_NeedDataSource(Object sender, EventArgs e) +54

ComponentArt.Web.UI.Grid.OnNeedDataSource(EventArgs e) +36

ComponentArt.Web.UI.Grid.DataBind() +475

Sitecore.Form.DataViewer.ComponentArtGridHandler`1.DataBind() +17

Sitecore.Form.DataViewer.ComponentArtGridHandler`1.InitializeGrid(Boolean dataBind) +503

Sitecore.Form.DataViewer.ComponentArtGridHandler`1..ctor(Grid grid, IGridSource`1 source, Boolean dataBind) +173

Sitecore.Form.DataViewer.ComponentArtGridHandler`1.Manage(Grid grid, IGridSource`1 source, Boolean dataBind) +94

Sitecore.Forms.Shell.UI.FormDataViewer.FormDataViewerPage.GridRender(Boolean update) +360

Sitecore.Forms.Shell.UI.FormDataViewer.FormDataViewerPage.OnPageSelected(Object sender, MultiPageSelectEventArgs e) +110

Sitecore.Forms.Shell.UI.FormDataViewer.FormDataViewerPage.OnLoad(EventArgs e) +223

System.Web.UI.Control.LoadRecursive() +50

System.Web.UI.Control.LoadRecursive() +141

System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627


Version Information: Microsoft .NET Framework Version:2.0.50727.4927; ASP.NET Version:2.0.50727.4927

Friday, December 11, 2009

Friday case: Sitecore is not starting up


Just had to deal with a pretty mysterious issue when my Sitecore app stopped staring up for whatever reasons.
Symptoms:
- nothing happens, browser just hangs with the “Connecting…” message
- nothing in the Sitecore logs
- nothing in the Event Viewer
- nothing unusual on the SQL side
- nothing unusually heavy on the worker process – CPU is idling out, memory is fine.

In overall, a sign that something is inherently wrong.

Thursday, December 10, 2009

Quick tip: resolving section sort order problem with inheritance


There is a known issue currently with the sort order set on the standard values for the “/sitecore/templates/System/Templates/Template section” template and not being picked correctly and always treated as zero until you set the sort order specifically for the section thus overriding the standard value.

This has impact on section inheritance, producing unexpected behavior in the following case:
1. You have an abstract “base product” template with the following sections:
image

2. You have a derivative template “monitor” with its own domain specific data section:
image

3. You want to have certain sections from the “base product” template show up first, then the “data” section from the “monitor” template itself, then the rest of sections from base:
image 

Since the default inherited sort order for a section is 100 (coming from __Standard values), however you won’t be able to accomplish this by setting the sort order of “descriptors” and “product data” section to 80 and 90 correspondingly.
This is because the value for the section sort order that is coming from the __Standard values will always be considered as zero.

There is an easy and simple way to solve this by simply setting the sort order of “descriptors” and “product data” sections to negative values (-2 and -1) for example.

Enjoy!

Thursday, December 03, 2009

Partial (Item) Cache Clearing Module – SitecoreStager (update)


A quick update. We have released new version of the Staging module with the full support of partial item cache clearing.
Not everyone was comfortable with full cache clearing process and that we released Stager as a shared source, now we have an official, supported, ready to go component addressing this need.

If you are not using Stager (I blogged about it some time ago) yet and have Staging module installed, seriously consider upgrading.

Check out the release notes here, there are some important things fixed also.
Enjoy!

Friday, October 30, 2009

Quick tip – remove “Edit HTML” option for the rich text field


A while ago  (in 2005 actually), I blogged about how to disable HTML tab in the HTML Editor. How it is almost 2010 and it is time to post an update :-)
Well, first thing I would like to point out is that after 4+ years, the approach pretty much has not changed. We changed the rich text editor from CuteEditor to Telerik’s RAD Editor, released a great deal of new functionality, but still preserved the idea of backward compatibility even in such small things as rich text editor configuration!
Isn’t it amazing?

Enough reminiscing, let me cut to the chase! Today with 6.x, you can still disable HTML tab for the RTE by modifying the security permissions on the “HTML View” item in one of the rich text profiles, for example for the “Rich Text Full”: /sitecore/system/Settings/Html Editor Profiles/Rich Text Full/Buttons/HTML View

Two things changed here. All profile definitions migrated to the “core” database and now the container names are a bit different.

In addition to this, as one of our partners noticed, there is another button in Content Editor above the RTE field called “Edit HTML” which needs to have the same rules applied to.
Capture

For that, follow the following steps:
1. Go to the core database, locate the field definition item:
/sitecore/system/Field types/Simple Types/Rich Text/Menu/Edit Html
2. On the Security Tab, click “Assign” and select the role you don’t want this option to be available to. Deny inheritance of this item or specify other security settings that make sense for your needs.
inheritance

That’s it, Folks! Enjoy Sitecore!

Thursday, September 03, 2009

Announcement: Partial (Item) Cache Clearing Module - SitecoreStager


Great news! We have released a shared source component that implements partial cache clearing model. Make sure to download the tool and read more about it. Since it is Shared Source, make sure you understand the support restrictions, etc. first before deploying the tool to production.

This tool does not substitute the Staging module as it provides cache clearing only, not file upload/download functionality.

For the implementations with frequent publish operations enabled (from workflow or single item publishes) and especially for multisite environments, this will significantly improve the performance of the delivery system and take the load off the SQL Server.

What I love about the tool is that the code is available so if there are specific architectural considerations for your implementation, you can reuse the code and implement the solution that fits your needs.

Kudos to Alexey Romaniuha for the actual implementation.

Enjoy and don’t forget to provide feedback!

List of blogs indexed on SDN


Greetings! Some of you asked - here is the list of blogs we currently index on new SDN search.
http://adeneys.wordpress.com/
http://blog.wojciech.org/?cat=5
http://briancaos.wordpress.com/
http://cmsmarketing.blogspot.com/
http://contenttree.blogspot.com/
http://dev-smar.blogspot.com/
http://jefraser.wordpress.com/category/sitecore/
http://kerrybellerose.blogspot.com/
http://km-sitecore.tumblr.com/
http://larsnielsen.blogspirit.com/
http://mcore.wordpress.com/
http://philheltewig.spaces.live.com/
http://richdias.wordpress.com/category/sitecore
http://sharesitecore.wordpress.com/
http://sitecore-on-the-road.blogspot.com/
http://sitecore.alexiasoft.nl/
http://sitecore.blogspirit.com/
http://sitecore.spaces.live.com/
http://sitecoreaustralia.wordpress.com/
http://sitecoredev.blogspot.com/
http://sitecoreexperience.spaces.live.com/
http://sitecoregadgets.blogspot.com/
http://sitecorejm.blogspot.com/
http://sitecorejohn.spaces.live.com/
http://sitecorekh.blogspot.com/
http://sitecoresmoothie.blogspot.com/
http://sitecoresupport.blogspot.com/
http://thesitecoreexperience.blogspot.com/
http://usoniandream.blogspot.com/
http://vasilinenko.blogspot.com/
http://www.alexeyrusakov.com/sitecoreblog
http://www.cassidy.dk/blog/sitecore

If your blog is not in the list, please submit it to the comments below and we will include it in the search.

BTW, the indexing logic is going to be improved soon, with posts only included into the index.
For those of you interested in tech details, it is kinda tricky since the URL format is not normalized, so it is not straightforward to setup the ignore rules and since we don’t have the control over the blog’s meta data, we have to be creative as usual :-)

Friday, August 28, 2009

SDN Search just got a bit better


We just pushed another small enhancement for our updated search now featuring “top results” functionality.
Coveo is not only a great search engine, but it also gives you plenty of reporting about what users search for on the website which is absolutely critical for such a resource as SDN.
We learnt that most searches are related with “fundamental” keyword, “sitecore security” and “media” so we picked out the most relevant documentation and instructed Coveo search to put them at the top of the list.
Check it out ;-)
top results 
Thank you for the feedback we got so far and of course, more enhancements are coming soon.

Thursday, August 27, 2009

Favorites and Links not working


Just noticed a minor issue in 6.1 with Favorites and Links buttons from the Navigate tab not working.
To fix that, simply go to the “core” database and clear our the “command” field for both items:
/sitecore/content/Applications/Content Editor/Ribbons/Chunks/Navigate/Links
/sitecore/content/Applications/Content Editor/Ribbons/Chunks/Navigate/Favorites

Good that everything is so (re)configurable in Sitecore ;-)

Thursday, August 13, 2009

Announcement: New Search on SDN


First time writing a blog post from an airplane and such exciting news! I am pleased to inform about new search integration on our Developer Network.

This is initial launch featuring the following capabilities:
- Improved relevancy of search within the HTML documents, PDF, Word and other document types.
- Improved search performance.
rss
- Refine your search by type of the document and location (you can search in release notes for example). 
refinements
-  Ability to search Sitecore Community Blogs and Shared Source Library.
source
- Save search results as RSS and keep yourself updated.
 rss-output
- Search within results, sort, save search query and filter.
- Perform advanced search.
- Rank search results.
search rating
- View cached documents with search term highlighting
- and many more.

All this above is provided by version 6 of Coveo Enterprise Search.

Hope it will make your search experience much better, for example include Forum search.
Please do comment as we are planning on enhancing this functionality further and adding Forum search. So we are eager to hear from you.

Now just logon and experience it!

Saturday, July 18, 2009

Ways to check field type in code


As a “safe check” code operation in Sitecore, you frequently check for expected field type before working with a field.
While there is an easy way to do it via “Type” property of a field returning string, it may not look really nice and considered hard-coding:
if (Sitecore.Context.Item.Fields["featured"].Type == "Droplink")
Plus backwards compatibility of such code is questionable.
 
I suggest you use the Sitecore.Data.Fields.FieldTypeManager class that has “GetField” method where you can pass the instance of your field and use “IS” keyword to check if it is safe to cast:
if (FieldTypeManager.GetField(Sitecore.Context.Item.Fields["title"]) is TextField)
if (FieldTypeManager.GetField(Sitecore.Context.Item.Fields["text"]) is HtmlField)
if (FieldTypeManager.GetField(Sitecore.Context.Item.Fields["featured"]) is LookupField)
if (FieldTypeManager.GetField(Sitecore.Context.Item.Fields["metakeywords"]) is MultilistField)

Just make sure to replace the field name strings with a reference to a GUID class and you will be all set!

Friday, July 17, 2009

Registry Cache for “website”


Applies to 5.3.x and 6.0.x.
Recently discovered issue with disabled “registry” cache can potentially increase chattiness of your Sitecore web server with SQL Server.

Basically what happens is regular SQL selects from ‘Properties’ table that stores user-based registry settings for a current site. The call is initiated by Item.DisplayName property which is frequently used on the delivery boxes too. This is not a problem for the authoring environments that operate in the context of “shell” site by default since the registry cache is enabled there. This is not the case for “website”*** as two places where this may be changed contain zeros:

<site name="website" … registryCacheSize="0" …  />

<cacheSizes>
  <sites>
    <website>
     <html>10MB</html>
     <registry>0</registry>
     <viewState>0</viewState>
      <xsl>5MB</xsl>
    </website>
   </sites>
</cacheSizes>

The way to fix this is to simply adjust the value of registry cache. You can try 1KB and monitor the /sitecore/admin/cache.aspx page to see the actual consumption. From my experience, it is rarely even approaching 1KB in most installations unless you are writing something there with custom code.

This will be officially documented as a known issue and published on SDN.

In meantime, go ahead and put it in your web.config ;-)

*** If you have a multisite environment, change this on the level of your custom site definition responsible for the front-end requests. If in doubt, let me know.

Item, Memory and Timing Thresholds Demystified


There seem to be a lot of confusion on the forums on this topic, so the doc team updated the article about why the warnings are commonly appearing in live environments even when the code is optimized.

The basic idea is that the functionality was not designed for usage under load tests or in production, so the best way would be to simply disable this functionality in production systems. Otherwise, your log files will be just filled with warnings and it will make difficult reading them.
To disable, simply remove the StartMeasurements processor from the “httpRequestBegin” pipeline and “StopMeasurements” from “httpRequestEnd”.

I suggest you do use the thresholds in QA when running tests, just make sure you have a single request test to identify the problematic pages.

Same rules apply to media requests that report threshold violations. If this happens under a single user load, make sure you don’t have a crazy number of items in the requested branch. I’ve seen media libraries when that was the case.

Take it easy.

Tuesday, May 12, 2009

Updated: Standalone apps under Sitecore web root


As this article suggests, it is possible though not officially recommended. Here is an update for what you need to do in Sitecore 6.x to make it happen.

***Updated. (Thanks to the commenters):

The easiest way to do it, especially if you don’t want to inherit anything from the parent Sitecore configuration down to your asp.net app is to use the <location /> config element with inheritInChildApplications="false". With this element you can wrap most config sections like <system.web />, <system.webserver />, etc:

image

It is worth mentioning that not all configuration sections can be wrapped into the <location /> element.

========================================

- Open the web.config of your standalone web app.
- Locate <httpHandlers>section under <system.web> and remove Sitecore specific http handlers:

<httpHandlers>
   <remove verb="*" path="sitecore_media.ashx"/>
   <remove verb="*" path="sitecore_xaml.ashx"/>
   <remove verb="*" path="sitecore_icon.ashx"/>
   ...
</httpHandlers>

- Do the same thing for httpModules section:

<httpModules>
   <remove name="SitecoreHttpModule" />
   <remove name="SitecoreUploadWatcher" />
   <remove name="SitecoreXslWatcher" />
   <remove name="SitecoreLayoutWatcher" />
   <remove name="SitecoreConfigWatcher" />
   ...
</httpModules>

- If you are running on IIS7 in integrated mode, you will need to the same thing for the <system.webServer> section:

<modules runAllManagedModulesForAllRequests="true">
   <remove name="SitecoreHttpModule" />
   <remove name="SitecoreUploadWatcher" />
   <remove name="SitecoreXslWatcher" />
   <remove name="SitecoreLayoutWatcher" />
   <remove name="SitecoreConfigWatcher" />
   ...
</modules>
 
<handlers>
   ...
   <remove name="Sitecore.MediaRequestHandler" />
   <remove name="Sitecore.XamlPageRequestHandler" />
   <remove name="Sitecore.IconRequestHandler" />
   ...
</handlers>
 
- Your standalone app will most likely use its own membership provider(s), so you will need to disable Sitecore membership provider:
<membership defaultProvider="AspNetSqlMembershipProvider">
   <providers>
      <remove name="sitecore" />
      ...
   </providers>
</membership>

- If neither role nor profile providers are used, disable them or if you do use them, add the remove statement the same way as it it shown above for the membership provider.

<profile enabled="false">
   ...
</profile>
<roleManager enabled="false">
   ...
</roleManager>

This way you can easily have an MVC app running in a virtual application (separate pool) of your Sitecore website.

Friday, May 08, 2009

Altering the behavior of the tree view control


You may have noticed this too. When you create a template, the Base Template dropdown may be tricky to operate with. If you are trying to find a template in the subfolders to inherit from and miss the expansion plus, the tree will collapse and you will have to start over. This has been bugging me for a while so I asked the tech support if there is an easy way to fix this and not have the tree to collapse.
Luckily, there is an easy fix, but you will have to mess with the Sitecore.js file located under /sitecore/shell/controls.

What you need to do is to add a global variable in Sitecore.js:

var iAmTree = null;

Then straight after line 563 within scSitecore.prototype.postEvent = function(tag, evt, parameters) add the following:

iAmTree = false;                                                                                      
if (ctl.className.toString() == "scTreeItem") iAmTree = true;  

And finally within scRequest.prototype.resume = function() alter this IF statement:

if (this.closePopups && typeof(scForm) != "undefined") {
    scForm.browser.closePopups("Request");
  }

to this:

if (this.closePopups && typeof(scForm) != "undefined" && iAmTree != true) {
    scForm.browser.closePopups("Request");
  }

This will also affect the Droptree field’s behavior and possibly more areas.

And you may have guessed – create a backup of Sitecore.js file and use the solution on your own risk ;-)

Special thanks goes to Ruslan for providing the fix.

Thursday, April 09, 2009

How to troubleshoot SQL connection issues


Had a problem with remote web app not connection to newly installed SQL Server. Was getting generic “A network-related or instance-specific error occurred while establishing a connection to SQL Server…”

Found this great article with the breakdown of possible scenarios, very useful. Mine was #6, SQLBrowser not running. Was clicking too fast through the installation ;-)

Monday, April 06, 2009

Find of the day - Mozilla specific client caching


Looks like Mozilla stores documents locally even if "no-cache" header is passed in the HTTP response.
Official explanation here.

Wednesday, April 01, 2009

Silverlight Client Caching


Since SL creates a XAP file for further consumption, browsers will be caching it as a usual asset. While being awesome for production, it introduces a pain in the development process as you need to clear the temporary files in your browser to see the change.

In order to get rid of this inconvenience, just turn off the caching on the IIS level. If you are on IIS7, extend "Output Caching" options by introducing a rule for ".xap" files and specify "cache using file change notifications ":

Untitled

In order to confirm it worked, fire up Fiddler and verify you get "no-cache" for the request to XAP file.

Cookie sharing between processes in Internet Explorer


If you installed IE8 and tried running two separate Sitecore sessions in different processes, you may have experienced this as well.
IE8 shares the cookies between two different processes (windows) now so this may bring you inconvenience especially during the development process.

There are solutions out there which address the problem with special "-nomerge" parameter, but I decided to apply the registry fix directly so all my IE launches will not use this new "FrameMerging" feature that supposedly improves performance.

Related reading:
http://www.walkernews.net/2009/03/26/use-ie8-nomerge-option-to-login-multiple-accounts-of-same-site/ http://www.walkernews.net/2009/04/02/alternative-ie8-nomerge-option-to-login-multiple-web-accounts/
http://www.microsoft.com/communities/newsgroups/list/en-us/default.aspx?dg=microsoft.public.internetexplorer.beta&tid=3d227efa-d0a1-4ec7-896e-2722c4026e62&cat=&lang=&cr=&sloc=&p=1

Registry fix from the article above:
HKCU\software\microsoft\internet explorer\main - FrameMerging = DWORD:0

Update 2/29/2012:

The registry key that disables this mess once and forever is actually called “SessionMerging” which can be found under:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main
SessionMerging = DWORD:0

Works for IE9 too!

Tuesday, March 31, 2009

Attach WCF services to Sitecore context


As you know, any stand-alone .NET resource such as ASPX webform or web service can be associated with a Sitecore context. With this in place, will be able to access all nice stuff from Sitecore.Context such as "ContentDatabase", "Domain", etc.

In order to do that, you can just drop the resource into one of the folders referenced by a site definition in the <sites> section.
For example, if your stand-alone resource is working with the back-end, "modules_shell" would be the best option:

<site name="modules_shell" virtualFolder="/sitecore modules/shell" physicalFolder="/sitecore modules/shell" rootPath="/sitecore/content" startItem="/home" language="en" database="core" domain="sitecore" content="master" enableWorkflow="true" />

As you can see, the "modules_shell" site is referencing the "/sitecore modules/shell" folder, so this would be the location for your resource.

It works great for aspx and asmx resources but fails for a WCF service that you may be using.
The reason for that is the FilterUrlExtensions processor in preprocessRequest pipeline that does not allow SVC extensions through. If you simply adjust the value of the first "allowed extensions"  parameter as it is shown below, your WCF service will be able to access Sitecore context:
<processor type="Sitecore.Pipelines.PreprocessRequest.FilterUrlExtensions, Sitecore.Kernel">
   <param desc="Allowed extensions (comma separated)">aspx, ashx, asmx, svc</param>
   <param desc="Blocked extensions (comma separated)">*</param>
   <param desc="Blocked extensions that stream files (comma separated)">*</param>
   <param desc="Blocked extensions that do not stream files (comma separated)"></param>
</processor>

Note, there are two processors with the same class name in web.config so don't confuse it with the one defined in the httpRequestBegin pipeline.

Wednesday, March 25, 2009

How to completely disable Lucene index


Why? As Alexey was blogging some time ago, for the dev machines and even production content delivery environments, it may make a lot of sense to disable the out-of-the-box search engine that Sitecore ships with. This may improve performance and reduce number of folders in Sitecore installation as you will be able to simply remove the whole "indexes" folder.

Latest updates for version 6 and 5.3


We pushed two updates yesterday for both major releases of CMS product.

The list of issues addressed in the latest update for version 6 (6.0.1) is impressive. A couple of them related to proxies and the one for CryptographicException seems to be addressing the need for step #7 in my guideline for Windows Authentication.

The update for 5.3.2 release shows the continuous support of the installations that were not upgraded yet ;-)

Tuesday, March 17, 2009

AD some speed


Today a new build of Active Directory module came out with a lot of improvements and tweaks targeting performance. If you have this guy installed, highly recommend to update your installations!

Friday, March 13, 2009

Friday Catch: Page Editor Not Yet Available


You may be getting this message in Page Editor after clicking any of the top bar buttons (Edit, Design, Log off).
In my case it is caused by the System.Web.UI.WebControls.ImageButton control's PostBackUrl property which I am assigning in code behind.
It appears that any control with that property assigned and used such as asp:LinkButton, asp:Button cause this problem on SR-1 installations and presumably earlier too.
To workaround it, I added a check for IsPageEditor in my control:
if (!Sitecore.Context.PageMode.IsPageEditor)
{
imageButton.PostBackUrl ="/mypage.aspx";
}
Works as temp workarond, the tech support will be investigating further.

Tuesday, January 27, 2009

Comprehensive Configuration Guide


We have published the configuration guide for Sitecore 6. The document was in the draft state for a while and now it is officially released after thorough review. It covers multiple configuration options as Sitecore is pretty flexible in that perspective.

The set of databases for the content delivery instance can be reduced to only one "web" and the size of this instance in default configuration can be decreased to 20 MB  (!!!) by removing the whole "/sitecore" folder.

There are ready-to-go web.configs and backups of the databases for a quick configuration effort.

Saturday, January 17, 2009

Friday Gotcha: Sitecore.Data.Items.Item.Fields


For the sake of performance, Sitecore will not give you all fields in the FieldCollection in the following code, only fields with explicit values on item level, including empty string:

foreach(Sitecore.Data.Fields.Field field in Sitecore.Context.Item.Fields)
{
  // here you will see only fields with values (even empty string) set on item level
  // fields with null in them or standard values will not be here.
}

However, you will be able to access fields with either Sitecore.Context.Item.Fields["title"] or with a PageEditor enabled Web Control such as sc:text: <sc:text field="title" runat="server" />

In order to have all the fields in the FieldCollection and iterate through them, make sure your code will include Sitecore.Data.Items.Item.Fields.ReadAll() call before your foreach:

Sitecore.Context.Item.Fields.ReadAll();
foreach(Sitecore.Data.Fields.Field field in Sitecore.Context.Item.Fields)
{
  // do your thing here
}

FAQ about this.

Wednesday, January 14, 2009

One of the things to remember before you go live


As I mentioned in one of my previous posts, it is always a good idea and common sense to block at least a week in project's timeline for load testing and performance optimization of your web site before the launch.

The performance optimization is a good topic for a separate blog and will not fit into one post BUT one of the things can be done pretty easily and give drastic performance improvements (2x and more times) for the content delivery side, also take the load of your SQL box. I am talking about database-level caching, particularly Item and Data caches.

First thing to check is the current max cache sizes of Item and Data caches on the cache statistics page, and it makes a lot of sense to perform this check while your solution is under the load testing: http://localhost/sitecore/admin/cache.aspx

If the values of "Size" column for web[data] and web[items] are approaching the "MaxSize" value, consider adjusting the values in web.config. There are no actual rules here 'cause the recommended values depend on your solution (content volume mostly). So by playing with the values, find the one that fits your needs. What will happen if your caches are maxed out? Nothing too exciting, actually. The next item information will trap into the cache but some lonely item will be evicted without two week notice.

You can find the description of cache settings here, but in nutshell, there are multiple locations where you can specify cache sizes:
1. /databases/database
2. /cacheSizes/databases
3. /settings/Caching.Default<cache_name>Size
4. value assigned in the assembly as a last try.

This is the order of processing. If any value greater than 0 is defined in a higher level, this value will be returned.

As for #3, it is important to note that some caches do not have the default cache values defined in the <settiings> section. This includes ChildCache, ParentCache and ItemCache. So if the search of the cache size falls down to #3, the value specified in code will be assigned.

As a part of the cache value assignment process, check this known issue for 5.3.x version, you may need to adjust the names of the caches. In Sitecore 6 it is not an issue.

I also want to stress that same rules are applied to other database-level and website-level caching types.