Stu Smith: Making It Up As I Go Along
“ My life working for BinaryComponents, coding, design, and other stuff. ”
It's often the case that when you start a project you have to make choices about architecture and technology that will affect you for a large proportion of the future of the project, but you have to make those choices (obviously) without the benefit of hindsight. One of those choices I had to make with FeedGhost involved displaying the contents of articles within RSS feeds.
RSS feeds usually have a "description" field which contains the content of the article, but unfortunately there doesn't seem to be a clear standard for what that field contains. Mostly it's HTML or "plain" text but different feeds seem to have ideas about how to encode this or what version of HTML to use.
(The screenshot above/left shows part of the improved river-view with prioritization and search-term boosting from the development version... a beta will be available early next week; if you'd like to try it and let us know what you like and don't like please contact us).
Very early on I figured that if I could convert that arbitrary HTML to a more regular format, I could then work with the contents much more easily. I picked XHTML since (a) it can be rendered by an embedded browser control and (b) can be easily traversed programmatically as an XmlDocument.
Writing a HTML to XHTML converter looks pretty easy... until you start to realize that a large proportion of the "HTML" out there isn't actually well-formed. For quite a while I was picking feeds at random, finding that they didn't convert correctly (due to bad HTML), and putting "intelligence" into my converter to cope. (Not coping, even with badly-formed HTML, is not a viable option). Fast-forward to today, and my converter can now take really messy HTML and usually come out with something sensible. (And if you find an article that doesn't display correctly, please do let me know).
With that out of the way, I then created a piece of "template" XML that would combine the converted articles with various bits of header and footer information. Remember this was way before our ribbon implementation, when FeedGhost displayed five articles at a time. To process this, I have a sort of poor man's ASP, in which an XHTML template can contain "active" elements that are processed and expanded as necessary. So a very crude rendering of an article might be something like:
<div>
<div class="item-title">
<data runat="server">data.Queries.GetNewsItemTitle(data.Selection.NewsFeedItemNode)</data>
</div>
<div>
<raw runat="server">data.Selection.NewsFeedItemNode.Description</raw>
</div>
</div>
(It's not actual FeedGhost code, but it's near enough. The difference between the <data> tag and the <raw> tag is that one quotes characters, and one merges XML trees. The "runat" attribute is only there as an easy-to-remember marker and has nothing to do with server-side processing since there isn't a server in this case.)
That's all well and good but those embedded expressions won't evaluate themselves. I've written a little C# tokenizer and parser that will build expression trees for basic C# 1.0 syntax. Using that, the document builder can then evaluate the expressions contained within "active" elements and fill in the resulting values.
This might seem a lot of work just to achieve a one-off document builder, but it's been useful all over the place. Since we're displaying data in an embedded browser, I can use stylesheets... with a similar evaluator system:
.item-titles-unread
{
background-color: %% data.ColorTable.PrimaryBrandingColor %%;
color: %% data.ColorUtility.BlackWhiteContrast(data.ColorTable.PrimaryBrandingColor) %%;
}
Another nice side-effect of this system is that since the document I want to display is entirely XML, I can process it easily programmatically:
Other than bug-fixes, our next big block of development will be an online version of FeedGhost. I'm hoping the conversion to XHTML will let us more easily produce Silverlight XAML from the articles. I can start simple (extract text only) and build up (image support... style support... etc).
Now that the "lite" version of FeedGhost is ready, the new subscription / locator tab coded, and prioritized reading is coming along nicely, we're starting to think about the web version of FeedGhost.
Given that we're a mainly Microsoft-based coding outfit, we're currently looking at whether Silverlight will be suitable, so I've been coding up some little demo projects in my spare time. (The one you can see to the left is my version of this idea).
[Incidentally, we're planning a web-site for all these little odd and ends of demo applications and components at some point, where you'll be able to download the articles and source-code.]
Finally Microsoft is beginning to realise that releasing a technology as Internet Explorer-only just doesn't work. (Anyone remember ClickOnce?) I can justify a Windows-only client application; I can't justify a Windows-only web application when Internet Explorer usage is at 75% and falling. Happily, Silverlight works on Internet Explorer, Firefox, Safari, etc.
Silverlight is of course competing with the likes of Flash, but my brain has limited space left for learning new stuff, so the fact that I can use C#, .NET, Visual Studio and Expression Blend is fantastic. Developing a Silverlight application feels (for the most part) like developing any other WPF-based application.
If you want resources to download to the client in the background, the downloader class is provided. It downloads asynchronously, but with foreground-thread events for progress updates and completion. It supports ZIP files and also plugs directly into WPF (for example, you can use a downloader to grab an image and then plug that in directly as the source to a bitmap). This is exactly the sort of simple class that makes developing Silverlight applications a real pleasure.
[Some of these limitations are being addressed, either in the first release version of Silverlight or subsequent ones. I've tried to mark those where I know that's the case. For the others, if I'm wrong please add a comment.]
For anything but the most trivial of applications, you'll probably want to communicate with the server, and for data, that's likely to be using XML. Unfortunately, Silverlight only provides a raw XmlReader at present, which means either ugly parsing code, or using an alternate data-transfer mechanism.
On the plus side, that alternate mechanism could be the server sending XAML to the client - Silverlight makes it very easy to parse and display XAML fragments.
[Note: LINQ-to-XML is apparently going to be available in Silverlight at some point, which will completely negate this minus point.]
Silverlight uses a subset of WPF for display. Unfortunately, there's quite a lot missing:
In WPF, when you define an x:Name attribute, that element may be referenced in code via a typed member variable. In Silverlight, this only seems to happen for pages, not user controls. By design? A bug? It's annoying anyway as your code ends up with a load of unsafe FindName calls.
Debugging Silverlight applications certainly needs work. Whereas in WPF you can trace through exceptions to find the exact problem, even the exact line of XAML that's problematic, in Silverlight more often than not that information simply isn't present, and instead some form of a generic exception is thrown. Conversely, and just as annoyingly, sometimes Silverlight doesn't give an error when perhaps it should - when I tried to use the binding syntax, rather than telling me that it wasn't supported, Silverlight just silently did nothing.
I appreciate of course that Silverlight is deliberately missing many features - it has to stay a small focused download, and can't become the kitchen sink that the .NET framework is. Additionally, it has to remain cross platform - I deliberately didn't mention the lack of a right-click event since that wouldn't work on a Mac for example, and I'd hate to see Silverlight become one of those frameworks where you constantly have to check the hosting platform.
Having said that, there are missing features that will be needed by certain developers, so perhaps Microsoft could modularize Silverlight. Keep the core tight and focused, and then allow developers to dynamically download whatever extras they need. Alternatively, there's definitely a market for 3rd party component vendors to market their own versions of these missing features.
Here's a little tip for those of you working in a dual-monitor setup: Windows does allow a desktop background to cover both screens, it's just not immediately apparent.
To apply a double-wide background, open the "Display Properties" control panel page, choose the "Desktop" tab, select your image, and choose "Position: Tile".
If you don't have any double-wide backgrounds, deviantART is a good place to start looking.
And finally, here's a little tip for those of you not working in a dual-monitor setup: get another monitor — once you get used to it, you'll wonder how you ever managed without it.
When you're setting up a server and/or website, it's always useful to be able to see what the internet infrastructure thinks of it, especially when things don't work and you can't see why. I'm sure there's a lot of these sorts of tools out there, but these are the two I use.
If you're having trouble getting an aspect of your server working nicely with the internet, this is the tool to use. It breaks down all of the boring-but-vital plumbing that you need to be working if you want people to be able to see your website, receive your mail, etc. Of course a lot of this may be handled by your ISP, but if you're responsible for your own server, this is a must.
This tool summarizes your website's search effectiveness as a blend of various search engine ranks and other metrics. Consider it a website health-check to find those obvious problems that you may have overlooked.