Main

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…

April 15, 2004

SimpleBlogService fixes.

Updating a posting via the SimpleBlogService was eliminating all categories and making the title link disappear.

The implementation of  Update in DataDTOProvider.cs expects the entry’s PostType property to be set and it wasn’t. This resulted in a CategoryType of StoryCollection being used where PostCollection would have been correct. The correct thing to do would be for Entries.GetEntry and Entries.GetCategoryEntry to correctly initialize the PostType property.

 

Since this wasn’t happening, I force the PostType to BlogPost in the Edit method of SimpleBlogService.

 

To correctly update the categories assigned to a post and prevent the assigned categories from being erased I added an overload for the Edit method that takes an array of category strings.

 

 

April 04, 2004

Dottext content stats updated trigger not updated

The flag enumeration values shared by the blog_Content table trigger hadn’t been updated which resulted in the stats not being updated (PostCount, CommentCount, etc.)

 

March 31, 2004

Delete 0.95 cookies when deploying 0.96 Dottext

The data stored in the Dottext cookie under 0.95 fails to parse under the current version of 0.96 (today’s source).

The symptom is a “The root element is missing” XML parsing error immediately on all pages.

The work-around is to delete the cookie. You can either use ToolsàInternet OptionsàDelete Cookies which will delete all your cookies, or ToolsàInternet OptionsàSettingsàView Files; the sort by Address and find the dottext cookie associated with your deployment web site and delete it.

 

Manually adding a user to the pre-release 0.96 Dottext schema

The current Dottext schema is adding user account and user role features which requires a little manual database updating:

1.      Add a record to the blog_GenericUsers table:

a.       UserName & Password, copy from blog_Config table.

b.      PasswordFormat = 1

c.       UserAccountStatus = 1

d.      IsAnonymous = 0

e.       ForceLogin = 1

2.      Add a record to the blog_UserProperties table:

a.       UserID, copy from blog_GenericUsers table.

b.      UserConfig = 3

3.      Add a record to the blog_Roles table:

a.       UserID, copy from blog_GenericUsers table.

b.      BlogID, copy from blog_Config table.

c.       BlogRoleID = 1

 

 

March 29, 2004

Merging Dottext 0.95 mods to 0.96 code base

My goal is to get on the latest code base with minimal mods for my skin and web service needs.

Created a snapshot of vaultpub as of 2004-03-30 11:31. I’m leaving the bulk of the source files out of Perforce and not using the Perforce SCC with Visual Studio. It corrupted my first shot at it to the point that I couldn’t do anything with the DottextWeb project in the Solution anymore, but it was fine by itself. Grrr…. Visual Studio crashed several times during debugging and the Dottext.Framework assembly kept getting lost and needed to be rebuilt when opening the solution and attempting to debug. This is behavior I haven’t seen in any other project (or earlier version of dottext). I wonder if it has anything to do with the worker threads started by the index generation events?

Copied OtherStuff\Configs\096_Web.config to DottextWeb and made changes.

Compiled solution files. Build works. Rebuild chokes. RichEditor.ascx.resx may not be checked in.

Created SearchIndex folder and gave ASP.NET account write access to it.

Added a FordeIndexUpdate.aspx page to force initial index population.

URL’s in search results are not right. Hostname and application name aren’t being combined correctly. Part of it is hard coding in 096db.sql, blog_aggregate_Search stored procedure, modified to remove hard coded ‘weblogs.asp.net’ in search permalink generation. That fixes the host part but the application part is missing. Realized that by editing the urlFormat attribute of the SearchConfiguration element in the Web.config file I could re-insert the DottextWeb without modifying any code. The “domains” attribute seems to restrict which blogs are aggregated in the index and can be a comma separated list of Hosts, as defined in the blog_Config table.

At this point the application appears to run well on localhost, including the search functionality and standard skins.

Adding the mods required by TonesNotes:

·        SimpleBlogService, added AddImageToGallery method, modified how categoryID is obtained.

·        Made Images folder writeable by ASP.NET.

Adding btone skin:

·        Added print.css copied from AnotherEon001

·        Added span.highlight style to style.css

·        Skins\btone\PageTemplate.ascx, change DT namespace back to UI.WebControls and ‘ContentRegion’ back to ‘contentRegion’.

·        Skins\btone\controls\BlogSearch.ascx, added.

·        Added btone to Admin\Skins.config

·        Modified btone\controls files: SingleColumn.cs, MonthList.cs, PostComment.cs

·        Added Skins\btone\UIData.cs with PostCategoryHyperLinks method.

·        Modified btone\controls files: Days.cs, EntryList.cs, ViewPost.cs

 

Initial merge complete.

 

 

March 25, 2004

Add aspnet to SQL db_owner role to enable execute permission on stored procedures.

When using Windows Authentication mode with .Text and a SQL Server Database.

The ASPNET account has to be given access to the database and added to the db_owner role.

 

February 06, 2004

New release of TonesNotes for Dottext supports posting images from Word

 

The latest release of TonesNotes is available here http://workspaces.gotdotnet.com/tonesnotes. It lets you post to a .Text blog from any open Word document and now supports posting images in the body of the note.

The README.htm file installed with the release contains a code change for the Dottext blog server to support posting images.

 

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;

}

 

 

 

February 04, 2004

Post to your .Text blog using this add-in for Word

I released the alpha version of my blog posting add-in for Microsoft Word 2003 or XP as a GotDotNet workspace: http://workspaces.gotdotnet.com/TonesNotes

TonesNotes is a free and lets you post to a .Text blog from any open Word document.

The intended mode of operation is to use a single Word document in which the ideas you’re working on take shape. When an idea is baked, place the insertion point within its content, click the “Post” button on the TonesNotes toolbar, and the content is simultaneously posted to one or more blogs and archived as a separate Word document on your local file system.

The command bar has a “New” button which starts a new entry at the bottom of the active Word document. An entry is demarked by a paragraph with the style “Heading 1” by default. The “New” command inserts a paragraph with a date stamp which will become the post creation time. Complete the note heading with a comma separated list of categories and a title. Anything in the note heading paragraph not recognized as a date or category name becomes part of the title.

Since not all ideas are suitable for public posting, the behavior of the Post command is driven by assigning a category name to each configured blog. A note is posted to each blog whose category name is listed in the entry heading, or simply archived if it isn't meant to be blogged.

In addition to the “New” and “Post” functions, the toolbar has a “Config” button which brings up the configuration dialog.

Here’s a topic page in the .Text wiki that lists pros, cons, and configuration for various authoring options including TonesNotes: http://dottextwiki.scottwater.com/default.aspx/Dottext.AuthoringOptions

 

 

January 30, 2004

Word add-in supporting posting to Dottext from Word

When I'm working, my usual mode of operation is to have a Word document open (typically Notebook.doc) in which I'll have several active entries. We rarely get to work on one thing at a time anymore, and that's reflected in my note taking.

To start a new entry, I hit a control-alt-A, and a macro inserts the start of an entry header at the end of the file. I complete the header by typing a comma separated list of categories and a short descriptive title; all in one paragraph; hit enter and start the body of the entry.

As I bounce between tasks, I'll edit the body of the corresponding entry and maybe the header as well.

Eventually the entry is done and it needs to be archived and optionally posted to a blog.

I archive each entry as an ordinary Word document in a tree of folders on my laptop. This is my primary repository since it is secure, accessible off-line and can handle rich content. The search function of Windows Explorer is also useful for finding old entries.

If the entry is suitable for posting to a blog, I add the name of the blog to the header and it gets posted at the same time.

This is the first real entry made this way, I'll be adding more information and sharing the implementation once it gets more fully baked.

January 13, 2004

Excellent source tree comparison and differencing tool: WinMerge

To speed up integrating Scott's latest Dottext changes with my own mods I went looking for an easy way to pinpoint changes in trees of source files.

WinMerge does the job well and its free. Highly recommended.

January 11, 2004

IE5 & IE6 blockquote with border CSS bug workaround

There’s an IE5 & IE6 cascading style sheet (CSS) bug affecting the “AnotherEon001” skin.

The bug is visible if a post contains a “blockquote” element which contains a “P” element.

What you’ll see is all the text following the “div” containing the “blockquote” will be shifted to the left from where it should have been.

The trigger for the bug is the “border-left” style applied to the “blockquote”.

Alternatives to avoid the bug:

1.      Remove the “border-left” style.

2.      Add a “border-bottom” style of equal width. Make it match the background if you don’t want to see it.

3.      Eliminate the “padding” style from the “blockquote”.

4.      Somehow arrange for the text within the “blockquote” not to contain any “p” elements J

Thanks for the insight into the bug goes to this link.

January 08, 2004

Dottext modification to extract categories and creation date from title string

This patch to Dottext is intended to simplify importing historical posts and allows you to assign categories when posting from Outlook using NewsGator.

You can download a zip of the modified source and binaries.

Details:

·         Looks for comma separated date and categories in the title string. If they are found, they are removed from the remainder of the title.

·         Categories are matched based on their title string and are case insensitive.

·         Both the web/admin add-new-post code and the web/service code used by NewsGator have been updated.

·         The date formats recognized are: "u", "s", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss ddd", "yyyy-MM-dd HH:mm ddd", "yyyy-MM-dd ddd".

For example, to create a new posting that you actually composed last night while off-line and would like to categorize under both dotNET and Dottext, enter a NewsGator "Subject:" or admin "Post Title" as follows:

2004-01-07 23:00, dottext, dotnet, This is the actual post title about dottext and dotnet stuff

The date, categories, and commas will be stripped from the actual post title.

Sort of a Wiki approach to supplying post meta data.

Dottext version patched:

·         Dottext 0.95.2004.102 Source

Files modified/added:

·         Code\DottextWeb\Admin\UserControls\EntryEditor.ascx.cs

·         Code\DottextWeb\Services\SimpleBlogService.asmx.cs

·         Code\Dottext.Framework\Util\TitleParser.cs