To install N2 CMS in a development

N2 CMS Developer Documentation
About
N2 CMS is a Web Application that simplifies the task of developing and managing web sites. The
intended audience is professional web developers and non-technical web managers.
The first version was published in 2006. Since then 45 versions have been released. The latest
version, 2.1, was published in October 2010.
Contents
About ....................................................................................................................................................... 1
System Requirements ............................................................................................................................. 5
Operating System ................................................................................................................................ 5
Web Servers ........................................................................................................................................ 5
.NET Framework .................................................................................................................................. 5
Databases ............................................................................................................................................ 5
Wildcard mapping (IIS 5-6.1) ............................................................................................................... 5
Visual Studio Development ................................................................................................................. 6
Shared Hosting .................................................................................................................................... 6
Links and Resources ................................................................................................................................ 6
Official Links......................................................................................................................................... 6
Developer documentation resources .................................................................................................. 6
Management documentation resources ............................................................................................. 6
Downloading ........................................................................................................................................... 6
N2 CMS 2.x Source Code ..................................................................................................................... 7
N2 CMS 2.x ASP.NET MVC Templates Pack ......................................................................................... 7
N2 CMS 2.x ASP.NET WebForms Templates Pack ............................................................................... 7
N2 CMS 2.x MVC Minimal Example ..................................................................................................... 7
N2 CMS 2.x C# Minimal Example ........................................................................................................ 7
N2 CMS 2.x Visual Basic Minimal Example .......................................................................................... 7
N2 CMS 2.x Compiled Framework and Management UI..................................................................... 7
Installing .................................................................................................................................................. 7
Web Platform Installer (WPI) .............................................................................................................. 7
Installing N2 CMS from Microsfot Web Platform Installer.............................................................. 7
Installing N2 CMS from Internet Information Services (IIS) Manager ........................................... 16
Installing N2 CMS from Microsoft WebMatrix .............................................................................. 21
Installing not yet published releases using WPI ............................................................................ 22
Unzip.................................................................................................................................................. 24
Installing ASP.NET Template Pack from zip .................................................................................. 25
Changing databases........................................................................................................................... 28
Using IIS ............................................................................................................................................. 29
Using Visual Studio Integrated Development Server ........................................................................ 29
Installing Code Snippets .................................................................................................................... 29
Installing Visual Studio Item Templates ............................................................................................ 30
Installing Intellisense Documentation for Visual Studio ................................................................... 30
Software Architecture ........................................................................................................................... 30
CMS Framework vs. Web Application ............................................................................................... 30
Web Application Architecture ........................................................................................................... 31
CMS Framework Architecture ........................................................................................................... 31
WebForms vs. MVC ........................................................................................................................... 32
Routing to content with ASP.NET MVC ......................................................................................... 32
Development topics .............................................................................................................................. 34
Converting the project to Visual Studio 2010 ................................................................................... 34
Creating a content page controller in ASP.NET MVC ........................................................................ 36
Creating Content Page Template in WebForms ................................................................................ 44
Content Type Development .............................................................................................................. 47
WebForms ASPX Pages ...................................................................................................................... 49
ASP.NET MVC View Helpers .............................................................................................................. 50
Defining editors ................................................................................................................................. 50
Parts on WebForms ........................................................................................................................... 52
Parts on ASP.NET MVC ...................................................................................................................... 54
Integrating with Existing ASP.NET MVC Application ......................................................................... 57
Integrating with Existing WebForms Application .............................................................................. 65
What, where and by whom? ............................................................................................................. 65
Caching .............................................................................................................................................. 67
Creating custom editors .................................................................................................................... 68
Organizing the editor interface ......................................................................................................... 70
Finding content.................................................................................................................................. 72
Finding details ............................................................................................................................... 74
Filtering content ................................................................................................................................ 74
Security .............................................................................................................................................. 76
Configuring permission.................................................................................................................. 76
Authorizing users ........................................................................................................................... 76
Membership & Roles ..................................................................................................................... 76
Manipulating content ........................................................................................................................ 76
Creating content ............................................................................................................................ 77
Relations between items ................................................................................................................... 78
Multiple sites ..................................................................................................................................... 78
Content Globalization........................................................................................................................ 78
Configuration..................................................................................................................................... 78
Adapters ............................................................................................................................................ 78
Global Events ..................................................................................................................................... 78
Management Plugins ......................................................................................................................... 78
Performance ...................................................................................................................................... 78
Caching .......................................................................................................................................... 78
Page complexity ............................................................................................................................ 79
Number of client requests ............................................................................................................. 79
Number of queries ........................................................................................................................ 79
Database index tuning ................................................................................................................... 79
Replacing core services ..................................................................................................................... 79
Building (unit) testable controllers.................................................................................................... 79
Upgrading .......................................................................................................................................... 79
Using the trunk .................................................................................................................................. 79
Deployment & Shared Hosting .............................................................................................................. 79
Packaging ........................................................................................................................................... 79
FTP ..................................................................................................................................................... 79
Configuration ..................................................................................................................................... 79
Model changes .................................................................................................................................. 79
Template Packs...................................................................................................................................... 79
ASP.NET MVC..................................................................................................................................... 79
Dinamico............................................................................................................................................ 80
WebForms ......................................................................................................................................... 80
Add-ons ......................................................................................................................................... 80
Frequently Asked Questions ................................................................................................................. 80
Where is the documentation?....................................................................................................... 80
Medium Trust ................................................................................................................................ 80
Wildcard Mapping ......................................................................................................................... 80
Common Exception Types ............................................................................................................. 80
Contributors .......................................................................................................................................... 80
Fine-tune authorization......................................................................................................................... 81
Add new roles to the content role provider...................................................................................... 81
Configuring role to manage site area ............................................................................................ 82
Training videos .................................................................................................................................. 84
System Requirements
Operating System
Any OS capable of running .NET framework such as:






Windows XP
Windows 2003
Windows Vista
Windows 2008
Windows 7
Windows 2008 R2
Web Servers



IIS 5-7.5
ASP.NET Development Server
WebMatrix
.NET Framework
 .NET Framework 3.5 SP1
 .NET Framework 4.0
N2 CMS 1.5 can also run on .NET Framework 2.0.
Databases
Supported databases include:













SQL Server 2008 *
SQL Server 2008 Express *
SQL Server 2005 *
SQL Server 2005 Express *
SQL Server 2000
SqlCe
MySQL *
SQLite *
Firebird
Jet
DB2
Oracle9i
Oracle10g
* A connection string example can be found in web.config
Wildcard mapping (IIS 5-6.1)
On IIS 5 to IIS 6.1 wildcard mapping can be enabled to support “extensionless urls” (no ending .aspx
on each page address). To enable this use IIS Manage.
 http://n2cms.com/wiki/IIS-Wildcard-Mapping.aspx
Visual Studio Development
Visual Studio 2008 or Visual Studio 2010 (needs project upgrade) are recommended for site
development with N2 CMS. Visual Studio Express can also be used.
Shared Hosting
Some users report no problems running in shared hosting under medium trust, others have had
problems. N2 CMS has been tested on unmodified medium trust. It’s recommended you ask the
hosting provider before you buy a long-term plan. Find more info online:
http://n2cms.com/wiki/Medium%20trust.aspx
Links and Resources
Official Links






Web site: http://n2cms.com/
Downloads: http://n2cms.codeplex.com/releases
Forum: http://n2cms.codeplex.com/discussions/
Bug tracker: http://n2cms.codeplex.com/workitem/list/basic
Source code: http://code.google.com/p/n2cms/source/checkout
Demo site: http://demo.n2cms.com/
Developer documentation resources










http://n2cms.com/Documentation.aspx
http://api.n2cms.com/
http://code.google.com/p/n2cms/wiki/Welcome
http://n2cms.com/wiki.aspx
http://n2cmstutorial.blogspot.com/
http://stackoverflow.com/questions/tagged/n2
http://jamesbroo.me/tag/n2-cms/
http://martinondotnet.blogspot.com/search/label/n2cms
http://www.codeproject.com/Articles/86664/N2CMS-Forum-Addon-Fixing-the-Theme.aspx
http://interferencelogik.com/docs/N2CMS_TheLittleHandbook.pdf
Management documentation resources
 http://training.lithe.net.au/
Downloading
The latest versions are available for download on Codeplex:
 http://n2cms.codeplex.com/releases
N2 CMS 2.x Source Code
This package reflects the N2 CMS framework development environment and contains both template
packs and all examples along with the framework source code. For site development it’s
recommended to start from one of the template packs, or examples.
N2 CMS 2.x ASP.NET MVC Templates Pack
This is the source code of the MVC template package along with a compiled version of the
framework. Use this package to develop your own site with existing functionality using ASP.NET
MVC.
N2 CMS 2.x ASP.NET WebForms Templates Pack
This is the source code of the WebForms template package along with a compiled version of the
framework. Use this package to develop your own site with existing functionality using ASP.NET
WebForms.
N2 CMS 2.x MVC Minimal Example
This package contains a simple example site along with a compiled version of the framework. Use
this package to understand the basics of ASP.NET MVC + N2 CMS or if you don’t need existing
templates.
N2 CMS 2.x C# Minimal Example
This package contains a simple example site along with a compiled version of the framework. Use
this package to understand the basics of WebForms/C# + N2 CMS or if you don’t need existing
templates.
N2 CMS 2.x Visual Basic Minimal Example
This package contains a simple example site along with a compiled version of the framework. Use
this package to understand the basics of WebForms/Visual Basic + N2 CMS or if you don’t need
existing templates.
N2 CMS 2.x Compiled Framework and Management UI
This is the N2 CMS framework compiled and zipped for upgrade of a previous version, or integration
with an existing site.
Installing
To install N2 CMS in a development environment unzip one of the template packs or examples, open
the solution file within with visual studio and run (Ctrl+F5). This will start a site using SQLite
embedded database and the visual studio integrated web server.
Web Platform Installer (WPI)
The same WPI package can be installed from the “Microsfot Web Platform Installer”, from “Internet
Information Services (IIS) Manager” or from “Microsoft WebMatrix”.
Installing N2 CMS from Microsfot Web Platform Installer
Make sure WPI is installed and start it. You can download WPI from:
 http://www.microsoft.com/web/downloads/platform.aspx
Locate N2 CMS in Web Applications / CMS / N2 CMS 2.x MVC Edition and check it and click Install.
Click I Accept to accept the LGPL license agreement.
This installs N2 CMS as an application in a virtual directory, i.e. http://localhost/N2CMS/. Use the
Web Site drop down to change this.
Most users will want to Create new database. The Database Administrator is used to create the
database and requires elevated permissions. The Database User is used by the web site to store and
read content during operation (this user needs to be permitted to create tables in the database). The
database password must be at least 8 characters, contain lower- and uppercase characters and
numbers. The database server is the name of the SQL Server instance. The database name is the
name of the database which is created. The web administrator password is the password for the
“admin” user when managing the web site online. Fill the blanks and click Continue.
Lean back and wait while the site is deployed.
Click on the Launch N2 CMS 2.x MVC Edition link to continue on the web based setup wizard. The
online setup wizard can be reached at any time from the “/n2/installation/” path.
Click on please help me install on a new site.
The username is “admin”. Use the password you chose previously and click Log in.
Click Create tables, and advance to step to by clicking on “step 2”.
Select a theme of your liking and click “Please import this”. Advance to step 3.
Click on restart, then click on managing.
Congratulations. The site is installed. When you return to it you can access this management UI from
the /N2/ path.
Installing N2 CMS from Internet Information Services (IIS) Manager
You can download a template pack from Codeplex and install it using IIS manager.
Right-click on a web site, Deploy / Import Application…
Select the package you downloaded from Codeplex and click Next.
Click Next.
Select “Create new database” and click Next.
From now on it’s the same as “Installing N2 CMS from Microsoft Web Platform Installer. Continue
reading there.
Installing N2 CMS from Microsoft WebMatrix
Install Site from Web Gallery. Select CMS / N2 CMS 2.x MVC Edition and click Next.
From now on it’s the same as “Installing N2 CMS from Microsoft Web Platform Installer. Continue
reading there.
Installing not yet published releases using WPI
Often there is a newer version available than the one in Application Gallery.
Click Options in the lower left corner.
Write http://n2cms.com/wpi.xml in “Display additional scenarios” and click Add feed, and then OK.
Select the N2 CMS tab, click on Customize and check the release you want to install. The installation
procedure is the same as in the previous tutorials.
Unzip
The template packs and examples can run straight from unzip. The steps to follow are roughly the
same as “ASP.NET MVC template pack”.
Installing ASP.NET Template Pack from zip
Download ASP.NET MVC template pack (or WebForms) and unzip.
Find the solution file within, and open it.
Visual Studio may ask permission to configure IIS. Choose YES.
To use SQLite database copy [ziproot]\Libraries\System.Data.SQLite.dll to [ziproot]\N2CMS\bin
To start the site, press Ctrl+F5.
Voila! You can access the management UI from the URL /n2/ with the username/password
admin/changeme. You can change the password in web.config.
Changing databases
N2 supports several kinds of databases. To configure another database open web.config in the site’s
root directory and find the <connectionStrings> section.
<!-- Some connection string examples
SQLite: <add name="N2CMS" connectionString="Data
Source=|DataDirectory|\n2.db;Version=3;New=True;" providerName="System.Data.SQLite"/>
SQL Server 2005: <add name="N2CMS"
connectionString="Server=(local);Database=N2_Templates;Integrated Security=SSPI"/>
SQL Express 2005: <add name="N2CMS" connectionString="Data
Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\N2.mdf;Integrated Security=True;User
Instance=True" providerName="System.Data.SqlClient"/>
SQL Server 2000: <add name="N2CMS" connectionString="Data
Source=SQLServer2000;Database=SQLDatabase2000;User
Id=SqlUser2000;Password=SqlPassword2000;Network Library=DBMSSOCN;"
providerName="System.Data.SqlClient"/>
MySQL: <add name="N2CMS" connectionString="Data Source=MySQLServer;Database=MySQLDatabase;User
Id=MySQLUser;Password=MySQLPassword;" providerName="MySql.Data.MySqlClient"/>
-->
<!-- Please not that you need to configure another database and remove
\bin\system.data.sqlite.dll if you run in medium trust -->
<add name="N2CMS" connectionString="Data
Source=|DataDirectory|\n2.sqlite.db;Version=3;New=True;" providerName="System.Data.SQLite" />
N2 supports several kinds of databases. To configure another database open web.config in the site’s
root directory and find the <connectionStrings> section. Remove the existing connection string and
update the most relevant template to your database’s settings.
Using IIS
The most easy way to configure IIS is to let WPI or visual studio configure the web application for
you. Doing this manually means creating a web site or a web application below a site (not virtual
directory) and setting the path to the unizipped site’s root directory.
Using Visual Studio Integrated Development Server
To use the integrated web server right-click on the templates project, choose project properties,
select the Web tab and select Visual Studio Development Server.
Installing Code Snippets
The downloadable packages on Codeplex contains a number of templates and snippets which are
useful when developing N2 sites.
Snippets are copied to [Documents]\Visual Studio 20xx\Code Snippets\Visual C#\My Code Snippets.
Once the snippets have been placed here they can be invoked from visual studio by their name and
tapping tab twice (e.g. n2propfta [tab] [tab]). This will expand a property with an editable attribute.
Available snippets:




n2prop.snippet
n2propcb.snippet
n2propenum.snippet
n2propfta.snippet




n2propimage.snippet
n2proptb.snippet
n2propuc.snippet
n2propurl.snippet
Installing Visual Studio Item Templates
The snippets folder also contains some Visual Studio Item Templates that appears when adding new
items in Visual Studio. Copy them from the Snippets folder in the template package zip to
[Documents]\Visual Studio 2008\Templates\ItemTemplates\Visual C#. The item templates creates a
content class and a corresponding template or controller. Available templates:
 N2 Item Template.zip
 N2 Page Template.zip
 N2 Page Controller.zip
Installing Intellisense Documentation for Visual Studio
Check for /bin/N2.xml. This enables code documentation during intellisense operations and hovering
in Visual Studio.
Software Architecture
An N2 CMS web site is layered into two parts. One part is a CMS Framework and another other part
is the Web Application.
CMS Framework vs. Web Application
The framework is represented by N2.dll, N2.Security.dll and N2.Management.dll as well as all files
below the /N2/ folder. These reflect upon the application to create a UI where the site’s structure
and content is managed. The framework provides tools the application can use to create a navigable
web site.
The application references N2.dll and uses API:s in the N2 namespace to model content items so they
can be managed from the management UI. The application contains the external shape of the site
including master pages, style sheets and application logic. The application is developed with ASP.NET
MVC or WebForms, either way they use the same version of the N2 CMS framework.
N2 Management
- Expose framework
features to managers
Web Application
- Application logic
- Layout
- Style
N2 Framework
- Base classes
- Web Controls
- Declarations
.NET Framework
Web Application Architecture
The N2 framework has only one requirement on the application. There must be a class inheriting
from N2.ContentItem. Instances of this class represent the pages managed in the UI. It’s a good idea
to use multiple classes for different kinds of pages, and use inheritance to share common properties.
Each content class is related to one or more ASPX templates, or views which display the user
managed content in a shared layout. The framework provides base classes and controls to simplify
placing content, creating navigation and more.
When a page instance is created in the UI it is assigned a name which gives this page an URL from
which it can be accessed. Assuming the start page has the path “/”, a page named “hello” will be
accessible from the path “/hello/”. The framework is responsible for mapping this logical path to the
ASPX template or view.
CMS Framework Architecture
The N2 CMS Framework uses Inversion of Control to compose all of the CMS’ functionality. During
initialization a set of services are constructed and exposed through a singleton context located at
N2.Context.Current. Many helper methods such as N2.Find.Items access this context to do their job.
Most of the interaction with N2 CMS is done through inheritance of classes or usage of attributes.
During the initialization phase N2 analyzes the application and learns how to connect the content in
the database with the application code.
It’s also possible to inject or replace services in N2 to bend the CMS’ behavior beyond recognition.
WebForms vs. MVC
Regardless of application technology content items are defined using classes and instances of these
are created and organized though a management UI. Each instance is given a name which is used to
construct the page’s logical URL.
In the WebForms application content classes define a path to an ASPX template which is used to
render that particular type of item. When a page instance’s logical URL is accessed the framework
executes this template.
In the MVC application a controller defines what types of content item it controls. When a page
instance of this type is accessed the control is executed and it determines what action to perform
(e.g. render a view).
Content Types
Classes inheriting
from N2.ContentItem
These classes look the
same between MVC
and WebForms
[Controls(typeof(Content))]
[PageDefinition(TemplateUrl=
Controller
Gathers the
data to be
rendered
View
Show data
with Html
helpers
ASPX Template
Uses web controls to display content
Url Routing
Url Rewriting
Site’s Structure and Content
Managed and organized from the UI
Pages that are outside a start page, e.g. pages in trash can also be accessed but not via a friendly url.
Pages handled by an MVC controller are accessed via an url that corresponds to
“/{controller}/{action}/?page={id}”.
Pages that are handled by a webforms page are accessible via “/{path-to-aspx-template}?page={id}”.
Routing to content with ASP.NET MVC
An example for an application using the ContentRoute and MVC. Model:
[PageDefinition]
public class ContentPage : PageModelBase
{
}
Controller:
[Controls(typeof(Models.ContentPage))]
public class ContentPagesController : ContentController<Models.ContentPage>
{
}
And the following incoming URL:
/news/n2-cms-2-1-1-released
This URL is based on each page’s name and the names of the ancestors leading up to the start page.
In this case the page “N2 CMS 2.1.1 released” is placed below the page “News” which is directly
below the start page.
When a request arrives routes are asked in order if they can handle it. Since the URL maps to a
content item the ContentRoute will respond with route data containing controller and referencing to
the item.
Path segments immediately after a path leading to a controller are mapped as actions if there is a
corresponding method on the controller. E.g. if there was an action “Comment” on the ContentPages
controller the following url would lead to that action:
/news/n2-cms-2-1-1-released/comment
The following URL would also lead to this item and would be generated for pages that aren’t within a
start page (e.g. if they have been thrown in the trash):
/ContentPages/Index/?page=123
Development topics
Converting the project to Visual Studio 2010
Start Visual Studio 2010 and open the solution file.
Click Finish.
Click Yes.
Open web.config, find the <system.web> and the following comment:
<!--Uncomment for .NET 4 <httpRuntime requestValidationMode="2.0"/>-->
And uncomment it:
<httpRuntime requestValidationMode="2.0"/>
Compile and run
Creating a content page controller in ASP.NET MVC
This tutorial assumes you have added the visual studio item templates. How to do this is documented
in the Installation section of this document.
1.
Right-click on the project, select and add a new N2 Contet Controller.
2.
The item template includes a content page class. Take note of these traits shared by most
content items:
a. It’s attributed by [PageDefinition]
b. It inherits from N2.ContentItem
c. It’s enriched by attributes with an editable title, name (url segment), and free text
3.
A content controller is also generated. It shares some traits in common with most content
controllers:
a. It [Controls] a type of content item (the one that was generated).
b. It inherits from ContentController<T>. The generic argument gives strongly typed
access to CurrentItem
c. It has an Index action.
4.
There is no view yet, but this is easy enough to generate. Right-click in the Index action
method, and Add View…
5.
Create a strongly typed view by setting the view data class to the generated model class.
6.
The view uses all regions from the master page. Usually MainContent is enough and the
others can be removed.
7. Tweaking the view a bit will reveal content managed from the UI:
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<%= Html.DisplayContent("Title") %>
<%= Html.DisplayContent("Text") %>
</asp:Content>
8.
A quick compile (F6 in visual studio) makes the page available in the management UI.
9.
This is the editing form generated from that model.
10.
And this is how the page looks in the end.
Creating Content Page Template in WebForms
1.
Right-click on the project node and Add / New item… Select N2 Page Template and Add.
2.
A content item class is generated.
3.
A page template is generated.
4.
The page template is given a code-behind inheriting from ContetPage<T>
5.
6.
7.
Content Type Development
The N2 programming model requires each type of content to have a class that is compiled into the
application. Instances of this class are later used from a template, controller or view.
Consider the following content class:
[PageDefinition("TutorialPage")]
[WithEditableTitle, WithEditableName]
public class TutorialPage : ContentItem
{
[EditableFreeTextArea("Text", 100)]
public virtual string Text
{
get { return (string)(GetDetail("Text") ?? string.Empty); }
set { SetDetail("Text", value, string.Empty); }
}
}
Ever since N2 CMS 2.1 it’s possible to get rid of the bulky getters and setters:
[PageDefinition("TutorialPage")]
[WithEditableTitle, WithEditableName]
public class TutorialPage : ContentItem
{
[EditableFreeTextArea("Text", 100)]
public virtual string Text { get; set; }
}
A common pattern is using an abstract base class for re-use across multiple types:
[WithEditableTitle, WithEditableName]
public abstract class ContentPageBase : ContentItem
{
[EditableFreeTextArea("Text", 100)]
public virtual string Text { get; set; }
}
[PageDefinition("Tutorial Page")]
public class TutorialPage : ContentPageBase
{
}
[PageDefinition("Example Page")]
public class ExamplePage : ContentPageBase
{
}
Both TutorialPage and ExamplePage will have an editable title, name and text.
When developing an ASP.NET MVC application the content item doesn’t know which template will
use it (the controller defines which content item it controls). When using WebForms however,
TemplateUrl is used:
/// <summary>
/// This is WebForms' style of content item declaration.
/// </summary>
[PageDefinition("WebForm Page",
TemplateUrl = "~/Path/To/My/Template.aspx")]
public class WebFormPage : ContentPageBase
{
}
Most of these attributes have additional properties that can be configured. Use visual studio
intellisense to discover these.
WebForms ASPX Pages
N2 CMS provides a number of web controls for creating UI with WebForms:








<n2:ControlPanel – renders the control panel
<n2:Display – displays content from the current page
<n2:HasValue – a placeholder that is displayed when a property has a value
<n2:Repeater - a repeater with support for no results
<n2:SlidingCurtain – creates a sliding box around the control panel
<n2:Tree – creates a tree structure
<n2:Zone – renders parts in a zone
<n2:ItemDataSource – binds items to grids and repeaters and navigation controls
There are also a number of base classes which helps accessing the current item and integrate witch
caching:





ContentPage – a page base class with access to the current page
ContentPage<T> - a page base class with strongly typed access to the current page
ContentUserControl – a user control base class with access to the current page
ContentUserControl<TPage> - a base class with strongly typed access to the current page
ContentUserControl<TPage, TPart> - a base class used for parts with access to page and part
Look at the WebForms template pack for examples on how to use these controls and base classes.
This project provides more web controls and TemplatePage<T> and TemplateUesrControl<T> with
additional functionality.
ASP.NET MVC View Helpers
When developing an ASP.MVC view there are some view helpers that can be useful:















Html.BeginAsyncAction
Html.HasValue
Html.ValueEquals
Html.ResolveService<T>
Html.CurrentPage
Html.CurrentPage<T>
Html.CurrentItem
Html.CurrentItem<T>
Html.Detail
Html.DisplayContent
Html.RenderDisplay
Html.DroppableZone
Html.ActionLink
Html.Zone
Html.RenderZone
Example:
<% using (Html.BeginAsyncAction("lazy", new { partial = true })){ %>
<%= Html.ActionLink("Loading expensive content", Html.CurrentPage(), "lazy", …
<% } %>
The example shows a link while the lazy action is being retrieved asynchronously from the client.
Defining editors
Editors are defined using attributes on content item classes or properties.
















WithEditableChild – Adds an edit for form a child item resolved by its name
WithEditableDateRange – Adds a date range editor
WithEditableName – Adds editing of the item’s name (url segment)
WithEditablePublishedRange – Adds editing of the items publishing range
WithEditableTitle – Adds editing of the item title
EditableCheckBox – Adds editing of a Boolean property
EditableChildren – Adds editing of a collection of children
EditableDate – Adds editing of a date
EditableEnum – Adds editing of an enum
EditableFileUpload – Adds file upload and store a link to the uploaded file
EditableFreeTextArea – Adds a WYSIWYG editor
EditableImage – Adds an image picker
EditableImageSize – Adds an image size drop down
EditableItem – Adds an editable child item
EditableLanguagesDropDown – Adds a drop down with languages
EditableLink – Adds a link picker



EditableTextBox – Adds a text box
EditableUrl – Adds an text box with link picker
EditableUserControl – Adds a custom user control
This is an example of a content item with too many editors defined:
[WithEditableChild]
[WithEditableDateRange]
[WithEditableName]
[WithEditablePublishedRange]
[WithEditableTitle]
public abstract class ContentPageBase : ContentItem
{
[EditableCheckBox]
[EditableChildren]
[EditableDate]
[EditableEnum]
[EditableFileUpload]
[EditableFreeTextArea]
[EditableImage]
[EditableImageSize]
[EditableItem]
[EditableLanguagesDropDown]
[EditableLink]
[EditableTextBox]
[EditableUrl]
[EditableUserControl]
public virtual string Text { get; set; }
}
Parts on WebForms
1.
Right-click on the project, Add, New item… , select N2 Item Template and Add.
2.
Use the n2propfta to add a free text area snippet. Give the property the name Text.
3. Edit TutorialPart.ascx and add a display control:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TutorialPart.ascx.cs"
Inherits="N2.UI.TutorialPart" %>
<div style="border:solid 10px red">
<n2:Display runat="server" propertyname="Text" />
</div>
4.
Compile and Voila! Select “Organize parts” and drag TutorialPartItem into a zone to see it in
action.
Parts on ASP.NET MVC
1.
Right-click on the project, Add, New item… N2 Content Controller
2. Change [PageDefinition] to [PartDefinition] and remove the attributes [WithEditableTitle] and
[WithEditableName]on the TutorialPart class. Move it to the Models.Parts namespace:
namespace N2.Templates.Mvc.Models.Parts
{
[PartDefinition("TutorialPart")]
public class TutorialPart : ContentItem
{
[EditableFreeTextArea("Text", 100)]
public virtual string Text { get; set; }
}
}
3. Change TutorialpartController to use the correct namespace and make it return a PartialView:
[Controls(typeof(Models.Parts.TutorialPart))]
public class TutorialPartController : ContentController<Models.Parts.TutorialPart>
{
public override ActionResult Index()
{
// Right-click and Add View..
return PartialView(CurrentItem);
}
}
4. <%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<N2.Templates.Mvc.Models.Parts.TutorialPart>
" %>
5.
6. <div style="border: solid 10px red">
7. <%= Model.Text %>
8. </div>
9.
Right-click in the action, Add View…, check Create a partial view (.ascx), and Add.
10. Add some markup:
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<N2.Templates.Mvc.Models.Parts.TutorialPart>"
%>
<div style="border: solid 10px red">
<%= Model.Text %>
</div>
11.
Compile and Voila! Choose “Organize parts” on a page and drag TutorialPart onto a zone.
Integrating with Existing ASP.NET MVC Application
1.
This tutorial is based on the default MVC application created by the visual studio project
template.
2.
Grab the latest version of “N2 CMS 2.x Compiled Framework and Management UI” and copy
the Bin and N2 folders to the application root folder.
3. Open up web.config and add the following sections:
<!-- add n2 section group -->
<configSections>
<sectionGroup name="n2" type="N2.Configuration.SectionGroup, N2">
<section name="host" type="N2.Configuration.HostSection, N2"
requirePermission="false" restartOnExternalChanges="true"/>
<section name="engine" type="N2.Configuration.EngineSection, N2"
requirePermission="false" restartOnExternalChanges="true"/>
<section name="database" type="N2.Configuration.DatabaseSection, N2"
requirePermission="false" restartOnExternalChanges="true"/>
<section name="edit" type="N2.Configuration.EditSection, N2"
requirePermission="false" restartOnExternalChanges="true"/>
</sectionGroup>
</configSections>
<!-- merge n2 connection string -->
<connectionStrings>
<!-- Some connection string examples
SQLite:
<add name="N2CMS"
connectionString="Data Source=|DataDirectory|\n2.db;Version=3;New=True;"
providerName="System.Data.SQLite"/>
SQL Server 2005:
<add name="N2CMS"
connectionString="Server=(local);Database=N2_Templates;Integrated
Security=SSPI"/>
SQL Express 2005:
<add name="N2CMS" connectionString="Data
Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\N2.mdf;Integrated
Security=True;User Instance=True" providerName="System.Data.SqlClient"/>
SQL Server 2000:
<add name="N2CMS" connectionString="Data
Source=SQLServer2000;Database=SQLDatabase2000;User
Id=SqlUser2000;Password=SqlPassword2000;Network Library=DBMSSOCN;"
providerName="System.Data.SqlClient"/>
MySQL:
<add name="N2CMS"
connectionString="Data Source=MySQLServer;Database=MySQLDatabase;User
Id=MySQLUser;Password=MySQLPassword;"
providerName="MySql.Data.MySqlClient"/>
-->
<!-- Please not that you need to configure another database and
remove \bin\system.data.sqlite.dll if you run in medium trust -->
<add name="N2CMS" connectionString="Data
Source=|DataDirectory|\n2.sqlite.db;Version=3;New=True;"
providerName="System.Data.SQLite" />
</connectionStrings>
<!-- add n2 config section -->
<n2 xmlns="http://n2cms.com/schemas/configuration/v3">
<host/>
<engine/>
<database />
<edit/>
</n2>
<system.web>
<!-- Allow posting html content -->
<httpRuntime requestValidationMode="2.0"/>
<!-- merge authentication section (switching to membership providers as
soon things are running is recommended)-->
<authentication mode="Forms">
<forms loginUrl="n2/login.aspx" protection="All" timeout="30000"
path="/">
<credentials passwordFormat="Clear">
<!-- WARNING: Change this default password. Please do it
now. -->
<user name="admin" password="changeme" />
</credentials>
</forms>
</authentication>
<!-- merge the pages section -->
<pages>
<controls>
<add tagPrefix="n2" namespace="N2.Web.UI.WebControls"
assembly="N2" />
</controls>
<namespaces>
<add namespace="System.Web.Mvc"/>
<add namespace="System.Web.Mvc.Ajax"/>
<add namespace="System.Web.Mvc.Html"/>
<add namespace="System.Web.Routing"/>
<add namespace="System.Collections.Generic"/>
<add namespace="N2.Web.Mvc.Html"/>
</namespaces>
</pages>
<!-- merge httpHandlers & httpModules (IIS5-6+WebDev) -->
<httpHandlers>
<add path="*.n2.ashx" verb="*" type="N2.Web.AjaxRequestHandler, N2" />
</httpHandlers>
<httpModules>
<add name="n2.initializer" type="N2.Web.InitializerModule, N2" />
</httpModules>
</system.web>
<!-- merge modules & handlers (IIS7) -->
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<add name="n2.initializer" type="N2.Web.InitializerModule, N2" />
</modules>
<handlers>
<add name="n2.ajax" path="*.n2.ashx" verb="*"
type="N2.Web.AjaxRequestHandler, N2" />
</handlers>
</system.webServer>
4.
Add references to bin/N2.dll and bin/N2.Extensions.dll.
5. Update Global.asax.cs:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
// add the content route before other routes
var engine = MvcEngine.Create();
engine.RegisterControllers(typeof(MvcApplication).Assembly);
RouteTable.Routes.MapContentRoute("Content", engine);
RegisterRoutes(RouteTable.Routes);
}
6. Add a HomePage content item:
namespace VanillaApplication.Models
{
[N2.PageDefinition]
public class HomePage : N2.ContentItem
{
}
}
7. Update the HomeController:
[N2.Web.Controls(typeof(Models.HomePage))]
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
8.
Compile and run, you should be redirected to the N2 installation
9. Click on help me install a database for a new site
10. Log in using the username and password you pasted into web.config (admin/changeme)
11.
Click to create tables (now is the good time to update the connection string to another
database if you don’t want to use SQLite)
12.
On step 2. Content Package go to Manually insert nodes and insert a “Root Page (fallback)”
and HomePage and click Add two separate nodes.
13.
Scroll down and click Update web.config
14.
On the finishing touches heed the advice and update the password in web.config. You pasted
this earlier so it should be easy to find. Click on managing.
15.
The integration should be working but you might want to update update the model and view
a bit.
16. Update the model to contain some editable stuff:
[N2.PageDefinition]
[WithEditableName, WithEditableTitle]
public class HomePage : N2.ContentItem
{
[EditableFreeTextArea]
public virtual string Text { get; set; }
}
17. Update /Views/Home/Index.aspx:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2><%= Html.CurrentPage<VanillaApplication.Models.HomePage>().Title %></h2>
<%= Html.DisplayContent("Text") %>
</asp:Content>
18. Update /Views/Shared/Site.master:
<body>
<%-- just within <body> --%>
<n2:SlidingCurtain runat="server">
<n2:ControlPanel runat="server"/>
</n2:SlidingCurtain>
<%-- Replace the hard-coded navigation --%>
<div id="menucontainer">
<ul id="menu">
<li>
<%= Html.ActionLink(N2.Find.StartPage)
%></li><%= N2.Web.Tree.From(N2.Find.StartPage, 2)
.ExcludeRoot(true) %>
</ul>
</div>
19.
Congratulations, your site is now content enabled. Integrating the template pack requires
more work, but understanding the basics is an important step.
Integrating with Existing WebForms Application
TODO
What, where and by whom?
It’s possible to use attributes to define which types of items can be created below another type, and
who can create.
[WithEditableName, WithEditableTitle]
public abstract class PageBase : N2.ContentItem
{
[EditableFreeTextArea]
public virtual string Text { get; set; }
}
Base classes can use and be referenced for restrictions.
[N2.PageDefinition]
[ItemAuthorizedRoles(new string[0])] // allow no one
public class HomePage : PageBase
{
}
ItemAuthorizedRoles prevents this page from being created in the UI.
[N2.PageDefinition]
[RestrictParents(typeof(HomePage))] // allow sections immediately below home page
[ItemAuthorizedRoles("Administrators")] // only admins can create this page
public class SectionPage : PageBase
{
}
RestrictParents make so this can only be created below a certain type. ItemAuthorizedRole restricts
who can create it (but not delete, move or edit).
[N2.PageDefinition]
[RestrictChildren(typeof(NewsPage))] // prevent TextPage to be allowed
public class NewsContainer : PageBase
{
}
RestrictChildren make so only the referenced types can be created below. By default all types are
allowed.
[N2.PageDefinition]
[RestrictParents(typeof(NewsContainer))] // allow only below news container
public class NewsPage : PageBase, ICommentable
{
}
Removing RestrictParents would make it possible to create this type below other types than
NewsContainer.
[N2.PageDefinition]
[RestrictParents(typeof(PageBase))] // allowed below any page inheriting from
PageBase
public class TextPage : PageBase, ICommentable
{
}
RestrictParents can use a baseclass to restrict to a larger number of types.
[PartDefinition]
// allowed in any zone on any page
public class FooterPart : ContentItem
{
}
By default all parts are allowed in any zone.
It’s optional to define on the pages which zones are available. The benefit of declaring with
[AvailableZone] is that parts can be added from the management UI without using drag and drop.
public interface ICommentable
{
}
Interfaces can be referenced for restrictions.
[PartDefinition]
[RestrictParents(typeof(ICommentable))] // allowed only below commentable items
[AllowedZones("Comments")] // allowed only in comments zone
public class CommentPart : ContentItem
{
}
This part can only be created below types implementing ICommentable. Additionally only the zone
“Comments” is allowed.
Caching
By default url-to-item mapping is enabled. Second level cache (generic database entity cache) and
output cache can be enabled via configuration. The caches are invalidated when content is changed.
Enable output cache for any controller implementing ContentController<> and any page
implementing ContentPage<>:
<n2 xmlns="http://n2cms.com/schemas/configuration/v3">
<host rootID="1" startPageID="2">
<!-- output cache caches the rendered page and
is invalidated when a page is published -->
<outputCache enabled="true" duration="10"/>
</host>
<engine/>
<database />
<edit/>
</n2>
To disable url-to-item mapping cache:
<n2 xmlns="http://n2cms.com/schemas/configuration/v3">
<host rootID="1" startPageID="2">
<web>
<!-- Disable url caching will make the system
traverse children for each request -->
<urls enableCaching="false" />
</web>
</host>
<engine/>
<database />
<edit/>
</n2>
To enable second level cache (generic database entity cache):
<n2 xmlns="http://n2cms.com/schemas/configuration/v3">
<host rootID="1" startPageID="2"/>
<engine/>
<!-- Other cache providers are also available -->
<database caching="true"
cacheProviderClass="NHibernate.Caches.SysCache2.SysCacheProvider,
NHibernate.Caches.SysCache2"/>
<edit/>
</n2>
Creating custom editors
The included editable attributes are build using the same system you can use to build your own.
1. Create a class inheriting from AbstractEditableAttribute, let visual studio generate the abstract
methods:
using N2.Details;
using System.Web.UI;
namespace VanillaApplication.Models
{
public class EditablePageDropDownAttribute : AbstractEditableAttribute
{
protected override Control AddEditor(Control container)
{
throw new NotImplementedException();
}
public override void UpdateEditor(N2.ContentItem item, Control editor)
{
throw new NotImplementedException();
}
public override bool UpdateItem(N2.ContentItem item, Control editor)
{
throw new NotImplementedException();
}
}
}
2. Implement AddEditor:
protected override Control AddEditor(Control container)
{
// here we create the editor control and add it to the page
DropDownList list = new DropDownList();
list.ID = Name;
list.DataTextField = "Title";
list.DataValueField = "ID";
list.DataSource = N2.Find.Items
.Where.AncestralTrail.NotLike("Trash%") // exclude trash
.MaxResults(1000) // keep a reasonable result size
.Filters(new AccessFilter()) // don't reveal secrets
.Select();
list.DataBind();
container.Controls.Add(list);
return list;
}
3. Now the available pages show up find but we need to persist what the manager selects:
public override void UpdateEditor(N2.ContentItem item, Control editor)
{
// here we update the editor control to reflect what was saved
ContentItem selectedItem = item[Name] as ContentItem;
if (selectedItem != null)
{
DropDownList list = editor as DropDownList;
list.SelectedValue = selectedItem.ID.ToString();
}
}
public override bool UpdateItem(N2.ContentItem item, Control editor)
{
// here we update the item from dropdown selection
DropDownList list = editor as DropDownList;
int selectedID = int.Parse(list.SelectedValue);
ContentItem previouslySelected = item[Name] as ContentItem;
if (previouslySelected != null && previouslySelected.ID == selectedID)
// no change
return false;
item[Name] = Engine.Persister.Get(selectedID);
return true;
}
4. Let’s use the editable on some properties:
public class HomePage : PageBase
{
[EditablePageDropDown]
public virtual ContentItem AboutPage { get; set; }
[EditablePageDropDown]
public virtual ContentItem CookiePage { get; set; }
}
5.
There they are.
Organizing the editor interface
When adding [Editable…] attributes on content classes you are defining what the editor interface will
look like. It’s possible to fine-tune how this interface will appear using “containers”. An example:
[TabContainer("content", "Content", 0)]
[WithEditableName(ContainerName = "content"), WithEditableTitle(ContainerName =
"content")]
public abstract class PageBase : N2.ContentItem
{
[EditableFreeTextArea(ContainerName = "content")]
public virtual string Text { get; set; }
}
Adds title, name and text editing to a tab “Content”.
[N2.PageDefinition]
[TabContainer("advanced", "Advanced", 10)]
public class HomePage : PageBase
{
[EditableImage(ContainerName = "content")]
public virtual string ImageUrl { get; set; }
[EditablePageDropDown(ContainerName = "advanced")]
public virtual ContentItem AboutPage { get; set; }
[EditablePageDropDown(ContainerName = "advanced")]
public virtual ContentItem CookiePage { get; set; }
}
Adds image picker to the Content tab defined in the base class, and an “Advanced” tab with two drop
down editors. The advanced tab is sorted after the content since it’s sortOrder property is greater
(10 > 0).
This is the previously defined editor interface.
It’s also possible to nest containers:
[TabContainer("content", "Content", 0)]
[FieldSetContainer("meta", "Meta attributes", 0,
ContainerName = "content", SortOrder = 100)]
[WithEditableName(ContainerName = "content")]
[WithEditableTitle(ContainerName = "content")]
public abstract class PageBase : N2.ContentItem
{
[EditableFreeTextArea(ContainerName = "content")]
public virtual string Text { get; set; }
[EditableTextBox(ContainerName = "meta")]
public virtual string MetaDescription { get; set; }
[EditableTextBox(ContainerName = "meta")]
public virtual string MetaKeywords { get; set; }
}
The resulting interface after the changes above.
These are the built-in containers:




[ExpandableContainer]
[FieldSetContainer]
[Separator]
[TabContainer]
To build your own extend from N2.Definitions.EditorContainerAttribute.
Finding content
There are multiple ways of finding content stored in the database:
 The finder fluent API (N2.Find.Items…)
 Traversing the content tree (N2.Find.StartPage.GetChildren()…)
 LINQ (using N2.Linq; Engine.QueryItems())
 Using NHibernate query options (hql, criteria, raw SQL, LINQ)
public ActionResult QueryForProperty()
{
ViewData["foundItmes"] = FindRecentlyPublishedWithFinder();
ViewData["traversedItmes"] = FindRecentlyPublishedWithTraversion();
ViewData["linqedItems"] = FindRecentlyPublishedWithLINQ();
ViewData["hqledItems"] = FindRecentlyPublishedItemsWithNHHql();
ViewData["criteriaItems"] = FindRecentlyPublishedItemsWithNHCriteria();
ViewData["nhlinqedItems"] = FindRecentlyPublishedItemsWithNHLINQ();
return View();
}
The MVC action above invokes multiple ways of finding content which will be analyzed in further
detail below.
private IEnumerable<ContentItem> FindRecentlyPublishedWithFinder()
{
// this will create a hql expression behind the scenes and run it
var recentlyPublishedItems = N2.Find.Items
.Where.Published.Gt(DateTime.Now.AddMonths(-1))
.Filters(new AccessFilter())
.Select();
return recentlyPublishedItems;
}
This is example usage of the finder fluent API.
private IEnumerable<ContentItem> FindRecentlyPublishedWithTraversion()
{
// this will force all contnet items in the database into memory
var recentlyPublishedItems = Find.EnumerateTree(Find.RootItem)
.Where(ci => ci.Published > DateTime.Now.AddMonths(-1))
.Where(new AccessFilter().Match)
.ToList();
return recentlyPublishedItems;
}
This is example usage of traversing the complete content hierarchy using a helper method. This
method will force all content to be loaded into server memory and isn’t optimal when there is a lot
of content.
private IEnumerable<ContentItem> FindRecentlyPublishedWithLINQ()
{
// the linq support is not fully functional in N2 2.1 beta
var recentlyPublishedItems = Engine.QueryItems()
.Where(ci => ci.Published > DateTime.Now.AddMonths(-1))
.Where(new AccessFilter().Match)
.ToList();
return recentlyPublishedItems;
}
This example uses the N2 LINQ wrapper around NH LINQ for finding items.
private IEnumerable<ContentItem> FindRecentlyPublishedItemsWithNHHql()
{
// use NHibernate hql api for querying
// will include previous versions by default
var recentlyPublishedItems =
Engine.Resolve<ISessionProvider>().OpenSession.Session
.CreateQuery("from ContentItem ci where ci.Published > :minDate")
.SetParameter("minDate", DateTime.Now.AddMonths(-1))
.Enumerable<ContentItem>()
.Where(new AccessFilter().Match)
.ToList();
return recentlyPublishedItems;
}
This example falls back to the NHibernate hql API for querying. The results are not filtered for
previous versions In this case. This is used behind the hood when using the N2 finder API.
private IEnumerable<ContentItem> FindRecentlyPublishedItemsWithNHCriteria()
{
// use NHibernate criteria api for querying
// will include previous versions by default
var recentlyPublishedItems =
Engine.Resolve<ISessionProvider>().OpenSession.Session
.CreateCriteria<ContentItem>("ci")
.Add(NHibernate.Criterion.Expression.Gt("Published",
DateTime.Now.AddMonths(-1)))
.List<ContentItem>()
.Where(new AccessFilter().Match)
.ToList();
return recentlyPublishedItems;
}
This example uses the NHibernate Criteria API for querying. The results are not filtered for previous
versions.
private IEnumerable<ContentItem> FindRecentlyPublishedItemsWithNHLINQ()
{
// use NHibernate linq api for querying
// will include previous versions by default
var recentlyPublishedItems =
Engine.Resolve<ISessionProvider>().OpenSession.Session
.Query<ContentItem>()
.Where(ci => ci.Published > DateTime.Now.AddMonths(-1))
.Where(new AccessFilter().Match)
.ToList();
return recentlyPublishedItems;
}
This example uses the NHibernate LINQ API for querying. The results are not filtered for previous
versions. This is used behind the hood when using the N2 LINQ API.
Finding details
Details are stored in a separate detail table. Querying for details means asking the database to do a
sub-select.
private object FindTextContainsWithFinder()
{
// this will cause a sub-select
var itemsWithSomestring = N2.Find.Items
.Where.Detail("Text").Like("%somestring%")
.Filters(new AccessFilter())
.Select();
return itemsWithSomestring;
}
Filtering content
A very common operation is filtering of lists. To simplify this there is a concept of filters. These are
the filters available by default:





AccessFilter – removes items not authorized by the user
CompositeFilter – is composed of other filters, removes items not authorized by all of these
NavigationFilter – is composed of a page, visible, published and access filter
CountFilter –skip and takes a number of items, needs to be reset after each use
DelegateFilter – encapsulates an action that does the filtering









DuplicateFilter – removes duplicates, needs to be reset after each use
InverseFilter – contains another filter which behavior is inversed
NullFilter – doesn’t filter
PageFilter – allows only pages (not parts)
ParentFilter – removes anything not structured below a parent
PublishedFilter – removes unpublished and expired items
TypeFilter – removes items not deriving from a certain type
VisibleFilter – removes non-visible items
ZoneFilter – removes items not in a given zone
Example, filtering found items:
private IEnumerable<ContentItem> FindRecentlyPublishedWithFinder()
{
var recentlyPublishedItems = N2.Find.Items
.Where.Published.Gt(DateTime.Now.AddMonths(-1))
.Filters(new AccessFilter())
.Select();
return recentlyPublishedItems;
}
The GetChildren method without parameters uses AccessFilter. When filtering children remember to
include an access filter. Example, filtering out child pages that are accessible:
public ActionResult FilteringChildPages()
{
ViewData["childPages"] = CurrentPage.GetChildren(
new CompositeFilter(
new AccessFilter(),
new PageFilter()));
return View();
}
The filter can also be invoked directly. Calling filter will remove entries from the list.
public ActionResult FilteringLists()
{
var children = CurrentPage.GetChildren();
var filter = new PublishedFilter();
// filtering a list will remove entries from the list
filter.Filter(children);
return View();
}
Without changing the list, it’s possible to call Pipe which returns the matching items.
public ActionResult PipingEnumerations()
{
var children = CurrentPage.GetChildren();
var filter = new PublishedFilter();
// piping will return a filtered enumeration without changing the input
var filteredChildren = filter.Pipe(children);
return View();
}
Security
N2 allows administrators to set specific permissions for content the role level. The available
permissions are Read, Write, Publish and administer. The roles are retrieved from the configured
roles provider.
Configuring permission
By default only read permissions are available to be managed. To enable the other permissions some
configuration is required:
<n2 xmlns="http://n2cms.com/schemas/configuration/v3">
<edit>
<!-- setting these roles to dynamic will enable administration -->
<writers dynamic="true"/>
<editors dynamic="true"/>
<administrators dynamic="true"/>
</edit>
</n2>
Authorizing users
By default N2 manages the security and throws an exception for unauthorized access. It’s possible to
override the default behavior on the content item:
[PageDefinition]
public class PerUserSecurable : PageBase
{
public override bool IsAuthorized(IPrincipal user)
{
if (base.IsAuthorized(user))
// continue allowing setting permissions via roles
return true;
// additionally maintain a list of authorized users
return AuthorizedUsers.Contains(
user.Identity.Name,
StringComparer.OrdinalIgnoreCase);
}
public IList<string> AuthorizedUsers
{
get
{
return (GetDetailCollection("AuthorizedUsers", /*create*/ false)
?? new DetailCollection()).ToList<string>();
}
}
}
Membership & Roles
Included in N2.Security.dll are membership, roles and profile provider which stores their settings in
the content item database. These providers can be replaced by the ASP.NET counterparts. Refer to
the ASP.NET documentation for information on how to configure membership providers.
Manipulating content
This is the content model consumed by the subsequent examples:
public abstract class PageBase : N2.ContentItem
{
[EditableFreeTextArea]
public virtual string Text { get; set; }
}
[PageDefinition]
public class HomePage : PageBase
{
[EditableLink]
public virtual ContentItem AboutPage { get; set; }
}
[PartDefinition]
[AllowedZones("Comments")] // allowed only in comments zone
public class CommentPart : ContentItem
{
[EditableFreeTextArea]
public virtual string Text { get; set; }
}
Creating content
A few examples performing CRUD operations on a comment:
public ActionResult CreateComment(string text)
{
// creates a comment below the current page
var comment = Engine.Definitions
.CreateInstance<CommentPart>(CurrentPage);
comment.Text = Server.HtmlEncode(text);
// the zone name property determines a part's zone
comment.ZoneName = "Comments";
Engine.Persister.Save(comment);
return Redirect(CurrentPage.Url);
}
That was an example creating a comment part in the ”Comments” zone.
public ActionResult ReadComment(int id)
{
var comment = Engine.Persister.Get<CommentPart>(id);
return Content(comment.Text);
}
That was an example getting a comment and returning its text.
public ActionResult UpdateComment(int id, string text)
{
var comment = Engine.Persister.Get<CommentPart>(id);
comment.Text = Server.HtmlEncode(text);
Engine.Persister.Save(comment);
return Redirect(CurrentPage.Url);
}
That was an example updating the text of a comment.
public ActionResult DeleteComment(int id)
{
var comment = Engine.Persister.Get<CommentPart>(id);
Engine.Persister.Delete(comment);
return Redirect(CurrentPage.Url);
}
That was an example deleting a comment.
public ActionResult Create1000Children()
{
// this is a way to give your site a good workout
for (int i = 0; i < 1000; i++)
{
var child = Engine.Definitions.CreateInstance<HomePage>(CurrentPage);
child.Title = "Child page " + i;
child.Name = "page" + i;
child.Text = "<p>Lorem ipsum dolor sit amet</p>";
child.AddTo(CurrentPage);
}
// saves all the children in one go
Engine.Persister.Save(CurrentPage);
return Redirect(CurrentPage.Url);
}
Sometimes, it’s useful to create a lot of test data. In such cases this is a way of quickly creating a lot
of content.
Relations between items
TODO
Multiple sites
TODO
Content Globalization
TODO
Configuration
TODO
Adapters
TODO
Global Events
TODO
Management Plugins
TODO
Performance
Caching
TODO
Page complexity
TODO
Number of client requests
TODO
Number of queries
TODO
Database index tuning
TODO
Any Advice On Performance?
Create Missing Indexes
MS SQL Server optimization
http://n2cms.codeplex.com/Thread/View.aspx?ThreadId=231772
Replacing core services
TODO
Building (unit) testable controllers
TODO
Upgrading
TODO
Using the trunk
TODO
Deployment & Shared Hosting
Packaging
FTP
Configuration
Model changes
Template Packs
ASP.NET MVC
TODO
Dinamico
TODO
WebForms
TODO
Add-ons
TODO
Frequently Asked Questions
Where is the documentation?
Here.
Medium Trust
TODO
Wildcard Mapping
TODO
Common Exception Types
TODO
Contributors
The application is released as open source and been improved by a number of contributors, which in
order of appearance are:





















Cristian Libardo
Sten Johanneson
Michele Scaramal
Martijn Rasenberg
Taras Strypko
Geert van Horrik
Elizabeth
Pedropaf
Matthew
Magomed Abdurakhmanov
Steve Mason
Jemerick
Tjassim
Tonez
Stanley Ipkiss
Kennet
James Crowley
Wayne Wong
mjwills
And Poulsen
Paul Knopf
N2 CMS Management documentation
Fine-tune authorization
Add new roles to the content role provider
Only if you use the "ContentRoleProvider" in web.config you can manage roles using the content
tree. Other role providers may give you other ways of managing roles.
1. Click "Settings", then "Show non-pages in navigation" and "Save".
2. Right-click on the Users node and choose "Edit", add some roles to the roles text area. One
role for each row and "Save and publish".
Enabling Dynamic Permissions (permissions on content)
This allows altering permissions on a per-role and per-content item (or hierarchy) basis. In
web.config:
<n2 xmlns="http://n2cms.com/schemas/configuration/v3">
<edit>
<writers dynamic="true"/>
<editors dynamic="true"/>
<administrators dynamic="true"/>
Adding roles to writers, editors or administrators
By default N2 recognizes roles Writers, Editors and Administrators and the user “admin”. To add
roles to these groups modify web.config:
<n2 xmlns="http://n2cms.com/schemas/configuration/v3">
<edit>
<writers dynamic="true" roles="Writers,EnglishWriters" />
<editors dynamic="true"/>
<administrators dynamic="true"/>
In addition to this, roles may have to be authorized to access the management UI. Do this in
/N2/web.config:
<authorization>
<allow users="Admin" roles="Administrators,Editors,Writers,EnglishWriters"/>
<deny users="*"/>
</authorization>
Configuring role to manage site area
N2 CMS can be set up separate multiple user roles to manage different areas of the site. To do this
add some roles, to your role provider.
Click on the root node to give custom permissions, and change the permissions according to the
following image. Right-click on "Save" and click on "Save whole branch".
Click on users in the toolbar, click on new, fill out the form like the image below and "Create user".
Continue to each other security area and change the settings and add users accordingly. If using
nested areas first update the page containing the other since saving whole branch will overwrite all
settings whithin.
Training videos
http://training.lithe.net.au/