Switch to Reading Mode

DeerBooks - Text/Writing Management

Revised: March 20, 2022 16:49:54 • By Natasha L. • 1061 words

Note: Some content on this site, including this article, is more than a decade old, and may not accurately reflect the author's current feelings or writing style. More information here.

  • 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.
  • "Reading Mode" template, with per-page default view override. I've always been fond of the color scheme used throughout this site, but even I have to admit that it can be less than comfortable to read large amounts of text here. Plus, while the narrow vertical columns are meant to showcase the background photos in addition to everything else on the page (hence why I called the design "Showcase"), that can be a distraction from written content. So, DeerBooks pages have the option to use a "Reading Mode" to change the view, indicated by a button with an open book to the right of the title (it can also be accessed by appending ?mode=read to the end of any DeerBooks URL ending in .htm). This mode shrinks the site header to its minimum size, inverts the content body colors (dark text on light background instead of light text on a dark background), increases the content body font size, widens the main content area, and darkens the background photo. And, for certain content that would benefit from always being viewed this way, such as my resume, there's an option to make "Reading Mode" the default for any page.
  • 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 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.
  • Detection and flagging of content revisions. Indicating whether a page has been revised from its initial publication is a useful standard among journalists, and while I am not a journalist, I felt it was a useful feature to add to this site. However, merely using the standard last-modified timestamp can be misleading for this purpose, since there are a lot of actions that will change that timestamp without actually changing the content. So, DeerBooks now stores a hash of the body content along with the body, to check whether substantive changes have occurred; when saving a page, if the hash of the new body doesn't match the hash already stored in the database, the system sets the revision timestamp to the current date and time (then updates the stored hash to check for the next revision). Then, if the revision timestamp is present, the template will add a note to the bottom indicating that the page has been modified since its initial publication.

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.

This article has been updated as of March 20, 2022 16:49