Skip to main content

Radreise Dänemark

At first the plan was just: bike North. A friend called my attention to shelters in Denmark when I read his travelogue about his Transcimbrica/Hovedting ride. So why not ride one or two weeks through the landscape of our direct neighbours.


While planning the GPS tracks of the route I discovered an ancient transportation and trading route. It's called oxen or army way, Ochsenweg and Heerweg in German and Hærvejen in Danish, both being part of the trans-European Eurovelo 3 route

For the German section there are GPX files downloadable on the Ochsenweg website.

On the Hærvejen website the partial tracks are quite hidden. I decided to work with a shared tour on Komoot as template for my tour. It turned out that this probably wasn't the most fitting route for me.


I woke the small herd up from their after lunch nap and received their full attention when I pushed the bike along a field edge to find an exit to a road again after being led to an extremely muddy forest path by the navigation device. I apoligized extensively for any inconveniences.

There are partially two routes, one for bicycles and one for hikers. The track for hikers often leads along forest paths and byways that are sometimes difficult to ride by bike. I figured that track I used seemed to follow the hiking route when the Hærvejen bicycle and hiking route separated. After this realisation I strictly followed the road signs if track and sign were conflicting. Besides that the route often leads along gravel paths that makes you fear for your tires.


Gravel path

The tour started in Hamburg. That meant the first 200 bike kilometers had to be accomplished in Germany. Having left these behind I crossed the border near Flensburg, I rode through Velje, Jelling, Mønsted, Viborg und Aalborg to the Northern coast to Hirtshals. On my way back I passed through Aalborg again, then headed East to Århus, took the train to Copenhagen. From Copenhagen I rode again South to get to Gedser on Falser island to hop on the ferry to Rostock.


The bike tour

Arrival and Northern Germany

From Berlin to the Danish border it's roughly 450 km so I cheated with a train ticket. I only considered direct connections so I chose a train to Hamburg and planned an nice first touring day through the federal state of Schleswig-Holstein.

After crossing the Kiel canal in Rendsburg heavy rainfall set in. Instead of staying overnight at a campsite of Wild Schleswig-Holstein I checked in to a small hotel, had a dry night and start into the day.


If suddenly a container ship appears behind the bushes...

Signpostings and quality of bike routes I rode along were consistent and easily to follow for people unfamiliar with the area.


Flensburg harbour

Vertical through Denmark

My tour and most part of Hærvejen crosses Danmark just in the middle, from Syddanmark to Midtjylland and Nordjylland, through rural, agricultural regions and glacial stamped landscape, tiny settlements right to the beatutiful coast.


Signpostings are blue signs with numbers of national (in red) and regional bike routes. The signs are larger than in Germany but also installed at a lower height so be aware of not missing them due to vegetation.

After five days I arrive in Hirtshals, amazing feels, a beautiful coastline and wonderful sound of the sea.



The Danish Nature Agency provides hundreds of mostly free overnight places in state owned areas. Among these places there are the shelters - simple, small, closed to three sides wooden huts. The places are often a bit hard to find and it's best to use the associated app or the official map.

Some shelters are bookable and/or cost a small fee (approx. 30 DKK = 4 € per person/night). One also has to consider varying facilities towards toilets/drinking water.

For German tourists (and probably people from other regions, too) it may appear strange but these places are absolutely clean. No graffitis, no vandalism, no littering and the commonly accepted code of practise is leave the place in the state it was when you arrived. Simple principle, easy to realize, don't be a jerk.

/images/RadreiseDK/26.thumbnail.jpg /images/RadreiseDK/04.thumbnail.jpg

Shelter are often log cabins, some with roof vegetation.

/images/RadreiseDK/37.thumbnail.jpg /images/RadreiseDK/23.thumbnail.jpg

Shelters in a forest

Large shelter

Doing tourist stuff

The initial plan included the idea of riding as fast as possible to Hirtshals and spend some time in Norway if the weather is alright. Admittedly I would have to roughly double my planned daily road stint to have a time buffer big enough for a safe return journey.

It quickly became clear that this plan wasn't practicable, well not that way that it wouldn't make me nervous about make it back in time and I'm on vacation not at a race. I usually cycled a bit above the plan of doing 100 km/day, saved time and money for ferry transits and decided to enjoy and vivit more of Denmark.

Somebody gave me a hint that the nearby UNESCO world heritage Jelling monuments are worth a visit. After studying tourism pamphlets during breakfast at a motel in Viborg)I also made a little detour to visit the world's largest limestone min in Mønsted (the weather was meh anyway).

/images/RadreiseDK/13.thumbnail.jpg /images/RadreiseDK/15.thumbnail.jpg

The large rune stone, große Runenstein, the "birth certificate" of Denmark. In the interactive exhibition visitors can learn about Viking history, p.e. via animated drawings.

/images/RadreiseDK/18.thumbnail.jpg /images/RadreiseDK/19.thumbnail.jpg

Mønsted limestone mine

In Århus/Aarhus I visited the art museum ARoS. Even if the admission fee of 160 DKK/22 € may seem much, it it worth every Øre/Cent - this is an absolute reccomendation from my side, expect to spend some hours. To be honest, the most fascinating installations were Berl-Berl by Jakob Kudsk Steensen and Storm Room

/images/RadreiseDK/27.thumbnail.jpg /images/RadreiseDK/33.thumbnail.jpg

Aarhus Cathedral

Rainbow Walk on top of ARoS is visible from afar.

/images/RadreiseDK/31.thumbnail.jpg /images/RadreiseDK/34.thumbnail.jpg

The end of the American dream?

Berl-Berl attracts the audience

Train to Sjælland

In order to reach the Eastern part of the country and its Southern islands I chose going by train again departing in Århus. This way I stress-free arrived in Copenhagen. I wasn't really intrigued to discover the city. With my heavily packed bike I would have needed an accomodation for the day/night to visit some places here and there and I just postponed that to another unspecific time in the future.

Nevertheless I cycled around the city, stopped for an extensive break by the water, to famous Christiania Freetown that just looks like Berlin Kreuzberg and to get an impression of the internationally much vaunted bicycle infrastructure. My experience is that the Danish bike infrastructure is implemented nationwide consistently regardless of city, small towns or overland roads.



1.000 kilometers

The journey wasn't planned in detail and still I was well prepared. That's not a contradiction, I had backup plans in case of bad weather or breakdowns for example. Initially I didn't plan to return via Gedser but there I was, no big deal.

Staying overnight in shelters is a great opportunity for outdoor and nature lovers to set camp along or near bike routes for free and effortless.

I had eleven amazing days of bike vacation in a beautiful country full of open-minded, great people.


Bye Danmark. Vi sees.

Comment on the fediverse

Migrate from Evernote to Joplin

On my journey to move away from closed services I was looking for a note taking application, an Evernote replacement to be specific and stumbled across Joplin. Even though not using Evernote very frequently anymore I wanted to preserve my notebooks, some of them being well-maintained collections of particular topics.


Advantages of choosing Joplin:

  • synchronisation capabilities (Nextcloud yay!)

  • import Evernote notebooks

  • desktop and mobile applications

  • write notes in Markdown (various plugins available, see Joplin's Markdown Guide)

This all sounded really good so I planned my further steps:

  1. install the desktop and mobile app

  2. export Evernote content

  3. set up Nextcloud sync

  4. import Evernote content

  5. evaluate results

  6. use Joplin

  7. delete Evernote account

With Joplin one can create, write and manage extensive collections of any topic. This is just one among many options, see also 12 Best Open Source Evernote Alternatives 2022.

The headache of exporting Evernote content

Getting notebooks out of Evernote became a bit tricky because one cannot just export them in the web browser interface or mobile app. The export function is exclusively available on one of the desktop applications. You can easily install the application on Windows and MacOS but this is a static blog so of course I am using Linux...

There is however the straw of a repackaged Evernote client for Windows available for Linux which is not open source:

Unfortunately you still have to export your notebooks one after the other.

Nextcloud WebDAV URL

If you follow the Nextcloud synchronisation instructions, you must input the WebDAV URL, not just the Nextcloud instance. This information is to be found in the Setting on the bottom left (see figure).


Aaaand we are done

The Joplin desktop client has a similar application structure. It lacks fancy widgets (pro or con, you decide) and has a cleaner look.


Switching from " install" to pip

When working on NoN I ran into the following message:

SetuptoolsDeprecationWarning: install is deprecated. Use build and pip and other standards-based tools

So I took a look at it, did a quick research and decided solving the problem should be doable for me.

Interesting/important links to start with:

What has ever done for us?

Among the obvious part, installing the application itself into the correct destination folder while also handling dependencies, one can specify plenty of additional files to be coped with like starter scripts, .desktop files, app icons, providing all kinds of the project's metadata.

If you are fierce enough or just don't know better you can write custom install/de-install/ruin the system routines - anything's possible.

For my personal use case the following tasks are required:

  1. install application files

  2. handle dependencies

  3. copy .desktop file

  4. copy starter script

  5. copy application icon

Converting to setup.cfg

You can however continue using with pip. setup.cfg is the TOML-formatted static configuration of the setuptools.setup function that is, according to the packaging tutorial, "simpler, easier to read, and avoids many common errors".

If you come from using $ python install like me you will already have a working script that can be easily transformed.


The first section of the file includes all the metadata so:

import info
with open(os.path.join(here, ""), encoding="utf-8") as f:
long_description = "\n" +



name = non
version = 0.81
description = Knights Of Ni - a GTK+ manager for your Nikola powered website
long_description = file:
long_description_content_type = text/markdown
license = MIT

For convenience and readability purposes I once put all the proper data into a separate info function so I didn't need to touch the install script which now has become dispensable.


The same applies for the remaining values that are listed in the options section.

All possible keywords/values are listed in the setuptools documentation. Some keys require a "section" data type that means these keys get their own subsection, p.e. "[options.data_files]".

So the old setup function

import info



packages = non
python_requires = >=3.6
install_requires =
include_package_data = True

share/applications =
share/icons/hicolor/scalable/apps =
bin =



After plagiarizing the pyproject.toml file from the packaging tutorial we are ready to build and hopefully will end up with an installable archive.

But first make sure to have a current build package builder installed:

$ python -m pip install --upgrade build

Then run build from the project's directory:

$ python -m build
* Creating virtualenv isolated environment...
* Installing packages in isolated environment... (setuptools>=42)
* Getting dependencies for sdist...
running egg_info
writing non.egg-info/PKG-INFO
writing dependency_links to non.egg-info/dependency_links.txt
writing requirements to non.egg-info/requires.txt
Successfully built non-0.81.tar.gz and non-0.81-py3-none-any.whl

Install the archive with pip:

$ pip install dist/non-0.81-py3-none-any.whl

Now it's time to check if everything is in its place and working.

Minor adjustments & tidying up the project

Start script

The installation path is determined by the Python version so the .desktop file points to the new start script that figures out the installation path instead of directly pointing to the application:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# execution file to put in /usr/bin

import os
import non


from non import application

None of the (custom) commands are needed anymore, the file is obsolete.

info file

All information have been merged into setup.cfg, the file is obsolete.

Pip now handles the installation and deinstallation process, edit installation section.

Final thoughts

Making my application pip install-ready was easier than expected with an even more compliant result than before. 10/10 would use pip again.

NoN: v0.8 release

The GTK GUI tool for managing Nikola powered websites Knights of Ni (NoN) just some polishing recently and I was shocked (shocked!) to see that the last release is two years old so I drafted a release from the current status.

A major change was the removal of the application-wide draft feature (Nikola's draft mode not affected). It was a rudimental implementation of an idea that I didn't know where to go with. I figured it would go to /dev/null eventually without regrets.

The application is still completely dependent on GTK3. Installation has been tested for Archlinux and Ubuntu.

The About dialog still proclaims it is version 0.7 but the dialog is lying, the version is 0.8. Trust me.

Sportplus trampoline fix


This article first appeared on Mastodon.

Somebody might remember me owning a fitness trampoline (a Sportplus SP-T-110) which I use on an almost daily basis.

So it was just a matter of time that the first rubber band snaps (I'm doing quite high jumps on my HIIT routine and from the product reviews that can and will happen regardless of workout intensity/weight).

In theory you can buy a replacement rubber band set and in practice it is not in stock atm.

So I bought regular bungee cord and clips and started to macgyver around.


I purchased the 8 mm bungee cord that turned out to be a bit too thick but still with the power of patience and a bit force the cord fit through the hole of the plastic mount.

The chosen length resulted in an educated guess based on the original cord and the lower elasticity of the new cord.


This is the result. I bought the green bungee cord on purpose, the replaced rubber bands are easy to spot.


This has been working for over two months now to my satisfaction with two replaced cords. I'm convinced I have to replace more original rubber bands with time. So be it.

Nikola: some new colour flavours for the Hybrid theme

The Hybrid theme for Nikola is a member of the Hyde theme family. You are able to set any subtheme it provides which are the main colours from the base16 project.

I'm not really a fan of these so I added some additional strong colours to the Hybrid theme that I use. My PR to the themes' repository was accepted so this is included in the theme when downloading from the application.

Now there are plenty of subthemes to choose from:

        # "hyde_subtheme": "theme-custom",
        # "hyde_subtheme": "theme-hybrid-01", # petrol
        # "hyde_subtheme": "theme-hybrid-02", # dark red
        # "hyde_subtheme": "theme-hybrid-03", # forest
        # "hyde_subtheme": "theme-hybrid-04", # eggplant
        # "hyde_subtheme": "theme-hybrid-05", # dark orange
        # "hyde_subtheme": "theme-base-08", # red
        # "hyde_subtheme": "theme-base-09", # orange
        # "hyde_subtheme": "theme-base-0a", # yellow
        # "hyde_subtheme": "theme-base-0b", # green
        # "hyde_subtheme": "theme-base-0c", # cyan
        # "hyde_subtheme": "theme-base-0d", # blue
        # "hyde_subtheme": "theme-base-0e", # magenta
        # "hyde_subtheme": "theme-base-0f", # brown
        # ...

Hyde colours

















Hybrid colours










Custom colour

The custom-theme has preset colours that you can directly change in the hybrid.css or better in your custom.css. Just create the file if you haven't already and add and adapt this snippet:

/* custom subtheme for hyde/hybrid theme */
.theme-custom .hsidebar {
  background-color: #070512;
.theme-custom .content a,
.theme-custom .related-posts li a:hover {
  color: #1582ae;


You can use your Mastodon account to reply to this post.


New online presence

There is a moving process going on from my GitHub Page: Merge and Destroy.

See you soon.

Update May 17th

I imported most of the posts and pages, images and listings and so on. I will probably leave the tutorials and some posts also over at the GitHub Page but will slim the page down.

The Google+ archive is now also hosted here.

Adding Mastodon comments to your static Nikola blog

Static and comments

The neverending story. The arch enemies. Beauty and the Beast. If you want to enable comments in a static blog article you will have to come back to third party services.

Nikola already supports several comment systems like Disqus or Isso. As a frequent Mastodon user it has long been my intent to integrate Mastodon threads as a detour comment system.

I stumbled across this JavaScript solution that does the job on any static page: Adding comments to your static blog with Mastodon.

The comments listed are the replies to the corresponding toot:

Potential and restrictions

Unlike embedded Mastodon toots the loaded comments fit neatly to the blog (some CSS theme adaptation required). Adding a comment is still done via the Mastodon web UI.

If you announce an article to Mastodon and want to refer to that toot as your comment thread you will have to either edit the page because you don't know the toot id in advance and therefore build and deploy your site a second time or be quick and announce the article before deploying and then edit the toot id.

A classic comment moderation is not possible though. I personally expect spam and inappropriate contents quite unlikly as you need a Mastodon account in the first place and instance admins are usually very accurate when it comes to enforce their instance rules. This might change with time but right now I don't see a substantial danger.

Preparing Nikola

The main question is "Where put the code?" and the answer is:


A shortcode provides a code snippet that you can call via

{{% name parameters %}}

just save the file in the shortcodes folder.

mastodon-comments.tmpl (Source)


    {{% mastodon-comments host=instance.domain username=username id=tootnr %}}


<div class="article-content">
  <p>You can use your Mastodon account to reply to this <a class="link" href="https://{{ host }}/@{{ username }}/{{ id }}">post</a>.</p>
  <p><a class="button" href="https://{{ host }}/interact/{{ id }}?type=reply">Reply</a></p>
  <p id="mastodon-comments-list"><button id="load-comment">Load comments</button></p>
  <noscript><p>You need JavaScript to view the comments.</p></noscript>
  <script src="/assets/js/purify.min.js"></script>
  <script type="text/javascript">
    function escapeHtml(unsafe) {
      return unsafe
           .replace(/&/g, "&amp;")
           .replace(/</g, "&lt;")
           .replace(/>/g, "&gt;")
           .replace(/"/g, "&quot;")
           .replace(/'/g, "&#039;");

    document.getElementById("load-comment").addEventListener("click", function() {
      document.getElementById("load-comment").innerHTML = "Loading";
      fetch('https://{{ host }}/api/v1/statuses/{{ id }}/context')
        .then(function(response) {
          return response.json();
        .then(function(data) {
          if(data['descendants'] &&
             Array.isArray(data['descendants']) &&
            data['descendants'].length > 0) {
              document.getElementById('mastodon-comments-list').innerHTML = "";
              data['descendants'].forEach(function(reply) {
                reply.account.display_name = escapeHtml(reply.account.display_name);
                reply.account.emojis.forEach(emoji => {
                  reply.account.display_name = reply.account.display_name.replace(`:${emoji.shortcode}:`,
                    `<img src="${escapeHtml(emoji.static_url)}" alt="Emoji ${emoji.shortcode}" height="20" width="20" />`);
                mastodonComment =
                  `<div class="mastodon-comment">
                     <div class="avatar">
                       <img src="${escapeHtml(reply.account.avatar_static)}" height=60 width=60 alt="">
                     <div class="comment">
                       <div class="author">
                         <a href="${reply.account.url}" rel="nofollow">
                           <span class="disabled">${escapeHtml(reply.account.acct)}</span>
                         <a class="date" href="${reply.uri}" rel="nofollow">
                           ${reply.created_at.substr(0, 10)}
                       <div class="mastodon-comment-content">${reply.content}</div>
                document.getElementById('mastodon-comments-list').appendChild(DOMPurify.sanitize(mastodonComment, {'RETURN_DOM_FRAGMENT': true}));
          } else {
            document.getElementById('mastodon-comments-list').innerHTML = "<p>Not comments found</p>";

The script uses DOMPurify so you have to put the purify.min.js file into the $THEME/assets/js/ folder.

There are some div classes used in the code and may require some adaptation to your theme. This should be done in the custom.css. I stole the CSS from Carl's site and this is what I use here:

custom.css (Source)

.mastodon-comment {
 background-color: azure;
 border-radius: 10px;
 padding: 5px;
 margin-bottom: 1rem;
 display: flex;
 font-size: 80%;
.mastodon-comment .content {
.mastodon-comment .avatar img {
.mastodon-comment .author {
.mastodon-comment .author .date {
.mastodon-comment .disabled {
.mastodon-comment-content p:first-child {

That's it.

Just add a shortcode to any article in your blog. You can even provide a regular comment system like Disqus parallely.


You can use your Mastodon account to reply to this post.


Websites that answer a single specific question

Hints are welcome. Comment here or over at Mastodon. In case of updates post gets republished.

BER - Berlin Brandenburg Airport

The first question touches a sore spot - Germany's most famous airport (BER). The construction project has been full of scandals involving mismanagement, patronage, bad planning, massive budget overrun and, of course, delay:

"Is the BER already open?" - though the answer is incorrect now


"Has the BER been finished yet?" with more sad details (German)


This is an easy one:

"Is it Friday?" (Danish)


The third site answers the question whether the avenue behind the Brandenburg Gate in Berlin is closed for traffic (which often is the case due to public events like marathon, turn of the year or national ceremonies):

"Is the 17th of June Street closed?" (German)


"Should I use threads?"


The container ship Ever Given grounded in the Suez Canal completely blocking any traffic:

"Is that ship still stuck?"

Mastodon: vitalize the timeline

Mastodon or the wider Fediverse are getting little boosts once in a while. New users often ask how to start and find interesting people here.

Let me try to help out.

(This article is getting updated occasionally...)



As a new user you usually start by registering an account on an existing instance. Start visiting your local timeline to see what your instance neighbours are posting.


The universal timeline differs very much between instances. Depending on instance setup and size, daytime and interests the federated timeline can be more or less useful or even usable. You should give it a try but be prepared for lots of spam, inappropriate, dull and NSFW content.

Profile directory

The profile directory hides a pretty useful overview of active users on your and other instances. It is not necessarily activated on every instance.



The search function still leaves much to be desired so hashtags are the way to at least find something.

You can either search directly by typing in the search bar in the left column or visit the URL <instance>/tags/<tag>.

If you use the advanced web interface, you can pin a tag as separate column.

Conversely, this means that you should use hashtags yourself in your own posts to be able to be found by others.

Hashtags can also be of use in the profile's detail page:

  • hashtags in bios are clickable.

  • with "Edit profile -> Profile -> Featured hashtags" you can list your most used/important hastags descending in frequency in the sidebar of your profile.


With a little clicking and scrolling you should be able to find some profiles to take a closer look. If you don't have a clue where to start, you begin with following your own instance admin (go to the 'About' page).

Aside from posts/toots these are some entry points when looking at a profile:

  • Is the profile currently used? Mastodon has experienced some hypes here and there, many people move their profiles to other instances or have backup accounts - there are a lot of deserted profiles.

  • Who is the profile following?

  • By whom is the profile followed?

  • Which interests does this person have (short bio, featured hastags)?

  • Are there any more interesting profiles in the profile directory of this instance (see top navigation bar on any profile page)?

You are basically leaping from tree to tree so bring some time and sit down.


Another user directory sorted by interests is Trunk. You can send a request if you want to be included.


People aren't everything. The Fediverse is based on free software and weird folks so of course there are bots. They've even got their own instance at

Regarding the predominantly serious issues being discussed on Mastodon bots can have the potential of cheering you up.

Come out and play

On Mastodon you don't just get entertained without own efforts. This is how you start:

  • fav what you like

  • boost what you really like

  • reply - a silly, funny, smart answer, a question, a "Thank you", what do you have to lose?

  • complete your profile in the following order: avatar, short bio, links, featured hashtags, pin one or few(!) relevant toots to your profile

  • create an #introduction toot and introduce yourself to the community

  • toot even if you think you are talking to a black hole

My personal and completely subjective tips

Do your own posts

Profile timelines that consist of boosts only are tedious, I tend to follow the original then.


Write something about you, something funny, profane, embarassing, ordinary, how was your day, how about a photo from outside? Better share a really silly showerthought than be the tenth to share that screenshot shit show of the day.

Mastodon interest bingo

You work in tech, are interested in FLOSS, data privacy, are politically active, ready for the revolution? All well and good, but this is not very unusual here (admittedly Mastodons are gregarious animals), what else matters for you? Do you have other hobbies (collecting stones, (niche) sports, handicrafts, watching rom coms, ...? Tell us.


A short note to a hot topic: not every content has to be hidden behind a content warning. Quite the contrary I feel fooled and find it counterproductive to make excessive use of that function for any triviality.