Adding tags for indexing webpages with Jekyll
		
		10 Apr 2019 - tsp 
 Last update 14 Jan 2021 
 
  2 mins  
		
	 
    
		The following is a description on how to add tags (as an index method) to your
statically generated Jekyll page.
Note that this only works if you can guarantee there are no special characters in your
tag names. Because of this - this is just a hackish way to solve the tagging problem. It also
doesnโt scale that way. If you have a really large project or a project where you
cannot trust your input data - you should use a different method.
The basid idea is to add a list of tags to the YAML frontmatter:
A small shellscript iterates over all markdown files in your project
structure excluding the tags directory and generates a list
of all articles for each tag it encounters - and an tag index as well.
These generated lists are markdown documents themselves and get
translated by Jekyll during the build run.
#!/bin/sh
if [ $# -eq 0 ]; then
        # First clean up
        rm -rf tags
        mkdir -p ./tags
        # Build index
        find ./ -name "*.md" -exec ./mktags.sh {} \; -path ./tags -prune
else
	# Index a given file
        echo "Indexing ${1}"
        CUTSTATE=0
        cat ${1} | while read -r LINE; do
                if [ ${CUTSTATE} -eq 0 ]; then
                        if echo "${LINE}" | grep -q 'title:'; then
                                CURTITLE=`echo "${LINE}" | sed 's#title:##g'`
                        fi
                        if [ "${LINE}" = "tags:" ]; then
                                CUTSTATE=1
                        fi
                elif [ ${CUTSTATE} -eq 1 ]; then
                        if [ "${LINE}" = "---" ]; then
                                CUTSTATE=2
                        else
                                TAGNAME=`echo ${LINE} | tr -d '-'`
                                TAGFNAME=`echo ${TAGNAME} | tr -d ' ' | tr '[:upper:]' '[:lower:]'`
                                if [ ! -e ./tags/${TAGFNAME}.md ]; then
                                        # Create tag file
                                        echo "---" > ./tags/${TAGFNAME}.md
                                        echo "layout: tagspage" >> ./tags/${TAGFNAME}.md
                                        echo "title: Tag ${TAGNAME}" >> ./tags/${TAGFNAME}.md
                                        echo "description: All articles and posts tagged with ${TAGNAME}" >> ./tags/${TAGFNAME}.md
                                        echo "tagname: ${TAGNAME}"  >> ./tags/${TAGFNAME}.md
                                        echo "---" >> ./tags/${TAGFNAME}.md
                                        #echo "${TAGNAME}" > ./tags/${TAGFNAME}.md
                                        if [ ! -e ./tags/index.md ]; then
                                                echo "---" > ./tags/index.md
                                                echo "layout: tagspage" >> ./tags/index.md
                                                echo "title: List of all known tags" >> ./tags/index.md
                                                echo "description: A list of all known tags on the page" >> ./tags/index.md
                                                echo "---" >> ./tags/index.md
                                        fi
                                        echo "* [${TAGNAME}](/tags/${TAGFNAME}.html)" >> ./tags/index.md
                                fi
                                if echo "${1}" | grep -q '_posts'; then
                                        TAGLINK=`echo ${1} | sed 's#./_posts/#/#g' | tr '-' '/' | sed 's#.md#.html#g'`
                                else
                                        TAGLINK=`echo ${1} | sed 's#./#/#g' | sed 's#.md#.html#g'`
                                fi
                                echo "* [${CURTITLE}](${TAGLINK})" >> ./tags/${TAGFNAME}.md
                        fi
                fi
        done
        return 1
fi
 
This script uses a single layout file _layouts/tagspage.html. This layouts file
may look like the following script (this is the one used on this page at the time of
writing this note):
---
layout: default
---
<div class="articleheader">
	{% if page.tagname %}
	<h1>All articles and pages tagged <em>{{page.tagname}}</em></h1>
	{% else %}
	<h1> All known tags </h1>
	{% endif %}
</div>
{{content }}
 
		
		 This article is tagged: