Open kgilmer opened 4 years ago
I use this bash script:
#!/bin/bash
set -eu
Trap_Exit()
{
######################################################################################################################
# EXECUTION
######################################################################################################################
local exit_code=$?
Undo_Git_Changes
exit ${exit_code}
}
Undo_Git_Changes()
{
######################################################################################################################
# EXECUTION
######################################################################################################################
{
cd "${script_dir}/${docs_theme_path}"
Undo_Work_In_Progress_Commit "${TEMPLATE_BRANCH}"
git branch -D "${build_branch}"
cd "${script_dir}"
Undo_Work_In_Progress_Commit "${CONTENT_BRANCH}"
git branch -D "${build_branch}"
} &> /dev/null
}
Undo_Work_In_Progress_Commit()
{
######################################################################################################################
# INPUT
######################################################################################################################
local branch="${1? Missing branch to undo.}"
######################################################################################################################
# EXECUTION
######################################################################################################################
git checkout "${branch}" || true
git log -n 1 | grep -q -c "\-\-tempwip\-\-" && git reset HEAD~1
return 0
}
Create_Work_In_Progress_Commit()
{
######################################################################################################################
# EXECUTION
######################################################################################################################
# creating a WIP commit
git add -A
git commit --no-verify --no-gpg-sign -m "--tempwip--" || true
git checkout -b "${build_branch}" || true
}
Inject_Docs_Versions_Drop_Down_Menu_Into_Theme()
{
######################################################################################################################
# VARS
######################################################################################################################
local layouts_partials_dir="${version_dir}/layouts/partials"
local versions_drop_down_menu_partial_file="${layouts_partials_dir}/auto-generated-versions-drop-down.html"
local footer_js_file_path="${layouts_partials_dir}/footer-js.html"
######################################################################################################################
# EXECUTION
######################################################################################################################
mkdir -pv "${layouts_partials_dir}"
while read -r doc_version; do
if [ -z "${doc_version}" ]; then
continue
fi
# We will not include the current version in the drop down
if [ "${doc_version}" = "${version}" ]; then
continue
fi
local drop_down_versions="${drop_down_versions}<a href=\"{{ \"../${doc_version}\" | relURL }}\">${doc_version}</a>\n"
done <<< "${versions}"
### INJECT RELEASE VERSIONS ###
printf "<div id=\"latest-version\">(<strong>Latest: </strong><span>${latest_version}</span>)</div>" > "${versions_drop_down_menu_partial_file}"
printf "<button class=\"dropbtn\">${version}</button>" >> "${versions_drop_down_menu_partial_file}"
printf "<div class=\"dropdown-content\">${drop_down_versions}</div>" >> "${versions_drop_down_menu_partial_file}"
}
Main()
{
######################################################################################################################
# DEFAULTS
######################################################################################################################
local script_dir="${PWD}"
local build_dir=build
local local_build=false
local dir_prefix="${PWD}"
if [ -f .bash.vars ]; then
. .bash.vars
elif [ -f .bash.vars.example ]; then
cp .bash.vars.example .bash.vars
. .bash.vars
else
printf "Missing ${PWD}/.bash.vars file with CONTENT_REPO_GIT_URL and TEMPLATE_REPO_GIT_URL"
echo
exit 1
fi
######################################################################################################################
# INPUT
######################################################################################################################
for input in "${@}"; do
case "${input}" in
--hfd | --hugo-from-docker )
shift 1
local dir_prefix="${1:-/home/developer/workspace}"
if [ $# -gt 1 ]; then
shift 1
fi
;;
--lb | --local-build )
local local_build=true
shift 1
;;
esac
done
######################################################################################################################
# VARS
######################################################################################################################
#local base_dir="${PWD}"
local docs_theme_name=template-web
local docs_theme_path="themes/${docs_theme_name}"
local versions_dir="${build_dir}/versions"
local releases_docs_home_dir="${build_dir}"/release/docs
local site_dir="${build_dir}/site"
local site_content_dir="${site_dir}/content"
local site_theme_dir="${site_content_dir}/themes"
local drop_down_versions=''
local date_time=$(date +"%Y-%m-%d_%Hh%Mm")
local build_branch="docs-build_${date_time}"
trap "Trap_Exit" EXIT
######################################################################################################################
# EXECUTION
######################################################################################################################
rm -rf "./${build_dir}"
mkdir -p "${site_dir}" "${site_content_dir}" "${versions_dir}" "${releases_docs_home_dir}"
if [ "${local_build}" = "true" ]; then
local tar_file_prefix="local"
### MANAGING CHANGES NOT COMMITTED IN OUR LOCAL REPOS ####
# changes in the theme
cd "${docs_theme_path}"
local TEMPLATE_BRANCH="$(git rev-parse --abbrev-ref HEAD )"
Create_Work_In_Progress_Commit
cd -
# changes in content
local CONTENT_BRANCH="$(git rev-parse --abbrev-ref HEAD )"
Create_Work_In_Progress_Commit
### CONTENT ###
cd "${site_content_dir}"
git clone --no-hardlinks --local ../../../ .
### THEME ###
cd "${docs_theme_path}"
git clone --no-hardlinks --local "../../../../../themes/${docs_theme_name}" .
cd -
### TAGGING ###
# Creating a development version to show up in the versions drop down menu
git tag v_dev
cd ../../../
else
### CONTENT ###
git clone "${CONTENT_REPO_GIT_URL}" "${site_content_dir}"
### THEME ###
git clone --depth 1 "${TEMPLATE_REPO_GIT_URL}" "${site_theme_dir}/${docs_theme_name}"
local tar_file_prefix="prod"
fi
### LATEST VERSION ####
cd "${site_content_dir}"
# The `v*` match tags to be published to the docs website, because tags not prefixed with `v` are only for internal
# reference.
# The `--sort` option uses a `-` in `-v:refname` to sort in descendant order
local versions=$(git tag --list 'v*' --sort -v:refname)
local latest_version=$(git tag --list 'v*' --sort -v:refname | head -1)
cd -
local tar_file="${build_dir}/${tar_file_prefix}-release_${latest_version}_${date_time}.tar.gz"
### BUILD RELEASES FOR ALL APPROOV VERSIONS ###
if [ -n "${versions}" ]; then
while read -r version; do
if [ -z "${version}" ]; then
continue
fi
### MAKE A LOCAL CLONE OF THE SITE CONTENT FOR A SPECIFIC DOCS VERSION ###
local version_dir="${versions_dir}/${version}"
local release_dir="${releases_docs_home_dir}/${version}"
rm -rf "${version_dir}"
git clone \
--no-hardlinks \
--local "${site_content_dir}" \
--branch "${version}" \
"${version_dir}"
# Set the correct base url in the config.toml ensures that the relative
# links are properly generated by Hugo, like in the index.json file
# used indexing the content for search.
sed -i "s|baseURL = \"/\"|baseURL = \"/docs/${version}/\"|g" "${version_dir}/config.toml"
Inject_Docs_Versions_Drop_Down_Menu_Into_Theme
### BUID RELEASE ####
hugo \
--ignoreCache \
--source "${dir_prefix}/${version_dir}" \
--destination "${dir_prefix}/${release_dir}" \
--themesDir "${dir_prefix}/${site_theme_dir}" \
--theme "${docs_theme_name}"
# Fix fonts folder location:
# @TODO Maybe hugo configuration can be set to avoid this?
mv "${release_dir}/fonts" "${release_dir}/assets"
done <<< "${versions}"
#### DOCS HOMEPAGE ###
# Creates index.html for domain.tld/docs and fix all links to point to the
# latest version, like domain.tls/docs/v2.0/some-page
cp "${releases_docs_home_dir}/${latest_version}/index.html" "${releases_docs_home_dir}"
sed -i "s|=\"./|=\"./${latest_version}/|g" "${releases_docs_home_dir}/index.html"
cp "${releases_docs_home_dir}/${latest_version}/sitemap.xml" "${releases_docs_home_dir}"
sed -i "s|<loc>/|<loc>/${latest_version}/|g" "${releases_docs_home_dir}/sitemap.xml"
# Add the search index.json file to the root of the project, but it's not
# needed to do the sed replace on this file, because the config.toml has
# now the correct relative path for the baseurl of each doc version site.
# See above sed replace in the foreach for creating each doc version.
cp "${releases_docs_home_dir}/${latest_version}/index.json" "${releases_docs_home_dir}"
### CREATING THE RELEASE TAR FILE ###
tar zcf "${tar_file}" -C "${releases_docs_home_dir}/.." .
printf "\n\nRELEASES: \n"
printf "\n -> Compressed: ${tar_file}"
printf "\n -> Uncompressed: ${releases_docs_home_dir}\n\n"
fi
Undo_Git_Changes
trap - EXIT
}
Main "${@}"
The bash script is tailored to deploy the docs site with all the versions into the docs
path of a site, like example.com/docs.
So just save the script in the root of your content repo build-release.sh
, and then invoke:
./build-release.sh --local-build
output:
RELEASES:
-> Compressed: build/local-release_v_dev_2020-05-15_18h06m.tar.gz
-> Uncompressed: build/release/docs
./build-release
The output:
RELEASES:
-> Compressed: build/prod-release_v2.3_2020-05-15_18h16m.tar.gz
-> Uncompressed: build/release/docs
The content and template are in separated repos on purpose, and the content repo never overrides nay file in the template on purpose too, because this way when fixing a bug in the the template we can deploy the fix to all versions of the docs, same if you decide to upgrade the template with a brand new look.
The drop down html generated by the script into the file auto-generated-versions-drop-down.html
will look like:
<div id="latest-version">(<strong>Latest: </strong><span>v2.3</span>)</div>
<button class="dropbtn">v2.3</button>
<div class="dropdown-content">
<a href="{{ .RelPermalink }}">v2.2</a>
<a href="{{ .RelPermalink }}">v2.1</a>
<a href="{{ .RelPermalink }}">v2.0</a>
</div>
Now in your template menu.html
you need to add:
<div class="dropdown">
{{ partial "auto-generated-versions-drop-down.html" . }}
</div>
My css looks like this:
/* The container <div> - needed to position the dropdown content */
#sidebar .dropdown {
position: relative;
display: block;
text-align: center;
margin:0.5rem auto 1rem auto;
padding: 0;
width: 8rem;
text-align: center;
}
#sidebar .dropdown #latest-version {
position: relative;
display: block;
color: var(--MENU-SECTIONS-LINK-color);
margin: auto;
}
/* Style The Dropdown Button */
#sidebar .dropdown button {
background-color: var(--MENU-HEADER-BG-color);
color: var(--MENU-SECTIONS-LINK-color);
font-size: 1.2rem;
margin: 0;
padding: 0.5rem;
width: 100%;
border: none;
cursor: pointer;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
/* Dropdown Content (Hidden by Default) */
#sidebar .dropdown-content {
position: absolute;
display: none;
background-color: #f9f9f9;
width: 100%;
padding: 0.5rem;
z-index: 1;
}
/* Links inside the dropdown */
#sidebar .dropdown-content a {
color: #666666;
padding: 0.5rem;
text-decoration: none;
display: block;
}
/* Change color of dropdown links on hover */
#sidebar .dropdown-content a:hover {
background-color: var(--MENU-HEADER-BORDER-color);
color: var(--MENU-SECTIONS-LINK-color);
}
/* Show the dropdown menu on hover */
#sidebar .dropdown:hover .dropdown-content {
display: block;
}
/* Change the background color of the dropdown button when the dropdown content is shown */
#sidebar .dropdown:hover .dropbtn {
background-color: var(--MENU-HEADER-BORDER-color);
}
In the end it looks like this:
Grav, the project that Hugo Learn is based on, has a feature in which documentation can be versioned, and there is a dropdown for the user to specify which version of the documentation to be used. Is there a way of enabling something like this in Hugo Learn?