So you've downloaded MonoX, played with it a bit, changed a few images and portions of CSS, even changed the layout on some pages and set a bunch of Web part properties. Now you want to take it one step further and use it as a foundation for your custom projects. Building a custom project from scratch is a simple task that can be done in just a few steps. Typically most of the custom projects consist of building a custom layout, template, adding pages and Web parts. The actual scope and complexity of the target application will define how these custom things are implemented.
This tutorial is intended for ASP.NET developers. It describes the process of creating a custom MonoX based project from scratch in MonoX 4.0.
Before you start building custom project we advise you to read the following articles and familiarize yourself with the terms and concepts that will be used in this tutorial:
We will divide this tutorial in the following sections:
- Unzip MonoX package and create a website in IIS
- Install MonoX CMS
How to: Install MonoX on Windows Server 2003
How to install MonoX on Windows Server 2008
How to perform MonoX installation
- Create a folder structure that you will need
- Change the configuration files
- Create a Master page layout
- Create a MonoX theme and template
- Create a Page and add Web parts (modules)
Unzipping the MonoX package and creating a website in IIS
Perform this process only if you didn't install MonoX via WebPI
First thing that we need to do is download the latest version of MonoX CMS that can be found on the Url provided above. When we have MonoX downloaded then we should create a website in IIS and install the MonoX as described in the articles mentioned above.
Creating a folder structure
In this step we will just suggest what we consider to be a good practice. It is totally up to you what folder structure will be used in your projects. Here is our basic folder structure:
MyProjectName
Code
BaseClasses
Classes
Layers
BusinessLayer
Repositories
LocalResources
Controls
MasterPages
Pages
Upload
Documents
Flash
Images
Media
WebParts
App_Themes
MyProjectName
App_Templates
MyProjectName
Here is a small overview of the folders above:
- Code - Is basically used to store all of your custom classes.
- BaseClasses - contains all classes that derive from MonoX classes: these include BaseUserControl, BaseAutoRegisterPart, BasePage, BaseMasterPage, ... (find out more about these classes here).It is a good practice to inherit these classes form MonoX base classes so you can take advantage of this layer later on in the development process.
- Classes - a place to store all of your utility classes.
- Layers BLL and Repository - business layer and data access layer classes go here.
- LocalResources - If your project requires globalization / localization then we practice to store resource files here
- Controls, MasterPages and Pages - a good place to store all your UserControls, Master page and Page files.
- Upload - folder used by the MonoX CMS for all built-in upload processes (e.g. HTML Editor document uploads, Multi file uploads etc.) It is a good practice to have this folder here so it will not be deleted during the MonoX upgrade process.
To have your own styling and to benefit from MonoX templating system copy the
/App_Themes/Default theme to
/App_Themes/MyProjectName and
/App_Templates/Default to
/App_Templates/MyProjectName. You can now reference
MyProjectName (of course, you will want to use more meaningful name in your real projects) as your new theme name in all pages and controls.
Changing the configuration files
After we have created a project folder structure, we need to change the configuration files. The majority of users will want to use Visual Studio IDE in their everyday work, so we can proceed by copying the
/MonoX/Samples/Solution/ProjectName.sln and
/MonoX/Samples/Solution/Portal.csproj to the Web site root folder. Rename ProjectName.sln to MyProjectName.sln and open it in Visual Studio. You can subsequently change the configuration settings - MonoX will work with the default settings, but it is good to know their exact purpose. Also note that any file editor (besides Visual Studio) can be used to make these changes.
If you didn't perform the MonoX installation or your database connection string is not properly set for any other reason, find the following code in the
web.config and modify it by entering your username, password, database server and instance names,
<
add
name
=
"LocalSqlServer"
connectionString
=
"Data Source=;uid=;pwd=;database=;Connect Timeout=90;"
providerName
=
"System.Data.SqlClient"
/>
Change the main upload folder configuration
<
add
key
=
"MonoXUploadPath"
value
=
"/Upload"
/>
<
add
key
=
"MonoXUploadPath"
value
=
"/MyProjectName/Upload"
/>
Change the e-mail "from" address
<
add
key
=
"MailFromAddress"
value
=
"monox@mono-software.com"
/>
<
add
key
=
"MailFromAddress"
value
=
"support@myprojectname.com"
/>
Change the application title
<
add
key
=
"ApplicationTitle"
value
=
"MonoX"
/>
<
add
key
=
"ApplicationTitle"
value
=
"MyProjectName"
/>
Change the smtp network settings used by MonoX to send e-mails.
If you notice a long delay when posting a message to the discussion board, adding a friend or sending a message via MonoX messaging page, chances are that your this setting is not configured correctly, and the SMTP connection is timing out.
<
network
host
=
"mail.yourdomain.com"
/>
Creating Master page layouts
Our next step is to create a layout that will be used for all pages by creating a set of ASP.NET master pages. MonoX provides you with a basic master page that should be inherited to harness all of the CMS features:
/MonoX/MasterPages/MonoX.master. After we have visually inherited the MonoX.master we can build our layout by entering some HTML, ContentPlaceHolders and PortalWebPartZone to our custom master page. Here are a few samples of a custom layout:
<%@ Master
Language="C#"
MasterPageFile="/MonoX/MasterPages/MonoX.master"
AutoEventWireup="true"
CodeBehind="Default.master.cs"
Inherits="MyProjectName.Web.MasterPages.Default"
EnableTheming="true" %>
<%@ Register TagPrefix="ctl" TagName="Header" Src="/MyProjectName/Controls/Header.ascx" %>
<%@ Register TagPrefix="ctl" TagName="Navigation" Src="/MyProjectName/Controls/Navigation.ascx" %>
<%@ Register TagPrefix="ctl" TagName="Footer" Src="/MyProjectName/Controls/Footer.ascx" %>
<
asp:Content
ID
=
"cp"
ContentPlaceHolderID
=
"cp"
runat
=
"Server"
>
<
asp:ScriptManagerProxy
ID
=
"scriptManagerProxy"
runat
=
"server"
></
asp:ScriptManagerProxy
>
<
ctl:Header
runat
=
"server"
ID
=
"ctlHeader"
/>
<
table
width
=
"950"
border
=
"0"
align
=
"center"
cellpadding
=
"0"
cellspacing
=
"0"
>
<
tr
>
<
td
width
=
"85"
align
=
"left"
valign
=
"top"
>
<
ctl:Navigation
runat
=
"server"
ID
=
"ctlNavigation"
/>
</
td
>
<
td
width
=
"40"
align
=
"left"
valign
=
"top"
>
<
asp:ContentPlaceHolder
ID
=
"cp"
runat
=
"server"
>
</
asp:ContentPlaceHolder
>
</
td
>
</
tr
>
</
table
>
<
ctl:Footer
runat
=
"server"
ID
=
"ctlFooter"
/>
</
asp:Content
>
Sample 1
<%@ Master
Language="C#"
MasterPageFile="/MonoX/MasterPages/MonoX.master"
AutoEventWireup="true"
CodeBehind="Default.master.cs"
Inherits="MyProjectName.Web.MasterPages.Default"
EnableTheming="true" %>
<%@ Register TagPrefix="ctl" TagName="Header" Src="/MyProjectName/Controls/Header.ascx" %>
<%@ Register TagPrefix="ctl" TagName="Navigation" Src="/MyProjectName/Controls/Navigation.ascx" %>
<%@ Register TagPrefix="ctl" TagName="Footer" Src="/MyProjectName/Controls/Footer.ascx" %>
<%@ Register Assembly="MonoX" Namespace="MonoSoftware.MonoX" TagPrefix="portal" %>
<%@ Register Assembly="MonoSoftware.Web" Namespace="MonoSoftware.MonoX.Controls" TagPrefix="mono" %>
<
asp:Content
ID
=
"cp"
ContentPlaceHolderID
=
"cp"
runat
=
"Server"
>
<
asp:ScriptManagerProxy
ID
=
"scriptManagerProxy"
runat
=
"server"
></
asp:ScriptManagerProxy
>
<
ctl:Header
runat
=
"server"
ID
=
"ctlHeader"
/>
<
table
width
=
"950"
border
=
"0"
align
=
"center"
cellpadding
=
"0"
cellspacing
=
"0"
>
<
tr
>
<
td
width
=
"85"
align
=
"left"
valign
=
"top"
>
<
ctl:Navigation
runat
=
"server"
ID
=
"ctlNavigation"
/>
</
td
>
<
td
width
=
"40"
align
=
"left"
valign
=
"top"
>
<
mono:PortalWebPartZone
HeaderText
=
"BlankHeaderZone"
ID
=
"blankHeaderWebPartZone"
runat
=
"server"
Width
=
"100%"
ChromeTemplateFile
=
"LeftColumn.htm"
ShowChromeForNonAdmins
=
"false"
>
<
ZoneTemplate
>
<
asp:ContentPlaceHolder
ID
=
"cp"
runat
=
"server"
>
</
asp:ContentPlaceHolder
>
</
ZoneTemplate
>
</
mono:PortalWebPartZone
>
</
td
>
</
tr
>
</
table
>
<
ctl:Footer
runat
=
"server"
ID
=
"ctlFooter"
/>
</
asp:Content
>
Sample 2
Of course, you will need to create your own header, footer and related controls if you need full customization. These are usually simple ASP.NET user controls. MonoX demo header and footer controls can be used if you just want to change the color scheme, layout and other style elements.
You can read more about the ASP.NET master pages
here, and don't forget to lookup the PortalWebPartZone in the
MonoX API documentation.
Creating MonoX themes and templates
I have already mentioned that we need to copy the
/App_Themes/Default theme to
/App_Themes/MyProjectName theme and
/App_Templates/Default to
/App_Templates/MyProjectName, because these folders would be used for theming (skinning) of all pages and controls. There are two approaches that you can take while creating your custom theme:
- Create a new theme from scratch
- Modify an existing MonoX demo theme
Create a new theme from scratch
Creating a new theme from scratch is a cleaner but more complex approach, so I'll just sketch a basic workflow for creating a new theme. We will soon publish a dedicated article on this topic.
- Design the layout and styling in Photoshop or similar tool
- Export the layout, styling (HTML, CSS) to the above mentioned theme and template folders
- Follow the existing MonoX CSS classes and HTML structure while styling master pages, pages and Web parts
Modify existing MonoX demo theme
Modifying the existing MonoX demo theme is simple way of restyling the portal theme in a custom project. First thing that you need to do is to embed your custom CSS to support custom master page layouts (header and footer included). Most real-world projects will not need all standard MonoX Web parts, so you can remove all "surplus" CSS classes and images and have a clean and optimized CSS file. Now you can restyle the CSS sections that you need.
/**** Photo Gallery - START ****/
.photos
{
font-family
: Trebuchet MS,
Arial
,
Helvetica
,
sans-serif
;
font-size
:
13px
;
color
:
#666
;
}
.photos A:link,
.photos A:active,
.photos A:visited
{
color
:
#dc613f
;
text-decoration
:
none
;
}
.photos A:hover
{
text-decoration
:
underline
;
}
...
/**** Photo Gallery - END ****/
As you can see, all functional sections have
START and
END tags inside the CSS file so you can easily navigate it and change all of its visual aspects.
The physical layout of a Web part is defined in Web part templates. For example, if you want to modify the photo album templates, you will need to change its template in
/App_Templates/MyProjectName/SocialNetworkingTemplates/AlbumList.htm. Template files look similar to this:
<
td
>
<
div
class
=
"album-list"
>
<# AlbumCover #>
<
table
cellpadding
=
"0"
cellspacing
=
"0"
>
<
tr
>
<
td
>
<!--<# AlbumName #>-->
<!--<# ViewButton #>-->
<
span
class
=
"album-title"
><# AlbumNameViewButton #></
span
> <
div
class
=
"author"
><
a
href="<# AuthorUrl #>" title="<# AuthorToolTip #>"><# AuthorText #></
a
></
div
>
</
td
>
</
tr
>
<
tr
>
<
td
class
=
"photo-count"
><# PhotoCount #></
td
>
</
tr
>
<
tr
>
<
td
class
=
"descr"
><# AlbumDescription #></
td
>
</
tr
>
<
tr
>
<
td
class
=
"album-links"
>
<
div
><# Rating #></
div
>
<
span
><# EditButton #></
span
>
<
span
><# DeleteButton #></
span
>
</
td
>
</
tr
>
</
table
>
</
div
>
</
td
>
Template files contains standard HTML and a set of predefined tags that are replaced with actual content at runtime. MonoX templating system also supports
NVelocity template engine syntax.
You can read more about the ASP.NET Themes
here, also you can take a look at the Web part templating sample
here.
Creating portal pages and adding some Web parts
Now it is time to use our restyled modules inside the layout we have created in previous steps. We will do so by creating a page that inherits from our BasePage class and visually inherits from the custom Master page. Our empty page should look similar to this:
<%@ Page Language="C#"
AutoEventWireup="true"
MasterPageFile="/MyProjectName/MasterPages/MyProjectName.Master"
Theme="MyProjectName"
Inherits="MyProjectName.Web.Default"
Title="MyProjectName Home"
CodeBehind="Default.aspx.cs" %>
<%@ MasterType TypeName="MonoSoftware.MonoX.BaseMasterPage" %>
<%@ Register TagPrefix="MonoX" TagName="Editor" Src="/MonoX/ModuleGallery/HtmlEditor.ascx" %>
<%@ Register Assembly="MonoX" Namespace="MonoSoftware.MonoX" TagPrefix="portal" %>
<
asp:Content
ContentPlaceHolderID
=
"cp1"
runat
=
"server"
>
<
MonoX:Editor
runat
=
"server"
ID
=
"editor"
Title
=
""
>
<
DefaultContent
>
<
div
>
<
ul
>
<
li
>
Line 1
</
li
>
<
hr
style
=
"margin-right: 30px;"
/>
<
li
>
Line 2
</
li
>
<
hr
style
=
"margin-right: 30px;"
/>
</
ul
>
</
div
>
</
DefaultContent
>
</
MonoX:Editor
>
</
asp:Content
>
It may be a good idea to use WebPartZones as containers for Web parts, as every part that is contained in it (in this case it is a MonoX HTML editor) will expose all of its settings via the administrative toolbar and allow administrators to perform interactive personalization. It is not obligatory and it is not used in this simple example, but you will see this approach in action in a majority of demo MonoX pages.
Let's take a look at the code-behind of our Default.aspx page:
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Web;
using
MonoSoftware.MonoX.Utilities;
using
System.Web.UI.WebControls;
using
MonoSoftware.Web;
using
MonoSoftware.MonoX;
using
MonoSoftware.Web.Controls;
using
System.Text;
namespace
MyProjectName.Web.Pages
{
public
partial
class
Default : MyProjectName.Web.BasePage
{
protected
void
Page_Load(
object
sender, EventArgs e)
{
}
}
}
Not much to see here - our code-behind class is empty, but we wanted to show that is it a good practice to inherit from the
MyProjectName.Web.BasePage which in turn inherits from the MonoX
BasePage.
Here are some useful links related to this topic:
How to add a MonoX page
How to edit MonoX page content
Conclusion
This article contains a few useful techniques to perform customizations and build applications on top of MonoX. Of course, you are always free to choose your own approach, as there are plenty extensions points built into our CMS. Please look at some projects based on MonoX to see what's possible and get a bit of inspiration:
Simple blog engine:
http://www.my-heat-pump.com
Combination of a blog, localization and CMS features:
http://www.torjanac.com
Group discount engine powering a network of localized sites:
http://www.promozebra.com
Localized eGovernment portal:
http://www.inspektorat.hr
Network of job boards:
http://www.cpl.ie
Social networking recruitment portal:
http://www.jobsmarket.ie
Medical scheduling application:
http://v2.anesthesiascheduler.com
Bank loan processing application:
http://app.sbaopen.com
... and many more.
The following resources will explain Web part (module) customization in more detail:
Building a custom Web part
How to: Create a custom pager template
How to: Extend MonoX and ASP.NET Profile