Prof. Dr. Detlef Stern

Zettelstore 0.6

Die gute Nachricht für alle Nutzer des Zettelstore: Version 0.6 ist verfügbar. Dies gilt auch für die Bibliothek, um auf den Zettelstore zuzugreifen (a.k.a Zettelstore Client.

Huch, seit dem letzten Release 0.5 ist kaum mehr als ein halber Monat vergangen. Was ist passiert? Eine grandiose Produktivitätssteigerung?

Das erste neue Produktmerkmal gab den Ausschlag.

Schon lange habe ich auf meiner Liste eine Verbesserung der Suchmöglichkeiten. Über die Weboberfläche gibt es zwar ein Suchfeld, aber es werden dann immer nur die Zettel aufgelistet, bei denen die Suchbegriffe irgendwie vorkamen. Bei einem Suchbegriff wie „ettel“ werden auch die Zettel mit den Inhalten „Zettel“, „Zettelkasten“, „Zettelstore“ oder „Zettelmarkup“ aufgeführt. Das Verhalten kamm man ändern, indem man eines der Zeichen „=“, „>“ oder „<“ voranstellt. Dann müssen alle Suchbegriffe als Wort, als Präfix oder Suffix im jeweiligen Zettel vorkommen. Im Zweifelsfall gibt es zu viele oder zu wenige Treffer.

Schon länger als diese Volltextsuche kann man die Liste aller Zettel nach deren Metadaten filtern. Ursprünglich für die Programmierschnittstelle (API) des Zettelstore entworfen, kann man auch in der Weboberfläche durch geschickte Anpassung der URL filtern. Man muss dazu sog. Queryparameter in der URL im Browser ergänzen. Hat bestimmt schon jeder mal gesehen, der sich eine URL im entsprechenden Eingabefeld des Browser angesehen hat. Queryparameter beginnen in der URL mit einem „?“. Dann folgt etwas nach dem Muster „N=W“ oder nur „N“. Mit einem „&“ getrennt, folgenden dann weitere Elemente dieser Muster. Das „K“ nennt sich Name, das was dem „W“ nennt sich Wert.

Der Zettelstore erlaubt es, als Name den eines Metadatums anzugeben und als Wert den gewünschten Wert, den dieses Metadatum haben sollte. Um zum Beispiel alle Zettel aufzulisten, die den Begriff „zettel“ im Titel haben, ändert man die URL zum Auflisten in der Weboberfläche von /h auf /h?title=zettel. Möchte man sich auf Zettel beschränken, die im Jahre 2022 geändert wurden, so wird daraus /h?title=zettel&published=2022. Möchte man statt dessen aus administrativen Gründen eine Liste aller Zettel, die mindestens einen defekten Verweis auf einen anderen Zettel enthalten, dann gibt man /h?dead an. Diese Form es Queryparameter fragt nur ab, ob das angegebene Metadatum im Zettel existiert. („dead“ wird automatisch vom Zettelstore gesetzt.)

Beginnt der Name eines Queryparameters dagegen mit „_“, dann behandelt Zettelstore diesen anders. Metadaten dürfen nicht mit diesem Zeichen beginnen. Ein „_s“ bezeichnet den eingegebenen Suchbegriff für die Volltextsuche, „_sort“ gibt an, nach welchem Kriterim die Liste sortiert werden soll, „_limit“ spezifiziert, wie viele Zettel maximal ausgegeben werden sollen.

So habe ich in meinem Zettelstore einen Zettel, mit einigen Links, die mir bei der Administration helfen. /?_sort=published&_limit=40 gibt mir die letzten 40 geänderten Zettel an, /?role=inbox&url alle noch zu integrierenden Zettel, die selbst auf eine externe Webseite verweisen. Um mich zu überraschen, werden mir mit /h?_sort=_random&_limit=10 zehn zufällige Zettel angezeigt. Und so weiter.

Das Problem?

Das herumbasteln mit den Queryparametern ist nicht wirklich nutzerfreundlich. Die so spezifizierten Suchen sind manchmal recht eingeschränkt. Und eine Volltextsuche nach dem vollständigen Wort „Zettel“ ist nicht gleichzeitig mit der Suche nach dem Suffix „2022“ möglich.

Die Lösung.

Schon länger habe ich vor, dass man eine Suche rein über eine Texteingabe formulieren kann, gar nicht so unähnlich, wie das bei den üblichen Suchmaschinen möglich ist. Und genau damit habe ich nach dem Release von Version 0.5 begonnen.

Im Ergebnis kann man nun auch in der Suchmaske der Weboberfläche nach Metadaten filtern, die Ergebnisliste sortieren und in der Länge beschränken. Man kann gleichzeitig nach ganzen Worten oder nur Wortbestandteilen suchen. D.h. man muss nicht mehr die Queryparameter manipulieren. Das ganze vereinfacht sich auch dadurch, dass nun der eingegebene Suchbegriff bei Ausgabe der Liste in einem eigenen Eingabefeld angezeigt wird und gleich geändert werden kann. Das erleichtert die Recherche ungemein.

Aber es gibt noch mehr.

Damit ich die Suchbegriffe leichter in Zetteln eintragen kann, gibt es eine Erweiterung zur Spezifikation von Links in Zettelmarkup. Neben der Referenz auf andere Zettel oder einer URL, kann nun dort auch eine Suchabfrage eingetragen werden. Damit das leichter erkennbar ist, muss diese mit „search:“ beginnen. Für die Liste der geänderten Zettel gebe ich nun [[40 letzte Änderungen|search:SORT REVERSE published LIMIT 40]] an, oder für die Liste der zu integrierenden Zettel mit URL [[Inbox mit URL|search:role:inbox url:]].

Wenn man so will, sind das nichts weiter als gespeicherte Suchanfragen, die einfach für ggf. weitergehende Recherchen verfeinert werden können. Sehr nützlich.

Es gibt noch mehr.

Seit mehr als einem halben Jahr erlaubt es der Zettelstore, den Inhalt anderer Zettel in einen Zettel zu integrieren. Das Stichwort dazu lautet „Transklusion“. Man gibt dazu die Identität des einzufügenden Zettel geeignet an, zum Beispiel {{{20220814151900}}}. Damit wird der Zettel mit der Kennung 20220814151900 in den aktuellen Zettel eingefügt.

Nun ist es auch möglich, statt der Kennung / Identität eines Zettels dort eine Suchabfrage einzugeben. Um mir in einem Übersichtszettel zum Beispiel die letzten fünf geänderten Zettel anzuzeigen, gebe ich dort {{{search:SORT REVERSE published LIMIT 5}}} an. Diese erscheinen in dem Übersichtszettel in einer Liste, als hätte sie jemand dort manuell eingegeben.

Wer will, könnte nun auch zum Beispiel den Zettelstore nutzen, um einen einfachen Blog zu realisieren. Auf der Startseite werden kann die letzten 15 Einträge angezeigt, die man per Klick im Detail lesen kann: {{{search:role:blogpost LIMIT 15}}}. Es gibt noch viele weitere Anwendungen dieses Features.

Und warum nun das frühe Release der Version 0.6?

Die Queryparameter werden nun für diesen Zwecke nicht mehr benötigt. Deren Verarbeitung macht aber den Programmcode unnötig kompliziert. Daher habe ich entschieden, dass der Zettelstore diese ab Version 0.7 nicht mehr unterstützt. Falls es aber Nutzer geben sollte, die noch Queryparameter verwenden, möchte ich denen etwas Zeit dafür geben. Daher das vorgezogene Release.

Tatsächlich habe ich den unnötigen Programmcode schon in einer internen Version entfernt. Vieles ist dadurch an Programmierung einfacher geworden. Dadurch können Suchabfragen in Zukunft auch leistungsfähiger werden. Zusätzlich wird auch der Programmcode zur Darstellung der Listen, ohne oder mit Transklusion, vereinfacht. Damit könnte die Darstellung flexibler gestaltet werden.

Und sonst, was kommt?

Was in der nächsten Version fertiggestellt wird, muss ich mir noch überlegen. Die übernommene Bibliothek für einfache Zeichnung enthält noch zu viele kleinste Problemfälle. Im Normalfall reicht sie, aber nur für einfachste Zeichnungen. Vielleicht ergänze ich sie um Pikchr. Diese scheint mir ausgereifter und besitzt eine Portierung nach Go. Das wäre mal zu evaluieren.

Irgendwie kam mir letztens die Idee von Zetteln mit einer Lebensdauer. Anwendungsbeispiel: Zettel über Personen oder nur temporär relevante Ereignisse. Ach, es gibt in meinem Zettelstore viele Zettel mit Ideen.

Neben dem Zettel Presenter soll es einen Zettel Blog geben, um Blogposts mit Hilfe von Zetteln zu erstellen. Darüber hinaus denke ich über ein Zettel Mail nach, mit dessen Hilfe eMails in Zettel verwandelt werden. Die Integration mit Pandoc hatte ich schon angesprochen.

Wenn man so will, stabilisiert sich das Produkt Zettelstore. Damit rücken weitere Anwendungen, die den Zettelstore so richtig nützlich machen, nach vorne,

Aber vielleicht kommt noch eine Anregung aus dem Kreis der Nutzer oder Interessierten dazu …