Search code examples
asp.net-mvcn2n2cms

N2 for MVC - how to get Zones working?


I'm looking at the N2 CMS Minimal Example for MVC (from here)

I've figured out most of it, but I see that N2 supports 'Parts' that you can drop into 'Zones'.

How do I get Zones and Parts working in the minimal example?

The Html.Zone() command doesn't seem to work out-of-the-box.


Solution

  • With a bit of help from libardo at the N2 forum

    Here's the 'minimal' way of adding Zones and Parts to the N2 Minimal Example for MVC:

    1) Add this namespace in the web.config pages.namespaces node:

    <pages>
      <namespaces>
        ...
        <add namespace="N2.Web.Mvc.Html"/>
        ...
    

    2) Add a Container page model, using the AvailableZones attribute:

    using N2.Integrity;
    ...
    
    [Definition("ContainerPage")]
    [AvailableZone("Right", "MyRightZone")]
    public class ContainerPage : N2.ContentItem
    {
       ...
    

    3) Add Container controller in the usual N2 manner, nothing special needed here to make it a container:

    [Controls(typeof(ContainerPage))]
    public class ContainerController : ContentController<ContainerPage>
    {
        ...
    

    4) In the view for the container, use the Html.DroppableZone function:

    <div class="n2zone">
      <% Html.DroppableZone("MyRightZone").Render(); %>
    </div>
    

    5) Add a part model, e.g. this one just shows Title as a string. Note that PartDefinition is what makes it a Part that can be dropped into a Zone:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using N2;
    using N2.Details;
    
    namespace MyProject.Models
    {
        [PartDefinition("SimplePart")]
        [WithEditableTitle("Title", 10)]
        public class SimplePart : ContentItem
        {
            [DisplayableLiteral()]
            public override string Title
            {
                get { return base.Title; }
                set { base.Title = value; }
            } 
        }
    }
    

    6) Add a Controller for the Part. This is the usual N2 controller except that we override Index to return a PartialView:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using N2.Web;
    using N2.Web.Mvc;
    using MyProject.Models;
    
    namespace MyProject.Controllers
    {
        [Controls(typeof(SimplePart))]
        public class SimplePartController : ContentController<SimplePart>
        {
    
            public override ActionResult Index()
            {
                return PartialView(CurrentItem);
            }
    
        }
    }
    

    7) Finally, add a partial view for the Part controller. Nothing special is needed here:

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MyProject.Models.SimplePart>" %>
    <div class="simplePart">
      <%= Html.DisplayContent(m => m.Title) %>
    </div>
    

    In the N2 editor you can then drop as many SimpleParts as you like into the ContainerPage pages.