mirror of
https://github.com/zadam/trilium.git
synced 2025-11-06 05:15:59 +01:00
feat(docs): reorganize script notes & document render note
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
# Downloading responses from Google Forms
|
||||
This tutorial showcases a basic integration with Google Forms, where we are able to download the responses of a form using the “Link to Sheets" functionality.
|
||||
|
||||
Note that the link will be publicly accessible to everyone (however the link is in a hard-to-guess format such as `https://docs.google.com/spreadsheets/d/e/2PACX-1vTA8NU2_eZFhc8TFadCZPreBfvP7un8IHd6J0SchrLLw3ueGmntNZjwRmsH2ZRcp1pJYDAzMz1FmFaj/pub?output=csv`). Make sure you are not accidentally publishing sensitive information.
|
||||
|
||||
## Obtaining the CSV link
|
||||
|
||||
1. Open the Google Forms in a browser.
|
||||
2. Select the “Responses” tab and click on “Link to Sheets”.
|
||||
3. Select “Create a new spreadsheet” and press “Create”.
|
||||
4. In Google Sheets, select File → Share → Publish to web.
|
||||
5. In the “Publish to the web” screen, make sure the “Link” tab is selected and instead of “Web page”, select “Comma-separated values (.csv)”.
|
||||
6. Copy the given link which will be used for the upcoming script.
|
||||
|
||||
## Creating the script
|
||||
|
||||
Create a “JS Frontend” script:
|
||||
|
||||
```
|
||||
const CSV_URL = "https://docs.google.com/spreadsheets/d/e/2PACX-1vTiwooLV2whjCSVa49dJ99p_G3_qhqHHRqttMjYCJVfLXVdTgUSNJu5K0rpqmaHYF2k7Vofi3o7gW82/pub?output=csv";
|
||||
|
||||
async function fetchData() {
|
||||
try {
|
||||
const response = await fetch(CSV_URL);
|
||||
return await response.text();
|
||||
} catch (e) {
|
||||
api.showError(e.message);
|
||||
}
|
||||
}
|
||||
|
||||
const data = await fetchData();
|
||||
console.log(data);
|
||||
// Do something with the data.
|
||||
```
|
||||
|
||||
Note that the data will be received as a string and there is no library to do the CSV parsing for us. To do a very simple parsing of CSV:
|
||||
|
||||
```
|
||||
const content = data
|
||||
.split("\n")
|
||||
.slice(1)
|
||||
.map((row) => row.split(","));
|
||||
```
|
||||
|
||||
This will return the data as an array of arrays.
|
||||
@@ -0,0 +1,47 @@
|
||||
# "New Task" launcher button
|
||||
In this example we are going to extend the functionality of <a class="reference-link" href="../../Advanced%20Usage/Advanced%20Showcases/Task%20Manager.md">Task Manager</a> showcase (which comes by default with Trilium) by adding a button in the <a class="reference-link" href="../../Basic%20Concepts%20and%20Features/UI%20Elements/Launch%20Bar.md">Launch Bar</a> () to create a new task automatically and open it.
|
||||
|
||||
## Creating the note
|
||||
|
||||
1. First, create a new <a class="reference-link" href="../../Note%20Types/Code.md">Code</a> note type with the _JS frontend_ language.
|
||||
2. Define the `#run=frontendStartup` label in <a class="reference-link" href="../../Advanced%20Usage/Attributes.md">Attributes</a>.
|
||||
|
||||
## Content of the script
|
||||
|
||||
Copy-paste the following script:
|
||||
|
||||
```javascript
|
||||
api.addButtonToToolbar({
|
||||
title: "New task",
|
||||
icon: "task",
|
||||
shortcut: "alt+n",
|
||||
action: async () => {
|
||||
const taskNoteId = await api.runOnBackend(() => {
|
||||
const todoRootNote = api.getNoteWithLabel("taskTodoRoot");
|
||||
const resp = api.createTextNote(todoRootNote.noteId, "New task", "")
|
||||
return resp.note.noteId;
|
||||
});
|
||||
|
||||
await api.waitUntilSynced();
|
||||
await api.activateNewNote(taskNoteId);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Testing the functionality
|
||||
|
||||
Since we set the script to be run on start-up, all we need to do is to [refresh the application](../../Troubleshooting/Refreshing%20the%20application.md).
|
||||
|
||||
## Understanding how the script works
|
||||
|
||||
<table class="ck-table-resized"><colgroup><col><col></colgroup><tbody><tr><td><pre><code class="language-application-javascript-env-frontend">api.addButtonToToolbar({
|
||||
title: "New task",
|
||||
icon: "task",
|
||||
shortcut: "alt+n",
|
||||
action: async () => {
|
||||
// [...]
|
||||
}
|
||||
});</code></pre></td><td><p>This uses the <a href="../Frontend%20Basics.md">Front-end API</a> to create a icon in the <a class="reference-link" href="../../Basic%20Concepts%20and%20Features/UI%20Elements/Launch%20Bar.md">Launch Bar</a>, by specifying:</p><ul><li>A title</li><li>A corresponding boxicons icon (without the <code>bx-</code> prefix).</li><li>Optionally, a keyboard shortcut to assign to it.</li><li>The action, which will be executed when the button is pressed.</li></ul></td></tr><tr><td><pre><code class="language-application-javascript-env-frontend">const taskNoteId = await api.runOnBackend(() => {
|
||||
// Shown below.
|
||||
return resp.note.noteId;
|
||||
});</code></pre></td><td><ul><li>This portion of code is actually executed on the server (backend) and not on the client (i.e. browser).<ul><li>The reason is that the creating notes is the responsibility of the server.</li></ul></li><li>Here we can also see that it is possible to return results from the server execution and read them in the client (<code>taskNoteId</code>).</li></ul></td></tr><tr><td><pre><code class="language-application-javascript-env-frontend">const todoRootNote = api.getNoteWithLabel("taskTodoRoot");</code></pre></td><td><ul><li>Here we identify a note with the <a href="../../Advanced%20Usage/Attributes.md">label</a> <code>#taskTodoRoot</code>. This is how the <a class="reference-link" href="../../Advanced%20Usage/Advanced%20Showcases/Task%20Manager.md">Task Manager</a> showcase knows where to place all the different tasks.</li><li>Normally this might return a <code>null</code> value if no such note could be identified, but error handling is outside the scope of this example. </li></ul></td></tr><tr><td><pre><code class="language-application-javascript-env-frontend">const resp = api.createTextNote(todoRootNote.noteId, "New task", "")</code></pre></td><td><ul><li>We create a new child note within the to-do root note (first argument) with the title “New task" (second argument) and no content by default (third argument).</li></ul></td></tr><tr><td><pre><code class="language-application-javascript-env-frontend">await api.waitUntilSynced();</code></pre></td><td><ul><li>Back on the client, since we created a new note on the server, we now need to wait for the change to be reflected in the client.</li></ul></td></tr><tr><td><pre><code class="language-application-javascript-env-frontend">await api.activateNewNote(taskNoteId);</code></pre></td><td><ul><li>Since we know the <a href="../../Advanced%20Usage/Note%20ID.md">ID</a> of the newly created note, all we have to do now is to show this note to the user.</li></ul></td></tr></tbody></table>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 491 B |
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,61 @@
|
||||
# Using promoted attributes to configure scripts
|
||||
A good use case of promoted attributes is to easily define the various parameters a script might need, for example an input and output note if it's processing data, or a checkbox to define a particular change in behavior for the script.
|
||||
|
||||

|
||||
|
||||
## Using check boxes to toggle flags
|
||||
|
||||
Instead of asking the user to modify a boolean value in the script, it's much more intuitive to use a checkbox for it as a promoted attribute.
|
||||
|
||||
To do so, first define the promoted attribute:
|
||||
|
||||
```
|
||||
#label:groupByExtension="promoted,alias=Group by extension,single,boolean"
|
||||
```
|
||||
|
||||
Then use it:
|
||||
|
||||
```javascript
|
||||
const byExtension = api.currentNote.getLabelValue("groupByExtension") === "true";
|
||||
if (byExtension) {
|
||||
// Do something.
|
||||
}
|
||||
```
|
||||
|
||||
This will work equally well in both front-end and back-end scripts.
|
||||
|
||||
## Using relations to select notes
|
||||
|
||||
One common use case for a script is to read data from another note and perhaps output its result in another note. To do so we need to define the following promoted attributes:
|
||||
|
||||
```
|
||||
#relation:input="promoted,alias=Input,single" #relation:output="promoted,alias=Output,single"
|
||||
```
|
||||
|
||||
Once we have this, we can add some basic error handling to ensure that the fields are completed by the user:
|
||||
|
||||
```javascript
|
||||
const inputNoteId = api.currentNote.getRelationValue("input");
|
||||
if (!inputNoteId) {
|
||||
api.showError("Missing input.");
|
||||
return;
|
||||
}
|
||||
|
||||
const outputNoteId = api.currentNote.getRelationValue("output");
|
||||
if (!outputNoteId) {
|
||||
api.showError("Missing output.");
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
Note that here we are using `api.showError` which is only available for frontend notes. If you are writing a backend note, simply remove `api.showError` but the user will no feedback on why the script did not execute properly.
|
||||
|
||||
Afterwards we can simply read the note and do something with it:
|
||||
|
||||
```javascript
|
||||
const note = api.getNote(inputNoteId);
|
||||
if (!note) {
|
||||
return;
|
||||
}
|
||||
const content = note.getContent().toString("utf-8");
|
||||
```
|
||||
Reference in New Issue
Block a user