In meinem Artikel Kleine Einführung in die Verwendung von „Browser Actions” beschreibe ich am Schluss einen Kurzbefehl, der einen ausgewählten Bereich aus einem Browser-Fenster als Snippet in einer Obsidian-Notiz speichert. In diesem Artikel möchte ich diesen Kurzbefehl erweitern, um die Möglichkeit zu bieten, dem Snippet eine eigene Anmerkung und Tags hinzuzufügen. Dazu nutze ich die Technik, die ich in meinem Artikel Mit einem Kurzbefehl Daten aus einem HTML-Formular in Obsidian integrieren vorgestellt habe. Dieser Kurzbefehl nutzt Aktionen, die von den Apps Browser Actions und Actions For Obsidian bereitgestellt werden.
Funktionsweise des Kurzbefehls
Der Kurzbefehl besteht aus zwei Bearbeitungssträngen, die abhängig davon, wie der Kurzbefehl aufgerufen wird, abgearbeitet werden. Erfolgt der Aufruf, nachdem in einem aktiven Browser-Fenster ein Bereich ausgewählt wurde, wird er ohne einen Input-Parameter aufgerufen. So wird dann zunächst die „Ja-Bedingung“ der „wenn“-Abfrage ausgeführt.
Wichtig ist, dass die „wenn“-Abfrage richtig ausgeführt wird. Dazu muss als Parameter in der Kurzbefehl-Eingabe-Box die „Nein-Eingabe“ ausgewählt sein. Dies wird genauer in meinem Artikel Mit einem Kurzbefehl Daten aus einem HTML-Formular in Obsidian integrieren erklärt.
Im ersten Schritt der Bearbeitung kommt die Aktion „Get Details of the tab…“ aus der Browser Action-App zum Einsatz, die alle relevanten Attribute des aktiven Browser-Fensters erfasst, die für diesen Kurzbefehl wichtig sind:
- pageURL
- pageTitle
- Current Selection (Markdown)
Nun wird ein vorgefertigtes HTML-Formular geöffnet und mit diesen Daten, wiederum unter Zuhilfenahme von Aktionen der App Browser Actions, gefüllt. Zusätzlich können in diesem Formular die eigenen Anmerkungen und die Tags erfasst werden.
Nach dem Klicken auf den „Send“-Button wird der Kurzbefehl erneut aufgerufen und der „Nein“-Teil der Bedingung durchlaufen. In diesem Teil wird der Inhalt des Snippets erstellt und mit Hilfe von Actions for Obsidian in die dafür vorgesehene Notiz in Obsidian eingefügt.
Das HTML-Formular
Das Layout
Das HTML-Formular ist einfach aufgebaut. Im oberen Bereich wird die Browser-Auswahl angezeigt. In der nächsten Reihe werden das Textfeld für die Eingabe eigener Anmerkungen und der Eingabe der Tags angeboten. Häufig benutzte Tags können im HTML-Code definiert werden und erscheinen an dieser Stelle dann als Checkboxen und können so schnell ausgewählt werden. Eine Eingabe des ‘#’-Zeichens ist nicht notwendig, da dies durch das JavaScript automatisch hinzugefügt wird.
Der untere Bereich zeigt die zuvor im Browser-Fenster erfassten Daten an. In der linken Spalte das Markdown der Auswahl und in der rechten Spalte die URL sowie der Seitentitel. Diese Felder sind notwendig, damit die Daten aus dem ersten Aufruf des Kurzbefehls weiterverarbeitet werden können. Außerdem können sie an dieser Stelle auch noch editiert werden. Es ist aber auch möglich, diesen Bereich zu verstecken, wozu im HTML-Code die CSS-Klasse .hidden-input
verwendet werden kann.
Am Ende der Seite wird der „Senden“-Button angezeigt, mit dem die Daten an den Kurzbefehl zur Erstellung des Snippets übergeben werden.
Der HTML-Code
Im <head>
-Bereich der HTML-Datei befinden sich die notwendigen CSS-Definitionen sowie der Aufruf der markedjs/marked-Bibliothek, die für die Erstellung der Vorschau des Markdowns genutzt wird.
Im <body>
-Bereich werden die zuvor beschriebenen Felder definiert, ebenso wie der „Senden“-Button. Dieser Bereich enthält auch den notwendigen JavaScript-Teil mit den beiden Funktionen:
updatePreview()
: Diese Funktion aktualisiert die Vorschau, sobald das Markdown verändert wird.handleSubmit()
: Diese Funktion bereitet die Formular-Daten als JSON-String auf und ruft den Kurzbefehl erneut mit dem JSON-String als Parameter auf. Dabei werden die Tags um das#
ergänzt und in einem Array gespeichert. Abschließend werden alle Daten in einem Objekt zusammengefasst, in einen JSON-String konvertiert und über das URL-Schemashortcuts://run-shortcut
an den Kurzbefehl übergeben.
Hier ist die gesamte HTML-Datei:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Erstelle Snippet mit einer Anmerkung und Tags in Obsidian</title> <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> <style> /* Base Body */ body { margin: 0; padding: 10px; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f4f7f9; color: #333; } /* Container */ .container { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; max-width: 1000px; margin: 0 auto; } /* Box */ .box { background-color: #fff; border-radius: 8px; box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1); padding: 15px; border: 1px solid #ddd; } /* Preview Box */ .preview-box { grid-column: 1 / 3; min-height: 200px; font-size: 0.9rem; overflow: auto; } .preview-box h2 { margin-top: 0; font-size: 1.2rem; color: #007acc; } /* Anmerkung und Tags - 2 Column Grid */ .notes-tags-box { grid-column: 1 / 3; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; } .note-field { } /* Tags Bereich */ .tag-input { width: 100%; padding: 8px; font-size: 0.9rem; border-radius: 4px; border: 1px solid #ccc; margin-top: 8px; margin-bottom: 15px; /* Added space below tag input field */ } /* Checkbox Gruppe - ermöglicht Zeilenumbruch */ .checkbox-group { display: flex; flex-wrap: wrap; gap: 10px; /* Space between checkboxes */ } .checkbox-group label { display: flex; align-items: center; margin-right: 10px; } /* Markdown und Meta Information 2 Column Grid */ .markdown-meta-box { grid-column: 1 / 3; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; } /* Eingabe und Textarea Stil */ textarea, input[type="text"] { width: 100%; padding: 8px; font-size: 0.9rem; border-radius: 4px; border: 1px solid #ccc; box-sizing: border-box; } textarea { min-height: 100px; resize: vertical; } /* Senden Button */ .submit-button { display: block; margin: 20px auto; padding: 12px 24px; font-size: 1rem; background-color: #007acc; color: white; border: none; border-radius: 5px; cursor: pointer; transition: background-color 0.3s; } .submit-button:hover { background-color: #005999; } /* Klasse zum Verstecken des Containers für das Markdown etc. */ .hidden-input { position: absolute; left: -1000px; overflow: hidden; width: 1px; height: 1px; } /* Minimales responsives Design */ @media (max-width: 768px) { .container { grid-template-columns: 1fr; } .preview-box, .notes-tags-box, .markdown-meta-box { grid-column: 1 / 2; } .notes-tags-box, .markdown-meta-box { grid-template-columns: 1fr; } } </style> </head> <body> <div class="container"> <!-- Vorschau (spans über beide columns) --> <div class="box preview-box" id="preview-container"> <h2>Vorschau der Auswahl</h2> <div id="preview"> <p>Markdown Preview wird hier angezeigt.</p> </div> </div> <!-- Anmerrkungen and Tags jeweils eine column --> <div class="notes-tags-box"> <div class="box notes-section"> <h3>Anmerkung</h3> <textarea id="notes" class="note-field" name="notes" placeholder="Gebe Deine Anmerkung hier ein..."></textarea> </div> <div class="box tags-section"> <h3>Tags</h3> <input type="text" id="tags" class="tag-input" placeholder="Für zusätzliche mit Kommas getrennte Tags"> <div class="checkbox-group"> <label><input type="checkbox"> Wichtig</label> <label><input type="checkbox"> Fragen</label> <label><input type="checkbox"> Beispiel</label> <label><input type="checkbox"> Idee</label> <label><input type="checkbox"> Widerspruch</label> <label><input type="checkbox"> Nachverfolgen</label> </div> </div> </div> <!-- Markdown und Meta Information über beide columns --> <!-- kann mit de class hidden-input ausgeblendet werden --> <div class="markdown-meta-box"> <div class="box markdown-section"> <h3>Markdown</h3> <textarea id="markdown" placeholder="Hier wird das Markdown der Auswahl angezeigt" oninput="updatePreview()"></textarea> </div> <div class="box meta-section"> <h3>URL</h3> <input type="text" id="url" placeholder="URL"> <h3>Seiten-Title</h3> <input type="text" id="title" placeholder="Seiten-Title"> </div> </div> </div> <button class="submit-button" onclick="handleSubmit()">Senden</button> <script> function updatePreview() { const markdownContent = document.getElementById('markdown').value; const previewBox = document.getElementById('preview'); previewBox.innerHTML = marked.parse(markdownContent); } function handleSubmit() { const notes = document.getElementById('notes').value; const tagsInput = document.getElementById('tags').value; const markdown = document.getElementById('markdown').value; const url = document.getElementById('url').value; const title = document.getElementById('title').value; const tagsArray = tagsInput.split(',') .map(tag => `#${tag.trim()}`) .filter(tag => tag.length > 1); const checkedTags = Array.from(document.querySelectorAll('.checkbox-group input[type="checkbox"]:checked')) .map(checkbox => `#${checkbox.parentElement.textContent.trim()}`); const tags = [...tagsArray, ...checkedTags]; const data = { notes: notes, tags: tags, markdown: markdown, url: url, title: title }; const jsonString = JSON.stringify(data); window.location.href = `shortcuts://run-shortcut?name=Snippets+&input=${encodeURIComponent(jsonString)}`; window.close(); } </script> </body> </html>
Das Snippet+ Layout
Bevor der Kurzbefehl betrachtet wird, muss das Layout des Snippets+ definiert werden. Es besteht aus den folgenden vier Bereichen:
- Kopfzeile: Die Kopfzeile beginnt mit dem Callout-Indikator
> [!quote]
. Darauf folgen das aktuelle Datum, der Seitentitel und die Seiten-URL. - Tags: Der zweite Abschnitt enthält eine Zeile mit den Tags.
- Auswahl: Der dritte Abschnitt enthält die Browserauswahl, formatiert in Markdown.
- Anmerkung: Der vierte Abschnitt enthält die Anmerkung, die zur besseren Unterscheidung von der Auswahl kursiv dargestellt wird.
Hier ist ein Beispiel im Markdown-Format, zusammen mit einem Screenshot aus Obsidian:
> [!quote] 06.12.24 [Flensburg – Wikipedia](https://de.wikipedia.org/wiki/Flensburg) >#Wichtig > **Flensburg** ([dänisch](https://de.wikipedia.org/wiki/D%C3%A4nische_Sprache) und [niederdeutsch](https://de.wikipedia.org/wiki/Niederdeutsche_Sprache) **Flensborg**, [nordfriesisch](https://de.wikipedia.org/wiki/Nordfriesische_Sprache) Flansborj oder _Flensborag_, [südjütisch](https://de.wikipedia.org/wiki/S%C3%B8nderjysk) _Flensborre_, [lateinisch](https://de.wikipedia.org/wiki/Latein) Flenopolis oder _Flensburgum_[[2]]()) ist eine große [kreisfreie](https://de.wikipedia.org/wiki/Kreisfreie_Stadt) [Mittelstadt](https://de.wikipedia.org/wiki/Mittelstadt) im Norden [Schleswig-Holsteins](https://de.wikipedia.org/wiki/Schleswig-Holstein). Nach [Kiel](https://de.wikipedia.org/wiki/Kiel) und [Lübeck](https://de.wikipedia.org/wiki/L%C3%BCbeck) ist Flensburg mit 92.667 Einwohnern (Stand: 31. Dezember 2023) die drittgrößte Stadt des Bundeslandes, die größte im [Landesteil Schleswig](https://de.wikipedia.org/wiki/S%C3%BCdschleswig) und die nördlichste [kreisfreie Stadt Deutschlands](https://de.wikipedia.org/wiki/Liste_der_kreisfreien_St%C3%A4dte_in_Deutschland). > > *Dat is mien Heimat, dor bün ik leid nich mehr to Huus.*
In dem Kurzbefehl wird dieser Callout so definiert:
Die Kurzbefehl-Definition
In dem ersten Block der meisten Kurzbefehle wird die Quelle der Kurzbefehleingabe definiert. In diesem Kurzbefehl ist das nicht notwendig, da beim ersten Aufruf die Aktion „Get details of the Tab…“ den aktiven Browser direkt aufruft und im zweiten Aufruf die Daten als Parameter direkt an den Kurzbefehl übergeben werden. Daher sollte „Keine Eingabe” als Quelle festgelegt werden.
Diese Option wird am einfachsten definiert, indem zunächst die Wenn-Aktion in den Kurzbefehleditor gezogen und dann die „Kurzbefehleingabe” als Eingabeparameter ausgewählt wird. Es erscheint der Eingabe-Block mit der Quelle „Nirgendwo“. Nun wird die Angabe der „Bilder und 18 weiter“-Eingaben auf „Nein“ gesetzt, indem die Auswahl aller Checkboxen aufgehoben wird.
Die weiteren Aktionen werden unter den Bereichen Wenn und Sonst eingetragen. Der Block unter dem Wenn wird ausgeführt, wenn die Kurzbefehleingabe beim Aufruf keine Daten enthält, und der Block unter dem Sonst-Block, wenn der Kurzbefehl über den „Senden“-Button der HTML-Seite aufgerufen wird. Dabei wird dann der Kurzbefehl mit einem Parameter aufgerufen.
Die „hat keinen Wert“-Bedingung
Wenn der Kurzbefehl aus dem Browser heraus aufgerufen wird, geschieht dies ohne einen Eingabewert, und daher wird der Block nach der „wenn“-Aktion durchlaufen.
Die Aktion „Get details of the tab active tab of frontmost window in frontmost browser“ aus der App „Browser-Actions“ übernimmt alle relevanten Daten von der Webseite. Diese Daten sind in der vollständigen Liste der erfassbaren Attribute beschrieben, die in der Browser-Action Dokumentation zu finden ist. Für diesen Kurzbefehl sind lediglich die aktuelle Auswahl (als Markdown), die URL und der Titel der Webseite relevant.
Als Nächstes wird die HTML-Datei mit dem Eingabeformular in einem neuen Tab des Browsers geöffnet. Die Formularfelder für die URL, den Seitentitel und das Markup werden dann mit den zuvor ermittelten Daten gefüllt. Dies geschieht mithilfe der Aktion „Set form field with ‘id’ attribute of field name to value parameter in active tab of frontmost window of frontmost browser“ aus der App „Browser-Actions“.
Sobald die Felder mit Daten gefüllt sind, können eine zusätzliche Anmerkung sowie Tags hinzugefügt werden. Danach wird der Kurzbefehl beendet.
Die „Sonst“-Bedingung
Wenn die Bearbeitung des Formulars durch das Klicken des „Senden-Buttons“ beendet wird, wird der Kurzbefehl erneut aufgerufen. Da dies nun mit dem JSON-String als Wert für die Kurzbefehleingabe geschieht, werden die Aktionen der Sonst
-Bedingung ausgeführt.
Als Eingabe erhält der Kurzbefehl einen JSON-String wie diesen:
{ "tags": [ "#Wichtig", "#Beispiel" ], "title": "Flensburg – Wikipedia", "notes": "Dat is mien Heimat, dor bün ik leid nich mehr to Huus.", "url": "https://de.wikipedia.org/wiki/Flensburg", "markdown": "**Flensburg** ([dänisch](https://de.wikipedia.org/wiki/D%C3%A4nische_Sprache) und [niederdeutsch](https://de.wikipedia.org/wiki/Niederdeutsche_Sprache) **Flensborg**, [nordfriesisch](https://de.wikipedia.org/wiki/Nordfriesische_Sprache) Flansborj oder _Flensborag_, [südjütisch](https://de.wikipedia.org/wiki/S%C3%B8nderjysk) _Flensborre_, [lateinisch](https://de.wikipedia.org/wiki/Latein) Flenopolis oder _Flensburgum_[[2]]()) ist eine große [kreisfreie](https://de.wikipedia.org/wiki/Kreisfreie_Stadt) [Mittelstadt](https://de.wikipedia.org/wiki/Mittelstadt) im Norden [Schleswig-Holsteins](https://de.wikipedia.org/wiki/Schleswig-Holstein). Nach [Kiel](https://de.wikipedia.org/wiki/Kiel) und [Lübeck](https://de.wikipedia.org/wiki/L%C3%BCbeck) ist Flensburg mit 92.667 Einwohnern (Stand: 31. Dezember 2023) die drittgrößte Stadt des Bundeslandes, die größte im [Landesteil Schleswig](https://de.wikipedia.org/wiki/S%C3%BCdschleswig) und die nördlichste [kreisfreie Stadt Deutschlands](https://de.wikipedia.org/wiki/Liste_der_kreisfreien_St%C3%A4dte_in_Deutschland)." }
Um daraus das Snippet+ zusammenzusetzen, müssen die einzelnen Schlüssel-Wert-Paare aufbereitet werden.
Zuerst wird das Tags-Array in einen einzelnen String umgewandelt, bei dem die einzelnen Tags durch Leerzeichen getrennt sind. Dies geschieht mit der Aktion „Text kombinieren“. Das Ergebnis wird in der Variablen „tags“ gespeichert.
Im nächsten Schritt wird das Markdown aufbereitet. Da das Snippet in einem Obsidian-Callout angezeigt werden soll, muss, falls die Auswahl aus mehreren Zeilen besteht, vor jeder Zeile das >
stehen. Dazu wird das Markdown zunächst in einzelne Zeilen aufgeteilt, damit dann mit der Aktion „Mit jedem Objekt aus text wiederholen“ vor jede Zeile das >
vorangestellt werden kann. Das Ergebnis dieser Schleife wird dann als kombinierter Text in der Variablen markdown
gespeichert.
Die gleiche Prozedur wird dann noch einmal mit den Anmerkungen notes
durchgeführt, da auch hier ggf. mehrere Zeilen eingegeben sein könnten.
Nun kann das Snippet in einem Textfeld, wie oben definiert, erstellt werden. Dieses Feld wird dann in Obsidian einer der Snippets+-Notiz vorangestellt (in meinem Fall im Vault „Obsidian Cloud“ in der Notiz „00 New/Snippet+“ unter der Überschrift ## Snippets+
).
Die „Stop and output“-Aktion wird automatisch nach dem ersten Lauf erstellt.
Fazit und Ausblick
Das war’s! Wie ich in einem der vorherigen Artikel erwähnt habe, füge ich die meisten meiner Kurzbefehle auf dem Mac nur dem Kurzbefehl-Menü im Finder hinzu, da dies für mich der einfachste Weg ist, auf sie zuzugreifen. Wenn andere Methoden zugewiesen werden, wie z.B. Tastenkurzbefehle, muss sichergestellt werden, dass das „Verknüpfungseingabe“-Feld auf „Nein“ und „Nirgendwo“ stehen bleibt. Andernfalls könnte dies dazu führen, dass der falsche Teil der bedingten Anweisung ausgeführt wird.
Dieser Kurzbefehl läuft nur auf dem Mac, da die Beschränkungen in iOS und iPadOS Apps wie „Browser Actions“ unmöglich machen.
Es sind sicherlich noch einige Erweiterungen möglich. Dieser Artikel soll kein „Endprodukt“ vorstellen, sondern zu eigenen Lösungen inspirieren.
Wie immer, freue ich mich über Lob, Kritik, Ideen oder Verbesserungsvorschläge in den Kommentaren.
Schreibe einen Kommentar