Can Glass.Mapper V3 support language fallback (field-level and item-level)?
Asked Answered
I

2

6

We just updated our project to use Glass.Mapper V3. We LOVE it. But we've encountered an issue. It doesn't seem to respect language fallback.

We have our site set up so that if a user picks a non-default language, they will see the item of that language if it exists. If not, they will see the default ("fallback") language version. We have also set this up at the field level, so that if there is a non-default version of an item but not all the fields are changed, any unchanged fields will fall back to the default language version's value for that field.

Is there anything we can do to enable Glass to use language fallback?

Irishirishism answered 30/10, 2013 at 19:48 Comment(6)
Which language fallback module are you using? The Partial Language Fallback module uses a standard values provider, so it should work with Glass without a problem. I have never used the Fallback Language Item Provider, so I'm not so sure about that one.Joses
And is it PLF that's failing, or just the item/version-level fallback?Ida
We're using both the Partial Language Fallback (field-level) and the Fallback Language Item Provider (item-level) modules. When I try to get a language version of an item that doesn't exist (try to get "es" when only "en" exists), I get null. If there is an "es" item but some fields are unchanged (falling back to the "en" version), they appear empty when accessed from Glass.Irishirishism
Dan, can you email me more details of what you are trying to do? In theory Glass should work because it just wraps the Sitecore item API, i.e. anything that happens behind an item, e.g. the fallback module, should still work.Autarky
@techphoria414, I stand corrected. Only the Fallback Language Item Provider module is not working. Upon further investigation, it is returning values from the field-level fallback, but when fields are lists of items, there are no items in the list (because item-level fallback doesn't get them).Irishirishism
@MichaelEdwards It looks to be related to this: groups.google.com/d/msg/glasssitecoremapper/giWIWqlGFS0/…. When I check the item in my code (before calling item.GlassCast()), item.Versions.Count is 0. Looking at your source for SitecoreService.cs, it looks like that check is invalidating it. github.com/mikeedwards83/Glass.Mapper/blob/master/Source/…. Thoughts or recommendations?Irishirishism
A
6

I am updating this with a bit of background on why we do the check. If you ask for a Sitecore item that doesn't exist you get a null value, so that is simple to handle. However if you ask for a Sitecore item that doesn't exist in that particular language returns an item with no versions. This means we have to do this check because otherwise Glass would end up returning empty class which I don't think makes much sense.

This answer will get a little experimental.

First in the the Spherical.cs file you need to disable the check:

protected void Application_BeginRequest()
{
    Sitecore.Context.Items["Disable"] = new VersionCountDisabler();
}

We can then move the check to later on to the Object Construction pipeline. First create a task:

public class FallbackCheckTask : IObjectConstructionTask
{
    public void Execute(ObjectConstructionArgs args)
    {
        if (args.Result == null)
        {
            var scContext = args.AbstractTypeCreationContext as SitecoreTypeCreationContext;
            if (scContext.Item == null)
            {
                args.AbortPipeline();
                return;
            }    
            //this checks to see if the item was created by the fallback module
            if (scContext.Item is Sitecore.Data.Managers.StubItem)
            {

                return;
            }

            // we could be trying to convert rendering parameters to a glass model, and if so, just return.
            if (String.Compare(scContext.Item.Paths.FullPath, "[orphan]/renderingParameters", true) == 0)
            {
                return;
            }

            if (scContext.Item.Versions.Count == 0)
            {
                args.AbortPipeline();
                return;
            }
        }
    }
}

Then finally register this task in the GlassMapperScCustom class:

    public static void CastleConfig(IWindsorContainer container){
        var config = new Config();

        container.Register(
            Component.For<IObjectConstructionTask>().ImplementedBy<FallbackCheckTask>().LifestyleTransient()
            );
        container.Install(new SitecoreInstaller(config));
    }

I haven't tested this but it should in theory work <- disclaimer ;-)

Autarky answered 31/10, 2013 at 16:52 Comment(4)
Well, Mike Edwards strikes again. It works exactly as described. I considered adding a check to see if the current site had fallback enabled, but decided that it was an unnecessary performance hit since the code will still work whether fallback is enabled or not. Great work and thanks again, Mike.Irishirishism
Rendering Parameter items don't have versions, so this code aborts the pipeline prematurely when trying to use GetParameters in a control (from this tutorial glass.lu/docs/tutorial/sitecore/tutorial23/tutorial23.html). We need to place a check above the second AbortPipeline call to make sure scContext.Item is not a 'renderingParameters' item.Jacob
Has anyone implemented this in Sitecore 7.2 with MVC fine? Unless a version is created for the language, no item seems to be getting returned. However, this only appears to be when using Sitecore Query + Glass, perhaps this is a separate issue?Crystallite
@PirateKitten Can you log your issue on GitHub and I will take a look.Autarky
C
1

There are few potential issues with provided solution when sitecore 7 (7.2) + IoC + solr + mvc is used.

When using IoC ex Winsdor please make sure that your Global.asax looks like this one <%@ Application Codebehind="Global.asax.cs" Inherits="Sitecore.ContentSearch.SolrProvider.CastleWindsorIntegration.WindsorApplication" Language="C#" %>. Once, by mistake this file has been changed to <%@ Application Codebehind="Global.asax.cs" Inherits="Merck.Manuals.Web.Global" Language="C#" %> and language fallback was not working. Also the errors we were getting wasn't descriptive as we thought that solr schema is incorrect.

Code Sitecore.Context.Items["Disable"] = new VersionCountDisabler(); can be added to PreprocessRequestProcessor and it works fine which is better solution that modifying global.asax.

Cyndycynera answered 8/5, 2015 at 12:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.