In the next release of Glass.Mapper.Sc we will support mapping rendering parameters to object, in this post I will explain how we implemented this.

You can get a pre-release version of this from the Glass.Mapper builder server right now (see the download page to find out how).

I had recently been going through some of the Glass.Mapper.Sc unit tests and updating them to use a fake Item rather than an item pulled from the Sitecore database. To do this I created a method which I could pass a dictionary of Ids and values to the item which contained the field values:

        public static Item CreateFakeItem(Dictionary<Guid, string> fields, string name="itemName")
        {
            var id = new ID(Guid.NewGuid());
            var templateId = new ID(Guid.NewGuid());
            var language = Language.Current;
            var version = Sitecore.Data.Version.Latest;
            
            var itemDefinition = new ItemDefinition(id, name, id, ID.Null);
            var fieldList = new FieldList();

            foreach (var fieldId in fields.Keys)
            {
                fieldList.Add(new ID(fieldId), fields[fieldId]);
            }

            var itemData = new ItemData(itemDefinition, language, version, fieldList);
            var item = new Item(id, itemData, new Database("master"));
            return item;
        }

The problem with this method was that fields had to be reference by ID, they couldn't be referenced by the field name. This got me thinking about a possible solution and I wondered if the only requirement to get fields to work by name would be to specify a proper template ID. So I update the CreateFakeItem method to accept a template ID and a database:

        public static Item CreateFakeItem(Dictionary<Guid, string> fields, ID templateId, Database database, string name = "ItemName")
        {
            var id = new ID(Guid.NewGuid());
            var language = Language.Current;
            var version = Sitecore.Data.Version.Latest;

            var itemDefinition = new ItemDefinition(id, name, templateId, ID.Null);
            var fieldList = new FieldList();

            if (fields != null)
            {
                foreach (var fieldId in fields.Keys)
                {
                    fieldList.Add(new ID(fieldId), fields[fieldId]);
                }
            }

            var itemData = new ItemData(itemDefinition, language, version, fieldList);
            var item = new Item(id, itemData, database);
            return item;
        }

I then created a GetRenderingParameters method that would read the values in the rendering parameters string into the appropriate fields:

        public T GetRenderingParameters<T>(NameValueCollection parameters, ID renderParametersTemplateId) where T:class{

            var item = Utilities.CreateFakeItem(null, renderParametersTemplateId, SitecoreContext.Database, "renderingParameters");

            using (new SecurityDisabler() )
            {
                using (new VersionCountDisabler())
                {
                    item.Editing.BeginEdit();

                    foreach (var key in parameters.AllKeys)
                    {
                        item[key] = parameters[key];
                    }
                    T obj = item.GlassCast<T>();

                    item.Editing.CancelEdit();
                    return obj;
                }
            }

        }

Now that I had an item that contained my rendering parameters as field values I could send it through the normal Glass.Mapper mapping process using the GlassCast method. Finally I just needed to cancel the item editing to ensure no values are saved back to the database.

Using the method we now have a very quick way to make fake versions of items which are useful for unit testing, this is one of the tests for Glass.Mapper.Sc:

            //Assign
            string fieldValue = "3.141592";
            decimal expected = 3.141592M;
            var fieldId = Guid.NewGuid();

            var item = Helpers.CreateFakeItem(fieldId, fieldValue);
            var field = item.Fields[new ID(fieldId)];

            var mapper = new SitecoreFieldDecimalMapper();


            //Act
            var result = (decimal)mapper.GetField(field, null, null);

            //Assert
            Assert.AreEqual(expected, result);

If you look at the tutorial you will also see under "Other" that you can actually pass any query string formatted string to Glass.Mapper and have it mapped to a class as long as you have a matching template in Sitecore.

For more information on how to access rendering parameters using Glass.Mapper see

  • Tutorial 23 - Rendering Parameters
  • .

    Glass needs your support!

    Glass.Mappper.Sc is supported by the generous donations of the Glass.Mapper.Sc community! Their donations help fund the time, effort and hosting for the project.

    These supporters are AMAZING and a huge thank you to all of you. You can find our list of supporters on the Rockstars page.

    If you use Glass.Mapper.Sc and find it useful please consider supporting the project. Not only will you help the project but you could also get a discount on the Glass.Mapper.Sc training and join the Rockstars page.

    Become a Rockstart