Every reading list system I've tried to use up until now has failed for me; it doesn't incentivize me to read the things, and it doesn't encourage thinking about what to read/what it is I'm reading. In an ideal world, I'd have about 10 things on there, and I'd eventually read all of them. I'd also
I want to design a reading list that helps me solve this problem. That is; it encourages me to keep the list short, and it encourages me to think about what I've read. We'll look at the design I arrived at next. This is my second go at implementing such a system. My first attempt was a browser extension, which didn't really work because it wasn't accessible enough to where I do my browsing/reading &emdash it only worked on my laptop in Firefox Developer's Edition. The main technical constraint is that I don't really know what I'm doing.
Design
My two problems were:
- Too much to read,
- Not engaging with what I read,
So, I set about designing a reading list that would solve these.
Too much to read!
When there's too much to read, I start to choose what I want to read. This means some (less appealing) things get left on the list for ages and ages, and it slowly builds up as I read the most interesting thing to me at each particular moment. This is how I ended up with 211 open tabs on my phone, because the 212th tab was the most interesting to me, so I read it, and closed it.
The cause of this problem, then, is
Not engaging with what I read
It's not that what I read isn't
I know from studying for my degree/high-school/learning things my whole life that I learn well by doing, and that if the thing I'm learning doesn't have much doing about it, then I learn it well by explaining it to myself (or others, but I'm more available). That way I know if I've "got" it or not. When I have to read material, explaining it back, summarising it, thinking about what I liked/didn't like is very useful and quite effective. I.E., I'd like to take notes about what I read.
I've tried a lot of note-taking systems in the past, and I currently use Obsidian/Anki pretty effectively for my degree. They don't work for this sort of incidental/leisurely reading for me because they require too much set-up. I have to open the note, edit all the metadata to make it match what I'm reading, think of a title, save it somewhere sensible. Then I have to be able to track it down and open it again when I want to refer to it. Once again, the problem is too much flexibility.
The solution for this seems straightforward: as well as opening the thing I get to read, the read button should
Implementation
This is actually my second go at implementing the system I described above. The first time was a couple of months ago as a browser extension. Whilst it did work, it ended up not being very useful because it would only run in firefox-dev, which is not where I did most of my browsing or reading. A big part of the problem is that I'm on my phone; I find things to read on my phone and, if I'm not quick, I'll read them there too. This reading list needs to work on mobile and on my laptop. Thus: a webpage.
I learned how to use PHP exactly one project ago in order to make this website, but it seemed like the right choice for this project. A big reason I wanted to use PHP is that I really didn't enjoy using Javascript when implementing this the first time, the async by default design really messes with my head and I didn't want to try doing server-side stuff with that. Since I have plenty of experience scripting in other languages, I figured this wouldn't be too hard to implement in PHP, and I was mostly right. I think I've spent about 10 hours working on this in total, including writing this post.
The main technical constraint is that I don't know what I'm doing. I want everything to be as simple as possible. This means no database! The list is stored as a .csv on the server,as is password hash that I use for adding to the list on any device.
"Just Open an Editor as Well as the Tab"
There's no way in hell I'm writing a text editor to write my notes in in the browser, especially since I'm a (Neo)Vim junkie and would die without my hjkl. The simplest way is just to open a text editor as well as the tab. It turns out, for some reason, that browsers don't let websites execute arbitrary executables, so I can't have "open $EDITOR" in my website. I googled about this for quite a while, and asked on a discord, where somebody said the magic words "custom URI scheme". It turns out that whilst websites can't execute arbitrary binaries on the client's computer, you can agree to allow certain hyperlinks to open a pre-defined program. This is how "zoom://" and "teams://" links work.
I set about create a custom URI handler on my computer to open Firefox and an editor instance at the same time. This consisted of writing a (Fish) shell script to do just that, and then writing a .desktop file that dealt with the URI magic. This is why, if you click on my "read" button (oh shoot, you shouldn't be able to... I need to add authentication to that), then nothing happens, or your browser will just complain. I want my shell script to have access to the page title attribute, so this is included in the URL as a query string. This also means the form has to have a "POST" rather than a "GET" method as otherwise the query is overridden with the (non-existent) form contents. The shell script parses the URI, then uses the variable replacement within Fish to populate a template string with the date, the page title and the URI. Then this is passed into nvim. A Firefox tab is also opened on the new page.
The actual button is very convoluted. It's a HTML form that includes a PHP script that is a HTML snippet of a button with an "onclick" attribute (the only piece of Javascript on this page!) which modifies window.href to a value which is provided by a second PHP include that calls a function which fetches the topmost item in the list, that hasn't been read, and echoes its URI after appending the title as a query string and swapping the protocol for my custom one.
This script also implements the only piece of feature creep I had. Once neovim is closed, it runs pandoc with a custom template to convert my markdown notes into the sort of beautiful HTML you see on this website. Then it copies it into the website directory, where the page script will link it to its entry in the reading list the next time the page loads. Notes are matched to their webpages by their (saved at adding) titles.
Fifo!
Fifo would be a cute name for a dog. The rest of the reading list application logic I implemented in PHP by reading/writing to a CSV file storing the URLs, titles, the date read and if notes exist. It's not too interesting.
Writing (and eventually reading) are authenticated using a password. This means only I can modify my list, but I can do it on any device I can access the website from.
What I learned
What I've made here is a tool to help me regulate my attention. It's a disability aid for my brain.
How to grow your own?
Uhhhhh, ask me lol. I will warn you my code is super janky, but it does work? It's a handful of PHP files to copy onto your website, and you need to use the PHP builtin password_hash
at the command line to produce your password hash to copy into the file.
What next?
There are a couple features I'd like to implement.
- List is displayed in reverse order, so the things you've read are at the bottom, and the thing you're going to read next is at the top.
- Logging in sets a session cookie so I don't have to keep enterring my password,
- You have to be logged in to have the "read" button modify the backend.
- UI for manually adding/changing a title in case the getting the title fails (it would be cool if this were reactive and showed what the title would be before you clicked add... ANSWER: WORST FEATURE EVER ARRGH I HATE JAVASCRIPT IT MADE ME WRITE A PHP API AND ARRRGHHS PROMISES)
- PHP script for generating filename / note title from h1 and title attributes, script so both the server and the uri handler can agree for any given url. Should use http(not s) so it fails less often
- Add CSS and make UI nicer (bigger) on mobile
- Disable read button on mobile
- No need for a login message taking up space if read button indicates not logged in
- There can be errors with note .md and .php titles not working as encoded urls properly (fixed since api fr filenames now)