Professional Documents
Culture Documents
All rights reserved. No parts of this work may be reproduced in any form or by any means - graphic, electronic, or
mechanical, including photocopying, recording, taping, or information storage and retrieval systems - without the
written permission of the publisher.
Products that are referred to in this document may be either trademarks and/or registered trademarks of the
respective owners. The publisher and the author make no claim to these trademarks.
While every precaution has been taken in the preparation of this document, the publisher and the author assume no
responsibility for errors or omissions, or for damages resulting from the use of information contained in this document
or from the use of programs and source code that may accompany it. In no event shall the publisher and the author be
liable for any loss of profit or any other commercial damage caused or alleged to have been caused directly or
indirectly by this document.
Contents 3
Table of Contents
Foreword 0
Part I Introduction 7
1 Welcome ................................................................................................................................... 7
2 Web parts ................................................................................................................................... 8
3 Social networking
................................................................................................................................... 9
Part II Installation 11
1 Installation requirements
................................................................................................................................... 11
2 Using the setup
...................................................................................................................................
package 11
3 Installation wizard
................................................................................................................................... 12
4 Configuration
...................................................................................................................................
settings 14
Web.config settings
.......................................................................................................................................................... 15
URL rewriting
......................................................................................................................................................... 15
Page optimization
......................................................................................................................................................... 18
Important.........................................................................................................................................................
MonoX configuration settings 19
Provider models
.......................................................................................................................................................... 23
5 Licensing ................................................................................................................................... 26
3
Contents 4
7 Ad management
................................................................................................................................... 59
8 Poll management
................................................................................................................................... 61
9 List management
................................................................................................................................... 63
10 Newsletter management
................................................................................................................................... 64
11 Blog management
................................................................................................................................... 65
12 Custom administration
...................................................................................................................................
modules 67
2 Creating custom
...................................................................................................................................
master and template pages 122
Index 172
5
Part
I
Introduction
Introduction 7
1 Introduction
This is a user manual for MonoX, a next generation portal development and social networking
framework for building advanced Web portals and applications. MonoX provides tools for quick and
intuitive construction of dynamic and fully editable portals and Web applications.
What You See Is What You Get (WYSIWYG) environment provided by MonoX engine allows users to
author advanced portals without coding. The first part of this manual is dedicated to explaining core
administrative concepts for all end user groups (administrators, designers, power users). The second
part - Portal development - describes advanced development tasks for users aiming to develop fully
customized solutions.
Important: the tilde character (~) that frequently appears in URLs in this manual is used in its usual
ASP.NET context and meaning: it is actually a shortcut notation for the HttpRuntime.
AppDomainAppVirtualPath property, which, according to the .NET documentation, "returns the
virtual path of the directory that contains the application hosted in the current application domain." If
your copy of MonoX is installed in http://localhost/MonoX, and the manual references the URL "~/
MonoX/SomePage.aspx", the page will be located at http://localhost/MonoX/MonoX/SomePage.aspx.
Additionally, screenshots in this manual were taken on various projects, skins and versions of the
package. Most of the screenshots are using the OldBlue MonoX skin. The functionality of the Web
parts is always the same, regardless of the front-end skin and template that is used on a particular
project.
1.1 Welcome
MonoX portal framework for ASP.NET allows you to create powerful Web applications and dynamic
Web portals with minimal effort.
standard Windows explorer, etc. It fully supports offline editing tools based on MetaWeblog API
(Microsoft Windows LiveWriter).
The main idea of ASP.NET 2.0 Web Part Framework is to let end users create and configure Web
pages by dragging in functional blocks (called Web Parts) and setting properties on these blocks. This
configuration happens right inside the Web page, using nothing but a standard Web browser. To
change a page in the site, you browse to this page, switch to edit mode and change it. Non-technical
users can change the layout of their page by dragging and dropping the web parts to different zones
on the page. Each of the parts exposes a configuration user interface to change its behavior and
appearance.
Combining the Web part paradigm with personalization opens up a whole new world of possibilities.
With the personalization framework inside ASP.NET 2.0, the settings applied on the parts on a page
can be different per user. You can allow any user to make changes to the page and these changes will
be visible to that user alone. This does not require writing support code - developers can concentrate
on programming the parts and decide which properties the user will want to configure. The Web Part
framework of MonoX does all the heavy lifting of serializing, storing, and retrieving the data associated
with site customization and member personalization.
History
ASP.NET 2.0 is not the first Microsoft product featuring Web Parts technology. They were (and still
are) used in Microsoft SharePoint Portal Server (SPS) and Windows SharePoint Services (WSS).
Version 3 of WSS is built upon Web Part Infrastructure core, while remaining backward compatible
with the WSS2 style of web parts. This means that you can apply the skills learned using MonoX and
ASP.NET 2.0 to build parts for Windows SharePoint Services. Many enterprise level server
applications leverage WSS as their web platform (like MS Office SharePoint Server 2007, Team
Foundation Server, PerformancePoint). You can modify and extend these applications using your Web
part skills. The market for Web parts covers all types of Web applications. This means that more
developers will be able to use the concept of Web parts in their solutions and that the market for third
party Web parts is becoming commercially feasible.
Mono Software used a concept similar to Web parts in the first commercial release of MonoX portal
framework (published during 2004). It was based on a very popular IBuySpy portal application, and
introduced drag and drop and visual configuration features that are now accepted in the new Web part
framework. However, the initial version was not using the standard API, as it was not available at that
time.
This new version of MonoX fully supports all the features of ASP.NET 2.0 Web part framework. To the
best of our knowledge, it is the only commercially available product with this feature, as other portal
products use proprietary module architectures. In addition, MonoX fully support all other standard ASP.
NET 2.0 / 3.5 features, including personalization, master pages, themes and provider models, and
adds significant additional functionality described in this manual.
Definition
Web Parts are customizable plug and play components that empower information workers to create
personalized user interfaces by simply dragging and dropping them onto a Web page. Web parts allow
customization at both design time and at run time. In fact, Web Parts blur the distinction between
design time and run time.
From the point of view of a developer, a Web part is simply an ASP.NET server control. To create a
new Web Part, you create an ASP.NET custom control. However, unlike standard ASP.NET controls,
which developers add to Web form pages at design time, Web Parts are intended to be added to Web
Part Pages either by authors at design time, or by users at run time.
The Web Part Framework in MonoX is used by three categories of users:
· End users personalize a Web Part Page to simplify and focus on the information that is most
relevant to them. They do this by customizing Web part properties.
· Web Page Authors use Web Parts to build custom solutions based on the existing functionality.
· .NET developers extend MonoX by introducing new functionality or extending the existing parts.
In addition to its core content management features, MonoX is now a fully featured social networking
framework that allows you to build any kind of online community. It includes:
II
Installation
Installation 11
2 Installation
This section describes the prerequisites and the steps that are necessary to completely install the
MonoX portal framework.
Microsoft Windows 2003 Server or higher OR Microsoft XP Professional or higher, with IIS 6.0 or
higher
Microsoft .NET 3.5 or higher
Microsoft SQL Server 2005 or higher OR Microsoft SQL Express
All commonly used browsers are supported in the end-user mode: Internet Explorer 6.0 or higher;
Firefox 1.0 or higher; Opera 7.5 or higher; Safari 1.2 or higher.
Internet Explorer and Firefox are also fully supported in the administration mode. Web part drag-and-
drop operation is currently not supported on Firefox by Microsoft's Web part framework, but this does
not limit the design functionality since there are another means to move Web parts from one zone to
another.
unzip the installation package in a folder of your choice (for example, C:\InetPub\wwwroot\MonoX2).
create an empty database using the SQL Server Management Studio or similar management tool.
Use the Security/Logins section of the Object explorer pane in the Management Studio to create a
new login (or use the existing one) for the account that will be used by MonoX engine to access the
database. Both Windows authentication and SQL Server authentication can be used, as long as you
grant read, write and all ASP.NET-related privileges to this account using the User mapping section
of the Login properties screen.
use the Internet Information Services management utility (type inetmgr in the Start-Run box) to
create a new Web site or virtual folder for MonoX. If you are using a virtual folder, make sure that a
new application is created (Application Settings section in the Directory tab of the folder properties
screen).
NOTE: By default, when ASP.NET allows anonymous access, the application runs in the context of a
special local account (this is NOT a domain account). In Windows 2000 and Windows XP, ASP.NET
applications run under the account called ASPNET. In Windows Server 2003, the account is called
NETWORK SERVICE. These user accounts are created during the .NET Framework installation
process with a unique, strong password, and are granted only limited permissions.
MonoX installation wizard will try to set the write privileges on the folders that require it (/RssStorage, /
Logs, /Cache, PageTemplates folder). This process may fail due to your local security configuration;
please make sure that the ASP.NET machine account has full write access on these folders (right click
on a folder using Windows Explorer, Properties, Security).
You can now access MonoX by typing its URL (as configured in the last step) in the browser window.
This will initiate the installation wizard, guiding you through the rest of the installation process.
- portal database (as configured in the LocalSqlServer setting of the Web.config) is present and
accessible, but does not contain any of the required tables
- InstallationDone setting of the User.config file is set to false
The first screen of the installation wizard lists the installation requirements:
You can specify the MonoX database name in the fourth step. Note that you can install unlimited
number of portal instances on a single database by choosing the "Use an existing database" option
and selecting the "Install new application" checkbox. Portal installation files have to be manually copied
to the separate folder in this "multi-portal" scenario.
config will still hold all common settings, but project-specific settings should go to a separate file, which
is being pointed to by an entry in the web.config:
<appSettings file="Configuration\Local\appSettings.config">
Most projects will have at two pairs of such configuration files, one for the local development, and one
for the production environment. Additionally, you can move the connection strings to its dedicated
configuration file, as well as some other sections. Here is how the configuration folder looks in many of
our custom projects:
Main database connection string is specified in the following section (note that the exact connection
string may be different in your case):
<connectionStrings>
<remove name="LocalSqlServer"/>
<add name="LocalSqlServer" connectionString="Data
Source=local;Trusted_Connection=true;database=MonoX2;" providerName="
System.Data.SqlClient"/>
</connectionStrings>
URL rewriting is a well known Search Engine Optimization (SEO) technique. The basic premise is that
clean URLs containing highly relevant keywords and without query string parameters will place your
pages much higher in search engine rankings. MonoX URL rewriting engine is based on Seth Yates'
URLRewriter.NET, an open-source, light-weight, highly configurable URL rewriting component for
ASP.NET.
There are three sections related to URL rewriter in the Web.config file:
This section looks a little different in IIS 7 - you can hold settings for both versions in the same
web.config:
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<add type="MonoSoftware.UrlRewriter.RewriterHttpModule,
MonoSoftware.UrlRewriter" name="UrlRewriter" />
Rule section:
<rewriter>
<if url="^(.*)/language/(.*)/(.*).aspx(\?(.+))?$" rewrite="
$1/$3.aspx?language=$2&$5"/>
<if url="^(.*)/language/(.*)/(.*).aspx$" rewrite="
$1/$3.aspx?language=$2"/>
</rewriter>
This particular rule set is entered by default. It takes care of special URL formatting needed for the
localization purposes. As you may notice, it uses Regular Expression syntax to extract and replace the
appropriate URL segments.
Rewrite action is by far the most frequent action in the everyday work with the URL rewriter. It
contains that a pattern to be matched from URL to be rewritten (url) and the replacement pattern fro
the new location (rewrite). The patterns are standard .NET regular expressions.This action can
optionally contain a processing (stop|continue|restart) and a conditions parameter.
It is important to note that all relevant URL types must be mapped to the ASP.NET runtime so the URL
rewriting module could catch them. By default, only the .aspx and related files (.ashx, .asmx) are
mapped to the ASP.NET runtime. You can implement "wildcard mapping" using the IIS admin tool.
Right click on the Web site you want to administer, Properties, Home directory tab, Configuration
button. Copy the executable path from one of the existing ASP.NET extensions (.asax, for example).
Click on the insert button, paste the executable path you copied in the previous step, and uncheck
"Verify that file exists".
When using wildcard mapping and handling all web requests using ASP.NET, the default document
settings in IIS are lost. Here’s a rule you can add at the bottom of your rule set which will give you back
default document handling:
Note that using processing=”restart” will rerun the URL back through the complete rule base in case
you have any earlier rules that depend on /default.aspx.
Support for multiple default documents is added via multiple rewrite entries:
<if url="^(.*)/(\?.+)?$">
<rewrite exists="$1/default.aspx" to="$1/default.aspx$2" />
<rewrite exists="$1/index.aspx" to="$1/index.aspx$2" />
</if>
Again, if you are using wildcard mapping and having ASP.NET handle every request, then you need to
add a rule to stop processing of file types that you do not want to handle (images, etc). A rule like the
following at the very top of your rule set will immediately stop rewriting anything with the extension .gif,
.png, .jpg, .ico, .pdf, .css or .js. Your situation may vary so you may want to add other extensions:
<rewrite url="^(/.+(\.gif|\.png|\.jpg|\.ico|\.pdf|\.css|\.js)(\?.+)?)$"
to="$1" processing="stop" />
Two regular expression characters that are typically included (but not required) are the ^ and the $. ^
means the beginning of the URL, while $ means the end of the URL.
Using the ~/ convention if you may install your application in different web application roots. This way,
you will not have to have different rules if your application is installed in a different virtual folder name
(or even in the root of the web site).
One very useful convention is to include an optional pattern to match query strings. If you don’t do this,
then people could break your rewriting by adding a query string.
Here, you have to use & because this is an XML file and it requires the & to be escaped properly. $2
relates to (.+) which will be the query string without the ?.
Two way URL mapping and using URL rewriter's rules for configuration tasks
URL rewriter rules are often used to hold commonly used URL patterns that can simplify the
configuration of multiple Web parts and pages. For example, each of the blog Web parts needs to be
aware of URLs for displaying blog post list, single post display, search page, tag/category list page,
etc. It is almost impossible to maintain and synchronize such large collections of configuration
settings.
The solution for this problem is to use the URL rewriter rules as a central repository for this type of
configuration settings, along with the additional attributes that can be parsed by the T4 code generator
built into Visual Studio. But let's start from the beginning - below is a typical URL rewriter rule:
name attribute is used to access the rule in a strongly-typed manner. For example, you can access
this rule from anywhere in your application by typing
MonoSoftware.MonoX.RewrittenPaths.BlogPost. Of course, you can use your own T4
templates in your custom projects to get the URL format and the namespace you need.
urlPattern attribute is returned as a member of the RewrittenPath class returned when
accessing the rule property described above. It is typically used to retrieve the URL used for
rewriting and parse it as needed. Values in the curly braces are just placeholders and can be
replaced by the real values. {PageName} is a special placeholder that is replaced by the name of
the page that is calling the rule, without the .aspx extension, allowing for "relative" URL rewriting: in
the example above, the single rule can be used regardless of the number of different pages holding
the blog modules. This rewriting is usually performed by the MonoSoftware.MonoX.UrlHelper.
RewritePagePath method and its overloads.
defaultPage holds the path of the default page that is used as a target in the particular rule. It is
very useful when you need to resolve the exact location of a page with specific functionality from
unrelated modules - for example, when search and LiveWriter modules need to determine which
page can be used to display blog posts.
MonoX introduces a powerful mechanism for page optimization. The contents of the Web.config
section that is in charge of page optimization is as follows:
<sectionGroup name="MonoSoftware.Web.WAO">
<section name="ViewState" type="
MonoSoftware.Web.WAO.ViewState.Configuration.ViewStateConfiguration,
MonoSoftware.Web.WAO" requirePermission="false"/>
<section name="HttpCompress" type="
MonoSoftware.Web.WAO.HttpCompress.Configuration.HttpCompressConfiguration,
MonoSoftware.Web.WAO" requirePermission="false"/>
</sectionGroup>
HttpCompress: each page or related resource can be compressed on the fly, reducing the impact on
the bandwidth and page load times. The settings displayed below are tuning the performance and
the behavior of the compression module. As it can be seen, you can set the MIME types that should
not be processed (usually for the files that are compressed already), as well as the exact paths/
URLs.
ViewState optimizer: MonoX can completely remove the contents of the ViewState hidden form field.
It practically means that your page will be much "lighter" in terms of size and load times, as
ViewState hidden field can hold tens of kilobytes of data even in moderately complex applications.
As an added benefit, this will also make your pages more SEO friendly - all this is possible without
loosing any of the ViewState-related functionality. Instead of the hidden form field, the ViewState
data can be stored in a database, file system, or session. This is controled via the following Web.
config entries:
A number of configuration switches in the web.config file is used to specify specific behavior of
installed portal(s). Multiple values (when supported by specific keys) are separated by commas (,) or
semicolons (;).
<!-- Page title prefix or suffix, used with all page titles -->
<add key="PageTitlePrefix" value="" />
<add key="PageTitleSuffix" value="" />
<!-- indicates if the MonoX installation has been performed; if set to
false all requests are redirected to the main installation page. ALWAYS set
to true in the production environment. -->
<add key="InstallationDone" value="true" />
<!-- Used with a "Tell a friend" control. Available built-in modules
that use it: News,Blog,Page,PhotoGallery -->
<add key="EnableContentSharingFor" value="Blog, PhotoGallery"/>
<!-- Tell a friend service account -->
<add key="TellAFriendAccount" value="2009121831841"/>
<!-- name of the favicon if it is to be used on the portal -->
<add key="FavIcon" value="favicon.ico" />
<!-- jQuery reference path. Change it to use other jQuery versions. -->
<add key="jQueryReferencePath" value="
~/MonoX/Scripts/jquery-1.3.2.min.js" />
<!-- Temporary upload path, used as an intermediary storage for
transferring uploaded files to Amazon S3 and similar services -->
<add key="TmpUploadPath" value="~/Upload/Tmp" />
<!-- indicates if thumbnails are automatically created and saved for
all uploaded files; they are alternatively created on the fly on each
request-->
<add key="StoreThumbnails" value="true" />
<!-- thumbnail size: Small (72px), Medium (144 px), Large (288 px) -->
<add key="ThumbnailSize" value="Small" />
<!-- indicates if Catalog icon images are shown for Web parts.
Appropriate icons has to be present in the
~/App_Themes/Common/img/CatalogIconImages -->
<add key="ShowCatalogIconImages" value="false" />
<!-- mail address used to send various confirmation mail messages from
the portal -->
<add key="MailFromAddress" value="monox@mono-software.com" />
<!-- application title used for user friendly email titles, signatures,
etc. If left empty, host name is used by default -->
<add key="ApplicationTitle" value="MonoX" />
<!-- indicates if all files are automatically converted to FLV format
-->
<add key="ConvertVideoToFlv" value="true" />
<!-- holds a physical path to the video converter executable -->
<add key="VideoConverterExeLocation" value="" />
<!-- maximum nuber of items to put in a single SiteMap "file" -->
<add key="MaxSiteMapItems" value="30000" />
<!-- flag if SSL is enabled while sending an e-mail portal wide -->
<add key="EnableSmtpSSL" value="false"/>
<!-- web page url used to show messages within the MonoX CMS -->
<add key="MessagePageUrl" value="~/MonoX/Pages/MonoX/Message.aspx" />
<!-- enables "pretty validators" mode in MonoX. Note: To correctly
implement pretty validator adapter on the custom project you need to add a
"ValidatorAdapter" css class to validator or your custom css class. -->
<add key="EnableValidatorsAdapter" value="true"/>
<!-- enables public user registration -->
<add key="EnableUserRegistration" value="true"/>
<!-- how long (in days) to keep the content cached in the client's
browser. Used by GetImage handler and related parts, cache for standard
static content types should also be set in system.webServer section (IIS
7) -->
<add key="ClientCacheMaxAge" value="30"/>
<!-- indicates if page output cache is enabled in admin mode. Disable
to avoid any side effects -->
ASP.NET 2.0 services that manage state do not interact directly with storage media - instead, they use
providers as intermediaries. A provider is a software module that provides a uniform interface between
a service and a data source. Providers abstract physical storage media, in much the same way that
device drivers abstract physical hardware devices. Because virtually all ASP.NET 2.0 state-
management services are provider-based, storing session state or membership state in a different
type of database (rather than a Microsoft SQL Server database) or even a flat file is as simple as
plugging in a different state and membership providers. Code outside the provider layer needn't be
modified, and a simple configuration change, accomplished declaratively through Web.config,
connects the relevant services to the new providers.
An additional benefit of the provider model is that all ASP.NET applications that use it can be easily
integrated with MonoX. Integrating excellent third-party applications like BlogEngine.Net and
YetAnotherForum.NET is only a matter of few configuration changes in the Web.config files of these
applications (full examples can be downloaded from the support site).
Below are the examples of the membership, role, personalization and search engine providers in
MonoX:
applicationName="MonoX" requiresUniqueEmail="false"
passwordFormat="Clear" maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="0" passwordAttemptWindow
="10" passwordStrengthRegularExpression="" name="
AspNetSqlMembershipProvider"
type="MonoSoftware.MonoX.MonoXMembershipProvider, MonoX"/>
<!-- ActiveDirectoryMembershipProvider is turned off by default
<add name="ActiveDirectoryMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ADConnectionString"
attributeMapUsername="sAMAccountName" applicationName="MonoX"
connectionUsername="username@yourdomain"
connectionPassword="pwd" /> -->
</providers>
</membership>
</providers>
</roleManager>
Apart from the "standard" providers that are presented above, MonoX utilizes provider-based
architecture for numerous different tasks and services, including:
Search engine:
<SearchEngine>
<providers>
<add name="PagesSearchProvider" type="
MonoSoftware.MonoX.SearchEngine.Providers.PagesSearchProvider, MonoX"
PagesDescriptionContentLenght="255" BoldSearchPhrases="true" FullTextSearch
="false"/>
<add name="NewsSearchProvider" type="
MonoSoftware.MonoX.SearchEngine.Providers.NewsSearchProvider, MonoX"
NewsReadPagePath="~/MonoX/Pages/NewsDetails.aspx" NewsContentLenght="255"
BoldSearchPhrases="true"/>
<add name="BlogSearchProvider" type="
MonoSoftware.MonoX.SearchEngine.Providers.BlogSearchProvider, MonoX"
BlogContentLenght="255" BoldSearchPhrases="true" FullTextSearch="false"/>
<RssStorage defaultProvider="RequestRssStorageProvider">
<providers>
<add name="DiskRssStorageProvider" type="
MonoSoftware.Web.RssEngine.Providers.DiskRssStorageProvider, MonoX"
workingFolder="~/MonoX/ApplicationData/RssStorage" sqlConnectionString=""
timeout="30"/>
<add name="CacheRssStorageProvider" type="
MonoSoftware.Web.RssEngine.Providers.CacheRssStorageProvider, MonoX"
workingFolder="" sqlConnectionString="" timeout="30"/>
<add name="RequestRssStorageProvider" type="
MonoSoftware.Web.RssEngine.Providers.RequestRssStorageProvider, MonoX"
workingFolder="" sqlConnectionString="" timeout=""/>
</providers>
</RssStorage>
<AntiSpam>
<providers>
<add name="Akismet" type="
MonoSoftware.Web.AntiSpam.AntiSpamProviders.Akismet.AkismetAntiSpamProvider
, MonoSoftware.Web" apiKey="YourApiKey" />
<add name="Defensio" type="
MonoSoftware.Web.AntiSpam.AntiSpamProviders.Defensio.DefensioAntiSpamProvid
er, MonoSoftware.Web" apiKey="YourApiKey" />
</providers>
</AntiSpam>
Caching:
File storage:
<FileContent defaultProvider="MonoXFileSystemContentProvider">
<providers>
<add name="MonoXFileSystemContentProvider" type="
MonoSoftware.MonoX.FileSystem.MonoXFileSystemContentProvider, MonoX" />
<!-- {0} in urlFormat parameter will be replaced by the bucket name.
Can be used if you want to use custom domain names via DNS alias entries.
-->
<add name="AmazonS3FileSystemContentProvider" type="
MonoSoftware.MonoX.FileSystem.AmazonS3FileSystemContentProvider, MonoX"
bucketLocation="us" accessKeyId="YourKeyId" secretAccessKey=
"YourSecretAccessKey" urlFormat="{0}.s3.amazonaws.com" />
</providers>
</FileContent>
Localization - used to support custom URL rewriting for localization scenarios. By default, localized
URLs have a string similar to "/language/en-US" embedded in it and MonoX extracts the culture
name from such strings. However, the end user can choose the custom rewriting scheme, in case of
which the the InitializeCulture in the BasePage has to be overriden to set Thread.
CurrentCulture and CurrentUICulture to the desired value, and then the
ILocalizationUrlRewriter can be implemented to reflect the custom rewriting rules.
<LocalizationHandler defaultProvider="MonoXLocalizationHandler">
<providers>
<add name="MonoXLocalizationHandler" type="
MonoSoftware.MonoX.Localization.LocalizationHandler, MonoX" />
</providers>
</LocalizationHandler>
2.5 Licensing
MonoX is available in two editions: Free and Source code edition. Regardless of the edition, it may be
used without limitations in both non-commercial and commercial projects. There are no hidden
limitations or complex licensing schemes.
We require that all users of the Free Edition include a backward link "Powered by MonoX" (either in
text or image, sample icons are available in the /App_Themes/Default/img folder) that points to our
Web site, http://monox.mono-software.com. This link may be localized and styled to "blend in" with the
target portal design.
Users of the Source Code edition do not have to display backward links on their pages and can modify
the source code as they need. All licensing information - domain names, license owner, version
numbers - are stored in a cryptographically signed license file (MonoX.lic) that is located in the main /
bin folder of the application. Users of the Source Edition can freely generate MonoX license files for
their domains using a module in the private administrative section of the Mono Software Web site.
Multiple domain names can be stored in a single license file, but each of the target domains must be
present in order for MonoX to work.
III
Working with MonoX
Working with MonoX 29
3.1 Logging in
Each of the default portal templates in MonoX contains a login link/button that redirects the user to the
login.aspx page in the portal root directory. By default, this page contains the login Web part. All of its
aspects are configured in the membership section of the Web.config 15 file (maximum number of
login attempts, minimum password length, etc).
<membership>
<providers>
<remove name="AspNetSqlMembershipProvider"/>
<add connectionStringName="LocalSqlServer"
enablePasswordRetrieval="true" enablePasswordReset="true"
requiresQuestionAndAnswer="true" applicationName="MonoX"
requiresUniqueEmail="false" passwordFormat="Clear"
maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
passwordStrengthRegularExpression="" name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</providers>
</membership>
Login control by default contains only username and password fields; a checkbox "Remember me next
time" is used to leave a cookie on a client computer so a user could be recognized on subsequent
visits without entering authentication data.
MonoX 3.0.651.35 and subsequent versions include support for OpenID, an open and decentralized
identity system that eliminates the need for multiple usernames across different websites, simplifying
your online experience.
Support for RpxNow service is added in version 3.0.1215.35. RPX helps users sign-in to your Web site
using an account they already have at numerous prominent social networking sites and services,
including Google, Yahoo, Facebook, LinkedIn, MySpace, Twitter, Microsoft Windows Live ID, AOL,
etc.
Compare the picture above with the administrative view of the same page:
As you can see from these initial screens, MonoX fully supports the WYSIWYG (What You See Is
What You Get) philosophy. All changes to the look and the functionality of the active page or any of its
Web parts can be performed instantly and interactively.
Each page is composed of several Web parts 8 (modules). Web parts are basic building blocks for
MonoX portal pages. Pages can also contain static HTML text, but all user-configurable, dynamic
content should be placed inside a Web part.
Main administrative tools that can be seen on each and every portal page are:
main administrator's toolbar 35 - a collapsible panel displayed at the top of each portal page. It holds
controls that enable you to change page display modes 36 and views 35 .All visual aspects of a
page and Web parts placed on it can be changed using this toolbar. Additionally, it displays a link to
the portal administration section 43 ; all back-end administrative tasks (page management, file
management, user management, etc.) can be performed there.
Web part menus 31 - each Web part has a menu with several options enabling administrators to
copy, export and minimize parts, or view and change Web part properties. This menu items are
called verbs. The Web part menu can be extended with your own verbs, and can be placed
anywhere inside the part, depending on the currently active chrome (see below).
Each Web part can have a different look & feel. One of the most important concepts related to the
Web part user interface customization, skinning and templating 118 is a Web part chrome 149 . It refers
to the peripheral user interface (UI) elements that frame each Web part control or server control. The
chrome for a control includes its border, its title bar, and the icons, title text, and verbs menu that
appear within the title bar. The appearance of the chrome is set at the Web part zone level, and
applies to all the server controls in the zone.
menu items. By default, common Web parts verbs appear on a drop-down verbs menu in each Web
part control's title bar, however this can be easily changed by using Web chrome template 149 . For
example, Web parts in the left column of the MonoX home page in the default installation have part
menu in their bottom left corners. The customization of default Web part chrome is often performed to
minimize clutter and to enhance the visual appeal of the page: many Web parts have very limited
screen space at their disposal.
Various positions and appearance of the Web part menus (examples rendered in Internet Explorer)
There are standard verbs for opening, closing, editing, and minimizing a control, and other verbs for
exporting a definition for the control or loading a Help file. Other custom verbs are often included to
perform part-specific tasks - for example, HTML editor includes an "Edit" verb to switch the display
mode to design mode and show HTML editors on the page. Additionally, some of the verbs are
dynamically shown and hidden depending on the page context and currently active display mode:
connect verb is shown only in the connect mode; delete verb is shown in the design mode if the part is
dynamically added to the page (static, hardcoded parts do not display this verb);close verb is shown
only if the AllowCloseVerb switch in the user.config file is set to true.
Web part menus and verbs are rendered differently across different browsers. Internet Explorer
displays a drop down menu, while other browsers render a flat list of links:
IV
Using the administrator's
toolbar
Using the administrator's toolbar 35
The toolbar is opened by clicking on the link "Change the look and functionality of this page" or at the
down-pointing arrow in the right corner. The following sections describe each display mode and view in
more details.
It is important to note that MonoX framework relies heavily on the ASP.NET personalization system for
storing the personal preferences for a page. It reads the configuration settings from the main
Web.config file; see the example below for a typical entry:
<webParts enableExport="true">
<personalization defaultProvider="SqlBlobPersonalizationProvider">
<providers>
<add connectionStringName="LocalSqlServer"
applicationName="MonoX" name="SqlBlobPersonalizationProvider" type="
MonoSoftware.MonoX.VersionedPersonalizationProvider" varyByParams="none"/>
</providers>
<authorization>
<allow verbs="enterSharedScope" roles="Administrators"/>
</authorization>
</personalization>
</webParts>
Configuring the authorization for personalization in this way allows only the users in administrators role
to switch the personalization view (scope) of Web pages into shared view (scope). Using the star (*)
for the users’ attribute (and removing the roles attribute) would allow that all users can set the scope of
Web pages into shared scope.
Administrative toolbar makes it easy to recognize the currently active portal view and display mode.
Administrative toolbar in the design mode. Note the short description and the Part Catalog icon. It also
features an additional tab (Module catalog) displaying all available portal modules from the module
gallery.
Portal page in the design mode. Note the HTML editors in the right and left columns and the HTML
editor toolbar that appears on a mouse click in the editable area.
An additional tab - Module catalog - is displayed in this mode. Below is a screenshot of this tab in
action:
imported Web parts: displays the parts that are imported via "Import Web parts" module that is
displayed in the bottom section of this tab. This is a useful utility that allows users to share Web
parts across portals. Parts can be exported to a local disk by clicking on the "Export" verb of each
part (if the export is enabled in the <webParts> section of the main Web.config file).
declarative Web part catalog: displays the parts that are hardcoded in the Catalog zone of the main
MonoX master page. Here is an example from the MonoX.master:
main Web part catalog: dynamically loads and displays all Web parts from the ModuleGalleryPath as
defined in the root web.config file (by default it is located at ~/MonoX/ModuleGallery).
Web part clipboard: displays parts that are copied to the clipboard by clicking on the "Copy" verb of
each part. This option is very useful if you want to copy a Web part to another page inside the same
portal.
page catalog: parts that are minimized or hidden are placed in this catalog, so they could be restored
later.
To add a Web part to the current page, just check a checkbox next to the part's title and select the
Web part zone in the lower right portion of the toolbar and click on the "Add" button.
This is a very simple connection, so after clicking on a link "Create a connection to a Consumer" you
will be able to define a consumer module (there is only one such module on this page, and it is
appropriately called "RSS consumer"). Click on the "Connect" button and the connection is created.
That's all! You are now able to exchange information between modules, and this technique can be
scaled out to very complex scenarios. In this example the provider mode expects an URL of the RSS
feed. After you click the "OK" button in the provider module, this information will be sent to the
consumer module which will display a list of news from the RSS feed at the specified URL.
There are no separate buttons for the edit mode in the administrative toolbar since this mode can be
initiated from each of the active Web parts and the portal engine has to know which Web part has
initiated the mode change (so the appropriate edit fields could be shown). The edit mode is therefore
activated by clicking the "Properties" verb in a Web part.
An additional tab - Module properties - is added to the administrative toolbar when the edit mode is
activated.
custom properties - lists properties that are specific to the selected Web part. Since all parts are
inheriting from the MonoSoftware.MonoX.BasePart, there are some common fields in this section
(cache time, CSS class, edit and view roles, header and footer, etc).
appearance - displays properties that are related to the part's visual appearance - title, chrome type,
firection, width and height
layout - displays chrome state (normal or minimized), zone and zone index of a selected Web part
behavior - displays description, title link, help mode, authorization filter, support for close, connect,
edit, hide, minimize and zone change actions
All changes to any of the Web part property are applied immediately after the "OK" or "Apply" buttons
are clicked.
You can proceed with the work as usual, changing display modes and editing content. When the initial
change is made, an additional button will show up: Approve changes.
As you can see by starting a browser on another computer and accessing the page without logging in
as an administrator, the changes you made are not yet visible to the "ordinary" users. Approve
changes button has to be clicked before the changes are published. "Approve changes" button has to
be clicked when the content is about to be published. "End revision" is clicked when a user wants to
exit the content versioning system.
Content versioning infrastructure is currently used by the portal personalization / layout engine and
HTML editor Web part. Other Web parts (blog engine) currently do not support the content versioning
functionality. HTML editor additionally includes support for the backup history logging.
V
Portal administration
Portal administration 43
5 Portal administration
As it can be seen from the previous section of this tutorial, MonoX administration is divided into two
equally important section:
main administrative toolbar, Web part menus and other administrative elements that are injected
into every portal page when the active user has administrative privileges
main administrative panel that holds and groups common back-end portal functionality: file
management, page management, user management, role management, and other similar back-end
tasks
Main administrative panel can be accessed by clicking on the link "Go to the portal administration
area" that is displayed at the top of each portal page when the currently active user had administrative
privileges.
The following sections will explain the functionality of the standard back-end administration modules.
Note that customized portals can have additional administration sections. Development of such
custom administration modules is explained in the development section 157 .
The left pane (Portal folders) displays the folder structure starting from the root portal folder. Right
mouse click on any of the folders will display a context menu with the relevant, self-explanatory folder
management options:
The right pane displays all files and subfolders of the selected folder. Again, right mouse click on any
of the displayed items displays a context menu with file-related options:
Most file management options in this menu are self-explanatory. Portal-specific operation are:
new page: portal engine reads all page templates from the file system and presents them in this
submenu. Each template is prefixed with the theme name. Page templates are contained in the
PageTemplates folder of each theme folder in the App_Templates root folder (note that each theme
in the App_Themes folder has accompanying App_Templates folder):
File structure of the App_Templates folder, showing PageTemplates for two separate themes, Arctic
and Default
Page template usage is explained in detail in the development section: it is important to remember that
a page template is an ordinary ASPX page without codebehind. Page templates can inherit from an
arbitrary page in the portal. You can use existing templates to create your customized versions; place
a new page template in appropriate PageTemplates folder and it will be automatically recognized by
the portal engine.
upload: this option is used to introduce new portal pages or files to the existing portal(s). Page can
be created by copying an existing page, or by using the New page option described above. However,
if you need to add a new page (one that is completely different from the existing pages and
templates), this is a recommended way to do it. The same holds for addition of other resources
(images and media files).
IMPORTANT: there is a significant difference between portal pages and "ordinary" files. A portal PAGE
has to have the ".aspx" extension and follow the standard .NET coding standards (syntax error will
cause an exception when the page is displayed). It also has to be a child of the MonoSoftware.MonoX.
BasePage base class. Portal pages are dynamic, "runnable" resources that provide a foundation for
most of the MonoX features.
A portal FILE can be anything - HTML file, image file, or any other "static" resource.
page properties: this option is used to enter or edit portal page properties: page title, META
description and keywords, and user roles that are authorized to view the selected page. If none of
the roles is selected, the page is considered to be public and is shown to all users, even the non-
authenticated ones. Page properties screen is shown only for portal pages.
This is where Amazon S3 steps in: it provides a simple Web services interface that can be used to
store and retrieve any amount of data, at any time, from anywhere on the Web. It gives any developer
access to the same highly scalable, reliable, fast, and relatively inexpensive data storage infrastructure
that Amazon uses to run its own global network of Web sites.
MonoX now includes a data provider that hooks into Amazon S3, allowing users to store their data in
the cloud. Best of all, this functionality is totally transparent to the end user, and site administrators can
access it via the familiar file explorer interface that is identical to the standard file management GUI 43
. Additionally, power users can develop their own file providers for other storage services by extending
the FileBrowserContentProvider class and implementing the IFileContentProvider
interface.
Note that you will have to enter the information about your access key ID and a secret access key in
the file content provider section of the Web.config file before you can use the Amazon S3 features.
<FileContent defaultProvider="MonoXFileSystemContentProvider">
<providers>
<add name="MonoXFileSystemContentProvider" type="
MonoSoftware.MonoX.FileSystem.MonoXFileSystemContentProvider, MonoX" />
<!-- {0} in urlFormat parameter will be replaced by the bucket
name. Can be used if you want to use custom domain names via DNS alias
entries. -->
<add name="AmazonS3FileSystemContentProvider" type="
MonoSoftware.MonoX.FileSystem.AmazonS3FileSystemContentProvider, MonoX"
bucketLocation="us" accessKeyId="EnterYourKeyId" secretAccessKey=
"EnterAccessKey" urlFormat="{0}.s3.amazonaws.com" />
</providers>
</FileContent>
"Amazon S3-aware" modules in MonoX (apart from the back end section) include the upload parts, file
gallery and the HTML editor. Amazon S3 storage is also available in the blog engine, social networking
section, and other related parts.
Left pane of this screen (Site map) is used to manage the portal navigation. Dragging a page from the
right pane to the desired place in the left pane's hierarchical structure is the easiest way to include a
page in the portal navigation menu. In the screenshot above, only "Home" and "News" pages are
shown in the main navigation; you can add any other pages by simply dragging them to the left.
Reordering of navigation items is also achieved by dragging them to the desired place in the
navigation. Dropping a navigation item on top of another item will create a hierarchical structure, where
a dropped item becomes a child of the item that it was dropped to. Dropping a navigation item between
two navigation items will simply reorder the existing structure.
Right mouse click on the site map will display a context menu show below:
New container page option creates a "container" item in the navigation - it is used to group several
navigation items together; clicking on the container item in the navigation menu just opens a list of
"child" navigation items in the dropdown menu without actually redirecting the user to another page.
New external page option creates a link to the "outside" page that does not necessarily has to be a
part of the local portal. It also allows users to create several alternative links to the same page.
Roles option allows users to define additional security privileges on the navigation items. Note that
navigation items inherit the security settings from the target pages, but it is possible to override these
settings using the role checklist on this screen.
Right mouse click in the right pane will initiate a context menu shown below:
New page option is used to create a new portal page based on the existing page template. The New
page pane shown here is very similar to the one used at the File management screen 43 . In addition
to fields used to specify template, page title, META description and keyword tags and role checklist,
user is able to explicitly specify a path that will be used to save a newly created page. Additionally, this
pane allows you to specify page output cache settings.
Page properties pane is very similar to the New page pane described above. It is used to edit the
properties of an existing page, and as such it doesn't allow changing the URL of the page. In addition,
it allows you to set page theme and master page.
Manage Web parts option offers a very powerful mechanism for managing personalization settings on
each page.
This module lists all Web parts on the selected page. User can copy or delete specific Web parts and
reset the personalization state, removing all dynamically added part and their settings.
Manage page templates pane allows users to preview all registered page templates grouped by site
theme (skin) and to upload new page templates in the selected theme.
Register portal page option allows administrators to select, import and register a page that was
created outside of the MonoX framework (in Visual Studio or any other development tool).
This screen features a grid-based administration interface that lists all users and their basic properties.
New user can be added by clicking on the "Add" button; properties of an existing user can be viewed
and edited by selecting the desired row in the grid (by clicking on it) and choosing "Edit" button. User is
removed from the database by clicking on the "Delete" link button.
User can be quickly located by using the "Find" field, entering user's full or partial name or e-mail
address, and clicking on the "Filter" button - only the records that match the search criteria will be
shown. Sorting is performed by clicking on the grid header columns.
This screen features a grid-based administration interface that lists all roles and their basic properties.
New role can be added by clicking on the "Add new" button; properties of an existing role can be
viewed and edited by selecting the desired row in the grid (by clicking on it) and choosing "Edit" button.
Role is removed from the database by clicking on the "Delete" button.
Role can be quickly located by using the "Find" field, entering it's full name, and clicking on the "Filter"
button - only the records that match the search criteria will be shown. Sorting is performed by clicking
on the grid header columns.
standard news articles: all time-dependant content items can be easily published using the modules
described in this section.
This back-end section is used to service front-end news modules that can be found in the Web part
gallery and used on the every portal page. Front-end modules are in charge of displaying the news to
the portal users and can do it in a very flexible way due to the templating techniques 150 that are
explained in the development section of this guide. Developers can also create new and fully
customized versions of the existing news modules.
news category administration allows users to create and maintain a hierarchy of news categories.
Every news category has a list of attributes that can be viewed and changed in the right pane. Note
that the category view and edit roles are assigned separately. Left pane displays the structure of the
news hierarchy; standard drag and drop actions can be used to change this structure.
news articles management is the most heavily used section of the news administration system.
This is the place where users actually enter news articles and assign them to categories.
Left pane shows news category hierarchy. Clicking on any of the category nodes in this pane will
present all news articles in the selected category in the right pane grid view. Users can add new or edit
the existing articles there, as well as deleting the selected articles.
Click on the "Add new" or "Edit" button will result in the popup displayed below. This screen contains
four tabs/sections.
"Edit" section allows users to enter news article title, short and full content.
"Publication" section contains checkbox that indicates if the article is currently published and three
related date fields: visible publish date that will be displayed in the front end module (if the date is
included in the news template), as well as start and end publishing dates.
"Display properties" section contains a checklist that allows users to modify the displayed content for
the selected article.
"Tags" section allows users to view and change META description tags for each article.
news publication section allows users to publish news articles. This feature is optional only if the
portal news system is in the advanced mode (NewsWorkingMode switch in user.config is set to
true): in this scenario, users in NewsEditorRoles (see user.config) are not able to directly publish the
articles they are entering. Instead, only users in the NewsPublisherRoleName (see user.config) or
top-level administrators are able to publish news. News publication section allows them to preview
all unpublished articles and to publish any of them by selecting the "Publish news" checkbox(es) and
clicking on the "Publish selected items" button.
After everything is set up correctly in the back-end, one of the front-end news modules can be picked
from the part catalog and placed on the page. Below is an example of the customized front end news
part.
5.7 Ad management
Ad management section allows administrators to create and manage an unlimited number of ad
campaigns. Each campaign can in turn hold an unlimited number of ads and related resources
(images, Google Ads, flash movies, etc.)
This screen features a "master-detail" grid-based administration interface that lists all campaigns and
their basic properties, along with the list of all resources in the selected campaign. New campaign can
be added by clicking on the "Add new" button; properties of an existing campaign can be viewed and
edited by selecting the desired row in the grid (by clicking on it) and choosing the "Edit" button.
Campaigns is removed from the database by clicking on the "Delete" button.
A specific campaign can be quickly located by using the "Find" field, entering it's title, and clicking on
the "Filter" button - only the records that match the search criteria will be shown. Sorting is performed
by clicking on the grid header columns.
Ads are managed using the grid view at the bottom of the screen.
Only the ads from the active campaigns are shown on the portal pages. A campaign can be explicitly
activated by clicking on the "Is campaign active" checkbox, even if the campaign start and end date
fields are empty.
This screen features a master-detail grid-based administration interface that lists all polls and their
basic properties. New poll can be added by clicking on the "Add" button; properties of an existing poll
can be viewed and edited by selecting the desired row in the grid (by clicking on it) and choosing the
"Edit" button. Poll is removed from the database by clicking on the "Delete" button.
A specific poll can be quickly located by using the "Find" field, entering it's title, and clicking on the
"Filter" button - only the records that match the search criteria will be shown. Sorting is performed by
clicking on the grid header columns.
Detailed view is shown below. New answer is added by clicking on the "Add poll answer" link at the
bottom. Answers can be reordered by using Move up and Move down links.
Portal administrators can easily define poll title, question, UI texts and the unlimited number of
answers with colors that will be used to draw the answer chard after the user clicks on a Vote button.
Here is the final look of the front-end module after it is picked from the part catalog and placed on the
page
Front-end poll module after the user vote has been submitted
This screen features a grid-based administration interface that lists all lists and their basic properties.
New list can be added by clicking on the "Add new" button; properties of an existing list can be viewed
and edited by selecting the desired row in the grid (by clicking on it) and choosing the "Edit" button. List
is removed from the database by clicking on the "Delete" button.
A specific list can be quickly located by using the "Find" field, entering it's title, and clicking on the
"Filter" button - only the records that match the search criteria will be shown. Sorting is performed by
clicking on the grid header columns.
Detailed view is shown below. Unlimited number of list items can be added to the list by clicking on the
"Add list item" link at the bottom of the screen. List item content can be edited by clicking on "Edit",
entering changes, and clicking on the "Update" link button to confirm the changes.
Below is an example of a custom front-end list Web part in action (the default list module can be
This screen features a grid-based administration interface that lists all newsletters and their basic
properties. New newsletter can be added by clicking on the "Add new" button; properties of an existing
newsletter can be viewed and edited by selecting the desired row in the grid (by clicking on it) and
choosing the "Edit" button. Newsletter is removed from the database by clicking on the "Delete" button.
Before a newsletter is sent to all subscribers it can be tested by sending it to a single address as
entered in the detailed view.
A specific newsletter can be quickly located by using the "Find" field, entering it's title, and clicking on
the "Filter" button - only the records that match the search criteria will be shown. Sorting is performed
by clicking on the grid header columns.
Detailed view is shown below. Note how you can define the target subscriber groups (roles) and
separate text and HTML content of the newsletter mail message. Also note that newsletter are sent
asynchronously, so administrator doesn't have to wait until the whole process finishes.
Blog settings screen allows administrators to add, edit and delete existing blogs. Note that MonoX blog
system supports multi-user scenarios, so there can be an unlimited number of separate blogs per
each portal.
Blog posts screen features a grid-based administration interface that lists all blog posts and their basic
properties. New blog post can be added by clicking on the "Add" button; an existing post can be
viewed and edited by selecting the desired row in the grid (by clicking on it) and choosing the "Edit"
button. Blog post is removed from the database by clicking on the "Delete" button.
A specific post can be quickly located by using the "Find" field, entering it's title, and clicking on the
"Filter" button - only the records that match the search criteria will be shown. Sorting is performed by
clicking on the grid header columns.
This panel allows you to insert or change a blog post and all its properties, including title, categories,
content, description, categories, roles and tags.
Note that the blog post entry and administration is usually done through the front end blog
parts; the back end screens described in this section are used only by the system
administrators.
VI
Working with Web parts
Working with Web parts 70
Pre-installed Web parts are by default placed in the folder at the following URL: ~/MonoX/
ModuleGallery (this can be changed by changing the value of ModuleGalleryPath configuration setting
in the user.config file). MonoX automatically loads all the module found at this location and displays
them in the Part catalog section of the main administrative toolbar - "Main Web part catalog" section.
Module can be added to the portal page by choosing a Web part zone from the "Add to" dropdown in
the lower right portion of the toolbar and clicking on the "Add" button. Modules that are already present
on the page can be dragged and dropped to other zones when the page is in the design mode 36 .
Module can be removed from the page by using a "Delete" menu option from the Web part menu 31 .If
a user needs to copy a module to all portal pages with the same layout, or to delete a module from a
page that cannot be accessed directly (due to the run time error or some other reason), Page
management 47 - Manage Web parts option should be used.
Each Web part has a set of properties that can be edited interactively to change their appearance and
behavior. This is done by choosing a "Properties" menu option from the Web part menu; page mode
automatically transfers to edit mode, and all part properties are available in the Module properties tab.
As all Web parts inherit from the common parent part (MonoSoftware.MonoX.BasePart), they share a
set of common properties:
Edit roles - defines a set of roles that are able to edit the part
View roles - defines a set of roles that are able to view the part
Template - used for specifying a template for the part
Header HTML - HTML that will be rendered in the header of the part
Footer HTML - HTML that will be rendered in the footer of the part
CSS class - CSS class that is applied to the part
Cache duration - value that specifies cache time (in seconds). If this value is equal to zero, the part
is not cached.
This part publicly exposes multiple properties that enable changes in width, height, navigation URL,
alternate text, etc. AdKeyword filter property enables users to enter additional filter criteria (only the
ads containing keywords entered in the back-end admin panel will appear), while AdTarget property is
used to specify a target navigation window (_self, _blank, _parent, _search, _top - standard values for
opening a pop-up window).
The most common usage scenarios involve placing only a BlogContainer Web part to a page - all
necessary linking and redirecting will be done automatically. The standard blog post page layout is
displayed below. The largest part holding the actual post is BlogContainer.
When a blog is accessed with editor privileges, all editing options are displayed at the top of the page.
You can set the blog settings and manage categories, add new blog post and manage comments, all
from a single front-end module.
Blog settings allow you to change blog name and dewcription; add, edit and delete blog categories;
and manage blog editors.
Blog editors are easily administered using this simple autocomplete dropdown box.
Blog edit interface offers our standard WYSIWYG editor and can be used instantly - all articles have a
link to the edit interface that is visible only to the users with appropriate privileges. It also offers other
neat features like automatic tag extraction and delayed publishing.
By default, MonoX anti-spam protection automatically checks all incoming comments with services like
Akismet and Defensio and does not display possible spam comments until they are manually
approved. All spam comments can be easily identified:
Advanced scenarios may involve placing separate blog parts on separate pages. In most of the
scenarios, blog parts use two-way URL rewriting 15 to support several common properties that are
used when you need to link the blog pages, or to achieve full search engine optimization. These are:
Note that all parameters in curly braces are dynamically parsed and replaced with actual values at
runtime. As explained in the URL rewriting section, {PageName} is a special placeholder that is
replaced by the name of the page that is calling the rule, without the .aspx extension, allowing for
"relative" URL rewriting. Although it may appear to the end user that blog system uses a lot of different
URLs and needs a complex navigation logic, for a developer everything is very simple: our default blog
implementation actually uses a single page: ~/Blog.aspx. Of course, the URL rewriting section in
the web.config file needs to be changed if you plan to create a different URL configuration, although
the default configuration should cover all but the most specific scenarios. Here is how it looks:
<!-- dynamic blog post rules, can be used regardless of the actual
name of the page that holds blog parts -->
<rewrite url="^(.*)/(.*)/post/(.*)/(.*)/(.*)/(\?(.+))?$" to="
$1/$2.aspx?BlogSlug=$3&BlogPostId=$4&$7" name="BlogPost"
defaultPage="~/Blog.aspx" urlPattern="
~/{PageName}/post/{Blog.Slug}/{IdentityId}/{Slug}/" />
<rewrite url="^(.*)/(.*)/posts/(.*)/(\?(.+))?$" to="
$1/$2.aspx?BlogSlug=$3&$5" name="BlogPosts" defaultPage="~/Blog.aspx"
urlPattern="~/{PageName}/posts/{Slug}/" />
<rewrite url="^(.*)/(.*)/search/(.*)/(.*)/(.*)/(\?(.+))?$" to="
$1/$2.aspx?BlogSlug=$3&SearchAction=$4&SearchValue=$5&$7" name=
"BlogSearch" defaultPage="~/Blog.aspx" urlPattern="
~/{PageName}/search/{Slug}/{SearchAction}/{SearchValue}/" />
<rewrite url="^(.*)/(.*)/tag/(.*)/(.*)/(\?(.+))?$" to="
$1/$2.aspx?BlogSlug=$3&SearchAction=tag&SearchValue=$4&$6" name
="BlogTag" defaultPage="~/Blog.aspx" urlPattern="
~/{PageName}/tag/{Slug}/{Tag}/" />
<rewrite url="^(.*)/(.*)/settings/(.*)/(\?(.+))?$" to="
$1/$2.aspx?ShowBlogSettings=true&BlogSlug=$3&$5" name="BlogSettings
" defaultPage="~/Blog.aspx" urlPattern="~/{PageName}/settings/{Slug}/" />
<rewrite url="^(.*)/(.*)/comments/(.*)/(\?(.+))?$" to="
$1/$2.aspx?ShowBlogCommentsAdmin=true&BlogSlug=$3&$5" name="
BlogCommentsAdmin" defaultPage="~/Blog.aspx" urlPattern="
~/{PageName}/comments/{Slug}/" />
<rewrite url="^(.*)/(.*)/edit/(.*)/(.*)/(.*)/(\?(.+))?$" to="
$1/$2.aspx?BlogSlug=$3&BlogPostId=$4&BlogEditMode=true&$7" name
="BlogPostEdit" defaultPage="~/Blog.aspx" urlPattern="
~/{PageName}/edit/{Blog.Slug}/{IdentityId}/{Slug}/" />
<rewrite url="^(.*)/(.*)/insert/(.*)/(\?(.+))?$" to="
$1/$2.aspx?BlogSlug=$3&BlogInsertMode=true&$5" name="BlogPostInsert
" defaultPage="~/Blog.aspx" urlPattern="~/{PageName}/insert/{Slug}/" />
<!-- shows all blog posts regardless of the blog they were posted to
-->
<rewrite url="^(.*)/(.*)/posts/(\?(.+))?$" to="$1/$2.aspx$3" name="
AllBlogPosts" defaultPage="~/Blog.aspx" urlPattern="
~/{PageName}/posts/{Slug}/" />
<rewrite url="^(.*)/(.*)/posts/(.*)/wlwmanifest.xml(\?(.+))?$" to="
$1/wlwmanifest.xml" name="WlwManifest" urlPattern="~/wlwmanifest.xml" />
Blog modules support templating 150 ; HTML templates should be placed in the ~/App_Templates/
(Theme Name)/BlogTemplates folder, where Theme Name is the currently active theme name. This
folder contains separate templates for blog comments, blog list, single blog post view, and all other
related parts.
Comment tags:
Captcha module
Web site owner (or any other e-mail address set in the module custom properties). This module is
protected by the Captcha module.
WebSiteName - Web site name shown on top of the module (Mono Ltd.)
Address - Address of the contact entity
City - City of the contact entity
ZipCode - Zip Code of the contact entity
Country - Country of the contact entity
Phone - Phone of the contact entity
Fax - Fax of the contact entity
EMail - E-mail of the contact entity (Address where to send contact
messages)
ValidationGroup - Validation group
MonoX also includes an improved SIlverlight-based upload control that allows users select and upload
multiple files in one step. It can also autogenerate thumbnails and convert video files to the FLV
format.
Both upload parts can work with various file system providers (see the ContentProviderTypeName
property), so they can store files not only on your local system, but also on various could-based
storage services like Amazon S3.
HTML editor part with Edit verb selected from the Web part menu. After the Edit verb is clicked...
...the page switches to the design mode and the HTML editor content is ready to be edited. Click inside
the editable area of the editor...
...and the editor toolbar pops down in the top portion of the page.
HTML editor toolbar includes standard tools, allowing even inexperienced users to start using it
efficiently in a very short time. Apart from the standard formatting tools, HTML editor includes:
save button in the top left corner that allows users to save their work
several media managers (image manager, flash manager, document manager) that allow users to
easily manage their media collections and add links to images, documents, and other media
HTML-specific tools (hyperlink manager, image map editor, template manager)
backup history: a portal can be set-up to "remember" all changes made through HTML editors
(SaveDocumentBackups configuration switch in user.config). Backup history dropdown box in the
bottom right corner of the editor toolbar allows users to replace the currently active content in the
editor area with any of the previous versions (NumberOfBackupItems configuration switch defines
how many of these versions will be displayed in the dropdown).
content versioning, as described in a separate section 41 .
Editor can be used in various toolbar modes, depending on the user's preferences (EditorToolbarMode
switch in the user.config file): PageTop (default), ShowOnFocus (toolbar is contained inside the editor
part and shown on focus) and Floating (editor toolbar is shown on focus, but floating outside the
Note: Before using this part, portal administrator needs to add a list of languages used in the Portal
language administration 134 .
ListId - - identifies the list that will be displayed in the module, set by
using the list editor control in the design mode.
CssSelectorClass - root CSS selector class that is used to apply different
styles to modules on different pages.
RepeatLayout - repeat layout (table or flow)
RepeatDirection - repeat direction (horizontal or vertical)
RepeatColumns - number of columns
List supports templating 150 ; HTML templates should be placed in the ~/App_Templates/(Theme
Name)/ListTemplates folder, where Theme Name is the currently active theme name.
The supported template tags are:
Other properties allow formatting of title sections (font size, background color, foreground color).
MonoX navigation menus are rendered via radMenu ASP.NET server control. It can be styled using its
set of skins in the ~/MonoX/Templates/RadControls/Menu folder.
<ul>
<li><a href='http://localhost/MonoX/FirstPage.aspx'>First page</
a><ul></ul></li>
</ul>
<ul>
<li><a href='http://localhost/MonoX/SecondPage.aspx'>Second page</a>
<ul>
<li><a href='http://localhost/MonoX/ChildPage.aspx'
class="dropdown_bg">Child page</a></li>
</ul>
</li>
</ul>
The exact structure of the rendered HTML can be changed directly in the ASCX file, as templates are
fully supported in the hierarchical repeater control that is a foundation for the navigation menu control.
ParentFilterItemId - Id of the parent menu item if the menu should not be rendered from the
root item.
MenuFlow - flow of the menu, horizontal or vertical.
MenuSkin - name of the menu skin, list of available skins is browsed from ~/MonoX/Templates/
RadControls/Menu.
RadControlsFolder - if the RadControlsFolder is not placed at ~/MonoX/Templates/
RadControls, you should specify the new location in this parameter.
RootMenuSeparatorString - root level separator character or string.
ShowRootItemsOnly - specifies if the menu control should render the root-level items only, used
mainly in footers and other secondary-level menus.
News security system (built on top of the MonoX user management system) allows you to manage
view and edit permissions for news categories.
ReadMorePage – used to reference the page used to display news article with full content
(optional). If not set, the news module will show full article content on the same page.
CategoryFilter – used to filter the content by categories. Only news articles from the chosen
category will be shown.
ShowNewsFromSubCategories – if this property is set to true, the category filter mechanism will
also include news articles from the child categories of the chosen category.
Main news module allows users to gain access to news content with almost no effort. Main news
module has all the settings pre-configured, so administrators can modify only few optional settings
such as read more page, category filter, etc.
Archive news module allows users to gain access to archived news content. This news module has all
settings pre-configured for filter out non-archived news content.
This news module has all the settings exposed to user so he can fully customize the news content.
The following properties can be customized:
NewsRepeatDirection
NewsRepeatColumns
NumberOfNewsItemsToShow
PagerPageSize
ShowRevision
ShowAllItems (shows all news articles regardless of whether they are
expired or not)
ShowTitle
ShowShortContent
ShowCategoryTitle
ShowCategoryTitleAsLink
ShowCategoryTitleAsLink
ShowFullCategoryPathway
ShowUsername
ShowCreateDate
ShowModificationDate
ShowVisibleDate
ShowRating
ShowViewCount
ShowIfEmpty (determines if the part is shown even if there are no active
news articles)
Home page news module has predefined filter to show only news articles marked as home page
articles in the news management section. News administrator needs to set a "Home page article"
property to have it displayed inside this module.
Random news module rotates news articles in a random order. User can set the category filter to show
articles from the specified categories only.
Single news module is configured to show only one news article in a full content mode. It is always
used on the “Read more page”, as set by other news modules.
News menu is news related module used to navigate through news categories. It also introduces a
category filter, news menu item render direction settings, and similar properties.
PollId - identifies the poll that will be displayed in the module, set by
using the poll editor control in the design mode.
VoteButtonText - text that is displayed on the 'Vote' button - used if
not defined in the poll settings.
TotalVotesTextTemplate - template for the 'Total votes' text - used if
not defined in the poll settings. Defaults to "Total: {0} votes.".
ExpirationDays - number of days after which the vote cookie will expire
on the user's computer.
CssSelectorClass - root CSS selector class that is used to apply
different styles to modules on different pages.
Configuring RSS reader is as easy as entering the URL of the source feed. Other properties can be
used to improve the look and feel of the module: RepeatLayout (Table, Flow), RepeatDirection
(Horizontal, Vertical), RepeatColumns, CssSelectorClass.
RSS reader supports templating 150 ; HTML templates should be placed in the ~/App_Templates/
(Theme Name)/RssReaderTemplates folder, where Theme Name is the currently active theme name.
The supported template tags are:
Search Web part can be used for implementing the front end (usually a textbox with a search button),
and the results page with a list of items that meet the search criteria. However, in the most common
scenario, MonoXSearchBox.ascx is used to provide a front end for the search box, while
MonoXSearch.ascx displays the search results.
Changing the appearance of the front end may involve editing of the HTML markup of the part. It is
located at the following URL: ~/MonoX/ModuleGallery/MonoXSearch.ascx. Note that the markup of the
control includes two panel controls, named plhSearch and plhSearchResults. ONLY the plhSearch
panel may be modified as this is not a repatable section and therefore cannot be modified; the existing
.NET controls (search textbox and button) cannot be removed from the control, but their properties
(CssClass and similar) may be changed.
To change the appearance of the search results page you may change an existing template or add a
new one. The template folder URL is ~/App_Templates/(Theme Name)/SearchEngineTemplates
folder, where Theme Name is the currently active theme name.
Search Web part relies on the ASP.NET provider model 23 . A provider is a software module that
provides a uniform interface between a service and a data source. In this case, portal search engine is
the service, but the data source can vary. Providers abstract physical storage media, so the common
functionality can be developed without regard for the differences in various storage models.
By default, the following providers are supplied with the MonoX installation: PageSearchProviders,
NewsSearchProvider, BlogsSearchProvider, GroupSearchProviders, UserProfileSearchProvider,
LuceneFileSystemSearchProvider and IndexingServiceSearchProvider.
In the example below, search engine can search and index portal pages and news articles, but users
can develop totally customized search engines and register them with MonoX. <SearchEngine>
section in the web.config file performs the registration of search providers:
<SearchEngine>
<providers>
<add name="PagesSearchProvider" type="
MonoSoftware.MonoX.SearchEngine.Providers.PagesSearchProvider, MonoX"
PagesDescriptionContentLenght="255" BoldSearchPhrases="true" FullTextSearch
="false"/>
<add name="NewsSearchProvider" type="
MonoSoftware.MonoX.SearchEngine.Providers.NewsSearchProvider, MonoX"
NewsReadPagePath="~/MonoX/Pages/NewsDetails.aspx" NewsContentLenght="255"
BoldSearchPhrases="true"/>
</providers>
</SearchEngine>
Note that full text search can be initiated if the FullTextSearch parameter is set to true AND full text
indexes are created on the target tables in the MonoX database using SQL Server Management studio
or other similar tool. More information on the development of the custom search providers can be
found in the second part of this manual.
By default, all registered providers are used on the search results page. To use only a subset of all
registered providers, use the following syntax in the Web part or page that holds the search box:
Activity stream Web part (SocialNetworking/Events.ascx) allows users to get real-time updates
on their friends' daily activities. This includes:
Besides various properties that define the display URL for each of the event categories, this part
introduces a EventsToDisplay "flagged enum" property that is used to defined which event types
are displayed.
Activity streams part supports templating 150 ; HTML templates should be placed in the file located at ~/
App_Templates/(Theme Name)/SocialNetworkingTemplates/Events.htm (or Events.ascx), where
Theme Name is the currently active theme name.
The supported template tags are:
<# Icon #>, used to display the event icon. FormatEventIcon method could be overriden to
implement the custom logic for displaying eventicons.
6.1.16.2 Comments Web part
Comments Web part allows users to leave comments on your blog posts, files, albums and wall notes.
With a little bit of custom development, comments can be added to other types of content.
Although a simple module, comments can add a lot of interactivity to your community resources.
Configuration of this module is easy: it primarily depends on a ParentEntityId /
ParentEntityType pair of properties, where the first one defines the Id of the entity your are
commenting, and the second one is used to specify the type of the parent entity (SnEntityType
enum can hold values for Album, Message, Note, BlogPost, ...). You can use Custom entity types for
linking comments for other types of content.
Comments Web part supports templating 150 ; HTML template file should be placed in the following
location: ~/App_Templates/(Theme Name)/SocialNetworkingTemplates/Comments.htm (or
Comments.ascx), where Theme Name is the currently active theme name.
The supported template tags are:
Discussion boards or forums are one of the oldest and most common social networking features:
discussion board represents virtual space where users can post messages to the community in a way
that all the responses will be viewable no matter how much time passes between each post. Typically
this will be a very dynamic area of your portal. Discussion system consists of several independent Web
parts that are located under ~/ModuleGallery/SocialNetworking/Discussion:
DiscussionBoard.ascx is a "home" control that displays discussion boards in a single item view.
It also contains an edit form that is used for adding new discussion boards, or editing the properties
of an existing board.
DiscussionContainer.ascx holds together individual discussion parts and switches between
active modules based on user's actions.
DiscussionTopicMessages.ascx displays a list of all messages inside a single discussion
topic.
DiscussionTopics.ascx holds a list of all topics in a single discussion board.
Discussion Web parts are self-contained and work out-of-the-box: you can modify their behavior
programmatically or via exposed properties that are described in the MonoX API documentation - for
example, forums can be public or private, message can be edited using simple text area or advanced
HTML editor, etc.
File gallery can be used whenever you need to display a list of files attached to a blog post, album, wall
note, comment, or another custom entity. This module is aware of the most file types, and uses
thumbnails generated by the attached upload module (the most common image or video file types),
OR displays a static, file type-specific icon for file types for which a thumbnail is not generated by
default (MS Office, PDF, ...)
File gallery is often used in conjunction with the file upload module (Silverlight upload module is
displayed in the images below):
Silverlight file upload module allows users to select multiple files that are uploaded in a single step
File gallery displays three files (a video file, a Word and a PDF document) in admin mode. The "trash"
icon allows administrators to remove the file from the gallery.
As all other "child" modules (Comments...), File gallery primarily depends on a ParentEntityId /
ParentEntityType pair of properties, where the first one defines the Id of the entity your are
commenting, and the second one is used to specify the type of the parent entity ( SnEntityType
enum can hold values for Album, Message, Note, BlogPost, ...). You can use Custom entity types for
linking comments for other types of content.
File gallery can store files using various file content providers (classes that implement the
IFileContentProvider interface). MonoX provides the default
MonoXFileSystemContentProvider and AmazonS3FileSystemContentProvider, an
advanced cloud-based storage mechanism.
If you need to use a file gallery in "static" scenarios, and specify list of files in the source of the page
when dynamic management is not necessary, use a FileList inner property.
Additionally, you may choose between standard and "PrettyPhoto" image click handling: in a standard
mode, a full size image or document is shown in a separate browser window, while PrettyPhoto
displays a nicely-formatted slideshow, but is not compatible with all document types.
Comments Web part supports templating 150 ; HTML template file should be placed in the following
location: ~/App_Templates/(Theme Name)/SocialNetworkingTemplates/FileGallery.htm (or FileGallery.
ascx), where Theme Name is the currently active theme name.
The supported template tags are:
File view Web part is almost exclusively used in combination with the File gallery 93 Web part to
display files in a "single file view" mode. It can properly recognize image and video file types and
generate proper viewers for such file types. If a File view contains files of another type (for example,
Word or PDF document), it redirects the request directly to the file URL, so the browser can handle
document download and display.
Additionally, this Web part can display description and comments for image and video files.
6.1.16.6 Flash video player Web part
Flash video player part encapsulates the Flash video player SWF. MonoX by default uses a free
Flowplayer video player - note that it is not distributed with MonoX, and you must download it
separately. You can set the width and height of the player, as well as the auto-play property. Everything
else is handled automatically.
MonoX supports automatic conversion of multiple video file formats to the .FLV format that is probably
the best option for developing various kinds of video collections. The Web.config parameter setting
ConvertVideoToFlv controls the conversion process - when it is set to "true", the conversion
process begins automatically when the file is uploaded via Silverlight Upload Web part. This process
requires a separate installation of video converter like ffMpeg that is NOT a part of the MonoX package
- it must be downloaded separately, and the location of the video converter's exe file must be specified
in the VideoConverterExeLocation parameter (it requires a physical path, for example C:\utilities
\ffMpeg.exe).
6.1.16.7 Followers Web part
Followers Web part looks and behaves similarly to the Friend list Web part, with one exception - it is
used in "one-way" friendship ("Twitter-style", following/follower) scenarios. Relationship mode is set in
the web.config file using the following tag:
By default, it is set to "TwoWay" ("Facebook-style") relationship mode: when a person A invites person
B to be her/his friend ("friend" is a generic term used throughout this manual, some users would prefer
a term "contact"), and person B accepts the invitation, a "friendship" relation is formed in both ways: A
-> B and B -> A. On the other hand, when SocialNetworkingRelationshipMode is set to
"OneWay", only the initial relationship (A -> B) is formed - person B does not typically have to approve
the request, so the person A becomes a "follower" of the person B.
Followers Web part works only in "OneWay" scenario described above. All other aspects (properties,
templating, look and feel) are shared with modules that inherit from the FriendList class.
6.1.16.8 Friend list Web part
Friend list is one of the core social networking modules, and can be used at different types of pages. In
most scenarios it is used to show a list of user avatars that are in "friendship" relation to the active
user.
UserId property can be set to the Id of the active user, or any other system user (for example, when
accessing the user profile page this part usually displays friends for the selected user, not the user
accessing the page).
Depending on the system configuration switch ShowBlogGravatars , Friend list part displays "
Gravatars" or local system avatars.
This Web part supports templating 150 ; HTML template file should be placed in the following location:
~/App_Templates/(Theme Name)/SocialNetworkingTemplates/Comments.htm (or ascx), where
Theme Name is the currently active theme name.
The supported template tags are:
In the context of social networking sites, groups allow users of to interact with each other around a
common topic. Modules such as forums, image galleries and walls can be fully utilized from the group
point of view.
By default, each group holds several resources: group wall, gallery and a group discusion board. The
default MonoX installation uses additional group modules (see below) to allow users to navigate
groups easily.
MonoX group system consists of a several independent Web parts that are located under ~/
ModuleGallery/SocialNetworking/Groups:
GroupContainer.ascx - Web part that holds all individual modules together and switches active
modules on and off based on the user actions.
GroupEdit.ascx - used by administrators to set the group properties (title, description, logo,
administrators).
GroupInfo.ascx - displays the basic group information: title, description, public/private settings,
links to join or leave the group, etc.
GroupInvitationList.ascx - eb part that holds the invitation list for the selected group (sent
and received invitations).
GroupList.ascx - Web part that displays a list of all groups (default scenario when the active user
is not a member of a group), or groups that the active user is subscribed to.
GroupMembers.ascx - displays group members. Inherits from from the friend list base control, so
it shares all properties and methods with it.
GroupPeopleSearch.ascx - used to search users and add them to the group.
GroupSearch.ascx - enables users to search through the list of all groups on a single site.
GroupView.ascx - displays all group resources - wall, albums, discussions.
NewGroupsList.ascx - displays groups ordered by their creation date, often used on dashboard
pages.
Group home, displaying wall, group info and group member modules
Group discussion
Invitation list displays a list of users that you invited to be your friends (or members of a particular
group), OR users that have invited you to form a friendship or join a group, depending on the value of
the InvitationListType (InvitationsSent or InvitationsReceived) property.
This Web part supports templating 150 ; HTML template file should be placed in the following location:
~/App_Templates/(Theme Name)/SocialNetworkingTemplates/InvitationList.htm (or .ascx), where
Theme Name is the currently active theme name.
The supported template tags are:
Messaging is essential to all community sites as it allows users to communicate with each another (or
a whole group) directly, resembling the look and feel of traditional mail clients. Messaging Web parts
are located in the ~/ModuleGallery/SocialNetworking/Messaging folder:
MessageCreate.ascx: contains the input form for creating a new message. A separate popup
page MessageFriendListAdmin.aspx is used to manage message lists that can be created by
each user.
MessageDetails.ascx: displays a single message and associated replies.
MessageList.ascx: presents a list of all sent of received messages.
MessageCenter.ascx: wraps all of the parts described above and dynamically selects and
displays the active massaging module, depending on the currently active mode.
The most common usage scenarios involve placing only a MessageCenter Web part to a page - all
necessary linking and redirecting will be done automatically. Below are displayed some of the
messaging Web parts in action.
Message center displaying a list of sent messages for currently active user
User picker control in action - autocomplete functionality allows users to easily find a right person at
the receiving end. If you need to enter multiple persons just use a comma to separate individual
entries.
You can easily create and manage unlimited number of friend lists, so there is no need to type long
lists of message recipients
Messaging parts in MonoX are totally self contained and virtually no administration is required to plug
in the messaging system to your portal. A handful of properties allows administrators to tweak the
behavior of individual Web parts:
DisplaysUsersOnly property in UserPicker,ascx defines if only a list of friends for the currently
active user will be displayed, as opposed to the full list of friends, messaging lists and group
members of the groups that currently active user also joined
ShowSendMailCheckbox shows or hides the "Send mail" checkbox from the MessageCreate
panel
AllowFileUpload defines is file attachments are allowed; file repository location is controlled by
the FileUpload property. The following special strings can be used in this property and will be
replaced by the appropriate values: {username}, {userid}, {id}.
This Web part displays new portal users and is commonly used in various dashboard pages. It can
sort users by their registration date or the date of last login. Additionally, users can be sorted randomly.
The sort order is controlled by the UserSortCriteria property. Additionally,
ShowValidAvatarsOnly propery is used to display only valid avatar images, to avoid large quantity
of "dummy" avatars being displayed.
All other aspects are identical to the Friend list 95 Web part.
People search Web part is a primary "user picker" module that is used throughout the social
networking systems of MonoX. It features an easy to use, autocomplete-enabled text box that allows
users to start typing user name (or first name, last name, e-mail) of the users they want to locate and
immediately get a list of all users that match the entered text.
This part can be used in two different scenarios, controlled by the ConfirmationRequired property.
When it is set to false, users can add other users to their friend lists without asking for confirmation.
This scenario is frequently used in OneWay, follower/following scenarios. Another important property is
SocialNetworkingMode: it defines if all users are searched when the active user starts typing -
alternatively, only the users which a members of the same groups as the currently active user will be
searched.
Additionally, this Web part exposes other properties that allows you to control the contents of the
invitation mail messages, visibility of the user search text box (it can be hidden when People search
part is placed on the user profile page), etc. More details are available in the accompanying API
documentation.
Photo gallery can be used as a valuable social networking resource. It offers an added value to your
users in various scenarios - whether it is used standalone or as a part of a social networking group.
MonoX photo gallery part set offers an intuitive interface that allows your users to easily create their
albums and upload unlimited number of photos in a matter of seconds. They can assign a title and a
description to each of the photo, as well as a title photo for each of the albums, while other users can
leave comments and share links to individual photos.
Photo gallery system consists of several independent Web parts that are located under ~/
ModuleGallery/SocialNetworking/Photo Gallery:
AlbumEditView.ascx - Web part that is used to edit the photo album's properties.
AlbumList.ascx - displays a list of photo albums.
NewAlbumsList.ascx - displays a list of new albums, commonly used on dashboard pages.
PhotoEditView.ascx - Web part that serves as an editor for individual photos, allowing users to
enter title, description and privacy settings to each of their photos.
PhotoGalleryContainer.ascx - Main photo gallery container part, holds together individual
album parts and switches the active part based on the user actions.
PhotoListView.ascx - Web part that displays a list of photos as a part of an album.
PhotoUpload.ascx - used to upload photos to the album.
This is how the album looks when the user clicks on the starting (cover) photo
Photo list and album lists parts support templating 150 . The supported template tags for
PhotoListView are:
A "Wall" is one of the key concepts in social networking portals. In the simplest scenarios, it represents
a space on every user's profile page that allows friends to post messages for the user to see.
Additionally, a wall can be used in "site-wide" scenarios, where users can see posts from their friends
regardless of where did they post it. It can also be used on group pages, allowing group members to
exchange messages and comments. This behavior is controlled via UserId and GroupId properties.
When UserId is set, the wall is switched to the owner mode where only notes posted directly at it are
shown. Alternatively, when GroupId is set to the non-empty value, the wall displays only group posts.
This Web part supports templating 150 ; HTML template file should be placed in the following location:
~/App_Templates/(Theme Name)/SocialNetworkingTemplates/WallNotes.htm (or .ascx), where
Theme Name is the currently active theme name.
This module allows users to manage their Avatar / Gravatar images and other general user
information such as first and last name, address, Web site etc. Administrators can manage other
user's profiles.
Note that user profile data structures and accompanying modules usually require a lot of changes in
custom projects. The default user profile Web part covers only basic and most common information for
general purpose portals.
VII
Working with MonoX pages
Working with MonoX pages 109
It is important to understand the difference between a portal page and a static HTML markup page.
Due to personalization system and advanced Web part capabilities, portal page can host controls that
are not physically present in the page markup; instead, they are dynamically created based on the
personalization settings or data saved by some of the Web parts that are included in the page. This
allows for very advanced application scenarios.
All page administration tasks should be performed from the page management pane 47 .
MonoX heavily relies on the ASP.NET master page infrastructure. Master pages allow users to create
a consistent layout for the pages in their portals and other Web applications. A single master page
defines the look and feel and standard behavior for all of the pages (or a group of pages) in the portal.
When users request the content pages, they merge with the master page to produce output that
combines the layout of the master page with the content from the content page.
It is mentioned previously that all portal pages actually depend on the master page infrastructure to
create a consistent layout for all portal pages. In practice, a master page is an ASP.NET file with the
extension .master (for example, MonoX.master) with a predefined layout that can include static text,
HTML elements, and server controls. The master page is identified by a special @Master directive that
replaces the @Page directive that is used for ordinary .aspx pages.
In addition to static text and controls that will appear on all pages, the master page also includes one
or more ContentPlaceHolder controls. These placeholder controls define regions where replaceable
content will appear. In turn, the replaceable content is defined in content pages. Once a portal is set
up, users typically create content pages, while the master page structure and hierarchy usually
remains intact until a global site redesign is required. From the user's perspective, the combined
master and content pages are a single, discrete page. The URL of the page is that of the content
page.
The default location for MonoX master pages is ~/MonoX/MasterPages. The hierarchy of built-in
nested master pages is as follows:
Main.master - specifies only the bare bones of the portal page - header, body, main form and Ajax
script manager.
UpdatePanel.master and UpdatePanelEmpty.master - both specify an additional container for
content pages to allow switching between Ajax and non-Ajax modes (UpdatePanel.master is used
when AjaxedWebPartManager configuration switch is set to true, and UpdatePanelEmpty.master is
used when it is set to false). By default, administrators are always working in the Ajax-enabled
mode. If you need to set the Ajax-enabled mode in a page regardless of the user privileges, set the
AjaxifiedPage property of a BasePage to true. If you don't want to use the Ajax features at all,
set the AjaxedWebPartManager property in web.config to false. All administrative actions will
cause a postback in this mode, which can slow you down, but is useful if you need to avoid Ajax
callbacks for some reason.
MonoX.master - contains portal administrator toolbar and does all the work related to it. All
customized master pages should have this page as a parent.
Default.master - this page specifies the layout of portal pages. There can be unlimited number of
master pages at this level.
This page illustrates usage of the Web part zones for the page layout. Zones are simply regions on a
page that contain Web Parts controls. Zones exist to lay out Web Parts controls on a page, and to
provide a common UI for the controls. There can be one or many zones on a page, each zone can
contain one or many Web Parts controls, and each zone can have a vertical or horizontal orientation
for page layout. There can be static or dynamic content outside the Web part zones, but such content
cannot be dynamically personalized.
Looking at this example you may notice that Web part zones are mixed at several levels of the master
page hierarchy. Search and navigation elements are usually placed in the Default.master page:
<%@ Master
Language="C#"
AutoEventWireup="true"
EnableTheming="true"
Inherits="MonoSoftware.MonoX.MasterPages.Default"
MasterPageFile="~/MonoX/MasterPages/MonoX.master"
Codebehind="Default.master.cs" %>
The purpose of this master page is to define the overall look and feel of all portal pages, and it does so
by specifying the content for the header and footer areas. However, the content area often varies in
content and appearance (number of columns, etc), so in this case its markup is contained in the
Default.aspx page which is a content page that goes into the ContentPlaceholder in the Default.
master. Note how the Web part zones are mixed with other types of content.
<%@ Page
Language="C#"
AutoEventWireup="true"
MasterPageFile="~/MonoX/MasterPages/Default.master"
Theme="Default"
Inherits="MonoSoftware.MonoX.Pages.Default"
Title="MonoX - Portal Framework for ASP.NET"
Codebehind="Default.aspx.cs" %>
<div class="main">
<table cellpadding="0" cellspacing="0" class="two-columns">
<tr>
<td class="left-column">
<portal:PortalWebPartZone ID="leftWebPartZone" runat="server"
Width="100%" ChromeTemplateFile="Standard.htm" HeaderText='<%$ Code:
PageResources.Zone_LeftPartZone %>'>
<ZoneTemplate>
<MonoX:Editor runat="server" ID="editor1" Title='<%
$ Code: PageResources.Title_LeftSection %>' DefaultDocumentTitle='<%$ Code:
PageResources.Title_LeftSection %>' >
<DefaultContent>
Default eidtor text goes here...
</DefaultContent>
</MonoX:Editor>
</ZoneTemplate>
</portal:PortalWebPartZone>
</td>
<td class="right-column">
<portal:PortalWebPartZone ID="rightPartZone" runat="server"
Width="100%" ChromeTemplateFile="Standard.htm" HeaderText='<%$ Code:
PageResources.Zone_RightPartZone %>'>
<ZoneTemplate>
<MonoX:Editor runat="server" ID="editor2" Title='<%$
Code: PageResources.Title_RightSection %>' DefaultDocumentTitle='<%$ Code:
PageResources.Title_RightSection %>'>
<DefaultContent>
Default eidtor text goes here...
</DefaultContent>
</MonoX:Editor>
</ZoneTemplate>
</portal:PortalWebPartZone>
</td>
</tr>
</table>
</div>
<div class="light-blue-wrapper">
<div class="light-blue-bg">
<table cellpadding="0" cellspacing="0" class="featured-project">
<tr>
<td class="project-container">
<MonoX:SlideShow runat="server" ID="ctlSlideShow">
<SlideShowItems>
<ModuleGallery:SlideShowItem runat="server"
ImageUrl="~/App_Themes/Default/img/Projects/project-jobs-market.jpg" Url
="http://www.jobsmarket.ie" Title="Jobs Market"></ModuleGallery:
SlideShowItem>
More slideshow items...
</SlideShowItems>
</MonoX:SlideShow>
</td>
<td class="project-description">
<portal:PortalWebPartZone ID="featuredProjectPartZone"
runat="server" Width="100%" ChromeTemplateFile="Standard.htm" HeaderText='
<%$ Code: PageResources.Zone_FeaturedProjectsZone %>'>
<ZoneTemplate>
<MonoX:Editor runat="server" ID="editor3" Title='<%
$ Code: PageResources.Title_FeaturedProjects %>' DefaultDocumentTitle='<%$
Code: PageResources.Title_FeaturedProjects %>'>
<DefaultContent>
Default eidtor text goes here...
</DefaultContent>
</MonoX:Editor>
</ZoneTemplate>
</portal:PortalWebPartZone>
</td>
</tr>
</table>
</div>
</div>
</asp:Content>
Left and right part zones are specified at this level. Note that all static content that is to be included into
some of the Web part zones must be wrapped in a server control.
VIII
Using Windows Live Writer
with MonoX
Using Windows Live Writer with MonoX 115
MonoX fully supports Windows Live Writer and other similar editing tools that recognize standard
MetaWeblog API, not only for the blog publishing tasks, but also for more general portal editing and
configuration actions.
Windows Live Writer can be configured to work with MonoX portal in a few easy steps:
3. Enter the address of the homepage URL and username/password combination. Home page URL
MUST point to the MetaWeblog.aspx page in the root of your portal installation.
4. Choose Metaweblog API and enter the remote posting URL. It is almost identical as the Weblog
home page URL entered in the previous step - the URL point to the MetaWeblog.ashx in the root of
your portal installation (only the extension is different, ashx instead of the usual aspx).
6. The next screen will only show a confirmation, and you are ready to start publishing with Windows
Live Writer.
IX
Portal themes
Portal themes 118
9 Portal themes
By Microsoft's definition, an ASP.NET theme is a "collection of property settings that allow you to
define the look of pages and controls, and then apply the look consistently across pages in a Web
application, across an entire Web application, or across all Web applications on a server." It is
important to note that this technique is not specific to portals and Web parts: it is a universal
mechanism introduced in version 2 of ASP.NET framework to support easier and more solid, scalable
and consistent Web site styling.
Themes are made up of a set of elements: skins, cascading style sheets (CSS), images, and other
resources. At a minimum, a theme will contain skins. Themes are defined in a special folder of your
portal: it is called App_Themes and is always placed in the root portal folder.
NOTE: it is very important to distinguish standard ASP.NET themes and MonoX theme sets (or skins,
as they are somewhat called in other CMS products). When we are talking about MonoX skins, we are
taking into account all elements that are needed to change the look and feel of an application. This
typically involves:
- a theme folder (~/App_Themes), holds application CSS(es), ASP.NET skin(s) (see below) and
associated image and media files
- a template folder (~/App_Templates), holds Web part templates (see below)
- one or many master pages 109 that define the layout of application pages
Please download a sample template from our template gallery to study a structure and content of a
typical MonoX theme set.
ASP.NET Skins
A skin file has the file name extension .skin and contains property settings for individual controls such
as buttons, labels, and so on. Control skin settings are like the control markup itself, but contain only
the properties you want to set as part of the theme. For example, the following is a section of the
Default.skin file that define the default look and feel of the Web part zone:
You create .skin files in the Theme folder. A .skin file can contain one or more control skins for one or
more control types. You can define skins in a separate file for each control or define all the skins for a
theme in a single file.
There are two types of control skins, default skins and named skins.
A default skin automatically applies to all controls of the same type when a theme is applied to a
page. A control skin is a default skin if it does not have a SkinID attribute. For example, if you create a
default skin for a WebPartZone control as in the example above, the control skin applies to all
WebPartZone controls on pages that use the theme. (Default skins are matched exactly by control
type, so that a Button control skin applies to all Button controls, but not to LinkButton controls or to
controls that derive from the Button object.)
A named skin is a control skin with a SkinID property set. Named skins do not automatically apply to
controls by type. Instead, you explicitly apply a named skin to a control by setting the control's SkinID
property. Creating named skins allows you to set different skins for different instances of the same
control in an application.
You can define themes for a single Web application, or as global themes that can be used by all
applications on a Web server. After a theme is defined, it can be placed on individual pages using the
Theme or StyleSheetTheme attribute of the @Page directive, or it can be applied to all pages in an
application by setting the <pages> element in the application configuration (Web.config) file. If the
<pages> element is defined in the Machine.config file, the theme will apply to all pages in Web
applications on the server.
Templating
In addition to the theming mechanism, MonoX employs a powerful templating technology that allows
users to control all visual aspects of individual Web parts. Most of the default Web parts (list, menu,
news, RSS reader, search engine) are template-aware and can be easily customized this way.
Template folders also holds chrome and page templates that are not Web part specific.
The structure of the individual template folders is even more simpler than the structure of the
corresponding theme folders. They contain only the templates (plain old HTML or ASCX files with
specific placeholders) and images or any other accompanying resources. The list of the standard
template placeholders and a short template development tutorial can be found in the developer's
section 150 .
Default theme is used at a default portal and can be used as a template for all further customizations.
DefaultAdmin theme is used to control all visual aspects of the administrative pages and portal
elements.
Common theme is used across other themes. It contains smaller chunks of CSS and standard
images. It is never explicitly applied to portal pages.
Sample themes are used to demonstrate the flexibility of the theme/templating mechanism in MonoX.
They usually contain a minimum number of elements needed to apply a fully featured new theme to
the most frequently used pages and parts. We will be placing such themes into our Template Gallery.
1. Create a new master page with the page title of your choice. We will use the name MyMaster.
master.
2. Put the following markup in the header of your page:
4. put the HTML and ASP.NET markup INSIDE the content control.
5. you may add unlimited number of Web part zones in the ASP.NET code and fill them with Web
parts:
Creating a custom template page is very similar to the procedure described above.
1. Create a new ASPX page with the page title of your choice. We will use the name
MyTemplate.aspx. This page will use previously created MyMaster.master as the master page. Put it
in the PageTemplates folder of the currently active theme (~/MonoX/App_Templates/(Theme
Name)/PageTemplates/).
2. Put the following markup in the header of the page:
<%@ Page
Language="C#"
MasterPageFile="~/MonoX/MasterPages/MyMaster.master"
AutoEventWireup="true"
Inherits="MonoSoftware.MonoX.BasePage"
Theme="Default"
Title=""
%>
<%@ MasterType TypeName="MonoSoftware.MonoX.BaseMasterPage" %>
<%@ Register TagPrefix="MonoX" TagName="Editor" Src
="~/MonoX/ModuleGallery/MonoXHtmlEditor.ascx" %>
<%@ Register Assembly="MonoX" Namespace="MonoSoftware.MonoX" TagPrefix
="portal" %>
4. put the HTML and ASP.NET markup INSIDE the content control.
5. you may add unlimited number of Web part zones in the ASP.NET code and fill them with Web
parts:
6. you new template page will appear in the New page menu option of the Page management 47
administration pane and you will be able to dynamically create new pages based on it.
edit the header declaration of the page and change the MasterPageFile and Theme attributes:
<%@ Page
Language="C#"
AutoEventWireup="true"
MasterPageFile="~/MonoX/MasterPages/Default.master"
Theme="Default"
Inherits="MonoSoftware.MonoX.Pages.Default"
Title="MonoX - Portal Framework for ASP.NET"
Codebehind="Default.aspx.cs" %>
use the "Page properties" dialog (right click on the page in the Page management section). You will
be able to choose the theme name and enter the path to the master page that is to be used for the
selected page. Note that the portal engine will not allow you to enter the non-existing master page,
or master page that is not compatible with the selected content page (due to different number of
placeholders or any other errors).
X
Personalization
Personalization 126
10 Personalization
Personalization is an ASP.NET application service responsible for saving, retrieving and reapplying
data that represents customizations which have been made to controls on a Web page. This service
can be made available to the selected users (typically administrators), selected groups of users or
even all portal users.
The personalization service "knows" how to store the customization data for a page and then retrieve it
when a user requests the page again. When a page with saved personalization data is re-requested,
the personalization service fetches the data so the page can be recreated for the user making the
request. However, personalization cannot be used by itself. To use personalization, you must use
controls within a WebPartZone so they will have Web Parts functionality.
WebPartManager is the key component of the Web parts control set that is responsible for the most of
the advanced features built into the MonoX portal framework. It acts as the hub or control center of a
Web Parts application. There must be one - and only one - WebPartManager control instance on every
page that uses Web Parts controls. MonoX always includes a WebPartManager in one of the built-in
master pages (MonoX.master), so there is no need to add it manually to any of the pages that inherit
from the MonoSoftware.MonoX.BasePage.
Most of the MonoX application services are built upon the ASP.NET personalization system and
require personalization to recreate the state of web pages after user customizations have been
applied. Some of the actions that affect the personalization state of the portal and as such are saved
by the personalization system are:
Advanced topics related to this subject are covered in Microsoft's Web Parts Personalization Overview
.
Web Parts personalization is enabled by default, and authenticated users of a Web Parts page are
able to personalize pages for themselves without any special configuration. However, individual or
user-scoped personalization changes are visible only to the user who made them. If you want to
provide a selected user (such as a site manager) or users with the ability to make personalization
changes in shared scope so that the changes to a page are visible to all users, you must add a setting
to the Web site's configuration file.
Within the <system.web> section of the Web.config file, add an <authorization> section (if it doesn't
exists already), and within that, add an <allow> element to specify which user or users have access to
shared personalization scope. See below for an example - of course, you should assign a valid portal
user account, or a group account, to the users/roles attribute. The user or users specified will have the
ability to edit a page in shared personalization scope, so that the changes they make will be visible to
all users.
<authorization>
<allow verbs="enterSharedScope" users="SomeUserAccount" roles="admin" />
</authorization>
XI
Security
Security 129
11 Security
MonoX works in conjunction with IIS, the .NET Framework, and the underlying security services
provided by the operating system, to provide a range of authentication and authorization mechanisms.
It closely follows ASP.NET security models and best practices to deliver solutions based on widely
accepted standards. Listed below are the resources that present detailed discussions on security-
related topics:
ASP.NET Security Overview: flow of security with a request, configuration settings, authentication,
authorization, role-based security
Building Secure ASP.NET Applications: authentication, authorization, and secure communication
Security Practices: ASP.NET 2.0 Security Practices at a Glance: a set of consolidated practices
designed to address ASP.NET version 2.0 security issues. The answers and recommendations
presented in this module are designed to supplement the companion modules and additional
guidance.
From the administrator's point of view, MonoX allows users to create security roles and to assign users
to appropriate roles using the User management 53 and the Role management 55 administration
panes. Access roles can be set on a page level (using the Page management 47 pane), and/or a Web
part level (using the Web part verbs menu 31 ). Web part allows users to specify both view and edit
roles.
Developers can also use the functionality from the System.Web.Security namespace that contains
classes that are used to implement ASP.NET security in Web server applications. Additionally, MonoX
provides a set of helper methods in a SecurityHelper class, while both BasePage and BasePart
classes automatically perform basic security checks.
XII
Search engine optimization
Search engine optimization 131
ViewState oprimization: MonoX can completely remove the contents of the ViewState hidden form
field. It practically means that your page will be much "lighter" in terms of size and load times, as
ViewState hidden field can hold tens of kilobytes of data even in moderately complex applications.
All this is possible without loosing any of the ViewState-related functionality. Instead of the hidden
form field, the ViewState data can be stored in a database, file system, or session.
HTTP compression: each page or related resource can be compressed on the fly, reducing the
impact on the bandwidth and page load times. More details on both ViewState and HTTP
compression can be found in the section "Page optimization 18 ".
URL rewriting 15 is a well known Search Engine Optimization technique. The basic premise is that
clean URLs containing highly relevant keywords and without query string parameters will place your
pages much higher in search engine rankings.
SiteMaps generation: Sitemaps are an easy way for webmasters to inform search engines about
pages on their sites that are available for crawling. In its simplest form, a Sitemap is an XML file that
lists URLs for a site along with additional metadata about each URL (when it was last updated, how
often it usually changes, and how important it is, relative to other URLs in the site) so that search
engines can more intelligently crawl the site. MonoX comes with a ready-to-use HttpHandler for
sitemaps generation.
Automatic META keywords generation: switching the AutogenerateMetaKeywords tag to True
will cause MonoX to automatically generate META description tags for every page in the portal.
Integration with Google Analytics: setting the GoogleAnalyticsAccountNo tag to your Google
Analytics account number (or numbers, for multiple portal instances) will set up everything that is
needed to integrate your portal with Google Analytics
Compact and standards-compliant output: MonoX produces very compact and standards-compliant
HTML output which is favored by search engines.
Powerful administration and editing tools: you can perform SEO-related fine tuning interactively and
in real time.
XIII
Localization
Localization 133
13 Localization
All localization aspects are fully supported in MonoX due to its very flexible architecture. It is very easy
to localize portal contents, as well as all administration and support utilities. A single portal instance
can support unlimited number of localized sites, where each site has the same structure, but different
(localized) content.
Here is a screenshot of the MonoX home page in default (English) language. The URL for this page is
~/Default.aspx.
Here is what happens after the administrator changes the language in the administrative toolbar to
Croatian (the URL is ~/language/hr-HR/Default.aspx):
Note that everything is localized - from the administrative interface to the navigation links and HTML
editor's content. However, this is not where localization support ends in MonoX: portal administrators
are allowed to localize even the built-in texts without recompilation or any other additional tasks.
Note that all localized instances (other than the default instance) has URL's of the following format: ~/
After you have translated the resources you need to build the project and navigate to the localization
project's "bin" folder. Copy all files and subfolders (e.g. "en-US", "hr-HR", "tr-TR", "cs-CZ") to the
MonoX bin folder and overwrite all of the MonoX original localization folders.
Restart the IIS application pool and refresh the portal page to get new, translated resources.
Additionally, MonoX includes support for completely interactive localization that does not require
recompilation of the project, as all resources are stored in the database. This gives users more power
and flexibility, since it would be impossible to localize all resources at run time (both built-in and
custom ones) using only a "resx approach". It is possible to export values from database to resx files
and vice versa, both for a single page/control or for a whole portal at once. To start using this approach
you will have to change the default ResourceProviderModel in the web.config file and set it to
DBResourceManager. This will enable the Portal localization management utility (found under "Other
tasks" on the main administrative screen), that does the real job for all portal pages and controls. The
screenshot of this pane is presented below:
This pane allows administrators to localize each and every localizable resource in the portal. Note that
MonoX uses translation engines to suggest a correct translation for each text, as it can be seen in the
screenshot above.
Regardless of the active resource provider model, administrators can dynamically add or remove
languages from a list of supported portal languages in the Language manager administration section:
Note that it is possible to have only one default language. Pages in all other languages will have URLs
of the form ~/language/LocaleName/PageName.aspx. The "language" part of this URL is configurable
and can be changed - of course, you don't have to create a physical folder structure of this type for the
localization tasks, as MonoX URL rewriting engine will take care of everything. The format of the
localized URL is not fixed, and can be controlled by developing a custom localization handler - this task
requires implementing the ILocalizationHandler interface. You can always switch the active
language using the language dropdown in the administrative toolbar on top of each page.
It is important to understand the types of content that is held in resource files, as opposed to content
that is also language-dependant, but localized using other tools. For example, a localized version of
the site will initially have all administrative interfaces translated to the appropriate language. However,
text in HTML editor Web parts will initially hold default (English) versions, and you will be able to
change it using the familiar editing interface. Each localized site will hold its own version of the content.
The same hold for the navigation links, as each localized site can have totally independent navigation
hierarchy - you can create it in the Page management 47 administration section. Blogs, groups, and
other social networking resources are also language-aware, so you are expected to open a separate
blog (or multiple blogs) for each localization instance of the site.
XIV
Portal development
Portal development 137
14 Portal development
This is a second part of the MonoX user manual, describing the basic development tools and
techniques.
The accompanying MonoX API documentation will be your main reference for a complete description
of the API contained inside MonoSoftware.MonoX and related namespaces.
All advanced MonoX projects share a similar folder hierarchy, as shown below:
The MonoX folder holds most of the CMS files (except skins, templates, and DLL files which are
placed in App_Themes, App_Templates and bin folders). You should also include at least a default
ASPX page to the root folder, while all other pages may go to any other folder. Note that the URL
rewriter gives you the absolute control on how and where the files will be stored - the physical storage
paths very often do not map directly to the corresponding virtual paths due to better SEO rankings and
page organization issues.
Along with a code for several HTTP handlers, MonoX folder includes various system subfolders:
As it can be seen from the structure above, new versions of MonoX use the Web Application Project
(WAP), instead of the Web Site project (WSP) model. Although it introduced some controversy when it
initially appeared (in VS 2005), MonoX initially adopted the WSP model as it was the recommended
approach. It quickly turned out that WSP projects are suitable for Web developers building sites with
only a minor level of application functionality included, while the WAP model is more suitable for
application developers focusing on more complex applications. Build and deploy times in WSP
projects were incredibly long, so we adopted WAP model for all future versions.
Additionally, we strongly support the usage of Web Deployment projects add-in (VS 2005 and 2008
versions), that provide additional functionality to build and deploy Web sites and Web applications.
This add-in includes a tool to merge the assemblies created during ASP.NET pre-compilation, and
provides a comprehensive UI within Visual Studio to manage build configurations, merging, and using
pre-build and post-build tasks with MSBuild. In this way, MonoX can be easily integrated with
continuous integration servers like CruiseControl or other similar agile development tools.
MonoX custom solutions typically include three or more projects: main Web application project, Web
deployment project, and data access layer project(s) - LLBLGen typically includes two projects in the
adapter scenario, DAL and DALDBSpecific. Of course, this depends on the data access tool of your
choice, and any custom projects that you may want to include.
New portal pages are dynamically instantiated using the Page management 47 administrative pane.
This process works by copying the desired template page to the desired folder under the name given
to it by the user. Template pages are actually ordinary ASPX pages WITHOUT the accompanying
codebehind files. They usually inherit from the MonoSoftware.MonoX.BasePage class, but you can
create a different class file and use it if you need to implement some kind of codebehind functionality.
Here is a code sample for the default template page:
<%@ Page
Language="C#"
MasterPageFile="~/MonoX/MasterPages/Default.master"
AutoEventWireup="true"
Inherits="MonoSoftware.MonoX.BasePage"
Theme="Default"
Title=""
%>
<%@ MasterType TypeName="MonoSoftware.MonoX.BaseMasterPage" %>
<%@ Register TagPrefix="MonoX" TagName="Editor" Src
="~/MonoX/ModuleGallery/MonoXHtmlEditor.ascx" %>
<%@ Register Assembly="MonoX" Namespace="MonoSoftware.MonoX" TagPrefix
="portal" %>
Quite often you need to develop a "static" version of the portal page, without using the Page
management utility, as you would do in any other ASP.NET project. There are no special
considerations for this type of task: your new page should inherit from the MonoSoftware.MonoX.
BasePage class to get access to all security-related and similar functionality that is built-in into the
portal pages.
Additional information on creating template pages and custom master pages can be found in the first
part of this manual 122 .
Using the Web Parts control set, you as a developer can enable end users to:
Personalize page content. Users can add new Web Parts controls to a page, remove them, hide
them, or minimize them like ordinary windows. Users can also type-in textual content using a
standard editor interface, without any previous experience with HTML or other server-side tools and
technologies.
Personalize page layout. Users can drag a Web Parts control to a different zone on a page, or
change its appearance, properties, and behavior.
Export and import controls. Users can import or export Web Parts control settings for use in other
pages or sites, retaining the properties, appearance, and even the data in the controls. This reduces
data entry and configuration demands on end users.
Create connections. Users can establish connections between controls so that, for example, a chart
control could display a graph for the data in a stock ticker control. Users could personalize not only
the connection itself, but the appearance and details of how the chart control displays the data.
Manage and personalize part, page and site-level settings. Authorized users can configure settings
at all levels, determine who can access a site or page, set role-based access to controls, and so on.
For example, a user in an administrative role could set a Web Parts control to be shared by all
users, and prevent users who are not administrators from personalizing the shared control.
Note that you are not forced to "pack" all the functionality of your application in various Web parts. You
can still have parts of the business or presentation logic on each page or user control, business layer
code, or anywhere else. MonoX does not impose a specific development standard or practice, so may
get up to speed very quickly.
All Web parts in the MonoX framework inherit from MonoSoftware.MonoX.BasePart. If you want
to develop distributable, self-registering parts, you should inherit from a class that is higher in the
object hierarchy, MonoSoftware.MonoX.BaseAutoRegisterPart. Detailed code sample is
available in the next section.
Our "Hello world" Web part is"statically" hosted in the WebPartSample.aspx page (it is declared in the
header section of the page):
An alternative would be to use the auto-registration approach: the part would have to inherit from
MonoSoftware.MonoX.BaseAutoRegisterPart and be placed into the ~/MonoX/
ModuleGallery path or any other location that is listed in web.config's ModuleGalleryPath comma-
separated list of locations.
</ZoneTemplate>
</portal:PortalWebPartZone>
Again, a Web part can be included inline or statically (as in the example above), or dynamically (by
using the Web part catalog when page is in the catalog mode 37 and dragging the part to the required
Web part zone). Static approach is best suited for scenarios in which you don't plan to make significant
changes to the page look and functionality in the production environment. If you want to make your
parts and pages more personalizable, use the dynamic approach, as it will allow administrators to
change the look and feel of portal pages without recompilation. There are no changes in the markup
when dynamic approach is used: all customization and personalization changes are saved to the portal
data store.
Web part itself is basically a simple user (ascx) control. A user control in ASP.NET is a kind of
composite control that works much like an ASP.NET Web page—you can add existing Web server
controls and markup to a user control, and define properties and methods for the control. MonoX does
not require that a Web part control inherits from the base Web Part class: this would limit the usage of
Web parts only to the custom server controls, which are much more complex in terms of development
effort and experience. Instead of this apporach, MonoX enables you to use all existing server controls
as Web Parts controls in order to achieve maximum code reuse and to gain the benefits of Web parts
personalization. In contrast to this approach, MonoX requires that all Web parts inherit from the
MonoSoftware.MonoX.BasePart (or MonoSoftware.MonoX.BaseAutoRegisterPart if you
want to expose your parts via part catalog).
Below is a code from the ASCX file of the HelloWorld Web part:
<p>
Please enter your name: <asp:TextBox runat="server" ID="txtName" CssClass
="borderlessInput"></asp:TextBox> <asp:Button runat="server" ID="btnOk"
Text="OK" CssClass="SilverButton" OnClick="btnOk_Click" />
</p>
<p>
<asp:Label ID="lblGreeting" runat="server"></asp:Label>
</p>
using System;
using System.Web.UI.WebControls.WebParts;
namespace MonoSoftware.MonoX.Samples
{
public partial class HelloWorld : BaseAutoRegisterPart
{
private string _name;
[WebBrowsable(true), Personalizable(true)]
[WebDescription("Test property for the Web part sample with the
default editor for string properties.")]
[WebDisplayName("Web part name")]
public string Name
{
get { return _name; }
set { _name = value; }
}
HtmlEditorPart))]
[WebDescription("Test property for the Web part sample with the
custom editor.")]
[WebDisplayName("Please enter a story")]
public string Story
{
get { return _story; }
set { _story = value; }
}
if (string.IsNullOrEmpty(this.Story))
lblGreeting.Text += "<br />Please tell me a story by using
the Story property... Note that the HTML editor is used to edit this
property.";
else
lblGreeting.Text += string.Format("<br /><br />Here is your
story:<br />{0}", this.Story);
}
}
}
This part adds two properties to the properties defined in the BasePart class. You can indicate
wheter to show the specific property in the part's property grid (see description of the page edit mode
39 for more details) by setting the WebBrowsable attribute to true; setting the Personalizable
property to true indicates that a particular property on any Web parts control should be enabled for
personalization.
You will notice that the Story property is using a custom Editor control (HtmlEditorPart). String
properties are by default edited via ordinary ASP.NET text boxes. If you need to change this
functionality (for this or any other parameter type), you need a custom Editor. Here is the code for our
HTML Editor:
using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using Telerik.Web.UI;
namespace MonoSoftware.MonoX
{
/// <summary>
/// HTML editor part, used in part editor zones.
/// </summary>
public class HtmlEditorPart : WebControl, INamingContainer, IWebEditor
{
private RadEditor htmlEditor = new RadEditor();
/// <summary>
/// Constructor.
/// </summary>
public HtmlEditorPart()
{
htmlEditor.ToolsFile =
"~/MonoX/ModuleGallery/MonoXHtmlEditorSmallToolsFile.xml";
htmlEditor.Skin = "Vista";
htmlEditor.BackColor = System.Drawing.Color.White;
htmlEditor.ToolbarMode = EditorToolbarMode.Default;
}
/// <summary>
/// Gets controls.
/// </summary>
public override ControlCollection Controls
{
get
{
EnsureChildControls();
return base.Controls;
}
}
/// <summary>
/// Creates child control.
/// </summary>
protected override void CreateChildControls()
{
this.Controls.Clear();
this.Controls.Add(this.htmlEditor);
/// <summary>
/// Gets or sets sender control.
/// </summary>
public object Sender
{
get
{
return _sender;
}
set
{
_sender = value;
}
}
As it can be seen from this example, creating a new editor involves the instantiation of the desired
control and implementation of a few methods required by the IWebEditor interface.
Additionally, most of all our projects uses Repository model for storing and retrieving objects, and a
BusinessLayer that holds project business rules. As a rule, no data manipulation or complex
business rule interpretation should be performed on the page / part / user control. Thus there are
usually two more base classes, BaseRepository and BaseBLL.
Although they share same names and some similarities, MonoX repository model does not directly
follow the repository model from Domain Driven Design (DDD), which is defined as "set of methods for
retrieving domain objects should delegate to a specialized Repository object such that alternative
storage implementations may be easily interchanged". However, this approach allows for much greater
degree of encapsulation in your code (when compared with the "codebehind data access" approach)
and is generally recommended.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MonoSoftware.LLBLGen;
using SD.LLBLGen.Pro.ORMSupportClasses;
using MonoSoftware.MonoX;
using MyProject.DAL.DatabaseSpecific;
namespace MyProject.Repositories
{
public class BaseRepositoryMyProject : RepositoryExtender, IDisposable
{
#region Constructor
/// <summary>
/// Constructor.
/// </summary>
protected BaseRepositoryMyProject()
: base()
{
}
/// <summary>
/// Returns an instance of the repository class, wraps the
constructor to allow for encapsulated instantiation, so the logic in he
constructor can be changed without changing the client code.
/// Reference:
http://www.netobjectives.com/ezines/ez0405NetObj_PerspectivesOfUseVsCreatio
nInOODesign.pdf
/// </summary>
/// <returns>Instance of the base repository.</returns>
public static BaseRepositoryMyProject GetInstance()
{
return new BaseJobsMarketMyProject();
}
#endregion
#region Methods
/// <summary>
/// Creates the LLBLGen IDataAccessAdapter.
/// </summary>
/// <returns>LLBLGen IDataAccessAdapter</returns>
public override IDataAccessAdapter GetAdapter()
{
return CreateAdapter();
}
/// <summary>
/// Used to create database-independant LLBLGen DataAdapter.
/// </summary>
/// <returns>IDataAccessAdapter for project's DAL</returns>
private IDataAccessAdapter CreateAdapter()
{
IDataAccessAdapter toReturn = null;
try
{
toReturn = CreateAdapter(ApplicationSettings
.LocalSqlServer);
}
catch { }
return toReturn;
}
/// <summary>
/// Used to create database-independant LLBLGen DataAdapter.
/// </summary>
/// <param name="connectionString">Connection string to use</param>
/// <returns>IDataAccessAdapter for MonoX DAL</returns>
private IDataAccessAdapter CreateAdapter(string connectionString)
{
return new DataAccessAdapter(connectionString, false,
SD.LLBLGen.Pro.ORMSupportClasses.CatalogNameUsage.Clear, null);
}
#endregion
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MonoSoftware.MonoX.BusinessLayer;
namespace MyProject.Layers
{
public class BaseBLLMyProject : BaseMonoXBLL
{
protected BaseBLLMyProject()
: base()
{ }
}
}
LLBLGen Pro saves developers a lot of time, up to over 50% of a total project's development time, and
lets them focus on the real deal: business logic code, instead of having them hammer out an endless
list of almost the same routines. You design your database schema's with the abstract modeling tools
you always use (for example a NIAM/ORM designer like Visio, or an E/R modeler), and LLBLGen Pro
takes care of the rest. All you have to do next is modify some of the names LLBLGen Pro has given
entities and fields if necessary, and generate code.
LLBLGen Pro comes with a powerful, state-of-the-art user interface, which doesn't require an
expensive IDE to run.
Learning LLBLGen's concept and syntax is easy, although it is a quite different from default ADO.NET
and similar database access options. MonoX provide an additional wrapper around LLBLGen
functionality, called GenericEntityHelper, which is specialized for the most common data access tasks
in the Web/portal environment.
Of course, you don't have to use LLBLGen in your projects based on MonoX. All other database
access methods - ADO.NET, LINQ, you name it - are possible..
If a default, table-based rendering is required for your projects, you can selectively excluded some
controls from the CSS friendly control adapter rendering process. This is done by commenting out
sections of the CSSFriendlyAdapters.browser file in the App_Browsers folder. For example, there are
known issues that prevent proper functioning of the ASP.NET Login control when it uses CSS
adapters. The section below is commented out to apply default (table-based) rendering to all instances
of the Login control throughout the site.
<!--
<adapter controlType="System.Web.UI.WebControls.Login"
adapterType="CSSFriendly.LoginAdapter" />
-->
Please note that all changes will take effect only after the project is recompiled!
This section provides more information on how to change visual aspects of the working portal: themes
and skins, chrome and Web part templates.
Themes are made up of a set of elements: skins, cascading style sheets (CSS), images, and other
resources. To create a new portal theme, just copy the existing theme folder (~/App_Themes/
(Theme_Name)) to the new theme folder (~/App_Themes/(New_Theme_Name)). You can than modify
the skin and CSS files, images, or any other resources. New theme will become active instantly, you
just have to declare the theme name in the desired page header:
<%@ Page
Language="C#"
MasterPageFile="~/MonoX/MasterPages/Default.master"
AutoEventWireup="true"
CodeFile="MyPage.aspx.cs"
Inherits="MyPage"
EnableTheming="true"
Theme="Default"
%>
Note that a complete MonoX theme also includes templates 150 and master page(s) 109 . Please study
these topics to gain a complete understanding of the theming (skinning) process.
The Web Parts control set uses the WebPartChrome class to render the chrome for WebPart controls.
Additionally, this class provides a way for developers to customize the rendering of any individual
section (such as the header or footer) of the WebPart controls in a WebPartZoneBase zone without
having to handle all the rendering for those controls. For example, you can override the
CreateWebPartChromeStyle method to customize some specific style attributes applied to the
WebPartZoneBase zone, but you can rely on the default rendering to handle the rest. However, this
process is time consuming and error-prone; it also requires a solid knowledge of Web part framework
details. Some level of customization can be achieved using a declarative syntax and skin files in theme
folders; however, this is also not a very flexible approach.
MonoX provides a much easier mechanism for customizing Web part chromes. Chrome templates can
be used to format the appearance of all Web parts. The process is simple: just create a chrome
template file (with the .htm extension) and place it in the chrome template folder (~/App_Templates/
ThemeName/ChromeTemplates). You can alternatively place the chrome template code inline,
between the <ChromeTemplate> tags of the choosen PortalWebPartZone - this approach does not
allow for changing themes, and is therefore not used when this feature is required.
The content of a typical chrome template is very simple:
<div class="box">
<div id='<# WebPartDragSurfaceId #>' class="box_hed"><# WebPartTitle
#></div>
<div class="box_content">
<# WebPartBody #>
</div>
<div class="box_footer"><# WebPartVerbs #></div>
</div>
If you plan to use the Web part's Chrome Type property (available in code or in the part's Properties -
Appearance section of the administrative toolbar, and can be set to Default, Border only, None, Title
and border, Title only), you will have to use the following section tags:
<# header #><# /header #> marks the header/title section of a Web part.
<# border #><# /border #> marks the border area(s) of a Web part.
<# body #><# /body #> marks the body/content area of a Web part.
Instead of the rather rigid default implementation of Web part chromes in the ASP.NET 2.0, MonoX
allows you to use chromes wherever you want. Some Web portals are chrome-less, but administrators
need to have some sort of chrome to show at least Web part title and a verb menu. Other portals use
chromes with all Web parts. MonoX gives you a total control of this aspect; you can declaratively set
which chrome template to use and when to show it:
MonoX uses template-based Web part chromes out of the box. If you want to disable this functionality
and use the basic ASP.NET functionality, please set the UseTemplates property of the
PortalWebPartZone to false.
Specify the control-specific template subfolder and set the IsTemplated switch to true in the
constructor:
public RssReader()
{
...
ControlSpecificTemplateSubPath = "RssReaderTemplates";
IsTemplated = true;
...
}
This means that the portal will look for templates for this part in the ~/App_Templates/(Theme name)/
RssReaderTemplates folder.
The hashtable tags is used to hold a list of all part-specific tags with accompanying values that will be
rendered in the template. RenderTemplatedPart method is available in the BasePart class.
Save the template file in the specified folder. The default template for the RssReader (Default.htm)
part is very simple:
<div class="news_box">
<p class="newsTitle"><# Title #></p>
<p><# Description #></p>
<a href="<# Link #>" class="x">read more</a>
</div>
As you can see, you can produce unlimited number of such HTML templates and change the look and
feel of the templated Web part in seconds. Even faster way that works well for simpler templates is to
specify the templates inline, without an external HTML (or ascx) file, using the
CurrentTemplateHtml inner property:
Notes: you don't have to put all the tags in the template file, as shown above (PubDate tag is not
used). Also, <% TemplateImagefolder %> is supported by default in all templated Web parts.It
maps to the following path format: ~/App_Templates/ThemeName/
ControlSpecificTemplateSubPathName/TemplateNameImages - in our case that is ~/App_Templates/
Default/RssReaderTemplates/DefaultImages.
IMPORTANT: if you don't need all of the templating features as described above, you could still use
the "standard" ASP.NET templating mechanisms in MonoX Web parts via another "inner" property:
TemplatedControl. It allows you to access the repeatable control that is used to render the Web
part (it is actually a standard ASP.NET ListView control in the majority of built-in controls). All of the
Connections are based on a "pull" model of connectivity, where the consumer gets data from the
provider. To create a connection, a control acting as a data provider defines a communication contract
indicating the data it can provide. Another control, acting as the consumer and with knowledge of the
communication contract, retrieves that data.
The mechanism for establishing a connection is a special callback method: one in the consumer and
one in the provider. However, the Web parts control set handles all the callback and communication
details, so the steps required of developers are minimal. As a developer, if you want to use the
simplest approach, all you have to do is select a method in the provider to use as the callback method,
and mark it in the source code with a ConnectionProvider attribute. Then within that method, return the
interface instance containing the data to pass to the consumer. The interface instance can be very
simple (for example, a single property that contains a string value such as a postal code). A provider
can implement one of the provided interfaces (IWebPartField, IWebPartRow, or IWebPartTable), but
in most cases it is preferable to create a simple, custom interface with one or more properties or
methods containing the data you want to share with a consumer, and implement that interface in the
provider. The consumer's callback method retrieves the instance of the interface from the provider.
Again, all that is required of a developer is to identify which method in the consumer (using a
ConnectionConsumer attribute) will retrieve the interface instance, and assign it to some internal
variable for processing and rendering. Note that the data from the provider is passed during the pre-
rendering phase of the page and control cycle, so you should plan to process the data and update any
logic in the consumer after pre-rendering is complete.
MonoX includes a very simple example that can be used to learn how to develop and modify Web part
connections. It is available at the following URL: ~/MonoX/Samples/ConnectionSampleSample/
ConnectionSample.aspx. More details on its front-end is available in the connection mode section 38 .
RssUrlProvider Web part (placed in the same sample folder) provides a RSS URL that is consumed by
the RssConsumer Web part and used to fetch the RSS feeds from the specified URL.
="RssUrlProvider.ascx.cs" Inherits
="MonoSoftware.MonoX.Samples.RssUrlProvider" %>
RssUrlProvider.ascx.cs:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using MonoSoftware.MonoX;
namespace MonoSoftware.MonoX.Samples
{
public partial class RssUrlProvider : BasePart,
IStringConnectionInterface
{
[ConnectionProvider("Rss URL Provider", "Default connection")]
public IStringConnectionInterface GetProviderData()
{
return this;
}
#endregion
}
Here is our custom IStringConnectionInterface - it doesn't get much simpler that this...
using System;
using System.Collections.Generic;
using System.Text;
namespace MonoSoftware.MonoX
{
public interface IStringConnectionInterface
{
string StringParameter { get; }
}
}
RssConsumer.ascx contains code for a DataList used to render the RSS feed items:
RssConsumer.ascx.cs:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using MonoSoftware.MonoX;
namespace MonoSoftware.MonoX.Samples
{
public partial class RssConsumer : BasePart
{
private IStringConnectionInterface _providerData = null;
[ConnectionConsumer("RSS consumer")]
public void SetProviderData(IStringConnectionInterface
providerData)
{
this._providerData = providerData;
}
public RssConsumer()
{
CatalogIconImageUrl = "";
Description = MonoSoftware.MonoX.Resources.Controls.RssReader
.Description;
Title = MonoSoftware.MonoX.Resources.Controls.RssReader.Title;
TitleIconImageUrl = string.Empty;
TitleUrl = string.Empty;
}
DataTable dt = null;
foreach (DataTable tbl in ds.Tables)
{
if (tbl.TableName.ToLower() == "item")
dt = tbl;
}
if (dt == null)
return null;
Now you can develop the CustomAdminControl just as you would work with an ordinary ASP.NET
user control.
Implement the IRssWebPart interface. The implementation assumes only one public method that
returns a RssChannel class:
Apart from this, you should fill in the appropriate title and description in the RssChannel object and
attach a list of RssChannelItems to it (adding the RssChannel object to cache is highly
recommended):
{
newsItem.LocalizedNewsItem = (NewsItemLocalizationEntity)
LocalizationTextHandler.GetLocalizedObject(newsItem.NewsItemLocalizations,
NewsItemLocalizationFields.LanguageId);
<SearchEngine>
<providers>
<add name="PagesSearchProvider" type="
MonoSoftware.MonoX.SearchEngine.Providers.PagesSearchProvider, MonoX"
PagesDescriptionContentLenght="255" BoldSearchPhrases="true" FullTextSearch
="true"/>
<add name="NewsSearchProvider" type="
MonoSoftware.MonoX.SearchEngine.Providers.NewsSearchProvider, MonoX"
NewsReadPageName="~/NewsExample.aspx" NewsContentLenght="255"
BoldSearchPhrases="true"/>
</providers>
</SearchEngine>
Note that full text search can be initiated if the FullTextSearch parameter is set to true AND full text
indexes are created on the target tables in the MonoX database using SQL Server Management
studio.
Below is a full source code for the PagesSearchProvider. It implements the ISearchEngineProvider
interface with several public properties and a Search() method that returns a list of
ISearchEngineResultsItems. Note that this example uses LLBLGen Pro for all data access tasks; it is
not mandatory and you can use a data access tool of your choice.
using System;
using System.Collections.Generic;
using System.Text;
using MonoSoftware.MonoX;
using MonoSoftware.MonoX.Utilities;
using SD.LLBLGen.Pro.ORMSupportClasses;
using MonoSoftware.MonoX.DAL.DatabaseSpecific;
using MonoSoftware.MonoX.DAL.HelperClasses;
using MonoSoftware.MonoX.DAL.EntityClasses;
using MonoSoftware.MonoX.DAL.FactoryClasses;
using MonoSoftware.MonoX.DAL;
using MonoSoftware.MonoX.Repositories;
using System.Linq;
using MonoSoftware.Web;
namespace MonoSoftware.MonoX.SearchEngine.Providers
{
/// <summary>
/// Pages search provider - searches pages and document portal tables.
/// </summary>
public class PagesSearchProvider : ISearchEngineProvider
{
#region Fields
/// <summary>
/// Content of the description text for each search result items.
/// </summary>
public static readonly string PagesDescriptionContentLenght =
"PagesDescriptionContentLenght";
/// <summary>
/// Indicates if search phrases will be bolded in the search
results.
/// </summary>
public static readonly string BoldSearchPhrasesParam =
"BoldSearchPhrases";
/// <summary>
/// Indicates if the provider should use full text search (CONTAINS
operator) or "ordinary" search (LIKE parameter). Full text requires
creation of full text search catalog on the Document table and related
tables.
/// </summary>
public static readonly string FullTextSearchParam =
"FullTextSearch";
/// <summary>
/// Maximum number of results to return.
/// </summary>
public static readonly string MaxNoOfResults = "MaxNoOfResults";
#endregion
/// <summary>
/// Gets localized provider name.
/// </summary>
public string ProviderLocalizedTitle
{
get { return MonoSoftware.MonoX.Resources.Search
.PagesProviderTitle; }
}
private System.Collections.Specialized.NameValueCollection
_providerAttributes;
/// <summary>
/// Gets or sets provider attributes.
/// </summary>
public System.Collections.Specialized.NameValueCollection
ProviderAttributes
{
get
{
if (_providerAttributes == null)
_providerAttributes = new
System.Collections.Specialized.NameValueCollection();
return _providerAttributes;
}
set
{
_providerAttributes = value;
}
}
/// <summary>
/// Gets an entity collection of document/pages search results.
/// </summary>
/// <returns></returns>
public EntityCollection<DocumentEntity> GetResultCollection()
{
int maxNoOfResults = 1000;
if (ProviderAttributes[MaxNoOfResults] != null)
Int32.TryParse(ProviderAttributes[MaxNoOfResults], out
maxNoOfResults);
/// <summary>
/// Implementation of the search method. Searches through all
documents and returns only the pages that contain documents with the
requested search term.
/// </summary>
/// <returns>List of ISearchEngineResultItem</returns>
public List<ISearchEngineResultItem> Search()
{
EntityCollection<DocumentEntity> collection =
GetResultCollection();
List<ISearchEngineResultItem> results = new List<
ISearchEngineResultItem>();
List<Guid> resultPages = new List<Guid>();
foreach (DocumentEntity doc in collection)
{
//remove duplicate search results
if (resultPages.Contains(doc.Id)) continue;
//remove pages that user is not allowed to see
if (!IsAccessAllowed(doc.Page)) continue;
resultPages.Add(doc.PageId);
descriptionContentLen = Convert
.ToInt32(ProviderAttributes[PagesDescriptionContentLenght]);
if (ProviderAttributes[BoldSearchPhrasesParam] != null)
if (bool
.Parse(ProviderAttributes[BoldSearchPhrasesParam]))
SearchEngineCore.BoldSearchPhrases(SearchPhrase,
ref descriptionTxt);
item.Related = String.Empty;
item.Url = String.Empty;
results.Add(item);
}
return results;
}
/// <summary>
/// Checks if the user is allowed to see the page.
/// </summary>
/// <param name="page"></param>
/// <returns></returns>
private bool IsAccessAllowed(PageEntity page)
{
if (page != null && page.PageRoles != null &&
page.PageRoles.Count > 0)
{
foreach (PageRoleEntity role in page.PageRoles)
{
if (SecurityUtility.IsUserInRole(role.RoleId))
return true;
}
return false;
}
return true;
}
/// <summary>
/// Gets page search result template.
/// </summary>
/// <returns></returns>
public ISearchEngineResultTemplate GetTemplate()
{
MonoXSearchTemplate mTemplate = new MonoXSearchTemplate();
mTemplate.TemplateFileName = TemplateFileName;
return mTemplate;
}
#endregion
}
}
14.11 Caching
MonoX engine provides excellent performance and scalability for your applications. However,
sometimes you will need to squeeze out every bit of performance from your server, and no matter how
solid the base engine is, and how good your coding skills are, you may hit the machine limits.The
critical parts of your application will typically include database access and page rendering. To help you
deal with issues caused by situations that demand significant processor time or other resources,
MonoX provides a powerful caching infrastructure, that allows you to use a number of techniques to
store page output or application data across HTTP requests and reuse it. Thus, the server does not
have to recreate information on each subsequent request, saving time and resources.
To illustrate the importance of proper caching strategies in high availability applications, we performed
a series of tests using a very common server hardware: 4-core Intel Pentium III Xeon processor, 4Gb
RAM, 7200 SATA HDDs, 100 Mb NIC with Windows 2003 / IIS 6. SQL Server 2008 was installed on
the same machine. Note that numbers would be much higher on a more powerful hardware, not to
mention separating Web and database server and various Web farm configurations, but we were
trying to simulate a typical real-world hosting scenarios. The tests were performed using Microsoft's
WCAT performance testing tool, with a total of 500 virtual clients running on a separate client
machines.
Since different results will be achieved in different environments, we started by measuring the
response for 10 different static HTML pages taken from a demo MonoX site. Pages vary in size from
30-60 Kb - note that much larger throughput could be achieved with smaller pages, but again, we
wanted to simulate a standard scenario.
Transactions/sec
466.17
Pathlength/Transaction
569.63 kilocycles
Context Switches/Transaction
4.56
Requests/sec
466.17
Pathlength/Request
569.63 kilocycles
Context Switches/Request
4.56
% Processor Time
2.49
MBits/sec
94.39
As it can be seen, in this "ideal" scenario server was able to deliver a bit less than 500 requests per
second at only 2.5% CPU time. It could deliver much more on a faster network - the NIC was a
bottleneck in this scenario since it was fully saturated.
Transactions/sec
153.83
Pathlength/Transaction
54372.32 kilocycles
Context Switches/Transaction
37.13
Requests/sec
153.83
Pathlength/Request
54372.32 kilocycles
Context Switches/Request
37.13
% Processor Time
78.49
MBits/sec
27.02
Since demo sites uses moderately complex modules (blogs, groups, photo albums, friend lists) that
require interaction with database and powerful rendering capabilities, the effective number of requests
was cut down to one third of the starting number. Additionally, the CPU time spiked up to almost 80%.
Additionally, average time to first byte rised up to almost 3 seconds. This time we had enough
bandwidth, but the server was not able to push more than 150 transactions per second.
Transactions/sec
213.15
Pathlength/Transaction
34762.35 kilocycles
Context Switches/Transaction
32.13
Requests/sec
213.15
Pathlength/Request
34762.35 kilocycles
Context Switches/Request
32.13
% Processor Time
69.53
MBits/sec
30.01
For the purposes of this test all relevant Web parts were cached using MonoX partial caching feature -
their CacheDuration property was set to 600 seconds. Although there was a significant improvement in
performance at more than 210 requests per second, this number is still under 50% of requests served
in a "static" benchmark scenario.
Transactions/sec
470.12
Pathlength/Transaction
3651.38 kilocycles
Context Switches/Transaction
47.43
Requests/sec
470.12
Pathlength/Request
3651.38 kilocycles
Context Switches/Request
47.43
% Processor Time
16.11
MBits/sec
94.42
This test clearly illustrates the power of full page caching. The performance measured in transactions/
sec is identical to the static benchmark scenario, due to the fact that pages are served from fast output
cache and all of the page lifecycle events, database calls and other resource intensive operations are
executed only at the initial page hit. Once again, the network interface is fully saturated, and there is a
possibility of significant improvement by adding a faster NIC.
MonoX supports Web part (partial) and full (page output) caching scenarios. More information on ASP.
NET caching in general can be found at Microsoft's site. All general concepts apply to MonoX,
especially advanced concepts such as caching multiple versions of a page (VaryBy feature) and
dependencies (MonoX relies primarily on key dependency features).
Partial caching is suitable for more complex and personalizable pages, when there is a little use of
caching on a page level. It involves setting the CacheDuration property of a target part - note that the
cache duration is always expressed in seconds. If you want to programatically add your items to
cache, we recommend using the MonoX cache provider architecture, that allows you to plug in other
cache engines instead of standard ASP.NET cache (for example, Microsoft AppFabric, formerly
named Velocity), as illustrated in this pseudocode example:
Cache root key is used at the part level - all other parameters are appended to it, allowing you to
develop a hierarchy of cache objects.
As we saw in the tests above, full page caching is even more powerful performance-wise. It is set in
the page administration - page properties pane:
MonoX automatically invalidates the cached version of a page on POST requests. Administrators can
always track the caching status of the page in the administrative toolbar and force it to refresh if
needed:
Note that MonoX by default caches different versions of a page based on four criteria: user roles array,
raw URL, current application and language. This ensures that users in different roles (for example,
"ordinary" users and administrators) do not get the same version of the page. Additionally, each
physical page can hold multiple versions for different URL rewriting rules, applications and localization
settings.
Of course, you can add your own VaryBy criteria interactively (see the screenshot above) or using the
markup.
More advanced scenarios require the usage of dependencies: for example, blog page can be
invalidated from several external page (back end administration). To achieve this, we could use
something similar to the following code that is already present in the Blog.aspx:
if (this.CacheDuration > 0)
{
if (UrlParams.Blog.BlogSlug.HasValue)
this.CacheDependencyKeys =
GetPageCacheKey(MonoSoftware.MonoX.Repositories.BlogRepository
.CacheParamMonoXBlog, UrlParams.Blog.BlogSlug.Value);
}
Now when an external page needs to invalidate the cached copy of the page, all you have to do is:
this.InvalidateCacheKey(BlogRepository.CacheParamMonoXBlog,
post.Blog.Slug);
Note that by default caching is turned off for administrators - set the
EnablePageOutputCacheInAdminMode setting to true if you want to enable it.
Also note that VaryByCustom feature relies on overriding the GetVaryByCustomString(...)
method in Global.asax. If you are going to use the Global.asax functionality in your custom projects,
please create your Global.asax in the root of the application (it must inherit from MonoSoftware.
MonoX.Global) and remove the following files from the default installation, if present:
PrecompiledApp.config, bin/App_global.asax.compiled and bin/App_global.asax.dll.
XV
Resources
Resources 169
15 Resources
MonoX is built upon standard ASP.NET tools and techniques, so there are many additional resources
that will help you learn how to use it efficiently in the shortest amount of time. Listed below are just a
few excellent resources on ASP.NET and Web part programming. Please do not hesitate to contact us
if you need more information on these topics.
Books
ASP.NET 2.0 Web Parts in Action: Building Dynamic Web Portals (by Darren Neimke)
The Web Part Infrastructure Uncovered (by Teun Duynstee)
ASP.NET 2.0 Website Programming: Problem - Design - Solution (by Marco Bellinaso)
Professional Web Parts and Custom Controls with ASP.NET 2.0 (by Peter Vogel)
Articles
Webcasts
People
David Barkol
Teun Duynstee
Mike Harder
Scott Guthrie
Darren Neimke
XVI
Credits
Credits 171
16 Credits
MonoX project was partially funded by the European Union's PHARE programme.
Mono Ltd. wishes the acknowledge the usage of the following high-quality open source and third-party
software libraries:
XML-RPC.NET
DotNetOpenId
Apache log4net
Lucene.Net
LLBLGen Pro
RadControls for ASP.NET Ajax
SharpZipLib
Smart Thread Pool
NVelocity
Discussion 91
-E-
-A- Edit mode 39
Activity stream 90
Ad management 59
Ad Web part 71 -F-
Additional resources 169 File gallery 93
Administrative toolbar 35 File management 43
Amazon S3 management 47 File upload Web part 78
ASP.NET machine account 11 File view 94
Followers 95
-B- Forum 91
Friend list 95
Blog management 65
Blog Web parts 72
Browse mode 36 -G-
Built-in themes 120 Groups 96
Business rules 145
-C- -H-
Hello world Web part 141
Caching 163 HTML editor Web part 79
Captcha Web part 77
Catalog mode 37
Chrome 30 -I-
Chrome templates 149
Comments 91 Installation 11
Connect mode 38 Installation requirements 11
Contact form Web part 77 Installation wizard 12
Content versioning 41 Integration with third-party software 23
Creating new MonoX projects 138 Invitation list 99
Creating new portal pages 140
CSS adapters 148
Custom administration controls 157
-L-
Custom administration modules 67 Language changer Web part 81
Custom master pages 122 Licensing 26
Custom themes 149 List management 63
List Web part 81
Role management 55
Navigation menu 82
New users list 102
-T-
News management 55 Theme 118
News Web parts 83 Themes, templates, chromes 148
Newsletter management 64
-U-
-O- URL Rewriting 15
Offline editing 115 User management 53
User profile Web part 106
Page compression 18
Page management 47
-V-
Password recovery Web part 85 Verbs 30, 31
People search 102 Video player 94
Personalization 126 ViewState optimization 18
Personalization provider 23
Personalization scope 126
Photo gallery 102 -W-
Poll management 61
Wall 105
Poll Web part 86
Web part basics 70
Portal administration 43
Web part connections 152
Portal development 137
Web part framework 8
Portal views 35
Web part menu 30, 31
Provider model 23
Web part templates 150
Web parts 8
-R- Web.config settings 15
Windows Live Writer 115
Repositories 145