Documenting: LibreOffice Writer Template Changing

Internally, LibreOffice Writer has been used for technical documentation for many years:

  • Writer is very strong in combination with style sheets and
  • SVG format is perfectly supported. Vector-based images can therefore be inserted very well.

When you work with large documents, there are two annoying peculiarities you should be aware of.

  • The first is that the program stops organizing pages when the document becomes large. This can be overcome in an ugly way. Just add more trees, by always embedding images as a character. It concerns this bug. If you deal with this the right way, then Writer has no problem with documents containing hundreds of pages.
  • The other one is that it is not possible to link templates to documents. This sounds a bit crazy and yes, it may be considered to be a bug.

An extension “Template Changer” was available for linking template files. However, it does not work with new versions. That is why we created a BASH script as a tool to solve this. It has been tested on Linux but should also work with Cygwin on Windows. OS-X should work with minor changes, like the date function in Unix does not require an @ sign.

The underlying idea is that you have documentation projects where both the documents and the templates are in the same directory. If that is the case with you, then this script can help you.

You can paste the following to a text file called “”, give it executable rights, put it in your documentation directory,  and start attaching templates to your documents.

Hope you like it!

Update 2018-11-19: Now both ODT and ODM files are supported.


# Template CHanger alternative
# This script uses xmlstarlet, zip and unzip.
echo ./, CHange Template...
echo This script inserts or replaces, a template XML node in a 
echo LibreOffice Writer file, by modifying meta.xml and adding an
echo absolute url for template location. It accepts both
echo document and master document files and template files.
echo xmlstarlet is expected to be installed.
echo This is for documentation projects where Writer files and Templates
echo reside in the same directory!
echo USE AT YOUR OWN RISK, HAVE A BACK-UP READY, wiebe-nedcad-nl
echo Run script always in directory with documents, cd your_project
echo "Usage: cht  "
echo Example: ./ writer.odt

## Variables I, more below Checks

# General

## Checks

# Do files exist with right extension?

if [ -f $TEMPL ] && [ "${TEMPL: -4}" == ".ott" ]; then
   echo "File $TEMPL found."
   echo "ERROR: Writer template $TEMPL does not exist or is not valid. Aborting."
   exit 1

if [ -f $DOC ] && ([ "${DOC: -4}" == ".odt" ] || [ "${DOC: -4}" == ".odm" ]); then
   echo "File $DOC found."
   echo "ERROR: Writer document $DOC does not exist or is not valid. Aborting."
   exit 1

# Do we have xmlstarlet?

hash xmlstarlet 2>/dev/null || { echo >&2 "ERROR: xmlstarlet is required. Please install this first. Aborting."; exit 1; }

## Variables II

# XML node "meta:template" values
echo Node meta:template will contain the following bare attributes:
# xlink:type xlink:actuate xlink:title xlink:href meta:date

# Static
N_XLINK_TYPE="xlink:type" && V_XLINK_TYPE="simple"

# Static
N_XLINK_ACTUATE="xlink:actuate" && V_XLINK_ACTUATE="onRequest"

# Template name

# Absolute template location

# Template time
# Lower epoch time sec to force updating document styles
BELLE_EPOCH_X=$(stat -c %Y $TEMPL)
V_META_DATE=$(date -d @$BELLE_EPOCH +%Y-%m-%dT%T.%9N)

## The proces

# Unzip the document file

mkdir -p $WORKDIR
if [ -z "$(ls -A ./$WORKDIR)" ]; then
   echo "Ready for processing meta.xml"
   echo "ERROR: ./$WORKDIR is not empty and may contain an unzipped document file. Aborting."
   exit 1
unzip -q $DOC -d $WORKDIR

# If exists, delete node meta:template, add node and subnodes via pipes
xmlstarlet ed -d "/office:document-meta/office:meta/meta:template" meta.xml | \
xmlstarlet ed -s  "/office:document-meta/office:meta" -t elem -n meta:template | \
xmlstarlet ed -i  "/office:document-meta/office:meta/meta:template" -t attr -n $N_XLINK_TYPE -v $V_XLINK_TYPE | \
xmlstarlet ed -i  "/office:document-meta/office:meta/meta:template" -t attr -n $N_XLINK_ACTUATE -v $V_XLINK_ACTUATE | \
xmlstarlet ed -i  "/office:document-meta/office:meta/meta:template" -t attr -n $N_XLINK_TITLE -v $V_XLINK_TITLE | \
xmlstarlet ed -i  "/office:document-meta/office:meta/meta:template" -t attr -n $N_XLINK_HREF -v $V_XLINK_HREF | \
xmlstarlet ed -i  "/office:document-meta/office:meta/meta:template" -t attr -n $N_META_DATE -v $V_META_DATE \
> temp.xml && mv temp.xml meta.xml

# What is the result?
echo meta.xml is now: && echo
cat meta.xml && echo

# Back-up original file
mv ../$DOC "../${DOC%.*}.bak"
echo A .bak file is created && echo

# Create modified Writer file, mimetype first
zip -rq ../$DOC mimetype .

# Cleaning up
cd ..
rm -rf $WORKDIR
echo Finished && echo

Leave a Reply

Your email address will not be published. Required fields are marked *