I have found a solution to my issue.
It pretty much IS as simple(ish) as just telling N2 CMS to render the ContentItem as you can use Html.DroppableZone()
by passing it the ContentPage... ish...
Html.DroppableZone()
can accept a ContentItem
and a "ZoneName" (string
) and it will render the specified ZoneName as if it was on the page the is contained in the ContentItem
. This does mean you're not rendering the page BUT a Part
from the page BUT in our case that's fine as all of the pages we want to render actually contain a part called "ServiceTemplate" which contains all the info we want to render on the other pages.
(Although you could possibly work out a way to use the original page's View to get the layout of the parts if you wanted the full page... Good luck as I had a go at it and found lots of issues with @section main{...}
etc...)
Controller
So as that's all fairly confusing so here is our Controller:
using System.Linq;
using System.Web.Mvc;
using N2;
namespace Data8.Website.N2.Controllers
{
public class ServiceDocsController : Controller
{
// GET: ServiceDocs
// Returns the specified service doc (partial view for AJAX)
public ActionResult Index(string url)
{
// Get the Content Item for that N2 Page (if it is an N2 Page!)
ContentItem contentItem = Context.Current.UrlParser.Parse(url);
// Ensure we found a valid N2 Content Page that contains a Service Template as one of it's parts... (these are all we will render!)
if (contentItem == null || !contentItem.IsPage || contentItem.Children.All(ci => ci.TemplateKey != "ServiceTemplate"))
{
return new HttpNotFoundResult("Page doesn't exist or doesn't contain a Service Template Part!");
}
// Return the partial view of that contentItem
return PartialView(contentItem);
}
}
}
It:
- Takes the URL of the page you want
- Uses the
N2
UrlParser
to find the ContentItem
for that page
- Check's it's the type of page we want (WE are only after pages with a
ServiceTemplate
part on it)
- Then passes that
ContentItem
to the Index view
FYI: We will be using AJAX to draw this on demand so it only returns a partial... You could use return View(contentItem);
instead to draw a full page with Layouts etc...
View
Now in the View:
@ @using N2
@model ContentItem
@foreach (ContentItem contentItem in Model.Children)
{
if (contentItem.Visible && contentItem.ZoneName != null && !contentItem.IsPage && contentItem.TemplateKey == "ServiceTemplate")
{
@Html.DroppableZone(Model, contentItem.ZoneName).Render()
}
}
The view loops though the ContentItem's Children and for each child it finds that matches the ServiceTemplate
Part we are looking for it renders it using the Html.DroppableZone()
function passing it the full page's ContentItem and the ContentItem's ZoneName
for this ServiceTemplate
.
SO as I said "SIMPLE!" ;)