Tmux Script to Create New Post Environment

In the article describing Tmux, as an example I have shown the script that creates an environment for writing content for my Hugo website. However, this script is not very convenient if I need to start writing a new blog post (the action that I do most often): I have to create an environment, then I must create new directory for a post, copy there a template and modify the parameters in the preamble (at least, I have to add the date and the title). Therefore, in order to facilitate this process I have developed a new script used to create an environment for writing new blog posts. In this article, I share this script and explain how it works so that you can adapt my experience in your setup.

Without long introductions, let the code speak:

#!/bin/bash

SITE_ROOT='/home/yury/PROJECTS/PERSONAL/zyrikby_webpage/website/'

# check if the session called exactly 'website' exist
if ! tmux has-session -t=website; then
  # if it does not exist
  # create a new session (new -s) called 'website' detached (-d flag)
  tmux new -s website -d

  # split the 0th pane in the 0th window of the 'website' vertically
  tmux split-window -v -t website:1.1 -p 70

  # get current year
  year=$(date +'%Y')
  # make all letters lowercase and substitute all spaces with dash in the post title
  title=$(echo "$1" | tr '[:upper:]' '[:lower:]' | tr -s ' ' '-')

  # change directory to the site root 
  tmux send-keys -t website:1.1 "cd $SITE_ROOT" C-m
  # create new post in the directory post/$year/$title
  tmux send-keys -t website:1.1 "hugo new -k post \"post/$year/$title\"" C-m
  # launch VSCode with the post/$year/$title directory as a root
  tmux send-keys -t website:1.1 "code \"content/post/$year/$title\"" C-m
  
  # launch hugo local server
  tmux send-keys -t website:1.2 "cd $SITE_ROOT" C-m
  tmux send-keys -t website:1.2 'hugo serve -e production -D -F' C-m
fi

tmux a -t=website

So, what happens here? Similarly to the script the previous article, here I create a new tmux session called website if it is not created yet; otherwise, I attach to it.

In this new tmux session, I split the window horizontally into two panes. In the upper pane, I run three commands:

  1. At first, I change the working directory to the site root.
  2. Then using the hugo new command, I create a new blog post using post archetype. This blog post is created in the directory: post/$year/$title, where the $year variable stores current year (so as I split my blog posts by the year), while the title variable contains the name of the blog post directory. The value stored in this variable is obtained by taking the first argument value and transforming it according to the following rules: all letters are lowercased and all consecutive whitespaces are substituted with a dash.
  3. Finally, I run VSCode taking this new directory as a root.

In the lower tmux pane, I run local hugo server that watches for changes in the directory and renders the website.

Put this script into the PATH directory (I put it into the ~/bin folder) and make it executable. Now, you can create an environment for a new blog post with the following command:

$ new_post.sh "Hello World"

Someone may ask why I spend time on adapting almost similar script shown in the previous article? The answer is simple: I would like to track the amount of time I spend on writing a blog post in order to reduce this time by improving my writing skills. This may surprise someone but writing a technical article takes quite a lot of time. For instance, I spend more than 2 hours working on this short blog post.

To track the amount of time I spend on a project, I use wakatime and its plugin for VSCode. However, by default wakatime recognizes as a project the directory where git project is activated. In my case, the root directory of my website is put under git, therefore, I cannot track time for every post separately. However, wakatime has a feature that allows to transform any directory into a wakatime project by putting there a file called .wakatime-project which first line specifies the name of the project. I use this functionality in a modified version of the script:

#!/bin/bash

SITE_ROOT='/home/yury/PROJECTS/PERSONAL/zyrikby_webpage/website/'

# check if the session called exactly 'website' exist
if ! tmux has-session -t=website; then
  # if it does not exist
  # create a new session (new -s) called 'website' detached (-d flag)
  tmux new -s website -d

  # split the 0th pane in the 0th window of the 'website' vertically
  tmux split-window -v -t website:1.1 -p 70

  # get current year
  year=$(date +'%Y')
  # make all letters lowercase and substitute all spaces with dash in the post title
  title=$(echo "$1" | tr '[:upper:]' '[:lower:]' | tr -s ' ' '-')

  # change directory to the site root 
  tmux send-keys -t website:1.1 "cd $SITE_ROOT" C-m
  # create new post in the directory post/$year/$title
  tmux send-keys -t website:1.1 "hugo new -k post \"post/$year/$title\"" C-m
  # create a .wakatime-project file and put there a line with the project name
  tmux send-keys -t website:1.1 "echo \"BLOG|$year|$title\" > \"content/post/$year/$title/.wakatime-project\"" C-m
  # launch VSCode with the post/$year/$title directory as a root
  tmux send-keys -t website:1.1 "code \"content/post/$year/$title\"" C-m
  
  # launch hugo local server
  tmux send-keys -t website:1.2 "cd $SITE_ROOT" C-m
  tmux send-keys -t website:1.2 'hugo serve -e production -D -F' C-m
fi

tmux a -t=website

I have also added .wakatime-project to .gitignore so that they do not appear under the version control. Indeed, once a blog post is written there is no need in having this file in the directory.

That’s all - today’s post is very short! I hope that it may give you some hints how to automate your everyday activities. Thank you for reading!

Yury Zhauniarovich
Yury Zhauniarovich
Assistant Professor

Related