Posted on March 22, 2008 12:24 by mcollins

On occasion, I have needed to write web applications for personal use or for my employers or clients.  These web applications have done different things, from being a full-fledged ERP application to being a personal website (my arch-nemesis) to being a website for an actual company.  One constant function that always seems to pop up for websites and web applications is the concept of content management.

(I should probably qualify this post by saying that I define a website as being what we normally expect a site to be.  For example, this blog is a website.  MSNBC News is a website.  However, there's an administrative piece to this blog, which I would consider a web application.  An ERP application with a web front end is a web application.)

In discussing content management, the first question to pop up is based around keeping content up to date.  "How do we update existing content?"  "How do we publish new items to the site?" "Can our marketing department do this?"

The good news to all of these topics is yes, but it requires some work from the developers to implement.  We live in a golden age right now in that the web has finally matured, and some of the desktop tools are starting to catch up.  In the earlier days of the web, users had to type the new content into a web form.  WYSIWYG editors based on MSHTML for example started showing up to allow users to do rich text formatting inside of a web page.  That was a step forward, but it really wasn't what everyone wanted to get to.

Now in the present, we have two really good tools for content management and publishing: Windows Live Writer from Microsoft and Microsoft Office Word 2007.  Both tools offer an ideal solution (and Windows Live Writer offers a better solution).  Both tools let content writers create, proof, and edit their content on their desktop or laptop machines, and when the content is ready to be published, both tools can communicate with web applications that implement open standards to publish the content to the websites.

So, how does this content publishing get done?  The answer is in the standards that other applications are using.  We could always build our own interface, but the advantages are that we don't need to rebuild Windows Live Writer if we follow the other open standards.  The most popular (in my opinion) standards right now are based on an XML-RPC protocol called the MetaWeblog API.  Using MetaWeblog, a tool such as Word or Windows Live Writer can make HTTP calls to the website and transfer the text for content plus any associated images.  MetaWeblog is a standard that developed from another earlier API that was developed for the Blogger blogging service.  MetaWeblog fixed some of the shortcomings of the API, but rather than replace the Blogger API, MetaWeblog enhanced it while leaving some of the functionality of the Blogger API in use.  In my next post, we'll take a look at the MetaWeblog API.  In this post however, we're going to look at the Blogger API.

First, my implementation of the Blogger API is using XML-RPC.NET from Cook Computing.  This is an excellent .NET implementation of the XML-RPC protocol and integrates very nicely into any ASP.NET website or web application.

The Blogger API specification can be found here.

The Blogger API defines seven operations that can be used by clients:

  • blogger.deletePost: deletes an existing post from a blog
  • blogger.editPost: edits an existing post on a blog
  • blogger.getTemplate: retrieves the text for the blog template for use in WYSIWYG editors
  • blogger.getUserInfo: retrieves the name of a user and the user's email address from the blog
  • blogger.getUsersBlogs: retrieves the list of blogs on the website that the user can post to
  • blogger.newPost: publishes a new post to a blog
  • blogger.setTemplate: uploads a new HTML template for a blog

 

Now, reading through this list of operations, two words are going to stick out to most readers: "post" and "blog."  You may now be asking yourself, is this really relevant to me because I'm not writing a blog.  The answer is yes, if you think of this API and these terms in abstract terms (couldn't come up with a better word than repeating terms...it's a Saturday morning...you can't expect too much from me).

So if I'm not writing a blog, can I still use the Blogger API?  Sure.  Think about it from the concept of another application.  What if you're building a knowledge base or a FAQ list for a customer.  They're not blogs, but they store content like a blog.  And a post could be a question on an FAQ, or a knowledge base item on a knowledge base, couldn't it?  Or if you're writing a news website, couldn't the "blog" be the news website and a post be an article?  The answer to al of these questions is yes.  You just need to fit these terms into the content management solution that you're building.

Back to our Blogger API implementation. the first thing that we want to do with our new website is to publish content to the site.  So we're going to start out with defining the blogger.newPost operation to allow us to publish contet to a website using the Blogger API.  Here's how that method is defined:

   1: [XmlRpcMethod("blogger.newPost",
   2:     Description = "Makes a new post to a blog.")]
   3: string NewPost(string appKey, string blogId, string userName,
   4:     string password, string content, bool publish);

 

In the above code sample, I defined a method named NewPost which will implement the blogger.newPost operation.  You'll also see on line 1, that I decorated the NewPost method with the XmlRpcMethodAttribute attribute.  The XmlRpcMethodAttribute class is defined by XML-RPC.NET and allows me to bind an XML-RPC operation to a .NET method.  When we actually add this method to an XML-RPC web service later in this post, any XML-RPC requests received by our web application requesting the method blogger.newPost will be directed to our NewPost implementation.

The NewPost method takes six parameters.  The appKey parameter is for the most part ignored.  I think that back in the early days of Blogger, Blogger probably assigned unique keys to each client application that had signed up to use the XML-RPC API.  Over time, I'm guessing that they moved away from this practice, which is why this key is not used.  It's very safe to go ahead and ignore this parameter.

The blogId parameter is the unique identifier of the blog where the new content should be posted to.  Again, if you're not writing a blog, this could be a unique identifier you assign to your website, a category, some sub-application, etc.  The meaning of blogId is open for you to determine in your implementation.

The userName and password parameters are obviously the user name and password of the user publishing the content to the website.  You could use these fields in an ASP.NET application for example to verify the user against the ASP.NET membership database or your proprietary user store.

The content parameter is the important stuff.  This parameter will contain the text or HTML text of the content being published to the website.  This is obviously the data that you're going to store and display on your web pages.

The publish parameter is a boolean parameter that is set to true if the author wants to make the content immediately available on the website, or save the content to be published at a later time if this parameter is set to false.  When I implement this interface, I usually have a binary field on my content table that I store this value in.  I'll then use that binary field to determine what content gets displayed on my web page.

The return value for the blogger.NewPost operation is the unique identifier for the new post, if the new post was published or saved to the blog (or website) successfully.

Assuming that we've successfully published a new post up to the website, what happens if we discover an error that we want to fix and update the website with the corrected content?  This is where the blogger.editPost operation comes into play:

   1: [XmlRpcMethod("blogger.editPost",
   2:     Description = "Changes the contents of the specified post.")]
   3: bool EditPost(string appKey, string postId, string userName,
   4:     string password, string content, bool publish);

 

The parameters for the EditPost operation look pretty similar to the NewPost operation, so I won't rehash them.  The only difference is that where NewPost accepted a blogId identifier to identify the blog that the new post was being published to, EditPost accepts the unique identifier of the post being edited.  This is the same value that was returned by NewPost as its return value.  All of the other parameters are the same.

The publish parameter of EditPost, serves the same purpose as in NewPost.  One reason why it's here on the EditPost operation too is that the author may not have published the new content when NewPost was called, but now the author wants to publish the content on the site.  The author can use EditPost to change the value of the "is published" flag.

The return value for EditPost is always true.  If an error occurred in editing or updating the post, then the XML-RPC operation should return a fault, which XML-RPC.NET will turn into a .NET exception.

On to our third operation: blogger.deletePost.  Obviously, this operation is used to delete a post that has already been published on the blog.

   1: [XmlRpcMethod("blogger.deletePost",
   2:     Description = "Deletes a post from the blog.")]
   3: bool DeletePost(string appKey, string postId, string userName,
   4:     string password, bool publish);

 

The only parameter here that doesn't make sense if the publish parameter.  It can be safely ignored.  Again, this operation will always return true, or will return a fault if an error occurs.

The next operation of interest is blogger.getUsersBlogs.  This operation is used in a multi-blog scenario where an author has the capability of publishing to many blogs or content areas.  Recall that the blogger.newPost operation requires the unique identifier of a blog to publish to?  Where does a client application get a list of the available blogs?  blogger.getUsersBlogs.

   1: [XmlRpcMethod("blogger.getUsersBlogs",
   2:     Description = "Returns information about all of the blogs that " +
   3:     "the user is a member of.")]
   4: Blog[] GetUsersBlogs(string appKey, string userName, string password);

 

The return value of blogger.getUsersBlogs is an array of structures containing information about the available blogs.  This structure looks like the following:

   1: [Serializable]
   2: [XmlRpcMissingMapping(MappingAction.Error)]
   3: public class Blog {
   4:     /// <summary>
   5:     /// The unique identifier of the blog.
   6:     /// </summary>
   7:     [SuppressMessage("Microsoft.Design", "CA1051",
   8:         Justification = "Public fields must be exposed for XML-RPC.NET")]
   9:     [SuppressMessage("Microsoft.Naming", "CA1704",
  10:         Justification = "The field name is specified by the Blogger API")]
  11:     public string blogid;
  12:  
  13:     /// <summary>
  14:     /// The name of the blog.
  15:     /// </summary>
  16:     [SuppressMessage("Microsoft.Design", "CA1051",
  17:         Justification = "Public fields must be exposed for XML-RPC.NET")]
  18:     public string blogName;
  19:  
  20:     /// <summary>
  21:     /// The URL where the blog is hosted.
  22:     /// </summary>
  23:     [SuppressMessage("Microsoft.Design", "CA1051",
  24:         Justification = "Public fields must be exposed for XML-RPC.NET")]
  25:     public string url;
  26: }

 

This structure has three fields: blogid, blogName, and url.  The blogid field is the blog's unique identifier that is sent to blogger.newPost.  The blogName parameter is something descriptive such as the title of the blog.  The url parameter is the URL of the home page for the blog.

A couple of .NET implementation notes, the structure doesn't have to be serializable, but I decorated the type with the SerializableAttribute attribute for my own use internally to my application.  Also, I added the SuppressMessageAttribute attributes to the structure to get around the FxCop errors that were being raised when validating this code.  At the time that I wrote this, XML-RPC.NET can only read public fields when serializing/deserializing XML-RPC strucutres.  I don't understand why public properties were not acceptable, but this is the way that it works.  I guess that I could always fix XML-RPC.NET, but I'm not losing sleep over this little detail and I want to implement the Blogger API, not rewrite XML-RPC.NET when there's a workaround that I can live with.

Also, I chose a class instead of a structure because internally I might build the list of blogs up in a collection type such as a List.  Reference types such as objects work better with these collection types than value-based types such as structs do.  That was my reasoning behind using a class and not a struct.

The next operation of interest is blogger.getUserInfo.  This operation can be called by a blogging client to get metadata about the blogger.

   1: [XmlRpcMethod("blogger.getUserInfo",
   2:     Description = "Returns information about the specified user.")]
   3: User GetUserInfo(string appKey, string userName, string password);

 

The User structure used by this method is defined below:

   1: [Serializable]
   2: [XmlRpcMissingMapping(MappingAction.Error)]
   3: public class User {
   4:     /// <summary>
   5:     /// The unique identifier for the user.
   6:     /// </summary>
   7:     [SuppressMessage("Microsoft.Design", "CA1051",
   8:         Justification = "Public fields must be exposed for XML-RPC.NET")]
   9:     [SuppressMessage("Microsoft.Naming", "CA1704",
  10:         Justification = "The field name is specified by the Blogger API")]
  11:     public string userid;
  12:  
  13:     /// <summary>
  14:     /// The user's first name.
  15:     /// </summary>
  16:     [SuppressMessage("Microsoft.Design", "CA1051",
  17:         Justification = "Public fields must be exposed for XML-RPC.NET")]
  18:     [SuppressMessage("Microsoft.Naming", "CA1704",
  19:         Justification = "The field name is specified by the Blogger API")]
  20:     public string firstname;
  21:  
  22:     /// <summary>
  23:     /// The user's last name.
  24:     /// </summary>
  25:     [SuppressMessage("Microsoft.Design", "CA1051",
  26:         Justification = "Public fields must be exposed for XML-RPC.NET")]
  27:     [SuppressMessage("Microsoft.Naming", "CA1704",
  28:         Justification = "The field name is specified by the Blogger API")]
  29:     public string lastname;
  30:  
  31:     /// <summary>
  32:     /// The user's nick name.
  33:     /// </summary>
  34:     [SuppressMessage("Microsoft.Design", "CA1051",
  35:         Justification = "Public fields must be exposed for XML-RPC.NET")]
  36:     public string nickname;
  37:  
  38:     /// <summary>
  39:     /// The user's email address.
  40:     /// </summary>
  41:     [SuppressMessage("Microsoft.Design", "CA1051",
  42:         Justification = "Public fields must be exposed for XML-RPC.NET")]
  43:     public string email;
  44:  
  45:     /// <summary>
  46:     /// The URL for the user's website or blog.
  47:     /// </summary>
  48:     [SuppressMessage("Microsoft.Design", "CA1051",
  49:         Justification = "Public fields must be exposed for XML-RPC.NET")]
  50:     public string url;
  51: }

 

Again, I made the same implementation decisions that I did with the above Blog structure.

The final two methods are used by WYSIWYG editors to download or replace the templates being used by the blogs.  As far as I can tell, these operations aren't being used by any current clients, however, here they are for completeness to the specification:

   1: [XmlRpcMethod("blogger.getTemplate",
   2:     Description = "Returns the text of the main or archive index " +
   3:     "template for the specified blog.")]
   4: string GetTemplate(string appKey, string blogId, string userName,
   5:     string password, string templateType);
   6:  
   7: [XmlRpcMethod("blogger.setTemplate",
   8:     Description = "Changes the template for the specified blog.")]
   9: bool SetTemplate(string appKey, string blogId, string userName,
  10:     string password, string templateText, string templateType);

 

The GetTemplate operation returns the text for the specified template.  The templateType parameter is going to identify which template to return.  According to the specification, there may be two templates.  The first template, identified by the type "main," returns the HTML for the home page of the blog.  The second template, identified by the type "archiveIndex," returns the HTML for a page that shows the summary of past posts on the blog.

In the SetTemplate operation, the parameter templateText contains the new HTML content for the home page or archive page, as indicated by the templateType parameter.  Like the other methods above, SetTemplate will always return true unless an error occurs and a fault is returned.

Here's the complete definition of my Blogger API operations, defined in a .NET interface that we'll use in a later post to implement these methods:

   1: /// <summary>
   2: /// Defines the XML-RPC operations that are supported by the Blogger
   3: /// API for clients to use to publish content to a website or blog.
   4: /// </summary>
   5: public interface IBloggerService {
   6:     /// <summary>
   7:     /// Deletes a post from the blog.
   8:     /// </summary>
   9:     /// <param name="appKey">
  10:     /// The unique identifier or passcode of the application deleting
  11:     /// the post. This parameter is typically ignored.
  12:     /// </param>
  13:     /// <param name="postId">
  14:     /// The unique identifier of the post to be deleted.
  15:     /// </param>
  16:     /// <param name="userName">
  17:     /// The login for a user that can delete the post.
  18:     /// </param>
  19:     /// <param name="password">The user's password.</param>
  20:     /// <param name="publish">This parameter is ignored.</param>
  21:     /// <returns>
  22:     /// Returns true if the post was successfully deleted.
  23:     /// </returns>
  24:     [XmlRpcMethod("blogger.deletePost",
  25:         Description = "Deletes a post from the blog.")]
  26:     bool DeletePost(string appKey, string postId, string userName,
  27:         string password, bool publish);
  28:  
  29:     /// <summary>
  30:     /// Changes the contents of the specified post.
  31:     /// </summary>
  32:     /// <remarks>
  33:     /// If <paramref name="publish"/> is set to true, then the post
  34:     /// should be published.
  35:     /// </remarks>
  36:     /// <param name="appKey">
  37:     /// The unique identifier or passcode of the application sending the
  38:     /// post. This parameter is typically ignored.
  39:     /// </param>
  40:     /// <param name="postId">
  41:     /// The unique identifier of the post that will be changed.
  42:     /// </param>
  43:     /// <param name="userName">
  44:     /// The login for a user who has permission to post to the blog.
  45:     /// </param>
  46:     /// <param name="password">
  47:     /// The password for the user.
  48:     /// </param>
  49:     /// <param name="content">
  50:     /// The contents of the post.
  51:     /// </param>
  52:     /// <param name="publish">
  53:     /// True if the post should be published immediately.
  54:     /// </param>
  55:     /// <returns>
  56:     /// Returns true if the post was successfully updated.
  57:     /// </returns>
  58:     [XmlRpcMethod("blogger.editPost",
  59:         Description = "Changes the contents of the specified post.")]
  60:     bool EditPost(string appKey, string postId, string userName,
  61:         string password, string content, bool publish);
  62:  
  63:     /// <summary>
  64:     /// Returns the text of the main or archive index template for the
  65:     /// specified blog.
  66:     /// </summary>
  67:     /// <param name="appKey">
  68:     /// The unique identifier or passcode of the application sending the
  69:     /// post. This parameter is typically ignored.
  70:     /// </param>
  71:     /// <param name="blogId">
  72:     /// The unique identifier of the blog whose template is to be returned.
  73:     /// </param>
  74:     /// <param name="userName">
  75:     /// The login for a user who has administrator permissions on the
  76:     /// specified blog.
  77:     /// </param>
  78:     /// <param name="password">
  79:     /// The user's password.
  80:     /// </param>
  81:     /// <param name="templateType">
  82:     /// <list>
  83:     /// <listheader>
  84:     /// <term>Template type</term>
  85:     /// <description>Description</description>
  86:     /// </listheader>
  87:     /// <item>
  88:     /// <term>main</term>
  89:     /// <description>
  90:     /// Returns the text for the main template of the blog.
  91:     /// </description>
  92:     /// </item>
  93:     /// <item>
  94:     /// <term>archiveIndex</term>
  95:     /// <description>
  96:     /// Returns the text for the archive index template of the blog.
  97:     /// </description>
  98:     /// </item>
  99:     /// </list>
 100:     /// </param>
 101:     /// <returns>
 102:     /// Returns the text of the specified blog template.
 103:     /// </returns>
 104:     [XmlRpcMethod("blogger.getTemplate",
 105:         Description = "Returns the text of the main or archive index " +
 106:         "template for the specified blog.")]
 107:     string GetTemplate(string appKey, string blogId, string userName,
 108:         string password, string templateType);
 109:  
 110:     /// <summary>
 111:     /// Returns information about the requested user.
 112:     /// </summary>
 113:     /// <param name="appKey">
 114:     /// The unique identifier or passcode of the application sending the
 115:     /// post. This parameter is typically ignored.
 116:     /// </param>
 117:     /// <param name="userName">
 118:     /// The login for the user whose information will be retrieved.
 119:     /// </param>
 120:     /// <param name="password">
 121:     /// The password for the user.
 122:     /// </param>
 123:     /// <returns>
 124:     /// Returns a structure containing the user's name, email address,
 125:     /// and website URL.
 126:     /// </returns>
 127:     [XmlRpcMethod("blogger.getUserInfo",
 128:         Description = "Returns information about the specified user.")]
 129:     User GetUserInfo(string appKey, string userName, string password);
 130:  
 131:     /// <summary>
 132:     /// Returns information about all of the blogs that the specified
 133:     /// user is a member of.
 134:     /// </summary>
 135:     /// <param name="appKey">
 136:     /// The unique identifier or passcode of the application sending the
 137:     /// post. This parameter is typically ignored.
 138:     /// </param>
 139:     /// <param name="userName">
 140:     /// The login for the user whose blogs will be retrieved.
 141:     /// </param>
 142:     /// <param name="password">
 143:     /// The password for the user.
 144:     /// </param>
 145:     /// <returns>
 146:     /// Returns an array of <see cref="Blog"/> objects describing the
 147:     /// blogs that the specified user has access to.
 148:     /// </returns>
 149:     [XmlRpcMethod("blogger.getUsersBlogs",
 150:         Description = "Returns information about all of the blogs that " +
 151:         "the user is a member of.")]
 152:     Blog[] GetUsersBlogs(string appKey, string userName, string password);
 153:  
 154:     /// <summary>
 155:     /// Makes a new post to a designated blog.
 156:     /// </summary>
 157:     /// <remarks>
 158:     /// If publish is set to true, then the post should
 159:     /// be published.
 160:     /// </remarks>
 161:     /// <param name="appKey">
 162:     /// The unique identifier or passcode of the application sending the
 163:     /// post. This parameter is typically ignored.
 164:     /// </param>
 165:     /// <param name="blogId">
 166:     /// The unique identifier of the blog that the post will be added to.
 167:     /// </param>
 168:     /// <param name="userName">
 169:     /// The login for a user who has permission to post to the blog.
 170:     /// </param>
 171:     /// <param name="password">
 172:     /// The password for the user.
 173:     /// </param>
 174:     /// <param name="content">
 175:     /// The contents of the post.
 176:     /// </param>
 177:     /// <param name="publish">
 178:     /// True if the post should be published immediately.
 179:     /// </param>
 180:     /// <returns>
 181:     /// Returns the unique identifier of the new post.
 182:     /// </returns>
 183:     [XmlRpcMethod("blogger.newPost",
 184:         Description = "Makes a new post to a blog.")]
 185:     string NewPost(string appKey, string blogId, string userName,
 186:         string password, string content, bool publish);
 187:  
 188:     /// <summary>
 189:     /// Changes the template for the specified blog.
 190:     /// </summary>
 191:     /// <param name="appKey">
 192:     /// The unique identifier or passcode of the application sending the
 193:     /// post.
 194:     /// </param>
 195:     /// <param name="blogId">
 196:     /// The unique identifier of the blog whose template is to be changed.
 197:     /// </param>
 198:     /// <param name="userName">
 199:     /// The login for a user who has administrator permissions on the
 200:     /// specified blog.
 201:     /// </param>
 202:     /// <param name="password">
 203:     /// The user's password.
 204:     /// </param>
 205:     /// <param name="templateText">
 206:     /// The text for the new template.
 207:     /// </param>
 208:     /// <param name="templateType">
 209:     /// <list>
 210:     /// <listheader>
 211:     /// <term>Template type</term>
 212:     /// <description>Description</description>
 213:     /// </listheader>
 214:     /// <item>
 215:     /// <term>main</term>
 216:     /// <description>
 217:     /// Changes the text for the main template of the blog.
 218:     /// </description>
 219:     /// </item>
 220:     /// <item>
 221:     /// <term>archiveIndex</term>
 222:     /// <description>
 223:     /// Changes the text for the archive index template of the blog.
 224:     /// </description>
 225:     /// </item>
 226:     /// </list>
 227:     /// </param>
 228:     /// <returns></returns>
 229:     [XmlRpcMethod("blogger.setTemplate",
 230:         Description = "Changes the template for the specified blog.")]
 231:     bool SetTemplate(string appKey, string blogId, string userName,
 232:         string password, string templateText, string templateType);
 233: }

 

In my next post, we'll expand upon the Blogger API by implementing the MetaWeblog API which will give us the ability to publish to a website using Microsoft Office Word 2007 or Windows Live Writer.  We'll also start to look at implementing these operations to actually do something.

Technorati tags: , , , ,


Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Related posts

Comments

September 19. 2009 15:38

i like
|

Tiffany Necklaces

October 2. 2009 13:11

art is a lie that tells the truth ugg classic cardy. Humor has been well defined as ugg calssic thinking in fun while feeling in earnest.The decline of literature indicates the decline of a ugg sale online nation ; the two ugg bailey button keep in their ugg classic min downward tendency. http://www.olugg.com/
|

ugg boots sale

October 2. 2009 14:01

cheap nokia phones life is the art of drawing nokia 8800 on sale sufficient conclusions from insufficient premises.Better to light one nokia 8800 candle than to curse the darkness. We can't all be apple heroes. Fear not that the life shall come to an end, but rather fear that it shall never have a ghd beginning. http://www.shopeday.com/
|

Bose headphones

October 7. 2009 16:44

Fear not that the chi flat iron life shall come to an end, but rather fear that it shall never have a ghd iv dark styler beginning. ghd iv kiss styler it is while you are patiently toiling at the little tasks of ghd hair iron life that the meaning and shape of great whole ghd mk4 iron of life dawn on you. http://www.ghdhairon.com/
|

GHD Hair Iron

October 8. 2009 00:09

You can't step twice into the same ugg boots river, for other ugg classic cardy waters are continually flowing in. In the ugg bailey button long run men hit only what they aim at ugg lo pro button. High expectations are the key to every UGG Knightsbridge thing. If you wait, all that happens is that you get older. http://www.ladiesugg.com/
|

Ugg Sale

October 11. 2009 01:54

Art is a lie that tells the truth ugg knightsbridge. Humor has been well defined as ugg lo pro button thinking in fun while feeling in earnest.The decline of literature indicates the decline of an ugg boots nation ; the two ugg bailey button keep in their uggs boots downward tendency.
http://www.olugg.com/
|

UGG Boots All On Sale

October 11. 2009 22:56

An ugg bailey button better be unborn than untaught,for ignorance is the root of misfortune.Genius17 withoutugg knightsbridge education is like silver in the mine. ugg boots man is not made for defeat. an uggs boots man can be destroyed but not defeated.No rational man can die without ugg lo pro button? uneasy apprehension.
http://www.love-ugg.com/
|

Ugg Boots On Sale

October 13. 2009 21:52

To most ugg boots men , the ugg bailey button experience is like the stern light of an ugg lo pro button ship which il-luminates only the uggs boots track it has passed. Too much ugg knightsbridge experience is a dangerous thing. We know nothing of what will happen in future , but by the analogy of past experience. Absence to love is what wind is to fire. It extinguishes the small; it inflames the great. http://www.hideboots.com/

|

ugg bailey button

October 14. 2009 21:37

The only chi flat iron ones among you who will be really happy ghd iv kiss styler are those who will have sought and foundhow to ghd hair serve. When the fight begins buy cheap ghd styler within himself, a man's worth something ghd iv dark sttyler. http://www.stylerghd.com/
|

ghd styler

October 14. 2009 21:38

The only chi flat iron ones among you who will be really happy ghd iv kiss styler are those who will have sought and foundhow to ghd hair serve. When the fight begins buy cheap ghd styler within himself, a man's worth something ghd iv dark sttyler. http://www.stylerghd.com/
|

ghd styler

October 15. 2009 18:44

When the fight begins within ugg bailey button himself, a man's worth something ugg lo pro button.Have no fear of perfection---you'll never reach it. uggs boots it is better to die on your feet than to live on your knees. ugg boots life is not all beer and skittles. Fear not that the life shall come to an end, but rather fear that it shall never have a ugg knightsbridge beginning. http://www.4ezlive.com/
|

UGG Boots

October 28. 2009 04:04

<h2 align="center">The warmest ugg boots</h2>
<p>While access to source sheepskin is more and more expensive, in order to create the warmest and highest quality <a href="www.goodugg.co.uk/...short-c-160.html">ugg" rel="nofollow">www.goodugg.co.uk/...short-c-160.html">ugg boots</a>, we are still at the cost of manufacturing. In addition to perfect our sheep fleece, the inner is extremely dense, so that your feet are wrapped in a fleece and fluffy soft and warm.</p>
<p>--&gt;<strong>The improvements come with toes</strong><br />
Traditional <a href="www.goodugg.co.uk/...ots-p-24145.html">ugg boots</a> are cosy, soft and easy to wear. The inner sheepskin fibres are denser, plusher and much softer on your skin, and the sheepskin definitely won't scratch your skin or cause odour problems associated with tradition ugg boots. You can actually see the difference very clearly.<br>
--&gt;<strong>Designed for bare toes</strong><br />
This premium graded sheepskin <a href="www.goodugg.co.uk/...-tall-c-162.html">ugg" rel="nofollow">www.goodugg.co.uk/...-tall-c-162.html">ugg tall boots</a> creates the worlds warmest and cosiest fashion icon. The thicker inner fleece acts as natural air conditioner, circulating and maintaining body warmth on colder days. Designed for bare feet our boots offer the ultimate indulgence in luxury and comfort.<br>
--&gt;<strong>Actively remove foot odor</strong><br />
A thicker spongy fleece of <a href="www.goodugg.co.uk/...short-c-160.html">ugg" rel="nofollow">www.goodugg.co.uk/...short-c-160.html">ugg classic short</a> will circulate more air. Synthetic ugg boots created from lower grade sheepskin do not posses this ability to circulate air as effectively as merino sheepskin. <br>
--&gt;<strong>Comfortable all year round</strong><br />
The worlds warmest <a href="www.goodugg.co.uk/...-tall-c-167.html">ugg boots</a> are also the worlds coolest, but only when your feet need chilling of course! Our thicker fleece allows your toes to enjoy their favourite footwear all year round.<br>
--&gt;<strong>Fashion Laws</strong><br />
The sheepskin boots and ugg boots women choose are predominantly of the <a href="www.goodugg.co.uk/...p-23487.html">classic tall ugg boot</a> or classic short styles. Proving that sheepskin boots truly are unisex.</p>
<p>We have to savor the hidden glamour of Ugg Boots with a different angle.</p>
<p>All rights reserved, reprint, please specify source comes from <a href="www.goodugg.co.uk/.../a> --<a href="www.goodugg.co.uk/...on-c-178.html">bailey button</a>,<a href="www.goodugg.co.uk/...ridge-c-321.html">ugg knightsbridge boots</a>,<a href="www.goodugg.co.uk/...rdy-c-161.html">cardy boots</a>,<a href="www.goodugg.co.uk/...-tall-c-162.html">ugg" rel="nofollow">www.goodugg.co.uk/...-tall-c-162.html">ugg tall classic</a></p>
|

angelia110

November 25. 2009 03:23



<a href="http://www.asicscloset.com/">asics onitsuka shoes</a>
<a href="www.asicscloset.com/...50.html">Discounted Women's asics onitsuka tiger mexico 66 shoes</a>
<a href="www.asicscloset.com/...c-46_52.html">Cheap men's asics onitsuka tiger mini clubman shoes</a>
|

asics onitsuka

November 25. 2009 21:36

good, great article, very usefull for us...thank you
|

mengembalikan jati diri bangsa

November 27. 2009 13:43

If a man join together to pursuit knowledge, no one can take it from him.cheap nfl jersys Books are to human beings which as nba jerseys sale emory to the individuanl nhl Jerseys.We cannot change anything mlb jerseys unless we learn and accept it, Damn does not liberate it, it oppresses.A classic adidas jerseys book which people praise but don't read.A man dies still if he has done nothing, as one who has done football child jerseys much.Education is something? which remains ofter one has forgotten everything football jerseys he learned in school.Education is something remains ofter one has forgotten everything he learned in school.http://www.nfljerseymlb.com/
|

cheap nhl jersey sale

November 27. 2009 13:44

Sorrow is peace in my heart like the ugg 5806 boots evening among the tall upside lace uggs silent trees.if you tears when you miss the ugg 5817 style boots sun, you will also miss the stars.her eager ugg 5819 fur boots face bothers my ugg 5842 classic boots dreams as the ugg 30th anniversary rain at ugg 5691 lo pro button night.once we dreamt that we were ugg 5202 infant's erin strangers. when we wake up we find that we were to love each other's. http://www.uggboots4buy.com/
|

ugg fur boots 5817

November 27. 2009 21:13

Something tried, something done.The people who get success in this world are efforts to look for air jordan 2 men opportunities they want, and if they cannot find af1 25th women, make them nike nz men.Not by restraint and severity shall you can access to true nike r5 kids wisdom, but by laissez-faire, and nike tl3 women childlike mirthfulness. If you would to know angthing about d&g high men, you should keep a happy ed hardy high boots mood.Where there is no desire, there will be no industrious.http://www.nikejordanshoes2sell.com/
|

Nike Jordan shoes,UGG boots, fashion high-heeled

November 27. 2009 21:13

Education makes a national easy to lead, but difficult to drive; easy to govern ugg sienna miller, but impossible to slavery.Determined to act christian louboutin high boots Decisivly and to bear the consequences. in this versace high boots world, hesitation can not access to ugg 30th anniversary success.jodan 1 women Learning is like nike shox nz sailing against the current d&g men high cut , not to advance is to drop back.http://www.onestop-onlineshopping.com/
|

Jordan shoes,edhardy shoes, Christian Louboutin boots

November 27. 2009 21:13

The boundless desert is enthusiastic pursuit of the ugg 5806 boots love of a green ugg 5304 fluff flip flop grass who shakes ugg 5817 style boots and flies away in ugg 5812 classic metallic smile. it is the tall upside lace uggs tears of the ugg boots earth that keep her smiles in ugg 5819 fur boots bloomit is the tears of the ugg 30th anniversary earth that keep her ugg 5812 classic metallic smiles in bloom if you tears when you miss the ugg lace up sun, you will also miss the stars.dancing water,the sands in your way request your songs and your movement.http://www.uggboots2buy.com/

|

ugg boots, ugg slippers, ugg handbags

November 30. 2009 23:27

One mouse click often leads to another fine blog. Like yours - Thanks.
|

Jarrod Newton

December 1. 2009 17:43

I am thankful for the new things I learned reading your post. Thanks.
|

Patrick Mullen

December 1. 2009 18:14

This is wonderful news, publishing right from WORD 2007 !

Regards,

Wilbur
|

Wilbur Parker

December 10. 2009 08:01

This is my first time i visit here. I found so many interesting stuff in your blog especially its discussion. From the tons of comments on your articles, I guess I am not the only one having all the enjoyment here! keep up the good work.
|

Legalsounds

December 10. 2009 11:40

Not sure if any of your other visitors have asked this...but what kind of theme are you using for your blog? I really like the style. I am running a blog too but can't ever seem to find my perfect theme. This one is really close ...but I'd maybe tweak a few things in the Header for my style. thx.
|

stained glass window film

December 10. 2009 18:37

<a href="www.realuggbuy.com/...d-p-1102.html">cheap ugg classic tall boots</a><br>
<a href="www.realuggbuy.com/...and-p-1102.html">ugg 5815 Boots on sale</a><br>
<a href="www.realuggbuy.com/...nd-p-1102.htmll">ugg classic tall chestnut</a>
|

ugg classic tall chestnut

December 12. 2009 07:24

<a href="http://www.oluggs.com/">uggs on sale</a>
<a href="www.oluggs.com/uggbaileybuttonc39.html">bailey" rel="nofollow">www.oluggs.com/...eybuttonc39.html">bailey button</a>
<a href="www.oluggs.com/uggbaileybuttonc39.html"> cheap uggs</a>
<a href="www.oluggs.com/...ccardyc27.html">discount ugg boots</a>
<a href="www.oluggs.com/...assictallc31.html">women's ugg</a>
<a href="www.oluggs.com/uggmayfairec46.html">UGG Mayfaire</a>
<a href="www.oluggs.com/...tnutbootsp1067.html">ugg classic short chestnut</a>
<a href="www.oluggs.com/...lassicshortc30.html">ugg classic short </a>
<a href="www.oluggs.com/...bootsgreyp1113.html">ugg bailey button grey</a>
<a href="www.oluggs.com/uggsundancec35.html">ugg sundance boots</a>
<a href="www.oluggs.com/uggnightfallc34.html">ugg nightfall boots</a>
<a href="www.oluggs.com/uggultratallc38.html">ugg" rel="nofollow">www.oluggs.com/uggultratallc38.html">ugg ultra tall</a>
<a href="www.oluggs.com/uggultratallc38.html">ugg" rel="nofollow">www.oluggs.com/uggultratallc38.html">ugg ultral short</a>
<a href="www.oluggs.com/...ssiccardyc27.html">cardy boots</a>
<a href="http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg boots</a>
<a href="http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg boots sale</a>
<a href="http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg boots uk</a>
<a href="http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg" rel="nofollow">http://www.oluggs.com">ugg australia</a>
<a href="http://www.oluggs.com">cheap ugg boots</a>
<a href="www.oluggs.com/...lassiccardyc27.html">ugg cardy</a>
<a href="www.oluggs.com/uggbaileybuttonc39.html">bailey" rel="nofollow">www.oluggs.com/...eybuttonc39.html">bailey button uggs</a>
<a href="www.oluggs.com/uggbaileybuttonc39.html">ugg bailey</a>
<a href="www.oluggs.com/uggclassictallc31.html">ugg classic tall</a>
<a href="http://www.myugleahy.com/">uggs" rel="nofollow">http://www.myugleahy.com/">uggs on sale</a>
<a href="http://www.myugleahy.com/">ugg boots on sale</a>
<a href="http://www.myugleahy.com/">discount ugg boots</a><a href="www.myugleahy.com/...sicshortc86.html">UGG" rel="nofollow">www.myugleahy.com/...sicshortc86.html">UGG Classic</a>
<a href="www.myugleahy.com/...sicshortc86.html">UGG" rel="nofollow">www.myugleahy.com/...sicshortc86.html">UGG Classic Short</a>
<a href="www.myugleahy.com/...sictallc103.html">UGG Classic Tall</a>
<a href="www.myugleahy.com/...iccardyc104.html">UGG Classic Cardy</a>
<a href="www.myugleahy.com/...sicminic102.html">UGG Classic Mini</a>
|

UGGStyle

December 13. 2009 11:30

is the theme you using free?
|

Foam Topper

December 14. 2009 20:19

<strong><a href="www.souggs.com/specials.html">Australia Ugg Boots</a></strong> becoming more and more popular,new style <strong><a href="http://www.souggs.com/">ugg boots</a></strong> will be the best seller for this Christmas,includes<strong><a href="www.souggs.com/products_all.html">Ugg Knightsbridge</a>,<a href="www.souggs.com/...ley-button-c-2.html">UGG Bailey Button</a></strong>;and the <strong><a href="www.shoeshotsale.com/.../strong><strong><a href="www.souggs.com/ugg-tall-5815-c-3.html">ugg classic tall boots,</a></strong> <strong><a href="www.souggs.com/...cardy-5819-c-1.html">ugg cardy boots</a></strong> also hot sale for these years,you can choose your lovely <strong><a href="www.souggs.com/products_new.html">UGGS Boots</a></strong> on shoesem.com,You can choose the <strong><a href="www.souggs.com/..._products.html">discount ugg boots</a></strong> or the newest <strong><a href="www.souggs.com/.../strong> for yourself or your friends.
|

ugg

December 14. 2009 20:19

<strong><a href="www.souggs.com/specials.html">Australia Ugg Boots</a></strong> becoming more and more popular,new style <strong><a href="http://www.souggs.com/">ugg boots</a></strong> will be the best seller for this Christmas,includes<strong><a href="www.souggs.com/products_all.html">Ugg Knightsbridge</a>,<a href="www.souggs.com/...ley-button-c-2.html">UGG Bailey Button</a></strong>;and the <strong><a href="www.shoeshotsale.com/.../strong><strong><a href="www.souggs.com/ugg-tall-5815-c-3.html">ugg classic tall boots,</a></strong> <strong><a href="www.souggs.com/...cardy-5819-c-1.html">ugg cardy boots</a></strong> also hot sale for these years,you can choose your lovely <strong><a href="www.souggs.com/products_new.html">UGGS Boots</a></strong> on shoesem.com,You can choose the <strong><a href="www.souggs.com/..._products.html">discount ugg boots</a></strong> or the newest <strong><a href="www.souggs.com/.../strong> for yourself or your friends.
|

ugg

December 25. 2009 04:59

Aw, this was a really quality post. In theory I'd like to write like this too - taking time and real effort to make a good article... but what can I say... I procrastinate alot and never seem to get something done.
|

Nobuko Mcguirl

January 16. 2010 14:54

I really loved this amazing blog. Please keep them coming. Regards, Sammy!!
|

ubuntu blog

January 26. 2010 10:04

Hi blogger, good day. Awesome post. You have gained a new subscriber. Pleasee keep them coming and I look forward to hear more of your superb posts. Take care, Tamela..
|

website hosting

January 27. 2010 05:53

http://www.tiffanycome.com/ Tiffany & Co
http://www.tiffanycome.com/accessories-c-7.html Tiffany Jewellery
http://www.tiffanycome.com/bangles-c-5.html tiffany and co
http://www.tiffanycome.com/bracelets-c-2.html Tiffany Bracelet On Sale
http://www.tiffanycome.com/cufflinks-c-6.html links of london
http://www.tiffanycome.com/earrings-c-3.html tiffany co london
http://www.tiffanycome.com/necklaces-c-1.html links london
http://www.tiffanycome.com/rings-c-4.html Tiffany Rings
http://www.tiffanycome.com/watches-c-8.html tiffany and company
|

tiffany jewellery

January 28. 2010 14:19

nice website and great information..thanks for the tips
|

Margrett Henricksen

January 31. 2010 08:09

Hi, I applaud your blog for informing people, very interesting article, keep up it coming Smile
|

dc shoes

February 11. 2010 13:55

Good thread. Cheers!!
|

auto accident lawyer

February 11. 2010 17:28

Hello. This is kind of an "unconventional" question , but have other visitors asked you how get the menu bar to look like you've got it? I also have a blog and am really looking to alter around the theme, however am scared to death to mess with it for fear of the search engines punishing me. I am very new to all of this ...so i am just not positive exactly how to try to to it all yet. I'll just keep working on it one day at a time Thanks for any help you can offer here
|

snoring exercises

February 11. 2010 18:54

Good thread. Cheers!!
|

personal injury lawyers

February 11. 2010 23:00

Good posts. Thanks!
|

website building

February 11. 2010 23:03

Very informative posts, glad I found this site. Thanks!
|

std testing

February 12. 2010 03:08

Hey, I liked the post. It's been 3 years since I got the tempurpedic bed that changed my life. Feeling well rested speaks for itself. I always tell people that it is some of the best money I have spent. Anyway, keep up the fantastic work!
|

Yulanda Poto

February 12. 2010 04:23

Awesome article.I have bookmarked it already. Truly, Benjamin.
|

cheap viagra

February 12. 2010 09:03

Your RSS feed doesn't work in my browser (google chrome) how can I fix it?
|

WoW Leveling Guide

February 13. 2010 12:07

Enjoyed the posts..
|

sorority

February 14. 2010 09:49

Great thread. Enjoyed the posts..
|

aloe cure

February 21. 2010 06:44

Enjoyed the posts..
|

fraternity

February 23. 2010 16:34

Makita's 18V Compact Lithium-Ion Cordless Impact Driver delivers more torque with less weight to the jobsite. The versatile BTD142HW packs plenty of torque for a wide range of fastening and drilling tasks, yet it weighs just under three pounds with an ergonomic design and a "one-touch" chuck for comfort and ease-of-use, all day long.
|

makita impact driver

February 25. 2010 11:48

Awesome post. Thanks! If your having problems with your colon come to <a href="http://www.coloniccleansing.info" rel="nofollow">www.ColonicCleansing.info</a>
|

colonic cleanse

February 25. 2010 14:46

Perfect post. Thanks! If your thinking about buying a classic car come to our blog at <a href="http://www.classicmontecarlos.com" rel="nofollow">classic monte carlo</a>
|

classic monte carlo

February 25. 2010 16:56

Login choose on the best <a href="http://www.legerdress.com/">herve dress</a>, <a href="www.legerdress.com/contact_us.html">herve leger dress</a>, <a href="www.legerdress.com/...e-p-5732.html">herve bandage dress</a>, <a href="www.legerdress.com/...s-p-5737.html">cheap herve leger dress</a>, <a href="www.legerdress.com/specials.html">herve leger sale</a>,and welcome your often login <a href="http://www.shoesem.com/">timberland men boots</a>, <a
href="http://www.warmuggs.com/">ugg on sale</a>, <a href="http://www.souggs.com/">cheap uggs boots</a>, <a href="http://www.baileyuggboots.com/">bailey uggs boots</a>, <a href="http://www.e-timberland.com/">timberland shoes</a>, <a href="http://www.bagsoluxury.com/">mulberry handbags</a>, <a href="http://www.tiffanycome.com/">tiffany &amp; co</a>, <a href="http://www.usoluxury.com/">2010 designer handbags</a>,and select other your favorite products.
|

herve leger dress

February 27. 2010 13:13

Do you think you have STD symptoms? See pictures here http://www.std-symptom.info and to find STD testing.
|

std testing

March 2. 2010 12:07

Hi.Sorry if my english is not good.anyway i just desire to tell that i like this post very much. many thanks!
|

the pacific streaming

March 4. 2010 09:41

I enjoy watching movies online, it is way cheaper than going to the theaters.
|

hd movies

March 4. 2010 09:58

Hello there.Forgive me if my english isn't nice.anyway i simply want to say that i like this article very much. say thank you!
|

watch the pacific online

March 4. 2010 11:27

Fascinating blog on Content Publishing 101: The Blogger API, not like the other ones!
|

emma watson

March 4. 2010 12:02

thanks for sharing great post.
|

Kenda Bulacan

March 4. 2010 20:33

I like watching movies online, it is way easier than going to the theaters.
|

watch movies online

March 4. 2010 21:05

Subject of this post is very interested, bookmarked
|

Alise Yockers

March 5. 2010 01:13

Well done! - I looked at the Wiki on this and it did not have as detailed info - thanks!
|

Ollie Slogeris

March 5. 2010 11:05

Is tethering against the Terms of Service of cell phone companies? Which ones allow it?
|

Refer 3 Get Yours Free

March 5. 2010 15:17

Thx for this nice article.
|

Renee Rochholz

Add comment


 

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

March 11. 2010 23:44

|