Main

June 09, 2005

9/11 Memorial

Someone with much more experience and wisdom than I, but very little computer savvy called me today to inquire about blogs, of all things.

The driving issue was the political gamesmanship in which the 9/11 Memorial project is now mired.

It was an easy thing to set him up with a Blogger.com site. It’s amazing when someone you know well - but never imagine in the context of blogging - suddenly becomes one.

 

 

 

June 17, 2004

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…

June 16, 2004

Google Free Site Search

Signed up for Google’s free site search service.

Modified their template to the following:

<form id="searchform" method="get" action="http://www.google.com/custom">

<input type="hidden" name="cof"

 value="S:http://blogs.toneengel.com/;GL:0;AH:left;LH:60;L:http://blogs.toneengel.com/skins/btone/images/sggb60.jpg“

+“;LW:60;AWFID:b764e198d2896699;">

<input type="hidden" name="domains" value="blogs.toneengel.com">

<input type="hidden" name="sitesearch" value="blogs.toneengel.com">

<p id="searchlabel"><label for="q" accesskey="4">Search this site:</label></p>

<p id="searchinput"><input type="text" id="q" name="q" size="18" maxlength="255" value="">&nbsp;
<input type="submit" value="Search"></p>

</form>

 

 

But this works much better within an ASP.NET page:

function googleSearch(searchString) {

     var cof = "S:http://blogs.toneengel.com/;GL:0;AH:left;LH:60;L:http://blogs.toneengel.com/skins/btone/images/sggb60.jpg;“+

“LW:60;AWFID:b764e198d2896699;";

     var domains = "blogs.toneengel.com";

     var sitesearch = "blogs.toneengel.com";

     var q = escape(searchString).replace(/\+/g,"%2B");

     location.href="http://www.google.com/custom?cof="+cof+"&domains="+domains+"&sitesearch="+sitesearch+"&q="+q;

}

<input type="text" id="searchString" onkeypress="if (event.keyCode == 13) googleSearch(searchString.value);" >

<input type="button" value="Google" onclick="googleSearch(searchString.value);">

 

Thanks to Mark Pilgrim for putting me on to this service.

 

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.

 

February 06, 2004

Changes to .Text for Image Posting using TonesNotes

The latest version of TonesNotes lets you post blog entries from Word that contain images:

Here is the change required of 0.95 vintage Dottext codebase.

Add the following method to the SimpleBlogService.asmx.cs file:

/// <summary>

/// Add an image to a specified gallery and return the url by which it will be accessible.

/// </summary>

/// <param name="username"></param>

/// <param name="password"></param>

/// <param name="gallery">Title of the target gallery, gallery will be created if it doesn't exist.</param>

/// <param name="postdate">Date to associate with the image. Not currently supported by the data model.</param>

/// <param name="title">Title for the image.</param>

/// <param name="description">Description for the image.</param>

/// <param name="categories">Array of categories to associate with the image. Not currently supported by the data model.</param>

/// <param name="filename">The non-path image filename including extension. Note that currently filenames must be unique within a gallery.</param>

/// <param name="data">Image file data in on-disk format matching the filename's extension.</param>

/// <returns>A url in the form http://blogs.mydomain.com/myblog/8/o_filename.jpg, where 8 is the integer CategoryID assigned to the gallery.

/// The returned url is an absolute url with a "o_" prefix on the filename.

/// Caller can make the prefix "t_" for thumbnail and "r_" for standard size.</returns>

[WebMethod(MessageName="AddImageToGallery",Description="Insert an image into a gallery with Categories",EnableSession=false)]

public string AddImageToGallery

      ( string username

      , string password

      , string gallery

      , DateTime postdate

      , string title

      , string description

      , string[] categories

      , string filename

      , byte[] data

      ) {

 

      BlogConfig config = Config.CurrentBlog(Context);

      CheckUser(username,password);

 

      int categoryID = 0;

 

      // Lookup the categoryID of gallery (gallery is the title).

      LinkCategoryCollection lcc = Links.GetCategories(CategoryType.ImageCollection, false);

      foreach (LinkCategory lc in lcc) if (string.Compare(lc.Title, gallery, true) == 0) { categoryID = lc.CategoryID; break; }

 

      // If gallery doesn't exist, try creating it.

      if (categoryID == 0) {

            LinkCategory category = new LinkCategory();

            category.CategoryType = CategoryType.ImageCollection;

            category.Title = gallery;

            category.IsActive = false;

            category.Description = "Images uploaded with new posts.";

            categoryID = Links.CreateLinkCategory(category);

            if (categoryID == 0) throw new Exception("CategoryID is zero");

      }

 

      // Insert the new image into the selected gallery.

      // This puts three copies (thumbnail, standard size, original size) of the image on disk under the "images" folder

      // and adds a record to the blog_Images table.

      Image image = new Image();

      image.CategoryID = categoryID;

      image.Title = title;

      image.IsActive = true;

      image.File = Images.GetFileName(filename);

      image.LocalFilePath = Images.LocalGalleryFilePath(Context, categoryID);

      int imageID = Images.InsertImage(image, data); 

 

      if (imageID == 0) throw new Exception("ImageID is zero");

 

      string baseImagePath = Images.HttpGalleryFilePath(Context, image.CategoryID);

 

      return baseImagePath + image.OriginalFile;

}

 

 

 

January 11, 2004

Share your RSS subscriptions with the world

 For reference when it comes time J to care about this myself…

If you haven't checked it out yet, you should really take a look at

http://feeds.scripting.com/rankings

Basically it's a site that allows you to upload your OPML file and share it with others. The link here shows the top 100 feeds people subscribe to. You can also go to each person and see their OPML list. You can also see who subscribes to your feed. Sadly, it seems that only 5 people subscribe to me, which is even less than my imagined 10 readers :)   (but then, Lutz Roeder's feed only has 3 subscriptions so what do I know)

Anyway, I just discovered some very cool feeds from there but I think it's still little known. So, what do you subscribe to? (BTW: you need to manually enable sharing your subscriptions so that you will be counted as a subscriber to someone else's feeds) 

(This is not aggregated on the main site so that I only bother the people who actually subscribe to my blog)


[ISerializable]