diff --git a/apps/client/package.json b/apps/client/package.json
index f3341ba5c..cd1317e2b 100644
--- a/apps/client/package.json
+++ b/apps/client/package.json
@@ -55,7 +55,7 @@
"mark.js": "8.11.1",
"marked": "16.4.2",
"mermaid": "11.12.1",
- "mind-elixir": "5.3.5",
+ "mind-elixir": "5.3.6",
"normalize.css": "8.0.1",
"panzoom": "9.4.3",
"preact": "10.27.2",
diff --git a/apps/client/src/translations/ro/translation.json b/apps/client/src/translations/ro/translation.json
index 0f443bc53..b0e412b35 100644
--- a/apps/client/src/translations/ro/translation.json
+++ b/apps/client/src/translations/ro/translation.json
@@ -302,7 +302,10 @@
"edit_branch_prefix": "Editează prefixul ramurii",
"help_on_tree_prefix": "Informații despre prefixe de ierarhie",
"prefix": "Prefix: ",
- "save": "Salvează"
+ "save": "Salvează",
+ "edit_branch_prefix_multiple": "Editează prefixul pentru {{count}} ramuri",
+ "branch_prefix_saved_multiple": "Prefixul a fost modificat pentru {{count}} ramuri.",
+ "affected_branches": "Ramuri afectate ({{count}}):"
},
"bulk_actions": {
"affected_notes": "Notițe afectate",
@@ -537,7 +540,8 @@
"opml_version_1": "OPML v1.0 - text simplu",
"opml_version_2": "OPML v2.0 - permite și HTML",
"format_html": "HTML - recomandat deoarece păstrează toata formatarea",
- "format_pdf": "PDF - cu scopul de printare sau partajare."
+ "format_pdf": "PDF - cu scopul de printare sau partajare.",
+ "share-format": "HTML pentru publicare web - folosește aceeași temă pentru notițele partajate, dar se pot publica într-un website static."
},
"fast_search": {
"description": "Căutarea rapidă dezactivează căutarea la nivel de conținut al notițelor cu scopul de a îmbunătăți performanța de căutare pentru baze de date mari.",
@@ -753,7 +757,8 @@
"placeholder": "Introduceți etichetele HTML, câte unul pe linie",
"reset_button": "Resetează la lista implicită",
"title": "Etichete HTML la importare"
- }
+ },
+ "importZipRecommendation": "Când importați un fișier ZIP, ierarhia notițelor va reflecta structura subdirectoarelor din arhivă."
},
"include_archived_notes": {
"include_archived_notes": "Include notițele arhivate"
@@ -799,7 +804,8 @@
"default_description": "În mod implicit Trilium limitează lățimea conținutului pentru a îmbunătăți lizibilitatea pentru ferestrele maximizate pe ecrane late.",
"max_width_label": "Lungimea maximă a conținutului",
"max_width_unit": "pixeli",
- "title": "Lățime conținut"
+ "title": "Lățime conținut",
+ "centerContent": "Centrează conținutul"
},
"mobile_detail_menu": {
"delete_this_note": "Șterge această notiță",
@@ -856,7 +862,8 @@
"convert_into_attachment_failed": "Nu s-a putut converti notița „{{title}}”.",
"convert_into_attachment_successful": "Notița „{{title}}” a fost convertită în atașament.",
"convert_into_attachment_prompt": "Doriți convertirea notiței „{{title}}” într-un atașament al notiței părinte?",
- "print_pdf": "Exportare ca PDF..."
+ "print_pdf": "Exportare ca PDF...",
+ "open_note_on_server": "Deschide notița pe server"
},
"note_erasure_timeout": {
"deleted_notes_erased": "Notițele șterse au fost eliminate permanent.",
@@ -1246,11 +1253,11 @@
"timeout_unit": "milisecunde"
},
"table_of_contents": {
- "description": "Tabela de conținut va apărea în notițele de tip text atunci când notița are un număr de titluri mai mare decât cel definit. Acest număr se poate personaliza:",
+ "description": "Cuprinsul va apărea în notițele de tip text atunci când notița are un număr de titluri mai mare decât cel definit. Acest număr se poate personaliza:",
"unit": "titluri",
- "disable_info": "De asemenea se poate dezactiva tabela de conținut setând o valoare foarte mare.",
- "shortcut_info": "Se poate configura și o scurtatură pentru a comuta rapid vizibilitatea panoului din dreapta (inclusiv tabela de conținut) în Opțiuni -> Scurtături (denumirea „toggleRightPane”).",
- "title": "Tabelă de conținut"
+ "disable_info": "De asemenea se poate dezactiva cuprinsul setând o valoare foarte mare.",
+ "shortcut_info": "Se poate configura și o scurtatură pentru a comuta rapid vizibilitatea panoului din dreapta (inclusiv cuprinsul) în Opțiuni -> Scurtături (denumirea „toggleRightPane”).",
+ "title": "Cuprins"
},
"text_auto_read_only_size": {
"description": "Marchează pragul în care o notiță de o anumită dimensiune va fi afișată în mod de citire (pentru motive de performanță).",
@@ -1503,7 +1510,9 @@
"window-on-top": "Menține fereastra mereu vizibilă"
},
"note_detail": {
- "could_not_find_typewidget": "Nu s-a putut găsi widget-ul corespunzător tipului „{{type}}”"
+ "could_not_find_typewidget": "Nu s-a putut găsi widget-ul corespunzător tipului „{{type}}”",
+ "printing": "Imprimare în curs...",
+ "printing_pdf": "Exportare ca PDF în curs..."
},
"note_title": {
"placeholder": "introduceți titlul notiței aici..."
@@ -2014,7 +2023,8 @@
"new-item-placeholder": "Introduceți titlul notiței...",
"add-column-placeholder": "Introduceți denumirea coloanei...",
"edit-note-title": "Clic pentru a edita titlul notiței",
- "edit-column-title": "Clic pentru a edita titlul coloanei"
+ "edit-column-title": "Clic pentru a edita titlul coloanei",
+ "column-already-exists": "Această coloană deja există."
},
"command_palette": {
"tree-action-name": "Listă de notițe: {{name}}",
@@ -2076,5 +2086,14 @@
"edit-slide": "Editați acest slide",
"start-presentation": "Începeți prezentarea",
"slide-overview": "Afișați o imagine de ansamblu a slide-urilor"
+ },
+ "read-only-info": {
+ "read-only-note": "Vizualizați o notiță în modul doar în citire.",
+ "auto-read-only-note": "Această notiță este afișată în modul doar în citire din motive de performanță.",
+ "auto-read-only-learn-more": "Mai multe detalii",
+ "edit-note": "Editează notița"
+ },
+ "calendar_view": {
+ "delete_note": "Șterge notița..."
}
}
diff --git a/apps/client/src/widgets/collections/calendar/index.tsx b/apps/client/src/widgets/collections/calendar/index.tsx
index 6cae60f26..bac6862b2 100644
--- a/apps/client/src/widgets/collections/calendar/index.tsx
+++ b/apps/client/src/widgets/collections/calendar/index.tsx
@@ -91,6 +91,7 @@ export default function CalendarView({ note, noteIds }: ViewModeProps
Labels can be used for a variety of purposes, such as storing metadata or configuring the behavior of notes. Labels are also searchable, enhancing note retrieval.
For more information, including predefined labels, see Labels.
Relations define connections between notes, similar to links. These can be used for metadata and scripting purposes.
@@ -27,25 +27,24 @@Conceptually there are two types of attributes (applying to both labels and relations):
color attribute
will change the color of the note as displayed in the Note Tree and
- links, and iconClass will change the icon of a note.
- iconClass will
+ change the icon of a note.In practice, Trilium makes no direct distinction of whether an attribute
is a system one or a user-defined one. A label or relation is considered
a system attribute if it matches one of the built-in names (e.g. like the
aforementioned iconClass). Keep this in mind when creating
- Promoted Attributes in
+ Promoted Attributes in
order not to accidentally alter a system attribute (unless intended).
Both the labels and relations for the current note are displayed in the Owned Attributes section @@ -56,14 +55,13 @@
In the list of attributes, labels are prefixed with the # character
whereas relations are prefixed with the ~ character.
Promoted Attributes create +
Promoted Attributes create a form-like editing experience for attributes, which makes it easy to enhancing the organization and management of attributes
Attributes in Trilium can be "multi-valued", meaning multiple attributes with the same name can co-exist. This can be combined with Promoted Attributes to - easily add them.
+ href="#root/_help_OFXdgB2nNk1F">Promoted Attributes to easily add them.Trilium supports attribute inheritance, allowing child notes to inherit
attributes from their parents. For more information, see
The Attribute definition specifies how should this value be interpreted: To create a new promoted attribute: When a new promoted attribute definition is created, it creates a corresponding
@@ -54,37 +52,37 @@
The only purpose of the attribute definition is to set up a template.
If the attribute was marked as promoted, then it's also displayed to the
user for easy editing.
-
Creating a new promoted attribute definition
-
How attribute definitions actually work
-
-
-
-
-
-
- Notice how the promoted attribute definition only creates a “Due date”
- box above the text content.
-
-
-
-
-
-
- Once a value is set by the user, a new label (or relation, depending on
- the type) is created. The name of the attribute matches one set when creating
- the promoted attribute.
-
| + | + |
|---|---|
+
+ |
+ Notice how the promoted attribute definition only creates a “Due date” + box above the text content. | +
+
+ |
+ Once a value is set by the user, a new label (or relation, depending on + the type) is created. The name of the attribute matches one set when creating + the promoted attribute. | +
So there's one attribute for value and one for definition. But notice how an definition attribute can be made Inheritable, meaning that it's also applied to all descendant notes. In this case, the @@ -95,22 +93,22 @@ to be able to easily alter them.
Here are a few practical examples:
startDate which
are then interpreted by the calendar view.#shareAlias (see
Sharing) in order to form clean URLs.#color,
+ class="reference-link" href="#root/_help_R9pX4DGra2Vt">Sharing) in order to form clean URLs.#color,
simply create a promoted attribute for it to make it easier.#calendar:initialDate
+ #calendar:view
| - | - | - |
|---|---|---|
| 1 | -
-
- |
- Right click on any note on the note tree and select Insert child note → Geo Map (beta). | -
| 2 | -
-
- |
- By default the map will be empty and will show the entire world. | -
| + | + | + |
|---|---|---|
| 1 | +
+
+ |
+ Right click on any note on the note tree and select Insert child note → Geo Map (beta). | +
| 2 | +
+
+ |
+ By default the map will be empty and will show the entire world. | +
The position on the map and the zoom are saved inside the map note and restored when visiting again the note.
| - | - | - |
|---|---|---|
| 1 | -To create a marker, first navigate to the desired point on the map. Then
- press the
- button in the Floating buttons (top-right)
- area.
- - If the button is not visible, make sure the button section is visible - by pressing the chevron button ( - ) in the top-right of the map. |
- - |
| 2 | -
-
- |
- Once pressed, the map will enter in the insert mode, as illustrated by
- the notification.
- - Simply click the point on the map where to place the marker, or the Escape - key to cancel. |
-
| 3 | -
-
- |
- Enter the name of the marker/note to be created. | -
| 4 | -
-
- |
- Once confirmed, the marker will show up on the map and it will also be - displayed as a child note of the map. | -
| + | + | + |
|---|---|---|
| 1 | +To create a marker, first navigate to the desired point on the map. Then
+ press the
+ button in the Floating buttons (top-right)
+ area.
+ + If the button is not visible, make sure the button section is visible + by pressing the chevron button ( + ) in the top-right of the map. |
+ + |
| 2 | +
+
+ |
+ Once pressed, the map will enter in the insert mode, as illustrated by
+ the notification.
+ + Simply click the point on the map where to place the marker, or the Escape + key to cancel. |
+
| 3 | +
+
+ |
+ Enter the name of the marker/note to be created. | +
| 4 | +
+
+ |
+ Once confirmed, the marker will show up on the map and it will also be + displayed as a child note of the map. | +
This works for:
A more advanced use-case is grouping by Relations.
+A more advanced use-case is grouping by Relations.
During this mode:
Using relations instead of labels has some benefits:
To do so:
#viewType=board #hidePromotedAttributes to emulate the
- default template.#board:groupBy to the name of a relation to group by, including the ~ prefix (e.g. ~status).Optionally, use Promoted Attributes for - easy status change within the note:
#relation:status(inheritable)="promoted,alias=Status,single"
- First, create a Kanban board from scratch and not a template:
+Assign #viewType=board #hidePromotedAttributes to emulate the
+ default template.
Set #board:groupBy to the name of a relation to group by, including the **~** prefix (e.g. ~status).
Optionally, use Promoted Attributes for + easy status change within the note:
#relation:status(inheritable)="promoted,alias=Status,single"
+ /home/node/trilium-data)
For a complete list of configuration environment variables (network settings, - authentication, sync, etc.), see Configuration (config.ini or environment variables).
+ authentication, sync, etc.), see Configuration (config.ini or environment variables).If you encounter permission issues with the data volume, ensure that:
Configure Traefik proxy and HTTPS. See #7768 for + reference
+Setting up Traefik as reverse proxy requires setting the following labels:
labels:
+ - traefik.enable=true
+ - traefik.http.routers.trilium.entrypoints=https
+ - traefik.http.routers.trilium.rule=Host(`trilium.mydomain.tld`)
+ - traefik.http.routers.trilium.tls=true
+ - traefik.http.routers.trilium.service=trilium
+ - traefik.http.services.trilium.loadbalancer.server.port=8080
+ # scheme must be HTTP instead of the usual HTTPS because Trilium listens on HTTP internally
+ - traefik.http.services.trilium.loadbalancer.server.scheme=http
+ - traefik.docker.network=proxy
+ # forward HTTP to HTTPS
+ - traefik.http.routers.trilium.middlewares=trilium-headers@docker
+ - traefik.http.middlewares.trilium-headers.headers.customrequestheaders.X-Forwarded-Proto=https
+After setting up a reverse proxy, make sure to configure the [missing note].
+docker-compose.yamlservices:
+ trilium:
+ image: triliumnext/trilium
+ container_name: trilium
+ networks:
+ - traefik-proxy
+ environment:
+ - TRILIUM_NETWORK_TRUSTEDREVERSEPROXY=my-traefik-host-ip # e.g., 172.18.0.0/16
+ volumes:
+ - /path/to/data:/home/node/trilium-data
+ - /etc/timezone:/etc/timezone:ro
+ - /etc/localtime:/etc/localtime:ro
+ labels:
+ - traefik.enable=true
+ - traefik.http.routers.trilium.entrypoints=https
+ - traefik.http.routers.trilium.rule=Host(`trilium.mydomain.tld`)
+ - traefik.http.routers.trilium.tls=true
+ - traefik.http.routers.trilium.service=trilium
+ - traefik.http.services.trilium.loadbalancer.server.port=8080
+ # scheme must be HTTP instead of the usual HTTPS because of how trilium works
+ - traefik.http.services.trilium.loadbalancer.server.scheme=http
+ - traefik.docker.network=traefik-proxy
+ # Tell Trilium the original request was HTTPS
+ - traefik.http.routers.trilium.middlewares=trilium-headers@docker
+ - traefik.http.middlewares.trilium-headers.headers.customrequestheaders.X-Forwarded-Proto=https
+
+networks:
+ traefik-proxy:
+ external: true
\ No newline at end of file
diff --git a/apps/server/src/assets/translations/ro/server.json b/apps/server/src/assets/translations/ro/server.json
index 5ed87626d..248e44725 100644
--- a/apps/server/src/assets/translations/ro/server.json
+++ b/apps/server/src/assets/translations/ro/server.json
@@ -256,7 +256,9 @@
"multi-factor-authentication-title": "Autentificare multi-factor",
"ai-llm-title": "AI/LLM",
"localization": "Limbă și regiune",
- "inbox-title": "Inbox"
+ "inbox-title": "Inbox",
+ "command-palette": "Deschide paleta de comenzi",
+ "zen-mode": "Mod zen"
},
"notes": {
"new-note": "Notiță nouă",
@@ -274,7 +276,8 @@
"export_filter": "Document PDF (*.pdf)",
"unable-to-export-message": "Notița curentă nu a putut fi exportată ca PDF.",
"unable-to-export-title": "Nu s-a putut exporta ca PDF",
- "unable-to-save-message": "Nu s-a putut scrie fișierul selectat. Încercați din nou sau selectați altă destinație."
+ "unable-to-save-message": "Nu s-a putut scrie fișierul selectat. Încercați din nou sau selectați altă destinație.",
+ "unable-to-print": "Nu s-a putut imprima notița"
},
"tray": {
"bookmarks": "Semne de carte",
@@ -427,7 +430,8 @@
"presentation": "Prezentare",
"presentation_slide": "Slide de prezentare",
"presentation_slide_first": "Primul slide",
- "presentation_slide_second": "Al doilea slide"
+ "presentation_slide_second": "Al doilea slide",
+ "background": "Fundal"
},
"sql_init": {
"db_not_initialized_desktop": "Baza de date nu este inițializată, urmați instrucțiunile de pe ecran.",
diff --git a/apps/website/src/translations/ro/translation.json b/apps/website/src/translations/ro/translation.json
index 5cb462254..538ca10b6 100644
--- a/apps/website/src/translations/ro/translation.json
+++ b/apps/website/src/translations/ro/translation.json
@@ -51,7 +51,8 @@
"mermaid_description": "Creați diagrame precum flowchart-uri, diagrame de secvență sau de clase, Gantt și multe altele, folosind sintaxa Mermaid.",
"mindmap_title": "Hartă mentală",
"mindmap_description": "Organizați-vă gândurile vizual sau organizați o sesiune de brainstorming.",
- "others_list": "și altele: <0>hartă a notițelor0>, <1>hartă a relațiilor1>, <2>căutări salvate2>, <3>randare a notițelor3>, și <4>vizualizări web4>."
+ "others_list": "și altele: <0>hartă a notițelor0>, <1>hartă a relațiilor1>, <2>căutări salvate2>, <3>randare a notițelor3>, și <4>vizualizări web4>.",
+ "title": "Multiple modalități de a reprezenta informația"
},
"extensibility_benefits": {
"title": "Partajare și extensibilitate",
@@ -72,7 +73,10 @@
"board_title": "Tabelă Kanban",
"board_description": "Organizați-vă sarcinile sau proiectele într-o tabelă Kanban cu o modalitate ușoară de a adăuga elemente și coloane noi și schimbarea stării acestora prin glisare cu mouse-ul.",
"geomap_title": "Hartă geografică",
- "geomap_description": "Planificați-vă vacanțele sau marcați-vă punctele de interes direct pe o hartă geografică. Afișați traseele GPX înregistrate pentru a putea urmări itinerarii."
+ "geomap_description": "Planificați-vă vacanțele sau marcați-vă punctele de interes direct pe o hartă geografică. Afișați traseele GPX înregistrate pentru a putea urmări itinerarii.",
+ "title": "Colecții",
+ "presentation_title": "Prezentare",
+ "presentation_description": "Organizați informația în diapozitive și prezentați-le pe tot ecranul, cu tranziții fine. Diapozitivele pot fi ulterior exportate ca PDF pentru o partajare ușoară."
},
"faq": {
"title": "Întrebări frecvente",
diff --git a/docs/Developer Guide/!!!meta.json b/docs/Developer Guide/!!!meta.json
index cdf47264f..4d2ee2157 100644
--- a/docs/Developer Guide/!!!meta.json
+++ b/docs/Developer Guide/!!!meta.json
@@ -1961,6 +1961,13 @@
"isInheritable": false,
"position": 10
},
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "lXjOyKpUSKgE",
+ "isInheritable": false,
+ "position": 20
+ },
{
"type": "label",
"name": "iconClass",
@@ -2071,6 +2078,34 @@
"format": "markdown",
"dataFileName": "Server translations.md",
"attachments": []
+ },
+ {
+ "isClone": false,
+ "noteId": "lXjOyKpUSKgE",
+ "notePath": [
+ "jdjRLhLV3TtI",
+ "yeqU0zo0ZQ83",
+ "TLXJwBDo8Rdv",
+ "lXjOyKpUSKgE"
+ ],
+ "title": "Adding a new locale",
+ "notePosition": 40,
+ "prefix": null,
+ "isExpanded": false,
+ "type": "text",
+ "mime": "text/html",
+ "attributes": [
+ {
+ "type": "label",
+ "name": "shareAlias",
+ "value": "new-locale",
+ "isInheritable": false,
+ "position": 20
+ }
+ ],
+ "format": "markdown",
+ "dataFileName": "Adding a new locale.md",
+ "attachments": []
}
]
},
diff --git a/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translat.md b/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translat.md
index 7ae59016f..f420ff7ad 100644
--- a/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translat.md
+++ b/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translat.md
@@ -27,11 +27,7 @@ Follow the Adding a new locale.
### Changing the language
diff --git a/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translations/Adding a new locale.md b/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translations/Adding a new locale.md
new file mode 100644
index 000000000..e36815b90
--- /dev/null
+++ b/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translations/Adding a new locale.md
@@ -0,0 +1,11 @@
+# Adding a new locale
+Once the Weblate translations for a single language have reached ~50% in coverage, it's time to add it to the application.
+
+To do so:
+
+1. In `packages/commons` look for `i18n.ts` and add a new entry to `UNSORTED_LOCALES` for the language.
+2. In `apps/server` look for `services/i18n.ts` and add a mapping for the new language in `DAYJS_LOADER`. Sort the entire list.
+3. In `apps/client`, look for `collections/calendar/index.tsx` and modify `LOCALE_MAPPINGS` to add support to the new language.
+4. In `apps/client`, look for `widgets/type_widgets/canvas/i18n.ts` and modify `LANGUAGE_MAPPINGS`. A unit test ensures that the language is actually loadable.
+5. In `apps/client`, look for `widgets/type_widgets/MindMap.tsx` and modify `LOCALE_MAPPINGS`. The type definitions should already validate if the new value is supported by Mind Elixir.
+6. In `packages/ckeditor5`, look for `i18n.ts` and modify `LOCALE_MAPPINGS`. The import validation should already check if the new value is supported by CKEditor, and there's also a test to ensure it.
\ No newline at end of file
diff --git a/docs/Developer Guide/Developer Guide/Documentation.md b/docs/Developer Guide/Developer Guide/Documentation.md
index 5f9f17e5f..e0c8283ff 100644
--- a/docs/Developer Guide/Developer Guide/Documentation.md
+++ b/docs/Developer Guide/Developer Guide/Documentation.md
@@ -1,5 +1,5 @@
# Documentation
-There are multiple types of documentation for Trilium:
+There are multiple types of documentation for Trilium:
* The _User Guide_ represents the user-facing documentation. This documentation can be browsed by users directly from within Trilium, by pressing F1.
* The _Developer's Guide_ represents a set of Markdown documents that present the internals of Trilium, for developers.
diff --git a/docs/README-ro.md b/docs/README-ro.md
index 9842cb319..b2bcf8720 100644
--- a/docs/README-ro.md
+++ b/docs/README-ro.md
@@ -34,12 +34,13 @@ ecran](https://triliumnext.github.io/Docs/Wiki/screenshot-tour):
-## ⏬ Download
+## ⏬ Descarcă
- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) –
- stable version, recommended for most users.
-- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) –
- unstable development version, updated daily with the latest features and
- fixes.
+ versiune stabilă, recomandată pentru majoritatea utilizatorilor.
+- [Versiune
+ periodică](https://github.com/TriliumNext/Trilium/releases/tag/nightly) –
+ versiune pentru dezvoltare și testare, actualizată zilnic și cu ultimele
+ funcționalități și buguri reparate.
## 📚 Documentație
diff --git a/docs/User Guide/!!!meta.json b/docs/User Guide/!!!meta.json
index f859cd689..23097f166 100644
--- a/docs/User Guide/!!!meta.json
+++ b/docs/User Guide/!!!meta.json
@@ -681,6 +681,13 @@
"isInheritable": false,
"position": 20
},
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "Gzjqa934BdH4",
+ "isInheritable": false,
+ "position": 30
+ },
{
"type": "label",
"name": "shareAlias",
@@ -1044,6 +1051,35 @@
"format": "markdown",
"dataFileName": "Trusted proxy.md",
"attachments": []
+ },
+ {
+ "isClone": false,
+ "noteId": "5ERVJb9s4FRD",
+ "notePath": [
+ "pOsGYCXsbNQG",
+ "Otzi9La2YAUX",
+ "WOcw2SLH6tbX",
+ "vcjrb3VVYPZI",
+ "5ERVJb9s4FRD"
+ ],
+ "title": "Traefik",
+ "notePosition": 40,
+ "prefix": null,
+ "isExpanded": false,
+ "type": "text",
+ "mime": "text/html",
+ "attributes": [
+ {
+ "type": "label",
+ "name": "shareAlias",
+ "value": "traefik",
+ "isInheritable": false,
+ "position": 30
+ }
+ ],
+ "format": "markdown",
+ "dataFileName": "Traefik.md",
+ "attachments": []
}
]
},
@@ -9872,23 +9908,16 @@
"position": 10
},
{
- "type": "label",
- "name": "iconClass",
- "value": "bx bx-columns",
- "isInheritable": false,
- "position": 10
- },
- {
- "type": "label",
- "name": "shareAlias",
- "value": "kanban-board",
+ "type": "relation",
+ "name": "internalLink",
+ "value": "oPVyFC7WL2Lp",
"isInheritable": false,
"position": 20
},
{
"type": "relation",
"name": "internalLink",
- "value": "Cq5X6iKQop6R",
+ "value": "IakOLONlIfGI",
"isInheritable": false,
"position": 30
},
@@ -9902,23 +9931,30 @@
{
"type": "relation",
"name": "internalLink",
- "value": "bdUJEHsAPYQR",
+ "value": "Cq5X6iKQop6R",
"isInheritable": false,
"position": 50
},
{
"type": "relation",
"name": "internalLink",
- "value": "oPVyFC7WL2Lp",
+ "value": "bdUJEHsAPYQR",
"isInheritable": false,
"position": 60
},
{
- "type": "relation",
- "name": "internalLink",
- "value": "IakOLONlIfGI",
+ "type": "label",
+ "name": "iconClass",
+ "value": "bx bx-columns",
"isInheritable": false,
- "position": 70
+ "position": 10
+ },
+ {
+ "type": "label",
+ "name": "shareAlias",
+ "value": "kanban-board",
+ "isInheritable": false,
+ "position": 20
}
],
"format": "markdown",
@@ -9968,59 +10004,73 @@
{
"type": "relation",
"name": "internalLink",
- "value": "KSZ04uQ2D1St",
+ "value": "zEY4DaJG4YT5",
"isInheritable": false,
"position": 10
},
{
"type": "relation",
"name": "internalLink",
- "value": "0ESUbbAxVnoK",
+ "value": "OFXdgB2nNk1F",
"isInheritable": false,
"position": 20
},
{
"type": "relation",
"name": "internalLink",
- "value": "XpOYSgsLkTJy",
+ "value": "KSZ04uQ2D1St",
"isInheritable": false,
"position": 30
},
{
"type": "relation",
"name": "internalLink",
- "value": "oPVyFC7WL2Lp",
+ "value": "0ESUbbAxVnoK",
"isInheritable": false,
"position": 40
},
{
"type": "relation",
"name": "internalLink",
- "value": "IakOLONlIfGI",
+ "value": "XpOYSgsLkTJy",
"isInheritable": false,
"position": 50
},
{
"type": "relation",
"name": "internalLink",
- "value": "lgKX7r3aL30x",
+ "value": "oPVyFC7WL2Lp",
"isInheritable": false,
"position": 60
},
{
"type": "relation",
"name": "internalLink",
- "value": "ZjLYv08Rp3qC",
+ "value": "IakOLONlIfGI",
"isInheritable": false,
"position": 70
},
{
"type": "relation",
"name": "internalLink",
- "value": "BlN9DFI679QC",
+ "value": "lgKX7r3aL30x",
"isInheritable": false,
"position": 80
},
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "ZjLYv08Rp3qC",
+ "isInheritable": false,
+ "position": 90
+ },
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "BlN9DFI679QC",
+ "isInheritable": false,
+ "position": 100
+ },
{
"type": "label",
"name": "iconClass",
@@ -10034,20 +10084,6 @@
"value": "geomap",
"isInheritable": false,
"position": 90
- },
- {
- "type": "relation",
- "name": "internalLink",
- "value": "zEY4DaJG4YT5",
- "isInheritable": false,
- "position": 100
- },
- {
- "type": "relation",
- "name": "internalLink",
- "value": "OFXdgB2nNk1F",
- "isInheritable": false,
- "position": 110
}
],
"format": "markdown",
@@ -11240,24 +11276,45 @@
{
"type": "relation",
"name": "internalLink",
- "value": "BlN9DFI679QC",
+ "value": "oPVyFC7WL2Lp",
"isInheritable": false,
"position": 30
},
{
"type": "relation",
"name": "internalLink",
- "value": "OFXdgB2nNk1F",
+ "value": "eIg8jdvaoNNd",
"isInheritable": false,
"position": 40
},
{
"type": "relation",
"name": "internalLink",
- "value": "bwZpz2ajCEwO",
+ "value": "CdNpE2pqjmI6",
"isInheritable": false,
"position": 50
},
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "OFXdgB2nNk1F",
+ "isInheritable": false,
+ "position": 60
+ },
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "BlN9DFI679QC",
+ "isInheritable": false,
+ "position": 70
+ },
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "bwZpz2ajCEwO",
+ "isInheritable": false,
+ "position": 80
+ },
{
"type": "label",
"name": "shareAlias",
@@ -11271,27 +11328,6 @@
"value": "bx bx-list-check",
"isInheritable": false,
"position": 110
- },
- {
- "type": "relation",
- "name": "internalLink",
- "value": "oPVyFC7WL2Lp",
- "isInheritable": false,
- "position": 120
- },
- {
- "type": "relation",
- "name": "internalLink",
- "value": "eIg8jdvaoNNd",
- "isInheritable": false,
- "position": 130
- },
- {
- "type": "relation",
- "name": "internalLink",
- "value": "CdNpE2pqjmI6",
- "isInheritable": false,
- "position": 140
}
],
"format": "markdown",
@@ -11740,10 +11776,38 @@
{
"type": "relation",
"name": "internalLink",
- "value": "bwZpz2ajCEwO",
+ "value": "BlN9DFI679QC",
"isInheritable": false,
"position": 20
},
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "bwZpz2ajCEwO",
+ "isInheritable": false,
+ "position": 30
+ },
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "GTwFsgaA0lCt",
+ "isInheritable": false,
+ "position": 40
+ },
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "zP3PMqaG71Ct",
+ "isInheritable": false,
+ "position": 50
+ },
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "R9pX4DGra2Vt",
+ "isInheritable": false,
+ "position": 60
+ },
{
"type": "label",
"name": "shareAlias",
@@ -11757,34 +11821,6 @@
"value": "bx bx-table",
"isInheritable": false,
"position": 20
- },
- {
- "type": "relation",
- "name": "internalLink",
- "value": "BlN9DFI679QC",
- "isInheritable": false,
- "position": 50
- },
- {
- "type": "relation",
- "name": "internalLink",
- "value": "GTwFsgaA0lCt",
- "isInheritable": false,
- "position": 60
- },
- {
- "type": "relation",
- "name": "internalLink",
- "value": "zP3PMqaG71Ct",
- "isInheritable": false,
- "position": 70
- },
- {
- "type": "relation",
- "name": "internalLink",
- "value": "R9pX4DGra2Vt",
- "isInheritable": false,
- "position": 80
}
],
"format": "markdown",
diff --git a/docs/User Guide/User Guide/Collections/Calendar.md b/docs/User Guide/User Guide/Collections/Calendar.md
index 1499de851..82966739c 100644
--- a/docs/User Guide/User Guide/Collections/Calendar.md
+++ b/docs/User Guide/User Guide/Collections/Calendar.md
@@ -48,7 +48,7 @@ In the _Collections_ tab in the Configuration (config.ini or environment variables).
+For a complete list of configuration environment variables (network settings, authentication, sync, etc.), see Configuration (config.ini or environment variables).
### Volume Permissions
diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Traefik.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Traefik.md
new file mode 100644
index 000000000..1582093a4
--- /dev/null
+++ b/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Traefik.md
@@ -0,0 +1,60 @@
+# Traefik
+Configure Traefik proxy and HTTPS. See [#7768](https://github.com/TriliumNext/Trilium/issues/7768#issuecomment-3539165814) for reference
+
+### Build the docker-compose file
+
+Setting up Traefik as reverse proxy requires setting the following labels:
+
+```yaml
+ labels:
+ - traefik.enable=true
+ - traefik.http.routers.trilium.entrypoints=https
+ - traefik.http.routers.trilium.rule=Host(`trilium.mydomain.tld`)
+ - traefik.http.routers.trilium.tls=true
+ - traefik.http.routers.trilium.service=trilium
+ - traefik.http.services.trilium.loadbalancer.server.port=8080
+ # scheme must be HTTP instead of the usual HTTPS because Trilium listens on HTTP internally
+ - traefik.http.services.trilium.loadbalancer.server.scheme=http
+ - traefik.docker.network=proxy
+ # forward HTTP to HTTPS
+ - traefik.http.routers.trilium.middlewares=trilium-headers@docker
+ - traefik.http.middlewares.trilium-headers.headers.customrequestheaders.X-Forwarded-Proto=https
+```
+
+### Setup needed environment variables
+
+After setting up a reverse proxy, make sure to configure the [missing note].
+
+### Example `docker-compose.yaml`
+
+```yaml
+services:
+ trilium:
+ image: triliumnext/trilium
+ container_name: trilium
+ networks:
+ - traefik-proxy
+ environment:
+ - TRILIUM_NETWORK_TRUSTEDREVERSEPROXY=my-traefik-host-ip # e.g., 172.18.0.0/16
+ volumes:
+ - /path/to/data:/home/node/trilium-data
+ - /etc/timezone:/etc/timezone:ro
+ - /etc/localtime:/etc/localtime:ro
+ labels:
+ - traefik.enable=true
+ - traefik.http.routers.trilium.entrypoints=https
+ - traefik.http.routers.trilium.rule=Host(`trilium.mydomain.tld`)
+ - traefik.http.routers.trilium.tls=true
+ - traefik.http.routers.trilium.service=trilium
+ - traefik.http.services.trilium.loadbalancer.server.port=8080
+ # scheme must be HTTP instead of the usual HTTPS because of how trilium works
+ - traefik.http.services.trilium.loadbalancer.server.scheme=http
+ - traefik.docker.network=traefik-proxy
+ # Tell Trilium the original request was HTTPS
+ - traefik.http.routers.trilium.middlewares=trilium-headers@docker
+ - traefik.http.middlewares.trilium-headers.headers.customrequestheaders.X-Forwarded-Proto=https
+
+networks:
+ traefik-proxy:
+ external: true
+```
\ No newline at end of file
diff --git a/packages/ckeditor5/package.json b/packages/ckeditor5/package.json
index a97c1079b..cf2dc5fde 100644
--- a/packages/ckeditor5/package.json
+++ b/packages/ckeditor5/package.json
@@ -6,6 +6,7 @@
"type": "module",
"main": "./src/index.ts",
"dependencies": {
+ "@triliumnext/commons": "workspace:*",
"@triliumnext/ckeditor5-admonition": "workspace:*",
"@triliumnext/ckeditor5-footnotes": "workspace:*",
"@triliumnext/ckeditor5-keyboard-marker": "workspace:*",
diff --git a/packages/ckeditor5/src/i18n.ts b/packages/ckeditor5/src/i18n.ts
new file mode 100644
index 000000000..3053f4b7d
--- /dev/null
+++ b/packages/ckeditor5/src/i18n.ts
@@ -0,0 +1,90 @@
+import { DISPLAYABLE_LOCALE_IDS } from "@triliumnext/commons";
+import { EditorConfig, Translations } from "ckeditor5";
+
+interface LocaleMapping {
+ languageCode: string;
+ coreTranslation: () => Promise<{ default: Translations }>;
+ premiumFeaturesTranslation: () => Promise<{ default: Translations }>;
+}
+
+const LOCALE_MAPPINGS: Record