Today I created a rendering component which has around 10 fields but the whole component is not editable in Experience Editor. I decided to use Edit Frame from Glass Mapper. The BeginEditFrame wants all the editable fields as a parameter. But for around 10 fields not that comfortable.
The following code snippet creates an Edit Frame only with 1 field.
| @using Glass.Mapper.Sc.Web.Mvc | |
| @model IYourModel | |
| @using (@Html.Glass().BeginEditFrame(Model, "Edit The Component", x => x.Image)) | |
| { | |
| // your code | |
| } |
Let’s implement a method which gets all the fields from your model.
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Linq.Expressions; | |
| namespace YourProject.Extensions | |
| { | |
| public static class ExperienceEditor | |
| { | |
| public static Expression<Func<T, object>>[] GetAllEditFrameFields<T>() where T : IGlassBase | |
| { | |
| var propertyNames = typeof(T).GetProperties().Select(p => p.Name); | |
| var expressions = new List<Expression<Func<T, object>>>(); | |
| foreach (var propertyName in propertyNames) | |
| { | |
| var param = Expression.Parameter(typeof(T), "model"); | |
| var body = Expression.Convert(Expression.PropertyOrField(param, propertyName), typeof(object)); | |
| expressions.Add(Expression.Lambda<Func<T, object>>(body, param)); | |
| } | |
| return expressions.ToArray(); | |
| } | |
| } | |
| } |
This method gets the model property names with some reflection magic and creates the lambda expressions dynamically.
You can see that the method has a limitation to allows only IGlassBase interfaces. It is needed to make it more safe as this interface contains all the base properties for a Sitecore item.
| using System; | |
| using System.Collections.Generic; | |
| using Sitecore.Globalization; | |
| namespace YourProject.Models | |
| { | |
| public interface IGlassBase | |
| { | |
| Guid Id { get; set; } | |
| Language Language { get; } | |
| int Version { get; set; } | |
| IEnumerable<Guid> BaseTemplateIds { get; } | |
| string TemplateName { get; } | |
| Guid TemplateId { get; set; } | |
| string Name { get; set; } | |
| string Url { get; } | |
| string FullPath { get; } | |
| } | |
| } |
Let’s use this util method in our view.
| @using Glass.Mapper.Sc.Web.Mvc | |
| @using YourProject.Extensions | |
| @model IYourModel | |
| @using (@Html.Glass().BeginEditFrame(Model, "Edit The Component", ExperienceEditor.GetAllEditFrameFields<IYourModel>())) | |
| { | |
| // your code | |
| } |
![Tamás Tárnok = [ C#, Sitecore, … ]](https://trnktms.com/wp-content/uploads/2021/11/pxart_white-small.png)
Nice idea! That works really nicely with view models. Do you mind if add this or something similar to the framework?
LikeLiked by 3 people
That would be really cool 🙂 You can do it more optimizely directly in Glass.Mapper. Because now it is resolving the model twice. I would really appreciate it!
LikeLiked by 1 person