Hi all,
Has anyone come up with a way to auto-generate the file name based on the title provided for a new post from the command line.
Currently this works:
hugo new posts/my_new_post.md
Then I type the title in the file as My New Post.
Normally I would already have the title in my mind and I do not care what the file name is.
Has someone set an alias or bash function (letβs say hugo_
) that on doing,
hugo_ My New Post
auto-creates the posts/my_new_post.md
and sets the title in post front-matter to My New Post?
I have come up with this wrapper bash script:
Can something like this be integrated in the hugo binary itself?
#!/usr/bin/env bash
# Time-stamp: <2016-11-28 16:31:04 kmodi>
# https://discuss.gohugo.io/t/auto-generate-file-name-based-on-title/4648/2?u=kaushalmodi
h="
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β Script : hugo_new_post.sh β
β Description : Script to generate a hugo post file using the title specified β
β at the command line. β
β Usage Example : hugo_new_post.sh -b \"/home/$USER/hugo/myblog\" -t \"My New Post\" β
β β
β β
β OPTIONS β
β β
β -b|--blogpath <path> : Root of hugo blog. (Mandatory argument) β
β --blogpath \"/home/\$USER/hugo/myblog\" β
β β
β -t|--title <string> : Title string of the post. (Mandatory argument) β
| Use double quotes if the title contains spaces. β
β --title \"My New Post\" β
β β
β -s|--section <dir> : Sub-directory in the 'content/' dir where the post β
β should be created. (Default: posts) β
β --section \"blog\" β
β β
β β
β -h|--help : Show this help β
β -d|--debug : Debug mode β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
blog_path=""
section="posts"
title=""
extra_args=""
here=$(pwd)
fext=".md"
debug=0
help=0
while [ $# -gt 0 ]
do
case "$1" in
"-b"|"--blogpath" ) shift
blog_path="$1";;
"-t"|"--title" ) shift
title="$1";;
"-s"|"--section" ) shift
section="$1";;
"-d"|"--debug" ) debug=1;;
"-h"|"--help" ) help=1;;
* ) extra_args="${extra_args} $1";;
esac
shift # expose next argument
done
if [[ ${debug} -eq 1 ]]
then
echo "blog path = ${blog_path}"
echo "title = ${title}"
echo "sub dir = ${section}"
echo "extra args = ${extra_args}"
fi
main () {
# Remove leading and trailing whitespace from ${title}
title=$(echo "${title}" | \sed -r -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
# Using ${title}
# - Replace '&' with "and", and '.' with "dot".
# - Then lower-case the whole title.
# - Then replace all characters except a-z, 0-9 and '-' with spaces.
# - Then remove leading/trailing spaces if any.
# - Then replace one or more spaces with a single hyphen.
# For example, converts "This, That \& Other!" to "this-that-and-other.md"
# (Note that we need to escape & with \ above, in the shell.)
fname=$(echo "${title}" \
| \sed -r -e 's/&/ and /g' \
-e 's/\./ dot /g' \
-e 's/./\L\0/g' \
-e 's/[^a-z0-9-]/ /g' \
-e 's/^[[:space:]]*//g' \
-e 's/[[:space:]]*$//g' \
-e 's/[[:space:]]+/-/g');
fpath="${blog_path}/content/${section}/${fname}${fext}"
if [[ ${debug} -eq 1 ]]
then
echo "fname = ${fname}"
echo "fpath = ${fpath}"
fi
# Create the new post
# Need to first cd to the hugo blog root dir
cd ${blog_path}
hugo new ${section}/${fname}${fext} ${extra_args}
# Replace the title in TOML front matter with ${title}, and add slug
tmp_file="/tmp/${USER}_hugo_post"
\cp -f ${fpath} ${tmp_file}
\sed -r -e 's/^(\s*title = ).*/\1"'"${title}"'"/' \
-e 's/^(\s*title = .*)/\1\nslug = "'"${fname}"'"/' \
${tmp_file} > ${fpath}
\rm -f ${tmp_file}
# Go back to the directory from where you launched this script
cd ${here}
# Open the file in EDITOR with cursor placed on the last line
last_line=$(wc -l ${fpath} | awk '{ print $1 }')
open_file_cmd="${EDITOR} +${last_line} ${fpath} &"
if [[ ${debug} -eq 1 ]]
then
echo "last line = ${last_line}"
echo "open file cmd = ${open_file_cmd}"
fi
eval "${open_file_cmd}"
}
help () {
echo "${h}"
}
if [[ ${help} -eq 1 ]]
then
help
exit 0
elif [[ -z ${blog_path} || -z ${title} ]]
then
echo "Error: Both '-b' and '-t' are mandatory arguments"
help
exit 1
else
main
exit 0
fi
UPDATE 2016/11/27: Replaced _
with -
in the tr
command.
UPDATE 2016/11/28: More improvements to the title->fname derivation. Also add slug to front-matter that matches the fname.
Hi. Have you tried dashes instead of underscores? I run
$ hugo new post/testing-me.md
SITE_ROOT/content/post/testing-me.md created
That file contains
+++
date = "2016-11-27T16:57:06-06:00"
title = "testing me"
+++
I just opened an issue to implement something like this.
https://github.com/spf13/hugo/issues/2743
Thanks. Actually I used underscores by mistake. Since then, I had switched to using hyphens instead. But the issue still remains.
- I would like the file names to be all lower case and the casing in title to be exactly as i want⦠example: Now I Know My ABCs
So by me specifying the title at the command line, itβs very easy to lower-case and hyphen-separate everything.
In addition, the script adds minor convenience like,
- Execution from anywhere (not needing to be in the hugo project root dir)
- Now having to specify the
posts/
subdir each time
- Opening in my $EDITOR on the last line
On top of that, I have an alias newp
. So I can type this from anywhere:
newp My New Post
and that creates posts/my-new-post.md
with title My New Post
, and opens the file with cursor at the last line in my $EDITOR
.
Having the βnew postβ utility automatically fill out the title is nice, but Iβd also like to see hugo simply fall back on inferring a title from the filename if none was provided. This would facilitate import / migration from Jekyll, and would allow users to exploit this content-oriented approach to specifying the title even if they are creating a new post without using the βnew postβ utility function.
1 Like