DeerBooks - Text/Writing Management

Updated: February 2, 2017 23:31:13 • 704 words
  • URL: GitHub
  • Started: August 2013
  • Role: Solo Developer
  • Tech: Django/Python, LaTeX


DeerBooks is the latest version of one of my earliest PHP projects: a text-focused content management system with unique features found in no other CMS. When I made the switch from PHP to Python, I took the opportunity to redesign how the system worked, but the feature list mostly stayed the same, with some additions.

Current Features

  • Optional table of contents to join multiple page objects into a single "book". This is a new feature that I never got around to including in the old PHP version, and it's a core feature of DeerBooks as it exists today: Individual content items (pages) can stand alone, or they can be added to a group (book/toc) that unifies all of them with a shared title ({Book Title} - {Page Title}), and a table of contents link that allows a visitor to jump between them (order is manually set). Additionally, this joins multiple pages together for the alternate view/print formats.
  • Support for full HTML formatting, or unformatted plain text. This makes it a powerful tool for building a website, and a quick and easy tool for writing. The basic code for this is currently very simple: If a page body contains <p> or <br> tags, it's displayed as-is. However, if it does not contain those, it's assumed to be unformatted, and the Django linebreaks filter is applied before display to turn the linebreaks into <p> and <br> tags. As a former LiveJournal user, I like having the option to just write in plain text without dealing with a WYSIWYG editor's bloated markup, but I also tend to do advanced HTML in some pages, so I wanted a CMS that could easily do both.
  • Integration with external reading services. As confident as I am in my own design work, I encourage everyone to do their online reading on their own terms. So, DeerBooks is fully integrated with Readability, Instapaper, and Pocket. Adding direct links for other services is certainly an option in the future, too. These tools perform a wonderful service, and I'm happy to encourage their use.
  • Alternate display in plain text, Markdown, and LaTeX formats, with manual override. My preference for plain-text reading and writing is somewhat anachronistic, but it's a strong preference nonetheless. So, in addition to the regular HTML view, every page can also be viewed as plain text (.txt) or Markdown (.md). Pages with Auto Export enabled can also be viewed as LaTeX source (.tex), which is used in the generation of print/export files. And, these formats can be manually uploaded instead of being automatically generated, which overrides that particular alternate format view.
  • Automatic generation of PDF, DVI, and PostScript files for export, reading, and/or printing. This is one of the key features of DeerBooks, and one of the original features of its PHP predecessor. A management command is run by cron on a regular basis, which checks for pages that can be automatically exported and which have been modified more recently than the existing exported files. If any such pages are found, it saves a copy of the page's LaTeX source view (or, if a LaTeX file has been manually uploaded for this page, it uses that instead) to a working directory, runs a LaTeX command on it, and attaches the resulting document files to the page.

Planned Features/Improvements

  • Automatic generation of EPub files. Generating PDFs from LaTeX is great, but PDFs aren't very mobile-friendly. So, I'd like to add EPub format to the list of document files automatically generated by DeerBooks.
  • Import of .txt files. Much of my long-form writing occurs in plain text files, and while it's simple enough to copy and paste, I'd love to have a method of directly importing a text file into the system.
  • Automatic table of contents for pages containing header tags. Much like how most wiki software will create a table of contents for a page with multiple headers, it would be very handy to automatically generate this for pages with multiple headers, with named anchor tags injected into the page's content.