Skip Navigation Links / Posts / Posts By Category

Posts for Category: SUB V2 Features

Feed for this Category
Daily Links

How many cool websites do you visit on any given day?  I'll bet that there must be some amazing sites and web pages that people visit on any given day that just go un-remembered and un-shared.  Not any more!  Today I added a new feature to my blog called "Daily Links" which allows me to arbitrarily add cool or interesting links via an administrative web part and have them appear on an RSS feed.  You can subscribe to the feed here:

    http://markitup.com/DailyLinksRss.ashx

This idea was originally an SUBV2 feature suggestion by Howard Van Rooijen as you can see in this comment:

    http://markitup.com/Posts/Post.aspx?postId=622ac040-d459-40dc-a66d-5478bbe2db8a#94085f1b-853d-4d1e-b1be-37f2ecc23448

I think that it would be great if this took off and we all started blogging our most interesting "visited links"; I think that this will turn up some real gems!

Thanks Howard :-)

posted on 3/20/2006 5:37:38 PM ( 5 Comments )


New version of SUB

I'm currently right in the middle of preparing a new release of SUB and I should have the source code up on ProjectDistributor later tonight.  If you are running an existing build of SUB remember from yesterdays post that the XML index files that used to live in the \data folder now live in the \App_Data folder although all of the post content folders still live under the old \data path.

I just wanted to mention three of the new features that I've added in this release that I'm real happy with.

1) Posts Archive Web Part

If you look on my website you will notice that, on the left side of the page there is now a web part that lists each month and shows how many posts exist for the month.  Clicking on a month takes you to a new page which displays the entries for that month.

2) OPML Web Part

Take a look at the following image:

OPML Web Part

 

This is a web part that allows you to specify the URL of an OPML feed and an optional path to an XSLT and then displays a list of all of the bloggers on the OPML.

 

3) Catalog Dialog

Take a look at the following image:

Catalog Dialog

The pop-up window that you can see with three tabs is called the CatalogDialog.  Basically, this is a Catalog Gallery that reads a list of web parts from an XML configuration file and displays them within a category.  You launch the CatalogDialog by clicking a button which is rendered at the head of each WebPartZone if you are authenticated.  When you click on one of the web part links in the CatalogDialog that web part is added to the zone in the main window that you launched the CatalogDialog from. 

Because this feature reads from an XML configuration file you can easily upload assemblies that contain web parts and then add a configuration entry to have web parts that are in the assembly that you uploaded appear within the catalog.  This makes it extremely easy to add your own web parts without having to redeploy the site. 

I created the CatalogDialog for the WebParts book that I'm currently writing and which will be finished next month!

 

posted on 3/1/2006 2:31:19 AM ( 0 Comments )


SUB V2 - First Release

OK, so I've just uploaded the source code for this blog (SUB V2) to ProjectDistributor.  To download it go here:

     http://projectdistributor.net/Projects/Project.aspx?projectId=182

The biggest features in this release are that the blog uses MasterPages, Themes, and has a pretty cool WebPart framework which is coming into shape.

To run the blog just open the solution file and do a build.  You also need to configure a database to use the ASPNET SQL Server tables because this version uses Profile to store some user information.

Aside from using the major new ASP.NET 2.0 features such Themes, MaserPages, WebPart, Profile etc, and the new runtime feature - Generics - it's a parity release with the ASP.NET 1.1 version of SingleUserBlog.  Here is a screenshot of the features that will appear in the next version (Iteration 1) of the software:

SUB V2 features that are coming soon

posted on 1/27/2006 7:13:09 PM ( 0 Comments )


Displaying dates and times in a local users time zone

Yesterdy I wrote about the TimeZones web service that I've added to this site and today I'll further explain the need for the web service.  To start, let's take a look at the problem of dates and break it into 2 segments: The date value and the format of the date value.

Formatting a culture aware date.

Let's say that you are from the US and you visit my site.  On reading an article (and after sighing that this guy doesn't know what he's talking about) you notice that the time that page says that the article was written on 18/1/2006.  Hrmm, you think to yourself... what is the 18th month again?  This is of course because in the US, dates are formatted as mm/dd/yyyy whereas in Australia here they are formatted as dd/mm/yyyy.

The answer to fixing the formatting of dates is thankfully quite simple.  Rather than formatting the date for a specific culture you can dynamically read the culture for the current user from the accept-languages array that is passed along with the head section of the request.  To do this you simply set the culture of the current thread when the request begins and then delegate all of the formatting of dates and number strings to the framework - in other words, it just works!  Here's the code that you can place in your application's BeginRequest method to achieve this outcome:

void Application_BeginRequest(Object sender, EventArgs e) {
    try {
        if (Request.UserLanguages.Length > 0) {
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(Request.UserLanguages[0]);
        }
    } catch (Exception ex) {
        PublishException(ex);
    }
}


SUB has that code in its startup so go ahead and try it out.  In Internet Explorer open up Tools | Options and choose "Languages" from the General tab.  In there you can add language or change the order of your language preferences.  Change it by adding Arabic or Chinese as your first preference and refresh the browser to see how the dates for this article are formatted.


Setting the correct date value

OK, so formatting culture aware dates is a breeze.  Just a couple of lines of code.  But what about storing the value that is used?  That's somewhat harder.  Here's a scenario:

Your website is hosted on a webserver that is located on the west coast of the US and you are currently living in Australia.  You use the web interface that is supplied with your blogging software to add a new article at 8:00am Australian time which is about 1:00pm Pacific time.  A time difference of 19 hours.

The next week, the people hosting your website move to Greenland and so when you post your next article - again at 8:00am Australian time, the time on the server is now 6:00pm on the previous day.  A time difference of 14 hours.

Finally, daylight time ends in Australia and you post another article at 8:00am Australian time which is now 7:00pm in Greenland.  A difference of 13 hours.

So how would you write a single piece of code that would always know to display the published times of your articles in Australian time?  One way would be to use javascript on the client and pass through the clients time to the server and use that.  It would work but it's cumbersome.

The better way - and the way that it is done for SUB - is to immediately store all dates in UTC time at the time that they are entered.  Working out the current UTC time is a no brainer:


     currentArticle.DateCreated = DateTime.UTCNow ;
     currentArticle.Modified = DateTime.UTCNow ;

The reason for storing the dates in UTC time is that it's easy to work with because every country already has a pre-existing way of defnining an offset from that time to work back to their own local time - the timezone difference.

Now that the time is stored as UTC time it can simply be converted to the local time of a given time zone as soon as it is reloaded from storage.  In the case of SUB the logic for doing that looks like this:


DateTime dt1 = DateTime.Parse(node.Attributes["dateCreated"].Value);
DateTime dt2 = DateTime.Parse(node.Attributes["dateModified"].Value);               
               
TimeZoneInformation info = TimeZoneInformation.FromName(
    BlogConfigurationSettings.TimeZoneName
    );


DateTime utc1 = info.FromUniversalTime(dt1);
DateTime utc2 = info.FromUniversalTime(dt2);

this.DateCreated = utc1;
this.DateModified = utc2;


See that the UTC times are pulled from the XML storage and then the TimeZoneInformation class is spun up for the time zone that the blog has been configured to use.  Then, using that class (which itself uses the underlying Windows API's) the UTC time can easily be converted to the timezone that the blog has been configured to use.

When the data is stuffed back into storage - such as when it is edited - the TimeZoneInformation class is again used to convert the local time back to UTC time as shown in the next snippet:


TimeZoneInformation info = TimeZoneInformation.FromName(
    BlogConfigurationSettings.TimeZoneName
    );

DateTime utc1 = info.ToUniversalTime(this.DateCreated);
DateTime utc2 = info.ToUniversalTime(this.DateModified);


attr = node.OwnerDocument.CreateAttribute("dateCreated");
attr.Value = FormatDateTime(utc1);
node.Attributes.Append(attr);

attr = node.OwnerDocument.CreateAttribute("dateModified");
attr.Value = FormatDateTime(utc2);
node.Attributes.Append(attr);

So when you read this article and you see that it was posted on 19/01/2006 at 8:19:10 AM (if your browser language is Australian anyway) you will know that I wrote it on the morning of the 19th January and not at 1:00am on the morning of the 20th January as would be the case if I was using the server times to store dates.

posted on 1/19/2006 6:21:58 PM ( 0 Comments )


Time Zone Web Service

I was chatting with Paul Stovell yesterday about SUB and he asked for a specific feature to do with having posts and comments displayed in his current time zone and not the time zone of the web server.  Specifically he asked:


Well, if you look at my site, it's got the time underneath the post - monday, 7:32pm... that's because it's stored in american time again... but I think even with SUB2 if you store them as universal times, they will be displayed again as american time (ie 10 hours behind)... could you have a Display Timezone or something?


Paul's right.  Even if I stored the dates as UTC format, when I got them back out and converted them based on the current time zone they would appear in US date times again.  When we first started to think about solving this problem it seemed simple: create a config setting that allows the admin to enter the UTC offset for the blog and then all DateCreated and DateModified times will use that.  The steps would be:

  • store all dates as UTC values
  • when re-loading dates calculate the difference between the offset and the server GMT offset
  • apply that difference to the UTC time

Something that simple would be great and easy to implement - except for daylight time adjustments.  To implement the daylight adjustments would mean that the user would have to enter a value for:

  • UTC Offset
  • Daylight adjustment minutes
  • Daylight start date
  • Daylight end date

It'd all be so much easier if the TimeZone class in the Framework exposed this information.  Luckily for me somebody had already gone to the trouble of exposing this information via API calls and made their code available via this CodeProject article:

    http://www.codeproject.com/dotnet/WorldClock.asp

I very hastily downloaded the code and hacked away at a few prototypes.  As you can see from the CodeProject article I also tacked on a couple of useful helper properties to help work out whether a current time zone is experiencing daylight time or not.

SUBV2 now uses this logic to store dates in UTC format and convert them to the blog owner's time before they are displayed on the site.

I've also exposed the some of the TimeZone logic via web services on this site.  You can go here to test them out:

     http://MarkItUp.com/WebServices/TimeZones.asmx

Feel free to play around with them but if you'd like to reference them from an application be sure to contact me first so that I can advise you of any changes or if I plan to move them to a new location.  Over time I'll probably issue keys to access the service so that I can formally keep track of who is using them.  If you want to try it out you'll have to hit this method first to get a list of the time zone names so that you can pass them to the other methods:

     http://markitup.com/WebServices/TimeZones.asmx?op=GetTimeZoneNames

 

posted on 1/19/2006 12:29:51 AM ( 10 Comments )


This blog is now running SUBV2

If this message has popped into your aggregator then I've most certainly done something right because today I changed my blog over to a brand new version of my SingleUserBlog blogging application which I affectionately refer to as SUBV2.  SUBV2 is a significant jump from the previous version in that it's built using ASP.NET 2.0.

Built using ASP.NET 2.0

Running on top of ASP.NET 2.0 has allowed me to introduce some extremely advanced features while possibly reducing the overall size of the codebase.  Some of the new features include MasterPages and Themes which are used to give the site its look and feel.  Another of the significant changes that have come through using ASP.NET 2.0 are Web Parts and Personalization.  By using these "portal" features I have been able to implement almost all of the content that is visible on this page by using web parts.  To get a feel for how web parts are used on this page, consider the following:

  • The Hosted By Orcsweb image is a web part
  • The Google Search Form is a web part
  • The Posting Categories list is a web part
  • Each of the Link Categories on the right are web parts
  • The Recent Posts listing is a web part
  • The Horizontal Rule just above the Recent Posts is a web part

As you can see, the web parts that are included with SUBV2 are a mixture of application web parts (Posting Categories and Recent Posts) as well as functional web parts that allow me to add any arbitrary image, link, or even HTML to the page at will.  The power of web parts is that they can easily be personalized at runtime.  This means that I can move any of the web parts around by simply dragging them with my mouse and placing them to almost anywhere on the page.  I can also add new web parts too.  As an example, I could easily add a new HTML web part that displayed a welcome message to visitors of my blog and place it at the top of each page on the site.  I could even add my own CSS or Javascript too!

Advanced Portal Framework Features

In addition to the "out-of-the-box" web part features, this blog also uses some pretty advanced portal customizations - such as a CatalogZone that is displayed in a pop-up dialog (ala Sharepoint V3).  The popup CatalogZone will be used to display web parts that are housed in custom web service galleries.
 
The blog also features:

  • Custom WebPartManager to implement common authorization filter logic
  • Custom EditorZone to display editor parts in expandible/collapsible regions
  • Custom WebPartZones to perform custom rendering on web part chrome and to add custom zone verbs to web parts
  • Custom PersonalizationProvider so that all personalization is stored against a common key (not the page url) so that changes made to a web part are applied right across the portal site


Migrating my content

Migrating the content from the previous version of my blog was simple and took me less than twenty minutes.  To migrate the content I opened the administration section of the previous version and saved the blog to BlogML format; then I opened the administration section of this version and imported it.  That's the power of BlogML!  The content that migrated included all of my internal links, attachments and images - so no content was lost at all.

Making SUBV2 publicly available

Over the weekend Paul Stovell - who is currently running SUBV1 for his blog - will be migrating that blog over to use SUBV2.  During that migration he will write a blog article that explains the steps that are involved in setting up SUBV2 and customizing it with your own MasterPage and Theme.  When he has posted that article I'll upload the source code for SUBV2 to ProjectDistributor so that it is publicly available.  In addition to Paul's article I'll be posting some tutorials to my blog that explain some of the features that are there.

Over time I'm hoping to build a small community around SUBV2 so that we can share Themes and WebParts.

posted on 1/14/2006 3:40:40 PM ( 2 Comments )