1NAME 2 Net::MovableType - light-weight MovableType client 3 4SYNOPSIS 5 use Net::MovableType; 6 my $mt = new Net::MovableType('http://mt.handalak.com/cgi-bin/xmlrpc'); 7 $mt->username('user'); 8 $mt->password('secret'); 9 $mt->blogId(1); 10 11 my $entries = $mt->getRecentPosts(5); 12 while ( my $entry = shift @$entries ) { 13 printf("[%02d] - %s\n\tURI: %s\n", 14 $entry->{postid}, $entry->{title}, $entry->{'link'} ) 15 } 16 17DESCRIPTION 18 Using *Net::MovableType* you can post new entries, edit existing 19 entries, browse entries and users blogs, and perform most of the 20 features you can perform through accessing your MovableType account. 21 22 Since *Net::MovableType* uses MT's *remote procedure call* gateway, you 23 can do it from any computer with Internet connection. 24 25PROGRAMMING INTERFACE 26 *Net::MovableType* promises an intuitive, user friendly, Object Oriented 27 interface for managing your web sites published through MovableType. 28 Most of the method names correspond to those documented in MovableType's 29 Programming Interface Manual. 30 31 CREATING MT OBJECT 32 33 Before you start doing anything, you need to have a *MovableType* object 34 handy. You can create a *MovableType* object by calling "new()" - 35 constructor method: 36 37 $mt = new MovableType('http://mt.handalak.com/cgi-bin/mt-xmlrpc.cgi'); 38 # or 39 $mt = new MovableType('http://author.handalak.com/rsd.xml'); 40 # or even.. 41 $mt = new MovableType('/home/sherzodr/public_html/author/rsd.xml'); 42 43 Notice, you need to pass at least one argument while creating *MT* 44 object, that is the location of your either mt-xmlrpc.cgi file, or your 45 web site's rsd.xml file. Default templates of *MT* already generate 46 rsd.xml file for you. If they don't, you should get one from 47 http://www.movabletype.org/ 48 49 If your rsd.xml file is available locally, you should provide a full 50 path to the file instead of providing it as a URL. Reading the file 51 locally is more efficient than fetching it over the Web. 52 53 Giving it a location of your rsd.xml file is preferred, since it will 54 ensure that your "blogId()" will be set properly. Otherwise, you will 55 have to do it manually calling "blogId()" (see later). 56 57 It is very important that you get this one right. Otherwise, 58 *Net::MovableType* will know neither about where your web site is nor 59 how to access them. 60 61 *MovableType* requires you to provide valid username/password pair to do 62 most of the things. So you need to tell *MovableType* object about your 63 username and passwords, so it can use them to access the resources. 64 65 You can login in two ways; by either providing your *username* and 66 *password* while creating *MT* object, or by calling "username()" and 67 "password()" methods after creating *MT* object: 68 69 # creating MT object with valid username/password: 70 $proxy = 'http://mt.handalak.com/cgi-bin/mt-xmlrpc.cgi'; 71 $mt = new MovableType($proxy, 'author', 'password'); 72 73 # or 74 $mt = new MovableType($proxy); 75 $mt->username('author'); 76 $mt->password('password'); 77 78 "username()" and "password()" methods are used for both setting username 79 and password, as well as for retrieving username and password for the 80 current logged in. Just don't pass it any arguments should you wish to 81 use for the latter purpose. 82 83 DEFINING A BLOG ID 84 85 Defining a blog id may not be necessary if you generated your 86 *Net::MovableType* object with an rsd.xml file. Otherwise, read on. 87 88 As we will see in subsequent sections, most of the *MovableType*'s 89 methods operate on specific web log. For defining a default web log to 90 operate on, after setting above *username* and *password*, you can also 91 set your default blog id using "blogId()" method: 92 93 $mt->blogId(1); 94 95 To be able to do that, you first need to know your blog id. There are no 96 documented ways of retrieving your blog id, except for investigating the 97 URL of your MovableType account panel. Just login to your MovableType 98 control panel (through mt.cgi script). In the first screen, you should 99 see a list of your web logs. Click on the web log in question, and look 100 at the URL of the current window. In my case, it is: 101 102 http://mt.handalak.com/cgi-bin/mt?__mode=menu&blog_id=1 103 104 Notice *blog_id* parameter? That's the one! 105 106 Wish you didn't have to go through all those steps to find out your blog 107 id? *Net::MovableType* provides "resolveBlogId()" method, which accepts 108 a name of the web log, and returns correct blogId: 109 110 $blog_id = $mt->resolveBlogId('lost+found'); 111 $mt->blogId($blog_id); 112 113 Another way of retrieving information about your web logs is to get all 114 the lists of your web logs by calling "getUsersBlogs()" method: 115 116 $blogs = $mt->getUsersBlogs(); 117 118 "getUsersBlogs()" returns list of blogs, where each blog is represented 119 with a hashref. Each hashref holds such information as *blogid*, 120 *blogName* and *url*. Following example lists all the blogs belonging to 121 the current logged in user: 122 123 $blogs = $mt->getUsersBlogs(); 124 for $b ( @$blogs ) { 125 printf("[%02d] %s\n\t%s\n", $b->{blogid}, $b->{blogName}, $b->{url}) 126 } 127 128 POSTING NEW ENTRY 129 130 By now, you know how to login and how to define your blog_id. Now is a 131 good time to post a new article to your web log. That's what "newPost()" 132 method is for. 133 134 "newPost()" expects at least a single argument, which should be a 135 reference to a hash containing all the details of your new entry. First, 136 let's define a new entry to be posted on our web log: 137 138 $entry = { 139 title => "Hello World from Net::MovableType", 140 description => "Look ma, no hands!" 141 }; 142 143 Now, we can pass above "$entry" to our "newPost()" method: 144 145 $mt->newPost($entry); 146 147 In the above example, *description* field corresponds to Entry Body 148 field of MovableType. This is accessible from within your templates 149 through *MTEntryBody* tag. MovableType allows you to define more entry 150 properties than we did above. Following is the list of all the 151 attributes we could've defined in our above "$entry": 152 153 dateCreated 154 *Authored Date* attribute of the entry. Format of the date should be 155 in *ISO.8601* format 156 157 mt_allow_comments 158 Should comments be allowed for this entry 159 160 mt_allow_pings 161 should pings be allowed for this entry 162 163 mt_convert_breaks 164 Should it use "Convert Breaks" text formatter? 165 166 mt_text_more 167 Extended entry 168 169 mt_excerpt 170 Excerpt of the entry 171 172 mt_keywords 173 Keywords for the entry 174 175 mt_tb_ping_urls 176 List of track back ping urls 177 178 Above entry is posted to your MT database. But you still don't see it in 179 your weblog, do you? It's because, the entry is still not published. 180 There are several ways of publishing an entry. If you pass a true value 181 to "newPost()" as the second argument, it will publish your entry 182 automatically: 183 184 $mt->newPost($entry, 1); 185 186 You can also publish your post by calling "publishPost()" method. 187 "publishPost()", however, needs to know *id* of the entry to publish. 188 Our above "newPost()", luckily, already returns this information, which 189 we've been ignoring until now: 190 191 my $new_id = $mt->newPost($entry); 192 $mt->publishPost($new_id); 193 194 You can also publish your post later, manually, by simply rebuilding 195 your web log from within your MT control panel. 196 197 ENTRY CATEGORIES 198 199 *MovableType* also allows entries to be associated with specific 200 category, or even with multiple categories. For example, above "$entry", 201 we just published, may belong to category "Tutorials". 202 203 Unfortunately, structure of our "$entry" doesn't have any slots for 204 defining its categories. This task is performed by a separate procedure, 205 "setPostCategories()". 206 207 "setPostCategories()" expects two arguments. First should be *postid* of 208 the post to assign categories to, and second argument should either be a 209 name of the primary category, or a list of categories in the form of an 210 arrayref. In the latter case, the first category mentioned becomes 211 entry's primary category. 212 213 For example, let's re-post our above "$entry", but this time assign it 214 to "Tutorials" category: 215 216 $new_id = $mt->newPost($entry, 0); # <-- not publishing it yet 217 $mt->setPostCategories($new_id, "Tutorials"); 218 $mt->publishPost($new_id); 219 220 We could also assign a single entry to multiple categories. Say, to both 221 "Tutorials" and "Daily Endeavors". But say, we want "Daily Endeavors" to 222 be the primary category for this entry: 223 224 $new_id = $mt->newPost($entry, 0); # <-- not publishing it yet 225 $mt->setPostCategories($newPid, ["Daily Endeavors", "Tutorials"]); 226 $mt->publishPost($new_id); 227 228 Notice, in above examples we made sure that "newPost()" method didn't 229 publish the entry by passing it false value as the second argument. If 230 we published it, we again would end up having to re-publish the entry 231 after calling "setPostCategories()", thus wasting unnecessary resources. 232 233 BROWSING ENTRIES 234 235 Say, you want to be able to retrieve a list of entries from your web 236 log. There couple of ways for doing this. If you just want titles of 237 your entries, consider using "getRecentPostTitles()" method. 238 "getRecentPostTitles()" returns an array of references to a hash, where 239 each hashref contains fields *dateCreated*, *userid*, *postid* and 240 *title*. 241 242 "getRecentPostTitles()" accepts a single argument, denoting the number 243 of recent entries to retrieve. If you don't pass any arguments, it 244 defaults to *1*: 245 246 $recentTitles = $mt->getRecentPostTitles(10); 247 for my $post ( @$resentTitles ) { 248 printf("[%03d] %s\n", $post->{postid}, $post->{title}) 249 } 250 251 Remember, even if you don't pass any arguments to 252 "getRecentPostTitles()", it still returns an array of hashrefs, but this 253 array will hold only one element: 254 255 $recentTitle = $mt->getRecentPostTitles(); 256 printf("[%03d] %s\n", $recentTitles->[0]->{postid}, $recentTitles->[0]->{title}); 257 258 Another way of browsing a list of entries, is through "getRecentPosts()" 259 method. Use of this method is identical to above-discussed 260 "getRecentPostTitles()", but this one returns a lot more information 261 about each post. It can accept a single argument, denoting number of 262 recent entries to retrieve. 263 264 Elements of the returned hash are compatible with the "$entry" we 265 constructed in earlier sections. 266 267 RETREIVING A SINGLE ENTRY 268 269 Sometimes, you may want to retrieve a specific entry from your web log. 270 That's what "getPost()" method does. It accepts a single argument, 271 denoting an id of the post, and returns a hashref, keys of which are 272 compatible with the "$entry" we built in earlier sections (see POSTING 273 NEW ENTRY): 274 275 my $post = $mt->getPost(134); 276 printf("Title: %s (%d)\n", $post->{title}, $post->{postid}); 277 printf("Excerpt: %s\n\n", $post->{mt_excerpt} ); 278 printf("BODY: \n%s\n", $post->{description}); 279 if ( $post->{mt_text_more} ) { 280 printf("\nEXTENDED ENTRY:\n", $post->{mt_text_more} ); 281 } 282 283 EDITING ENTRY 284 285 Editing an entry means to re-post the entry. This is done almost the 286 same way as the entry has been published. "editPost()" method, which is 287 very similar in use to "newPost()", but accepts a *postid* denoting the 288 id of the post that you are editing. Second argument should be a 289 hashref, describing fields of the entry. Structure of this hashref was 290 discussed in earlier sections (see POSTING NEW ENTRY): 291 292 $mt->editPost($postid, $entry) 293 294 DELETING ENTRY 295 296 You can delete a specific entry from your database (and weblog) using 297 "deletePost()" method. "deletePost()" accepts at least one argument, 298 which is the id of the post to be deleted: 299 300 $mt->deletePost(122); # <-- deleting post 122 301 302 By default entries are deleted form the database, not from your web log. 303 They usually fade away once your web log is rebuilt. However, it may be 304 more desirable to remove the entry both from the database and from the 305 web site at the same time. 306 307 This can be done by passing a true value as the second argument to 308 "deletePost()". This ensures that your pages pertaining to the deleted 309 entry are rebuilt: 310 311 $mt->deletePost(122, 1); # <-- delet post 122, and rebuilt the web site 312 313 UPLOADING 314 315 With *Net::MovableType*, you can also upload files to your web site. 316 Most common use of this feature is to associate an image, or some other 317 downloadable file with your entries. 318 319 *Net::MovableType* provides "upload()" method, which given a file 320 contents, uploads it to your web site's archives folder. On success, 321 returns the URL of the newly uploaded file. 322 323 "upload()" method accepts either a full path to your file, or a 324 reference to its contents. Second argument to upload() should be the 325 file's name. If you already provided file's full path as the first 326 argument, *Net::MovableType* resolves the name of the file 327 automatically, if it's missing. 328 329 If you passed the contents of the file as the first argument, you are 330 required to provide the name of the file explicitly. 331 332 Consider the following code, which uploads a logo.gif file to your web 333 site: 334 335 $url = $mt->upload('D:\images\logo.gif'); 336 337 Following example uploads the same file, but saves it as "my-log.gif", 338 instead of "logo.gif": 339 340 $url = $mt->upload('D:\images\logo.gif', 'my-logo.gif'); 341 342 Following example downloads a file from some remote location, using 343 LWP::Simple, and uploads it to your web site with name "image.jpeg": 344 345 use LWP::Simple; 346 347 $content = get('http://some.dot.com/image.jpeg'); 348 $url = $mt->upload( \$content, 'image.jpeg' ) 349 350ERROR HANDLING 351 If you noticed, we didn't even try to check if any of our remote 352 procedure calls succeeded. This is to keep the examples as clean as 353 possible. 354 355 For example, consider the following call: 356 357 $new_id = $mt->newPost($entry, 1); 358 359 There is no guarantee that the above entry is posted, nor published. You 360 username/password might be wrong, or you made a mistake while defining 361 your *mt-xmlrpc* gateway? You may never know until its too late. 362 363 That's why you should always check the return value of the methods that 364 make a remote procedure call. 365 366 All the methods return true on success, "undef" otherwise. Error message 367 from the latest procedure call is available by calling "errstr()" static 368 class method. Code of the error message (not always as useful) can be 369 retrieved through "errcode()" static class method: 370 371 $new_id = $mt->newPost($entry, 1); 372 unless ( defined $new_id ) { 373 die $mt->errstr 374 } 375 376 or just: 377 378 $new_id = $mt->newPost($entry, 1) or die $mt->errstr; 379 380 If you are creating your *MovableType* object with an rsd.xml file, you 381 should also check the return value of "new()": 382 383 $mt = new Net::MovableType($rsd_url); 384 unless ( defined $mt ) { 385 die "couldn't create MT object with $rsd_url: " . Net::MovableType->errstr 386 } 387 388TODO 389 Should implement a caching mechanism 390 391 Manual is still not complete, more methods are left to be documented 392 properly 393 394CREDITS 395 Following people have contributed to the library with their suggestions 396 and patches. The list may not be complete. Please help me with it. 397 398 Atsushi Sano 399 For rsd.xml and "newMediaObject()" support. 400 401COPYRIGHT 402 Copyright (C) 2003, Sherzod B. Ruzmetov. All rights reserved. 403 404 This library is a free software, and can be modified and distributed 405 under the same terms as Perl itself. 406 407AUTHOR 408 Sherzod Ruzmetov <sherzodr AT cpan.org> 409 410 http://author.handalak.com/ 411 412SEE ALSO 413 the Net::Blogger manpage 414 415