![]() |
|
Spaces home InsertableContentSourceProfileFriendsBlogMore ![]() | ![]() |
InsertableContentSourceScottIsAFool's Dev Stuff
|
|||||
|
June 03 New Writer Plugins Using The New SDKAs mentioned, and demonstrated, there is a new SDK for Live Writer and true to form, I have been beavering away with them writing up new plugins. This post will showcase the 6 plugins I’ve written using the new SDK. So let’s jump straight into it. Emotify Plugin You might remember that the first plugin I ever wrote for Live Writer was my Insert Emoticon plugin, where you clicked on the insert link on the right, chose your emoticon and put it in your post. Well I always found that to just be tedious and a pain, so with this new SDK, I can now take it one step further. So I have added to the original plugin and now you can simply do a Live Messenger emoticon code in your post Now Playing There are many different plugins that allow you to put what you’re listening to into your blog and I think I’ve used each one, but this is a perfect example of a plugin that could utilise the HeaderFooterSource base class. And that’s exactly what I’ve done. The plugin itself is nothing special, it doesn’t even have its own API, but what it does allow is for you to customize what you want it to say and what parts of the song to show: Now, a couple of things about this plugin, for it to work, you need to have the Windows Media Player blogging plugin which you can download here for XP or here for Vista. If you’re using iTunes, then you don’t need to install anything else, the plugin will query iTunes itself for the currently playing information.
Capitalize Title This is a very simple plugin that will check to see if your blog title is using capital letters for the first letter of each word, if this isn’t the case, then it changes that. So a blog title would look like this: A New Blog Post Entry With Capital Letters (rather than: a new blog post entry with capital letters). Signature Plugin This plugin is quite unique as it has per blog settings! What this plugin does is uses the HeaderFooterSource and at the end of the blog entry will put a signature (like SL in my case). Now sometimes you want to use different signatures for different blogs (if you have more than one configured), so this plugin allows you to have different signatures for each blog configured!!
Bold Hyperlink Plugin This was a request from Steve Clayton who wanted all of his hyperlinks to be bold, so that’s what this plugin does. It checks the contents of the blog entry and makes all the hyperlinks in the blog post bold. Profanity Checker This plugin was something I discussed with the Writer team as a good example of the PublishNotificationHook base class for checking the contents of a post and cancelling the publish if certain criteria are met. So this allows you to configure what words would cancel a blog post from being published, and just to make sure they can’t easily be changed (say by a child), you have to password protect them ScottIsAFool.WriterUtilities For some of these plugins, they all required some common code, so I have started compiling my own WriterUtilities static class. Now one of the methods you’ll find is a nice little trick for your Writer plugins. In the IPostInfo interface, all the properties (like title, contents, keywords, etc) are read only, so you can’t actually change them using your code. But wait a minute, isn’t that what I’m doing with at least 3 of the above plugins? Yes, yes it is. Using this WriterUtilities class, you can also change it too, but be warned, it is unsupported by Microsoft (and me public override bool OnPrePublish(IWin32Window dialogOwner, IProperties properties, IPublishingContext publishingContext, bool publish) { string newtitle = "My New Title"; return ScottIsAFool.WriterUtils.ReplaceText(publishingContext.PostInfo, newtitle, PostItems.Title); } I also have a another method which returns an array of Blogs configured on the system (which I use for my Signature plugin). I should note that this utilities class is only compatible with the CTP and should not be used in the 1.0 SDK! Source Code As always I am making the source code for all these available on CodePlex. Codeplex page: http://www.codeplex.com/NewLiveWriterPlugins
All of these plugins should be put in c:\program files\windows live\writer\plugins (or the locale/architecture equivalent). SL Whilst writing this, I was listening to Aerosmith - Lay It Down The New Live Writer SDKIn 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", 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, 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: SL Whilst writing this, I was listening to The Lightning Seeds - Change March 18 Writing An Application That Opens Windows Live WriterEveryone knows that you can easily make a plugin for Windows Live Writer, but one of the APIs that's not as well known or spoken about is the Windows Live Writer Application API. This set of API calls will allow you to open Windows Live Writer in a particular way. What do I mean by that? Well, you can open Live Writer at the Open Post window, or the options window, as just a couple of examples. The real power with this API is the BlogThis set of calls. Some of you might be familiar with the Blog This addins for Internet Explorer (no longer available) and Firefox, which would allow you to click on the Blog This button in your browser, and it would open up Live Writer with either the page details loaded in Writer, or the highlighted text from the webpage you were viewing. Also anyone who uses my Live Writer sidebar gadget in Vista, this uses the same principle. In this article I will show you how to write a simple Windows application that uses some of the BlogThis calls. To start off, make sure you have the latest version of Windows Live Writer installed by going to http://writer.live.com/. Now, create a new project in Visual Studio and add a reference in that project to the Windows Live Writer COM assembly (C:\Program Files\Windows Live\Writer\WindowsLiveWriter.Application.dll) and then for using it we put: using WindowsLiveWriterApplicationLib;
Now we have to create an instance of the WindowsLiveWriterApplicationLibClass: WindowsLiveWriterApplicationClass wlwapp; public Form1() { InitializeComponent(); wlwapp = new WindowsLiveWriterApplicationClass(); cbOptions.SelectedIndex = 5; } Now, for this example I have just created a basic WinForms application with a series of buttons for showing the different functions, it looks like this:
This App will show a few examples, but not all, after a certain point, they're all one and the same really, just for a different use. We'll start off with the basic Open Writer button. The call that we make for this one is NewPost(), as that is effectively opening Writer as if running the program from a shortcut. So the code for this is: private void btnOpenWriter_Click(object sender, EventArgs e) { wlwapp.NewPost(); } For the Open Post button, we use OpenPost(): private void btnOpenPost_Click(object sender, EventArgs e) { wlwapp.OpenPost(); } Now for the Open Options button, we use the ShowOptions() call. This call can be made with no parameters, and it will default to the preferences tab in the options window. However, you can put in a string parameter to open a different tab from the options window, and you can choose from the following: "preferences", “accounts”, "blogthis", “spelling”, “glossary”, "plugins", "webproxy", and "pings". And you can see from my App that I have put this in a drop down: Which for the code looks like: private void btnOpenOptions_Click(object sender, EventArgs e) { string option = cbOptions.SelectedItem.ToString(); wlwapp.ShowOptions(option); } Now, the cool thing about this API is when it comes to putting images into a blog post and there are a couple of methods you can use for Images, one is for a single image, and one is for an image-set, so for multiple images. I'll start with the single image method first which uses the BlogThisImageFile() call: private void btnOpenWithImage_Click(object sender, EventArgs e) { DialogResult result = openFileDialog1.ShowDialog(); if (result == DialogResult.OK) { string title = string.Empty; if (!string.IsNullOrEmpty(txbxBlogTitle.Text)) { title = txbxBlogTitle.Text; } else { title = "My New Blog Post"; } string imagefile = openFileDialog1.FileName; // Open a new post using the imagefile we just selected wlwapp.BlogThisImageFile(title, imagefile, txbxComment.Text); } } And for multiple images, we use the BlogThisImageFileList() call: private void btnOpenWithFiles_Click(object sender, EventArgs e) { DialogResult result = openFileDialog2.ShowDialog(); if (result == DialogResult.OK) { string title = string.Empty; if (!string.IsNullOrEmpty(txbxBlogTitle.Text)) { title = txbxBlogTitle.Text; } else { title = "My New Blog Post"; } string[] imagefiles = openFileDialog2.FileNames; // Open a new post with the files we selected wlwapp.BlogThisImageFileList(title, imagefiles, txbxComment.Text); } } The BlogThis set of calls also has one for URLs, BlogThisLink(), which will most likely be what the Blog This add-ins for IE and FF use. The code for this is: private void btnOpenUrl_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(txbxUrl.Text) && txbxUrl.Text.StartsWith("http://")) { label3.ForeColor = Color.Black; string title = string.Empty; if (!string.IsNullOrEmpty(txbxBlogTitle.Text)) { title = txbxBlogTitle.Text; } else { title = "My New Blog Post"; } wlwapp.BlogThisLink(title, txbxUrl.Text, txbxComment.Text); } else { label3.ForeColor = Color.Red; } } As I mentioned, I'm not going to go into detail about the others, but I will give a quick description of them:
There are some good examples of where these API calls have been used, and I have tried to cover the main ones in this post, although one I haven't mentioned is one I used quite frequently, which is the Live Writer System Tray App, which works in a similar way to my sidebar gadget. If you wish to download the source code for my example app, you can do so from my SkyDrive area. SL March 17 Insert Video Source Code Released!In a decision I have been mulling over for quite some time now, I have finally decided to release my Insert Video plugin's source code. The reason I hadn't released it before was because of the amount of time and effort I had put into making the plugin, it was my pride and joy, and I wasn't comfortable releasing all my hard work so freely, call it selfish if you will, I don't care If I'm honest though, the main reason I have released this isn't so people can see how I made the plugin, but to be able to add to it themselves. I have a number of projects that I'm working on at the moment and just don't have the time to maintain the plugin, to add in the video sites that people are requesting. So I figured if the source code is out there, the community themselves can actually update and build the plugin themselves with added sites. Now, I will warn any enthusiast that wants to look at the code, it's not clean, this was mainly written about 18 months ago and I was still very much finding my feet when it came to programming, having just got back into it again. There are virtually no comments, if any at all. My logic, whilst seemingly logical to me, might escape others and have them scratching their head thinking "what the f...". I don't blame you, I actually had the same problem when I did the last update So, go over to the source code now on CodePlex: http://www.codeplex.com/InsertVideo SL Whilst writing this I was listening to Oasis - 10 Cigarettes & Alcohol Insert IMDb PluginFor the longest time I've wanted to do a plugin for IMDb, but unfortunately, they don't offer any kind of API to tap into, which would mean doing a whole bunch of screenscraping, which to be honest, I really couldn't be bothered to do. Now, IMDb still doesn't offer any kind of API, but I was on CodePlex the other day and found someone has been writing a wrapper for IMDb that does all the screenscraping that I would have to have done. Great It's very easy to use, there are two methods in which you can get the film details, you can either search for the film you want, or if you have the IMDb link, you can paste the link in and get the relevant details: So now that you have the film information you want, you can choose what parts of it to put in your blog entry, so if you didn't want the description to appear, just untick it and it won't appear. Once you're ready to insert, hit Insert and you'll get something like this: Jurassic Park Sam Neill, Jeff Goldblum, Bob Peck, Joseph Mazzello, Samuel L. Jackson, Wayne Knight Scientists clone dinosaurs to populate a theme park which suffers a major security breakdown and releases the dinosaurs. Easy huh. Now, when it comes to what information you want to show, I have given three predefined templates, or you can choose a custom option: Now, as I mentioned, I'm using the IMDb wrapper from CodePlex, but I had to make a slight alteration to its code for use in the plugin, so the plugin itself comes with a slightly custom build of the wrapper. All I did was change the following line of code from: Wc.Proxy = Nothing to: Wc.Proxy = PluginHttpRequest.GetWriterProxy() This makes sure my plugin carries on like my other plugins in using Writer's proxy settings so it can be used behind a proxy. As the source code for the original wrapper is Open Source, I have also included the modified source code within my own project page on CodePlex. I should however note that the wrapper was written in .NET 3.5 which means for my plugin to use it, it had to be built in .NET 3.5 too, which was kind of annoying, but hey ho. If you want to use this plugin you have to make sure you have .NET 3.5 installed. If you don't you'll be prompted by the installer anyway. Download: http://gallery.live.com/LiveItemDetail.aspx?li=aa71d18d-e738-475d-85fa-198c64ea3987 SL Whilst writing this I was listening to Manic Street Preachers - Interiors (Song for Willem De Kooning )
|
|||||
|
|