Start downloading books now!
Launch ShelfServer
Tomes
E-Book reader for iPhone & iPod Touch

OpenSource ShelfServer released

July 5th, 2009

It took me long enough, but source for the ShelfServer is finally
available.  If you’d like to setup your own server, there are hooks to
customize security, and some other assorted goodies.

Source links are here:  http://www.iphonebookshelf.com/trac/wiki/ShelfServer

The source is made available under the terms of the GNU General Public License, version 3.

Please post any questions or issues with the source release in the
support forum: http://www.iphonebookshelf.com/forum/list.php?17

The source release is of course provided as-is, without warranty,
and is officially unsupported. I’ll do anything I can to help, but if
it breaks, you get to keep the pieces.

Searching for something?

May 22nd, 2009

I’ve been frantically coding away at BookShelf for the past few
weeks, and search is just about ready to go.  I should have a beta out
this weekend with it, and I’m thinking a point release in the next
couple of weeks to Apple which will include search as well as on-device
file organization (which is already in the current beta).

After that, I plan to work on color customization, an in-app sales
interface to buy books online, and a few other assorted goodies that
should hopefully be ready in time for BookShelf’s first birthday.

Espresso Live Preview with Chrome, hold the Copypasta

April 29th, 2009

It seems like ages now that I’ve sought the “perfect” website design tool. Ever since the dark days of FrontPage, I’ve loathed HTML generators with their bloated markup and non-standards compliance. Still, while hand-coding XHTML is clearly the One True Path to Enlightenment, I’m no Buddha; and being able to do things WYSIWYG from time to time is a nice crutch. At the very least, I need a quick at hand live preview so that while I walk the Eight (below the) Fold Path, I can get a feel for what my page looks like as I’m writing it.
I spent a few weeks not long ago searching out Mac web design tools and putting them through their paces. I looked at full WYSIWYG tools like Sandvox and Rapidweaver, but both were a bit too invasive in terms of site layout, and neither allowed mixing rich text editing with manual markup creation while still providing a constant live preview.
I’ve always got my beloved TextMate to fall back on for markup editing, but Apple-Tabbing and hitting refresh in a browser isn’t exactly what I have in mind for live preview.
I tried out Coda for a while, but decided to Refrain from that. Nice enough, but not quite. Finally I settled on Espresso, in part because it finally unlocked in the last MacHeist, but more because I already fell in love with MacRabit’s CSSEdit which I still use extensively for editing pages that haven’t quite turned into “sites” of their own yet.
Espresso’s not bad, all told. It’s got live preview which you can tear off into its own window. It would be nice if you could dock the preview window to the top or bottom of the editor, but so be it. Espresso doesn’t have any kind of rich text editing, but with the rapidly updating live preview, I can pretty much live without that. I still write better markup than any generator I’ve ever run into.
Still, I was left with the problem of chrome. Espresso does make some valiant effort to preview script files like PHP, but it took one look at my pages and curled up in a ball whimpering in the corner. So I write complicated PHP pages…. It was about that point I decided to scrap PHP for the content pages in the site anyways, so no biggie. But the last thing I wanted to do was end up with all the chrome on every single page. What a maintenance nightmare…


Instead, I came up with a publishing process which applies the site chrome to bare XHTML pages as the site is uploaded. Each page is well-formed XHTML which has an html and mostly empty head tag (the title is set in each page), and a body tag with only the main (center) content of each page. All of the top/side navigation, colors, CSS, etc. is left off.
I wrote a bit of Ant script which prepares the XHTML pages before upload. I went with Ant mostly because it’s the devil I know very well, being a Java coder by day. Bash, Perl, or <insert scripting language> would surely have served just as well. The Ant script compiles and executes a few Java classes which connect to my MySQL server to get news and FAQ’s which are output to XHTML snippets using Freemarker templates (again, the devil I use every day). Finally the Ant script executes an XSLT transformation on all of the XHTML files to apply the chrome and output static HTML files which contain all of the chrome, ready to upload.
This way I only have to update the chrome in one place, but I still don’t need any scripting on the webserver to display everything. All of that’s great except that live preview only ever shows black text on a white background. Not too helpful that. Today I finally found the missing link.


It’s always been in the back of my mind that web browsers can apply XSLT transforms to XML files on the fly when they load them. The Daily WTF’s XSLT Mandlebrot reminded me of that this morning. As it turns out, the Safari-based live preview in Espresso honors XML processing directives as well, and so my prayers were finally (mostly) answered.
I had to tweak my XSLT a little bit to make it work. It appears that Safari only has an XSLT 1.0 parser whereas Firefox happily takes XSLT 2.0. Fortunately I didn’t have to change much to make 1.0. I had to default some of the xsl:param elements that are normally sent in from Ant to sensible values and also rename all of my source files from .html to .xhtml to get everything to work.
The final result is that I have plain XHTML files with no chrome and live preview WITH the chrome appearing in Espresso. I can edit the basic XHTML files; and in less than a second, the preview updates with all of its chrome-y goodness. The changes to make it all work are pretty minimal.
First, the web pages themselves: All pages must be well-formed valid XHTML. A minimum example looks something like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<?xml-stylesheet type="text/xsl" href="apply-style.xsl"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>News</title>
<link href="style.css" rel="stylesheet" type="text/css"/>
</head>
<body>

<div>Put your main content here.</div>
</body>
</html>

The file starts with an xml declaration and the XHTML doctype followed by an xml-stylesheet processing directive. That’s where the real magic happens. That directive points to an XSL file in the same directory which can process this page’s XML to create the final page. Below that are the rest of a simple XHTML page. The link to the CSS fools Espresso into thinking that there’s a stylesheet that can be edited and overridden for this page. The link element is actually replaced by the XSLT, but it does the job of allowing the CSS to be edited. Finally inside the body is the main content of the page, no chrome required.
The XSLT file that brings the whole thing together looks something like this:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/1999/xhtml dtd/xhtml1-strict.xsd"
exclude-result-prefixes="html"
version="1.0">

<xsl:strip-space elements="*"/>
<xsl:output
indent="no"
media-type="text/html"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
cdata-section-elements="html:style html:script"
/>
<!-- Default is just copy everything. -->
<xsl:template match="@*|node()"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:template>

<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="/html:html/html:head/html:title"/></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="description" content="EBook reader for iPhone or iPod Touch"/>
<meta name="keywords" content="iphone,ebook,e-book,reader,electronic,ipod"/>
<link href="{$httpRoot}style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="header">
Header stuff goes here.
</div>

<div id="content">
<div id="maincontent">
<xsl:comment>=======Main Content Starts Here=======</xsl:comment>
<xsl:apply-templates select="/html:html/html:body/*"/>
<xsl:comment>========Main Content Ends Here========</xsl:comment>
</div>

<div id="sidecontent">
Side-nav content here
</div>
</div>

<div id="footer">
<div id="copyrightdesign">Copyright © 2008-2009 Zachary Bedell. All rights reserved.</div>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

The above template is greatly simplified, but it gets the idea across. The real version has code to include the XML files containing site news & FAQ’s where appropriate, a template which calculates the correct value of {$httpRoot} based on the current sub-directory level, and some other BookShelf specific stuff. When I need to update the chrome for the site, the XSLT is the only file I need to touch (plus maybe the CSS if it’s a formatting change). Once the XSLT is updated, re-running the Ant script generates new HTML files and SCP’s them up to my Mac Mini webserver.
To make all of this work in Espresso, you need to … do nothing. Just open or create a project for your files, open an XHTML file and launch a live preview for it. Done!

ShelfServer Beta – ePub Support

April 22nd, 2009

Just posted to the ShelfServer beta distribution is preliminary support for ePub format books.

For anyone new to BookShelf’s beta releases, please keep in mind the true meaning of the word BETA: Barely Even Tested At all…  I’ve managed to get this working on a couple of favorite ePub’s from FeedBooks.com, but it’s certainly possible you may have trouble with it.  Still, if you’re feeling adventurous…
ShelfServer Beta

Obligatory App Store Complaint

April 21st, 2009

And it’s not even my own rant.  Just a link to someone else’s:

[…] but when Apple ties my hands behind my back and lets users punch me publicly in the face without allowing me to at least respond back, it’s hard to get excited about building an app.

http://log.maniacalrage.net/post/98510137/a-little-over-a-week-and-a-half-ago-google

The desire to link that that post is actually what pushed me over the edge to finally setup WordPress on the site.  Mr. Murray rather tidily sums up most of my major frustrations with the app store.  The number of, “I couldn’t figure out how to do foo!  This app sucks!” reviews I’ve read is disgusting.  Of course none of them ever bother to email me or post in the forums…

If you’re reading this contemplating a review, please for the love of Steve, at least drop an email to support at iphone bookshelf dot com first.  If I can possibly help you I will.

In case you were curious…

April 21st, 2009

Welcome intrepid reader,

I’ve made it a (somewhat sporadic) habit for some years to occasionally rave, rant, or otherwise spew forth meaningless nonsense on my personal blog, first on LiveJournal and now on my own domain since LJ’s policies departed a bit from my liking a few years ago.  While said ranting has occasionally leaned towards my iPhone development efforts, I figured the time has come to finally do something official for my applications.

So for the curious, the terminally bored, or perhaps the desperate insomniac, I offer this blog.  I expect I’ll occasionally curse the name of Steve here as I spend hours working around the iPhone’s quirks.  I’ll surely post links to nifty articles about development, and I’ll probably even talk about future plans for the app from time to time.

If that sort of thing tickles your fancy, read on!

Feel free to post any comments or suggestions, but please do be nice.  You can flame me on the forums if you really feel the need.  And to any would-be comment spammers:  May the fleas of a thousand yaks infest your underoos ’til the end of your days.

Copyright © 2008-2009 Zachary Bedell. All rights reserved.