Integrate Blogger content with PHP applications using the ... · Introduction You might have heard of Blogger, a free blogging platform that lets you easily create personal weblogs
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Integrate Blogger content with PHP applicationsusing the Blogger Data APIUse PHP to retrieve and add blog posts to Blogger through thesophisticated Blogger Data API
Skill Level: Introductory
Vikram VaswaniFounderMelonfire
04 Oct 2011
Blogger is a free, popular blogging platform that lets users create their own weblogs,and post messages and news, through a WYSIWYG editing interface. With theBlogger Data API, which is REST-based, you can access Blogger content throughany XML-compliant programming toolkit. In this article, learn how to use the BloggerData API to list blog content, add or edit blog posts, and manipulate blog commentswith the Zend Framework's Zend_Gdata component. You'll build a simple applicationthat demonstrates the power of the Blogger API.
Introduction
You might have heard of Blogger, a free blogging platform that lets you easily createpersonal weblogs and publish posts on any topic. Blogger, which has been aroundsince 1999, was one of the first blogging platforms on the web. It was purchased byGoogle and integrated into Google's suite of free services.
Popular blogger applicationsWhile Blogger is a popular option for blog platforms, many otheroptions exist. For one, IBM Connections software includesintegrated blog capabilities. Other popular blog software optionsinclude Wordpress, Drupal, and Typepad, among many others.
With Blogger, it's easy for people without specific technical knowledge to create andmaintain their own weblog. Blogger:
• Comes with several predefined templates and layouts
• Supports comments, access controls, and mobile devices
• Is tightly integrated with other services (such as Twitter, Google AdSense,and others) for content sharing and monetization.
In a nutshell, Blogger provides everything you need to publish your blog withouthaving to worry about the technical details.
Frequently used acronyms
• API: Application programming interface
• HTML: Hypertext Markup Language
• HTTP: Hypertext Transfer Protocol
• REST: Representational State Transfer
• RSS: Really Simple Syndication
• URL: User interface
• WYSISYG: What You See Is What You Get
• XML: Extensible Markup Language
But Blogger isn't just interesting to users. Like many other Google services, Bloggerhas a developer API that lets you get your hands on the innards of the service andextract content to create your own custom applications and mashups. You canaccess the Blogger Data API, which follows the REST model, through anyXML-capable development toolkit. It already has client libraries for many commonprogramming languages, including my favorite: PHP.
In this article, learn about the Blogger Data API, and how to integrate and useBlogger content with PHP applications. Many examples will guide you through:
Before you get into the PHP code, this section gives an overview of the BloggerData API. As with all REST-based services, the API accepts HTTP requestscontaining one or more XML-encoded input arguments and returns XML-encodedresponses that can be parsed in any XML-aware client. With the Blogger API, theresponse always consists of an Atom or RSS feed containing the requestedinformation.
Blogger has both public and private feeds. You can access public feeds, such aslists of posts within a blog, without authentication. Private feeds requireauthentication. For example, a private feed requires authentication to perform add orupdate operations on a blog post or comment. The examples in this articledemonstrate both types of feeds.
To get the most out of this article, you should have a Blogger account with at leastone blog and one post. If you don't have one, you can log into Blogger (seeResources), create a new blog, and add a new post to it for testing purposes. Whileyou're logged in, try to access the URLhttp://www.blogger.com/feeds/default/blogs in a web browser. Youshould see something similar to Listing 1.
The metafeed in Listing 1 provides a list of all the blogs associated with the currentlyauthenticated user. It opens with a <feed> element as the root element. The<feed> element contains:
• <link> elements, which contain URLs for different versions of the feed
• An <author> element, which specifies the account owner
• <openSearch> elements, which contain summary statistics
The outermost <feed> element encloses one or more <entry> elements, eachrepresenting a blog. Each <entry> contains further detail, including the title,description, creation date, last update date, and author of each blog. Each entry alsoincludes a set of feed links, which are feeds that contain the blog posts, blogtemplate, and blog settings.
In Listing 1, each blog is associated with a unique identifier, or blog ID. The blog IDis used to construct the URLs to the blog-specific feeds. For example, to find thepost feed for a specific blog, use the URL specified in the <linkrel='http://schemas.google.com/g/2005#post' ... /> element. Listing2 shows what the post feed might look like.
<published>2011-09-01T03:34:00.001-07:00</published><updated>2011-09-01T21:06:44.258-07:00</updated><title type='text'>My Third Post</title><content type='html'>This is my third post<br /></content><link rel='replies' type='application/atom+xml'href='http://vvaswani.blogspot.com/feeds/12345POSTIDHERE12345/comments/default'title='Post Comments'/>
Listing 2 reveals that the post feed contains a set of <entry> elements, and thateach one represents a single post of the blog. Each <entry> includes:
• The title, content, and publication date of the post.
• Links to the post's public URL, post edit URL, comments feed URL, andcomments feed edit URL. These feeds are used to view and edit the post,or its comments, through the Blogger Data API.
Each post also has a unique identifier, called the post ID, which is in the <id>element of the entry. It is a composite string that includes both the blog ID and postID, in the format tag:blogger.com,1999:blog-BLOGID.post-POSTID. Forexample, in the identifying stringtag:blogger.com,1999:blog-1234.post-6789, the blog identifier is 1234and the post identifier is 6789.
Now that you know how to access blog and post feeds through the API, try the samething from within a PHP application. To generate the feeds in Listings 1 and 2, youfirst manually log in to Blogger with a Google account. To retrieve and process thefeeds from within a PHP application, the same authentication task needs to beperformed programmatically.
Doing the authentication manually is a fairly messy task and requires a lot of code toaccount for the various scenarios that can arise during a typical authenticationtransaction. Fortunately, the Zend Framework includes Zend_Gdata, a PHP clientlibrary designed specifically for developers trying to integrate PHP applications withthe Google Data API. Zend_Gdata provides a convenient, object-oriented interfaceto the Google Data API (see the link in Resources to download it). It encapsulatesmost of the common tasks, including authentication, and leaves you free to focus onthe core functions of your application.
After you install Zend's Gdata library, look through Listing 3. It shows how to processthe feed from Listing 1 and convert it into a web page listing all of the authenticateduser's weblogs on Blogger.
Listing 3 loads the Zend class libraries and initializes an instance of theZend_Gdata service class. Zend_Gdata uses a Zend_Http_Client object,which is provided with the necessary user authentication information and used toopen an authenticated connection to the Blogger service. This class also serves asthe control point for all subsequent interaction with the Blogger Data API.
Once an authenticated connection is open, the getFeed() method is used toretrieve the list of blogs. getFeed() accepts a Zend_Gdata_Query object, whichis passed the URL for the blog listing feed. The response to the getFeed() API callis an XML feed similar to that in Listing 1, which is then parsed and converted into aPHP object. Entries within the feed are represented as array elements, making itpossible to:
• Iterate over the feed
• Retrieve the individual blog names and URLs
• Format them for display in a web browser
Figure 1 shows the output you might see.
Figure 1. Example web page displaying a user's blogs
As noted earlier, each blog and post within the Blogger service has a uniqueidentifier. If you have the unique identifier for a blog, you can generate the URL forthe corresponding blog feed, which contains a list of all the posts within that blog.Listing 4 shows the process for retrieving and processing such a blog feed with theZend_Gdata client library.
As in Listing 3, Listing 4 first initializes the Zend libraries and creates anauthenticated Zend_Gdata service object. The blog identifier is used to constructthe URL to the blog feed, which is converted into a Zend_Gdata_Query object andpassed to the getFeed() method. The resulting feed is then parsed andprocessed, in the usual manner, to produce a list of all the posts within the specifiedblog. Figure 2 shows an example of the output.
You can combine Listing 3 and Listing 4 to produce a list of all the authenticateduser's blogs and posts within each blog. Listing 5 shows the combined code.
// set credentials for ClientLogin authentication$user = "[email protected]";$pass = "your-password";
try {// perform login// initialize service object$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'blogger');$service = new Zend_Gdata($client);
// create array$data = array();
// get list of all posts in all blog feeds$query1 = new Zend_Gdata_Query('http://www.blogger.com/feeds/default/blogs');$feed1 = $service->getFeed($query1);foreach ($feed1 as $entry1) {
$arr = explode('-', (string)$entry1->getId());$id = $arr[2];$query2 = new Zend_Gdata_Query('http://www.blogger.com/feeds/'.$id.'/posts/default');
Listing 5 first requests the blog metafeed and iterates over the entries within it toretrieve each blog's unique identifier. This identifier is then used to construct theURL to the blog's post feed, which is requested and processed to extract each post'stitle and URL. All of this information is stored in a nested array, as in Listing 6.
Once the array is completely generated, you can simply iterate over it and prepare anested list of blogs and their posts. Figure 3 shows an example of the output.
Figure 3. Web page displaying user's blogs and blog posts
Adding blog posts
In addition to allowing post retrieval, the Blogger Data API also allows authenticatedusers to add new posts to a blog programmatically. Create a newZend_Gdata_App_Entry object, set its title and content, and then POST it to thepost feed. Listing 7 shows the example code.
// create a new entry object// populate it with user input$uri = 'http://www.blogger.com/feeds/' . $id . '/posts/default';$entry = $service->newEntry();$entry->title = $service->newTitle($_POST['title']);$entry->content = $service->newContent($_POST['body']);$entry->content->setType('text');
// save entry to server// return unique id for new post$response = $service->insertEntry($entry, $uri);$arr = explode('-', $response->getId());$id = $arr[2];echo 'Successfully added post with ID: ' . $id;
In the code in Listing 7, a simple web form allows the user to input a title and bodyfor a blog post. After the form is submitted, the script loads the Zend class librariesand creates an authenticated service object. The script then uses the serviceobject's newEntry() method to create a new entry object and uses thenewTitle() and newContent() methods to set the title and content of the blogpost from the user's input. After these attributes are set, the insertEntry()method is used to save the new post to Google's servers.
The return value of the insertEntry() method is an entry representing the newlycreated post. This entry now contains the post's unique identifier, which can beextracted and displayed on the result page. After it is saved, the new post becomesvisible in the public blog and also appears in all API feeds for that blog.
Editing and deleting blog posts
You can also delete or edit existing posts through the Blogger Data API. In both
cases, the corresponding DELETE or PUT request must be transmitted to the post'sedit URL (see Listing 2 for an example). Only authenticated users can perform bothof these operations.
The code in Listing 8 shows how to delete an existing blog post through the API,assuming you already have the blog and post IDs.
// set credentials for ClientLogin authentication$user = "[email protected]";$pass = "your-password";
// set blog and post ids$bid = 'YOUR-BLOG-ID-HERE';$pid = 'YOUR-POST-ID-HERE';
try {// perform login// initialize service object$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'blogger');$service = new Zend_Gdata($client);
// set URI for entry to delete// obtain from <link rel=edit ... />$uri = 'http://www.blogger.com/feeds/' . $bid . '/posts/default/' . $pid;$service->delete($uri);echo 'Successfully deleted post with ID: ' . $pid;
Listing 8 uses the service object's delete() method to delete the specified blogpost. The delete() method accepts the post's edit URL and transmits a DELETErequest to that URL. After it is deleted, the blog post will disappear from both thepublic blog and any API feeds that reference it.
To display the code to update an existing blog post through the API, again assumingyou already have the blog and post IDs, use the code in Listing 9.
// set credentials for ClientLogin authentication$user = "[email protected]";$pass = "your-password";
// set blog and post ids$bid = 'YOUR-BLOG-ID-HERE';$pid = 'YOUR-POST-ID-HERE';
try {// perform login// initialize service object$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'blogger');$service = new Zend_Gdata($client);
// set URI for entry to update// obtain from <link rel=self ... />$uri = 'http://www.blogger.com/feeds/' . $bid . '/posts/default/' . $pid;
// get the existing entry// set new values// save it back$response = $service->get($uri);$entry = new Zend_Gdata_App_Entry($response->getBody());$entry->title = $service->newTitle("New title");$entry->content = $service->newContent("New content");$entry->content->setType('text');$service->updateEntry($entry);echo 'Successfully updated post with ID: ' . $pid;
Updating a blog post through the API is a two-step process. First, you need toretrieve the existing blog post and convert it to a Zend_Gdata_App_Entry object.Then, you can use service object methods, such as newTitle() andnewContent(), to update the entry and save it back to the server using theupdateEntry() method.
Similar to the insertEntry() method, the return value of the updateEntry()method is an entry representing the post, including its unique identifier and content.After it is saved, the updated post becomes visible in the public blog and in all APIfeeds referencing that blog.
Working with comments
Just as you can add, edit, and delete posts, you can also add, edit, and delete postcomments. In Listing 2, notice that each post entry includes links to the post'scomments feed. Adding a new comment is as simple as inserting an entry into thiscomments feed.
// set credentials for ClientLogin authentication$user = "[email protected]";$pass = "your-password";
// set blog and post ids$bid = 'YOUR-BLOG-ID-HERE';$pid = 'YOUR-POST-ID-HERE';
try {// perform login// initialize service object$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'blogger');$service = new Zend_Gdata($client);
// create a new entry object// populate it with user input$uri = "http://www.blogger.com/feeds/$bid/$pid/comments/default";$entry = $service->newEntry();$entry->content = $service->newContent('This is a very interesting post.');$entry->content->setType('text');
// save entry to server// return unique id for new comment$response = $service->insertEntry($entry, $uri);$arr = explode('/', $response->getEditLink()->href);$id = $arr[8];echo 'Successfully added comment with ID: ' . $id;
Adding a new comment is almost the same as adding a new post; the onlydifference lies in the URL to which the request is posted (in this case, the commentsfeed URL). The response to the insertEntry() method is an object representingthe newly added comment. The object can then be parsed to retrieve the uniquecomment identifier, which is needed if you want to delete the comment later.
Assuming you have the comment identifier, you can use the code in Listing 11 toprogrammatically remove the comment with the delete() method.
// set credentials for ClientLogin authentication$user = "[email protected]";$pass = "your-password";
// set blog, post and comment ids$bid = 'YOUR-BLOG-ID-HERE';$pid = 'YOUR-POST-ID-HERE';$cid = 'YOUR-COMMENT-ID-HERE';
try {// perform login// initialize service object$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'blogger');$service = new Zend_Gdata($client);
// set URI for entry to delete// obtain from <link rel=edit ... />$uri = "http://www.blogger.com/feeds/$bid/$pid/comments/default/$cid";$service->delete($uri);echo 'Successfully deleted comment with ID: ' . $cid;
<?php echo date('d M Y H:i', strtotime($entry->getUpdated())); ?></li>
<?php endforeach; ?></ul>
</body></html>
Example application: Content Management System
Let's put everything into practice by building a simple real-world application thatdemonstrates the power of the Blogger Data API. The example application is aweb-based content manager that lets users view their existing blog posts, add newposts, and edit or delete existing posts. Edits are performed through abrowser-based WYSIWYG editor and transmitted to Blogger through the BloggerData API.
To begin, download and install the TinyMCE JavaScript editor on your developmentserver (see Resources for a link). Create a script containing the code shown inListing 13.
// for add and edit operationsif (isset($_POST['submit'])) {
// if post id present// update post with new contentif (isset($_POST['pid'])) {$arr = explode('-', $_GET['pid']);$pid = $arr[2];$uri = 'http://www.blogger.com/feeds/' . $bid . '/posts/default/' . $pid;$response = $service->get($uri);$entry = new Zend_Gdata_App_Entry($response->getBody());$entry->title = $service->newTitle($_POST['title']);$entry->content = $service->newContent($_POST['body']);$entry->content->setType('text');$service->updateEntry($entry);echo 'Successfully updated post with ID: ' . $pid;
} else {// if post id not present// create a new post// populate it with user input$uri = 'http://www.blogger.com/feeds/' . $bid . '/posts/default';$entry = $service->newEntry();$entry->title = $service->newTitle($_POST['title']);$entry->content = $service->newContent($_POST['body']);$entry->content->setType('text');$response = $service->insertEntry($entry, $uri);$arr = explode('-', $response->getId());$id = $arr[2];echo 'Successfully added post with ID: ' . $id;
}}
// for edit and delete operationsif (isset($_GET['op'])) {
The code above might look complex, but it's just a couple of conditional statementswrapped around code you've already seen. It might help to break it down, as follows.
• The script begins by loading the Zend class libraries and settingcredentials for authentication. It also defines the blog ID. All subsequentoperations will take place only on the specified blog.
• Assuming no request parameters exist, the script connects to the BloggerAPI and requests a list of all posts in the specified blog. It then processesthe resulting feed and displays the list of posts as an HTML list.Each post is accompanied by three links: to View, Edit, or Delete the
post. The View link specifies the public URL of the post. The Edit andDelete links simply invoke the script again, passing it the selected postID as a GET request parameter.
• After generating the list of current posts, the script also generates a webform for the user to add a new post. The form contains a single-line textinput field (for the post title) and a multi-line text area (for the post body).The TinyMCE editor, which is also initialized at page load, automaticallytakes care of converting the text area into a WYSIWYG text editing fieldwith formatting and hyperlink controls.
• What happens next depends on which operation the user chooses.If the user chooses... Then...
To add a new post After content is entered into the webform and submitted, the scriptcreates a new entry object using thenewEntry() method, populates itwith the submitted input, and savesit to the blog using theinsertEntry() method.
To delete an existing post The ID of the selected post isretrieved from the request URL, andthe post feed URL is constructedusing the blog ID and post ID. Thepost is then deleted using theservice object's delete() method.
To edit an existing post The ID of the selected post isretrieved from the request URL, andthe post feed URL is constructedusing the blog ID and post ID. Thepost is then retrieved using theservice object's get() method.The content of the post is used topre-populate the web form forediting, together with a hidden fieldcontaining the unique post ID.After the user makes changes to thecontent and resubmits the form, thehidden post ID is used to identifyand update the existing post withthe updateEntry() method.
For the sake of simplicity, this script does not include any input validation. In aproduction environment, you need to add validation to ensure the integrity andvalidity of the data being collected from the user.
In this article, you learned how to integrate Blogger blog posts directly into a PHPapplication by using the Blogger Data API and Zend Gdata client library. The articleprovided an introduction to the Blogger feed format. You also learned how to:
• Retrieve blogs, posts, and comments
• Add, edit, and delete posts
• View, add, and delete comments
The Blogger API provides a sophisticated, format-independent mechanism tointegrate public blog content into any web application. It's great for mashups, or tobuild your own custom interface to Blogger. Try it out sometime, and see what youcan do.
• Developer's Guide and Reference Guide: Learn more about the Blogger DataAPI.
• The Blogger blog: Track Blogger Data API news.
• Blogger: Create your free Blog: Register for a free Blogger account.
• The Zend_Gdata component: Read more about it in the Programmer'sReference Guide.
• Blogger Developer Group: Read and join discussions related to Blogger DataAPI development.
• IBM Connections: Learn more about the integrated blog capabilities in IBMConnections.
• More articles by this author (Vikram Vaswani, developerWorks, August2007-current): Read articles about XML, additional Google APIs and othertechnologies.
• New to XML? Get the resources you need to learn XML.
• XML area on developerWorks: Find the resources you need to advance yourskills in the XML arena, including DTDs, schemas, and XSLT. See the XMLtechnical library for a wide range of technical articles and tips, tutorials,standards, and IBM Redbooks.
• IBM XML certification: Find out how you can become an IBM-CertifiedDeveloper in XML and related technologies.
• developerWorks technical events and webcasts: Stay current with technology inthese sessions.
• developerWorks on Twitter: Join today to follow developerWorks tweets.
• developerWorks podcasts: Listen to interesting interviews and discussions forsoftware developers.
• developerWorks on-demand demos: Watch demos ranging from productinstallation and setup for beginners to advanced functionality for experienceddevelopers.
Get products and technologies
• Zend Framework: Download Zend, which is based on simplicity, object-orientedbest practices, corporate friendly licensing, and a rigorously tested agilecodebase.
• TinyMCE editor: Get the platform-independent web-based JavaScript HTMLWYSIWYG editor.
• IBM product evaluation versions: Download or explore the online trials in theIBM SOA Sandbox and get your hands on application development tools andmiddleware products from DB2®, Lotus®, Rational®, Tivoli®, andWebSphere®.
Discuss
• developerWorks profile: Create your profile today and set up a watchlist on theBlogger Data API.
• XML zone discussion forums: Participate in any of several XML-relateddiscussions.
• The developerWorks community: Connect with other developerWorks userswhile exploring the developer-driven blogs, forums, groups, and wikis.
About the author
Vikram VaswaniVikram Vaswani is the founder and CEO of Melonfire, a consultingservices firm with special expertise in open-source tools andtechnologies. He is also the author of the books Zend Framework: ABeginners Guide and PHP: A Beginners Guide.
Trademarks
IBM, the IBM logo, ibm.com, DB2, developerWorks, Lotus, Rational, Tivoli, andWebSphere are trademarks or registered trademarks of International BusinessMachines Corporation in the United States, other countries, or both. These and otherIBM trademarked terms are marked on their first occurrence in this information withthe appropriate symbol (® or ™), indicating US registered or common lawtrademarks owned by IBM at the time this information was published. Suchtrademarks may also be registered or common law trademarks in other countries.See the current list of IBM trademarks.Adobe, the Adobe logo, PostScript, and the PostScript logo are either registeredtrademarks or trademarks of Adobe Systems Incorporated in the United States,and/or other countries.Other company, product, or service names may be trademarks or service marks of