mirror of
https://github.com/zadam/trilium.git
synced 2025-10-31 18:36:30 +01:00
Merge branch 'develop' into date/time
This commit is contained in:
@@ -28,7 +28,7 @@
|
||||
where you can track your daily weight. This data is then used in <a href="#root/_help_R7abl2fc6Mxi">Weight tracker</a>.</p>
|
||||
<h2>Week Note and Quarter Note</h2>
|
||||
<p>Week and quarter notes are disabled by default, since it might be too
|
||||
much for some people. To enable them, you need to set <code>#enableWeekNotes</code> and <code>#enableQuarterNotes</code> attributes
|
||||
much for some people. To enable them, you need to set <code>#enableWeekNote</code> and <code>#enableQuarterNote</code> attributes
|
||||
on the root calendar note, which is identified by <code>#calendarRoot</code> label.
|
||||
Week note is affected by the first week of year option. Be careful when
|
||||
you already have some week notes created, it will not automatically change
|
||||
@@ -40,15 +40,26 @@
|
||||
(identified by <code>#calendarRoot</code> label):</p>
|
||||
<ul>
|
||||
<li>yearTemplate</li>
|
||||
<li>quarterTemplate (if <code>#enableQuarterNotes</code> is set)</li>
|
||||
<li>quarterTemplate (if <code>#enableQuarterNote</code> is set)</li>
|
||||
<li>monthTemplate</li>
|
||||
<li>weekTemplate (if <code>#enableWeekNotes</code> is set)</li>
|
||||
<li>weekTemplate (if <code>#enableWeekNote</code> is set)</li>
|
||||
<li>dateTemplate</li>
|
||||
</ul>
|
||||
<p>All of these are relations. When Trilium creates a new note for year or
|
||||
month or date, it will take a look at the root and attach a corresponding <code>~template</code> relation
|
||||
to the newly created role. Using this, you can e.g. create your daily template
|
||||
with e.g. checkboxes for daily routine etc.</p>
|
||||
<h3>Migrate from old template usage</h3>
|
||||
<p>If you have been using Journal prior to version v0.93.0, the previous
|
||||
template pattern likely used was <code>~child:template=</code>.
|
||||
<br>To transition to the new system:</p>
|
||||
<ol>
|
||||
<li>Set up the new template pattern in the Calendar root note.</li>
|
||||
<li>Use <a href="#root/_help_ivYnonVFBxbQ">Bulk Actions</a> to remove <code>child:template</code> and <code>child:child:template</code> from
|
||||
all notes under the Journal (calendar root).</li>
|
||||
<li>Ensure that all old template patterns are fully removed to prevent conflicts
|
||||
with the new setup.</li>
|
||||
</ol>
|
||||
<h2>Naming pattern</h2>
|
||||
<p>You can customize the title of generated journal notes by defining a <code>#datePattern</code>, <code>#weekPattern</code>, <code>#monthPattern</code>, <code>#quarterPattern</code> and <code>#yearPattern</code> attribute
|
||||
on a root calendar note (identified by <code>#calendarRoot</code> label).
|
||||
@@ -138,9 +149,4 @@
|
||||
<p>Trilium has some special support for day notes in the form of <a href="https://triliumnext.github.io/Notes/backend_api/BackendScriptApi.html">backend Script API</a> -
|
||||
see e.g. getDayNote() function.</p>
|
||||
<p>Day (and year, month) notes are created with a label - e.g. <code>#dateNote="2025-03-09"</code> this
|
||||
can then be used by other scripts to add new notes to day note etc.</p>
|
||||
<p>Journal also has relation <code>child:child:child:template=Day template</code> (see
|
||||
[[attribute inheritance]]) which effectively adds [[template]] to day notes
|
||||
(grand-grand-grand children of Journal). Please note that, when you enable
|
||||
week notes or quarter notes, it will not automatically change the relation
|
||||
for the child level.</p>
|
||||
can then be used by other scripts to add new notes to day note etc.</p>
|
||||
14
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Advanced Usage/Templates.html
generated
vendored
14
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Advanced Usage/Templates.html
generated
vendored
@@ -40,7 +40,19 @@
|
||||
you can also mark templates with <code>#workspaceTemplate</code> to display
|
||||
them only in the workspace.</p>
|
||||
<p>Templates can also be added or changed after note creation by creating
|
||||
a <code>~template</code> relation pointing to the desired template note.</p>
|
||||
a <code>~template</code> relation pointing to the desired template note. </p>
|
||||
<p>To specify a template for child notes, you can use a <code>~child:template</code> relation
|
||||
pointing to the appropriate template note. There is no limit to the depth
|
||||
of the hierarchy — you can use <code>~child:child:template</code>, <code>~child:child:child:template</code>,
|
||||
and so on.</p>
|
||||
<aside class="admonition important">
|
||||
<p>Changing the template hierarchy after the parent note is created will
|
||||
not retroactively apply to newly created child notes.
|
||||
<br>For example, if you initially use <code>~child:template</code> and later
|
||||
switch to <code>~child:child:template</code>, it will not automatically
|
||||
apply the new template to the grandchild notes. Only the structure present
|
||||
at the time of note creation is considered.</p>
|
||||
</aside>
|
||||
<h2>Additional Notes</h2>
|
||||
<p>From a visual perspective, templates can define <code>#iconClass</code> and <code>#cssClass</code> attributes,
|
||||
allowing all instance notes (e.g., books) to display a specific icon and
|
||||
|
||||
@@ -65,8 +65,16 @@ function load() {
|
||||
new BEtapiToken(row);
|
||||
}
|
||||
|
||||
for (const row of sql.getRows<NoteEmbeddingRow>(/*sql*/`SELECT embedId, noteId, providerId, modelId, dimension, embedding, version, dateCreated, dateModified, utcDateCreated, utcDateModified FROM note_embeddings`)) {
|
||||
new BNoteEmbedding(row).init();
|
||||
try {
|
||||
for (const row of sql.getRows<NoteEmbeddingRow>(/*sql*/`SELECT embedId, noteId, providerId, modelId, dimension, embedding, version, dateCreated, dateModified, utcDateCreated, utcDateModified FROM note_embeddings`)) {
|
||||
new BNoteEmbedding(row).init();
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
if (e && typeof e === "object" && "message" in e && typeof e.message === "string" && e.message.includes("no such table")) {
|
||||
// Can be ignored.
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ import { initializeTranslations } from "./services/i18n.js";
|
||||
|
||||
async function startApplication() {
|
||||
await initializeTranslations();
|
||||
await import("./www.js");
|
||||
const startTriliumServer = (await import("./www.js")).default;
|
||||
await startTriliumServer();
|
||||
}
|
||||
|
||||
startApplication();
|
||||
|
||||
@@ -266,7 +266,7 @@ function getMonthNote(dateStr: string, _rootNote: BNote | null = null): BNote {
|
||||
return monthNote;
|
||||
}
|
||||
|
||||
let monthParentNote;
|
||||
let monthParentNote: BNote | null;
|
||||
|
||||
if (rootNote.hasLabel("enableQuarterNote")) {
|
||||
monthParentNote = getQuarterNote(getQuarterNumberStr(dayjs(dateStr)), rootNote);
|
||||
@@ -296,7 +296,7 @@ function getMonthNote(dateStr: string, _rootNote: BNote | null = null): BNote {
|
||||
|
||||
function getWeekStartDate(date: Dayjs): Dayjs {
|
||||
const day = date.day();
|
||||
let diff;
|
||||
let diff: number;
|
||||
|
||||
if (optionService.getOption("firstDayOfWeek") === "0") { // Sunday
|
||||
diff = date.date() - day + (day === 0 ? -6 : 1); // adjust when day is sunday
|
||||
@@ -456,7 +456,7 @@ function getDayNote(dateStr: string, _rootNote: BNote | null = null): BNote {
|
||||
return dateNote;
|
||||
}
|
||||
|
||||
let dateParentNote;
|
||||
let dateParentNote: BNote | null;
|
||||
|
||||
if (rootNote.hasLabel("enableWeekNote")) {
|
||||
dateParentNote = getWeekNote(getWeekNumberStr(dayjs(dateStr)), rootNote);
|
||||
|
||||
@@ -16,5 +16,5 @@ describe("Migration", () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
}, 60_000);
|
||||
});
|
||||
|
||||
@@ -25,10 +25,12 @@ async function migrate() {
|
||||
}
|
||||
|
||||
// backup before attempting migration
|
||||
await backupService.backupNow(
|
||||
// creating a special backup for version 0.60.4, the changes in 0.61 are major.
|
||||
currentDbVersion === 214 ? `before-migration-v060` : "before-migration"
|
||||
);
|
||||
if (!process.env.TRILIUM_INTEGRATION_TEST) {
|
||||
await backupService.backupNow(
|
||||
// creating a special backup for version 0.60.4, the changes in 0.61 are major.
|
||||
currentDbVersion === 214 ? `before-migration-v060` : "before-migration"
|
||||
);
|
||||
}
|
||||
|
||||
const migrations = await prepareMigrations(currentDbVersion);
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ function deriveMime(type: string, mime?: string) {
|
||||
function copyChildAttributes(parentNote: BNote, childNote: BNote) {
|
||||
for (const attr of parentNote.getAttributes()) {
|
||||
if (attr.name.startsWith("child:")) {
|
||||
const name = attr.name.substr(6);
|
||||
const name = attr.name.substring(6);
|
||||
const hasAlreadyTemplate = childNote.hasRelation("template");
|
||||
|
||||
if (hasAlreadyTemplate && attr.type === "relation" && name === "template") {
|
||||
@@ -472,7 +472,7 @@ async function downloadImage(noteId: string, imageUrl: string) {
|
||||
|
||||
if (imageUrl.toLowerCase().startsWith("file://")) {
|
||||
imageBuffer = await new Promise((res, rej) => {
|
||||
const localFilePath = imageUrl.substr("file://".length);
|
||||
const localFilePath = imageUrl.substring("file://".length);
|
||||
|
||||
return fs.readFile(localFilePath, (err, data) => {
|
||||
if (err) {
|
||||
@@ -521,14 +521,14 @@ function downloadImages(noteId: string, content: string) {
|
||||
const inlineImageMatch = /^data:image\/[a-z]+;base64,/.exec(url);
|
||||
|
||||
if (inlineImageMatch) {
|
||||
const imageBase64 = url.substr(inlineImageMatch[0].length);
|
||||
const imageBase64 = url.substring(inlineImageMatch[0].length);
|
||||
const imageBuffer = Buffer.from(imageBase64, "base64");
|
||||
|
||||
const attachment = imageService.saveImageToAttachment(noteId, imageBuffer, "inline image", true, true);
|
||||
|
||||
const encodedTitle = encodeURIComponent(attachment.title);
|
||||
|
||||
content = `${content.substr(0, imageMatch.index)}<img src="api/attachments/${attachment.attachmentId}/image/${encodedTitle}"${content.substr(imageMatch.index + imageMatch[0].length)}`;
|
||||
content = `${content.substring(0, imageMatch.index)}<img src="api/attachments/${attachment.attachmentId}/image/${encodedTitle}"${content.substring(imageMatch.index + imageMatch[0].length)}`;
|
||||
} else if (
|
||||
!url.includes("api/images/") &&
|
||||
!/api\/attachments\/.+\/image\/?.*/.test(url) &&
|
||||
@@ -631,7 +631,7 @@ function saveAttachments(note: BNote, content: string) {
|
||||
content: buffer
|
||||
});
|
||||
|
||||
content = `${content.substr(0, attachmentMatch.index)}<a class="reference-link" href="#root/${note.noteId}?viewMode=attachments&attachmentId=${attachment.attachmentId}">${title}</a>${content.substr(attachmentMatch.index + attachmentMatch[0].length)}`;
|
||||
content = `${content.substring(0, attachmentMatch.index)}<a class="reference-link" href="#root/${note.noteId}?viewMode=attachments&attachmentId=${attachment.attachmentId}">${title}</a>${content.substring(attachmentMatch.index + attachmentMatch[0].length)}`;
|
||||
}
|
||||
|
||||
// removing absolute references to server to keep it working between instances,
|
||||
|
||||
@@ -14,37 +14,35 @@ import type { Express } from "express";
|
||||
|
||||
const MINIMUM_NODE_VERSION = "20.0.0";
|
||||
|
||||
// setup basic error handling even before requiring dependencies, since those can produce errors as well
|
||||
export default async function startTriliumServer() {
|
||||
// setup basic error handling even before requiring dependencies, since those can produce errors as well
|
||||
process.on("unhandledRejection", (error: Error) => {
|
||||
// this makes sure that stacktrace of failed promise is printed out
|
||||
console.log(error);
|
||||
|
||||
process.on("unhandledRejection", (error: Error) => {
|
||||
// this makes sure that stacktrace of failed promise is printed out
|
||||
console.log(error);
|
||||
// but also try to log it into file
|
||||
log.info(error);
|
||||
});
|
||||
|
||||
// but also try to log it into file
|
||||
log.info(error);
|
||||
});
|
||||
function exit() {
|
||||
console.log("Caught interrupt/termination signal. Exiting.");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
function exit() {
|
||||
console.log("Caught interrupt/termination signal. Exiting.");
|
||||
process.exit(0);
|
||||
}
|
||||
process.on("SIGINT", exit);
|
||||
process.on("SIGTERM", exit);
|
||||
|
||||
process.on("SIGINT", exit);
|
||||
process.on("SIGTERM", exit);
|
||||
if (utils.compareVersions(process.versions.node, MINIMUM_NODE_VERSION) < 0) {
|
||||
console.error();
|
||||
console.error(`The Trilium server requires Node.js ${MINIMUM_NODE_VERSION} and later in order to start.\n`);
|
||||
console.error(`\tCurrent version:\t${process.versions.node}`);
|
||||
console.error(`\tExpected version:\t${MINIMUM_NODE_VERSION}`);
|
||||
console.error();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (utils.compareVersions(process.versions.node, MINIMUM_NODE_VERSION) < 0) {
|
||||
console.error();
|
||||
console.error(`The Trilium server requires Node.js ${MINIMUM_NODE_VERSION} and later in order to start.\n`);
|
||||
console.error(`\tCurrent version:\t${process.versions.node}`);
|
||||
console.error(`\tExpected version:\t${MINIMUM_NODE_VERSION}`);
|
||||
console.error();
|
||||
process.exit(1);
|
||||
}
|
||||
tmp.setGracefulCleanup();
|
||||
|
||||
tmp.setGracefulCleanup();
|
||||
startTrilium();
|
||||
|
||||
async function startTrilium() {
|
||||
const app = await buildApp();
|
||||
|
||||
/**
|
||||
@@ -98,7 +96,7 @@ function startHttpServer(app: Express) {
|
||||
|
||||
log.info(`Trusted reverse proxy: ${app.get("trust proxy")}`);
|
||||
|
||||
let httpServer;
|
||||
let httpServer: http.Server | https.Server;
|
||||
|
||||
if (config["Network"]["https"]) {
|
||||
if (!config["Network"]["keyPath"] || !config["Network"]["keyPath"].trim().length) {
|
||||
|
||||
Reference in New Issue
Block a user