I have a few how-to pages that exist in the N2 CMS system and I want to include one or two of them at the bottom of a normal MVC view. I have manged to use the N2 APIs to pull back a ContentItem for the specific page in the Controller using:
ContentItem contentItem = global::N2.Context.Current.UrlParser.Parse("/support/sample-code/example-one");
Now I was hoping it was as simple as pulling this content item back and then asking N2 to render the related page/parts in place in the view but I haven't been able to find ANY docs or info on if this is possible or how I would go about it.
Can anyone point me in the right direction?
Thanks. :)
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...)
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:
N2
UrlParser
to find the ContentItem
for that pageServiceTemplate
part on it)ContentItem
to the Index viewFYI: 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...
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!" ;)