Quantcast
Channel: Developer to developer
Viewing all articles
Browse latest Browse all 9076

DefaultContentAreaLoader does not load blocks from content area not having English language

$
0
0

In one of the projects we took over recently there is a scheduled job which is indexing all the pages for search engine (not Find).

One of new features requested by customer was to have a page type strongly built with wide range of content blocks, so to be able to use values from blocks we had to pull some of the datafrom blocks inserted into content areas when indexing.

After initial release we noticed that sometimes the content is not loaded properly, then I started look into the extension method used there and it seems that DefaultContentAreaLoader have issues load blocks when called from scheduled job.

Steps to reproduce with Alloy site:

  1. Make sure to have enabled at least 2 languages (e.g. English and Swedish) and create start pages for each
  2. Make sure English start page have inserted into Large content area 3 blocks of type TeaserBlock
  3. Create for one of the Teaser blocks the Swedish language version and add it to Swedish start page
  4. Create 2 new Teaser blocks only in Swedish and add to Swedish start page
  5. Add class with extension methods

    	public static class ContentAreaExtensions
    	{
    		private static readonly Injected<IContentLoader> ContentLoader;
    		public static IEnumerable<T> GetItemsWithContentLoader<T>(this ContentArea contentArea) where T : ContentData
    		{
    			if(contentArea == null)
    			{
    				return new List<T>();
    			}
    			return contentArea.FilteredItems
    				.Select(item => ContentLoader.Service.Get<ContentData>(item.ContentLink))
    				.Select(icontent => icontent as T)
    				.Where(result => result != null);
    		}
    		public static IEnumerable<T> GetItemsWithGetContentExtension<T>(this ContentArea contentArea) where T : ContentData
    		{
    			if (contentArea == null)
    			{
    				return new List<T>();
    			}
    			return contentArea.FilteredItems
    				.Select(item => item.GetContent())
    				.Select(icontent => icontent as T)
    				.Where(result => result != null);
    		}
    	}​
  6. Add scheduled job

    	[ScheduledPlugIn(DisplayName = "Blocks loader job")]
    	public class BlocksLoaderJob : ScheduledJobBase
    	{
    		private readonly Injected<IContentLoader> _contentLoader;
    		private readonly Injected<ILanguageBranchRepository> _languageBranchRepository;
    		public BlocksLoaderJob()
    		{
    		}
    		/// <summary>
    		/// Called when a scheduled job executes
    		/// </summary>
    		/// <returns>A status message to be stored in the database log and visible from admin mode</returns>
    		public override string Execute()
    		{
    			StringBuilder builder = new StringBuilder();
    			foreach (var lang in _languageBranchRepository.Service.ListEnabled())
    			{
    				var langVer = _contentLoader.Service.Get<StartPage>(ContentReference.StartPage, new CultureInfo(lang.LanguageID));
    				if (langVer != null)
    				{
    					var blocks = langVer.MainContentArea.GetItemsWithContentLoader<TeaserBlock>().ToList();
    					var blocksLoadedByExt = langVer.MainContentArea.GetItemsWithGetContentExtension<TeaserBlock>().ToList();
    					builder.AppendLine($"Language {lang.Name}: <br /> Blocks with content loader: {blocks.Count()} | Blocks with content AREA loader: {blocksLoadedByExt.Count()} <br />");
    				}
    			}
    			return builder.ToString();
    		}
    	}​
  7. Run the scheduled job
  8. Result is

    Language English:
    Blocks with content loader: 3 | Blocks with content AREA loader: 3
    Language svenska:
    Blocks with content loader: 3 | Blocks with content AREA loader: 1 ​

Simply we can see that when we call from scheduled job the way to load blocks with IContent GetContent(this ContentAreaItem item)extension blocks missing English language version are not loaded (only 1 block loaded for Swedish)

I started looking at the extension and internally Episerver calls there method  IContentGet(ContentAreaItem contentAreaItem) from DefaultContentAreaLoader which internally uses language from IContentLanguageAccessor _languageAccessor and that seems to be always English when called from scheduled job.

Note: it works just fine when called e.g. when publishing page from publish content event


Viewing all articles
Browse latest Browse all 9076

Trending Articles