In a recent project I was working on, I found myself needing a way to be able to get at the rendering parameters and / or datasource of the rendering when using controller renderings. Below is a quick snippet to show one approach of how you can approach this problem.
public class ControllerSitecoreContext : SitecoreContext, IControllerSitecoreContext { private IGlassHtml glassHtml; public ControllerSitecoreContext(IGlassHtml glassHtml) { this.glassHtml = glassHtml; } public T GetRenderingParameters() where T : class { string parameters = RenderingContext.CurrentOrNull.Rendering["Parameters"]; if (String.IsNullOrEmpty(parameters)) { return default(T); } return glassHtml.GetRenderingParameters(parameters); } public T GetDataSource() where T : class { string dataSource = RenderingContext.CurrentOrNull.Rendering.DataSource; if (String.IsNullOrEmpty(dataSource)) { return default(T); } Guid dataSourceId; if (dataSource.StartsWith("query:")) { string query = dataSource.Remove(0, 6); var item = PageContext.Current.Item.Axes.SelectSingleItem(query); if (item != null) return item.GlassCast(); else return default(T); } else { return Guid.TryParse(dataSource, out dataSourceId) ? GetItem(dataSourceId) : GetItem(dataSource); } } } public interface IControllerSitecoreContext : ISitecoreContext { T GetDataSource() where T : class; T GetRenderingParameters() where T : class; }
It’s worth noting that by inheriting from the regular SitecoreContext provided by Glass Mapper, you can treat and use this in the same way as the regular ISitecoreContext in Glass Mapper for Sitecore. In use you can simply then inject your IControllerSitecoreContext as a dependency – something like this
public class MyController : Controller { private IControllerSitecoreContext sitecoreContext; public MyController(IControllerSitecoreContext sitecoreContext) { this.sitecoreContext = sitecoreContext; } }
Hope this helps Nat.
I give it 20 minutes before Mike Edwards pings me to tell me there is a better way 😉
I will be first 🙂 but it won’t be about Glass. I understand why you check the Rendering.Datasource but if you see that it’s not empty you can simply get to the item from Rendering.Item. That one can be many things but with the datasource defined it will be IT. Here’s some more on the subject: http://jockstothecore.com/sitecore-mvc-item-maze/
I know we’re having this conversation on Twitter, but if you don’t require multiple inheritance then you can inherit from Glass.Mapper.Sc.Web.Mvc.GlassController which give you access to GetRenderingItem (the datasource), GetControllerItem (datasource or current item) and GetRenderingItem (rendering parameters).
The GlassController also gives you access to SitecoreContext, so in the above example you should be able to remove that inheritance, not requiring multiple inheritance unless you have a more complex usage you have where chaining to GlassController is not going to be possible.
I missed the conversation on Twitter, but I like this topic….
How can you mock the GetRenderingParameters if you inherit your controller from GlassController?
I like the approach or having a base controller, but I think that’s harder to mock? maybe I am saying something stupid, would not make life easier to add the GetRenderingParameters somewhere else that’s easier to mock?