Posts in Category: Development

mojoPortal Gets A Little Microformat Oomph

Just integrated Oomph, a javascript Microformat Overlay into mojoPortal. You can watch the PDC presentation about Oomph from this page https://sessions.microsoftpdc.com/public/timeline.aspx, click Day 3 then click Oomph and you can see the video links at the bottom.

Microformats are a way of marking up information in html using some agreed upon conventions that add semantic meaning to the markup. For example hcard, is a format for marking up contact information. What Oomph does is recognize the hcards and hcalendar items in your page and creates a javascript widget in the top left of the page that gives you some neat options for adding contact to your Yahoo Contacts, adding events to your googe calendar, showing event and contact locations on a map using Virtual Earth, etc. Pretty neat stuff. You can see it in action on our consulting list, where I've marked up the content using hcard format. The list view feature of our Event Calendar Pro add on product also renders in hcalendar format so events can show up in the oomph widget. I've shrunk my browser window down a bit to make a screen shot of the widget below but for best impressions try it yourself.

oomph screen shot

Other Developments

I always like to dogfood new features here on mojoPortal.com to work out any issues, so this site is runnning the very latest code from my sandbox.

At the moment I'm also testing some performance optimizations that I just integrated into mojoPortal. As we start to do more ajaxy javascript things in mojoPortal we find ourselves adding a lot of links to javascript files which adds additional http requests to our page. So I've integrated some work by Omar Al Zabir, that he has made available in the very cool Dropthings project. This combines most of our javascript files into one request and moves the javascript to the bottom of the page to improve performance.

A similar issue exists for css files in the skin. We like to organize css into separate files based on logical things from a development perspective, but from a performance perspective we'd like to have only one link to an external css file. I implemented a solution for css files based on some of the techniques I learned from Omar's work. It combines all the css files and minifies them as well using Michael Ash's C# implementation of the YUI Compressor. So far it seems to be working great and I haven't noticed any side effects or problems.

These new feature is only in my sandbox at the moment but will be in svn trunk within a few days.

UPDATE 2008-11-03

Just discovered that moving the javascript to the bottom broke usage of NeatHtml in the forums. Luckily I have Web.config setting to disable the javascript combiner so I have fixed it on this site while I investigate a solution. There is an option that Omar implemented to add a "pin" attribute to any script that you don't want to combine or move to the bottom. The problem is I don't believe that is a valid attribute and it will break xhtml validation to use it, so I will have to find another solution.

UPDATE 2008-11-04

I managed to get a solution to pin some scripts without breaking xhtml validation, so now on this site I'm testing combined scripts again and so far so good.

Gravatar Joe Audette is the founder of the mojoPortal project and was the primary developer until February 2017.

Hello World mojoPortal Quick Start Code

Just completed a new documentation page to help developers get going quickly with mojoPortal.

Hello World - Developer Quick Start

The article has a zip with sample code you can drop in and start hacking on with a few simple steps as indicated in the article. It shows how you can use a plain old UserControl or a UserControl that inherits from SiteModuleControl. Both examples also illustrate the use of the ASP.NET UpdatePanel for ajax postbacks.

Enjoy!

Gravatar Joe Audette is the founder of the mojoPortal project and was the primary developer until February 2017.

Lowering Entry Point Barriers for Developers

I'm always interested to hear developer opinions about mojoPortal. I don't always agree with them, but I try to keep an open mind and see their perspective. So I monitor the blogosphere with google alerts, so that if anyone mentions mojoPortal in their blog I get an email alert with a link. It doesn't catch everything and more often than not I just get alerts about my own blog posts, but now and then something of interest appears.

So I got an alert about this blog post by Artem Smirnov where he complained about having to inherit from a base class to make a mojoPortal plug in. He wishes he could just use a plain old UserControl and he does not want to have to create any configuration file to install it.

mojoPortal provides a base class, SiteModuleControl which "is a" UserControl that contains some additional functionality that allows you to make multi instance features. Like a blog for example, in mojoPortal you can put an instance of the blog feature on one page and another instance on another page and these are totally separate instances with different content. This is the way most of the features in mojoPortal work and SiteModuleControl provides the instance specific properties and settings that enable easy development of features that support multiple intances.

But maybe sometimes you don't need your feature to support multiple instances and would rather just use a plain old UserControl. This is the valid point I took from Artem's post. And since SiteModuleControl "is a" UserControl and plugs in the same way you plug in a UserControl, I thought, why not make it possible to use a plain old UserControl if you want to. Its a very simple code change to support it, the only thing we do differently if the UserControl is a SiteModuleControl is set a few properties on it, if its just a plain UserControl we skip that step.

Control c = Page.LoadControl(module.ControlSource);
if (c == null) { continue; }

if (c is SiteModuleControl)
{
SiteModuleControl siteModule = c as SiteModuleControl;

siteModule.SiteId = siteSettings.SiteId;
siteModule.ModuleConfiguration = module;
parent.Controls.Add(siteModule);
}
else if(c is UserControl)
{
parent.Controls.Add(c);
}

This change is in svn trunk now. I would also like to mention that you can easily install a SiteModuleControl or a UserControl right from the Web UI, you don't have to create configuration files to install it though there is a system for it and it is recommended if you will be packaging your feature for installation on other machines. The place where you can install it from the UI is under Administration Menu > Advanced Tools > Feature Installation

So, it is now possible to use a plain old UserControl if you want to. If you need to support multiple instances of your feature like we do for most of the mojoPortal features then you should inherit your UserControl from SiteModuleControl and follow the guidelines for feature development.

Gravatar Joe Audette is the founder of the mojoPortal project and was the primary developer until February 2017.

A Custom AdRotator - Borrowing Code from The Mono Project

Sometimes in ASP.NET development you need just a little different functionality than what the built in controls have. Often you can inherit the control and extend functionality on top of the original version, but sometimes you wish you could just make a small change to the inner workings of the control. One option is to borrow the Mono implementation and modify it to meet your needs.

So today I wanted to implement an Ad Rotator so I could alternate the banner ad on mojoPortal.com to switch between my add for Event Calendar Pro and Form Wizard Pro. There is a built in AdRotator control in ASP.NET, so I read a few articles about it, here and here. In those articles they suggest click tracking by using a redirect page, but I wanted to track it in google Analytics since we already have it integrated in mojoPortal. To do this I need to add an onclick to the rendered link to call the tracking code and then navigate to the href. So an example onclick for tracking is like this:

onclick="mojoPageTracker._trackPageview('/EventCalendarProBanner.aspx');window.open(this.href,'_self');return false;"

This just tracks a made up url (/EventCalendarProBanner.aspx) before navigating to the linked product page.

The ASP.NET AdRotator control can consume an xml file in this format:

<?xml version="1.0" encoding="utf-8" ?>
<Advertisements>
<Ad>
<ImageUrl>~/images/Contoso_ad.gif</ImageUrl>
<NavigateUrl>http://www.contoso.com</NavigateUrl>
<AlternateText>Ad for Contoso.com</AlternateText>
</Ad>
<Ad>
<ImageUrl>~/images/ASPNET_ad.gif</ImageUrl>
<NavigateUrl>http://www.asp.net</NavigateUrl>
<AlternateText>Ad for ASP.NET Web site</AlternateText>
</Ad>
</Advertisements>
 

But I wanted to add another property to store my OnClick code, so my new format is like this:

<?xml version="1.0" encoding="utf-8" ?>
<Advertisements>
<Ad>
<ImageUrl>~/Data/Sites/1/skins/mojosite-brightside/eventcalpro-banner.gif</ImageUrl>
<NavigateUrl>~/event-calendar-pro-offer.aspx</NavigateUrl>
<AlternateText>A better event calendar for mojoportal</AlternateText>
<OnClientClick>mojoPageTracker._trackPageview('/EventCalendarProBanner.aspx');window.open(this.href,'_self');return false;</OnClientClick>
</Ad>
<Ad>
<ImageUrl>~/Data/Sites/1/skins/mojosite-brightside/formwizardpro-leaderboard.gif</ImageUrl>
<NavigateUrl>~/form-wizard-pro-single-installation-license-offer.aspx</NavigateUrl>
<AlternateText>Form Wizard Pro - Easy Forms for mojoPortal</AlternateText>
<OnClientClick>mojoPageTracker._trackPageview('/FormWizardProBanner.aspx');window.open(this.href,'_self');return false;</OnClientClick>
</Ad>
</Advertisements>

Since I don't really have access to the internal workings of the ASP.NET AdRotator, I decided to have a look at the source code for the Mono project implementation of this control. I downloaded the 3 files AdRotator.cs, AdCreatedEventArgs.cs, and AdCreatedEventHandler.cs, added them into my mojoPortal.Web.Controls project and changed the namespace so it wouldn't clash with the built in ASP.NET version. I had to modify a few small things where it was using some internal Mono stuff but not much. I added the OnClientClick property to AdCreatedEventArgs.cs and added on line of code to the render method of AdRotator.cs:

if (e.OnClientClick != null && e.OnClientClick.Length > 0)
w.AddAttribute(HtmlTextWriterAttribute.Onclick, e.OnClientClick);

I add it to my layout.master (Master Page) and configure it to read the xml file with my ads:

<mp:AdRotator id="ads1" runat="server" AdvertisementFile="~/App_Data/mojoads.ads" />

And voila, it works and only took about 20 minutes to implement.

 

Gravatar Joe Audette is the founder of the mojoPortal project and was the primary developer until February 2017.

ZedGraph - Easy Web Charts

Everybody likes charts, a picture tells a thousand words they say, and I'm no different, I like them too. I've had my eye on the ZedGraph project for several years and have been including their dlls with mojoPortal for a long time with the intention of using ZedGraph in mojoPortal. I don't know why it took me so long to actually use it, but I finally implemented a chart in the Site Statistics feature of mojoPortal to show the trend of site registrations. I suppose it might have taken me so long to get around to this partly because charts are not that useful unless you have a significant amount of data. This year I have definitely noticed an increasing rate of people registering on mojoPortal.com, so I thought I would like to see this on a chart. ZedGraph is so easy! It took me maybe 30 minutes total to figure out how to create my first chart. Now I'm all excited to use it in a lot of places like sales reports for the web store feature and other interesting metrics. Maybe could produce pie charts of survey results, not for text questions but for ones that have choices we could show pie charts of how many people picked the various choices. Anyway, lots of ideas where to use it!

You can see the live version of this chart on our community page:

community growth chart

Now for me this chart is very meaningful because I can see that site registration started rising after the august 2007 release of mojoPortal that included support for OpenID and Windows Live ID, having those options makes it easy for a lot of people to register becuase they don't have to have any new passwords. That rise also was probably due to the 2007 CMS Awards. Then the big increase in the trend started when I went on a mojoPortal Beautification Campaign and made about 20 new good looking skins from April 2008 to May 2008. mojoPortal.com got a makeover with a new skin in May 2008 as well. In any case, its a positive trend showing an order of magnitude in growth. I sure hope it keeps going up! We have at least another order of magnitude to go to catch up with DotNetNuke. Where we are currently getting about 250 new members per month, they get more than that per day. So I look to them to see how high it could go.  They have a lot more visibility due to all the support they have from Microsoft, and they take a more agressive approach to aquiring members by requiring site registration in order to download. I don't plan to change our approach, registration is not required to download mojoPortal, but registration is required to get support in the forums. I am looking at ways to increase our visibility in the Microsoft ecosystem. Hopefully we will be able to move to CodePlex soon for our source code and file hosting. The Codeplex Team is working on some fixes to their svn bridge that should make it possible for us to move there. I think that move will give us a lot more visibility in the .NET community.

Don't Forget Voting for the 2008 CMS Awards ends October 20

So if you haven't already please vote for mojoPortal!

vote for mojoportal in the 2008 cms awards

 

Gravatar Joe Audette is the founder of the mojoPortal project and was the primary developer until February 2017.