mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	feat(docs): improve documentation for code notes, code blocks
This commit is contained in:
		
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 68 KiB | 
| @@ -1,5 +1,5 @@ | ||||
| # Advanced Showcases | ||||
| Trilium offers advanced functionality through [Scripts](Code%20Notes/Scripts.md) and [Promoted Attributes](Attributes/Promoted%20Attributes.md). To illustrate these features, we've prepared several showcases available in the [demo notes](Database.md): | ||||
| Trilium offers advanced functionality through [Scripts](../Note%20Types/Code/Scripts.md) and [Promoted Attributes](Attributes/Promoted%20Attributes.md). To illustrate these features, we've prepared several showcases available in the [demo notes](Database.md): | ||||
|  | ||||
| *   [Relation Map](Relation%20Map.md) | ||||
| *   [Day Notes](Advanced%20Showcases/Day%20Notes.md) | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| # Task Manager | ||||
| Task Manager is a [promoted attributes](../Attributes/Promoted%20Attributes.md) and [scripts](../Code%20Notes/Scripts.md)showcase present in the [demo notes](../Database.md). | ||||
| Task Manager is a [promoted attributes](../Attributes/Promoted%20Attributes.md) and [scripts](../../Note%20Types/Code/Scripts.md)showcase present in the [demo notes](../Database.md). | ||||
|  | ||||
| ## Demo | ||||
|  | ||||
| @@ -15,7 +15,7 @@ New tasks are created in the TODO note which has `~child:template` [relation](.. | ||||
|  | ||||
| ### Attributes | ||||
|  | ||||
| Task template defines several [promoted attributes](../Attributes/Promoted%20Attributes.md) - todoDate, doneDate, tags, location. Importantly it also defines `~runOnAttributeChange` relation - [event](../Code%20Notes/Events.md) handler which is run on attribute change. This [script](../Code%20Notes/Scripts.md) handles when e.g. we fill out the doneDate attribute - meaning the task is done and should be moved to "Done" note and removed from TODO, locations and tags. | ||||
| Task template defines several [promoted attributes](../Attributes/Promoted%20Attributes.md) - todoDate, doneDate, tags, location. Importantly it also defines `~runOnAttributeChange` relation - [event](../../Note%20Types/Code/Events.md) handler which is run on attribute change. This [script](../../Note%20Types/Code/Scripts.md) handles when e.g. we fill out the doneDate attribute - meaning the task is done and should be moved to "Done" note and removed from TODO, locations and tags. | ||||
|  | ||||
| ### New task button | ||||
|  | ||||
| @@ -46,7 +46,7 @@ api.addButtonToToolbar({ | ||||
|  | ||||
| In the demo screenshot above you may notice that TODO tasks are in red color and DONE tasks are green. | ||||
|  | ||||
| This is done by having this CSS [code note](../Code%20Notes.md) which defines extra CSS classes: | ||||
| This is done by having this CSS [code note](../../Note%20Types/Code.md) which defines extra CSS classes: | ||||
|  | ||||
| ``` | ||||
| span.fancytree-node.todo .fancytree-title { | ||||
| @@ -58,6 +58,6 @@ span.fancytree-node.done .fancytree-title { | ||||
| } | ||||
| ``` | ||||
|  | ||||
| This [code note](../Code%20Notes.md) has `#appCss` [label](../Attributes.md)which is recognized by Trilium on startup and loaded as CSS into the application. | ||||
| This [code note](../../Note%20Types/Code.md) has `#appCss` [label](../Attributes.md)which is recognized by Trilium on startup and loaded as CSS into the application. | ||||
|  | ||||
| Second part of this functionality is based in event handler described above which assigns `#cssClass` label to the task to either "done" or "todo" based on the task status. | ||||
| @@ -1,21 +1,21 @@ | ||||
| # Weight Tracker | ||||
|  | ||||
|  | ||||
| The `Weight Tracker` is a [Script API](../Code%20Notes/Script%20API.md) showcase present in the [demo notes](../Database.md). | ||||
| The `Weight Tracker` is a [Script API](../../Note%20Types/Code/Script%20API.md) showcase present in the [demo notes](../Database.md). | ||||
|  | ||||
| By adding `weight` as a [promoted attribute](../Attributes/Promoted%20Attributes.md) in the [template](../Attributes/Template.md) from which [day notes](Day%20Notes.md) are created, you can aggregate the data and plot weight change over time. | ||||
|  | ||||
| ## Implementation | ||||
|  | ||||
| The `Weight Tracker` note in the screenshot above is of the type `Render Note`. That type of note doesn't have any useful content itself. Instead it is a placeholder where a [script](../Code%20Notes/Scripts.md) can render its output. | ||||
| The `Weight Tracker` note in the screenshot above is of the type `Render Note`. That type of note doesn't have any useful content itself. Instead it is a placeholder where a [script](../../Note%20Types/Code/Scripts.md) can render its output. | ||||
|  | ||||
| Scripts for `Render Notes` are defined in a [relation](../Attributes.md) called `~renderNote`. In this example, it's the `Weight Tracker`'s child `Implementation`. The Implementation consists of two [code notes](../Code%20Notes.md) that contain some HTML and JavaScript respectively, which load all the notes with a `weight` attribute and display their values in a chart. | ||||
| Scripts for `Render Notes` are defined in a [relation](../Attributes.md) called `~renderNote`. In this example, it's the `Weight Tracker`'s child `Implementation`. The Implementation consists of two [code notes](../../Note%20Types/Code.md) that contain some HTML and JavaScript respectively, which load all the notes with a `weight` attribute and display their values in a chart. | ||||
|  | ||||
| To actually render the chart, we're using a third party library called [chart.js](https://www.chartjs.org/)which is imported as an attachment, since it's not built into Trilium. | ||||
|  | ||||
| ### Code | ||||
|  | ||||
| Here's the content of the script which is placed in a [code note](../Code%20Notes.md) of type `JS Frontend`: | ||||
| Here's the content of the script which is placed in a [code note](../../Note%20Types/Code.md) of type `JS Frontend`: | ||||
|  | ||||
| ``` | ||||
| async function getChartData() { | ||||
|   | ||||
| @@ -1,21 +0,0 @@ | ||||
| # Code Notes | ||||
| Trilium supports creating "code" notes, i.e. notes which contain some sort of formal code - be it programming language (C++, JavaScript), structured data (JSON, XML) or other types of codes (CSS etc.). | ||||
|  | ||||
| This can be useful for a few things: | ||||
|  | ||||
| *   computer programmers can store code snippets as notes with syntax highlighting | ||||
| *   JavaScript code notes can be executed inside Trilium for some extra functionality | ||||
|     *   we call such JavaScript code notes "scripts" - see [Scripts](Code%20Notes/Scripts.md) | ||||
| *   JSON, XML etc. can be used as storage for structured data (typically used in conjunction with scripting) | ||||
|  | ||||
|  | ||||
|  | ||||
| ## Extra languages | ||||
|  | ||||
| Trilium supports syntax highlighting for many languages, but by default displays only some of them (to reduce the number of items). You can add extra languages in Options -> Code notes. | ||||
|  | ||||
| ## Code blocks | ||||
|  | ||||
| An alternative to the code note is a "code block" - feature of a text note which can add short snippets of code to the text editor. Starting with TriliumNext v0.90.12, the code blocks also support syntax highlighting. | ||||
|  | ||||
|  | ||||
| @@ -1,96 +0,0 @@ | ||||
| # Custom Widgets | ||||
| It's possible to create custom widget in three possible locations where you can display your custom content. | ||||
|  | ||||
| Positions are: | ||||
|  | ||||
| *   `left-pane` | ||||
| *   `center-pane` | ||||
| *   `note-detail-pane` - located within `center-pane`, but specific to note (split) | ||||
| *   `right-pane` | ||||
|  | ||||
| ## Example - word count widget | ||||
|  | ||||
| Create a code note of type JS frontend and **give it a** `**#widget**` **label**. | ||||
|  | ||||
| ``` | ||||
| /* | ||||
|  * This defines a custom widget which displays number of words and characters in a current text note. | ||||
|  * To be activated for a given note, add label 'wordCount' to the note, you can also make it inheritable and thus activate it for the whole subtree. | ||||
|  *  | ||||
|  * See it in action in "Books" and its subtree. | ||||
|  */ | ||||
| const TPL = ` | ||||
|     Word count:  | ||||
|      | ||||
|  | ||||
|       | ||||
|  | ||||
|     Character count:  | ||||
|      | ||||
| `; | ||||
|  | ||||
| class WordCountWidget extends api.NoteContextAwareWidget { | ||||
|     static get parentWidget() { return 'center-pane'; } | ||||
|  | ||||
|     get position() { return 100; } // higher value means position towards the bottom/right | ||||
|  | ||||
|     isEnabled() { | ||||
|         return super.isEnabled() | ||||
|             && this.note.type === 'text' | ||||
|             && this.note.hasLabel('wordCount'); | ||||
|     } | ||||
|  | ||||
|     doRender() { | ||||
|         this.$widget = $(TPL); | ||||
|         this.$wordCount = this.$widget.find('.word-count'); | ||||
|         this.$characterCount = this.$widget.find('.character-count'); | ||||
|         return this.$widget; | ||||
|     } | ||||
|  | ||||
|     async refreshWithNote(note) { | ||||
|         const {content} = await note.getNoteComplement(); | ||||
|  | ||||
|         const text = $(content).text(); // get plain text only | ||||
|  | ||||
|         const counts = this.getCounts(text); | ||||
|  | ||||
|         this.$wordCount.text(counts.words); | ||||
|         this.$characterCount.text(counts.characters); | ||||
|     } | ||||
|  | ||||
|     getCounts(text) { | ||||
|         const chunks = text | ||||
|             .split(/[\s-+:,/\\]+/) | ||||
|             .filter(chunk => chunk !== ''); | ||||
|  | ||||
|         let words; | ||||
|  | ||||
|         if (chunks.length === 1 && chunks[0] === '') { | ||||
|             words = 0; | ||||
|         } | ||||
|         else { | ||||
|             words = chunks.length; | ||||
|         } | ||||
|  | ||||
|         const characters = chunks.join('').length; | ||||
|  | ||||
|         return {words, characters}; | ||||
|     } | ||||
|  | ||||
|     async entitiesReloadedEvent({loadResults}) { | ||||
|         if (loadResults.isNoteContentReloaded(this.noteId)) { | ||||
|             this.refresh(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = WordCountWidget; | ||||
| ``` | ||||
|  | ||||
| After you make changes it is necessary to restart Trilium so that the layout can be rebuilt. | ||||
|  | ||||
| ### Example screenshot | ||||
|  | ||||
| On the bottom you can see the resulting widget: | ||||
|  | ||||
|  | ||||
| @@ -1,29 +0,0 @@ | ||||
| # Events | ||||
| [Script](Scripts.md) notes can be triggered by events. Note that these are backend events and thus relation need to point to the "JS backend" code note. | ||||
|  | ||||
| ## Global events | ||||
|  | ||||
| Global events are attached to the script note via label. Simply create e.g. "run" label with some of these values and script note will be executed once the event occurs. | ||||
|  | ||||
| *   `run` | ||||
|     *   `frontendStartup` - executes on frontend upon startup | ||||
|     *   `mobileStartup` - executes on mobile frontend upon startup | ||||
|     *   `backendStartup` - executes on backend upon startup | ||||
|     *   `hourly` - executes once an hour on backend | ||||
|     *   `daily` - executes once a day on backend | ||||
|  | ||||
| ## Entity events | ||||
|  | ||||
| Other events are bound to some entity, these are defined as [relations](../Attributes.md) - meaning that script is triggered only if note has this script attached to it through relations (or it can inherit it). | ||||
|  | ||||
| *   `runOnNoteCreation` - executes when note is created on backend | ||||
| *   `runOnNoteTitleChange` - executes when note title is changed (includes note creation as well) | ||||
| *   `runOnNoteContentChange` - executes when note content is changed (includes note creation as well). | ||||
| *   `runOnNoteChange` - executes when note is changed (includes note creation as well) | ||||
| *   `runOnNoteDeletion` - executes when note is being deleted | ||||
| *   `runOnBranchCreation` - executes when a branch is created. Branch is a link between parent note and child note and is created e.g. when cloning or moving note. | ||||
| *   `runOnBranchChange` (since v0.62) - executes when a branch is changed - either expanded status or prefix are changed. | ||||
| *   `runOnBranchDeletion` - executes when a branch is delete. Branch is a link between parent note and child note and is deleted e.g. when moving note (old branch/link is deleted). | ||||
| *   `runOnChildNoteCreation` - executes when new note is created under _this_ note | ||||
| *   `runOnAttributeCreation` - executes when new attribute is created under _this_ note | ||||
| *   `runOnAttributeChange` - executes when attribute is changed under _this_ note | ||||
| @@ -1,7 +0,0 @@ | ||||
| # Script API | ||||
| Trilium offers a "Script API" that enables scripts to perform various useful functions. There are two main APIs available: | ||||
|  | ||||
| *   [Frontend API](https://triliumnext.github.io/Notes/frontend_api/FrontendScriptApi.html) | ||||
| *   [Backend API](https://triliumnext.github.io/Notes/backend_api/BackendScriptApi.html) | ||||
|  | ||||
| Please note that the Script API is currently experimental and may undergo changes in future updates. | ||||
| @@ -1,54 +0,0 @@ | ||||
| # Scripts | ||||
| Trilium supports creating [code notes](../Code%20Notes.md), i.e. notes which allow you to store some programming code and highlight it. Special case is JavaScript code notes which can also be executed inside Trilium which can in conjunction with [Script API](Script%20API.md) provide extra functionality. | ||||
|  | ||||
| ## Scripting | ||||
|  | ||||
| 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: | ||||
|  | ||||
| *   frontend running in the browser (using HTML, CSS, JavaScript) - this is mainly used to interact with the user, display notes etc. | ||||
| *   backend running JavaScript code in node.js runtime - this is responsible for e.g. storing notes, encrypting them etc. | ||||
|  | ||||
| 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. | ||||
|  | ||||
| ## Button use case | ||||
|  | ||||
| Let's take a look at our demo script (shipped with default Trilium [database](../Database.md)) - Task manager. One of the things this script does is adding a button to the Trilium interface which will allow user to easily add new Task (TODO item). | ||||
|  | ||||
|  | ||||
|  | ||||
| First take a look at the red circle all the way on the top - this what we want to achieve - new button in UI which will create new note representing a task/todo item. | ||||
|  | ||||
| Red point below the first one marks the note type we have created for this script - it's "JavaScript frontend". It's frontend because adding button to UI is clearly frontend responsibility. | ||||
|  | ||||
| In the note content you can see the code which calls one of the API methods, this one is specifically meant to add new buttons. Code needs to set few button properties: | ||||
|  | ||||
| *   button title | ||||
| *   icon which should appear on the button | ||||
| *   optional shortcut under which you can trigger the button | ||||
| *   most importantly "action" - what must happen when button is clicked | ||||
|  | ||||
| ### Action handler | ||||
|  | ||||
| Saving the note to the database is backend's responsibility, so we immediately pass control to the backend and ask it to create a note. Once this is done, we show the newly created note so that the user can set the task title and maybe some attributes. | ||||
|  | ||||
| ### Script execution | ||||
|  | ||||
| So we have a script which will add the button to the toolbar. But how can we execute it? One possibility is to click on "play" icon (marked by red circle). The problem with this is that this UI change is time bound by Trilium runtime so when we restart Trilium, button won't be there. | ||||
|  | ||||
| We need to execute it every time Trilium starts up, but we probably don't want to have to manually click on play button on every start up. | ||||
|  | ||||
| The solution is marked by red circle at the bottom - this note has [label](../Attributes.md) `#run=frontendStartup` - this is one of the "system" labels which Trilium understands. As you might guess, this will cause all such labeled script notes to be executed once Trilium frontend starts up. | ||||
|  | ||||
| (`#run=frontendStartup` does not work for [Mobile frontend](../../Installation%20%26%20Setup/Mobile%20Frontend.md) - if you want to have scripts running there, give the script `#run=mobileStartup` label) | ||||
|  | ||||
| ### More showcases | ||||
|  | ||||
| You can see more scripting with explanation in [Advanced showcases](../Advanced%20Showcases.md) | ||||
|  | ||||
| ## Events | ||||
|  | ||||
| See [Events](Events.md). | ||||
|  | ||||
| ## Script API | ||||
|  | ||||
| See [Script API](Script%20API.md). | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 99 KiB | 
| @@ -1,11 +1,11 @@ | ||||
| # Custom Request Handler | ||||
| Trilium provides a mechanism for [scripts](Code%20Notes/Scripts.md) to open a public REST endpoint. This opens a way for various integrations with other services - a simple example would be creating new note from Slack by issuing a slash command (e.g. `/trilium buy milk`). | ||||
| Trilium provides a mechanism for [scripts](../Note%20Types/Code/Scripts.md) to open a public REST endpoint. This opens a way for various integrations with other services - a simple example would be creating new note from Slack by issuing a slash command (e.g. `/trilium buy milk`). | ||||
|  | ||||
| ## Create note from outside Trilium | ||||
|  | ||||
| Let's take a look at an example. The goal is to provide a REST endpoint to which we can send title and content and Trilium will create a note. | ||||
|  | ||||
| We'll start with creating a JavaScript backend [code note](Code%20Notes.md) containing: | ||||
| We'll start with creating a JavaScript backend [code note](../Note%20Types/Code.md) containing: | ||||
|  | ||||
| ``` | ||||
| const {req, res} = api; | ||||
| @@ -53,7 +53,7 @@ Trilium will then find our code note created above and execute it. `api.req`, `a | ||||
|  | ||||
| In the code note we check the request method and then use trivial authentication - keep in mind that these endpoints are by default totally unauthenticated, and you need to take care of this yourself. | ||||
|  | ||||
| Once we pass these checks we will just create the desired note using [Script API](Code%20Notes/Script%20API.md). | ||||
| Once we pass these checks we will just create the desired note using [Script API](../Note%20Types/Code/Script%20API.md). | ||||
|  | ||||
| ## Custom resource provider | ||||
|  | ||||
|   | ||||
| @@ -40,7 +40,7 @@ To protect shared notes with a username and password, you can use the `#shareCre | ||||
|  | ||||
| The default shared page is basic in design, but you can customize it using your own CSS: | ||||
|  | ||||
| *   **Custom CSS**: Link a CSS [code note](Code%20Notes.md) to the shared page by adding a `~shareCss` relation to the note. If you want this style to apply to the entire subtree, make the label inheritable. You can hide the CSS code note from the tree navigation by adding the `#shareHiddenFromTree` label. | ||||
| *   **Custom CSS**: Link a CSS [code note](../Note%20Types/Code.md) to the shared page by adding a `~shareCss` relation to the note. If you want this style to apply to the entire subtree, make the label inheritable. You can hide the CSS code note from the tree navigation by adding the `#shareHiddenFromTree` label. | ||||
| *   **Omitting Default CSS**: For extensive styling changes, use the `#shareOmitDefaultCss` label to avoid conflicts with Trilium's [default stylesheet](../Basic%20Concepts/Themes.md). | ||||
|  | ||||
| ### Adding JavaScript | ||||
|   | ||||
		Reference in New Issue
	
	Block a user