3

I am using Glass Mapper v4 with Autofac and cant figure out how to make it work with the Language Item Fall back module. There are examples of creating a class that implements IObjectConstructionTask (see below)

public class FallbackCheckTask : IObjectConstructionTask
{
    public void Execute(ObjectConstructionArgs args)
    {
        if (args.Result == null)
        {
            var scContext = args.AbstractTypeCreationContext as SitecoreTypeCreationContext;

            // if the item itself is null, regardless of version, abort
            if (scContext.Item == null)
            {
                args.AbortPipeline();
                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;
            }

            // the default glassmapper code would simply abort pipeline if the context items version count for the current langauge was 0
            // but this does not take item fallback into account
            // added here a check on the fallback extension method GetFallbackItem, recursively (for chained fallback)
            // and then if that fallback item is null or it's version count is 0 (and only then) would you go ahead and abort the pipeline
            if (scContext.Item.Versions.Count == 0)
            {
                var fallBackItem = CheckRecursivelyForFallbackItem(scContext.Item);
                if (fallBackItem == null)
                    args.AbortPipeline();
                else if (fallBackItem.Versions.Count == 0)
                    args.AbortPipeline();
                return;
            }
        }
    }

    // in the case of chained fallback, eg fr-CA -> en-CA -> en
    // could be that the middle languages don't have versions either, but DO have a fallback item
    // therefore, must check back further until either a version is found, or there are no more fallback items
    private Item CheckRecursivelyForFallbackItem(Item thisItem)
    {
        var fallBackItem = thisItem.GetFallbackItem();
        if (fallBackItem != null)
        {
            if (fallBackItem.Versions.Count == 0)
                fallBackItem = CheckRecursivelyForFallbackItem(fallBackItem);
        }
        return fallBackItem;
    }
}

Then you register (with Castle Windsor)

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

            container.Register(
               Component.For<IObjectConstructionTask>().ImplementedBy<FallbackCheckTask>().LifestylePerWebRequest()
              );
          //  config.EnableCaching = false;

            container.Install(new SitecoreInstaller(config));
        }

I am using Autofac and do not know how to perform the same action as above and assure it happens in the right order. I am registering my types the typical way (See below) but it doesn't seem to be hooking my FallbackCheckTask class.

 public static void Register()
    {
        var builder = new ContainerBuilder();
        builder.RegisterControllers(typeof(MvcApplication).Assembly);

        // register our types
        builder.RegisterType<FallbackCheckTask>().As<IObjectConstructionTask>().InstancePerLifetimeScope();

        // build and set the resolver
        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    }

I also have the Language Item Fallback wired up and working as expected if glass is not involved in fetching the items values. I understand why Glass is not mapping the data out of the box, I just cant seem to get the fix working. Any thoughts?

EDIT 2015-05-21 19:00

I edited GlassMapperScCustom.cs as follows:

public static IDependencyResolver CreateResolver(){
        var config = new Glass.Mapper.Sc.Config();
        var resolver = new DependencyResolver(config);

        resolver.ObjectConstructionFactory.Add(() => new FallbackCheckTask());

        return resolver;
    }

And now its calling the Execute method of the the FallbackCheckTask only if there is a version of the item, if there is no version its not calling the method. Also, no matter what I do if I enable this Task my test query items always come back as NULL:

  var test = SitecoreContext.QuerySingle<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}");
            var test1 = SitecoreContext.Query<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}").ToList();
            var test2 = SitecoreContext.GetCurrentItem<Item>();
            var test3 = SitecoreContext.GetItem<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}");

So to sum it up, I am a little better off now then I was before but when the task class is registered queries come back as null for all items no matter if they have a version or not. As mentioned before, any help is appreciated.

Liam
  • 27,717
  • 28
  • 128
  • 190
mluker
  • 702
  • 8
  • 26
  • A long shot- have you disabled the version count? – Ian Graham May 23 '15 at 07:57
  • Yeah, I have disabled the version count. Thanks. – mluker May 26 '15 at 12:08
  • you should likely put the "Edit" as an answer. [It's perfectly acceptable to answer your own question](http://meta.stackexchange.com/questions/17845/etiquette-for-answering-your-own-question) – Liam Nov 03 '15 at 09:30

1 Answers1

2

I know you mentioned that you were using the VersionCountDisabler but does it look like this:

using(new VersionCountDisabler()){

        var test = SitecoreContext.QuerySingle<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}");
        var test1 = SitecoreContext.Query<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}").ToList();
        var test2 = SitecoreContext.GetCurrentItem<Item>();
        var test3 = SitecoreContext.GetItem<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}");

}

Or are you disabling it in some other manner?

I also notice that your fallback code doesn't seem to update the scContent.Item property. I think you need to update it to the following:

public class FallbackCheckTask : IObjectConstructionTask
{
public void Execute(ObjectConstructionArgs args)
{
    if (args.Result == null)
    {
        var scContext = args.AbstractTypeCreationContext as SitecoreTypeCreationContext;

        // if the item itself is null, regardless of version, abort
        if (scContext.Item == null)
        {
            args.AbortPipeline();
            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;
        }

        // the default glassmapper code would simply abort pipeline if the context items version count for the current langauge was 0
        // but this does not take item fallback into account
        // added here a check on the fallback extension method GetFallbackItem, recursively (for chained fallback)
        // and then if that fallback item is null or it's version count is 0 (and only then) would you go ahead and abort the pipeline
        if (scContext.Item.Versions.Count == 0)
        {
            var fallBackItem = CheckRecursivelyForFallbackItem(scContext.Item);
            if (fallBackItem == null)
                args.AbortPipeline();
            else if (fallBackItem.Versions.Count == 0)
                args.AbortPipeline();

            //don't just return but update the scContext.Item to the fallback item
            scContext.Item = fallbackItem;
        }
    }
}

// in the case of chained fallback, eg fr-CA -> en-CA -> en
// could be that the middle languages don't have versions either, but DO have a fallback item
// therefore, must check back further until either a version is found, or there are no more fallback items
private Item CheckRecursivelyForFallbackItem(Item thisItem)
{
    var fallBackItem = thisItem.GetFallbackItem();
    if (fallBackItem != null)
    {
        if (fallBackItem.Versions.Count == 0)
            fallBackItem = CheckRecursivelyForFallbackItem(fallBackItem);
    }
    return fallBackItem;
}
}
Ian Graham
  • 3,206
  • 1
  • 15
  • 23
Michael Edwards
  • 6,308
  • 6
  • 44
  • 75
  • Your updates fixed it! Thank you so much, I really appreciate it! I have one question though. Is there a more global way to disable the version counts or am I stuck doing it like you have above? – mluker May 29 '15 at 15:05
  • Wait... sorry. It fixed it from crashing but its still not actually pulling the content for the fallback language. – mluker May 29 '15 at 15:11
  • 1
    Hi, this works as I expect it to in my tests. One thing to consider in this scenario is that all sub-properties are populated in the context of the parent item. Therefore if you fallback the "root" item then the children will be populated in the language of the parent and not the user's original language. – Michael Edwards Jun 01 '15 at 18:57
  • Thanks for all of your help, it doesn't seem to work properly for me in Sitecore 8 rev3. I installed both the language fallback and the field fallback and used your code and still no luck. Taking glass out of the picture, it still wont fallback. Thanks again. – mluker Jun 04 '15 at 02:43
  • I was testing on 7.5, seems odd that it wouldn't work for a later version. I did create a custom method for the language fallback just to test. – Michael Edwards Jun 04 '15 at 06:01
  • I think I have the wrong version of the Sitecore.Sharedsource.PartialLanguageFallabck.dll. The problem is in the method "public static Language GetFallbackLanguage(this Item langItem)" the call to "var fallbackLangName = langItem[Constants.FieldIds.FallbackLanguage];" is returning null. – mluker Jun 04 '15 at 16:24
  • It turns out if I do not implement IObjectConstructionTask it works as long as I wrap all data calls with using(VersionCountDisabler()). That gets tedious, is there a better way? I tried adding it to the Global.asax with no luck (Sitecore.Context.Items["Disable"] = new VersionCountDisabler(); ) – mluker Jun 04 '15 at 19:05
  • 2
    I have written some notes on this: http://www.glass.lu/Mapper/Sc/Documentation/VersionCountDisabler – Michael Edwards Jun 22 '15 at 08:55