Update to my blogging workflow
Published: 2020-08-17 | Last Updated: 2022-01-09 | ~10 Minute Read
Motivation
As I have stated before my blogging workflow had room for improvement and since then I have wanted to work on making it easier for myself to write posts.
As I mentioned in that previous blog post I wanted to build this blog from scratch and seeing as I used a small bash script previously to create my blog posts I thought I would expand on that.
Upon review of whether others had done the same in the past I came across other really nice bash tools to maintain and publish posts to a blog. The one with the most “fame” seems to be bashblog but there are also org-bash-blog and pandoc-bash-blog.
Although those are really nice, and seem to be actively developed, I thought that if I used them I would not be adhering to the rules that I had set for myself, specifically the “from scratch” rule. So I decided to write my own version of a bash tool for this purpose and Bourne to Blog was born.
Creation
The thought process behind the script took my current workflow as a starting point, so I’d like to point out that the way I create my blog posts may not necessarily be the same way you do it. So I think it’s very important to describe my current workflow.
Initial Plan
In my original post I briefly mentioned my overall workflow, but I will expand on that here.
On some of the initial brainstorming sessions that I had when I first started my blog, I came up with the idea that the header and footer of the page for my blog posts were always going to be the same (static within static pages? :p).
I wanted to focus on the blog post content rather than the hassles of maintaining a web site. So I decided to separate the header and footer files since they would always be the same, This allowed me to focus on the content of the posts and when I was ready to publish something I would simply concatenate the header and footer files to the post content to create the final website.
Bourne to Blog Workflow
With that same initial workflow in mind Bourne to Blog expects a header and a footer file to be pre-created in order to generate the final post for publishing.
That looks like the following:
With that in mind these files should already exist and be provided to Bourne to Blog.
The current files that I’m using are the following, I will provide sample files on github as well.
My current header file looks like this:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="/css/style.css">
<link rel="icon" href="/favicon.ico">
<title>Nix Adventures</title/>
</head>
<body>
<header>
</header>
<nav>
<ul>
<li><a href="/index.html">Home</a></li>
<li><a href="/blog/blog.html">Blog</a></li>
<li><a href="/apps/apps.html">Applications</a></li>
<li><a href="/pages/pages.html">Websites</a></li>
<li><a href="/games/games.html">Games</a></li>
<li id="feed"><a href="/feed.xml"><img src="/img/feed.png" alt="RSS Feed"></a></li>
</ul>
</nav>
<main>
I define a pretty basic HTML structure and stop after creating the <main>
HTML opening tag. With that I can simply create the content of my posts and all of the HTML generated by the discount tool will fit nicely below this opening tag.
Let’s take a look at the footer file:
</main>
<footer>
</br>
</br>
</br>
</br>
<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
<img alt="Creative Commons License" style="border-width:0"src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" />
</a>
<p>This work by
<a xmlns:cc="http://creativecommons.org/ns#" href="https://nixing.mx" property="cc:attributionName" rel="cc:attributionURL">nixing.mx</a>
is licensed under a
<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
</p>
</br>
</br>
</footer>
</body>
</html>
As you can see the first line of the footer file is the </main>
close tag, this means that anything before that is part of the post. The rest of the footer is simply the licensing information for the posts and I end with the closure of the </html>
tag.
Bourne to Blog will “sandwich” these files along with the content of the post in order to create a final ready-to-publish post. If our post file was the following for example:
# This is my first blog post!
## It was very simple to accomplish
This is my first blog post using `Bourne to Blog`
Then the full blog post web page after Bourne to Blog is executed would be the following:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="/css/style.css">
<link rel="icon" href="/favicon.ico">
<title>Nix Adventures</title/>
</head>
<body>
<header>
</header>
<nav>
<ul>
<li><a href="/index.html">Home</a></li>
<li><a href="/blog/blog.html">Blog</a></li>
<li><a href="/apps/apps.html">Applications</a></li>
<li><a href="/pages/pages.html">Websites</a></li>
<li><a href="/games/games.html">Games</a></li>
<li id="feed"><a href="/feed.xml"><img src="/img/feed.png" alt="RSS Feed"></a></li>
</ul>
</nav>
<main>
<h1>This is my first blog post!</h1>
<h2>It was very simple to accomplish</h2>
<p>This is is my first blog post using <code>Bourne to Blog</code></p>
</main>
<footer>
</br>
</br>
</br>
</br>
<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
<img alt="Creative Commons License" style="border-width:0"src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" />
</a>
<p>This work by
<a xmlns:cc="http://creativecommons.org/ns#" href="https://nixing.mx" property="cc:attributionName" rel="cc:attributionURL">nixing.mx</a>
is licensed under a
<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
</p>
</br>
</br>
</footer>
</body>
</html>
With that we have created the final blog post that is now ready to be published to our public web server, an updated version of our previous diagram would be the following:
Bourne to Blog Features
The idea was to make a really simple tool, doing so would help the ease of maintenance and the ease of use. With that in mind I though of what to me are the core features for this kind of tool:
- Create the blog post and allow for preview
- Publish the blog post to your public web server
- Publish / Update your blog RSS feed
These basic features will allow the code base to remain small and manageable.
Additional Features
For additional features I plan to set up an include based mechanism, this will allow for a modular system. By doing this we accomplish the goal of maintaining a small core codebase as well as allowing for additional functionality to be implemented.
Another benefit of having this type of setup is that if users don’t need a certain functionality they can simply omit adding the included file that implements the non-desired functionality and avoid having a bloated tool on their system.
Development
This tool is something I did for myself because of the way I want to run my blog and also because it helps me learn about shell scripting. I currently have not finished adding the RSS feed publishing feature so I’ll be working on that next.
I’m excited to see what other features I come up with and implement in this tool, I want to keep it simple and I aim to keep it functional so don’t expect to see an automated chat function for your blog any time soon (although that’d be really cool from a bash script don’t you think?).
The internals
The script at this point is just over 100 lines with comments and spaces, so I’d calculate about 100 lines of actual code if not less. Once the RSS feature is added that number will go up, but I hope I can keep that number low in order to avoid adding bugs and also avoid going crazy trying to fix the ones that do come up.
The script is currently divided up into two functions, once the RSS feature is added that should make three, which will be the core of the script. These functions take input from a set of variables in the script which the user can edit to accommodate to their needs and then simply focus on the blog posts after that.
The script will take either of two (or both) flags and will process the posts accordingly. Each of those flags is set up to allow the user to execute part of the script in case the other functionality is not desired.
The build function
This function is in charge of doing the conversion to HTML from markdown and the “sandwich” with the footer, header and the post content that you pass into it.
It basically takes the file that you create with your text editor and calls the markdown
command from the discount program on that file to end up with an HTML file.
Once that is done the header and footer files get concatenated into the final file which is ready for preview and / or publishing.
The code of that function is the following:
# Function that will build the posts
function buildPosts() {
# Message when starting the function
echo $EXEC_MSG
# For loop that goes over all files with the .md extension in the specified directory
for FILE in $SOURCE_DIR$SOURCE_EXTENSION
do
# Define for loop variables
# Define the FILE_NAME variable from the FILE variable value, removes the extension
FILE_NAME=`basename "$FILE" | cut -d "." -f 1`
# Define the HEADER_FILE variable from the global HEADER_FILE variable value
HEADER_FILE=$1
# Define the FOOTER_FILE variable from the global FOOTER_FILE variable value
FOOTER_FILE=$2
# Define the TEMP_PATH variable from the global TEMP_PATH variable value
WORK_DIR=$3
# Define the CURRENT_FILE variable
CURRENT_FILE="Creating $FILE_NAME"
# Echo the name of the file that is being created
echo $CURRENT_FILE
# Use the Markdown library to create the temporary html file
markdown $FILE > $WORK_DIR$FILE_NAME
# Build the page with the header file content and the footer file content and write the new HTML file
cat $HEADER_FILE $WORK_DIR$FILE_NAME $FOOTER_FILE > $WORK_DIR$FILE_NAME.html
# Delete the initial file with no html extension
rm $WORK_DIR$FILE_NAME
# End the for loop
done
# Echo a completion message
echo $COMPLETION_MSG
}
The publish function
This function is in charge of connecting to your SFTP server and uploading the created file(s) from the build function into the desired folder on that server.
I created this function with SFTP since that is all I have available at the moment on my public web server, there is no rsync
or scp
. I think that thisis a good thing since SFTP in general is a more well supported technology and thus makes the script more portable.
The function code is the following:
# Function that will publish the posts to the public web server
function publishPosts() {
# Change into the working directory defined by WORKING_DIR
cd $WORK_DIR
# Determine if there are any files that need to be uploaded to the webserver
if [ $NUMBER -ge 1 ]
then
# Upload the files in the FILES variable to the webserver
echo "$FILES" | while read LINE ; do (echo cd $BLOG_PATH; echo lcd $WORK_DIR; echo put $LINE; echo quit) | sftp -b - -i "$IDENTITY_FILE" "$USER"@"$HOST" ; done
else
# Echo a message and do nothing if there are no new files
echo $NO_FILES_MSG
fi
}
Conclusion
I will continue to add functionality that I find useful for myself and possibly others. Overall I’m really happy that I got the time to work on this little project and I’m excited to see if it grows. If not, I might blog about it while using it to publish that post like I did this one! :P
I hope you enjoy it, and if you do plan to use it, you should update the list of users over at the Bourne to Blog Github repository.