Update to my blogging workflow

August 17, 2020 | ~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 it may be important to point out that the way I create my blog posts may not necessarily 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 create the final post for publishing.

That looks like the following:

Header and footer diagram

With that in mind these files should 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:

Full post diagram

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:

  1. Create the blog post and allow for preview
  2. Publish the blog post to your public web server
  3. 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 this is a good think 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.