As I mentioned yesterday I'm moving posts over to Jekyll from my WordPress blog. To get started, I used a wordpress plugin called simply Jekyll Exporter to export all of my posts and pages into markdown files. This worked pretty well, but since I want my site to be 100% AMP Only, I decided that rather than just publishing them all I should make sure that none of the old markup (much of which has been migrated between 3 different platforms) ends up causing pages not to validate in the AMP Validator.
I decided not to wait till I had converted all 212 pages to go live at nickmoline.com, but in the vein of old Under Construction pages of the 90s I decided it would be neat to display a progress bar on how much of the backlog I've worked my way through.
What's cool about this bar (which is shows up not only here, but also on the home page and in the previous blog post) is that it is being generated entirely dynamically from my jekyll repo. I thought it would be interesting to explain how I got my repo to generate this dynamically in this post.
Determining what is done
Jekyll has a global array called site.posts
which contains everything necessary to loop through all of the posts on the site. In the Liquid Template Language (the templating engine Jekyll uses), you can use .size
to determine how many elements are in an array, including this list of posts.
This way I'm able to determine how many posts have been written.
Determining what is not done
Live posts in Jekyll are stored in a _posts
folder. There is also a _drafts
folder which contains post drafts that you haven't finished yet, but there's a difference between drafts and what I'm doing here. As such my first goal was to create a Collection of the posts that have not been migrated yet. I moved all of the posts that I had not yet checked for formatting and placed them in a _pending
folder, i then configured the collection by adding to my collections array in the _config.yml
file like so:
This now creates a new collection named pending
which works much the same as the built in posts
. The list of pending posts are available in a separate array site.pending
which I similarly can use site.pending.size
to get a count of.
Calculating Percentage
I can now add the two values together to get a total count of posts both pending and live.
Math in Liquid is done with filters, so I take site.posts.size
and I add with | plus:
the site.pending.size
to get a total count. You'll notice I then multiply this by 1.0
. The reason I do this is to make sure the total_post_count
variable is a floating point number, rather than an integer.
To get the percentage, I can then divide site.posts.size
by total_post_count
.
{% assign migration_percentage = site.posts.size | divided_by: total_post_count | times: 100 | round: 2 %}
For presentation's sake I'm then multiplying by 100 and then rounding to 2 significant digits. At this point I have all of the numbers I need. I know how many published posts there are (currently ##), how many posts are pending migration (##), how many posts there are total (##), and what percentage of the total posts are done (##%).
Rendering the progress bar
The progress bar itself I'm rendering using the HTML5 tag progress element which is specifically designed for rendering this.
<progress
max=""
value=""
title="% migrated"
></progress>
I could have set max
to 100
and used the migration_percentage
as the value
, but I thought using the actual values would make for a more accurate status bar as it would be calculated with a higher precision than I want to display. I then set a title attribute so that when you hover over the progress bar you see the percentage.
For styling the progress bar, I followed the fantastic guide posted at css-tricks by Panjak Parashar and then tweaked things a bit to my personal liking.
So that I can easily include this in multiple places, I stored all of this in an include file named migration-progress.html
so that I could include it in multiple places (such as the home page and my previous blog post and future tweaks could be shown in multiple places.
Dealing with future posts
At this point some of you may have noticed a flaw in the above that this post actually exacerbates, it counts new posts as migrated posts. The more I blog before the files are published, the more the numbers will be incorrect. To solve this, when I finished I simply replaced the calculation making the total a fixed number (212) and calculating the number published as the total minus what is left in the pending folder.
Here is the final modified version to take this into consideration.
{% assign total_post_count = 212.0 %}
{% assign posts_migrated_count = total_post_count | minus: site.pending.size %}
{% assign migration_percentage = posts_migrated_count | divided_by: total_post_count | times: 100 | round: 2 %}
<progress max=""
value=""
title="% migrated"></progress>
Migrated <strong></strong>
out of <strong></strong> posts migrated (<strong>%</strong>).
<strong></strong> posts remaining to migrate.
UPDATE 2020-08-27
I've finished the migration, migrating all of the 212 posts from my old blog, as such I've flipped the gauges that you see on this page and others to a fixed 100% complete gauge. While this code worked very well, there's no reason for it to be making additional math updates now that it is always going to come across as 100%. The code snips above are still how to make the gauge dynamic.