We are happily using this approach in a couple of sites now and are looking at integrating both Articulate (blog) and Dialogue (forum).
Are there any recommended approaches for this, particularly as all these projects use route hijacking and their own MasterModel; I aware of the below posts but am still struggling conceptually how to do this cleanly (without reverting to use of dynamic/object) and have an upgrade path to future Articulate/Dialogue updates.
In the Articulate example it looks as if ModelLogic is extended create Articulate compatible models, are these calling methods in the the Articulate library (e.g. creating a ListModel).
Should we exclude the Articualte document types from model generation [assembly: IgnoreContentType("Articulate")]?
I've haven't tried to integrate any of these packages yet, but when Shannon showed me Articulate I discussed with him how it could be integrated. We came up with an event which you can use. More info here: http://issues.umbraco.org/issue/U4-5065.
Ariculate creates it's own models and passes those to views and with this event you can change that model.
public class UmbracoEvents : ApplicationEventHandler
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
PreRenderViewActionFilterAttribute.ActionExecuted += PreRenderViewActionFilterAttribute_ActionExecuted;
}
protected void PreRenderViewActionFilterAttribute_ActionExecuted(object sender, ActionExecutedEventArgs e)
{
if (e.Controller.GetType().ToString() == "Articulate.Controllers.ArticulateRichTextController")
{
var oldModel = (Articulate.Models.PostModel)e.Model;
var newModel = new Model();
newModel.OldModel = oldModel;
e.Model = newModel;
}
}
}
In the above example you take the Articulate model and put that into your own model. This way you can still have a MasterModel for example. You need to change the views to accept the new model and change the view to work with that model, but at least you can have your own model and the Articulate model as part of that. You'll probably run into some other issues, but let me know how it goes.
Thanks, have now got Articulate integrated and are using the following slightly modified event handler:
protected void PreRenderViewActionFilterAttributeActionExecuted(object sender, ActionExecutedEventArgs e)
{
if (e.Controller.GetType().ToString().StartsWith("Articulate.Controllers"))
{
var articulateModel = (Articulate.Models.MasterModel)e.Model;
var newModel = ModelLogic.CreateMasterModel();
newModel.ArticulateModel = articulateModel;
e.Model = newModel;
}
}
Then in our themed Views and Partials (partials where needed) we modify the view logic to use our MasterModel and pull out the Articulate model as needed into a variable for use when rendering Articulate content / calls to Articulate helpers.
Also found it helpful to have a copy of the Articulate repo available locally (compile DLL in debug mode) so we could figure out which partials were causing The model item passed into the dictionary is of type 'x', but this dictionary requires a model item of type 'y' errors.
Additional thing to note is that the Tags controller uses an 'ArticulateVirtualPage' as it's IPublishedContent which means CurrentPage throws an exception; our Master page called an Action that used CurrentPage to get settings from the site root; we had to modify this to use Umbraco.TypedContentAtRoot.
Will post a follow up if decide to integrate Dialogue.
In our Articulate theme Views we then modify them to work with IMasterModel and pull out the Articulate model as needed, e.g. Master.cshtml:
@using Articulate
@inherits UmbracoViewPage<Hybrid.Extensions.Models.IMasterModel>
@{
Layout = null;
var blogModel = Model.ArticulateModel;
}
// render master using @Model for site MasterModel (navigation etc) and @blogModel for Articulate e.g. @Html.RssFeed(blogModel)
Post.cshtml
@using Articulate
@using Articulate.Models
@model Hybrid.Extensions.Models.IMasterModel
@{
Layout = "Master.cshtml";
var blogModel = Model.ArticulateModel as PostModel;
ViewBag.CssBodyClass = "post-template";
}
@if (blogModel != null)
{
// render post using blogModel
}
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
using Umbraco.Web.Mvc;
using Application.Core.Builders;
namespace Application.Web.App_Start
{
public class ModelManipulationComposer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Components().Append<ModelManipulationComponent>();
}
}
public class ModelManipulationComponent : IComponent
{
public void Initialize()
{
PreRenderViewActionFilterAttribute.ActionExecuted += PreRenderViewActionFilterAttribute_ActionExecuted;
}
protected void PreRenderViewActionFilterAttribute_ActionExecuted(object sender, ActionExecutedEventArgs e)
{
if (e.Controller.GetType().ToString().StartsWith("Articulate.Controllers"))
{
var articulateModel = (Articulate.Models.MasterModel)e.Model;
var newModel = ModelLogic.CreateMasterModel();
newModel.ArticulateModel = articulateModel;
e.Model = newModel;
}
}
}
}
Articulate/Dialogue integration
Hi,
We are happily using this approach in a couple of sites now and are looking at integrating both Articulate (blog) and Dialogue (forum).
Are there any recommended approaches for this, particularly as all these projects use route hijacking and their own
MasterModel
; I aware of the below posts but am still struggling conceptually how to do this cleanly (without reverting to use of dynamic/object) and have an upgrade path to future Articulate/Dialogue updates.In the Articulate example it looks as if
ModelLogic
is extended create Articulate compatible models, are these calling methods in the the Articulate library (e.g. creating aListModel
). Should we exclude the Articualte document types from model generation[assembly: IgnoreContentType("Articulate")]
?Any pointers/examples appreciated.
Thanks.
Hello,
I've haven't tried to integrate any of these packages yet, but when Shannon showed me Articulate I discussed with him how it could be integrated. We came up with an event which you can use. More info here: http://issues.umbraco.org/issue/U4-5065.
Ariculate creates it's own models and passes those to views and with this event you can change that model.
In the above example you take the Articulate model and put that into your own model. This way you can still have a MasterModel for example. You need to change the views to accept the new model and change the view to work with that model, but at least you can have your own model and the Articulate model as part of that. You'll probably run into some other issues, but let me know how it goes.
Jeroen
Thanks, have now got Articulate integrated and are using the following slightly modified event handler:
Then in our themed Views and Partials (partials where needed) we modify the view logic to use our MasterModel and pull out the Articulate model as needed into a variable for use when rendering Articulate content / calls to Articulate helpers.
Also found it helpful to have a copy of the Articulate repo available locally (compile DLL in debug mode) so we could figure out which partials were causing
The model item passed into the dictionary is of type 'x', but this dictionary requires a model item of type 'y'
errors.Additional thing to note is that the Tags controller uses an 'ArticulateVirtualPage' as it's
IPublishedContent
which meansCurrentPage
throws an exception; our Master page called an Action that usedCurrentPage
to get settings from the site root; we had to modify this to useUmbraco.TypedContentAtRoot
.Will post a follow up if decide to integrate Dialogue.
Hi
I'm try to do the same :). What are you doing here: ModelLogic.CreateMasterModel()?
Thanks for your help.
Best regards,
Manuel
See Hybrid Framework for example - ModelLogic.cs
In our Articulate theme Views we then modify them to work with IMasterModel and pull out the Articulate model as needed, e.g. Master.cshtml:
Post.cshtml
Hi thanks for your help. It's working if I use an articulate model but I got erverytime a null reference exception here:
@{
Layout = null;
var articulateMasterModel = Model.ArticulateModel;
}
if I call an other page.
do you have any idea how I can solve this?
thx & best regards,
Manuel
Apologies for the belated reply.
Sorry not really without seeing code, I'm not sure what you mean by 'call on another page'.
We only use the Articulate models with our views in App_Plugins\Articulate\Themes, other views on the site we just ignore it.
I'm trying to do the same in an Umbraco 8 project that I have built using the same architecture at the Hybrid 7 framework.
The way you hook into the startup events has changed so if anyone knows how to alter
PreRenderViewActionFilterAttribute.ActionExecuted += PreRenderViewActionFilterAttribute_ActionExecuted;
for Umbraco 8 please post.
Got it working
is working on a reply...