Sie sind auf Seite 1von 70

1. n2cms Home . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1 Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.1 Server Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.2 Setting Up Your Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.2.

1 Visual Studio Snippets and Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.2.2 Installing N2CMS NuGet Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.2.3 Configuring the Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.2.4 Deciding Where to Store Attachments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.3 Prepare for Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.3.1 Install a New Instance of N2 Dinamico MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.3.2 Install a New Instance of N2 MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.3.3 Install a New Instance of N2 WebForms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.3.4 Integrate N2 into an Existing MVC Site . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.3.5 Integrate N2 into an Existing WebForms Site . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.4 Deploying N2 to a web server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.5 The N2 Installation Wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.6 Contributing Code back to N2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.1 Site and Language Roots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.2 Creating and Editing Content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.2.1 Edit mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.2.2 Linking to Content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.2.3 Organize Parts mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.2.4 Using the Rich Text Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.3 Managing Permissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.3.1 Securing Non-ContentItem Pages with N2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.4 Search Engine Optimization (SEO) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.5 Importing and Exporting Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.6 Troubleshooting Runtime Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.6.1 Common Runtime Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.6.2 File Upload Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.6.3 Proxy Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.6.4 Routing Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 Developer Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.1 The Domain Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.1.1 Editors via Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.1.2 Your First ContentItem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.2 Creating and Updating Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.3 Page Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.3.1 Creating a ContentPage controller in ASP.NET MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.3.2 Creating a Content Page Template in WebForms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.3.3 Dinamico Page Tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.4 Master Pages and Zones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.5 Theming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.6 Part Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.6.1 Built-in Parts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.6.2 Defining Zones within Parts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.6.3 Dinamico Part Tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.6.4 MVC Part Tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.6.5 Overriding Part Rendering with Adapters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.6.6 Template-First Definitions (MVC Razor) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.6.7 WebForms Part Tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.7 Editors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.7.1 Built-in Editor Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.7.2 Creating Custom Editors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.7.3 Organizing Editors with Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.8 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.9 Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.10 Links and Relations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.11 Finding Content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.12 Caching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3 3 5 6 8 8 10 11 11 11 11 12 12 13 13 14 15 17 18 20 21 22 24 27 28 29 29 29 29 30 30 31 31 31 33 35 35 37 37 39 41 43 43 44 44 45 45 45 45 48 48 49 51 51 52 55 57 57 59 59 62

1.3.13 Filtering Content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.14 Extending the Administration System with UI Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.15 Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.16 Extending web.config . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.17 Permissions and Roles, Programmatically . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.4 Additional Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.4.1 Getting Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

63 65 67 68 68 69 69

n2cms Home
This is the home of the n2cms space. To help you on your way, we've inserted some of our favourite macros on this home page. As you start creating pages, blogging and commenting you'll see the macros below fill up with all the activity in your space.

Recently Updated
Managing Permissions

a minute ago updated by Benjamin Herila [Administrator] view change


Permissions and Roles, Programmatically

a minute ago updated by Benjamin Herila [Administrator] view change


Contributing Code back to N2

32 minutes ago updated by Anonymous view change


Contributing Code back to N2

yesterday at 4:20 PM updated by Benjamin Herila [Administrator] view change


Getting Support

May 13, 2013 updated by Benjamin Herila [Administrator] view change


Configuring the Database

May 01, 2013 updated by Benjamin Herila [Administrator] view change


Installing N2CMS NuGet Packages

May 01, 2013 updated by Benjamin Herila [Administrator] view change


diagram-src.pptx

Apr 29, 2013 attached by Benjamin Herila [Administrator]


Installing N2CMS NuGet Packages

Apr 28, 2013 updated by Anonymous view change


Creating and Editing Content

Apr 26, 2013 updated by Benjamin Herila [Administrator] view change


image2013-4-26 14:10:50.png

Apr 26, 2013 attached by Benjamin Herila [Administrator]


image2013-4-26 14:1:20.png

Apr 26, 2013 attached by Benjamin Herila [Administrator]


Site and Language Roots

Apr 26, 2013 updated by Benjamin Herila [Administrator] view change


image2013-4-26 13:6:14.png

Apr 26, 2013 attached by Benjamin Herila [Administrator]


image2013-4-26 13:2:45.png

Apr 26, 2013 attached by Benjamin Herila [Administrator] Navigate space

Getting Started
N2 is a lightweight CMS framework. With just a few strokes of your keyboard a wonderful strongly typed model emerges complete with a management UI. You can spend the rest of your day building the best site imaginable.

Project home page and more information at n2cms.com

"It's so .NET!"
Unlike most CMS'es you build the model of the data that needs to be managed using C# or VB code in Visual Studio. The type below is picked up by the N2 engine at runtime and made available to be edited. The code uses an open API with multiple built-in options and unlimited customization options.

[PageDefinition(TemplateUrl = "~/my/pageitemtemplate.aspx")] public class PageItem : N2.ContentItem { [EditableFreeTextArea] public virtual string Text { get; set; } }

"I never thought getting the data out again could be so easy"
N2 CMS knows not to mess with YOUR HTML. For web-forms it provides a nice data binding controls, and for ASP.NET MVC routes to your controller and provides easy access to data.

Binds a control to the current page's text property: <asp:Literal Text="<%$ CurrentItem: Text %>" runat="server" /> Provides create, read, update, delete access to content through ASP.NET the databinding API: <n2:ItemDataSource ID="Level1Items" runat="server" Path="/" /> <asp:DataGrid DataSourceID="Level1Items" runat="server" /> Renders non-page items added to the "RightColumn" zone: <n2:Zone ZoneName="RightColumn" runat="server" /> Outputs content using the default control (a literal in this case): <n2:Display PropertyName="Text" runat="server" />

"This API is my friend"


N2 CMS not only makes the content manageable by non-techies, it also makes it easy to find and do stuff with content programmatically.

public void DoSomeStuffWithSomeItems(DateTime minDate, DateTime maxDate) { IList<ContentItem> items = N2.Find.Items .Where.Created.Between(minDate, maxDate) .And.SavedBy.Eq("admin") .OrderBy.Published.Desc .Select(); foreach (ContentItem item in items) DoSomethingWith(item); }

"I just know what to do with this"


N2 is bundled with a usable editor interface that allows (among other things) editing, organization, moving, exporting and importing of content.

Virtually no administration or configuration is required. To further simplify usage you can create plug ins.

Contents Links
N2CMS Home page http://n2cms.com N2CMS Community page http://n2cms.codeplex.com N2CMS Github repository (code access) http://github.com/n2cms/n2cms

Server Requirements
Operating System
Any OS capable of running .NET framework such as: Windows XP Windows 2003 Windows Vista, Windows 7, Windows 8 Windows 2008/R2 IIS 6 or newer ASP.NET Development Server WebMatrix .NET Framework 3.5 SP1 .NET Framework 4.0 Windows XP and Windows Server 2003 (and Windows Server 2003 R2) do not support .NET Framework 4.5.

Web Servers

N2CMS has been tested successfully on the Visual Studio embedded web server, IIS, and IIS Express.

.NET Framework
N2CMS 1.5 can run on .NET 2.0. We recommend that you run N2CMS on the latest version of the .NET framework possible.

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 for these database engines 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). Wilcard mapping is an IIS feature that enables requests to all types of resources to pass through managed ASP.NET code. This allows N2 CMS to serve pages for pages not ending with .aspx. This is configured slightly differently depending on IIS version. Try searching and pick the version you're using: http:/ /www.google.com/search?q=iis+wildcard+mapping

Visual Studio Development


Visual Studio 2012 is recommended for site development with N2CMS. Visual Studio Express can also be used. Visual Studio 2012 project files are included in the N2CMS source tree.

Shared Hosting
Some users report no problems running in shared hosting under medium trust, others have had problems. N2CMS has been tested on unmodified medium trust. Its recommended you ask the hosting provider before you buy a long-term plan. Note that N2CMS can be somewhat RAM intensive, and requires a minimum of 64 MB of RAM dedicated to your website. More RAM may be needed depending on the plugins you require or the amount of traffic your website receives. Plug-ins such as site search can also increase the memory requirement.

Setting Up Your Environment


Development Environment
There are two supported environments that you can use for developing a site with N2: 1. Git-based environment 2. Nuget-based environment Choose this: If you want this:

Nuget-based environment

You want the easiest integration of N2 in an exisitng project. The Nuget framework will download and install all required dependencies into an existing Visual Studio project. You always want to have the most recent code, or you want to use one of the sample template projects. The Git-based environment contains both the WebForms and MVC template packs, sample data, plus the N2 Core and all dependency binaries. This is a great way to get started with N2, particularly if you don't already have a project started. You can use one of the existing projects as a basis for your new N2-based site: WebForms Templates Pack ASP.NET MVC Templates Pack ASP.NET MVC "Dinamico" Templates Pack (uses the Razor engine)

Git-based environment

Getting the Bits


Each of the supplied packages is supplied either as a Git repository or as a Nuget package. Start with Git: check out the N2 repository located at http://github.com/n2cms/n2cms. Note: We don't recommend using Github's archive formats (tgz, zip). Using the archive formats will make your installation more difficult to update as Git's patching infrastructure will not be available. Start with Nuget: install the requisite Nuget package from within your Visual Studio project: n2cms_webforms n2cms_mvc n2cms_dinamico

Overview of Available Packages


Package N2 CMS 2.x Source Code Description 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 its recommended to start from one of the template packs, or examples. 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. 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. 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 dont need existing templates. 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 dont need existing templates. 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 dont need existing templates. This is the N2 CMS framework compiled and zipped for upgrade of a previous version, or integration with an existing site.

N2 CMS 2.x ASP.NET MVC Templates Pack

N2 CMS 2.x ASP.NET WebForms Templates Pack

N2 CMS 2.x MVC Minimal Example

N2 CMS 2.x C# Minimal Example

N2 CMS 2.x Visual Basic Minimal Example

N2 CMS 2.x Compiled Framework and Management UI

Getting up and Running


Each package contains one or more Visual Studio Solution (*.sln) files. Open the Solution file for what you want to run, and edit the web.config file to use the database engine of your choosing. Invoke the Run command in Visual Studio to launch a development web server with N2 running inside. You should see the setup wizard right away. The next step is to either start using N2 and begin building your content using the pre-defined templates, or start developing with N2 to customize the system to suit your needs. Most users will want to do at least some development and customization as every website has different needs and the templates don't cover every possible scenario that can be achieved with N2 CMS.

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.

Updating N2CMS
After you've installed N2CMS in one of these ways, you will want to update it from time to time to take advantage of the latest features, security patches, and other updates. If you opted to use the Nuget deployment model, the Nuget packages will be updated periodically, and you can update using the built-in Nuget update mechanism to update your local instance of N2CMS. If you chose the Git deployment model, you can use git pull to get the latest updates in your own Git repository.

Visual Studio Snippets and Templates


The downloadable packages on Codeplex contains a number of templates and snippets which are useful when developing N2 sites. You need to update the path with your own version of Visual Studio. For example, if you are using Visual Studio 2008 you need to substitute in 2008 for 2010 in the paths below. Snippets are copied to [Documents]\Visual Studio 2010\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 include: 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 2010\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


The IntelliSense documentation should be installed automatically. If it is not installed, check for ~/bin/N2.xml. This enables code documentation during intellisense operations and hovering in Visual Studio.

Installing N2CMS NuGet Packages


First, download the release and extract to a path such as C:\N2Packages (this example path is used below) Compiled N2CMS Releases are available here https://n2cms.codeplex.com/releases/ Next, decide whether you want to use the ZIP or NOZIP management packs.

Before doing anything listed on this page


Back up your project before installing or uninstalling any N2CMS nuget packages.

Which management pack should I choose?


You can choose whichever management pack is right for you. Consider the following benefits and drawbacks. The benefit of the ZIP management pack is that it is a single file for the N2 Management Interface. However, if you store your website in a source control depot (e.g. Git repo), you end up with a lot of bloat as the ~5 MB N2.zip file gets upgraded over time. You also need to upload the entire N2.zip when you update it. The benefit of the NOZIP management pack is that you can take advantage of Web Deploy incremental uploads, as well as more efficient source control storage as the files are installed separately (not extracted). Additionally, the Zip Virtual Path Provider is not installed, which means that less memory is used by N2CMS.

Switching Management Packs


You can switch management packs (e.g. ZIP to NOZIP or visa-versa) at any time by first uninstalling any current management pack, and then installing the desired management pack.

Multiple Management Packs


You MUST NOT install multiple management packs on your N2 installation. This is not supported and you will likely break your N2 installation. The only supported recourse in this situation is to start a new project! Back up your N2 installation before installing any management packs.

Upgrading from N2CMS 2.5 and earlier


Uninstall-Package n2cms.dinamico Uninstall-Package n2cms Uninstall-Package n2cms.management

Installation Instructions
Example: Dinamico Template Pack
For the NOZIP option:

Install-Package -Source C:\N2Packages -Name n2cms.dinamico Install-Package -Source C:\N2Packages -Name n2cms.management.nozip

For the ZIP option:

Install-Package -Source C:\N2Packages -Name n2cms.dinamico Install-Package -Source C:\N2Packages -Name n2cms.management.zip

Database Connection
If this is a clean installation, you will need to install the database.

Upgrading
You can upgrade just the management pack. The N2CMS libraries will be updated automatically if required. You can also upgrade the template packs. Run the relevant Install-Package command as listed above.

Install-Package -Source C:\N2Packages -Name n2cms.management.nozip

OR

Install-Package -Source C:\N2Packages -Name n2cms.management.zip

Configuring the Database


N2 supports several kinds of databases. Relational Database XML Data Store NoSQL Database

Installing Database Drivers


You may need to install a database driver in order to enable accessing a particular type of database. For example, if you want to use SQLite relational database, you should install the N2CMS.SQlite.X86 NuGet package (which in turn installs System.Data.SQLite). If you want to use the built-in XML data store, no additional database driver is required.

Using a Relational Database


To configure a relational database open web.config in the sites root directory and find the <connectionStrings> section.

<!-- 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" />

Then replace the connection string tag with one that corresponds to the database engine you want to use. Database Engine SQLite Connection String <add name="N2CMS" connectionString="Data Source=|DataDirectory|\n2.db;Version=3;New=True;" providerName="System.Data.SQLite"/> <add name="N2CMS" connectionString="Server=(local);Database=N2_Templates;Integrate d Security=SSPI"/> <add name="N2CMS" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\N2.mdf; Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient"/>

SQL Server 2005+

SQL Express 2005+

SQL Server 2000

<add name="N2CMS" connectionString="Data Source=SQLServer2000;Database=SQLDatabase2000;User Id=SqlUser2000;Password=SqlPassword2000;Network Library=DBMSSOCN;" providerName="System.Data.SqlClient"/> <add name="N2CMS" connectionString="Data Source=MySQLServer;Database=MySQLDatabase;User Id=MySQLUser;Password=MySQLPassword;" providerName="MySql.Data.MySqlClient"/>

MySQL

N2 supports several kinds of databases. To configure another database open web.config in the sites root directory and find the <connectionStrings> section. Remove the existing connection string and update the most relevant template to your databases settings.

XML Data Store


Coming soon! N2CMS supports storing your data as loose XML files on disk. This avoids the need to load any database drivers, which in some cases can reduce your site's memory footprint and improve performance. This option is not recommended for large websites.

NoSQL Data Store


Coming soon! N2CMS supports NoSQL databases such as MongoDB. N2CMS can be extended to support other NoSQL systems as well. To configure MongoDB:

Switching Databases After Installation


You can change the database type after installing N2. To do this we recommend that you first export all your site data and users from N2 using the Bulk > Export functionality, then switch database engines and re-enable installation by setting allowInstallation="true" and modifying the connection string in web.config. Then navigate to your site and in the setup wizard, after creating tables opt to import the .xml file that you just exported. N2 will recreate the database entities for your data in the new database.

Deciding Where to Store Attachments


N2 can store uploaded files (attachments) within the database or in the filesystem. The default is to store attachments in the filesystem. If you want to store attachments in the database, you need to add this to your web.config:

<database><files storageLocation="database" />

Prepare for Installation


Install a New Instance of N2 Dinamico MVC
Install using NuGet (recommended) Install from Git
If you want to have the absolute latest build of N2, you can install N2 MVC from the Git repository.

Install a New Instance of N2 MVC


You might want to consider the Dinamico templates, which use the newer Razor engine instead of the legacy asp.net view engine.

Install using NuGet (recommended)

Install from Git


If you want to have the absolute latest build of N2, you can install N2 MVC from the Git repository.

Install a New Instance of N2 WebForms


Install using NuGet (recommended) Install from Git
If you want to have the absolute latest build of N2, you can install N2 MVC from the Git repository.

Integrate N2 into an Existing MVC Site


Update Global.asax.cs:

using N2.Web.Mvc; public static void RegisterRoutes(RouteCollection routes) { routes.MapContentRoute("Content", N2.Context.Current);

Add a HomePage content item:

namespace VanillaApplication.Models { [N2.PageDefinition] public class HomePage : N2.ContentItem { } }

Update the HomeController:

[N2.Web.Controls(typeof(Models.HomePage))] public class HomeController : Controller { public ActionResult Index() { ViewData["Message"] = "Welcome to ASP.NET MVC!"; return View(); } }

Compile and run. You should be directed to the N2 installation.

Integrate N2 into an Existing WebForms Site

Deploying N2 to a web server


Deploying N2 to a Web Server
When you are

Web.config Entries
{content needs to be written}

Publishing from Visual Studio


{content needs to be written}

Keeping Production and Development Data in Sync


Once you deploy in production, you may or may not want to move away from using the default SQLite database engine. Either way, take care not to replace your production database with an older development database! We recommend that you periodically replace the database you use in development with copy of your production database so that you can experiment with your current production data. Your development and production instances of N2 do not necessarily need to be using the same database engine. We recommend that you use the import/export feature in the N2 administration area to first export your site to a file, and then import this file in your production setup. Why not simple database replication? Because not all data is stored natively in the database, traditional database replication is not guaranteed to provide consistent replication of your N2 site data. The N2 import/export API handles all data, including data not stored in the database. Note: If the file is very large, you might not be able to upload the file to your development instance unless you change some configuration settings. See the related topic: File upload issues.

Streamlining deployment using ZipFS


The N2 administration area uses a number of small image files that can be burdensome to deploy over FTP. Furthermore, some hosting environment impose limitations on the total number of files hosted. To eliminate these small resource files, you can deploy a N2.ZIP file containing these resource files. The server will transparently extract this N2.ZIP file and serve the extracted files to clients on demand.

{content needs to be written} Caveat: more memory used by the ZIP DLL.

The N2 Installation Wizard


These steps assume you have already set up the files for your N2 installation. If you have not yet done that please see Prepare for Installation. When you navigate to your site's root (~/) you should be redirected to the N2 installation wizard.

Set a password for your new site. Leave the checkbox selected (you can change this later in web.config if you wish) Click on help me install a database for a new site Log in using the username admin and password you just wrote. Continue to create tables. Now is the good time to update the connection string to another database if you dont want to use SQLite. If you are installing N2 in an existing database, the N2 setup wizard will drop any tables that have conflicting names with N2's tables. We recommend that you install N2 in its own database. On step 2. Content Package go to Manually insert nodes and insert a Root Page (fallback) and HomePage and click Add two separate nodes.

If necessary, scroll down and click Update web.config.

On the finishing touches click on disable installation. This will make this installation wizard unavailable. To re-enable it, set allowInstallation to true in web.config (this is needed for upgrade).

Contributing Code back to N2


One of the key features of N2CMS is our vibrant community of users and developers. When you extend N2CMS to meet your own, your

customers, or your organizations' needs, we encourage you to commit useful portions of what you create back to the community, so that others can benefit from your work. Think of the time that N2CMS saves you! Your contributions will help our thousands of users in turn.

Why share your code back to the N2 project?


Give back to the community that gave you this awesome software (and documentation!) Community code reviews will find even more bugs Further community contributions will improve upon your code, adding value that you can pass back to your customers at no additional cost to you! We will consider every contribution, and we want to make it as simple as possible. This article should contain everything you need to know about contributing code back to N2.

Github
Official development of N2CMS takes place on Github.

Get your own copy of N2CMS


Not just anyone can commit to the N2CMS code. A member of the N2CMS development team code reviews every community contribution in a forum open to the entire N2CMS community. Therefore, if you want to modify or add to the N2CMS code, you should make your own copy (or fork ) of the N2CMS repository on Github. To do this, you just sign into Github and press the Fork button on the N2CMS Github page. Once you do that, your very own fork will be created. Notice the title now becomes your_user_name/n2cms rather than n2cms/n2cms! You can push to this rep ository, and then let us know that you'd like us to merge your change(s) into the official branches by sending a pull request (more on that below).

Figure 1. the Fork button on the n2cms/n2cms Github page

Licensing your contributions


You retain ownership of code you contribute to N2CMS. Under U.S. copyright law, an author automatically owns the copyright to anything that author created. However, in some countries, you may need to explicitly declare copyright. A copyright statement should appear at the top of every file you commit. N2CMS itself is licensed under the LGPL license. That means while you can link your own code against the N2CMS libraries and license that linked code any way you want (including not licensing it at all), any derivative works or modifications to the N2CMS library itself are licensed under the LGPL. You can license your contribution by adding a comment header to the file you're committing. If you're modifying a file that is already part of N2CMS, you shouldn't add a header because that file is already covered by the N2CMS LGPL license.

Adding files and Committing Sending a Pull Request Updating Your Fork from Official Branches

Graphical User Interface (GUI) Alternatives to the Git Command Line


We know the command line isn't a hospitable environment for some users and developers. Luckily, for you folks who prefer a GUI environment to the Git command line, free solutions are available!

Name SourceTree Atlassian

Description SourceTree provides rich Git functionality with a slightly more complex user interface. Highly recommended. Github's own official GUI client, available for Windows and Mac.

Download links http://www.sourcetreeapp.com/ Windows & Mac

Github for Windows Github

Windows: http://windows.github.com/ Mac OSX: http://mac.github.com/

Setting up SourceTree
First, you need to fork the repository on Github per the instructions above. 1. click Clone/New in the toolbar. Under Source Path / URL, enter the URL to your fork of the N2CMS repository (see above). 2. specify the destination path on your PC where you want to save the source code 3. click Clone and SourceTree will set up your own copy of the repository. Now, you need to add a remote for the official n2cms branches, so that you can pull changes from there. 1. make sure that your n2cms clone is open in SourceTree (double-click the item in the repository list on the left) 2. right-click Remotes and click New Remote

3. In the New Remote dialog, fill in the required properties a. Remote name: github-n2cms b. URL / Path: git@github.com:n2cms/n2cms.git 4. Click OK to save the Remote 5. You can now fetch and pull (which is equivalent to fetch+merge) changes from the official Github repository into your own local copy. When you've done that, you can push those changes to your Github fork copy as well.

Why wasn't my pull request accepted?


Unfortunately, we aren't able to merge every pull request. A member of the N2CMS developer team will let you know in the pull request itself why the pull request isn't accepted. In some cases, we might make modifications to your code as a condition of its acceptance. Or, we might ask you to fix a problem or two and merge it afterwards.

Management
Signing in to N2
You'll need a username and password to log on to N2CMS. When you have this, visit ~/n2 (e.g. www.yourdomain.com/n2) to enter your credentials.

For N2CMS 2.5 and earlier


When you sign in, you'll see a 3-pane view (pictured below) that consists of: The largest area is the preview pane, which shows you the page on your site that you're currently viewing. If you enter edit mode, the edit form occupies this area. On the left, the site tree, which shows you the content of your website. Drag and drop nodes to adjust parenting (for example, put one page "under" another page). Left-click a node to view that page in the preview pane. Right-click a node to access the On the top, the toolbar allows you to perform a variety of management tasks such as: Sign out from the administration area

Manage user accounts Manage site-wide settings Manage page-level access permissions Perform bulk operations, such as import/export

Figure 1. the management UI N2CMS does not currently support website templates that contain frame-breaking scripts.

For N2CMS 2.5 and later (with UI refresh)


When you sign in, you'll see a user interface that should look familiar if you're already familiar with earlier versions of N2CMS. However, it's been refreshed for improved accessibility, performance, and mobile device compatibility.

In this section
Signing in to N2 For N2CMS 2.5 and earlier For N2CMS 2.5 and later (with UI refresh)

Continue reading

Site and Language Roots


An instance of N2CMS can actually host multiple websites, and multiple languages of multiple websites. When you first set up n2cms, the installer creates a root node under which all your sites are contained. The root node by default has the following children: A start page or language intersection which represents the root of a particular website (you can have more than one of these if you are hosting more than one website) A Trash bin which holds deleted content items from all sites in the N2 instance An Upload folder which holds uploaded assets, such as images and available file downloads, which are accessible to all websites You should have one language intersection under your root node which represents a particular site, and then a start page for each language of that website. For example, your structure could look as follows: Root node (LanguageIntersection) my_website (StartPage) en-us (StartPage) es-es

(StartPage) ... (LanguageIntersection) my_other_website (StartPage) en-us (StartPage) es-es (StartPage) ... (Trash) (Upload) Your content pages for each site/language combination go under the respective StartPage.

Differentiating Multiple Websites (Virtual Sites in a single N2 installation)


There is currently no way to specify multiple hostnames for a differentiating site. A code contribution to fix this would be welcomed!

Hostname (DNS)

You can assign a hostname to a language intersection (or a start page located directly under the Root node) by using the Site configuration menu. Depending on which template pack you are using, you can also configure custom HTTP 404 and 500 error pages by pointing to a node in your content tree. These custom 404/500 pages can even use parts like any other content page! Fill in the Site host name (DNS) field with the domain you want to map. If you leave this field blank (this is the default), then all domains will map to that site.

Template/Theme
You can also customize the template or theme that this virtual site inherits by customizing the Site Theme option. The changes are applied immediately when you Save.

Example Screenshot

n2_host.config file

The n2_host.config file maps hosts to root and start pages. URLs are generated relative to the StartPage specified in the startPageID attribute.

<?xml version="1.0" encoding="UTF-8"?> <!-- This is stored in a separate file so that the installation wizard can write to this file without write access to web.config --> <host rootID="1" startPageID="4" multipleSites="true"> <web extension="" /> <vpp> <zips> <add name="n2.management" observedPath="~/N2/" filePath="~/N2/N2.zip"/> </zips> </vpp> </host>

You should check that the rootID and startPageID node point to the correct root and start page node ID. You might need to look into the database to find the IDs of the start page and rootID. These values should be initially set up correctly by the N2CMS setup wizard.

Additional Localization Option


Root StartPageEN (url : /) Page1EN Page2EN Page3EN StartPageFR (url : /fr) Page1FR Page2FR Page3FR

Creating and Editing Content


Creating a new page
To create a new page, right-click on the parent (the page you want to make the new page under) and click New in the context menu.

Then, you can select a template for the new page. Usually, you want the template called Content Page. Once you select a template, the page is created and you are taken to Edit mode.

Editing Content
Content editing is done in one of two modes: Edit mode Organize Parts mode When you first create a page, you're taken to Edit mode. Here, you specify the basic attributes of the page: the page title the url of the page (which is usually generated from the title automatically)

any metadata such as keywords, etc.

Figure 1. Edit form overview (click above to enlarge) sss

Edit mode
In Edit mode, the various properties of the item you are editing are displayed. There are a variety of editor types, all of which are controlled by att ributes on the classes you are editing. For more information on these editor types and how to create your own, see the Editors topic in the documentation.

Entering Edit Mode


There are two ways of entering Edit Mode: 1. In the left pane of the Administration panel, right-click on a content item and select Edit from the context menu. 2. On the N2 toolbar, click the Edit button as shown below:

Figure 1. Entering Edit mode.

Editing a page
Now we are accessing the site's edit interface (/edit) and are editing the start page. Remember we defined a property named Text? Remember that we gave that property an attribute: EditableFreeTextArea? That attribute is interpreted by the N2 engine and a html editor is displayed when we edit the page without the need to write a single form.

Attributes on content items

While we're still remembering what we discussed in the previous chapter. The TextPage class was also decorated with an attribute: [Defi nition]. The attribute tells N2 what type of page is called when we are editing. In this GalleryItem we're creating a new item.

Labels on editable stuff


That label saying Text is actually the parameter we gave to the attribute on the property.

Editing Parts in Edit Mode


Each Part is displayed in the Edit Mode interface as an item within a zone. You can click on an item to edit that item in more detail, or you can use the up and down icons to move the item up or down within its current zone. Click the Add icon to add a new item in the given zone.

Figure 2. Editing parts on a page in Edit mode.

Linking to Content
In this section... Page-to-Page Navigation Single Links Video: Creating an inline hyperlink Dynamically Linking to Content Items File Downloads

Page-to-Page Navigation
Single Links
There are a few ways that users can download files. You can choose from embedded hyperlinks, or two parts that Method How to Use Screenshot

Insert part: Hyperlink

1. Drag and drop a Hyperlink part from the Organize Parts toolbox into the page. 2. Select a page in your site. You can click on the Browse (hyperlink icon) button to pop up a dialog that allows you to select any page from the site content tree. 3. Fill out the properties of the hyperlink (noting the link URL property) 4. Click Save to save the hyperlink to the document. a. You need to click Save again to save your changes to the overall page. For more information, read about the Hyperlink content part.

Inline hyperlink

1. In any rich text editor, highlight text and click on the Hyperlink button (red circles in the screenshot). 2. Fill in the properties of the link. You can use the Browse Server button to select another page in your website or enter any URL manually. 3. Click Save to write the hyperlink to the document. a. You need to click Save again to save your changes to the overall page. b. Finally, click Save and Publish to publish the document.

Video: Creating an inline hyperlink

Dynamically Linking to Content Items


You can list sub-pages manually and create hyperlinks as in the scenarios above. However, you can also use the Content List or Selection parts to create a dynamic list of Method Insert part: Content List How to Use 1. Drag and drop a Content List part from the Organize Parts toolbox into the page. 2. Select the Parent of the item that you want to enumerate children from. For more information, read about the Content List. Screenshot

Insert part: Selection

1. Drag and drop a Selection part from the Organize Parts toolbox into the page. 2. Mark the checkbox next to each item you want to include in the selection (see screenshot) For more information, read about the Selection Content Part.

File Downloads

Method Insert part: File Download List

How to Use 1. Drag and drop a File Download List from the Organize Parts toolbox into the page. 2. Select the directory on your server (e.g. /upload/...) and specify a file mask (e.g. *.jpg for all file names ending in .jpg) 3. Decide how you want the files to be sorted.

Screenshot

Link to file directly using Hyperlink Content Part

1. Drag and drop a Hyperlink part from the Organize Parts toolbox into the page. 2. Select the file that the user should download. You can click on the Browse ( hyperlink icon) button to pop up a dialog that allows you to select any file from the upload directory. For more information, read about the Hyperlink content part.

Link to file directly by creating a hyperlink in a rich text area

1. In any rich text editor, highlight text and click on the Hyperlink button (red circles in the screenshot). 2. Fill in the properties of the link. You can use the Browse Server button to select a file to be downloaded.

Organize Parts mode


Inline editing is also possible, which allows you to edit the content of a page while viewing that page. This mode allows you to more easily predict

what the page is going to look like after editing is complete. There is also a visual tool for editing the parts on a page. On the N2 toolbar, click the Organize Parts icon. When you mouse over any part, a handle is shown. You can click and drag the part up or down in its current zone, or to a different zone on the page. Note that parts can restrict what zones they participate in, and only valid target zones are displayed in the drag and drop interface. Again, changes are saved immediately. You can also add new parts by clicking on the ways: Description 1. Click Edit in the top toolbar and then choose Organize. Add icon in the Edit Mode interface, or by entering Organize Parts mode in one of two

Screenshot

2. Expand the toolbar (fig. a) if it's not expanded already, and then click the Organize Parts icon (fig. b) when the tray opens.

(a)

(b)

Using Organize Parts mode


When you are in Organize Parts mode, a list of available parts is shown in the Parts Toolbox. You can drag and drop a part from the parts toolbox to an available zone, as pictured below. When you complete the drop operation successfully, the properties for your newly-created zone will open and you can customize that part for the first time. Parts Toolbox Available Zone

(click above to enlarge)

Template-Defined (Fixed) Parts


Some parts are built-in to the page type or template that you have selected. When you are in Organize Parts mode, these fixed parts are highlighted when you mouse-over them and a on the Edit Page screen. pencil icon appears that allows you to edit the property. These properties are also accessible

Zoned Parts
Other parts can be dragged and dropped into areas called "Zones" on the page. When you enter "Organize Parts" mode on a page, the available zones are highlighted in green when you begin dragging a Part into the page. The available zones are also shown in the Edit form on the right-hand side.

Using the Rich Text Editor


The Rich Text Editor is based on TinyMCE. The editor generally works like any word processor.

System Requirements
The following web browsers are supported: Internet Explorer 9 or higher, Google Chrome, Mozilla Firefox 3 or higher

Styles
Please note that the styles displayed in the Rich Text Editor may not look the same in the editor as they will appear on the web site. Click Save to save your changes and you can preview the results live. You can always return to the editor if you want to make additional changes.

Extended Functionality

The extended functionality can be accessed by clicking on the Show/Hide Toolbars option all the way on the left of the editor.

Hyperlinks
To insert a hyperlink, use the Insert/Edit link button. The Insert/Edit link button will be disabled if there is no text selected. After you click the Insert/Edit Link button, the Insert/Edit Link Dialog will be shown. Click the Browse button to select the link target from the site hierarchy. Alternatively, you can type any web URL into the box to link to that location. Click Insert when you are finished to create the link. The Unlink butto n (directly to the right of the Insert/Edit Link button) can be used to remove a hyperlink (the underlying text will remain).

Managing Permissions
Editing Page Permission Managing Roles Available roles can be managed from TODO

Common User Management Tasks


I want to... Create a user Remove a user Disable a user Change a user's password

Edit user properties

Resetting the built-in admin password


The built-in admin account has its password stored in the web.config file. In order to protect the admin password, you should hash it using the SHA-1 algorithm. For optimal security, you can also use the SHA-256 algorithm and salt the hash with n2CMS#@; for example, if your desired password is password, the value you hash should be n2CMS#;@password. Encryption standard None Web.config setting

<credentials passwordFormat="Plain"> <user name="admin" password="password" /> </credentials>

SHA1

<credentials passwordFormat="SHA1"> <user name="admin" password="b57f73b8bb929a7f8bc2983f6b3 a0a253027d080" /> </credentials>

SHA256 (N2CMS v2.5 and later)

<credentials passwordFormat="SHA1"> <user name="admin" password="b57f73b8bb929a7f8bc2983f6b3 a0a253027d080" /> </credentials>

See Also
Permissions and Roles, Programmatically

Securing Non-ContentItem Pages with N2

Search Engine Optimization (SEO) Importing and Exporting Data

Troubleshooting Runtime Issues


Really, the first thing that you should check is that the App_Data/n2_host.config file is set up correctly.

Common Runtime Exceptions


Exception Type Castle.MicroKernel.ComponentNotFoundExc eption Exception Text No component for supporting the service N2.Persistence.Search.IAsyncIndexer was found Resolution Upload/replace N2.Management.dll

File Upload Issues


Increasing the Maximum Upload Size
The 4MB default is set in machine.config, but you can override it in you web.config. For instance, to expand the upload limit to 20MB, you'd do this: <system.web> <httpRuntime executionTimeout="240" maxRequestLength="20480" /> </system.web> Since the maximum request size limit is there to protect your site, it's best to expand the file-size limit for specific directories rather than your entire application. That's possible since the web.config allows for cascading overrides. You can add a web.config file to your folder which just contains the above, or you can use the <location> tag in your main web.config to achieve the same effect. This will override the upload size limit for files within the N2 administration area only: <location path="N2"> <system.web> <httpRuntime executionTimeout="110" maxRequestLength="20000" /> </system.web> </location>

Error When Creating Directories


If your N2 root is not ~/, you may receive an error such as this when creating directories:

[NullReferenceException: Object reference not set to an instance of an object.] N2.Edit.FileSystem.Directory1.Reload() in c:\Projekt\OSS\github\n2cms\n2cms\src\Mvc\MvcTemplates\N2\Files\FileSystem\Directory.a spx.cs:44 N2.Edit.FileSystem.Directory1.OnInit(EventArgs e) in c:\Projekt\OSS\github\n2cms\n2cms\src\Mvc\MvcTemplates\N2\Files\FileSystem\Directory.a spx.cs:35 System.Web.UI.Control.InitRecursive(Control namingContainer) +140 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +480

The workaround is to create an entry in your hosts file like

127.0.0.1

n2site.enferno.local

n2site

Create the site in IIS manager, bind it to your name like n2site, and map the root to your project folder. Change project setting to Use Local IIS Server and set the project url to http://n2site This workaround does not work on Windows Azure. When using N2 on Windows Azure you must use / as the root of your N2 site.

Proxy Issues Routing Issues

Developer Fundamentals
CMS Framework vs. Templates
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 sites 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.

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. Its 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.

Its 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 pages 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 instances 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).

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 pages 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 arent within a start page (e.g. if they have been thrown in the trash): /ContentPages/Index/?page=123

The Domain Model


The N2 Domain Model
Okay, let's dive right in and look how a what a simple project would look like in Visual Studio. That's where most of the development effort is spent when developing an N2 CMS. N2 allows you to define which types of content items are available in your CMS by creating .NET classes and decorating them with attributes. You can develop diverse functionality without creating any database tables or building any input forms. An important concept in N2 is the ContentItem class. This is the definition of a certain kind of page in our CMS. Instances of this class (objects) contain the content/data that we want to display using a template (an aspx page). Classes that inherit ContentItem have properties (e.g. the Text string) that expose the actual content. The properties are decorated with C# attributes that tell N2 how to handle the properties. For example, N2 can automatically generate editors to be used in the Edit interface (more on that in the next topic). {TODO} Figure 1. A bird's-eye view of the N2 content and view model.

A Simple Example: TextPage


Let's create a simple page type. We'll call this a TextPage, and as such we will create a corresponding class called TextPage. This is what TextPa ge looks like: (source code) By default, N2 inherits a few properties from ContentItem. sss

Defining Additional Properties


Any properties that we want to expose through our Views, we need to define on our own. Let's define: a title some textual (body) content an optional header image

Exposing Properties through Editors


Now that we've defined our properties, we will decorate them with C# attributes that tell N2 how to handle the properties. For example, N2 can automatically generate editors to be used in the Edit interface. (We'll discuss the Edit interface in more detail in the next topic)

Figure 1. Editors are exposed via attributes on the properties defined in ContentItems.

Creating the View


The ContentItem tells N2 everything about the data that needs to be stored for a given item in N2's database. However, it does not define how the ContentItem will look when N2 generates a HTML page. We will cover Creating the View in a later chapter; the actual implementation of the view will differ depending upon the view framework we're using (either MVC or WebForms). However, the content model (ContentItem) remains the same.

Since TextPage inherits from N2.ContentItem (in this case a bit down the inheritance chain) it is treated by the N2 engine as a content type and made available for editing through the edit interface. Take a quick look at that Text property before you move on. It has an interesting attribute that's used by the N2 engine to determine what kind of editor should be used to edit that property.

A property encapsulating our content


First, lets examine that attribute called EditableCheckbox. The attribute tells the N2 engine that this is a property that is editable in edit mode.

Since it's the EditableCheckbox attribute a textarea is displayed when you edit this page. The parameters are just the name displayed in edit and the order of this property. There are a number of built-in "editable" attributes. For more information, see the Editors chapter in the user guide. Note the call to GetDetail in the getter. GetDetail gets values from a content detail collection and SetDetail updates the same value. Any serializable class is supported. The content detail collection contains all custom properties.

Editors via Attributes Your First ContentItem


Your First ContentItem
Let's create a simple page type. We'll call this a TextPage, and as such we will create a corresponding class called TextPage. This is what TextPa ge looks like:

using N2.Details; using N2.Integrity; using N2.Definitions; using System; public class TextPage : ContentItem { }

By default, N2 inherits a few properties and methods from ContentItem. Here are a few of particular interest (don't worry about the details for now): public virtual DateTime Created { get; set; } public virtual string IconUrl { get; } public virtual bool IsPage { get; } public virtual IList<T> GetChildren<T>() where T : ContentItem public virtual IList<T> GetChildren<T>(string zoneName) where T : ContentItem public virtual string TemplateUrl { get; } public virtual string Title { get; set; } public virtual DateTime Updated { get; set; } public virtual string Url { get; } public virtual int VersionIndex { get; set; } Note that none of these methods are abstract. Thus, you can see that N2 does a lot of the work for you. N2 takes care of versioning, managing URLs (though you can customize them), children, templates, modification and creation times, and more. Also note that all of these methods and properties are virtual; thus, you can override any of them in your own subclass to completely customize N2 to your exact needs. We won't do any customization right now, but we did want to point out this highly flexible engineering model.

Make it a Page
In N2, every piece of content -- whether it's a page, part, or data entity -- is a ContentItem. Therefore, we need to let N2 know that we actually want to create a page. Pages in N2 implement the IPage interface, which is simply a marker interface. In other words, IPage doesn't actually define any methods or properties. Note: At this point we've basically built AbstractPage, which is a base class for all pages used in the Webforms template pack.

Defining Additional Properties


Any properties that we want to expose through our Views (which we'll see how to create in a bit), we need to define on our own. Let's define: a title some textual (body) HTML content an optional header image Now for the image:

[FileAttachment, EditableFileUploadAttribute("Image", 90, ContainerName = Tabs.Content, CssClass = "main")] public virtual string Image { get { return (string)(GetDetail("Image") ?? string.Empty); } set { SetDetail("Image", value, string.Empty); } }

Exposing Properties through Editors


Now that we've defined our properties, we will decorate them with C# attributes that tell N2 how to handle the properties. For example, N2 can automatically generate editors to be used in the Edit interface. (We'll discuss the Edit interface in more detail in the next topic)

Figure 1. Editors are exposed via attributes on the properties defined in ContentItems.

Creating the View


The ContentItem tells N2 everything about the data that needs to be stored for a given item in N2's database. However, it does not define how the ContentItem will look when N2 generates a HTML page. We will cover Creating the View in a later chapter; the actual implementation of the view will differ depending upon the view framework we're using (either MVC or WebForms). However, the content model (ContentItem) remains the same.

Since TextPage inherits from N2.ContentItem (in this case a bit down the inheritance chain) it is treated by the N2 engine as a content type and made available for editing through the edit interface. Take a quick look at that Text property before you move on. It has an interesting attribute that's used by the N2 engine to determine what kind of editor should be used to edit that property.

A property encapsulating our content


First, lets examine that attribute called EditableCheckbox. The attribute tells the N2 engine that this is a property that is editable in edit mode. Since it's the EditableCheckbox attribute a textarea is displayed when you edit this page. The parameters are just the name displayed in edit and the order of this property. There are a number of built-in "editable" attributes. For more information, see the Editors chapter in the user guide. Note the call to GetDetail in the getter. GetDetail gets values from a content detail collection and SetDetail updates the same value. Any serializable class is supported. The content detail collection contains all custom properties.

Creating and Updating Items Page Types


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 its 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 doesnt 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 { }

Creating a ContentPage controller in ASP.NET MVC


This tutorial assumes you have added the Visual Studio item templates. How to do this is documented in Setting Up Your Environment. Right-click on the project, select add and select N2 Content Controller.

The item template includes a content page class. Take note of these traits shared by most content items: 1. Its attributed by [PageDefinition] 2. It inherits from N2.ContentItem Its enriched by attributes with an editable title, name (url segment), and free text A content controller is also generated. It shares some traits in common with most content controllers: 1. It [Controls] a type of content item (the one that was generated). 2. It inherits from ContentController<T>. The generic argument gives strongly typed access to CurrentItem 3. It has an Index action. There is no view yet, but this is easy enough to generate. Right-click in the Index action method, and Add View

Create a strongly typed view by setting the view data class to the generated model class. The view uses all regions from the master page. Usually MainContent is enough and the others can be removed. 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>

A quick compile (F6 in visual studio) makes the page available in the management UI.

Creating a Content Page Template in WebForms


This tutorial assumes you have added the Visual Studio item templates. How to do this is documented in Setting Up Your Environment. Right-click on the project node and Add / New item Select N2 Page Template and Add

A content item class and a page template is generated. Content item class:

foo

Page template:

bar

Note that the page template (in the code-behind) inherits from ContentPage<T>. Compiling (F6 by default) makes the page available in the N2 management UI.

Dinamico Page Tutorial


Creating the Page Type
The Dinamico page types are located in XXX

Creating a View
The basic idea is to be able to create multilpe views with different editors by only adding a view. This is a step aside from a fully strongly typed model. The idea is to to add cshtml files with code like this:

@{ Content.Define(re => { re.Title = "News page"; re.DefaultValue("Visible", false); re.RestrictParents("Container"); re.Sort(N2.Definitions.SortBy.PublishedDescending); }); }

The file executed by this init method:

engine.RegisterViewTemplates<Controllers.ContentPagesController>()

which builds up a template definition conneted to the ContentPage type. The filename is stored in as TemplateKey and is used to find the correct view to render.

Master Pages and Zones Theming


N2 has a robust theming engine that allows you to completely take over the rendering of your pages. N2 supports theming both MVC and WebForms pages.

Theming with MVC


To create an MVC theme, put the following folder structure in TODO

Theming with Dinamico


Dinamico themes use the Razor engine.

Theming with WebForms


When using WebForms, the entire page must be wrapped in a server form in order to enable zones and parts to function in drag-and-drop mode properly.

Part Types
Overview
TODO

Built-in parts
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.

Built-in Parts Defining Zones within Parts


TODO

Defining Zones in MVC Parts Defining Zones in WebForms Parts

Dinamico Part Tutorial


I see there are views defined in all sorts of places, such as: ~/Dinamico/Themes/Default/Views/ContentPages/XXX.cshtml ~/Dinamico/Themes/Default/Views/ContentParts/XXX.cshtml but then there are also some things in a Shared folder e.g. ~/Dinamico/Themes/Default/Views/Shared/ If for example I define a part such as this:

[PartDefinition()] [RestrictChildren(typeof(foo))] [AvailableZone("Content", "Content")] public class CustomPart : PartModelBase { ... }

The template-first system of defining content assumes the location [ThemeRoot]/Default/Views/[Controller]/*.cshtml, where [ThemeRoot] and [Controller] is configurable during startup.

MVC Part Tutorial


This tutorial assumes you have added the Visual Studio item templates. How to do this is documented in Setting Up Your

Environment. Right-click on the project, Add, New item N2 Content Controller.

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; } } }

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); } }

Right-click in the action, Add View, check Create a partial view (.ascx), and Add

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>

Compile and Voila! Choose Organize parts on a page and drag TutorialPart onto a zone.

Overriding Part Rendering with Adapters


Adapters allow you to override rendering of a part type with custom code. You can use Adapters if the view engines don't meet your needs. Adapters are commonly used in situations where the views need to be completely embedded within the project assembly, or for extremely dynamic or flexible parts. Use MvcAdapter to handle parts rendered in the Mvc or Dinamico frameworks. Use XXX (TODO) to handle parts rendered in the WebForms framework.

Example Adapter [Adapts(typeof(NewsList))] public class NewsListAdapter : MvcAdapter { public override void RenderTemplate(System.Web.Mvc.HtmlHelper html, N2.ContentItem model) { html.ViewContext.Writer.Write( /** write HTML here **/ ); } }

Template-First Definitions (MVC Razor)


Fluent Parts allow you to define a part directly from within a Razor view file. A number of simple examples of these type of parts are available in ~/Dinamico/Themes/Default/Views/ContentParts

How N2 Finds and Enumerates Fluent Parts


TODO

The base type is defined as a model of type M decorated with [PartDefinition] and there is a controller with [Controls(typeof(M))].

namespace Dinamico.Controllers { [Controls(typeof(Models.ContentPart))] public class ContentPartsController : ContentController<Models.ContentPart> { public override ActionResult Index() { return PartialView((string)CurrentItem.TemplateKey, CurrentItem); } } } namespace Dinamico.Models { /// <summary> /// This part model is the base of several "template first" definitions /// located in /dinamico/default/views/contentparts/ /// </summary> [PartDefinition] [WithEditableTemplateSelection(ContainerName = Defaults.Containers.Metadata)] public class ContentPart : PartModelBase { } }

Sample: Raw HTML part @model Dinamico.Models.ContentPart @{ Content.Define(a => { a.Title = "Raw HTML"; a.Image("/N2/Resources/Icons/Html.png"); a.Text("HTML").Configure(txt => { txt.Columns = 60; txt.Rows = 10; txt.TextMode = System.Web.UI.WebControls.TextBoxMode.MultiLine; }); }); } @if (Content.Has.HTML) { <div>@Html.Raw(Content.Data.HTML)</div> }

WebForms Part Tutorial


This tutorial assumes you have added the Visual Studio item templates. How to do this is documented in Setting Up Your Environment. Right-click on the project, Add, New item , select N2 Item Template and Add.

Use the n2propfta template to add a free text area snippet. Give the property the name Text. 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>

Compile and Voila! select Organize parts and drag TutorialPartItem into a zone to see it in action.

Editors
Built-in Editor Types
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 items 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; } }

Creating Custom Editors


The included editable attributes are build using the same system you can use to build your own. 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(); } } }

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; }

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; }

Lets use the editable on some properties:

public class HomePage : PageBase { [EditablePageDropDown] public virtual ContentItem AboutPage { get; set; } [EditablePageDropDown] public virtual ContentItem CookiePage { get; set; } }

Compile, refresh, and there they are.

Organizing Editors with Containers


When adding [Editable] attributes on content classes you are defining what the editor interface will look like. Its 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 its sortOrder property is greater (10 > 0). This is the previously defined editor interface:

Nesting Containers
Its 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:

Built-in Containers
These are the built-in containers: [ExpandableContainer] [FieldSetContainer] [Separator] [TabContainer] To build your own extend from N2.Definitions.EditorContainerAttribute.

Inheritance Constraints
Its 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; } }

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 { }

Restricting Parents and Children


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 { }

Zone Restrictions
By default all parts are allowed in any zone. Its 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 { }

Polymorphic Restrictions
Base classes can use and be referenced for restrictions.

[N2.PageDefinition] [ItemAuthorizedRoles(new string[0])] // allow no one public class HomePage : PageBase { }

Interfaces can also 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.

Enforced Sorting
To sort the children of a certain page the [SortChildren] attribute is used:

[PageDefinition("News Container")] [SortChildren(SortBy.PublishedDescending)] public class NewsContainer : ContentPageBase { }

Custom sort expression can be used to sort on other details:

[PageDefinition("Calendar")] [SortChildren(SortBy.Expression, SortExpression = "EventDate")] public class Calendar : ContentPageBase { }

Children are sorted whenever one child is saved. When applying the attribute to already saved content one page must be published again in order for changes to take effect.

Links and Relations 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 isnt 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; }

Caching
URL to Item Mapping Cache
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>

Database Entity Cache


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>

NHibernate Caching
TODO

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: Filter Type AccessFilter CompositeFilter Description removes items not authorized by the user is composed of other filters, removes items not authorized by all of these is composed of a page, visible, published and access filter skip and takes a number of items, needs to be reset after each use encapsulates an action that does the filtering removes duplicates, needs to be reset after each use contains another filter which behavior is inversed doesn't filter allows only pages (not parts) removes anything not structured below a parent

NavigationFilter CountFilter DelegateFilter DuplicateFilter InverseFilter NullFilter PageFilter ParentFilter

PublishedFilter TypeFilter VisibleFilter ZoneFilter

removes unpublished and expired items removes items not deriving from a certain type removes non-visible items removes items not in a given zone

Examples
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, its 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(); }

Extending the Administration System with UI Plugins


The UI plug-in system in N2 CMS allows developers to add modular functionality to the N2 backend administrative system simply through decorating types that they create with attributes. These types can then be identified and instantiated by the framework as needed. Some examples of plug-ins are shown below.

Toolbar Plugins
To register an interface into the management UI you add an attribute to your page, e.g.:

[ToolbarPlugin("EDIT", "edit", "{ManagementUrl}/Content/Edit.aspx?{Selection.SelectedQueryKey}={selected}", ToolbarArea.Preview, Targets.Preview, "{ManagementUrl}/Resources/icons/page_edit.png", 50, ToolTip = "edit", GlobalResourceClassName = "Toolbar", RequiredPermission = Permission.Write)]

IPlugin
UI Plug-ins are classes that are decorated by an attribute that implements the N2.Plugin.IPlugin interface. This interface provides a Name and a SortOrder for the plug-in. It identifies the Type that is being Decorated by the attribute and it provides a method for checking if a User IsAuthorized to use this plug-in. The classes for the UI plug-in system are held in N2 assembly under the N2.Plugin namespace.

Finding UI Plug-ins
There is a service identified by the IPluginFinder interface that returns a list of all the UI plug-ins in the system that have been found. The default implementation of this service is the N2.Plugin.PluginFinder class. UI Plug-ins can be excluded from being found by adding elements to the interfacePlugins element in web.config: N2 framework services can find and use UI plug-ins by calling into the IPluginFinder. For example in the Control Panel there is this method.

protected virtual void AddPluginsControlPanelState(state) { var pluginPanel = new Panel(); pluginPanel.CssClass = "plugins"; Controls.AddPluginPanel(); ContentItem start = Engine.Resolve<IUrlParser>().StartPage; ContentItem root = Engine.Persister.Repository.LoadEngine.Resolve<IHost>(.CurrentSite.RootItemID); foreach (IControlPanelPlugin plugin in Engine.Resolve<IPluginFinder>(.GetPlugins<IControlPanelPlugin>)) { var span = new HtmlGenericControl("span"; span.Attributes"class" = "control"; pluginPanel.Controls.Addspan; plugin.AddTo(span, new PluginContext(CurrentItem, null, start, root, state, Engine.ManagementPaths)); } }

This code has not been checked, would someone please review it and update this article? Thanks!

Here, the IPluginFinder is used to get all the control panel UI plug-ins, decorated by attributes deriving from IControlPanelPlugin. Each are then added to the pluginPanel control.

Backend Administration Plug-ins


The primary role of the UI Plug-in system is to add to the N2 CMS backend administration functionality. These UI plug-ins are identified by being decorated with attributes that derive from the AdministrativePluginAttribute. UI Plug-ins are automatically added to the Control Panel, Navigation Pane and Toolbars. The attributes specify where the button or link will appear, both in terms of the toolbar area, for instance, and the sort order. Also they specify in what state the current page should be for this item to appear. For instance, Control Panel plugins can choose to be displayed during the states specified in the N2.Web.UI.WebControls.ControlPanelState enum: Unknown Hidden - The control panel is hidden, e.g. the user is not an editor Visible - The control panel is visible displaying a page normally. Editing - The control panel is displayed while editing the page in place. DragDrop - The control panel is displayed during drag and drop of parts. Previewing - The control panel is displayed while previewing an item version.

Control Panel
Pages that are decorated with attributes that implement the IControlPanelPlugin interface are added to the control panel. There are three of these attributes built in to N2 CMS: ControlPanelLinkAttribute, Control PanelDrapPluginAttribute and ControlPanelSeparatorAttribute. ControlPanelLinkAttribute adds a link to the control panel. ControlPanelSeparatorAttribute adds a separator to the control panel. ControlPanelDragPluginAttribute adds a link to the control panel that is shown only if there is a zone on the page being viewed.

Toolbar
The ToolbarPluginAttribute is used to decorate toolbar buttons that should appear in the toolbars of the administration area. The attribute defines things like the URL to which the button should link, a URL to an icon for the button, the frame and toolbar area in which the button should appear.

Navigation Pane
Pages that are decorated with attributes that derive from NavigationPluginAttribute are added to the right click context menu on the navigation

page. There are two built-in attributes in N2 CMS: The NavigationLinkPluginAttribute adds a link to the decorated page in the context menu and NavigationSeparatorPluginAttribute adds a separator in the context menu.

Edit Toolbar
Pages that are decorated with the EditToolbarPluginAttribute appear in a toolbar on the Edit page of the administration

Other Plug-ins
In this section a selection of other plug-ins are described.

Scheduling
N2 has a scheduling service that executes work items on a scheduled basis. This functionality can be found in the N2.Plugin.Scheduling namespace of the N2 assembly. Types that derive from ScheduledAction and decorated with the ScheduleExecutionAttribute are plug-ins that the Scheduler can find and execute. The scheduler uses a service called Heart that provides a regular beat event. When the beat event is triggered the Scheduler checks to see if any ScheduledAction plug-ins are due to be executed by interrogating their Interval, LastExecuted and Repeat properties.

N2.Templates Wiki Add-on


The Wiki add-on to the N2.Templates project, which can be found in the N2.Addons.Wiki namespace of the Wiki assembly, uses UI plug-ins to provide user controls that may be used in the text of a wiki article. These user controls must derive from WikiTemplate and be decorated with attributes that implement the IWikiTemplateRenderer interface. There are two built in attributes: WikiTemplateAttribute or the DefaultWikiTemplateAttribute, which just assumes that the template files are found in the folder '~/Wiki/UI/WikiTemplates'. The wiki add-on uses built-in renderers, found in the N2.Addons.Wiki.Renderers namespace, to convert the wiki text into HTML. In this case there is a TemplateRenderer that lookups up the template renderer plug-in user control based. It is instantiated with this code: Renderers"Template" = new TemplateRenderer(pluginFinder.GetPlugins<ITemplateRenderer>()); As an example, if a wiki article contained "LatestArticles". That text will be converted into an instance of the LatestArticles.ascx user control.

Services
Inversion of Control
In software engineering, inversion of control (IoC) is a programming technique, expressed here in terms of object-oriented programming, in which object coupling is bound at run timeby an assembler object and is typically not known at compile time usi ng static analysis. N2 performs inversion of control to allow developers to abstractly extend the framework with their own implementations. Custom implementations can replace and extend those provided by the framework in a plugin-like fashion.

Services
Services are the basic extension points of the N2 framework. They are singletons instantiated at application start-up.

[Service] public class SeoDefinitionAppender : IAutoStart { // ...

Service Activation via Configuration


You can set up a service so that it is activated when certain configuration criteria are met.

[Service] [Service(typeof(IContentItemRepository), Configuration = "xml")] [Service(typeof(IRepository<ContentItem>), Configuration = "xml", Replaces = typeof(ContentItemRepository))] class HtmlContentRepository : IContentItemRepository {

Service Constructors
N2CMS will automatically resolve constructor parameters and pass in instances of the relevant items. If you're modifying built-in N2 classes, take care not to create dependency cycles here or you'll end up with stack overflow as N2 recursively tries to instantiate these dependencies for you.

Troubleshooting and Debugging


If you're having trouble getting Services to load, there might be a dependency issue. You'll get more useful exceptions for troubleshooting if you add a reference to the Windsor package. Windsor Installation Method Nuget package Instructions 1. Warning: Don't use the nuget package within the N2.Everything solution. Use one of the following two alternative options. 2. Install the N2CMS Windsor Nuget package as follows:

Install-Package N2CMS.IoC.Windsor3

Project reference (N2.Everything.sln)

1. Add a project reference to N2.IoC.Windsor3 2. Modify the <engine> tag in web.config file as follows:

<engine containerType="N2.Engine.Castle.Winds orServiceContainer, N2.IoC.Windsor3">

Manual

1. Copy the following DLL files to your project ~/bin directory: N2.IoC.Windsor3.dll N2.IoC.Windsor3.pdb 2. Modify the web.config as in the Project Reference section above.

Extending web.config Permissions and Roles, Programmatically


You can use the regular ASP.NET membership functions to create and manage users. Look inside N2.Edit.Membership.Edit and you will find that it is as simple as: To do this... Add a user to a role Remove a user from a role Use this code... Roles.AddUserToRole(SelectedUserName, item.Value);

Roles.RemoveUserFromRole(SelectedUserName, item.Value);

Save changes to a user

System.Web.Security.Membership.UpdateUser(SelectedU ser);

Create a new user Delete a user

How does it work?


If you look in web.config you will see that everything membership-related is actually driven by N2.Security.ContentMembershipProvider by default.

<providers> <add passwordFormat="Hashed" name="ContentMembershipProvider" type="N2.Security.ContentMembershipProvider, N2.Management" /> </providers>

This in turn uses something called ItemBridge to persist the standard .NET Membership objects as regular ContentItems.

See Also
Managing users and permissions

Additional Resources
File ckeditor_placeholder_4.1.zip SqlFileStorage.zip N2EditablePropertyGrid.zip N2CMS_TheLittleHandbook.pdf Modified

Apr 15, 2013 by

Apr 15, 2013 by

Apr 15, 2013 by

Apr 15, 2013 by

Drag and drop to upload or

browse for files

Download All

Getting Support
Free Community Support
Free community support is provided for issues with N2CMS, and for feature requests on a best-effort basis with no SLA. All community solutions are licensed under the LGPL unless otherwise specified. For bugs and feature requests, please file an issue at Github and a member of the community will eventually try to address a fix. The bug tracker is located at https://github.com/n2cms/n2cms/issues If you are trying to extend N2CMS with the intention of contributing your code back to the N2CMS project, please provide the source code of your

project and we can try to help you debug it. The code must be licensed under LGPL or a compatible license. The solution will be made available to the community, and may be incorporated into the main N2CMS distribution or template libraries in whole or in part.

Commercial Support
If you have a requirement for a project that isnt open-source, or if you need a solution more quickly, various N2 community members offer consulting services at market rates. Please contact those members directly for additional information.

Das könnte Ihnen auch gefallen