Main

June 17, 2004

Inventory of changes made to 2004/06/19 dasBlog codebase

As a first step to merging some of the changes I’ve made back into the common source code, here’s an inventory of all the changes made.

I’m looking for authorization and opinions on how and how much of this to merge back.

These changes can be seen at this site.

 I attempted to use the GDN interface to send a message to the workspace owner. It seemed to hang and there was no confirmation, so I’m posting the information and sending it to Clemens by e-mail.

For anyone who’s interested, here’s a zip of the changed files, and here’s a zip of the originals.

Inventory of dasBlog source code changes:

 File

Change

BlogDataService.cs

Added 3 methods to interface and implementation class.

Part of bug fix for month containing off-by-one-day posts.

CategoryCacheEntry.cs

Splits categories on comma instead of pipe. Could split on pipe if its there, and comma if not.

DayEntry.cs

Added public bool MayContain(DateTime startUtc, DateTime endUtc)

Returns true if this DayEntry may contain an entry in the UTC time interval from startUtc to endUtc.

Entry.cs

Added atomId field, public AtomId property, IsCategory method, IsLanguage method, InitializeEntryId method, and InitializeAtomId method.

EntryBase.cs

Changed value for EntryId set by Initialize from just guid to string.Format(@"{0:yyyy\/MM\/dd}/{1}", CreatedUtc, Guid.NewGuid().ToString());

This supports the readable-URL mapping implementation. After default initialization, additional code changes call InitializeAtomId and InitializeEntryId once a Title is set and before an entry is first saved, which locks in its permanent id.

TimeZone.cs

Added a FormatAdjustedUniversalTime overload and reimplemented the original in terms of the new overload which accepts a string.Format style format string to format the whole thing (DateTime, time zone name, time zone sign, time zone hour, time zone minutes).

ActivityBox.ascx.cs

AggBugs.aspx.cs         

ClickThroughs.aspx.cs

Commentview.aspx.cs

CrosspostReferrers.aspx.cs

DeleteCommentBox.ascx.cs

DeleteEntryBox.ascx.cs

EditBlogRollBox.ascx.cs

EditContentFiltersBox.ascx.cs

EditCrosspostSites.aspx.cs

EditNavigatorLinksBox.ascx.cs

Eventlog.aspx.cs

ftb.*.aspx

Login.aspx.cs

PermaLink.aspx.cs

Referrers.aspx.cs

ArchiveMonthsList.cs

CategoryList.cs

WeblogCalendar.cs

AggregatorBugHandler.cs

cdfHandler.cs

ClickThroughHandler.cs

CrosspostReferrerHandler.cs

PingbackAPI.cs

SyndicationServiceBase.cs

SyndicationService
 Implementation.cs

TrackbackHandler.cs

UrlMapper change, 1 or more link generation related changes

AdminNavBar.ascx.cs

UrlMapper, add 7 lines to map control NavigateUrl’s to absolute urls to work with 2004/06/17/foobar style URLs.

CommentViewBox.ascx.cs

UrlMapper, 3 lines

session entryId is lower case

EditConfigBox.ascx

EditConfigBox.ascx.cs

Added checkEnableUrlRewritingWithoutExtension propery & checkbox.

UrlMapper

EditEntryBox.ascx.cs

BloggerAPI.cs

MailToWeblog.cs

Added call to InitializeAtomId, UrlMapper, many

EditNavigatorLinksBox.ascx

Changed “Blogroll Feeds” to “Add new link…”, an copy and paste bug.

FormatControl.ascx.cs

FormatPage.aspx.cs

Change from calling Sever.MapPath to calling a new SiteConfig.MapPath. This was a bug. Serve.MapPath is request relative and won’t work as desired for any pages below the root folder.

Logout.ascx.cs

Factored logout logic to a static SiteSecurity.Logout() method.

Search.ascx

Added support for Google Free Site Search service. Since this is subscription based, it isn’t portable to other users unless they register and customize some hard coded properties. Should be factored differently but can also just be omitted. No dependencies.

UrlMapper

StringTables.resx

Added “text config enable url rewriting without extensions” prompt for internationalization of edit config change.

Web.config

UrlMapper section is now a no-op. It would be simple to reinstitute it as an alternative to the optimized rewriting scheme or no-rewriting. Since all URL generation / mapping is routed through one file (2 classes), it would be easy to drop in a call to the original LinkRewriter and UrlMapper logic.

Macros.cs

UrlMapper

MailTo() – bug fix, escape apostrophe in messageSubject.

MapPath bug fix.

Added AbsoluteUri, GetRssMainUrl, GetAtomMainUrl, GetStartPageUrl (UrlMapper suppot, required)

, TraceWrite, TraceWarn (allow adding to the ASP.NET trace output), no dependencies.

, DrawArchiveMonths (compact format of links to archive months with posts), no dependencies.

, WhenFormatted(string) (calls the new TimeZone.FormatAdjustedUniversalTime method)

SharedBasePage.cs

UrlMapper

Dropped in some performance timer stuff that I have to pull out or release Kizmet.Library.Diagnostics.dll.

Modified LoadEntries to call new GetEntriesInMonthLocalTime method that fixes the off-by-one-day month view bug.

SiteConfig.cs

Added using newtelligence.DasBlog.Web.Core

Added enableUrlRewritingWithoutExtensions Boolean property.

Added a UrlMapper instance field and property.

Added a public default constructor to initialize urlMapper field.

Added static MapPath method to fix users of Server.MapPath (wrong method for the job).

UrlMapper

SiteSecurity.cs

Added static Logout method factored out of logout control.

MapPath bug fixes.

Removed fix by luke@jurasource.co.uk that’s no longer needed after MapPath bug fix.

Themes.cs

Changed replace of pipe with backslash to replace of comma to backslash. This could change again to support legacy users with pipe in their cats (as opposed to cats in their pipes ;-))

UrlMapperModule.cs

Implements an optimized mapping and centralized generation of the URL api listed in the following table. Note that the native API remains unchanged and the url’s in the table are followed by “.aspx” if the configuration doesn’t call for hiding extensions (which requires a wildcard mapping in IIS). A minor change would allow supporting entries with legacy guid only EntryId values.

Overhauled the HandleBeginRequest method and added a UrlMapper class.

Would have to restore some support for the original mapping module. Could add the new behavior as a third choice after the original mapping scheme or no mapping scheme. Right now the new mapping scheme replace the old and requires a class recompile to make changes.

Utilities.cs

Many changes. Mostly migration of functionality to the UrlMapper class now living with the UrlMapperModule.

SyndicationService
ExperimentalImplementation.cs

Switched from using a url based AtomId to using the Entry.AtomId property.

 

Mapping Name

External (virtual) Url Pattern

Internal (real) Url Pattern

 

 

 

default

 

default.aspx

default

default

default.aspx

default

default?nc=1

default_nocache.aspx

login

login

login.aspx

logout

logout

logout.aspx

search

search?q=.*

SearchView.aspx?q=.*

accessdenied

accessdenied

FormatPage.aspx?path=siteConfig/accessdenied.format.html

disclaimer

disclaimer

FormatPage.aspx?path=siteConfig/disclaimer.format.html

pageerror

pageerror

FormatPage.aspx?path=siteConfig/pageerror.format.html

post

yyyy/mm/dd/[0-9a-z\-]{1,48}

PermaLink.aspx?guid=yyyy/mm/dd/[0-9a-z\-]{1,48}

postWithComments

yyyy/mm/dd/[0-9a-z\-]{1,48}?c=1

CommentView.aspx?guid=yyyy/mm/dd/[0-9a-z\-]{1,48}

day

yyyy/mm/dd

default.aspx?date=yyyy-mm-dd

month

yyyy/mm

default.aspx?month=yyyy-mm

category

category/[0-9a-z\-\., ]{1,48}

CategoryView.aspx?category=[0-9a-z\-\., ]{1,48}

rssMain

rss/main.xml

SyndicationService.asmx/GetRss

rssComment

rss/comment.xml

SyndicationService.asmx/GetCommentsRss

rssCommentPost

rss/comment/yyyy/mm/dd/[0-9a-z\-]{1,48}.xml

SyndicationService.asmx/GetEntryCommentRss?guid=yyyy/mm/dd/[0-9a-z\-]{1,48}

rssCategory

rss/category/[0-9a-z\-\., ]{1,48}.xml

SyndicationService.asmx/GetRssCategory?categoryName=[0-9a-z\-\., ]{1,48}

atomMain

atom/main.xml

SyndicationServiceExperimental.asmx/GetAtom

atomCategory

atom/category/[0-9a-z\-\., ]{1,48}.xml

SyndicationServiceExperimental.asmx/GetAtom?categoryName=[0-9a-z\-\., ]{1,48}

cdfMain

cdf/main.xml

cdf.ashx

clickThrough

ct/yyyy/mm/dd/[0-9a-z\-]{1,48}?u=.*

ct.ashx?id=yyyy/mm/dd/[0-9a-z\-]{1,48}&url=.* (maximum absolute url length is 128 for IE)

trackback

trackback/yyyy/mm/dd/[0-9a-z\-]{1,48}

Trackback.aspx?guid=yyyy/mm/dd/[0-9a-z\-]{1,48}

aggbug

aggbug/yyyy/mm/dd/[0-9a-z\-]{1,48}

aggbug.ashx?id=yyyy/mm/dd/[0-9a-z\-]{1,48}

cptrk

cptrk/yyyy/mm/dd/[0-9a-z\-]{1,48}

cptrk.ashx?id=yyyy/mm/dd/[0-9a-z\-]{1,48}

pingback

pingback

pingback.aspx

 

 

Yeah! First post on a new overhauled dasBlog engine

From the start, I wasn’t as interested in a wildly popular blog as much as a reliable publicly accessible place to share the notes I’d been accumulating for a few years. And perhaps with Weblogs.com being unceremoniously shut down, reliability and self-determination aren’t so bad.

Anyone who’s reached the point in their blogging where they’re ready to move on to a new engine knows that preserving permalinks can dominate the equation. So, being a bit anally retentive, because I clearly don’t have the volume of high quality posts and user comments to justify it, I decided to invest in the future by making the URL scheme of all public site links a top priority of the move. After looking around a bit, here’s what I wanted to end up with:

Purpose

Public URL Scheme

default

 

login

login

logout

logout

search

search?q=.*

post

yyyy/mm/dd/[0-9a-z\-]{1,48}

postWithComments

yyyy/mm/dd/[0-9a-z\-]{1,48}?c=1

day

yyyy/mm/dd

month

yyyy/mm

category

category/[0-9a-z\-\., ]{1,48}

Rss Main

rss/main.xml

Rss Comment

rss/comment.xml

Rss Comment Post

rss/comment/yyyy/mm/dd/[0-9a-z\-]{1,48}.xml

Rss Category

rss/category/[0-9a-z\-\., ]{1,48}.xml

Atom Main

atom/main.xml

Atom Category

atom/category/[0-9a-z\-\., ]{1,48}.xml

Click Through

ct/yyyy/mm/dd/[0-9a-z\-]{1,48}?u=.*

Trackback

trackback/yyyy/mm/dd/[0-9a-z\-]{1,48}

Aggregator Bug

aggbug/yyyy/mm/dd/[0-9a-z\-]{1,48}

Crosspost Tracker

cptrk/yyyy/mm/dd/[0-9a-z\-]{1,48}

pingback

pingback

 

I wanted a scheme that hid the implementation details and made it simple to figure out what post a URL relates to. If it was possible to build something today that would implement this scheme, I figured I could live with it for a long time and through multiple technology transitions. Only time will tell how truly myopic I’m being, but hell, you have to try.

WordPress was my first choice of engines based on its free, open source status, and the quality of some of the sites that use it. It was my first exposure to MySQL (which was really, really simple to get going – no wonder its doing so well) and PHP (which would have been simple if I’d remembered to remove the wildcard mapping from my IIS 5.0 server before trying to serve my first page. Overall the functionality was reasonably impressive, the standard interface was clean and appealing, but… On looking into the details of the PHP implementation it became clear that this was ASP vintage technology in an ASP.NET and JSP world. Not really un-expected, but definitely a step backwards.

The real stopping point with WP was my lack of interest in running Apache to serve it. Without Apache, there was no replacement for mod_rewrite. Despite what this post says, using PathInfo to forward information to what will always look like a PHP is a big sacrifice on the GUBUS. Without mod_rewrite, there was no grand-unified-blog-URL-scheme (Unless I wanted to write a custom ISAPI filter or something to do the work. Thanks, but no.)

It also became clear that the sites I’d liked were much more than straight WordPress. They were heavily customized and artistically templated.

So it was back to the blog engine comparison table. If I wanted to stick with a .NET codebase, the choices seemed to be Dottext or dasBlog. So I took another look at dasBlog.

dasBlog’s information schema was simpler than WP’s, but pleasantly transparent due to its use of XML files for storage. I can see a storage subsystem reimplementation on the horizon, but it makes for a quick and open prototyping platform. One of the glaring holes is the lack of a real Category entity. Event though dasBlog implements a visually attractive hierarchical category system, internally the implementation is out of gas. Because categories don’t have independent IDs and display strings, everything you might want to do with them is a compromise. A bit more work for the future.

First things first though. On to the grand-unified-BLOG-url-scheme implementation.

Having no clear idea of the level of effort (this was my learn-the-codebase project); I dove in and started making changes.

Along the way I abandoned the existing URL and link rewriting support for being non-scalable. Learned when not to use Request.MapPath (a post on that later); and about remote debugging in ASP.NET (another post); and crawled through the bowels of pingbacks and trackbacks.

By the time I finished, I’d modified every place in the code were a link was being generated to bring them all through the same centralized module that was responsible for parsing incoming URLs. Keeping things in sync is hard enough without separating where things have to be maintained.

One of the goals of the effort was to be able to run the exact same configuration on http://localhost/dasblog and http://tonesnotes.org, with or without an IIS wildcard mapping in each case. This turned out to be so cool that I ended up completely forgetting about how painful it had been to transfer a blog from one context to another. The ONLY change that has to be made is the “External Weblog URL”. Hide the ASP.NET extensions or not, run it at the root of its own IIS 6 web site or deep down on some IIS 5 developer box, it just works.

Okay, more testing is needed before I can make that claim, but there are enough cards on the table to be sure the outcome’s going to be good.

Another piece of work that came out of the effort was an extension of Scott’s import tool to consume Dottext blogs. (another post)

Time for bed now…

April 20, 2004

Second looks at dasBlog

Downloaded the latest DasBlog beta distribution (assemblies pre-built).

It was very easy to bring up compared to Dottext due to the lack of a database configuration. Not using a database has advantages and disadvantages.

The key steps were:

Download the 1.6.4107.0 beta zip
Unzip to a new empty folder (no previous content, themes, settings added)
Use Properties->Web Sharing with alias 'dasBlog' & default permissions.
set default.aspx as the default document
add local ASPNET, IUSR_, and IWAM_ accounts to root folder with default / read permissions)
give local ASPNET, IUSR_, and IWAM_ accounts write access to content, siteconfig, and log folders.
Login with admin/admin

Edit the siteconfig\siteSecurity.config file to add user accounts.