nasauber.de

Blog: Einträge 03.08–05.09.2021

gpx2svg 0.2.0 released

After quite some time, a few things changed, so let's do another release of of gpx2svg, the program to convert GPX to SVG. So what's new?

Not much more to say, the code still does the one thing it was written to do ;-) Thanks again to Hans for supplying the initial patch! Have a lot of fun with gpx2svg!


Own homepage for KGeoTag

As of now, KGeoTag, the stand-alone, KDE-based photo geotagging program, has it's own homepage at https://kgeotag.kde.org/. Big thanks to the KDE project, esp. the Sysadmin Ben Cooksley, for setting this up and making it possible!

This is now the right place for information about the project and blog posts. Consequently, the two posts KGeoTag 1.0 coming soon and KGeoTag 1.0.0 out now I posted here have been moved over to their new home.

I really love to see the project evolving. May it last a long time :-)


Setting up WKD with lighttpd

Web Key Directory is an approach for simple distribution of public PGP keys. The idea is that a mail client checks for a needed key automatically and the user can simply encrypt a mail, without further interaction (no searching on a keyserver or manual downloading and importing into GnuPG).

The first site you find searching for it is GnuPG's WKD wiki page. But – just speaking of me – this page is quite confusing, and setting up WKD seems to be quite complicated. Happily, it isn't ;-)

A nice blog post describes what has to be done when you want to setup WKD. Just in case the linked blog post is removed: Providing PGP keys via WKD using the "direct" method (there's also an "advanced" method I didn't use) strips down to:

Finally, you need to tell the HTTP server to deliver the correct MIME type for the key file(s). As usual, the article only contains configuration examples for Apache and nginx. As a lighttpd user, you're used to that ;-)

To make life a bit easier for the lighttpd users out there wanting to setup WKD, here's the snippet you need to make lighttpd deliver the correct MIME type and HTTP headers:

$HTTP["url"] =~ "^/.well-known/openpgpkey/hu/" {
    mimetype.assign = ( "" => "application/octet-stream" )
    setenv.add-response-header = ( "Access-Control-Allow-Origin" => "*" )
}

You can validate your setup to be correct using some WKD validator as e. g. provided by metacode.biz.

Now go and make the world a bit better by setting up WKD ;-)


Dynamic nested menu with Jekyll

Whilst porting my old graduating class's homepage abi2002amschiller.de to Jekyll, I faced a problem on how to implement the menu. It's a dynamic menu with nested submenus, without a defined level count. The old PHP implementation always showed a "path" which leads to the the currently opened menu, and the actual menu itself.

Doing this in Jekyll/Liquid was a bit tricky. In Jekyll's Navigation Tutorial, one can find a Nested tree navigation with recursion, but this always dumps the whole menu. Not what I wanted. After some research and coding I ended up getting the very menu I had before, with the help of a data file and three scripts partly called recursively, all in pure Liquid. Not too hard, but also not quite trivial.

I publish this stuff as CC0 1.0. Do what you want with it. Here we are:

The menu definition

The data file navigation.yml consists of menu elements with names and links each, and possibly a sub-menu. There's one root element holding the top-level menu. Menus can be nested arbitrarily deep:

- name: "Home"
  link: "/"

  submenu:

  - name: "Top level entry 1"
    link: "/1/"

    submenu:

    - name: "Submenu 1 entry 1"
      link: "/1/1/"

    - name: "Submenu 1 entry 2"
      link: "/1/2/"

      submenu:

      - name: "Subsubmenu 1.2 entry 1"
        link: "/1/2/1/"

      - name: "Subsubmenu 1.2 entry 2"
        link: "/1/2/2/"

      - name: "Subsubmenu 1.2 entry 3"
        link: "/1/2/3/"

    - name: "Submenu 1 entry 3"
      link: "/1/3/"

  - name: "Top level entry 2"
    link: "/2/"

  - name: "Top level entry 3"
    link: "/3/"

The menu generation code

The menu itself consists of two unordered lists. One is the "path" to the currently opened menu, the other one is the menu itself. I indented the code here for better readability here. For the output linked below, there's no indentation and empty lines, because I really have a rough time each time I mess with Liquid's white space control for nice HTML output ;-)

Here's the main menu code navigation.html:

<nav id="navigation_path">
<ul>
{% include navigation_path.html menu = site.data.navigation %}
</ul>
</nav>

<nav id="navigation_menu">
<ul>
{% include navigation_find_menu.html menu = site.data.navigation %}

{% unless open_menu %}
{% assign open_menu = site.data.navigation[0].submenu %}
{% endunless %}

{% for item in open_menu %}
    {% if page.dir == item.link %}
        <li><span>{{ item.name }}</span></li>
    {% else %}
        <li><a href="{{ item.link }}">{{ item.name }}</a></li>
    {% endif %}
{% endfor %}
</ul>
</nav>

Here's navigation_path.html. This one walks along the menu structure and recursively includes itself until the path is built, always passing itself a part of the original menu data:

{% for item in include.menu %}
    {% if page.dir contains item.link %}
        {% if item.submenu %}
            {% if page.dir == item.link %}
                <li><span>{{ item.name }}</span></li>
            {% else %}
                <li><a href="{{ item.link }}">{{ item.name }}</a></li>
            {% endif %}
        {% endif %}
    {% endif %}

    {% if item.submenu %}
        {% include navigation_path.html menu = item.submenu %}
    {% endif %}
{% endfor %}

And here's navigation_find_menu.html, which – also by including itself recursively – finds the currently opened menu. If no open menu is found (because we're on the first level), open_menu stays empty. In this case, site.data.navigation[0].submenu, the top-level submenu of the root element, is displayed by navigation.html.

{% for item in include.menu %}
    {% if page.dir == item.link %}
        {% if item.submenu %}
            {% assign open_menu = item.submenu %}
        {% else %}
            {% assign open_menu = include.menu %}
        {% endif %}
    {% endif %}

    {% if item.submenu %}
        {% include navigation_find_menu.html menu = item.submenu %}
    {% endif %}
{% endfor %}

What it looks like

You can view the output of the above code, using a minimal layout. Only the links have been converted to relative ones manually to make it work with a non-"/" root. You can as well download the sources.

I hope this helps somebody :-)