Skip to content

Book data object

joseph edited this page Sep 4, 2011 · 1 revision

The "book data object" is a simple API convention that connects your book's content and structure to the Monocle Reader object. It's designed to map pretty closely to standard concepts in the EPUB and Zhook ebook formats. We've designed it to be flexible — the simplest implementation is trivial, and more complex implementations can be devised to accommodate features like offline caching, AJAX loading of content, and so on.

The book data object should provide certain required methods.

Methods:

  • getComponents: returns an array of all the component ids that are to be accessed in linear reading order (ie, like the spine in an EPUB OPF file — you don't have to list every component, just the ones that are read in order).

  • getContents: a function that returns an array of nested objects. Each object responds to title (a string), and src. src is a string that "addresses" a component and (optionally) a location within that component. Locations within components are indicated using standard HTML anchor notation — for example, "cmpt1#part3" points to an element with an id of "part3" within the component named "cmpt1". An example is shown in the next section.

  • getComponent(componentId, callback): takes a component id (from the list returned by getComponents) and returns the body text of the corresponding component. If nothing is returned, Monocle will wait for the callback to be invoked (ie, by an asynchronous operation). Either call the callback with data, or return data, but not both.

  • getMetaData(key): takes a string "key" and returns the value of that metadata for this book. There is not yet any standardized list of possible keys -- we'll just see what happens for a bit. Note that if nothing will go wrong if you return null or an empty string for any requested key.

Note that if these methods retrieve any data from a server using AJAX techniques, it should be a synchronous operation, because the clients of the book data object expect the result to be returned from the method itself (not via a callback). The exception is getComponent, which can use the callback for asynchronous data retrieval.

An example of getContents

This is an example of a contents structure with one top-level section containing two sub-sections:

[
  {
    title: "I: A curious incident",
    src: "component1.xhtml",
    children: [
      {
        title: "I. a. Part the first",
        src: 'component1.xhtml#part-the-first'
      },
      {
        title: "I. a. Part the second",
        src: 'component3.xhtml#part-the-second'
      }
    ]
  }
]

Complete example of a book data object

This is an example of a fully-specified book data object.

var bookData = {
  getComponents: function () {
    return [
      'component1.xhtml',
      'component2.xhtml',
      'component3.xhtml',
      'component4.xhtml'
    ];
  },
  getContents: function () {
    return [
      {
        title: "Chapter 1",
        src: "component1.xhtml"
      },
      {
        title: "Chapter 2",
        src: "component3.xhtml#chapter-2"
      }
    ]
  },
  getComponent: function (componentId) {
    return {
      'component1.xhtml':
        '<h1>Chapter 1</h1><p>Hello world</p>',
      'component2.xhtml':
        '<p>Chapter 1 continued.</p>',
      'component3.xhtml':
        '<p>Chapter 1 continued again.</p>' +
        '<h1 id="chapter-2">Chapter 2</h1>' +
        '<p>Hello from the second chapter.</p>',
      'component4.xhtml':
        '<p>THE END.</p>'
    }[componentId];
  },
  getMetaData: function(key) {
    return {
      title: "A book",
      creator: "Inventive Labs"
    }[key];
  }
}

// Initialize the reader element.
Monocle.Reader('reader', bookData, {}, function (reader) {
  reader.moveTo({ page: 3 });
});