The New Live Writer SDK

In my LiveSide post, I mentioned that the Live Writer SDK had been updated as well as Live Writer itself. In this post I will show you how to build a couple of quick plugins that use the new APIs, but first, what’s changed?

The big thing to note is that all the API calls in the previous version of the SDK are unchanged; the changes have been additions to the SDK. So the main two new additions are two new plugin classes: PublishNotificationHook and HeaderFooterSource. This gives us four types of plugins: ContentSource, SmartContentSource, PublishNotificationHook and HeaderFooterSource. There are also a couple of other new smaller additions, like the TaskServices class that will let you perform a task in the background whilst still keeping the Writer UI in a responsive state.

But this post is going to concentrate on those two new Plugin base classes, which you can see after the jump.

PublishNotificationHook

This type of plugin can be used to access the post either before or after it’s published. The reason you might want to do this is to check the post for something, this can be the title, the contents or even the keywords (blog engine permitting). You would check the post for whatever you’re looking for and if it passes your check, you allow the post to be published, or else you tell Writer to stop publishing and the post remains unpublished.

Let’s look at some code. The plugin starts off the same way as a ContentSource or SmartContentSource plugin in that you have to declare some WriterPlugin attributes:

    [WriterPlugin("07b95fc3-887e-4558-b53a-0e2a5a47f431", 
"PublishNotification Example", PublisherUrl = "http://www.liveside.net", Description = " ", ImagePath = "writer.png", HasEditableOptions = false)]

So now we create the plugin class and mark it as a PublishNotificationHook class:

    public class PublishNotificationExample : PublishNotificationHook
    {

Like ContentSource or SmartContentSource plugins, you can override the Initialize() method (if your plugin requires settings), this is also true for HeaderFooter plugins too.

With PublishNotificationHook plugins, I mentioned that you can access the post before (or after) it’s published, and we do this by overriding the OnPrePublish and OnPostPublish methods. In this very quick example, I’m going to check whether my post’s contents (ie, the body of the blog entry) contains the word “liveside”:

        public override bool OnPrePublish(IWin32Window dialogOwner, 
            IProperties properties, IPublishingContext publishingContext, 
            bool publish)
        {
            // Check the post contents to see if liveside appears, if it does, 
// return true (publish),
// if it doesn't, return false (cancel publish) return publishingContext.PostInfo.Contents.ToLower().Contains("liveside"); }

Now, the publishingContext.PostInfo is where all the cool stuff is. In this property (which is an IPostInfo object), you have access to the Contents, Keywords, Title, Categories, and even tells you whether it’s a page or not (for WordPress users). Now with this quick check, if my post doesn’t contain the word liveside, then the OnPrePublish method will return false which will stop the post from publishing, if it does contain it, then it will return true and continue to publish.

The OnPostPublish method is slightly different, this method would allow you to do something once the post has been published, for example, update your Twitter status with the blog title and permalink:

        public override void OnPostPublish(IWin32Window dialogOwner, 
            IProperties properties, IPublishingContext publishingContext, 
            bool publish)
        {
            // If this post is a draft (false), don't do anything
            // if it's an actual publish, then publish = true;
            if (!publish)
                return;

            string updateTwitter = string.Format("{0} - {1}",
                publishingContext.PostInfo.Title,
                publishingContext.PostInfo.Permalink);

            // Code to update Twitter
        }

You’ll notice the variable publish that gets passed in both OnPostPublish and OnPrePublish, this will tell your plugin whether it’s being saved as a draft or as an actual published entry. This is the same for HeaderFooterSource plugins, too.

And there you have it, a quick plugin that uses the PublishNotificationHook base class.

HeaderFooterSource

This type of plugin can be used to automatically add some html code to a blog post as either a header, or a footer. Quick examples of this could be a Digg button (header), or Social Bookmarking widget (footer). Now the cool thing about this type of plugin is you can actually specify the permalink for the post to be used, even if the post has yet to be published (I’ll cover this when I start going through the code). If you want to see what your post will look like when using this type of plugin, you just go to the Preview tab and the plugin will get loaded (there are separate methods for the Preview HTML and the Published HTML, but again, I’ll go through that in the code).

Start off by creating the class and declaring it as a HeaderFooterSource plugin:

    public class HeaderFooterSourceExample : HeaderFooterSource
    {

Now, as I mentioned, the cool thing about this base class is you can tell the plugin to use the post’s permalink (even though it hasn’t been published yet), but what we need to do is tell Writer that the plugin will require a [currently] non-existent permalink, we do this by overriding the RequiresPermalink boolean (whose default is false):

        public override bool RequiresPermalink
        {
            get
            {
                return true;
            }
        }

The HeaderFooterSource base class will create two methods for us: GeneratePreviewHtml() and GeneratePublishHtml(). Now these both work in a similar way to GeneratePublishHtml() and GenerateEditorHtml() in SmartContentSource plugins. The GeneratePreviewHtml() is what shows when you switch to the Preview tab, and the GeneratePublishHtml() is what gets published.

So first off the GeneratePreviewHtml():

        public override string GeneratePreviewHtml(ISmartContent smartContent,
            IPublishingContext publishingContext, 
            out HeaderFooterSource.Position position)
        {
            // This tells the plugin where to put your code
            position = Position.Header;
            return "Nothing to see here yet!";
        }

And then the GeneratePublishHtml():

        public override string GeneratePublishHtml(IWin32Window dialogOwner, 
            ISmartContent smartContent, IPublishingContext publishingContext, 
            bool publish, out HeaderFooterSource.Position position)
        {
            position = Position.Header;
            string yeehaaaa = string.Format("This blog entry's link is: <br />" + 
                "<a href=\"{0}\">{0}</a>.", publishingContext.PostInfo.Permalink);

            return yeehaaaa;
        }

So if you now click on the Preview tab, your post would look like this:

Notes about these plugins

After you have have first added any of these plugins to Live Writer, when you click on the Publish button (or Preview for HeaderFooterSource), Writer will ask you if you want to use these plugins for the blog you’re currently using:

For these new types of plugins, you can enable or disable each plugin on a per blog basis, which you can do from the Accounts options window:

And that’s about all you need to know for now. I have made some plugins of my own using these new APIs, but I will cover those in another post.

As always, the source code for this can be found in my skydrive area:

http://cid-fabdddc5cad93494.skydrive.live.com/self.aspx/LiveSide%20-%20Public/SourceCode/NewAPIPlugin.zip

SL

Whilst writing this, I was listening to The Lightning SeedsChange

About these ads
  1. #3 by Unknown on March 25, 2009 - 7:38 am

    http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8%E8%A3%BD%E8%96%AC+%E5%8C%BB%E8%96%AC%E5%93%81&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8%E8%A3%BD%E8%96%AC+%E5%8C%96%E7%B2%A7%E5%93%81&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8%E8%A3%BD%E8%96%AC+%E5%B0%B1%E8%81%B7&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8%E8%A3%BD%E8%96%AC++%E4%BF%9D%E6%B9%BF%E6%B6%B2&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8%E8%A3%BD%E8%96%AC+cm%09&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8%E8%A3%BD%E8%96%AC+%E3%83%92%E3%83%AB%E3%83%88%E3%83%83%E3%83%97%09&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8%E8%A3%BD%E8%96%AC+%E5%9F%BA%E7%A4%8E%E5%8C%96%E7%B2%A7%E5%93%81%09&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8%E8%A3%BD%E8%96%AC+%E6%96%B0%E7%A4%BE%E5%B1%8B&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8%E8%A3%BD%E8%96%AC+%E3%83%89%E3%83%A2%E3%83%9B%E3%83%AB%E3%83%B3%E3%83%AA%E3%83%B3%E3%82%AF%E3%83%AB&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8%E8%A3%BD%E8%96%AC+%E6%8E%A1%E7%94%A8&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8%E8%A3%BD%E8%96%AC+%E8%96%AC%E5%93%81&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8%E8%A3%BD%E8%96%AC+%E7%97%9B%E6%95%A3%E6%B9%AF&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8%E8%A3%BD%E8%96%AC+%E6%BC%A2%E6%96%B9&btnG=%E6%A4%9C%E7%B4%A2&lr=

  2. #6 by Unknown on April 7, 2009 - 4:46 am

    http://twomore.net/saishunkan/index.htmlhttp://popeo.net/saishunkan/index.htmlhttp://futureyuki.com/saishunkan/index.htmlhttp://gugully.com/saishunkan/index.htmlhttp://xiday.org/saishunkan/index.htmlhttp://guclass.comhttp://kucoast.comhttp://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8+%E5%8C%BB%E8%96%AC%E5%93%81&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8+%E5%8C%96%E7%B2%A7%E5%93%81&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8+%E5%B0%B1%E8%81%B7&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8+%E4%BF%9D%E6%B9%BF%E6%B6%B2&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8+cm&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8+%E3%83%92%E3%83%AB%E3%83%88%E3%83%83%E3%83%97&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8+%E5%9F%BA%E7%A4%8E%E5%8C%96%E7%B2%A7%E5%93%81&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8+%E6%96%B0%E7%A4%BE%E5%B1%8B&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8+%E3%83%89%E3%83%A2%E3%83%9B%E3%83%AB%E3%83%B3%E3%83%AA%E3%83%B3%E3%82%AF%E3%83%AB&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8+%E6%8E%A1%E7%94%A8&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8+%E8%96%AC%E5%93%81&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8+%E7%97%9B%E6%95%A3%E6%B9%AF&btnG=%E6%A4%9C%E7%B4%A2&lr=http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E6%98%A5%E9%A4%A8+%E6%BC%A2%E6%96%B9&btnG=%E6%A4%9C%E7%B4%A2&lr=

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: