Wednesday 8 February 2012

How to change the sort order in the editor tree

One of the questions I've been asked by a couple of clients now is whether there is a way to sort the items that appear in the editor tree.

I've recently been asked about one of the sites which is used to advertise cars. In the CMS there is a page called "a list of cars for sale" and underneath that we create "a car for sale". Rather than creating each new car at the bottom of the list, they want to be able to group the cars around registration date. The reason for this is to make it much easier to maintain. If you have 50 cars in a list, it's not easy to manage.

Forgive me that I'm not able to post the actual full code, but I'll do my best to point you in the right direction. It turns out the solution is quite simple. In the "a list of cars for sale" page, you can override the Children property like so:


        public override System.Collections.Generic.IList<ContentItem> Children
        {
            get
            {
                // for each of your children, cast it to a CarForSalePage and sort them with LINQ
                // then return the list cast back to a list of content items
            }
        }

Using this method you really have a powerful tool at your disposal for cutomising the editor. If.. (if!) I ever get time I'd like to fork the code and look at being able to customise this in the admin tool.

Hope this helps!

Wednesday 13 July 2011

How to make the N2 CMS free text area a bit more "WYSIWYG"

One of my clients recently noted that it would be much nicer if when he's editing the content of his website that the free text areas look like they do when he clicks on the "Save and publish" button. In other words, he wants the editor to be more "WYSIWYG" and show the real colours, fonts, font sizes etc when he's editing.

It's actually a simple fix to make. Open your web.config  and look in the <n2> tag for the <edit> tag. You just need to add one line in there and away you go. I've highlighted it below:


<edit>
        <!-- Set checkInstallationStatus to false to disable redirect to install page -->
        <installer checkInstallationStatus="true" />
        <writers dynamic="true"/>
        <editors dynamic="true"/>
        <administrators dynamic="true"/>
        <tinyMCE cssUrl="/Content/Css/N2Edit.css" enabled="true" />
</edit>

Now you just need to add the styles you like to the N2Edit.css file and you can customise the editor so that what you edit is what you see.

Saturday 29 January 2011

Importing data into N2

One of the projects I'm working on at the moment is for a local community website. The old site has a message forum and we want to migrate the content into N2 preserving as much of the data as we can.

It is quite easy to do with N2 in that you can create a class of any page, populate it and save it.

Here's an example from the code which imports the actual messages on the message board - it's not the best, but it works and demonstrates the principle.


                N2.Templates.Mvc.Models.Pages.MessagePage mp = new Models.Pages.MessagePage();
                mp.Created = reader.GetDateTime(reader.GetOrdinal("datePosted"));
                mp.Parent = parent;
                mp.Author = reader.GetString(reader.GetOrdinal("MessageAuthor"));
                mp.Text = reader.GetString(reader.GetOrdinal("MessageText"));

                mp.Title = string.Format("Reply by {0}-{1}", reader.GetString(reader.GetOrdinal("Username")), ForumHelper.GetDateAsNumbers(mp.Created));


                N2.Context.Persister.Save(mp);
                N2.Context.Persister.Save(parent);


There's a couple of things to note. The title must be unique in N2 so I have got around this by creating the title as normal, but adding the date of when it was created onto the end. You must also specify the parent page too and save it after you have created the message to create the relationship between them.

What I am impressed with is that I can take an existing message board and import all the forums, topics and messages and do so really easily with N2. I have also imported all the user account information, profiles etc as well and we're hoping to get the new site live within a month. I'll let you know how we go on!

Tuesday 18 January 2011

Exceptioneer - superb and a doddle to integrate into N2

One of the lads at work pointed me in the direction of Exceptioneer which quite honestly is fantastic.

Although Elmah which comes with N2 is simple to use and is very helpful in tracking bugs, if you get an exception on one of your N2 sites which is "buried down" under a load of code it's not easy to find. Exceptioneer gives you information on the current username, stack trace, where it was called from on the front end etc. There's simply so much information it collects for you that it would be hard to do a screenshot.

Another big bonus is that it also tracks your javascript errors! I can't recommend this enough and this will definitely be a part of all N2 work I do from now on... not that I write code with loads of exceptions in it of course! :)

Finally, if all that wasn't good enough... Exceptioneer has a free account which can log up to 2000 exceptions a month.

Not strictly N2, but a couple of fantastic tools

I'm currently working on a project of my own to convert an existing local community site into a full-on N2 site. The main part has involved migrating the message forum, news gathering service and other migration coding.

I'm wanting to post the news regularly to Twitter and, once it's up and running, Facebook. I've found this library as a superb, simple way to post to Twitter now they are using oAuth which is more complicated than their old authentication method. Check this out:

www.diplo.co.uk/blog/2010/8/9/oauth-with-twitter.aspx

Sunday 12 December 2010

N2CMS MVC and how to create a configurable MasterPage option

One of the most common questions on the N2CMS forums seems to be how to make it possible to be able to select a master page. In the past when I've worked on cms driven sites the templates have been relatively straightforward - the homepage has had a unique design whilst the others have had a set template. This was quite easy to do as I just created my own class which derived from the StartPage class and then created it's own HTML without using the main MasterPage. Simple, but effective.

However, recently I've been asked to convert an existing Sharepoint site to the MVC version of N2. This has been quite interesting to do and one of the areas I've had to work on is how to give the user the option of which master page template to use. I can't do this statically and because there are a number of templates on the current Sharepoint site it's possible that users may need to change page templates "on the fly".

I'm not going to go to deep in to the workings of this - it's probably easier to fire up N2 MVC and step through the code. I'm going to give you a step-by-step tutorial to get it working!

I'd like to thank the guys on this discussion on the N2CMS forum (n2cms.codeplex.com/discussions?size=2147483647) for providing the inspiration for this. I can't find the exact post however.

Step 1:
Make sure you download the latest v2.1rc MVC version of the site and make sure you copy the DLLs in the library folder into the bin folder of the N2CMS folder. If you don't do this with then you might get an error when you first try to start the site.

Step 2:


In the services folder, open the ThemedMasterViewEngine.cs file. In that there's a method which tries to determine which Master page to use based on theme or uses the  there's a class which checks to see what master page to use.



public class ThemedMasterViewEngine : WebFormViewEngine
{
        // You should change the "TwoColumnLayout.master" to be your default template
        string masterPageFile = "~/Views/Shared/TwoColumnLayout.master";

public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
if (!controllerContext.IsChildAction)
{
if (string.IsNullOrEmpty(masterName))
masterName = masterPageFile;

var root = Find.Closest<StartPage>(controllerContext.RouteData.CurrentPage()) ?? Find.ClosestStartPage;
if (root != null)
{
string theme = root.Theme;
if (!string.IsNullOrEmpty(theme))
{
string potentialMaster = string.Format("~/Views/Shared/{0}.master", theme);
if (base.FileExists(controllerContext, potentialMaster))
{
masterName = potentialMaster;
}
}
}
}

return base.FindView(controllerContext, viewName, masterName, useCache);
}
}

Step 3:

In the models/pages folder there's a ContentPageBase.cs class. We're going to change this to add an enum for the name of the page templates and add a property for any page which derives from the ContentPageBase (which is all of them) which allows you to select a template and puts it under the Advanced tab.

Open /Models/Pages/ContentPageBaseup and add this code:

        public enum PageTemplates
        {
            MyHomePage,
            TwoColumnLayout
        }

        [EditableEnum("Page layout", 60, typeof(PageTemplates), ContainerName = Tabs.Advanced)]
        public virtual PageTemplates PageLayout
        {
            get { return (PageTemplates)(GetDetail("PageLayout") ?? PageTemplates.TwoColumnLayout); }
            set
            {
                SetDetail("PageLayout", value, PageTemplates.TwoColumnLayout);
            }
        }

Step 4:

In the controllers folder, open up the TemplatesControllerBase.cs file. We're going to add some code in here which tries to get the name of the PageLayout from the page and sets the master page. Find the method below (be careful - there's a few overloads of it) and replace the method with this code:

protected override ViewResult View(string viewName, string masterName, object model)
{
CheckForPageRender(model);

            model = model ?? CurrentItem;
            if (model != null)
            {
                var item = model as N2.Templates.Mvc.Models.Pages.ContentPageBase;
                if (!string.IsNullOrEmpty(item.PageLayout.ToString()))
                {
                    masterName = item.PageLayout.ToString();
                }
            }

return base.View(viewName, masterName, model ?? CurrentItem);
}

Step 5:

I think this might be an oversight in the n2 release, but I've found I have to add this line into the web.config in the n2 editing folder:

<httpRuntime requestValidationMode="2.0" />

Otherwise I get an error when I try to change the page layout.

Step 6:

If you start up your site, and select "Edit" on any page you will find that under the "Advanced" tab you have a drop down list of layouts. If you change this you will be able to change the master page used on the site!

Friday 3 December 2010

New version of N2CMS released

I don't know if you've seen on http://n2cms.codeplex.com/releases but v2.1rc has been released. I'd strongly recommend anyone to sign up for the release notifications on Codeplex for the code as this way you will get the latest versions as soon as they come out. On the page for the releases if you look on the right you'll see the button to set notification settings.

As you know, I've been doing tutorials for the web forms version of N2. If you read my earlier posts you'll have read that for beginners I'd recommended the web forms version to get started with because of the better templates that came with it - it was simply easier/quicker to create pages and items. This looks like it has changed with the new release and I am currently investigating the new changes so that I'll be able to comment on the web forms vs MVC projects.

Another reason to download the new version is that it now ships with documentation! Now, I've read the documentation and it's still not perfect nor complete but it's far better than the array of wikis, pages and dead pages that are on the web. So, if nothing else you have a much better starting point for v2.1 than you did with the earlier versions.

All that said, I still aim to continue writing on this blog. There's some new features in the new version which look very interesting such as templates. This will allow you to create templates of pages and subpages with pre-populated content. Very useful.

I think however, my focus will broaden somewhat to include my experiences of the N2 MVC. I also am intrigued by how we can extend the editor with jQuery and similar technologies.

For now though, have a look at the new version!