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
And for bonus points, overrides the Plugin's Option Dialog to provide a dialog that shows extra diagnostic information.
Example output is:
(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. [WriterPluginAttribute( "{6F75058E-EED6-4f8c-BBE5-BE0D6126358D}", "Verse Of The Day", PublisherUrl="http://blogs.msdn.com/jmstall", ImagePath="Bitmap1.bmp", Description="Insert a 'Verse of the Day' from BibleGateway", HasEditableOptions=true) ] [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 = "http://www.biblegateway.com/usage/votd/rss/votd.rdf"; 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; } } }
// 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. [WriterPluginAttribute( "{6F75058E-EED6-4f8c-BBE5-BE0D6126358D}", "Verse Of The Day", PublisherUrl="http://blogs.msdn.com/jmstall", ImagePath="Bitmap1.bmp", Description="Insert a 'Verse of the Day' from BibleGateway", HasEditableOptions=true) ] [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 = "http://www.biblegateway.com/usage/votd/rss/votd.rdf"; 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.