Converting To Jekyll
Converting to Jekyll
As many of you probably noticed, our layout got more simplistic, smaller, and reminiscent of the 90’s. I could make a joke about I’m a ham so I’m legally obligated to build websites like it’s 1992; but that’s not the truth. The truth is I like this minimalistic terminal inspired design. Is it the one I wanted? No. I found several terminal themed Hugo themes that were better. But Hugo was a pain. So…here we are.
“It’s all static sites now.”
Years ago I remember static sites were the norm. Sure, you had PHP and some CGI stuff; but websites were still a largely static affair. You had a webroot, all your files were there, and all URLs were relative to that. I could barely configure a webserver back then…but I could hack something together in front page, add the Blogger tags in the right places and make a site. Then…I don’t know…13 years ago or so; I got in to Wordpress. I was lazy. I just wanted to write content. It took all the work out of it, ya know. I just go on, write something, publish, and with everything rendered at load I didn’t have to wonder if I updated the menu on 4000 HTML files.
This, of course, comes with a downside. Wordpress is highly exploitable.
This was part of the reason I finally ditched it. Despite my best efforts to lock it down, my keeping of nothing important here in case it got hacked, and everything else; I finally had to say no more. The security issues were getting to be too much. Twice in a year I had one blog get 1000 spam posts put in it. Just one theme. With comments and everything disabled…I’m not sure where the SQL injection was occuring; I had most commands and input boxes disabled. This is the same theme that was also running a sketchy looking CRON job. As a postscript: I posted 1-star review saying I would never use those themes again. The author was VERY quick to ask about the issues…but then ghosted me after I expressed them. That was enough.
The reality is there wasn’t much dynamic content here. I had a few pieces of random text and some PHP pulling from shell scripts. I can still run those scripts; just iframe embed a php, server STILL has PHP enabled since I use it for imghost. I just had to figure out what I wanted to use….and how.
Hugo, Jekyll, & Static Site Generators
I could write very little about them. Static site generators have been around forever. Originally you were the static site generator writing all your static HTML for your web-browser. CMS-like editors existed for a while. I very clearly remember a program for Windows from the mid 90’s whos goal was to help you maintain your static site. You could make changes and deploy them to all the pages that needed them. Somwhat similar in concept to what these new things do; except they render from files instead of working with a full site.
But the problem for me, as someone with little web expierence, was getting all of this working or unstand how it worked. I tried Hugo, I really did. It was the one everyone recommended. But the reality was at the end of the day; I couldn’t get it to do what I want. I could build a site with it; but I was stuck using lousy themes. The ones I liked, didn’t work. I literally tried for days to the point I took everything down. I think the biggest issue with Hugo is that none of my stuff was organized like a website, so I had confusion as to where to put files to render. It also refused to let me put HTML or stuff in the markdown files. Yeah…I get it…but holy cow; modifying themes to do one-off stuff was annoying. It also felt like I was mixing too many programming languages; most of which I’m not familiar with. This made trying to hack things together much more difficult.
So I decided to try Jekyll. I won’t say it was easier; but clearly something about it clicked since I’m using it. It has a similar organization to Hugo in how it handles files; which is going to take some getting used to. I have to navigate deeper in to folders than I want to create posts. I did concede that there’s no real difference between “pages” and “posts” from a functional standpoint. Wordpress treated them differently. This was a problem for doing things in Jekyll like generating post lists. The thing I really didn’t want is to have to treat this like a manual site and update links in pages every time I added a non-blog related page. In fact when I first started…I had this little bash script written up:
#!/bin/bash
POSTS=$(find . -type f -exec stat -c '%Y %n' {} \; | sort -nr | awk 'NR==1,NR==3 {print $2}')
echo $POSTS
for FILE in $POSTS; do
cp -R $FILE $(pwd)/../
done
This script was basically finding the three most recent posts and copying them in to a directory? Why? I thought that’s what I had to do. I only wanted a couple of posts on the main page; the way this theme was done it listed ALL of them. Yeah, this is because I’m an idiot and didn’t bother actually reading the docs. By this point I just wanted to get something up. I was starting to feel a large level of defeat which wasn’t good in my brain-fogged mental state.
Then I found the option to limit the number of posts. Oh boy. I was on to something. I just had to figure out how to make the rest of this stuff work.
I won’t go in to the details. There were a few hours of raging at the monitor because gems just made no sense. Where was my theme stored? What? It made no sense. Then it did; and I started hacking on some of the theme code. I ultimately made the following modifications:
- hacking css and head.html to pick bulleted lists in the front matter
- putting a non-relative link in the menu
Now the main thing I really started to like about Jekyll was the fact I could mix HTML in my markdown. I’d tried this in Hugo and it literally yelled at me. If I wanted to do HTML snippits…there was another way I had to do them. I’m not worried about sticking to the straight markdown format; sometimes I have just snippits of code I want to use. Jekyll will let me do that. For example; the front page of this theme was originally had the display of posts as part of the theme’s layout:
---
layout: default
---
{{ content }}
{% assign contentwonl = content | strip_newlines %} {% unless contentwonl == "" %} <br /> {% endunless %} <!-- add line break if there is any content -->
{%- if site.posts.size > 0 -%}
<ul>
{%- for post in site.posts -%}
<li>
{%- assign date_format = "%Y-%m-%d" -%}
[ {{ post.date | date: date_format }} ] <a href="{{ post.url | relative_url }}">{{ post.title | escape }}</a>
</li>
{%- endfor -%}
</ul>
{%- endif -%}
Which is cool and all; but I’m the kind of person I want my index.md to be my ENTIRE index file. I wanted more flexibility in where I put things. Where as Hugo would have complianed had I tried to put that code in a markdown file; Jekyll let me do this:
# ***Recent Posts:***
<ul>
{% for post in site.posts limit:3 %}
<li>
<a href="{{ post.url }}">{{ post.title }} - /{{ post.categories }}</a>
{{ post.excerpt }}
<a href="{{ post.url }}">Posted: {{ post.date | date: "%d-%^b-%Y" }} | Read More...</a>
</li><br>
{% endfor %}
</ul>
# *Less Recent Posts:*
<ul>
{% assign counter = 0 %}
{% for post in site.posts limit:6 %}
{% assign counter = counter | plus: 1 %}
{% if counter > 3 %}
<li>
/{{ post.categories }}: <a href="{{ post.url }}">{{ post.title }} | {{ post.date | date: "%d-%^b-%Y" }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
I put that right in my index.md where I wanted it; changed the layout from “home” to “default”. No complaints about HTML in Markdown; Jekyll just takes all the markdown, renders it as html; and renders all the HTML as HTML.
But that’s not really what I came here to talk about. I came to talk about .bashrc. Yes.
If not running interactively, don’t do anything
Let me show you something that cost me two hours:
case $- in
*i*) ;;
*) return;;
esac
This is at the very top of .bashrc. This was a problem.
You see…the one thing I liked about Wordpress was the fact I write a post, I publish, it’s up. Static site generators by their very nature don’t do this. They support this for development; but it’s not a good idea to use them for production use. So I started thinking of ways around this; some kind of landing page on the server to trigger a render, CRONJOB every few minutes…those were about it. I didn’t realize githooks were a thing. Even better since I’m running my own git; the scripts are just all local.
You see…I’d been spending a lot of time updating stuff on my GIT, writing Aasterisk notes and such. This was one of the reasons I wanted to switch to something that used markdown. The new way of doing the website lends itself to being a git repository. This is actually what I want…then I just push new files up. The other magic of git is githooks; scripts I can run based on various actions taken. This is actually how a lot of people use Hugo and other static generators; they just push to their site’s repository and use a githook to tell it to render.
Well…this is where my .bashrc file screwed me over. Ruby, gems, and jekyll aren’t installed system wide; they’re installed per-user. But I have root…so it’s no problem for me to sudo su git and install all the stuff. Right? Actually right. That’s not the problem. The problem were my flippin paths!
# Install Ruby Gems to ~/gems
export GEM_HOME="$HOME/gems"
export PATH="$HOME/gems/bin:$PATH"
These lines specify that all of this goes under your home directory. The problem becomes when .bashrc isn’t processed. Those PATHs never get exported to shell. The result? I’m trying to figure out why the hell I’m specifying my .bashrc at every possible step but getting either invalid commands or something wanting root. I mean it’s for non-login shells..which are usually non-interactive. But I even got to the point where I was putting the build in an external script and calling that…becuase it “magically worked when I ran the script”.
Anyway…after moving those lines to the TOP of the file; the githook works.
#!/bin/bash
GIT_REPO=$HOME/[REDACTED]/pickmy-dot-org-jekyll-site.git
TMP_GIT_CLONE=/tmp/blog$$
PUBLIC_WWW=[REDACTED]
mkdir -p $TMP_GIT_CLONE
git clone $GIT_REPO $TMP_GIT_CLONE
pushd $TMP_GIT_CLONE
bundle install
bundle exec jekyll build -d $PUBLIC_WWW
popd
That’s literally it. There’s probably some fancy way to do it; but this does the same job. Clone the repository, build, GTFO. The temporary directories are cleared out daily; there’s a number of write-protected files that hang up the script. So I just do a rm -r /tmp/blog*
as a root cronjob every 24 hours.
I’m still fried over the whole thing; that’s why this post is no where near my usual quality…or maybe it is.
Posted on: 24-AUG-2022