Merge branch 'main' of https://github.com/TriliumNext/Trilium into feat/ui-improvements

This commit is contained in:
Adorian Doran
2025-11-05 17:35:10 +02:00
200 changed files with 4891 additions and 2782 deletions

View File

@@ -11,7 +11,7 @@
"license": "AGPL-3.0-only",
"packageManager": "pnpm@10.20.0",
"devDependencies": {
"@redocly/cli": "2.10.0",
"@redocly/cli": "2.11.0",
"archiver": "7.0.1",
"fs-extra": "11.3.2",
"react": "19.2.0",

View File

@@ -22,8 +22,9 @@ async function main() {
buildSwagger(context);
buildScriptApi(context);
// Copy index file.
// Copy index and 404 files.
cpSync(join(__dirname, "index.html"), join(context.baseDir, "index.html"));
cpSync(join(context.baseDir, "user-guide/404.html"), join(context.baseDir, "404.html"));
}
main();

View File

@@ -15,7 +15,7 @@
"circular-deps": "dpdm -T src/**/*.ts --tree=false --warning=false --skip-dynamic-imports=circular"
},
"dependencies": {
"@eslint/js": "9.39.0",
"@eslint/js": "9.39.1",
"@excalidraw/excalidraw": "0.18.0",
"@fullcalendar/core": "6.1.19",
"@fullcalendar/daygrid": "6.1.19",
@@ -59,7 +59,7 @@
"normalize.css": "8.0.1",
"panzoom": "9.4.3",
"preact": "10.27.2",
"react-i18next": "16.2.3",
"react-i18next": "16.2.4",
"reveal.js": "5.2.1",
"svg-pan-zoom": "3.6.2",
"tabulator-tables": "6.3.1",

View File

@@ -137,7 +137,7 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
command: "editBranchPrefix",
keyboardShortcut: "editBranchPrefix",
uiIcon: "bx bx-rename",
enabled: isNotRoot && parentNotSearch && noSelectedNotes && notOptionsOrHelp
enabled: isNotRoot && parentNotSearch && notOptionsOrHelp
},
{ title: t("tree-context-menu.convert-to-attachment"), command: "convertNoteToAttachment", uiIcon: "bx bx-paperclip", enabled: isNotRoot && !isHoisted && notOptionsOrHelp },

View File

@@ -159,7 +159,7 @@ describe("shortcuts", () => {
expect(matchesShortcut(event, "Shift+F1")).toBeTruthy();
// Special keys
for (const keyCode of [ "Delete", "Enter" ]) {
for (const keyCode of [ "Delete", "Enter", "NumpadEnter" ]) {
event = createKeyboardEvent({ key: keyCode, code: keyCode });
expect(matchesShortcut(event, keyCode), `Key ${keyCode}`).toBeTruthy();
}

View File

@@ -46,6 +46,7 @@ for (let i = 1; i <= 19; i++) {
const KEYCODES_WITH_NO_MODIFIER = new Set([
"Delete",
"Enter",
"NumpadEnter",
...functionKeyCodes
]);

View File

@@ -36,10 +36,13 @@
},
"branch_prefix": {
"edit_branch_prefix": "Edit branch prefix",
"edit_branch_prefix_multiple": "Edit branch prefix for {{count}} branches",
"help_on_tree_prefix": "Help on Tree prefix",
"prefix": "Prefix: ",
"save": "Save",
"branch_prefix_saved": "Branch prefix has been saved."
"branch_prefix_saved": "Branch prefix has been saved.",
"branch_prefix_saved_multiple": "Branch prefix has been saved for {{count}} branches.",
"affected_branches": "Affected branches ({{count}}):"
},
"bulk_actions": {
"bulk_actions": "Bulk actions",

View File

@@ -109,7 +109,8 @@
"export_type_single": "Solo questa nota, senza le sottostanti",
"format_opml": "OPML - formato per scambio informazioni outline. Formattazione, immagini e files non sono inclusi.",
"opml_version_1": "OPML v.1.0 - solo testo semplice",
"opml_version_2": "OPML v2.0 - supporta anche HTML"
"opml_version_2": "OPML v2.0 - supporta anche HTML",
"share-format": "HTML per la pubblicazione sul web - utilizza lo stesso tema utilizzato per le note condivise, ma può essere pubblicato come sito web statico."
},
"password_not_set": {
"body1": "Le note protette sono crittografate utilizzando una password utente, ma la password non è stata ancora impostata.",

View File

@@ -0,0 +1,13 @@
.branch-prefix-dialog .branch-prefix-notes-list {
margin-top: 10px;
}
.branch-prefix-dialog .branch-prefix-notes-list ul {
max-height: 200px;
overflow: auto;
margin-top: 5px;
}
.branch-prefix-dialog .branch-prefix-current {
opacity: 0.6;
}

View File

@@ -10,53 +10,86 @@ import Button from "../react/Button.jsx";
import FormGroup from "../react/FormGroup.js";
import { useTriliumEvent } from "../react/hooks.jsx";
import FBranch from "../../entities/fbranch.js";
import type { ContextMenuCommandData } from "../../components/app_context.js";
import "./branch_prefix.css";
// Virtual branches (e.g., from search results) start with this prefix
const VIRTUAL_BRANCH_PREFIX = "virt-";
export default function BranchPrefixDialog() {
const [ shown, setShown ] = useState(false);
const [ branch, setBranch ] = useState<FBranch>();
const [ branches, setBranches ] = useState<FBranch[]>([]);
const [ prefix, setPrefix ] = useState("");
const branchInput = useRef<HTMLInputElement>(null);
useTriliumEvent("editBranchPrefix", async () => {
const notePath = appContext.tabManager.getActiveContextNotePath();
if (!notePath) {
useTriliumEvent("editBranchPrefix", async (data?: ContextMenuCommandData) => {
let branchIds: string[] = [];
if (data?.selectedOrActiveBranchIds && data.selectedOrActiveBranchIds.length > 0) {
// Multi-select mode from tree context menu
branchIds = data.selectedOrActiveBranchIds.filter((branchId) => !branchId.startsWith(VIRTUAL_BRANCH_PREFIX));
} else {
// Single branch mode from keyboard shortcut or when no selection
const notePath = appContext.tabManager.getActiveContextNotePath();
if (!notePath) {
return;
}
const { noteId, parentNoteId } = tree.getNoteIdAndParentIdFromUrl(notePath);
if (!noteId || !parentNoteId) {
return;
}
const branchId = await froca.getBranchId(parentNoteId, noteId);
if (!branchId) {
return;
}
const parentNote = await froca.getNote(parentNoteId);
if (!parentNote || parentNote.type === "search") {
return;
}
branchIds = [branchId];
}
if (branchIds.length === 0) {
return;
}
const { noteId, parentNoteId } = tree.getNoteIdAndParentIdFromUrl(notePath);
const newBranches = branchIds
.map(id => froca.getBranch(id))
.filter((branch): branch is FBranch => branch !== null);
if (!noteId || !parentNoteId) {
if (newBranches.length === 0) {
return;
}
const newBranchId = await froca.getBranchId(parentNoteId, noteId);
if (!newBranchId) {
return;
}
const parentNote = await froca.getNote(parentNoteId);
if (!parentNote || parentNote.type === "search") {
return;
}
const newBranch = froca.getBranch(newBranchId);
setBranch(newBranch);
setPrefix(newBranch?.prefix ?? "");
setBranches(newBranches);
// Use the prefix of the first branch as the initial value
setPrefix(newBranches[0]?.prefix ?? "");
setShown(true);
});
async function onSubmit() {
if (!branch) {
if (branches.length === 0) {
return;
}
savePrefix(branch.branchId, prefix);
if (branches.length === 1) {
await savePrefix(branches[0].branchId, prefix);
} else {
await savePrefixBatch(branches.map(b => b.branchId), prefix);
}
setShown(false);
}
const isSingleBranch = branches.length === 1;
return (
<Modal
className="branch-prefix-dialog"
title={t("branch_prefix.edit_branch_prefix")}
title={isSingleBranch ? t("branch_prefix.edit_branch_prefix") : t("branch_prefix.edit_branch_prefix_multiple", { count: branches.length })}
size="lg"
onShown={() => branchInput.current?.focus()}
onHidden={() => setShown(false)}
@@ -69,9 +102,27 @@ export default function BranchPrefixDialog() {
<div class="input-group">
<input class="branch-prefix-input form-control" value={prefix} ref={branchInput}
onChange={(e) => setPrefix((e.target as HTMLInputElement).value)} />
<div class="branch-prefix-note-title input-group-text"> - {branch && branch.getNoteFromCache().title}</div>
{isSingleBranch && branches[0] && (
<div class="branch-prefix-note-title input-group-text"> - {branches[0].getNoteFromCache().title}</div>
)}
</div>
</FormGroup>
{!isSingleBranch && (
<div className="branch-prefix-notes-list">
<strong>{t("branch_prefix.affected_branches", { count: branches.length })}</strong>
<ul>
{branches.map((branch) => {
const note = branch.getNoteFromCache();
return (
<li key={branch.branchId}>
{branch.prefix && <span className="branch-prefix-current">{branch.prefix} - </span>}
{note.title}
</li>
);
})}
</ul>
</div>
)}
</Modal>
);
}
@@ -80,3 +131,8 @@ async function savePrefix(branchId: string, prefix: string) {
await server.put(`branches/${branchId}/set-prefix`, { prefix: prefix });
toast.showMessage(t("branch_prefix.branch_prefix_saved"));
}
async function savePrefixBatch(branchIds: string[], prefix: string) {
await server.put("branches/set-prefix-batch", { branchIds, prefix });
toast.showMessage(t("branch_prefix.branch_prefix_saved_multiple", { count: branchIds.length }));
}

View File

@@ -1591,6 +1591,20 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
this.clearSelectedNodes();
}
async editBranchPrefixCommand({ node }: CommandListenerData<"editBranchPrefix">) {
const branchIds = this.getSelectedOrActiveBranchIds(node).filter((branchId) => !branchId.startsWith("virt-"));
if (!branchIds.length) {
return;
}
// Trigger the event with the selected branch IDs
appContext.triggerEvent("editBranchPrefix", {
selectedOrActiveBranchIds: branchIds,
node: node
});
}
canBeMovedUpOrDown(node: Fancytree.FancytreeNode) {
if (node.data.noteId === "root") {
return false;

View File

@@ -13,8 +13,8 @@ export default function EditedNotesTab({ note }: TabContext) {
useEffect(() => {
if (!note) return;
server.get<EditedNotesResponse>(`edited-notes/${note.getLabelValue("dateNote")}`).then(async editedNotes => {
editedNotes = editedNotes.filter((n) => n.noteId !== note.noteId);
const noteIds = editedNotes.flatMap((n) => n.noteId);
editedNotes = editedNotes.filter((n) => n.noteId !== note.noteId);
const noteIds = editedNotes.flatMap((n) => n.noteId);
await froca.getNotes(noteIds, true); // preload all at once
setEditedNotes(editedNotes);
});
@@ -41,11 +41,11 @@ export default function EditedNotesTab({ note }: TabContext) {
)}
</span>
)
}))}
}), " ")}
</div>
) : (
<div className="no-edited-notes-found">{t("edited_notes.no_edited_notes_found")}</div>
)}
</div>
)
)
}

View File

@@ -72,8 +72,8 @@ function EditorFeatures() {
return (
<OptionsSection title={t("editorfeatures.title")}>
<EditorFeature name="emoji-completion-enabled" optionName="textNoteEmojiCompletionEnabled" label={t("editorfeatures.emoji_completion_enabled")} description={t("editorfeatures.emoji_completion_description")} />
<EditorFeature name="note-completion-enabled" optionName="textNoteCompletionEnabled" label={t("editorfeatures.note_completion_enabled")} description={t("editorfeatures.emoji_completion_description")} />
<EditorFeature name="slash-commands-enabled" optionName="textNoteSlashCommandsEnabled" label={t("editorfeatures.slash_commands_enabled")} description={t("editorfeatures.emoji_completion_description")} />
<EditorFeature name="note-completion-enabled" optionName="textNoteCompletionEnabled" label={t("editorfeatures.note_completion_enabled")} description={t("editorfeatures.note_completion_description")} />
<EditorFeature name="slash-commands-enabled" optionName="textNoteSlashCommandsEnabled" label={t("editorfeatures.slash_commands_enabled")} description={t("editorfeatures.slash_commands_description")} />
</OptionsSection>
);
}

View File

@@ -1,6 +1,6 @@
{
"formatVersion": 2,
"appVersion": "0.99.2",
"appVersion": "0.99.3",
"files": [
{
"isClone": false,
@@ -2700,6 +2700,7 @@
}
],
"format": "html",
"dataFileName": "Note Types.html",
"attachments": [],
"dirFileName": "Note Types",
"children": [

View File

@@ -270,7 +270,7 @@
</li>
</ul>
</li>
<li>Note Types
<li><a href="root/Trilium%20Demo/Note%20Types.html" target="detail">Note Types</a>
<ul>
<li><a href="root/Trilium%20Demo/Note%20Types/Canvas.json" target="detail">Canvas</a>
</li>

View File

@@ -14,6 +14,7 @@
<div class="ck-content">
<h2>☑️ Tasks</h2>
<ul>
<li data-list-item-id="e4b26220d6ce48997f1116dc1d1d83dc0">[…]</li>
</ul>

View File

@@ -14,11 +14,10 @@
<div class="ck-content">
<figure class="image image-style-align-right image_resized" style="width:29.84%;">
<img style="aspect-ratio:150/150;" src="Trilium Demo_icon-color.svg" width="150"
height="150">
<img style="aspect-ratio:150/150;" src="Trilium Demo_icon-color.svg"
width="150" height="150">
</figure>
<p><strong>Welcome to Trilium Notes!</strong>
</p>
<p>This is a "demo" document packaged with Trilium to showcase some of its
features and also give you some ideas on how you might structure your notes.
@@ -26,22 +25,17 @@
you wish.</p>
<p>If you need any help, visit <a href="https://triliumnotes.org">triliumnotes.org</a> or
our <a href="https://github.com/TriliumNext">GitHub repository</a>
</p>
<h2>Cleanup</h2>
<p>Once you're finished with experimenting and want to cleanup these pages,
you can simply delete them all.</p>
<h2>Formatting</h2>
<p>Trilium supports classic formatting like <em>italic</em>, <strong>bold</strong>, <em><strong>bold and italic</strong></em>.
You can add links pointing to <a href="https://triliumnotes.org/">external pages</a> or&nbsp;
<a
class="reference-link" href="Trilium%20Demo/Formatting%20examples">Formatting examples</a>.</p>
<h3>Lists</h3>
<p><strong>Ordered:</strong>
</p>
<ol>
<li data-list-item-id="e877cc655d0239b8bb0f38696ad5d8abb">First Item</li>
@@ -56,7 +50,6 @@
</li>
</ol>
<p><strong>Unordered:</strong>
</p>
<ul>
<li data-list-item-id="e68bf4b518a16671c314a72073c3d900a">Item</li>
@@ -67,7 +60,6 @@
</li>
</ul>
<h3>Block quotes</h3>
<blockquote>
<p>Whereof one cannot speak, thereof one must be silent”</p>
<p> Ludwig Wittgenstein</p>
@@ -75,9 +67,9 @@
<hr>
<p>See also other examples like <a href="Trilium%20Demo/Formatting%20examples/School%20schedule.html">tables</a>,
<a
href="Trilium%20Demo/Formatting%20examples/Checkbox%20lists.html">checkbox lists,</a> <a href="Trilium%20Demo/Formatting%20examples/Highlighting.html">highlighting</a>,
href="Trilium%20Demo/Formatting%20examples/Checkbox%20lists.html">checkbox lists,</a> <a href="Trilium%20Demo/Formatting%20examples/Highlighting.html">highlighting</a>, <a href="Trilium%20Demo/Formatting%20examples/Code%20blocks.html">code blocks</a>and
<a
href="Trilium%20Demo/Formatting%20examples/Code%20blocks.html">code blocks</a>and <a href="Trilium%20Demo/Formatting%20examples/Math.html">math examples</a>.</p>
href="Trilium%20Demo/Formatting%20examples/Math.html">math examples</a>.</p>
</div>
</div>
</body>

View File

@@ -21,8 +21,12 @@
language, should that fail it is possible to manually adjust it. The color
scheme for the syntax highlighting is adjustable in settings.&nbsp;</p><pre><code class="language-application-javascript-env-frontend">function helloWorld() {
alert("Hello world");
}</code></pre>
<p>For larger pieces of code it is better to use a code note, which uses
a fully-fledged code editor (CodeMirror). For an example of a code note,

View File

@@ -0,0 +1,21 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../../style.css">
<base target="_parent">
<title data-trilium-title>Note Types</title>
</head>
<body>
<div class="content">
<h1 data-trilium-h1>Note Types</h1>
<div class="ck-content">
<p>T</p>
</div>
</div>
</body>
</html>

View File

@@ -13,9 +13,8 @@
<h1 data-trilium-h1>Task manager</h1>
<div class="ck-content">
<p>This is a simple TODO/Task manager. You can see some description and explanation
here: <a href="https://github.com/zadam/trilium/wiki/Task-manager">https://github.com/zadam/trilium/wiki/Task-manager</a>
</p>
<p>This is a simple TODO/Task manager. See the <a href="https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases/task-manager">Trilium documentation</a> for
information on how it works.</p>
<p>Please note that this is meant as scripting example only and feature/bug
support is very limited.</p>
</div>

View File

@@ -16,18 +16,32 @@
<p>Documentation: <a href="http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_02.html">http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_02.html</a>
</p><pre><code class="language-text-x-sh">#!/bin/bash
# This script opens 4 terminal windows.
i="0"
while [ $i -lt 4 ]
do
xterm &amp;
i=$[$i+1]
done</code></pre>
</div>
</div>

View File

@@ -17,6 +17,6 @@
},
"scripts": {
"edit-docs": "cross-env TRILIUM_PORT=37741 TRILIUM_DATA_DIR=data TRILIUM_INTEGRATION_TEST=memory-no-store DOCS_ROOT=../../../docs USER_GUIDE_ROOT=\"../../server/src/assets/doc_notes/en/User Guide\" tsx ../../scripts/electron-start.mts src/edit-docs.ts",
"edit-demo": "cross-env TRILIUM_PORT=37741 TRILIUM_DATA_DIR=data TRILIUM_INTEGRATION_TEST=memory-no-store DOCS_ROOT=../../../docs USER_GUIDE_ROOT=\"../../server/src/assets/doc_notes/en/User Guide\" tsx ../../scripts/electron-start.mts src/edit-demo.ts"
"edit-demo": "cross-env TRILIUM_PORT=37744 TRILIUM_DATA_DIR=data TRILIUM_INTEGRATION_TEST=memory-no-store DOCS_ROOT=../../../docs USER_GUIDE_ROOT=\"../../server/src/assets/doc_notes/en/User Guide\" tsx ../../scripts/electron-start.mts src/edit-demo.ts"
}
}

View File

@@ -67,7 +67,7 @@
"@types/xml2js": "0.4.14",
"archiver": "7.0.1",
"async-mutex": "0.5.0",
"axios": "1.13.1",
"axios": "1.13.2",
"bindings": "1.5.0",
"bootstrap": "5.3.8",
"chardet": "2.1.1",
@@ -110,12 +110,12 @@
"multer": "2.0.2",
"normalize-strings": "1.1.1",
"ollama": "0.6.2",
"openai": "6.7.0",
"openai": "6.8.0",
"rand-token": "1.0.1",
"safe-compare": "1.1.4",
"sanitize-filename": "1.6.3",
"sanitize-html": "2.17.0",
"sax": "1.4.1",
"sax": "1.4.3",
"serve-favicon": "2.5.1",
"stream-throttle": "0.1.3",
"strip-bom": "5.0.0",

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -19,8 +19,7 @@ class="image image_resized" style="width:74.04%;">
<img style="aspect-ratio:1911/997;" src="1_AI_image.png"
width="1911" height="997">
</figure>
<h2>Embeddings</h2>
<h2>Embeddings</h2>
<p><strong>Embeddings</strong> are important as it allows us to have an compact
AI “summary” (it's not human readable text) of each of your Notes, that
we can then perform mathematical functions on (such as cosine similarity)
@@ -36,7 +35,7 @@ class="image image_resized" style="width:74.04%;">
<p>To see what embedding models Ollama has available, you can check out
<a
href="https://ollama.com/search?c=embedding">this search</a>on their website, and then <code>pull</code> whichever one
you want to try out. As of 4/15/25, my personal favorite is <code>mxbai-embed-large</code>.</p>
you want to try out. A popular choice is <code>mxbai-embed-large</code>.</p>
<p>First, we'll need to select the Ollama provider from the tabs of providers,
then we will enter in the Base URL for our Ollama. Since our Ollama is
running on our local machine, our Base URL is <code>http://localhost:11434</code>.
@@ -80,59 +79,59 @@ class="image image_resized" style="width:74.04%;">
<p>These are the tools that currently exist, and will certainly be updated
to be more effectively (and even more to be added!):</p>
<ul>
<li><code>search_notes</code>
<li data-list-item-id="e56ad2313afb3f2f5162bcb3d9bf8e963"><code>search_notes</code>
<ul>
<li>Semantic search</li>
<li data-list-item-id="ee3b5cc2bd60f496e7919c63def713108">Semantic search</li>
</ul>
</li>
<li><code>keyword_search</code>
<li data-list-item-id="e9abe7bae428aff060dfc70ef669bd079"><code>keyword_search</code>
<ul>
<li>Keyword-based search</li>
<li data-list-item-id="ea8e2cece0d711e80eacfdb42e5d0edc3">Keyword-based search</li>
</ul>
</li>
<li><code>attribute_search</code>
<li data-list-item-id="e775735113778afe2073695881679540b"><code>attribute_search</code>
<ul>
<li>Attribute-specific search</li>
<li data-list-item-id="e64a93997e8ae8cc348e222f926866921">Attribute-specific search</li>
</ul>
</li>
<li><code>search_suggestion</code>
<li data-list-item-id="e58d04b2e226a143a8c8941337b04113a"><code>search_suggestion</code>
<ul>
<li>Search syntax helper</li>
<li data-list-item-id="e7c1ed076f0e0e3c242ca659276576860">Search syntax helper</li>
</ul>
</li>
<li><code>read_note</code>
<li data-list-item-id="e30741593cef85e71179301c280063bc2"><code>read_note</code>
<ul>
<li>Read note content (helps the LLM read Notes)</li>
<li data-list-item-id="e9c50f6fe0b4f013f16f9b32dbf6dbc92">Read note content (helps the LLM read Notes)</li>
</ul>
</li>
<li><code>create_note</code>
<li data-list-item-id="ec71fd71ce58b9d8338bc66e7c99ae1cb"><code>create_note</code>
<ul>
<li>Create a Note</li>
<li data-list-item-id="e0b0bae68b45bb0c27bc092145452ecd1">Create a Note</li>
</ul>
</li>
<li><code>update_note</code>
<li data-list-item-id="e7e816d84f52cf76096d2b5f1e4665989"><code>update_note</code>
<ul>
<li>Update a Note</li>
<li data-list-item-id="ed28fc8ca5a4753c1b680ee52d140940a">Update a Note</li>
</ul>
</li>
<li><code>manage_attributes</code>
<li data-list-item-id="e4580152b092501aa4fa87d1562b0f304"><code>manage_attributes</code>
<ul>
<li>Manage attributes on a Note</li>
<li data-list-item-id="ea0601e29b574cf0e4c40ae0e7d60bfa4">Manage attributes on a Note</li>
</ul>
</li>
<li><code>manage_relationships</code>
<li data-list-item-id="ecea045d4312b04ea06ac12802efb0544"><code>manage_relationships</code>
<ul>
<li>Manage the various relationships between Notes</li>
<li data-list-item-id="e3293a7c119de1a0eb2ddf8779a0b0d65">Manage the various relationships between Notes</li>
</ul>
</li>
<li><code>extract_content</code>
<li data-list-item-id="e483a2ef5f76d4da426c6059ddd3827a0"><code>extract_content</code>
<ul>
<li>Used to smartly extract content from a Note</li>
<li data-list-item-id="e1735854ab39d6d4e06a242bc2f80b839">Used to smartly extract content from a Note</li>
</ul>
</li>
<li><code>calendar_integration</code>
<li data-list-item-id="e11df70f4a6846bf881cb110c2950065f"><code>calendar_integration</code>
<ul>
<li>Used to find date notes, create date notes, get the daily note, etc.</li>
<li data-list-item-id="e0f1dfa6c5520bf02e125c1932b4f6e5e">Used to find date notes, create date notes, get the daily note, etc.</li>
</ul>
</li>
</ul>
@@ -145,17 +144,18 @@ class="image image_resized" style="width:74.04%;">
<p>You don't need to tell the LLM to execute a certain tool, it should “smartly”
call tools and automatically execute them as needed.</p>
<h2>Overview</h2>
<p>Now that you know about embeddings and tools, you can just go ahead and
use the “Chat with Notes” button, where you can go ahead and start chatting!:</p>
<figure
class="image image_resized" style="width:60.77%;">
<p>To start, simply press the <em>Chat with Notes</em> button in the&nbsp;
<a
class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/Vc8PjrjAGuOp/_help_xYmIYSP6wE3F">Launch Bar</a>.</p>
<figure class="image image_resized" style="width:60.77%;">
<img style="aspect-ratio:1378/539;" src="2_AI_image.png"
width="1378" height="539">
</figure>
<p>If you don't see the “Chat with Notes” button on your side launchbar,
you might need to move it from the Available Launchers section to the
Visible Launchers section:</p>
<figure class="image image_resized" style="width:69.81%;">
<img style="aspect-ratio:1765/1287;" src="9_AI_image.png"
width="1765" height="1287">
</figure>
</figure>
<p>If you don't see the button in the&nbsp;<a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/Vc8PjrjAGuOp/_help_xYmIYSP6wE3F">Launch Bar</a>,
you might need to move it from the <em>Available Launchers</em> section to
the <em>Visible Launchers</em> section:</p>
<figure class="image image_resized"
style="width:69.81%;">
<img style="aspect-ratio:1765/1287;" src="9_AI_image.png"
width="1765" height="1287">
</figure>

View File

@@ -8,7 +8,7 @@
<li>
<p><a class="reference-link" href="#root/_help_HI6GBBIduIgv">Labels</a>&nbsp;can
be used for a variety of purposes, such as storing metadata or configuring
the behaviour of notes. Labels are also searchable, enhancing note retrieval.</p>
the behavior of notes. Labels are also searchable, enhancing note retrieval.</p>
<p>For more information, including predefined labels, see&nbsp;<a class="reference-link"
href="#root/_help_HI6GBBIduIgv">Labels</a>.</p>
</li>
@@ -21,7 +21,7 @@
class="reference-link" href="#root/_help_Cq5X6iKQop6R">Relations</a>.</p>
</li>
</ol>
<p>These attributes play a crucial role in organizing, categorising, and
<p>These attributes play a crucial role in organizing, categorizing, and
enhancing the functionality of notes.</p>
<h2>Viewing the list of attributes</h2>
<p>Both the labels and relations for the current note are displayed in the <em>Owned Attributes</em> section

View File

@@ -11,7 +11,7 @@ const {secret, title, content} = req.body;
if (req.method == 'POST' &amp;&amp; secret === 'secret-password') {
// notes must be saved somewhere in the tree hierarchy specified by a parent note.
// This is defined by a relation from this code note to the "target" parent note
// alternetively you can just use constant noteId for simplicity (get that from "Note Info" dialog of the desired parent note)
// alternatively you can just use constant noteId for simplicity (get that from "Note Info" dialog of the desired parent note)
const targetParentNoteId = api.currentNote.getRelationValue('targetNote');
const {note} = api.createTextNote(targetParentNoteId, title, content);
@@ -30,7 +30,7 @@ else {
be saved</li>
</ul>
<h3>Explanation</h3>
<p>Let's test this by using an HTTP client to send a request:</p><pre><code class="language-text-x-trilium-auto">POST http://my.trilium.org/custom/create-note
<p>Let's test this by using an HTTP client to send a request:</p><pre><code class="language-text-x-trilium-auto">POST http://your-trilium-server/custom/create-note
Content-Type: application/json
{
@@ -64,12 +64,12 @@ Content-Type: application/json
can always look into its <a href="https://expressjs.com/en/api.html">documentation</a> for
details.</p>
<h3>Parameters</h3>
<p>REST request paths often contain parameters in the URL, e.g.:</p><pre><code class="language-text-x-trilium-auto">http://my.trilium.org/custom/notes/123</code></pre>
<p>REST request paths often contain parameters in the URL, e.g.:</p><pre><code class="language-text-x-trilium-auto">http://your-trilium-server/custom/notes/123</code></pre>
<p>The last part is dynamic so the matching of the URL must also be dynamic
- for this reason the matching is done with regular expressions. Following <code>customRequestHandler</code> value
would match it:</p><pre><code class="language-text-x-trilium-auto">notes/([0-9]+)</code></pre>
<p>Additionally, this also defines a matching group with the use of parenthesis
which then makes it easier to extract the value. The matched groups are
available in <code>api.pathParams</code>:</p><pre><code class="language-text-x-trilium-auto">const noteId = api.pathParams[0];</code></pre>
<p>Often you also need query params (as in e.g. <code>http://my.trilium.org/custom/notes?noteId=123</code>),
<p>Often you also need query params (as in e.g. <code>http://your-trilium-server/custom/notes?noteId=123</code>),
you can get those with standard express <code>req.query.noteId</code>.</p>

View File

@@ -0,0 +1,35 @@
<p>Nightly releases are versions built every day, containing the latest improvements
and bugfixes, directly from the main development branch. These versions
are generally useful in preparation for a release, to ensure that there
are no significant bugs that need to be addressed first, or they can be
used to confirm whether a particular bug is fixed or feature is well implemented.</p>
<h2>Regarding the stability</h2>
<p>Despite being on a development branch, generally the main branch is pretty
stable since PRs are tested before they are merged. If you notice any issues,
feel free to report them either via a ticket or via the Matrix.</p>
<h2>Downloading the nightly release manually</h2>
<p>Go to <a href="https://github.com/TriliumNext/Trilium/releases/tag/nightly">github.com/TriliumNext/Trilium/releases/tag/nightly</a> and
look for the artifacts starting with <code>TriliumNotes-main</code>. Choose
the appropriate one for your platform (e.g. <code>windows-x64.zip</code>).</p>
<p>Depending on your use case, you can either test the portable version or
even use the installer.</p>
<aside class="admonition note">
<p>If you choose the installable version (e.g. the .exe on Windows), it will
replace your stable installation.</p>
</aside>
<aside class="admonition important">
<p>By default, the nightly uses the same database as the production version.
Generally you could easily downgrade if needed. However, if there are changes
to the database or sync version, it will not be possible to downgrade without
having to restore from a backup.</p>
</aside>
<h2>Automatically download and install the latest nightly</h2>
<p>This is pretty useful if you are a beta tester that wants to periodically
update their version:</p>
<p>On Ubuntu:</p><pre><code class="language-text-x-trilium-auto">#!/usr/bin/env bash
name=TriliumNotes-linux-x64-nightly.deb
rm -f $name*
wget https://github.com/TriliumNext/Trilium/releases/download/nightly/$name
sudo apt-get install ./$name
rm $name</code></pre>

View File

@@ -0,0 +1,42 @@
<aside class="admonition warning">
<p>This functionality is still in preview, expect possible issues or even
the feature disappearing completely.
<br>Feel free to <a href="#root/pOsGYCXsbNQG/BgmBlOIl72jZ/_help_wy8So3yZZlH9">report</a> any
issues you might have.</p>
</aside>
<p>The read-only database is an alternative to&nbsp;<a class="reference-link"
href="#root/pOsGYCXsbNQG/tC7s2alapj8V/_help_R9pX4DGra2Vt">Sharing</a>&nbsp;notes.
Although the share functionality works pretty well to publish pages to
the Internet in a wiki, blog-like format it does not offer the full functionality
behind Trilium (such as the advanced&nbsp;<a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/wArbEsdSae6g/_help_eIg8jdvaoNNd">Search</a>&nbsp;or
the interactivity behind&nbsp;<a class="reference-link" href="#root/pOsGYCXsbNQG/_help_GTwFsgaA0lCt">Collections</a>&nbsp;or
the various&nbsp;<a class="reference-link" href="#root/pOsGYCXsbNQG/_help_KSZ04uQ2D1St">Note Types</a>).</p>
<p>When the database is in read-only mode, the Trilium application can be
used as normal, but editing is disabled and changes are made in-memory
only.</p>
<h2>What it does</h2>
<ul>
<li data-list-item-id="e97d71c2d01fa683d840e3f8de9e5bea9">All notes are read-only, without the possibility of editing them.</li>
<li
data-list-item-id="e6e82b25093f659cca922614ea8701ca4">Features that would normally alter the database such as the list of recent
notes are disabled.</li>
</ul>
<h2>Limitations</h2>
<ul>
<li data-list-item-id="ec1a648467ed42eee3d6b96f829b6daad">Some features might “slip through” and still end up creating a note, for
example.
<ul>
<li data-list-item-id="ed98de88bf24f574cfda28cf278be7f86">However, the database is still read-only, so all modifications will be
reset if the server is restarted.</li>
<li data-list-item-id="e3f0450830304fa98038a8a5fd9026b06">Whenever this occurs, <code>ERROR: read-only DB ignored</code> will be shown
in the logs.</li>
</ul>
</li>
</ul>
<h2>Setting a database as read-only</h2>
<p>First, make sure the database is initialized (e.g. the first set up is
complete). Then modify the <a href="#root/pOsGYCXsbNQG/tC7s2alapj8V/_help_Gzjqa934BdH4">config.ini</a> by
looking for the <code>[General]</code> section and adding a new <code>readOnly</code> field:</p><pre><code class="language-text-x-trilium-auto">[General]
readOnly=true</code></pre>
<p>If your server is already running, restart it to apply the changes.</p>
<p>Similarly, to disable read-only remove the line or set it to <code>false</code>.</p>

View File

@@ -4,12 +4,9 @@
script to enable it.</p>
<p>What it does:</p>
<ul>
<li data-list-item-id="e9c42a70a65d868a17df3413c17b7e6cf">Disables <code>customWidget</code> launcher types in <code>app/widgets/containers/launcher.js</code>.</li>
<li
data-list-item-id="ecd3fb5a4737b444e0c850eaea3877261">Disables the running of <code>mobileStartup</code> or <code>frontendStartup</code> scripts.</li>
<li
data-list-item-id="ea137da7a8e7ea33537b6ccf972a24728">Displays the root note instead of the previously saved session.</li>
<li
data-list-item-id="eae25286d35c9c22f543fddb8475d09aa">Disables the running of <code>backendStartup</code>, <code>hourly</code>, <code>daily</code> scripts
and checks for the hidden subtree.</li>
<li>Disables <code>customWidget</code> launcher types in <code>app/widgets/containers/launcher.js</code>.</li>
<li>Disables the running of <code>mobileStartup</code> or <code>frontendStartup</code> scripts.</li>
<li>Displays the root note instead of the previously saved session.</li>
<li>Disables the running of <code>backendStartup</code>, <code>hourly</code>, <code>daily</code> scripts
and checks for the hidden subtree.</li>
</ul>

View File

@@ -21,7 +21,7 @@
<ol>
<li>Set the text to search for in the <em>Search string</em> field.
<ol>
<li>Apart from searching for words ad-literam, there is also the possibility
<li>Apart from searching for words literally, there is also the possibility
to search for attributes or properties of notes.</li>
<li>See the examples below for more information.</li>
</ol>

View File

@@ -31,7 +31,7 @@
and you will see a list of all modified notes including the deleted ones.
Notes available for undeletion have a link to do so. This is kind of "trash
can" functionality known from e.g. Windows.</p>
<p>Clicking an undelete will recover the note, it's content and attributes
<p>Clicking an undelete will recover the note, its content and attributes
- note should be just as before being deleted. This action will also undelete
note's children which have been deleted in the same action.</p>
<p>To be able to undelete a note, it is necessary that deleted note's parent

View File

@@ -29,7 +29,7 @@
<li><em><strong>Editable</strong></em> changes whether the current note:
<ul>
<li>Enters <a href="#root/_help_CoFPLs3dRlXc">read-only mode</a> automatically if
the note is too big (default behaviour).</li>
the note is too big (default behavior).</li>
<li>Is always in read-only mode (however it can still be edited temporarily).</li>
<li>Is always editable, regardless of its size.</li>
</ul>

View File

@@ -1,5 +1,5 @@
<p>Collections are a unique type of notes that don't have a content, but
instead display its child notes in various presentation methods.</p>
<p>Collections are a unique type of note that don't have content, but instead
display their child notes in various presentation methods.</p>
<h2>Main collections</h2>
<table>
<thead>
@@ -94,7 +94,7 @@
in the&nbsp;<a class="reference-link" href="#root/_help_BlN9DFI679QC">Ribbon</a>.</p>
<h2>Archived notes</h2>
<p>By default, <a href="#root/_help_MKmLg5x6xkor">archived notes</a> will not be
shown in collections. This behaviour can be changed by going to <em>Collection Properties</em> in
shown in collections. This behavior can be changed by going to <em>Collection Properties</em> in
the&nbsp;<a class="reference-link" href="#root/_help_BlN9DFI679QC">Ribbon</a>&nbsp;and
checking <em>Show archived notes</em>.</p>
<p>Archived notes will be generally indicated by being greyed out as opposed

View File

@@ -1,12 +1,12 @@
<p>Data directory contains:</p>
<ul>
<li><code>document.db</code> - <a href="#root/_help_wX4HbRucYSDD">database</a>
<li data-list-item-id="e02c8e6918e645272972d94bf51bd34e1"><code>document.db</code> - <a href="#root/_help_wX4HbRucYSDD">database</a>
</li>
<li><code>config.ini</code> - instance level settings like port on which the
<li data-list-item-id="ee3b386f752a4d2de88a1362ff4bc447a"><code>config.ini</code> - instance level settings like port on which the
Trilium application runs</li>
<li><code>backup</code> - contains automatically <a href="#root/_help_ODY7qQn5m2FT">backup</a> of
<li data-list-item-id="e9acb98fe27a493914c7f61574b277d59"><code>backup</code> - contains automatically <a href="#root/_help_ODY7qQn5m2FT">backup</a> of
documents</li>
<li><code>log</code> - contains application log files</li>
<li data-list-item-id="e9f5de6d3c7f8d79710eb8c8e2ccac979"><code>log</code> - contains application log files</li>
</ul>
<h2>Location of the data directory</h2>
<p>Easy way how to find out which data directory Trilium uses is to look
@@ -18,30 +18,42 @@
<p>Data directory is normally named <code>trilium-data</code> and it is stored
in:</p>
<ul>
<li><code>/home/[user]/.local/share</code> for Linux</li>
<li><code>C:\Users\[user]\AppData\Roaming</code> for Windows Vista and up</li>
<li><code>/Users/[user]/Library/Application Support</code> for Mac OS</li>
<li>user's home is a fallback if some of the paths above don't exist</li>
<li>user's home is also a default setup for [[docker|Docker server installation]]</li>
<li data-list-item-id="e52706d339ce2332e73c5cfdc51edf81d"><code>/home/[user]/.local/share</code> for Linux</li>
<li data-list-item-id="e5709c767479c028d2ef60d17124ea924"><code>C:\Users\[user]\AppData\Roaming</code> for Windows Vista and up</li>
<li
data-list-item-id="eae590672aea8b24e625f372fb22d1f1b"><code>/Users/[user]/Library/Application Support</code> for Mac OS</li>
<li
data-list-item-id="e150ab7fc3c436d7cbac192acf3fe433f">user's home is a fallback if some of the paths above don't exist</li>
<li
data-list-item-id="e5f476ac39d8fa453e19b8399073a79d7">user's home is also a default setup for [[docker|Docker server installation]]</li>
</ul>
<p>If you want to back up your Trilium data, just backup this single directory
- it contains everything you need.</p>
<h3>Changing the location of data directory</h3>
<p>If you want to use some other location for the data directory than the
default one, you may change it via TRILIUM_DATA_DIR environment variable
to some other location:</p>
default one, you may change it via <code>TRILIUM_DATA_DIR</code> environment
variable to some other location:</p>
<h3>Windows</h3>
<ol>
<li data-list-item-id="e8597645795a4e5b079b8e2e4a772a7d7">Press the Windows key on your keyboard.</li>
<li data-list-item-id="ee32856df1db7c2d206baa480a672eeac">Search and select “Edit the system variables”.</li>
<li data-list-item-id="e08c7cdc0659b414465a07c78dfdaeb34">Press the “Environment Variables…” button in the bottom-right of the newly
opened screen.</li>
<li data-list-item-id="e6c7bae2590161a2661b6229c0853021c">On the top section ("User variables for [user]"), press the “New…” button.</li>
<li
data-list-item-id="effac7dc3976f17d309958dd3374cfa8d">In the <em>Variable name</em> field insert <code>TRILIUM_DATA_DIR</code>.</li>
<li
data-list-item-id="e3b74fdd03536563bb461e11111fae5ff">Press the <em>Browse Directory…</em> button and select the new directory
where to store the database.</li>
<li data-list-item-id="ed6df567f0fa772a14610b3904a0cb635">Close all the windows by pressing the <em>OK</em> button for each of them.</li>
</ol>
<h4>Linux</h4><pre><code class="language-text-x-trilium-auto">export TRILIUM_DATA_DIR=/home/myuser/data/my-trilium-data</code></pre>
<h4>Mac OS X</h4>
<p>You need to create a <code>.plist</code> file under <code>~/Library/LaunchAgents</code> to
load it properly each login.</p>
<p>To load it manually, you need to use <code>launchctl setenv TRILIUM_DATA_DIR &lt;yourpath&gt;</code>
</p>
<p>Here is a pre-defined template, where you just need to add your path to:</p><pre><code class="language-text-x-trilium-auto">
Label
<p>Here is a pre-defined template, where you just need to add your path to:</p><pre><code class="language-text-x-trilium-auto"> Label
set.trilium.env
RunAtLoad
@@ -50,76 +62,75 @@
launchctl
setenv
TRILIUM_DATA_DIR
/Users/YourUserName/Library/Application Support/trilium-data
</code></pre>
/Users/YourUserName/Library/Application Support/trilium-data </code></pre>
<h3>Create a script to run with specific data directory</h3>
<p>An alternative to globally setting environment variable is to run only
the Trilium Notes with this environment variable. This then allows for
different setup styles like two <a href="#root/_help_wX4HbRucYSDD">database</a> instances
or "portable" installation.</p>
<p>To do this in unix based systems simply run trilium like this:</p><pre><code class="language-text-x-trilium-auto">TRILIUM_DATA_DIR=/home/myuser/data/my-trilium-data trilium</code></pre>
<p>To do this in Unix-based systems simply run <code>trilium</code> like this:</p><pre><code class="language-text-x-trilium-auto">TRILIUM_DATA_DIR=/home/myuser/data/my-trilium-data trilium</code></pre>
<p>You can then save the above command as a shell script on your path for
convenience.</p>
<h2>Fine-grained directory/path location</h2>
<p>Apart from the data directory, some of the subdirectories of it can be
moved elsewhere by changing an environment variable:</p>
<table>
<thead>
<tr>
<th>Environment variable</th>
<th>Default value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>TRILIUM_DOCUMENT_PATH</code>
</td>
<td><code>${TRILIUM_DATA_DIR}/document.db</code>
</td>
<td>Path to the&nbsp;<a class="reference-link" href="#root/_help_wX4HbRucYSDD">Database</a>&nbsp;(storing
all notes and metadata).</td>
</tr>
<tr>
<td><code>TRILIUM_BACKUP_DIR</code>
</td>
<td><code>${TRILIUM_DATA_DIR}/backup</code>
</td>
<td>Directory where automated&nbsp;<a class="reference-link" href="#root/_help_ODY7qQn5m2FT">Backup</a>&nbsp;databases
are stored.</td>
</tr>
<tr>
<td><code>TRILIUM_LOG_DIR</code>
</td>
<td><code>${TRILIUM_DATA_DIR}/log</code>
</td>
<td>Directory where daily&nbsp;<a class="reference-link" href="#root/_help_bnyigUA2UK7s">Backend (server) logs</a>&nbsp;are
stored.</td>
</tr>
<tr>
<td><code>TRILIUM_TMP_DIR</code>
</td>
<td><code>${TRILIUM_DATA_DIR}/tmp</code>
</td>
<td>Directory where temporary files are stored (for example when opening in
an external app).</td>
</tr>
<tr>
<td><code>TRILIUM_ANONYMIZED_DB_DIR</code>
</td>
<td><code>${TRILIUM_DATA_DIR}/anonymized-db</code>
</td>
<td>Directory where a&nbsp;<a class="reference-link" href="#root/_help_x59R8J8KV5Bp">Anonymized Database</a>&nbsp;is
stored.</td>
</tr>
<tr>
<td><code>TRILIUM_CONFIG_INI_PATH</code>
</td>
<td><code>${TRILIUM_DATA_DIR}/config.ini</code>
</td>
<td>Path to&nbsp;<a class="reference-link" href="#root/_help_Gzjqa934BdH4">Configuration (config.ini or environment variables)</a>&nbsp;file.</td>
</tr>
</tbody>
</table>
<figure class="table">
<table>
<thead>
<tr>
<th>Environment variable</th>
<th>Default value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>TRILIUM_DOCUMENT_PATH</code>
</td>
<td><code>${TRILIUM_DATA_DIR}/document.db</code>
</td>
<td>Path to the&nbsp;<a class="reference-link" href="#root/_help_wX4HbRucYSDD">Database</a>&nbsp;(storing
all notes and metadata).</td>
</tr>
<tr>
<td><code>TRILIUM_BACKUP_DIR</code>
</td>
<td><code>${TRILIUM_DATA_DIR}/backup</code>
</td>
<td>Directory where automated&nbsp;<a class="reference-link" href="#root/_help_ODY7qQn5m2FT">Backup</a>&nbsp;databases
are stored.</td>
</tr>
<tr>
<td><code>TRILIUM_LOG_DIR</code>
</td>
<td><code>${TRILIUM_DATA_DIR}/log</code>
</td>
<td>Directory where daily&nbsp;<a class="reference-link" href="#root/_help_bnyigUA2UK7s">Backend (server) logs</a>&nbsp;are
stored.</td>
</tr>
<tr>
<td><code>TRILIUM_TMP_DIR</code>
</td>
<td><code>${TRILIUM_DATA_DIR}/tmp</code>
</td>
<td>Directory where temporary files are stored (for example when opening in
an external app).</td>
</tr>
<tr>
<td><code>TRILIUM_ANONYMIZED_DB_DIR</code>
</td>
<td><code>${TRILIUM_DATA_DIR}/anonymized-db</code>
</td>
<td>Directory where a&nbsp;<a class="reference-link" href="#root/_help_x59R8J8KV5Bp">Anonymized Database</a>&nbsp;is
stored.</td>
</tr>
<tr>
<td><code>TRILIUM_CONFIG_INI_PATH</code>
</td>
<td><code>${TRILIUM_DATA_DIR}/config.ini</code>
</td>
<td>Path to&nbsp;<a class="reference-link" href="#root/_help_Gzjqa934BdH4">Configuration (config.ini or environment variables)</a>&nbsp;file.</td>
</tr>
</tbody>
</table>
</figure>

View File

@@ -27,6 +27,6 @@
any startup scripts that might cause the application to crash.</li>
</ul>
<h2>Synchronization</h2>
<p>For Trilium desktp users who wish to synchronize their data with a server
<p>For Trilium desktop users who wish to synchronize their data with a server
instance, refer to the&nbsp;<a class="reference-link" href="#root/_help_cbkrhQjrkKrh">Synchronization</a>&nbsp;guide
for detailed instructions.</p>

View File

@@ -40,7 +40,7 @@
<h3>Disabling / Modifying the Upload Limit</h3>
<p>If you're running into the 250MB limit imposed on the server by default,
and you'd like to increase the upload limit, you can set the <code>TRILIUM_NO_UPLOAD_LIMIT</code> environment
variable to <code>true</code> disable it completely:</p><pre><code class="language-text-x-trilium-auto">export TRILIUM_NO_UPLOAD_LIMIT=true </code></pre>
variable to <code>true</code> to disable it completely:</p><pre><code class="language-text-x-trilium-auto">export TRILIUM_NO_UPLOAD_LIMIT=true </code></pre>
<p>Or, if you'd simply like to <em>increase</em> the upload limit size to something
beyond 250MB, you can set the <code>MAX_ALLOWED_FILE_SIZE_MB</code> environment
variable to something larger than the integer <code>250</code> (e.g. <code>450</code> in

View File

@@ -1,5 +1,5 @@
<p>One core features of Trilium is that it supports multiple types of notes,
depending on the need.</p>
<p>One of the core features of Trilium is that it supports multiple types
of notes, depending on the need.</p>
<h2>Creating a new note with a different type via the note tree</h2>
<p>The default note type in Trilium (e.g. when creating a new note) is&nbsp;
<a

View File

@@ -3,7 +3,7 @@
it. Special case is JavaScript code notes which can also be executed inside
Trilium which can in conjunction with&nbsp;<a class="reference-link" href="#root/_help_GLks18SNjxmC">Script API</a>&nbsp;provide
extra functionality.</p>
<h2>Scripting</h2>
<h2>Architecture Overview</h2>
<p>To go further I must explain basic architecture of Trilium - in its essence
it is a classic web application - it has these two main components:</p>
<ul>
@@ -14,8 +14,8 @@
</ul>
<p>So we have frontend and backend, each with their own set of responsibilities,
but their common feature is that they both run JavaScript code. Add to
this the fact, that we're able to create JavaScript [[code notes]] and
we're onto something.</p>
this the fact, that we're able to create JavaScript <a class="reference-link"
href="#root/_help_6f9hih2hXXZk">code notes</a> and we're onto something.</p>
<h2>Use cases</h2>
<ul>
<li><a class="reference-link" href="#root/_help_TjLYAo3JMO8X">"New Task" launcher button</a>

View File

@@ -0,0 +1,7 @@
<p>Older versions of Trilium Notes allowed the use of Common.js module imports
inside backend scripts, such as:</p><pre><code class="language-text-x-trilium-auto">const isBetween = require('dayjs/plugin/isBetween')
api.dayjs.extend(isBetween)</code></pre>
<p>For newer versions, Node.js imports are <strong>not officially supported anymore</strong>,
since we've added a bundler which makes it more difficult to reuse dependencies.</p>
<p>Theoretically it's still possible to use imports by manually setting up
a <code>node_modules</code> in the server directory via <code>npm</code> or <code>pnpm</code>.</p>

View File

@@ -0,0 +1,9 @@
<p>In <code>doRender()</code>:</p><pre><code class="language-text-x-trilium-auto">this.cssBlock(`#my-widget {
position: absolute;
bottom: 40px;
left: 60px;
z-index: 1;
}`)</code></pre>
<hr>
<p>Reference: <a href="https://trilium.rocks/X7pxYpiu0lgU">https://trilium.rocks/X7pxYpiu0lgU</a>
</p>

View File

@@ -0,0 +1,30 @@
<ul>
<li><code>doRender</code> must not be overridden, instead <code>doRenderBody()</code> has
to be overridden.</li>
<li><code>parentWidget()</code> must be set to <code>“rightPane”</code>.</li>
<li><code>widgetTitle()</code> getter can optionally be overriden, otherwise
the widget will be displayed as “Untitled widget”.</li>
</ul><pre><code class="language-text-x-trilium-auto">const template = `&lt;div&gt;Hi&lt;/div&gt;`;
class ToDoListWidget extends api.RightPanelWidget {
get widgetTitle() {
return "Title goes here";
}
get parentWidget() { return "right-pane" }
doRenderBody() {
this.$body.empty().append($(template));
}
async refreshWithNote(note) {
this.toggleInt(false);
this.triggerCommand("reEvaluateRightPaneVisibility");
this.toggleInt(true);
this.triggerCommand("reEvaluateRightPaneVisibility");
}
}
module.exports = new ToDoListWidget();</code></pre>
<p>The implementation is in <code>src/public/app/widgets/right_panel_widget.js</code>.</p>

View File

@@ -87,5 +87,17 @@ module.exports = new MyWidget();</code></pre>
}
module.exports = new MyWidget();</code></pre>
<p>Reload the application one last time. When you click the button, a "Hello
World!" message should appear, confirming that your widget is fully functional.</p>
<p><code>parentWidget()</code> can be given the following values:</p>
<ul>
<li><code>left-pane</code> - This renders the widget on the left side of the
screen where the note tree lives.</li>
<li><code>center-pane</code> - This renders the widget in the center of the
layout in the same location that notes and splits appear.</li>
<li><code>note-detail-pane</code> - This renders the widget <em>with</em> the
note in the center pane. This means it can appear multiple times with splits.</li>
<li><code>right-pane</code> - This renders the widget to the right of any opened
notes.</li>
</ul>
<p><a href="#root/_help_s8alTXmpFR61">Reload</a> the application one last time.
When you click the button, a "Hello World!" message should appear, confirming
that your widget is fully functional.</p>

View File

@@ -1,4 +1,5 @@
<p>As Trilium is currently in beta, encountering bugs is to be expected.</p>
<p>While Trilium is actively maintained and stable, encountering bugs is
possible.</p>
<h2>General Quick Fix</h2>
<p>The first step in troubleshooting is often a restart.</p>
<p>If you experience an UI issue, the frontend may have entered an inconsistent
@@ -15,7 +16,7 @@
variable to reset the open tabs to a single specified note ID (e.g., <code>root</code>).
In Linux, you can set it as follows:</p><pre><code class="language-text-x-trilium-auto">TRILIUM_START_NOTE_ID=root ./trilium</code></pre>
<h2>Broken Script Prevents Application Startup</h2>
<p>If a custom script causes Triliumto crash, and it is set as a startup
<p>If a custom script causes Trilium to crash, and it is set as a startup
script or in an active <a href="#root/_help_MgibgPcfeuGz">custom widget</a>, start
Triliumin "safe mode" to prevent any custom scripts from executing:</p><pre><code class="language-text-x-trilium-auto">TRILIUM_SAFE_MODE=true ./trilium</code></pre>
<p>Depending on your Trilium distribution, you may have pre-made scripts

View File

@@ -420,7 +420,7 @@
"end-time": "Ora di fine",
"geolocation": "Geolocalizzazione",
"built-in-templates": "Modelli integrati",
"board": "Tavola",
"board": "Kanban Board",
"status": "Stato",
"board_note_first": "Prima nota",
"board_note_second": "Seconda nota",

View File

@@ -417,7 +417,7 @@
"end-time": "結束時間",
"geolocation": "地理位置",
"built-in-templates": "內建模版",
"board": "儀表板",
"board": "板",
"status": "狀態",
"board_note_first": "第一個筆記",
"board_note_second": "第二個筆記",

View File

@@ -270,6 +270,38 @@ function setPrefix(req: Request) {
branch.save();
}
function setPrefixBatch(req: Request) {
const { branchIds, prefix } = req.body;
if (!Array.isArray(branchIds)) {
throw new ValidationError("branchIds must be an array");
}
// Validate that prefix is a string or null/undefined to prevent prototype pollution
if (prefix !== null && prefix !== undefined && typeof prefix !== 'string') {
throw new ValidationError("prefix must be a string or null");
}
const normalizedPrefix = utils.isEmptyOrWhitespace(prefix) ? null : prefix;
let updatedCount = 0;
for (const branchId of branchIds) {
const branch = becca.getBranch(branchId);
if (branch) {
branch.prefix = normalizedPrefix;
branch.save();
updatedCount++;
} else {
log.info(`Branch ${branchId} not found, skipping prefix update`);
}
}
return {
success: true,
count: updatedCount
};
}
export default {
moveBranchToParent,
moveBranchBeforeNote,
@@ -277,5 +309,6 @@ export default {
setExpanded,
setExpandedForSubtree,
deleteBranch,
setPrefix
setPrefix,
setPrefixBatch
};

View File

@@ -154,6 +154,7 @@ function register(app: express.Application) {
apiRoute(PUT, "/api/branches/:branchId/expanded-subtree/:expanded", branchesApiRoute.setExpandedForSubtree);
apiRoute(DEL, "/api/branches/:branchId", branchesApiRoute.deleteBranch);
apiRoute(PUT, "/api/branches/:branchId/set-prefix", branchesApiRoute.setPrefix);
apiRoute(PUT, "/api/branches/set-prefix-batch", branchesApiRoute.setPrefixBatch);
apiRoute(GET, "/api/notes/:noteId/attachments", attachmentsApiRoute.getAttachments);
apiRoute(PST, "/api/notes/:noteId/attachments", attachmentsApiRoute.saveAttachment);

View File

@@ -158,13 +158,11 @@ function startHttpServer(app: Express) {
// Not all situations require showing an error dialog. When Trilium is already open,
// clicking the shortcut, the software icon, or the taskbar icon, or when creating a new window,
// should simply focus on the existing window or open a new one, without displaying an error message.
if ("code" in error && error.code == "EADDRINUSE") {
if (process.argv.includes("--new-window") || !app.requestSingleInstanceLock()) {
console.error(message);
process.exit(1);
}
if ("code" in error && error.code === "EADDRINUSE" && (process.argv.includes("--new-window") || !app.requestSingleInstanceLock())) {
console.error(message);
} else {
dialog.showErrorBox("Error while initializing the server", message);
}
dialog.showErrorBox("Error while initializing the server", message);
process.exit(1);
});
} else {

View File

@@ -14,11 +14,11 @@
"preact": "10.27.2",
"preact-iso": "2.11.0",
"preact-render-to-string": "6.6.3",
"react-i18next": "16.2.3"
"react-i18next": "16.2.4"
},
"devDependencies": {
"@preact/preset-vite": "2.10.2",
"eslint": "9.39.0",
"eslint": "9.39.1",
"eslint-config-preact": "2.0.0",
"typescript": "5.9.3",
"user-agent-data-types": "0.4.2",

View File

@@ -70,7 +70,7 @@
"calendar_description": "Organizza i tuoi eventi personali o professionali utilizzando un calendario, con supporto per eventi di un giorno intero o di più giorni. Visualizza i tuoi eventi a colpo d'occhio con le viste settimanale, mensile e annuale. Interazione semplice per aggiungere o trascinare eventi.",
"table_title": "Tabella",
"table_description": "Visualizza e modifica le informazioni relative alle note in una struttura tabellare, con vari tipi di colonne quali testo, numeri, caselle di controllo, data e ora, collegamenti e colori, oltre al supporto per le relazioni. Facoltativamente, è possibile visualizzare le note all'interno di una gerarchia ad albero all'interno della tabella.",
"board_title": "Board",
"board_title": "Kanban Board",
"board_description": "Organizza le tue attività o lo stato dei tuoi progetti in una lavagna Kanban con un modo semplice per creare nuovi elementi e colonne e modificare facilmente il loro stato trascinandoli sulla lavagna.",
"geomap_title": "Geomappa",
"geomap_description": "Pianifica le tue vacanze o segna i tuoi punti di interesse direttamente su una mappa geografica utilizzando indicatori personalizzabili. Visualizza le tracce GPX registrate per seguire gli itinerari.",

View File

@@ -70,7 +70,7 @@
"calendar_description": "使用行事曆規劃個人或專業活動,支援全天及多日活動。透過週、月、年檢視模式,一覽所有活動。通過簡單互動即可新增或拖曳活動。",
"table_title": "表格",
"table_description": "以表格結構顯示並編輯筆記資訊,支援多種欄位類型,包括文字、數字、核取方塊、日期與時間、連結及顏色,並支援關聯功能。可選擇性地在表格內以樹狀層級結構顯示筆記內容。",
"board_title": "儀表板",
"board_title": "板",
"board_description": "將您的任務或專案狀態整理成看板,輕鬆建立新項目與欄位,並透過在看板上拖曳即可簡單變更狀態。",
"geomap_title": "地理地圖",
"geomap_description": "使用可自訂的標記直接在地圖上規劃您的假期行程或標記感興趣的地點。顯示已記錄的GPX軌跡以便追蹤行程路線。",

View File

@@ -10,7 +10,8 @@
"jsxImportSource": "preact",
"skipLibCheck": true,
"types": [
"vite/client"
"vite/client",
"vitest/config"
],
"paths": {
"react": ["../../node_modules/preact/compat/"],