So the Live Writer Plugin model is so cool and easy that I had to write a plugin. (and do it with Edit-and-Continue). The obvious ones were already done (eg, Paste code from VS), so I scratched my head for an idea and I finally got one: a "verse of the day" plugin. This

  1. gets an RSS feed from (in this case
  2. parses an item from the RSS feed containing the verse, using specific knowledge of how the xml at the URL above is laid out. I'm just using XmlDocument here instead of the new fancier Xml libraries.
  3. formats it into an HTML string.
  4. inserts that into the blog.

And for bonus points, overrides the Plugin's Option Dialog to provide a dialog that shows extra diagnostic information.

Example output is:

1 Samuel 16:7“But the LORD said to Samuel, "Do not consider his appearance or his height, for I have rejected him. The LORD does not look at the things man looks at. Man looks at the outward appearance, but the LORD looks at the heart.”

Brought to you by Copyright (C) NIV. All Rights Reserved.


(end of example output).

Here's the code snippet. I only tested this for for a few minutes and am not alleging this to be bullet proof:

// Simple Windows Live Writer extension for showing a Verse-of-the-Day.
// This gets the verse via an RSS feed from BibleGateway.
using System;
using WindowsLive.Writer.Api;
using System.Windows.Forms;
using System.IO;
using System.Xml;

namespace VerseOfTheDay
    // Plugin to take all URLs and convert them to all uppercase.
        "Verse Of The Day", 
        Description="Insert a 'Verse of the Day' from BibleGateway",
    [InsertableContentSourceAttribute ("Verse Of the Day", SidebarText="Verse of the day")]
    public class MyExt : ContentSource
        #region Configuration
        // This is the URL for the RSS feed that provides the content.
        static string s_SourceUrl = "";
        static int s_TimeoutSeconds = 5;
        static string s_FormatString = "<table border=1><tr><td><b><a href={0}>{1}</a></b>{2}</td></tr></table>";
        #endregion // Configuration

// LiveWriter calls this when the "Options" button is selected in the plugins menu. // This would let us have a dialog to configure options for this plugin. public override void EditOptions(IWin32Window dialogOwner) { // Show settings. // We could be fancier and allow editing the settings, and persisting them to a file. string caption = "Settings for 'Verse of the Day' PlugIn"; string text = string.Format("RSS feed to get verse from: {0}\r\nTimeout when reading RSS feed:{1} seconds\r\n\r\nHTML Format String (args 0 is a URL to the verse, arg 1 is the title, arg 2 is the verse contents):\r\n{2}", s_SourceUrl, s_TimeoutSeconds, s_FormatString); MessageBox.Show(dialogOwner, text, caption); } XmlDocument GetRssFeed(string url) { // Use LiveWriter Services to make the HTTP request. // - this lowers the security requirements for the plugin, // - cooperates with Internet configurations in LiveWriter. PluginHttpRequest request = new PluginHttpRequest(s_SourceUrl); Stream s = request.GetResponse(s_TimeoutSeconds * 1000); // throws on timeout. if (s == null) throw new InvalidOperationException("Couldn't retrieve data from " + s_SourceUrl); StreamReader sr = new StreamReader(s); string xmlString = sr.ReadToEnd(); // gets the XML. // Parse the XML to get the verse. // The XML is an RSS feed with 1 item, containing the "verse of the day". XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlString); return doc; } // This is invoked by LiveWriter when the user chooses this plug-in from the insert menu. public override DialogResult CreateContent(IWin32Window dialogOwner, ref string content) { // Get from verse via BibleGateway. // The XML is an RSS feed with 1 item, containing the "verse of the day". XmlDocument doc = GetRssFeed(s_SourceUrl); XmlElement item = doc.LastChild["channel"]["item"]; string title = item["title"].InnerText; string verse = item["content:encoded"].InnerText; string link = item["guid"].InnerText; // Format the information and return as an HTML string. content = string.Format(s_FormatString, link, title, verse); // Return success. return DialogResult.OK; } } }


 To build  it, include a reference to WindowsLive.Writer.Api.dll in the WLW installation directory. For example, from the command line, if the above is named class1.cs:

csc /t:library Class1.cs /r:"C:\Program Files\Windows Live Writer\WindowsLive.Writer.Api.dll"


Next up: playing around to get it on Gallery.