Smashwords Book Widget for WordPress

Sherrie and I founded in 2011 an independent publishing house for inspiring travel stories. Our ebooks are published via Smashwords.
Smashwords is a great platform for distributing ebooks to all the main players such as iTunes, Barnes & Nobel, Kobo etc. The only one missing is Amazon.

Smashwords also launched its own ebook store on Smashwords.com with a smart affiliate program. Why smart? The affiliate rate can be juiced. Normally affiliate partners earn 15% of the book price. But in order to get the books sales up the author can “juice” the book. That means he or she increases the percentage of the affiliate earnings. This works well with digital goods since there is next to nil in costs per book. Only the fixed setup costs. So its ok to give away, lets say a gigantic 50% of the book price to an affiliate partner (like we do at the moment) since these are sales we probably wouldn’t have had otherwise.
So far so good. What Smashwords is missing however is good affiliate material, like banners, widgets etc. Competitors like Amazon have tons of them. Since we want to find affiliate partners for our ebooks on Smashwords this is definitely a disadvantage.

But hey, why not make our own? Thats the advantage of being a software developer. They can develop software – as in a Smashwords widget for example 🙂
I decided to go for a WordPress widget, since its the most used blogging software and the installation of widgets is super easy, especially if its included in the official WordPress plugin repository.

If you just want to use it go here, read further if you are interested in the technical details.

What were the technical challenges to create the Widget? A walk through the code.

Getting books from Smashwords
First we have to get the books from a particular author from Smashwords. Smashwords doesn’t provide any form of API to access its data so we have to get the data from the normal Smashwords pages. PHP has several ways to load content from another server. Unfortunately not all of them are always available, this depends on the server configuration of the WordPress installation. As a plugin we have no control over it. Therefore the best is to try all possibilities in order to find one that works. Fortunately WordPress does that for us and encapsulates it in a simple function:

wp_remote_get($url)

Parsing the retrieved html
Since Smashwords sends us complete HTML page back we get a lot of data in which we need to find the book data. To parse the html page I used the simplehtmldom library, which comes as Open Source under MIT license. It allows easy access to the html dom:

foreach($html->find('div[class=bookCoverImg]') as $div){
  // more code...
  $a = $div->find('a[class=bookTitle]');
  $link = $a[0]->href;
  // more code...
}

Caching the books
It costs a lot of time to do the above steps and the books don’t change very often. Therefore its a good idea to cache the loaded books.
Wordpress offers an object cache which can be accessed over these two methods:

get_transient($key)
set_transient($key, $value, $expiry_time_in_seconds)

Before contacting Smashwords we first check our cache if the date is there already:

function getBooks($params){
  $author = $params['author'];
  // get data from cache
  if ( false === ( $allBooks = get_transient( $author ) ) ) {
    // It wasn't there, so regenerate the data and save the transient
    $allBooks = $this->getBooksFromSmashwords($params);
    set_transient( $author, $allBooks, 60*60*12 ); // 12h
  }
return $allBooks;
}

Displaying the books
The widget can display one or more books at the same time. This can be configured in the Widget settings.
If the author has more books then configured the user should be able to scroll through the books like a slide show. To get a nice sliding effect I used the jQuery libary:

$swbw_slideInner.animate({
  'marginLeft' : slideWidth*(-currentPosition)
});

Since widgets are per default multi widgets, that means that they can be placed multiple times on the same page its important to use no ids in the rendered html as they are per definition only allowed once per page. The sames goes for selecting elements in the dom via jQuery. Its important to use selectors who are relative to the widget:

jQuery(document).ready(function($){
  $(".swbw_slideshow").each(
    function decorateSlider(){
      var slides = $('.swbw_slide', this);
      // ...
    }
  )
}

What does that mean? First we identify all widgets on the page by

$(".swbw_slideshow").each(...

Within the widgets we select relatively to the widget by the second parameter this:

var slides = $('.swbw_slide', this);

This way we make sure that we address only the current widget and not the others.

Go here to download the full code.

Resources:

 

This entry was posted in creating ebooks, tutorials. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *