Templates 2.0 (#636)
Templates 2.0 and a whole bunch of other refactoring
@@ -0,0 +1,16 @@
|
||||
Blocks use the fenced code block notation of [[Markdown]], and assign special behavior to it.
|
||||
|
||||
The general syntax is:
|
||||
|
||||
```block-type
|
||||
block configuration
|
||||
```
|
||||
|
||||
These are the block types that ship with SilverBullet, but [[Plugs]] can define their own:
|
||||
|
||||
* `template`: [[Live Templates]]
|
||||
* `query`: [[Live Queries]]
|
||||
* `toc`: [[Table of Contents]]
|
||||
* `embed`: [[Live Embeds]]
|
||||
|
||||
The fenced code block syntax is also used to get [[Markdown/Syntax Highlighting]] for numerous programming languages.
|
||||
@@ -2,9 +2,16 @@ An attempt at documenting the changes/new features introduced in each
|
||||
release.
|
||||
|
||||
---
|
||||
## Next
|
||||
_Not yet released, this will likely become 0.6.0._
|
||||
## Edge
|
||||
_Not yet released, this will likely become 0.6.0. To try this out now, check out [the docs on edge](https://community.silverbullet.md/t/living-on-the-edge-builds/27)._
|
||||
|
||||
* **Templates 2.0**: templates are now turbo charged (that’s a technical term) and have replaced a lot of previously built in (slash) commands. There’s more to this than will fit this CHANGELOG, have a look at [[Templates]]: and more specifically [[Page Templates]], [[Snippets]], [[Live Template Widgets]] and [[Libraries]].
|
||||
A quick FAQ:
|
||||
* **Where did my templates go!?** They have now moved to the [[Template Picker]], see that “T” button up there? Yeah, that’s new.
|
||||
* **Where did all my slash commands go?!** They are now distributed via [[Libraries]]. Yep, Libraries are here, enabling an easier way to distribute templates and pages. Read [[Libraries]] for more info.
|
||||
* **But, what about slash templates etc.?!** Yeah, we did some rebranding and changed how these are defined. Slash templates are now [[Snippets]] and cannot _just_ be instantiated via [[Slash Commands]], but through [[Commands]] and custom keybindings as well. Awesomeness.
|
||||
* **And my page templates broke!?** Yeah, same story as with [[Snippets]]: the format for defining these changed a bit, but should be easy to update to the new format: check [[Page Templates]].
|
||||
* The [[Getting Started]] page (that is embedded in the `index` page that is auto-generated when creating a new space) has been updated to include instructions on how to import the [[Library/Core]] library.
|
||||
* **Directives have now been removed** from the code base. Please use [[Live Queries]] and [[Live Templates]] instead. If you hadn’t migrated yet and want to auto migrate, downgrade your SilverBullet version to 0.5.11 (e.g. using the `zefhemel/silverbullet:0.5.11` docker image) and run the {[Directive: Convert Entire Space to Live/Templates]} command with that version.
|
||||
* (Hopefully subtle) **breaking change** in how tags work (see [[Objects]]):
|
||||
* Every object now has a `tag` attribute, signifying the “main” tag for that object (e.g. `page`, `item`)
|
||||
@@ -12,17 +19,14 @@ _Not yet released, this will likely become 0.6.0._
|
||||
* The new `itags` attribute (available in many objects) includes both the `tag`, `tags` as well as any tags inherited from the page the object appears in.
|
||||
* Page tags now no longer need to appear at the top of the page, but can appear anywhere as long as they are the only thing appearing in a paragraph with no additional text, see [[Objects$page]].
|
||||
* New [[Markdown/Code Widgets|Code Widget]]: `toc` to manually include a [[Table of Contents]]
|
||||
* New template type: [[Live Template Widgets]] allowing you to automatically add templates to the top or bottom of your pages (based on some criteria). Using this feature it possible to implement [[Table of Contents]] and [[Linked Mentions]] without having “hard coded” into SilverBullet itself.
|
||||
* **“Breaking” change:** Two features are now no longer hardcoded into SilverBullet, but can be activated quite easily using [[Live Template Widgets]] (see their respective documentation pages on instructions on how to do this):
|
||||
* [[Table of Contents]]
|
||||
* [[Linked Mentions]]
|
||||
* Filter list (used by [[Page Picker]] and [[Command Palette]]) improvements:
|
||||
* Filter list (used by [[Page Picker]], [[Template Picker]] and [[Command Palette]]) improvements:
|
||||
* Better ranking
|
||||
* Better positioning of modal (especially on mobile)
|
||||
* Better mouse behavior
|
||||
* Templates:
|
||||
* Somewhat nicer rendering of {{templateVars}} (notice the gray background)
|
||||
* Rendering of [[Markdown/Code Widgets]] (such as live queries and templates) **are now disabled** on template pages, which should make them less confusing to read and interpret.
|
||||
* The `indexPage` [[SETTINGS]] can now contain template variables, such as `{{today}}`
|
||||
* Backend work in preparation for supporting more “serverless” deployments (e.g. Cloudflare workers and Deno Deploy) in the future
|
||||
* Move from [Oak](https://oakserver.github.io/oak/) to [Hono](https://hono.dev/)
|
||||
* Support for in-process plug loading (without workers)
|
||||
@@ -73,7 +77,7 @@ _Not yet released, this will likely become 0.6.0._
|
||||
---
|
||||
## 0.5.6
|
||||
* Various optimization and bug fixes
|
||||
* Experimental idea: [[Template Sets]]
|
||||
* Experimental idea: [[Libraries]]
|
||||
* The `Alt-Shift-n` key was previously bound to both {[Page: New]} and {[Quick Note]}. That won’t work, so now it’s just bound to {[Quick Note]}
|
||||
* The `Alt-q` command is now bound to the new {[Live Queries and Templates: Refresh All]} command, refreshing all [[Live Queries]] and [[Live Templates]] on the page. This is to get y’all prepared to move away from directives.
|
||||
* It’s likely that version 0.6.0 **will remove directives**, so please switch over to live queries and templates, e.g. using...
|
||||
@@ -89,7 +93,7 @@ _Not yet released, this will likely become 0.6.0._
|
||||
## 0.5.4
|
||||
* We’re on a journey to rethink [[Templates]]:
|
||||
* It is now _recommended_ you tag all your templates with a `#template` tag, this will exclude them from [[Objects]] indexing and may in the future be used to do better template name completion (but not yet).
|
||||
* New feature: Introducing [[Slash Templates]], allowing you to create custom [[Slash Commands]]. This deprecates snippets and page templates, because [[Slash Templates]] are awesomer.
|
||||
* New feature: Introducing [[Snippets]], allowing you to create custom [[Slash Commands]]. This deprecates snippets and page templates, because [[Snippets]] are awesomer.
|
||||
* Many styling fixes and improvements to [[Live Queries]] and [[Live Templates]]
|
||||
* Added a “source” button to [[Live Queries]] and [[Live Templates]] for better debugging (showing you the markdown code rendered by the template so you can more easily detect issues)
|
||||
* [[Live Queries]]:
|
||||
@@ -125,14 +129,14 @@ _Not yet released, this will likely become 0.6.0._
|
||||
Oh boy, this is a big one. This release brings you the following:
|
||||
|
||||
* [[Objects]]: a more generic system for indexing and querying content in your space, including the ability to define your own custom object “types” (dubbed [[Tags]]). See the referenced pages for examples.
|
||||
* [[Live Queries]] and [[Live Templates]]: ultimately will replace [[🔌 Directive]] in future versions and **[[🔌 Directive]] is now deprecated.** They differ from directives in that they don’t materialize their output into the page itself, but rather render them on the fly so only the query/template instantiation is kept on disk. All previous directive examples on this website how now been replaced with [[Live Templates]] and [[Live Queries]]. To ease the conversion there is {[Directive: Convert Query to Live Query]} command: just put your cursor inside of an existing (query) directive and run it to auto-convert.
|
||||
* The query syntax used in [[Live Queries]] (but also used in [[🔌 Directive]]) has been significantly expanded, although there may still be bugs. There’s still more value to be unlocked here in future releases.
|
||||
* [[Live Queries]] and [[Live Templates]]: ultimately will replace directives in future versions and **directives are now deprecated.** They differ from directives in that they don’t materialize their output into the page itself, but rather render them on the fly so only the query/template instantiation is kept on disk. All previous directive examples on this website how now been replaced with [[Live Templates]] and [[Live Queries]]. To ease the conversion there is {[Directive: Convert Query to Live Query]} command: just put your cursor inside of an existing (query) directive and run it to auto-convert.
|
||||
* The query syntax used in [[Live Queries]] (but also used in directives) has been significantly expanded, although there may still be bugs. There’s still more value to be unlocked here in future releases.
|
||||
* The previous “backlinks” plug is now built into SilverBullet as [[Linked Mentions]] and appears at the bottom of every page (if there are incoming links). You can toggle linked mentions via {[Mentions: Toggle]}.
|
||||
* A whole bunch of [[PlugOS]] syscalls have been updated. I’ll do my best update known existing plugs, but if you built existing ones some things may have broken. Please report anything broken in [Github issues](https://github.com/silverbulletmd/silverbullet/issues).
|
||||
* This release effectively already removes the `#eval` [[🔌 Directive]] (it’s still there, but likely not working), this directive needs some rethinking. Join us on [Discord](https://discord.gg/EvXbFucTxn) if you have a use case for it and how you use/want to use it.
|
||||
* This release effectively already removes the `#eval` (it’s still there, but likely not working), this directive needs some rethinking. Join us on [Discord](https://discord.gg/EvXbFucTxn) if you have a use case for it and how you use/want to use it.
|
||||
|
||||
**Important**:
|
||||
* If you have plugs such as “backlinks” or “graphview” installed, please remove them (or to be safe: all plugs) from the `_plug` folder in your space after the upgrade. Then, also remove them from your [[PLUGS]] page. The backlinks plug is now included by default (named [[Linked Mentions]]), and GraphView still needs to be updated (although it’s been kind of abandoned by the author).
|
||||
* If you have plugs such as “backlinks” or “graphview” installed, please remove them (or to be safe: all plugs) from the `_plug` folder in your space after the upgrade. Then, also remove them from your `PLUGS` page. The backlinks plug is now included by default (named [[Linked Mentions]]), and GraphView still needs to be updated (although it’s been kind of abandoned by the author).
|
||||
|
||||
Due to significant changes in how data is stored, likely your space will be resynced to all your clients once you upgrade. Just in case you may also want to {[Space: Reindex]} your space. If things are really broken, try the {[Debug: Reset Client]} command.
|
||||
|
||||
@@ -142,7 +146,7 @@ Due to significant changes in how data is stored, likely your space will be resy
|
||||
The big change in this release is that SilverBullet now supports two [[Client Modes|client modes]]: _online_ mode and _sync_ mode. Read more about them here: [[Client Modes]].
|
||||
|
||||
Other notable changes:
|
||||
* Massive reshuffling of built-in [[🔌 Plugs]], splitting the old “core” plug into [[Plugs/Editor]], [[Plugs/Template]] and [[Plugs/Index]].
|
||||
* Massive reshuffling of built-in [[Plugs]], splitting the old “core” plug into [[Plugs/Editor]], [[Plugs/Template]] and [[Plugs/Index]].
|
||||
* Directives in [[Live Preview]] now always take up a single line height.
|
||||
* [[Plugs/Tasks]] now support custom states (not just `[x]` and `[ ]`), for example:
|
||||
* [IN PROGRESS] An in progress task
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
Commands define actions that SilverBullet can perform. They range from simple edit commands, such as {[Text: Bold]}, but may be more elaborate such as {[Page: Rename]}. At a technical level, all commands are implemented via [[Plugs]].
|
||||
Commands define actions that SilverBullet can perform. They range from simple edit commands, such as {[Text: Bold]}, but may be more elaborate such as {[Page: Rename]}.
|
||||
|
||||
SilverBullet ships with a lot of commands built in, but custom ones can also be defined using [[Templates]] and [[Plugs]].
|
||||
|
||||
All available commands appear in the [[Command Palette]] but may have key bindings as well (these key bindings appear in the [[Command Palette]] and are configurable in [[SETTINGS]]).
|
||||
@@ -4,7 +4,7 @@ This enables a few things:
|
||||
|
||||
* **Linking and browsing** to other publicly hosted SilverBullet spaces (or websites adhering to its [[API]]). For instance the [[!silverbullet.md/CHANGELOG|SilverBullet CHANGELOG]] without leaving the comfort of your own SilverBullet client.
|
||||
* **Reusing** content from externally hosted sources, such as:
|
||||
* _Templates_, e.g. by federating with `silverbullet.md/template` will give you access to the example templates hosted there without manually copying and pasting them and automatically pull in the latest version. So you can, for instance, use `render [[!silverbullet.md/template/page]]` to use the [[template/page]] template. See [[Template Sets]] for more on this use case.
|
||||
* _Templates_, e.g. by federating with `silverbullet.md/template` will give you access to the example templates hosted there without manually copying and pasting them and automatically pull in the latest version. So you can, for instance, use `render [[!silverbullet.md/template/page]]` to use the [[Library/Core/Query/Page]] template. See [[Libraries]] for more on this use case.
|
||||
* _Data_: such as tasks, item, data hosted elsewhere that you want to query from your own space.
|
||||
|
||||
**Note:** Federation does not support authentication yet, so all federated spaces need to be unauthenticated and will be _read-only_.
|
||||
|
||||
@@ -19,6 +19,19 @@ Here is another example:
|
||||
## This is a section
|
||||
This is content
|
||||
|
||||
For convenience, you may use the `attribute.subAttribute` notation, which internally will expand:
|
||||
|
||||
```yaml
|
||||
attribute.subAttribute: 10
|
||||
```
|
||||
|
||||
to
|
||||
|
||||
```yaml
|
||||
attribute:
|
||||
subAttribute: 10
|
||||
```
|
||||
|
||||
# Special attributes
|
||||
While SilverBullet allows arbitrary metadata to be added to pages, there are a few attributes with special meaning:
|
||||
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
Welcome to SilverBullet. Since you’re starting fresh, you may want to kick off by importing the [[Library/Core]] [[Libraries|library]] of templates and pages. You can do so easily with the button below. Just push it — you know you want to!
|
||||
|
||||
{[Library: Import|Import Core Library]("!silverbullet.md/Library/Core/")}
|
||||
|
||||
Did that? Let’s proceed.
|
||||
|
||||
## Getting started
|
||||
The best way to get a good feel for what SilverBullet is to immediately start playing with it. Here are some things for you to try:
|
||||
|
||||
* Click on the page picker (book icon) icon at the top right, or hit `Cmd-k` (Mac) or `Ctrl-k` (Linux and Windows) to open the **page switcher**.
|
||||
* Click on the page picker (book icon) icon at the top right, or hit `Cmd-k` (Mac) or `Ctrl-k` (Linux and Windows) to open the [[Page Picker]].
|
||||
* Type the name of a non-existent page to create it.
|
||||
* You _can_ create pages in folders (if you’re into that type of thing) simply by putting slashes (`/`) in the name (even on Windows), e.g. `My Folder/My Page`. Don’t worry about that folder existing, we’ll automatically create it if it doesn’t.
|
||||
* Click on the terminal icon (top right), hit `Cmd-/` (Mac) or `Ctrl-/` (Linux and Windows), or tap the screen with 3 fingers at the same time (on mobile) to open the **command palette**. The {[Stats: Show]} one is a safe one to try.
|
||||
* Click on the terminal icon (top right), or hit `Cmd-/` (Mac) or `Ctrl-/` (Linux and Windows), or tap the screen with 3 fingers at the same time (on mobile) to open the [[Command Palette]]. The {[Stats: Show]} one is a safe one to try.
|
||||
* Click on the “T” icon (top right), or hit `Cmd-Shift-t` (Mac) or `Ctrl-Shift-t` (Linux and Windows) to open the [[Template Picker]] and see what templates you have installed (which should be a few after importing the Core library)
|
||||
* Select some text and hit `Alt-m` to ==highlight== it, or `Cmd-b` (Mac) or `Ctrl-b` (Windows/Linux) to make it **bold**, or `Cmd-i` (Mac) or `Ctrl-i` (Windows/Linux) to make it _italic_.
|
||||
* Click a link somewhere on this page to navigate there. When you link to a new page it will initially show up in red (to indicate it does not yet exist), but once you click it — you will create the page automatically (only for real when you actually enter some text).
|
||||
* Start typing `[[` somewhere to insert your own page link (with completion).
|
||||
* [ ] Tap this box 👈 to mark this task as done.
|
||||
* Start typing `:party` to trigger the emoji picker 🎉
|
||||
* Type `/` somewhere in the text to invoke a **slash command**.
|
||||
* Hit `Cmd-p` (Mac) or `Ctrl-p` (Windows, Linux) to show a preview for the current page on the side.
|
||||
* If this is matching your personality type, you can click this button {[Editor: Toggle Vim Mode]} to toggle Vim mode. If you cannot figure out how to exit it, just click that button again. _Phew!_
|
||||
|
||||
Notice that as you move your cursor around on this page and you get close to or “inside” marked up text, you will get to see the underlying [[Markdown]] code. This experience is what we refer to as “live preview” — generally your text looks clean, but you still can see what’s under the covers and edit it directly, as opposed to [WYSIWYG](https://en.wikipedia.org/wiki/WYSIWYG) that some other applications use. To move your cursor somewhere using your mouse without navigating or activating (e.g. a wiki, regular link, or a button) hold `Alt` when you click. Holding `Cmd` or `Ctrl` when clicking a link will open it in a new tab or window.
|
||||
@@ -36,4 +42,4 @@ Beyond that, you can find more information about SilverBullet on its official we
|
||||
1. Through its [regular website link](https://silverbullet.md/)
|
||||
2. Directly without leaving SilverBullet, through [[Federation]], just click on this: [[SilverBullet]] (note that all of these will be read-only, for obvious reasons)
|
||||
|
||||
To keep up with the latest and greatest going-ons in SilverBullet land, keep an eye on the [[CHANGELOG]], and regularly update your SilverBullet instance (`silverbullet upgrade` if you’re running the Deno version). If you run into any issues or have ideas on how to make SilverBullet even awesomer (yes, that’s a word), [join the conversation on GitHub](https://github.com/silverbulletmd/silverbullet).
|
||||
To keep up with the latest and greatest going-ons in SilverBullet land, keep an eye on the [[CHANGELOG]].
|
||||
@@ -1,247 +0,0 @@
|
||||
In this guide we will show you how to deploy silverbullet and cloudflare in containers, making them "talk/communicate" in the same private network just for them.
|
||||
|
||||
This guide assumes that you have already deployed Portainer. If not, see [this official guide](https://docs.portainer.io/start/install-ce/server/docker/linux) from Portainer to deploy it on Linux.
|
||||
|
||||
### Brief
|
||||
|
||||
This guide will be divided into three parts, in the first we'll set up Silverbullet with Cloudflare. In the second, we will set up Cloudflare from the beginning to access Silverbullet from outside our LAN using [Tunnels](https://www.cloudflare.com/products/tunnel/). And in the third step, we protect our Silverbullet instance with [Access Zero Trust](https://www.cloudflare.com/products/zero-trust/access/) for authentication.
|
||||
|
||||
# 1 - Deploy Silverbullet and Cloudflare in Portainer
|
||||
|
||||
## Prepare the Template
|
||||
We will prepare a template in Portainer where we will add the configuration of a ==docker-compose.yaml== that will run our containers, and we will be able to move the stack to another server/host if necessary using the same configuration.
|
||||
|
||||
First, go to **Home** > (Your environment name, default is **local**) > **App Templates** > **Custom Templates** and click on the blue button in the right corner > "**Add Custom Template**".
|
||||

|
||||
|
||||
### Name
|
||||
|
||||
Choose a name for the silverbullet stack, we chose "**silverbullet-docker**", very imaginative... 😊.
|
||||
|
||||
### Description
|
||||
|
||||
Fill the description with your own words; this is up to you because it is optional.
|
||||
|
||||
### Icon Url
|
||||
|
||||
Copy and paste this url to get the icon. ``https://raw.githubusercontent.com/silverbulletmd/silverbullet/main/web/images/logo.ico``
|
||||
|
||||
### Platform
|
||||
|
||||
Choose Linux
|
||||
|
||||
### Type
|
||||
|
||||
Standalone
|
||||
|
||||
### Build Method
|
||||
|
||||
As for the Build method choose “**Web Editor**” and copy-paste this ==docker-compose.yaml== configuration:
|
||||
|
||||
```yaml
|
||||
version: '3.9'
|
||||
services:
|
||||
silverbullet:
|
||||
image: zefhemel/silverbullet
|
||||
container_name: silverbullet
|
||||
restart: unless-stopped
|
||||
## To enable additional options, such as authentication, set environment variables, e.g.
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
#- SB_USER=username:1234 #feel free to remove this if not needed
|
||||
volumes:
|
||||
- space:/space:rw
|
||||
ports:
|
||||
- 3000:3000
|
||||
networks:
|
||||
- silverbullet
|
||||
|
||||
cloudflared:
|
||||
container_name: cloudflared-tunnel
|
||||
image: cloudflare/cloudflared
|
||||
restart: unless-stopped
|
||||
command: tunnel run
|
||||
environment:
|
||||
# If deploying in to Portainer add your token value here!
|
||||
# If deploying manually create a ".env" file and add the variable and the value of the token.
|
||||
- TUNNEL_TOKEN=your-token-value-here!
|
||||
#- TUNNEL_TOKEN=${TUNNEL_TOKEN}
|
||||
depends_on:
|
||||
- silverbullet
|
||||
networks:
|
||||
- silverbullet
|
||||
|
||||
networks:
|
||||
silverbullet:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
space:
|
||||
```
|
||||
|
||||
We will replace "your-token-value-here" with a real token value in the next steps.
|
||||
|
||||
Once you have this, go to the bottom of the page and click **Actions** > **Create Custom Template**.
|
||||

|
||||
|
||||
Now we have to build the network before we can deploy it.
|
||||
|
||||
**NOTE***: If you got a *Error code 8: Attempt to write a readonly database* when running `docker compose up`.
|
||||
|
||||
Ensure that the directory on the host system that is mounted as /space in your container has the correct permissions. For example:
|
||||
|
||||
```shell
|
||||
sudo chown -R 1000:1000 /path/to/space
|
||||
sudo chmod -R 755 /path/to/space
|
||||
```
|
||||
|
||||
## Create the network for silverbullet
|
||||
|
||||
Go to **Home** > **Networks** > **Add Network**.
|
||||
|
||||
### Name
|
||||
|
||||
Choose "**silverbullet**" because that is the name we are already using in the ==docker-compose.yaml==.
|
||||
|
||||
You can leave all the other options by default or change them to suit your network needs.
|
||||
|
||||

|
||||

|
||||
Click **Create Network** at the bottom of the page.
|
||||

|
||||
|
||||
## Deploying the Stack
|
||||
|
||||
Go to **Home** > **Local** > **App Templates** > **Custom Templates**.
|
||||
|
||||
Go into the **silverbullet-docker** and click on **Edit**.
|
||||

|
||||
Click on **Deploy the stack**.
|
||||

|
||||
Give it a few seconds and you will get a notification that both containers are running. 😇
|
||||
|
||||
Only the silverbullet container should be working properly by this point, as we haven't finished with Cloudflare yet.
|
||||

|
||||
|
||||
## Verification
|
||||
|
||||
In a web browser in your local network (if your server is in your LAN) write the IP address of your server and add the port 3000 at the end, like this:
|
||||
``http://your-ip-address:3000 ``
|
||||
|
||||
Right now the connection to silverbullet is **HTTP** and PWA([Progressive Web Apps](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps)) and offline mode will not work yet. Don’t worry we will get into that later, but for now, it should be working correctly. Try to type something and sync it to your server.
|
||||
|
||||
---
|
||||
|
||||
# 2 - Set up Cloudflare with Tunnels.
|
||||
|
||||
Now we are going to use Cloudflare to be able to connect to SilverBullet from outside our network and have a valid SSL certificate without opening any ports or needing a static IPv4 address from our ISP or changing our router configuration.
|
||||
|
||||
You will need three things:
|
||||
|
||||
* An account with Cloudflare ☁️.
|
||||
* A debit/credit card 💳.
|
||||
* A domain name (you can buy it on [Njalla](https://njal.la/) 😉. Your real name will not be shown if someone uses whois tools).
|
||||
|
||||
We assume you've already [signed up to Cloudflare](https://www.cloudflare.com/), if not you can go and do it now. It's free but you'll need to add a real debit/credit card to have access to the tunnels and zero access. If you don't want to do that, you can use **alternatives** like [Caddy](https://caddyserver.com/docs/quick-starts/reverse-proxy) or [Nginx](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) for reverse proxy and [Authelia](https://www.authelia.com/) or you can use the [basic authentication built-in](https://silverbullet.md/Authentication) for authentication.
|
||||
|
||||
## Add your Site/Domain Name to Cloudflare
|
||||
|
||||
Follow the [official docs](https://developers.cloudflare.com/fundamentals/get-started/setup/add-site/) of Cloudflare on how to add a site, it's really easy, just remember to change the name servers (DNS) to the ones suggested by Cloudflare in the website where you bought your domain name.
|
||||

|
||||
Like this (This is Njalla config panel)
|
||||

|
||||
|
||||
## Setup Tunnel
|
||||
|
||||
Without opening any ports or touching the firewall, we set up this tunnel to connect it to our server.
|
||||
|
||||
Click on **Zero Trust** once you have added your site/domain name.
|
||||

|
||||
Click on **Create Tunnel**.
|
||||

|
||||
Choose a name for your tunnel, I chose "myhome", very imaginative again 😛. And then click on **Save Tunnel**.
|
||||

|
||||
|
||||
Since we have already set up a container of Cloudflare, just copy the token you are given. And be careful, if someone gets your token they will be able to make a tunnel connection to your server.
|
||||

|
||||
|
||||
Now that you have the token value of your tunnel, it's time to configure the cloudflare container in Portainer. Let's go there.
|
||||
|
||||
Go to **App Templates** > **Custom Templates** > **Edit**.
|
||||

|
||||
Replace “your-token-value-here!” with your token value.
|
||||

|
||||
Click on **Update the template**.****
|
||||
|
||||
Next, go to **Stacks** and click on the stack “**silverbullet-docker**”, or the name of your choice, then click **Remove**.
|
||||

|
||||
Click **Remove** to confirm. Don't worry, this will only remove the stack and the containers attached to it, not the template.
|
||||

|
||||
Then go to **App Templates**.
|
||||
|
||||
Go into the **silverbullet-docker** and click on **Edit**.
|
||||

|
||||
Click **Deploy Stack**.
|
||||

|
||||
Come back to Cloudflare and in the Connectors section you will see that a connection has been made to your server. Click **Next**.
|
||||

|
||||
Click **Add a public hostname**.
|
||||

|
||||
Fill in the **subdomain** field with the name you want to use to access silverbullet. Choose your domain name and for **Type** choose **HTTP** and the **URL** should be **silverbullet:3000**.
|
||||
|
||||

|
||||
Check now with **silberbullet.your-domain-name.com**. You should be able to access it.
|
||||
|
||||
# 3 - Set up Cloudflare Zero Access Trust (Auth).
|
||||
|
||||
We assume you've already [signed up to Cloudflare](https://www.cloudflare.com/), if not you can go and do it now, it's free but you'll need to add a real debit/credit card to have access to the tunnels and zero access. If you don't want to do that, you can use **alternatives** like [Caddy](https://caddyserver.com/docs/quick-starts/reverse-proxy) or [Nginx](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) for reverse proxy and [Authelia](https://www.authelia.com/) or you can use the [BasicAuth build-in](https://silverbullet.md/Authentication) for authentication.
|
||||
|
||||
Go to **Access** > **Applications** and click **Add an application** from the Zero Trust panel.
|
||||

|
||||
|
||||
Select **Self-Hosted**.
|
||||

|
||||
Choose a name for your application and use the same name for the subdomain you chose in the previous steps. In our case both are **silverbullet**.
|
||||

|
||||
Leave the rest of the page as default and click **Next** at the bottom of the page.
|
||||
|
||||
Now it's time to select the name of the policy, the action and the duration of the session.
|
||||
|
||||
Select a descriptive **Name** for future troubleshooting, select **Allow** for the **Action** and leave the session duration at its default.
|
||||
|
||||
In the **Configure rules** section, select **Emails** if you want to use emails (or you can use a range of IPs, specific countries...) for verification, and enter the emails you want to allow access to Silverbullet.
|
||||

|
||||
Leave the rest of the page as default and click **Next** at the bottom of the page.
|
||||
|
||||
On the next page, leave everything as default and click on **Add Application** at the bottom of the page.
|
||||
|
||||
Go to **silverbullet.your-domain-name.com** and you should see a page like this:
|
||||

|
||||
Going back to the Zero Trust overview, we are now going to create some special rules to allow some specific files from silverbullet without authentication. The same thing happens with other auth applications such as [Authelia](https://silverbullet.md/Authelia).
|
||||
|
||||
Create a new self-hosted application in Cloudflare, we suggest the name **silverbullet bypass**.
|
||||
|
||||
And add the following **paths**:
|
||||
|
||||
```
|
||||
.client/manifest.json
|
||||
.client/[a-zA-Z0-9_-]+.png
|
||||
service_worker.js
|
||||
```
|
||||
|
||||
Leave the rest as default and click **Next** at the bottom of the page.
|
||||

|
||||
For the policy name we suggest **silverbullet bypass paths**, as for the **Action** you need to select **Bypass**, and in the Configure Rules **Select** **Everyone** or you can exclude a range of IP's or countries if required.
|
||||
|
||||
Leave the rest as default and click **Next** at the bottom of the page.
|
||||

|
||||
These rules only take effect on the specific paths, you can read more about [Policy inheritance on Cloudflare.](https://developers.cloudflare.com/cloudflare-one/policies/access/app-paths/)
|
||||
|
||||
On the next page, leave everything as default and click on **Add Application** at the bottom of the page.
|
||||
|
||||
Go and check your **silberbullet.your-domain-name.com** everything should be working correctly.
|
||||
|
||||
Now the connection to silverbullet is **HTTPS** and PWA ([Progressive Web Apps](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps)) and offline mode will work.
|
||||
|
||||
I hope this guide has been helpful.
|
||||
|
Before Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 252 KiB |
|
Before Width: | Height: | Size: 208 KiB |
|
Before Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 123 KiB |
@@ -14,4 +14,3 @@ People have found various simple to more complex ways of achieving this.
|
||||
* Using [[Deployments/ngrok]] is likely the easiest solution to exposing your _locally running_ SilverBullet to the Internet. Note that “locally running” can mean your own local machine, but can still refer to running it on a server in your network (like a Raspberry Pi).
|
||||
* [[Deployments/Caddy]]: the easiest solution to expose SilverBullet running on a publicly accessible server to the Internet (but local network as well using Tailscale)
|
||||
* [[Authelia]] setup hints
|
||||
* [[Guide/Deployment/Cloudflare and Portainer]]
|
||||
|
||||
@@ -9,8 +9,6 @@ Particularly useful keyboard shortcuts (that you may not know about).
|
||||
| Cmd-z/Ctrl-z | Undo the latest change |
|
||||
| Cmd-u/Ctrl-u | Go one change ahead |
|
||||
| Alt-h | Navigate to the home page |
|
||||
| Ctrl-Alt-t | Toggle table of contents|
|
||||
| Ctrl-Alt-m | Toggle mentions |
|
||||
| Cmd-Shift-f/Ctrl-Shift-f | Search for text across your entire space |
|
||||
# System
|
||||
| Combination (Mac/Win-Linux) | Action |
|
||||
@@ -20,8 +18,6 @@ Particularly useful keyboard shortcuts (that you may not know about).
|
||||
| Cmd-Shift-p/Ctrl-Shift-p | Update plugs (from the `PLUGS` file) |
|
||||
| Alt-q | Refresh all live queries and templates on this page |
|
||||
| Cmd-p/Ctrl-p | Toggle markdown preview |
|
||||
| Ctrl-Alt-t | Toggle table of contents|
|
||||
| Ctrl-Alt-m | Toggle mentions |
|
||||
| Cmd-Shift-f/Ctrl-Shift-f | Search for text across your entire space |
|
||||
|
||||
# Navigation
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
A lot of useful functionality in SilverBullet is implemented through [[Templates]], as well as regular [[Pages]]. Some of these you will create yourself for your own specific use, but many are generic and generally useful. Libraries offer a way to _distribute_ sets of templates and pages easily.
|
||||
|
||||
# What’s in a library
|
||||
Here are some things that a library may provide:
|
||||
* Various [[Slash Commands]], such as `/today`, `/task`, `/table`.
|
||||
* Useful [[Page Templates]]
|
||||
* Useful widgets such as [[Table of Contents]] or [[Linked Mentions]]
|
||||
* Useful pages that help you perform maintenance on your space, like detecting broken links, such as [[Library/Core/Page/Maintenance]].
|
||||
|
||||
# What libraries are on offer?
|
||||
Libraries are still a young concept in SilverBullet and therefore we’re still exploring how to organize and structure these.
|
||||
|
||||
Currently, we have the following libraries available:
|
||||
|
||||
* [[Library/Core]]: this is the library you want to import _for sure_. Just do it.
|
||||
* [[Library/Journal]]: for the journalers among us.
|
||||
@@ -0,0 +1,25 @@
|
||||
This library is highly recommended for everybody to import immediately. It provides a lot of functionality you’ll likely appreciate (and may be used to having out of the box, if you’re longer-term SilverBullet user).
|
||||
|
||||
Some random examples:
|
||||
* [[Table of Contents]] and [[Linked Mentions]]
|
||||
* All the slash commands you know and love, ranging from `/h1` to `/task` to `/table` to `/code` to `/query` to `/template` to `/today` to...
|
||||
* Some useful general purpose pages such as [[Library/Core/Page/Maintenance]] and [[Library/Core/Page/Template Index]].
|
||||
|
||||
# Installation
|
||||
To import this library, run the {[Library: Import]} command in your SilverBullet space and enter:
|
||||
|
||||
!silverbullet.md/Library/Core/
|
||||
|
||||
# Included templates
|
||||
```query
|
||||
template
|
||||
where name =~ /^{{escapeRegexp @page.name}}\//
|
||||
render [[Library/Core/Query/Template]]
|
||||
```
|
||||
|
||||
# Included utility pages
|
||||
```query
|
||||
page
|
||||
where name =~ /^{{escapeRegexp @page.name}}\// and tags != "template"
|
||||
render [[Library/Core/Query/Page]]
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
description: Define a new Page Template
|
||||
tags: template
|
||||
hooks.newPage:
|
||||
suggestedName: Library/Personal/Page/
|
||||
forPrefix: Library/Personal/Page/
|
||||
confirmName: true
|
||||
frontmatter: |
|
||||
tags: template
|
||||
displayName: "|^|"
|
||||
hooks.newPage:
|
||||
suggestedName: Library/Personal/Page/
|
||||
---
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
description: "Create a quick note"
|
||||
tags: template
|
||||
hooks.newPage:
|
||||
suggestedName: "Inbox/{{today}} {{time}}"
|
||||
confirmName: false
|
||||
command: "Quick Note"
|
||||
key: "Alt-Shift-n"
|
||||
---
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
tags: template
|
||||
hooks.newPage:
|
||||
suggestedName: "template/snippet/"
|
||||
confirmName: true
|
||||
forPrefix: template/snippet/
|
||||
description: Define a new Snippet Template
|
||||
frontmatter: |
|
||||
tags: template
|
||||
hooks.snippet:
|
||||
name: "|^|"
|
||||
---
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
tags: template
|
||||
description: Define a new template
|
||||
hooks.newPage:
|
||||
suggestedName: template/
|
||||
forPrefix: template/
|
||||
frontmatter:
|
||||
tags: template
|
||||
---
|
||||
|^|
|
||||
@@ -0,0 +1,36 @@
|
||||
We would like to keep our space clean, these are some tools that help you do that.
|
||||
|
||||
# Broken links
|
||||
This shows all internal links that are broken.
|
||||
|
||||
```template
|
||||
query: |
|
||||
link where toPage and pageExists(toPage) = false
|
||||
template: |
|
||||
{{#if .}}
|
||||
{{#each .}}
|
||||
* [[{{ref}}]]: broken link to [[{{toPage}}]]
|
||||
{{/each}}
|
||||
{{else}}
|
||||
No broken links, all good!
|
||||
{{/if}}
|
||||
```
|
||||
|
||||
# Conflict copies
|
||||
These are pages that have conflicted copies (as a result of sync), have a look at them as well as their original (non-conflicted versions) and decide which one to keep.
|
||||
|
||||
```template
|
||||
query: |
|
||||
page where name =~ /\.conflicted\.\d+$/
|
||||
select
|
||||
name as conflictedName,
|
||||
replace(name, /\.conflicted\.\d+$/, "") as cleanName
|
||||
template: |
|
||||
{{#if .}}
|
||||
{{#each .}}
|
||||
* [[{{cleanName}}]]: confict copy [[{{conflictedName}}]]
|
||||
{{/each}}
|
||||
{{else}}
|
||||
No conflicting pages!
|
||||
{{/if}}
|
||||
```
|
||||
@@ -0,0 +1,47 @@
|
||||
This page lists all templates currently available in your space.
|
||||
|
||||
# New Page
|
||||
$newPage
|
||||
These [[!silverbullet.md/Page Templates]] are available through the {[Page: From Template]} command.
|
||||
|
||||
```query
|
||||
template where hooks.newPage render [[Library/Core/Query/Template]]
|
||||
```
|
||||
|
||||
# Snippets
|
||||
$snippets
|
||||
These can be used as [[!silverbullet.md/Snippets]] via [[!silverbullet.md/Slash Commands]]:
|
||||
|
||||
```query
|
||||
template where hooks.snippet render [[Library/Core/Query/Template]]
|
||||
```
|
||||
|
||||
# Widgets
|
||||
$widgets
|
||||
Widgets can either be automatically attached to the top or bottom of pages (matching certain criteria) or used inline via [[!silverbullet.md/Live Templates]].
|
||||
|
||||
## Top
|
||||
```query
|
||||
template
|
||||
where hooks.top
|
||||
order by order
|
||||
render [[Library/Core/Query/Template]]
|
||||
```
|
||||
|
||||
## Bottom
|
||||
```query
|
||||
template
|
||||
where hooks.bottom
|
||||
order by order
|
||||
render [[Library/Core/Query/Template]]
|
||||
```
|
||||
|
||||
## Inline
|
||||
Use these as `page` in [[!silverbullet.md/Live Templates]] to render useful things in your pages:
|
||||
|
||||
```query
|
||||
template
|
||||
where name =~ /\/Widget\// and hooks.top = null and hooks.bottom = null
|
||||
order by order
|
||||
render [[Library/Core/Query/Template]]
|
||||
```
|
||||
@@ -2,5 +2,4 @@
|
||||
tags: template
|
||||
description: A page reference link as a list item
|
||||
---
|
||||
|
||||
* [[{{name}}]]
|
||||
@@ -1,7 +1,5 @@
|
||||
---
|
||||
tags: template
|
||||
type: query
|
||||
description: generic task template that supports updating the status back in the origin page
|
||||
order: 1
|
||||
description: Generic task template that supports updating the status back in the origin page
|
||||
---
|
||||
* [{{state}}] [[{{ref}}]] {{name}}
|
||||
@@ -0,0 +1,5 @@
|
||||
#template
|
||||
* [[{{ref}}]] {{description}}
|
||||
{{#if usage}}
|
||||
* **Usage:** {{usage}}
|
||||
{{/if}}
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
description: Insert a fenced code block
|
||||
tags: template
|
||||
hooks.snippet.slashCommand: code
|
||||
---
|
||||
```|^|
|
||||
|
||||
```
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
tags: template
|
||||
description: Insert Frontmatter
|
||||
hooks.snippet:
|
||||
slashCommand: frontmatter
|
||||
insertAt: page-start
|
||||
command: "Insert Frontmatter"
|
||||
---
|
||||
---
|
||||
|^|
|
||||
---
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
tags: template
|
||||
description: Make this a level 1 heading
|
||||
hooks.snippet:
|
||||
slashCommand: h1
|
||||
match: "^#*\\s*"
|
||||
---
|
||||
#
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
tags: template
|
||||
description: Make this a level 2 heading
|
||||
hooks.snippet:
|
||||
slashCommand: h2
|
||||
match: "^#*\\s*"
|
||||
---
|
||||
##
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
tags: template
|
||||
description: Make this a level 3 heading
|
||||
hooks.snippet:
|
||||
slashCommand: h3
|
||||
match: "^#*\\s*"
|
||||
---
|
||||
###
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
tags: template
|
||||
description: Make this a level 4 heading
|
||||
hooks.snippet:
|
||||
slashCommand: h4
|
||||
match: "^#*\\s*"
|
||||
---
|
||||
####
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
tags: template
|
||||
description: Insert a horizontal rule
|
||||
hooks.snippet.slashCommand: hr
|
||||
---
|
||||
---
|
||||
@@ -1,9 +1,7 @@
|
||||
---
|
||||
tags: template
|
||||
type: slash
|
||||
trigger: "note-admonition"
|
||||
displayName: "/note-admonition"
|
||||
description: Insert a "note" admonition
|
||||
hooks.snippet.slashCommand: note-admonition
|
||||
---
|
||||
> **note** Note
|
||||
> |^|
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
description: Insert a live query
|
||||
tags: template
|
||||
hooks.snippet.slashCommand: query
|
||||
---
|
||||
```query
|
||||
|^|
|
||||
```
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
tags: template
|
||||
description: Insert a table
|
||||
hooks.snippet.slashCommand: table
|
||||
---
|
||||
| Header A | Header B |
|
||||
|----------|----------|
|
||||
| Cell A|^| | Cell B |
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
tags: template
|
||||
description: Turn the current line into a task
|
||||
hooks.snippet:
|
||||
slashCommand: task
|
||||
matchRegex: "^(\\s*)[\\-\\*]?\\s*(\\[[ xX]\\])?\\s*"
|
||||
command: "Turn into task"
|
||||
key: "Ctrl-q t"
|
||||
---
|
||||
$1* [ ]
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
description: Insert an inline template
|
||||
tags: template
|
||||
hooks.snippet.slashCommand: "template"
|
||||
---
|
||||
```template
|
||||
page: "[[|^|]]"
|
||||
```
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
tags: template
|
||||
description: "Today's date"
|
||||
hooks.snippet.slashCommand: today
|
||||
---
|
||||
{{today}}
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
tags: template
|
||||
description: "Tomorrow's date"
|
||||
hooks.snippet.slashCommand: tomorrow
|
||||
---
|
||||
{{tomorrow}}
|
||||
@@ -1,9 +1,7 @@
|
||||
---
|
||||
tags: template
|
||||
type: slash
|
||||
trigger: "warning-admonition"
|
||||
displayName: "/warning-admonition"
|
||||
description: Insert a "warning" admonition
|
||||
tags: template
|
||||
hooks.snippet.slashCommand: warning-admonition
|
||||
---
|
||||
> **warning** Warning
|
||||
> |^|
|
||||
@@ -3,8 +3,7 @@ description: >
|
||||
Adds a convenient "Copy to my space" button to any
|
||||
template found via federation
|
||||
tags: template
|
||||
type: widget:bottom
|
||||
where: 'name =~ /^!/ and tags="template"'
|
||||
hooks.bottom.where: 'name =~ /^!/ and tags="template"'
|
||||
---
|
||||
# Template actions
|
||||
* {[Page: Copy|Copy to my space]}: use this template in your space by making a local copy of it (and tweaking it as you like)
|
||||
@@ -1,8 +1,7 @@
|
||||
---
|
||||
description: Adds Linked Mentions to all pages
|
||||
description: Adds Linked Mentions to pages
|
||||
tags: template
|
||||
type: widget:bottom
|
||||
where: 'true'
|
||||
hooks.bottom.where: 'true'
|
||||
---
|
||||
```template
|
||||
# We need to escape handlebars directives here, since we're embedding
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
tags: template
|
||||
description: |
|
||||
Shows all tasks that contain a link the current page. For instance a task that references `[[John]]` in its name, would appear on the `John` page.
|
||||
---
|
||||
|
||||
```query
|
||||
task where name =~ /\[\[{{escapeRegexp @page.name}}\]\]/ where done = false render [[Library/Core/Query/Task]]
|
||||
```
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
description: Adds a Table of Contents to pages
|
||||
tags: template
|
||||
hooks.top:
|
||||
where: 'true'
|
||||
# Show all the way at the top
|
||||
order: 0
|
||||
---
|
||||
```toc
|
||||
minHeaders: 3
|
||||
```
|
||||
@@ -1,11 +1,9 @@
|
||||
---
|
||||
tags: template
|
||||
type: live
|
||||
description: Queries all tasks tagged with a specific tag.
|
||||
usage: Pass in the tag to filter on as the `value` of this template
|
||||
order: 2
|
||||
---
|
||||
|
||||
```query
|
||||
task where tags = "{{.}}" and done = false render [[template/tasks/task]]
|
||||
task where tags = "{{.}}" and done = false render [[Library/Core/Query/Task]]
|
||||
```
|
||||
@@ -0,0 +1,28 @@
|
||||
This library contains some useful page templates for journalers. Want to easily create a daily or weekly note? These templates can get you started. Instantiate them via {[Page: From Template]}.
|
||||
|
||||
# Installation
|
||||
To import this library, run the {[Library: Import]} command in your SilverBullet space and enter:
|
||||
|
||||
!silverbullet.md/Library/Journal/
|
||||
|
||||
# Included templates
|
||||
```query
|
||||
page
|
||||
where name =~ /^{{escapeRegexp @page.name}}\//
|
||||
render [[Library/Core/Query/Page]]
|
||||
```
|
||||
|
||||
# Tips
|
||||
Do you want your space’s start page to always be either your daily or weekly note? You can!
|
||||
|
||||
To set the _daily note_ as the default page, set the following in [[SETTINGS]]:
|
||||
|
||||
```yaml
|
||||
indexPage: "Journal/Day/{{today}}"
|
||||
```
|
||||
|
||||
And for the _weekly note_:
|
||||
|
||||
```yaml
|
||||
indexPage: "Journal/Week/{{weekStart}}"
|
||||
```
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
description: "Your daily note template"
|
||||
tags: template
|
||||
hooks.newPage:
|
||||
suggestedName: "Journal/Day/{{today}}"
|
||||
confirmName: false
|
||||
openIfExists: true
|
||||
forPrefix: "Journal/Day/"
|
||||
command: "Open Daily Note"
|
||||
key: "Alt-Shift-d"
|
||||
---
|
||||
* |^|
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
description: "Open your weekly note page"
|
||||
tags: template
|
||||
hooks.newPage:
|
||||
suggestedName: "Journal/Week/{{weekStart}}"
|
||||
forPrefix: "Journal/Week/"
|
||||
confirmName: false
|
||||
openIfExists: true
|
||||
command: "Open Weekly Note"
|
||||
key: "Alt-Shift-w"
|
||||
---
|
||||
# Goals
|
||||
* |^|
|
||||
@@ -1,3 +1,3 @@
|
||||
Linked Mentions are references from other pages to the current page. Technically, they’re not a built-in feature, but you can easily implement them using [[Live Template Widgets]].
|
||||
On this site you see a section “Linked Mentions” appear along the bottom of every page that has incoming links. 👇🏻 This section lists all pages that contain a _link_ to the current page. This allows for easy navigation, and may help you discover linked concepts through these links.
|
||||
|
||||
To enable linked mentions being added to your pages, include the [[template/widget/linked-mentions]] template in your space, either through copy and pasting or through [[Federation]].
|
||||
Linked Mentions are not a feature built into SilverBullet directly, but can easily be added by importing the [[Library/Core|core library]].
|
||||
@@ -0,0 +1,13 @@
|
||||
Live Embeds allow you to embed internet content into your page inside of an iframe. This is useful to embed youtube videos or other websites.
|
||||
|
||||
```embed
|
||||
url: https://youtu.be/BbNbZgOwB-Y
|
||||
```
|
||||
|
||||
Note, there is specific support for YouTube videos — it automatically sets the width and height, and replaces the URL with an embed URL.
|
||||
|
||||
The body of an `embed` block is written in [[YAML]] and supports the following attributes:
|
||||
|
||||
* `url` (mandatory): the URL of the content to embed
|
||||
* `height` (optional): the height of the embedded page in pixels
|
||||
* `width` (optional): the width of the embedded page in pixels
|
||||
@@ -8,16 +8,16 @@ order by lastModified desc
|
||||
where size > 100
|
||||
select name
|
||||
limit 10
|
||||
render [[template/page]]
|
||||
render [[Library/Core/Query/Page]]
|
||||
```
|
||||
It’s most convenient to use `/query` [[Slash Commands]] to insert a query in a page.
|
||||
It’s most convenient to use the `/query` [[Snippets|snippet]] to insert a query in a page.
|
||||
|
||||
For those comfortable reading such things, [here you can find the full query grammar](https://github.com/silverbulletmd/silverbullet/blob/main/common/markdown_parser/query.grammar).
|
||||
|
||||
The general syntax is to specify a `querySource` followed by a number of clauses that modify or restrict. If you haven’t already, check out how [[Objects]] work in SilverBullet.
|
||||
|
||||
# Clauses
|
||||
## `where` [[@expression]]
|
||||
## where [[@expression]]
|
||||
A `where` clause filters out all objects that do not match a certain condition. You can have multiple `where` clauses if you like, which will have the same effect as combining them with the `and` keyword.
|
||||
|
||||
Here is a simple example based on a custom tag `#person` (see [[Objects]] on how this works):
|
||||
@@ -35,19 +35,19 @@ To query all `person`s that are above age 21, we can use the following `where` c
|
||||
```query
|
||||
person where page = "{{@page.name}}" and age > 21
|
||||
```
|
||||
## `order by` [[@expression]]
|
||||
## order by [[@expression]]
|
||||
To sort results, an `order by` clause can be used, optionally with `desc` to order in descending order (ascending is the default):
|
||||
|
||||
```query
|
||||
person where page = "{{@page.name}}" order by age desc
|
||||
```
|
||||
## `limit` [[@expression]]
|
||||
## limit [[@expression]]
|
||||
To limit the number of results, you can use a `limit` clause:
|
||||
|
||||
```query
|
||||
person where page = "{{@page.name}}" limit 1
|
||||
```
|
||||
## `select`
|
||||
## select
|
||||
You can use the `select` clause to select only specific attributes from the result set. You can use it either simply as `select attribute1, attribute2` but also select the value of certain expressions and give them a name via the `select age + 1 as nextYear` syntax:
|
||||
|
||||
```query
|
||||
@@ -56,22 +56,22 @@ where page = "{{@page.name}}"
|
||||
select name, age, age + 1 as nextYear
|
||||
```
|
||||
|
||||
## `render each [[template]]` and `render all [[template]]`
|
||||
## render each `[[template]]` and render all `[[template]]`
|
||||
$render
|
||||
By default, results are rendered as a table. To instead render results using [[Templates|a template]], use the `render` clause, which comes in two shapes `render each` where the template is instantiated for _each_ result (the `each` keyword is optional):
|
||||
|
||||
```query
|
||||
person
|
||||
where page = "{{@page.name}}"
|
||||
render each [[template/person]]
|
||||
render each [[internal-template/person]]
|
||||
```
|
||||
|
||||
And `render all` where the entire result set is passed to the template as a list so the template can do its own iteration using `#each`, which you could then use to e.g. build a table (using this [[template/people]] template, for instance):
|
||||
And `render all` where the entire result set is passed to the template as a list so the template can do its own iteration using `#each`, which you could then use to e.g. build a table (using this [[internal-template/people]] template, for instance):
|
||||
|
||||
```query
|
||||
person
|
||||
where page = "{{@page.name}}"
|
||||
render all [[template/people]]
|
||||
render all [[internal-template/people]]
|
||||
```
|
||||
# Expressions
|
||||
$expression
|
||||
|
||||
@@ -1,41 +1,24 @@
|
||||
Live Template Widgets allow you to automatically render templated markdown widgets to the top or bottom of pages matching specific criteria.
|
||||
Live Template Widgets allow you to automatically render templated markdown widgets at the top or bottom of pages matching specific criteria.
|
||||
|
||||
> **warning** Warning
|
||||
> This feature is still _experimental_, aspects of it may change, or it could be removed altogether.
|
||||
|
||||
If you have no idea what that means or what you would use this for; you probably don’t need this feature. Don’t worry about it.
|
||||
|
||||
# Defining
|
||||
Live Template Widgets follow the same pattern as other [[Templates]] with a few additional attributes:
|
||||
Live Template Widgets are regular [[Templates]] that set a `hooks.top` or `hooks.bottom` attribute (depending on where you would like them to appear), specifying:
|
||||
|
||||
* `tags`: should be set to `template` as for any other template
|
||||
* `type`: should be set to `widget:top` or `widget:bottom` depending on where you would like it to appear
|
||||
* `where`: should contain an [[Live Queries$expression]] that evaluates to true for the _pages_ you would like to apply this template to, usually this checks for a specific tag, but it can be any expression. Think of this as a `where` clause that should match for the pages this template is applied to.
|
||||
* `priority` (optional): in case you have multiple templates that have matching `where` expression, the one with the priority set to the lowest number wins.
|
||||
* `enabled` (defaults to `true`): in case you want to (temporarily) disable this template, set this to `false`.
|
||||
* `order` (optional): in case you have multiple templates that have matching `where` expression, the one with the priority set to the lowest number wins.
|
||||
|
||||
# Example
|
||||
The following widget template applies to all pages tagged with `person` (see the `where`). It uses the [[!silverbullet.md/template/live/incoming]] template, to show all incomplete tasks that reference this particular page.
|
||||
|
||||
Indeed, you can use [[Live Queries]] and [[Live Templates]] here as well.
|
||||
The following widget template applies to all pages tagged with `person` (see the `where`). It uses the [[Library/Core/Widget/Linked Tasks]] template to show all incomplete tasks that contain a link to the current page.
|
||||
|
||||
---
|
||||
tags: template
|
||||
type: widget:top
|
||||
where: 'tags = "person"'
|
||||
hooks.top.where: 'tags = "person"'
|
||||
---
|
||||
## Incoming tasks
|
||||
```template
|
||||
page: "[[!silverbullet.md/template/live/incoming]]"
|
||||
page: "[[!silverbullet.md/Library/Core/Widget/Linked Tasks]]"
|
||||
```
|
||||
|
||||
## Table of contents
|
||||
The [[Table of Contents]] as it appears on this site is implemented using a template: [[template/widget/toc]].
|
||||
|
||||
## Linked Mentions
|
||||
The [[Linked Mentions]] as they appear on this site are also implemented using a template: [[template/widget/linked-mentions]].
|
||||
|
||||
## Plug widget template
|
||||
This site uses the [[internal-template/plug-widget]] template for pages tagged with `plug`, such as [[Plugs/Editor]], [[Plugs/Github]] and [[Plugs/Mermaid]].
|
||||
|
||||
|
||||
More examples can be found [[Library/Core/Page/Template Index$widgets|here]].
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
Live templates render [[Templates]] inline in a page. They’re called “Live” because their content updates dynamically.
|
||||
Live Templates are a type of [[Blocks|block]] that render [[Templates]] inline in a page.
|
||||
|
||||
## Syntax
|
||||
Live Templates are specified using [[Markdown]]‘s fenced code block notation using `template` as a language. The body of the code block specifies the template to use, as well as any arguments to pass to it.
|
||||
Template blocks are specified using [[Markdown]]‘s fenced code block notation using `template` as a language. The body of the block specifies the template to use, as well as any arguments to pass to it.
|
||||
|
||||
Generally you’d use it in one of two ways, either using a `page` [[Templates|template]] reference, or an inline `template`:
|
||||
|
||||
Here’s an example using `page`:
|
||||
```template
|
||||
page: "[[template/today]]"
|
||||
page: "[[internal-template/today]]"
|
||||
```
|
||||
|
||||
And here’s an example using `template`:
|
||||
@@ -27,12 +26,12 @@ value:
|
||||
You can also pass in the result of a [[Live Queries|query]] as a value by setting the `query` attribute:
|
||||
|
||||
```template
|
||||
query: |
|
||||
tag where parent = "page" select name
|
||||
template: |
|
||||
{{#each .}}
|
||||
* #{{name}}
|
||||
{{/each}}
|
||||
query: |
|
||||
tag where parent = "page" select name
|
||||
```
|
||||
|
||||
If you just want to render the raw markdown without handling it as a handlebars template, set `raw` to true:
|
||||
@@ -41,4 +40,3 @@ template: |
|
||||
This is not going to be {{processed}} by Handlebars
|
||||
raw: true
|
||||
```
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ The biggest hurdle to get over with SilverBullet is that you need to get this th
|
||||
* [[Install]]: Installation instructions for various setups
|
||||
* [[Deployments]]: various deployment options
|
||||
* [[Authelia]]: configuring SilverBullet with [Authelia](https://www.authelia.com/) authentication.
|
||||
* [[Guide/Deployment/Cloudflare and Portainer]]: configuring SilverBullet with a Cloudflare tunnel, portainer and optional Cloudflare zero trust authentication.
|
||||
|
||||
For more additional guides, check out [our community guides](https://community.silverbullet.md/c/guides/6).
|
||||
|
||||
# User interface
|
||||
SilverBullet’s UI is minimalist by design. Let’s look at the few UI elements and how to use them.
|
||||
@@ -21,10 +22,9 @@ SilverBullet’s UI is minimalist by design. Let’s look at the few UI elements
|
||||
* [[Client Modes]] (the 🔄 button)
|
||||
* [[Index Page]] (the 🏠 button)
|
||||
* [[Page Picker]]
|
||||
* [[Template Picker]]
|
||||
* [[Command Palette]]
|
||||
* The main [[Editor]] component contains your page’s text, as well as potentially:
|
||||
* [[Table of Contents]]
|
||||
* [[Linked Mentions]]
|
||||
* The main [[Editor]] component contains your page’s text
|
||||
|
||||
# Core Concepts
|
||||
These are the core concepts used in SilverBullet:
|
||||
@@ -50,7 +50,7 @@ These are the core concepts used in SilverBullet:
|
||||
# Navigation
|
||||
The main ways to roam your space, beside following page links, are:
|
||||
* [[Page Picker]]
|
||||
* [[Linked Mentions]]
|
||||
* [[Template Picker]]
|
||||
* [[Full Text Search]]
|
||||
|
||||
# Advanced topics
|
||||
@@ -58,8 +58,8 @@ The main ways to roam your space, beside following page links, are:
|
||||
* [[Frontmatter]]
|
||||
* [[Attributes]]
|
||||
* [[Live Queries]]
|
||||
* [[Templates]] and [[Live Templates]]
|
||||
* [[Federation]]: it possibly to “sync in” content from outside sources, such as [[Template Sets]]
|
||||
* [[Templates]]
|
||||
* [[Federation]]: it possibly to “sync in” content from outside sources, such as [[Libraries]]
|
||||
|
||||
# Extending SilverBullet
|
||||
A lot of SilverBullet’s functionality is built as [[Plugs]] using the robust [[PlugOS]] extension mechanism. If you are adventurous you can try to build [[Plugs/Development|such plugs yourself]].
|
||||
|
||||
@@ -8,20 +8,4 @@ Currently, SilverBullet provides a few code widgets out of the box:
|
||||
* `embed`
|
||||
* `markdown`
|
||||
|
||||
In addition, plugs like [[Plugs/KaTeX]] and [[Plugs/Mermaid]] add additional ones.
|
||||
|
||||
## `embed`
|
||||
This allows you to embed internet content into your page inside of an iframe. This is useful to embed youtube videos or other websites.
|
||||
and a YouTube video:
|
||||
|
||||
```embed
|
||||
url: https://youtu.be/BbNbZgOwB-Y
|
||||
```
|
||||
|
||||
Note, there is specific support for YouTube videos — it automatically sets the width and height, and replaces the URL with an embed URL.
|
||||
|
||||
The body of an `embed` block is written in [[YAML]] and supports the following attributes:
|
||||
|
||||
* `url` (mandatory): the URL of the content to embed
|
||||
* `height` (optional): the height of the embedded page in pixels
|
||||
* `width` (optional): the width of the embedded page in pixels
|
||||
In addition, plugs like [[Plugs/KaTeX]] and [[Plugs/Mermaid]] add additional ones.
|
||||
@@ -53,10 +53,10 @@ The following query shows all attributes available for tasks:
|
||||
upnext
|
||||
```
|
||||
|
||||
Although you may want to render it using a template such as [[template/task]] instead:
|
||||
Although you may want to render it using a template such as [[Library/Core/Query/Task]] instead:
|
||||
|
||||
```query
|
||||
upnext render [[template/task]]
|
||||
upnext render [[Library/Core/Query/Task]]
|
||||
```
|
||||
|
||||
## taskstate
|
||||
|
||||
@@ -4,7 +4,10 @@ The page picker can be invoked by clicking the 📔 icon in the top bar, or by p
|
||||
|
||||
The main input is the **filter phrase** and can be used to narrow down the list of page results.
|
||||
|
||||
If the filter phrase contains `#tags` the results will be filtered based on matching those tags. That means to quickly see a list of all `#template`s you can use `#template` as a filter phrase.
|
||||
If the filter phrase contains `#tags` the results will be filtered based on matching those tags.
|
||||
|
||||
> **note** Note
|
||||
> [[Templates]], even though technically regular pages, do not appear in the page picker. To navigate to them, use the [[Template Picker]] instead.
|
||||
|
||||
Pressing the `Enter` key will open/create the selected page. Pressing `Shift-Enter` will always open or create (if it doesn't already exist) the page _exactly matching_ the filter phrase. Therefore, if you intend to create a new page, simply type the name of the new page and hit `Shift-Enter`.
|
||||
|
||||
|
||||
@@ -1,11 +1,28 @@
|
||||
The {[Page: From Template]} command enables you to create a new page based on a page template. A page template is a [[Templates|template]] with the `type` attribute (in [[Frontmatter]]) set to `page`.
|
||||
Page templates enable you to define templates for creating new pages. They can be invoked in a few ways:
|
||||
|
||||
* Explicitly using the {[Page: From Template]} command
|
||||
* Explicitly using a custom command configured in the template
|
||||
* Implicitly when configured to be used automatically for a specific _page prefix_.
|
||||
|
||||
A page template is a [[Templates|template]] using the `hooks.newPage` attribute (in [[Frontmatter]]).
|
||||
|
||||
The following configuration options are supported:
|
||||
|
||||
* `suggestedName`: the proposed name for the new page, can use template placeholders such as `{{today}}`.
|
||||
* `confirmName`: Confirm the suggested page name before creating it (defaults to `true`).
|
||||
* `openIfExists`: If a page with the `suggestedName` already exists, open it instead of overwriting it. This is useful to implement page templates like [[Library/Journal/New Page/Daily Note]].
|
||||
* `forPrefix`: automatically apply (or offer, when multiple page templates match) this page template for page names that start with this prefix.
|
||||
* `command`: expose the snippet as a [[Commands|command]].
|
||||
* `key`: Bind the snippet to a keyboard shortcut (note: this requires to _also_ specify the `command` configuration).
|
||||
* `mac`: Bind the snippet to a Mac-specific keyboard shortcut.
|
||||
|
||||
An example:
|
||||
|
||||
---
|
||||
tags: template
|
||||
type: page
|
||||
pageName: "📕 "
|
||||
hooks.newPage:
|
||||
suggestedName: "📕 "
|
||||
forPrefix: "📕 "
|
||||
---
|
||||
# {{@page.name}}
|
||||
As recorded on {{today}}.
|
||||
@@ -14,7 +31,7 @@ An example:
|
||||
## Notes
|
||||
## Conclusions
|
||||
|
||||
Will prompt you to pick a page name (defaulting to “📕 “), and then create the following page (on 2023-08-08) when you pick “📕 Harry Potter” as a page name:
|
||||
When using the {[Page: From Template]} command and selecting this template, this will prompt you to pick a page name (defaulting to “📕 “), and then create the following page (on 2023-08-08) when you pick “📕 Harry Potter” as a page name:
|
||||
|
||||
# 📕 Harry Potter
|
||||
As recorded on 2022-08-08.
|
||||
@@ -23,4 +40,6 @@ Will prompt you to pick a page name (defaulting to “📕 “), and then create
|
||||
## Notes
|
||||
## Conclusions
|
||||
|
||||
In addition, this page template will be used automatically when you create _any_ new page starting with “📕 “ by navigating to a new page matching this prefix, such as “📕 Foundation”.
|
||||
|
||||
As with any [[Templates|template]], the `frontmatter` can be used to define [[Frontmatter]] for the new page.
|
||||
@@ -16,13 +16,13 @@ Plugs are distributed as self-contained JavaScript bundles (ending with `.plug.j
|
||||
# Core plugs
|
||||
These plugs are distributed with SilverBullet and are automatically enabled:
|
||||
```query
|
||||
plug where uri = null order by name render [[template/plug]]
|
||||
plug where uri = null order by name render [[internal-template/plug]]
|
||||
```
|
||||
|
||||
# Third-party plugs
|
||||
These plugs are written either by third parties or distributed separately from the main SB distribution.
|
||||
```query
|
||||
plug where uri != null order by name render [[template/plug]]
|
||||
plug where uri != null order by name render [[internal-template/plug]]
|
||||
```
|
||||
|
||||
Want to develop your own plugs? Have a look at [[Plugs/Development]].
|
||||
@@ -8,5 +8,5 @@ See the [original RFC](https://github.com/silverbulletmd/silverbullet/discussion
|
||||
|
||||
Specific implementations for sharing are implemented in other plugs, specifically:
|
||||
```query
|
||||
plug where shareSupport = true render [[template/page]]
|
||||
plug where shareSupport = true render [[Library/Core/Query/Page]]
|
||||
```
|
||||
|
||||
@@ -48,7 +48,7 @@ There is a [[!silverbullet.md/template/tasks/task]] template you can use to rend
|
||||
Try it (by clicking on the checkbox inside of the query):
|
||||
|
||||
```query
|
||||
task where page = "{{@page.name}}" and name = "Remote toggle me" render [[template/task]]
|
||||
task where page = "{{@page.name}}" and name = "Remote toggle me" render [[Library/Core/Query/Task]]
|
||||
```
|
||||
|
||||
* [ ] Remote toggle me
|
||||
|
||||
@@ -1,20 +1,12 @@
|
||||
This page contains settings for configuring SilverBullet and its Plugs. Changing any of these will go into effect immediately in most cases except `indexPage` and `customStyles`, which require a reload.
|
||||
|
||||
```yaml
|
||||
# Initial page to load when launching SB
|
||||
# Initial page to load when launching SB, can contain template variables
|
||||
indexPage: "[[SilverBullet]]"
|
||||
|
||||
# Load custom CSS styles from the following page, can also be an array
|
||||
customStyles: "[[STYLES]]"
|
||||
|
||||
# Template settings
|
||||
quickNotePrefix: "📥 "
|
||||
dailyNotePrefix: "📅 "
|
||||
dailyNoteTemplate: "[[template/page/Daily Note]]"
|
||||
weeklyNotePrefix: "🗓️ "
|
||||
weeklyNoteTemplate: "[[template/page/Weekly Note]]"
|
||||
weeklyNoteMonday: false
|
||||
|
||||
# It is possible to override keyboard shortcuts and command priority
|
||||
shortcuts:
|
||||
- command: "{[Stats: Show]}" # Using the command link syntax here
|
||||
|
||||
@@ -15,13 +15,11 @@ You were told wrong.
|
||||
* [[Install]]: how to install and deploy SilverBullet.
|
||||
* [[Manual]]: how to use this thing.
|
||||
* [[CHANGELOG]]: we’re in active development, so things change rapidly, watch this page to keep up.
|
||||
* Development:
|
||||
* [Roadmap](https://github.com/orgs/silverbulletmd/projects/2/views/1): currently planned features and priorities.
|
||||
* [Issues](https://github.com/silverbulletmd/silverbullet/issues): if you have ideas, or find bugs, please report them.
|
||||
* [Discussions](https://github.com/silverbulletmd/silverbullet/discussions): got ideas for features or questions? Ask them here.
|
||||
* Socials:
|
||||
* [Mastodon](https://fosstodon.org/@silverbulletmd): follow SilverBullet development on [Mastodon](https://joinmastodon.org/)
|
||||
* [Discord](https://discord.gg/EvXbFucTxn): for more real-time support and discussion, join our Discord!
|
||||
* [Roadmap](https://github.com/orgs/silverbulletmd/projects/2/views/1): currently planned features and priorities.
|
||||
* [Issues](https://github.com/silverbulletmd/silverbullet/issues): if you have ideas, or find bugs, please report them.
|
||||
* [Community](https://community.silverbullet.md): join our discourse community!
|
||||
* [Discord](https://discord.gg/EvXbFucTxn): for more real-time support and discussion!
|
||||
* [Mastodon](https://fosstodon.org/@silverbulletmd): follow SilverBullet development on [Mastodon](https://joinmastodon.org/)
|
||||
|
||||
# Features
|
||||
Some highlights:
|
||||
@@ -29,13 +27,13 @@ Some highlights:
|
||||
* SilverBullet runs in any modern browser (including mobile ones) as a [[PWA]] in two [[Client Modes]] ([[Client Modes$online|online]] and [[Client Modes$sync|synced]] mode), where the _synced mode_ enables **100% offline operation**, keeping a copy of content in the browser’s local ([IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API)) database, syncing back to the server when a network connection is available.
|
||||
* SilverBullet provides an enjoyable [[Markdown]] writing experience with a clean UI, rendering text using [[Live Preview|live preview]], further **reducing visual noise** while still providing direct access to the underlying markdown syntax.
|
||||
* SilverBullet supports wiki-style **page linking** using the `[[page link]]` syntax. Incoming links are indexed and appear as [[Linked Mentions]] at the bottom of the pages linked to thereby providing _bi-directional linking_.
|
||||
* SilverBullet allows you to boost your writing/knowledge collection productivity using its various [[Templates]] mechanism.
|
||||
* SilverBullet is optimized for **keyboard-based operation**:
|
||||
* Quickly navigate between pages using the **page switcher** (triggered with `Cmd-k` on Mac or `Ctrl-k` on Linux and Windows).
|
||||
* Run commands via their keyboard shortcuts or the **command palette** (triggered with `Cmd-/` or `Ctrl-/` on Linux and Windows).
|
||||
* Use [[Slash Commands]] to perform common text editing operations.
|
||||
* SilverBullet is a platform for [[End-User Programming]] through its support for [[Objects]], [[Live Queries]] and [[Live Templates]], allowing to make parts of your pages _dynamic_.
|
||||
* SilverBullet can be extended using [[Plugs]].
|
||||
* SilverBullet is a platform for [[End-User Programming]] through its support for [[Objects]], [[Live Queries]], [[Live Templates]] and [[Live Template Widgets]], allowing to make parts of your pages and UI dynamic.
|
||||
* SilverBullet allows you to boost your writing/knowledge collection productivity using its various [[Templates]] mechanism.
|
||||
* SilverBullet can be extended using [[Libraries]] and [[Plugs]].
|
||||
* **Self-hosted**: you own your data. All content is stored as plain files in a folder on disk (if you so choose). Back up, sync, edit, publish, script with any additional tools you like.
|
||||
* SilverBullet is free, [**open source**, MIT licensed](https://github.com/silverbulletmd/silverbullet) software.
|
||||
|
||||
@@ -87,10 +85,10 @@ function helloWorld() {
|
||||
# Beyond Markdown
|
||||
Where things get slightly more interesting is when using features like [[Live Queries]] that allow you to query all types of [[Objects]] indexed based on the pages in your [[Spaces]].
|
||||
|
||||
Let’s explore this with a meta example of using this functionality for this very website. All pages in this space that represent a [[Plugs|plug]] are tagged with the `#plug` [[Tags|tag]]. Now, if we want to render a list of all plugs in one place using the [[template/plug]] template, we can simply do this as follows:
|
||||
Let’s explore this with a meta example of using this functionality for this very website. All pages in this space that represent a [[Plugs|plug]] are tagged with the `#plug` [[Tags|tag]]. Now, if we want to render a list of all plugs in one place using the [[internal-template/plug]] template, we can simply do this as follows:
|
||||
|
||||
```query
|
||||
plug render [[template/plug]]
|
||||
plug render [[internal-template/plug]]
|
||||
```
|
||||
|
||||
Hover over that list and click the edit button to see the query that generates this view.
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
Slash commands are built-in to SilverBullet. You can trigger them by typing a `/` in your text (after whitespace).
|
||||
Slash commands are quick ways to perform repetitive tasks, 99% of the time this will mean inserting a [[Snippets|snippet]].
|
||||
|
||||
The [[Plugs/Editor]] plug provides a few helpful ones:
|
||||
You can trigger a slash command by typing a `/` in your text (after some white space).
|
||||
|
||||
* `/h1` through `/h4` to turn the current line into a header
|
||||
* `/hr` to insert a horizontal rule (`---`)
|
||||
* `/table` to insert a markdown table (whoever can remember this syntax without it)
|
||||
* `/today` to insert today’s date
|
||||
* `/tomorrow` to insert tomorrow’s date
|
||||
|
||||
You can create custom slash commands using [[Slash Templates]].
|
||||
Technically, no slash commands ship with SilverBullet directly. However, you can easily add useful ones via [[Libraries]].
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
Slash templates allow you to define custom [[Slash Commands]] that expand “snippet style” templates inline.
|
||||
|
||||
# Definition
|
||||
You can define a slash template by creating a [[Templates|template page]] with a template tag and `trigger` attribute. If you’d like to (temporarily) disable the template, you can set the `enabled` attribute to `false`.
|
||||
|
||||
Example:
|
||||
|
||||
---
|
||||
tags: template
|
||||
trigger: meeting-notes
|
||||
---
|
||||
## Meeting notes for {{today}}!
|
||||
|
||||
|^|
|
||||
|
||||
## Frontmatter
|
||||
A template’s [[Frontmatter]] is interpreted by SilverBullet’s [[Templates|template]] engine and removed when instantiated. However, to still include frontmatter after instantiation, you can use the `frontmatter` attribute.
|
||||
|
||||
Example:
|
||||
|
||||
---
|
||||
tags: template
|
||||
trigger: meeting-notes
|
||||
frontmatter: |
|
||||
date: {{today}}
|
||||
---
|
||||
## Meeting notes for {{today}}!
|
||||
|
||||
|^|
|
||||
|
||||
Which will expand into e.g.
|
||||
|
||||
---
|
||||
date: 2023-11-11
|
||||
---
|
||||
## Meeting notes for 2023-11-11
|
||||
|
||||
.
|
||||
|
||||
When the page already contains frontmatter before invoking the slash command, it will be augmented with the additional frontmatter specified by the template.
|
||||
|
||||
# Use
|
||||
You can _trigger_ the slash template by typing `/<trigger>` (e.g. `/meeting-notes`) in any page.
|
||||
@@ -0,0 +1,51 @@
|
||||
Snippets allow you to define custom [[Slash Commands]] that expand snippet style templates inline.
|
||||
|
||||
# Definition
|
||||
You define a snippet by creating a [[Templates|template]] with a `hooks.snippet` attribute that configures the snippet. The following configuration options are supported:
|
||||
|
||||
* `slashCommand`: expose the snippet via the `/my-snippet` notation.
|
||||
* `command`: expose the snippet as a [[Commands|command]].
|
||||
* `key`: Bind the snippet to a keyboard shortcut (note: this requires to _also_ specify the `command` configuration).
|
||||
* `mac`: Bind the snippet to a Mac-specific keyboard shortcut.
|
||||
* `matchRegex` (advanced use only): match the current line against a regular expression, and replace the match with the template’s body.
|
||||
* `insertAt`: by default a snippet is inserted at the cursor position, but alternatively it can be inserted at: `line-start`, `line-end`, `page-start` or `page-end`.
|
||||
|
||||
Minimal example:
|
||||
|
||||
---
|
||||
tags: template
|
||||
hooks.snippet:
|
||||
slashCommand: meeting-notes
|
||||
---
|
||||
## Meeting notes for {{today}}!
|
||||
|
||||
|^|
|
||||
|
||||
## Frontmatter
|
||||
A template’s [[Frontmatter]] is interpreted by SilverBullet’s [[Templates|template]] engine and removed when instantiated. However, to inject frontmatter after instantiation, you can use the `frontmatter` attribute.
|
||||
|
||||
Example:
|
||||
|
||||
---
|
||||
tags: template
|
||||
hooks.snippet.slashCommand: meeting-notes
|
||||
frontmatter: |
|
||||
date: {{today}}
|
||||
---
|
||||
## Meeting notes for {{today}}!
|
||||
|
||||
|^|
|
||||
|
||||
Which will expand into e.g.
|
||||
|
||||
---
|
||||
date: 2023-11-11
|
||||
---
|
||||
## Meeting notes for 2023-11-11
|
||||
|
||||
.
|
||||
|
||||
When the page already contained frontmatter before inserting the snippet, it will be augmented with the additional frontmatter specified by the template.
|
||||
|
||||
# Use
|
||||
A snippet can be _triggered_ via the specified `slashCommand` via `/slashCommand` or via {[Open Command Palette]} and/or its associate key bindings when `command`, `key`/`mac` are specified.
|
||||
@@ -1,4 +1,4 @@
|
||||
You can add a table of contents to a page using the `toc` [[Markdown/Code Widgets|Code Widget]].
|
||||
You can add a table of contents to a page using `toc` [[Blocks]].
|
||||
|
||||
In its most basic form it looks like this (click the edit button to see the code):
|
||||
|
||||
@@ -10,12 +10,7 @@ You can use it in two ways:
|
||||
1. _Manually_, by adding a `toc` widget to the pages where you’d like to render a ToC
|
||||
2. _Automatically_, using a [[Live Template Widgets|Live Template Widget]]
|
||||
|
||||
To have a ToC added to all pages with a larger (e.g. 3) number of headings, it is recommended to use [[template/widget/toc|this template widget]]. You can do this by either copy and pasting it into your own space, or by using [[Federation]] and have it included in your space that way:
|
||||
|
||||
```yaml
|
||||
federation:
|
||||
- uri: silverbullet.md/template/widget/toc
|
||||
```
|
||||
To have a ToC added to all pages with a larger (e.g. 3) number of headings, it is recommended to use [[Library/Core/Widget/Table of Contents|this template widget]].
|
||||
|
||||
## Configuration
|
||||
In the body of the `toc` code widget you can configure a few options:
|
||||
@@ -29,3 +24,5 @@ Example:
|
||||
header: false
|
||||
minHeaders: 1
|
||||
```
|
||||
|
||||
Want to add a table of contents to all your pages automatically? You can — that’s functionality available via the [[Library/Core]] library.
|
||||
@@ -0,0 +1 @@
|
||||
The template picker is used to navigate between [[Templates]]. Functionally it’s equivalent to the [[Page Picker]] except that it only shows pages tagged with `template`.
|
||||
@@ -1,66 +0,0 @@
|
||||
> **warning** Experimental
|
||||
> This is still an experimental idea. These templates may change, be renamed etc. prepare yourself for breakage.
|
||||
|
||||
This is an attempt at collecting useful, reusable templates so you don’t have to reinvent the wheel.
|
||||
|
||||
While you may just copy & paste these templates to your own space, the most convenient ways to use them is using [[Federation]]. This will synchronize these templates into your space and make them available for use instantly.
|
||||
|
||||
To set this up, add the following to your [[SETTINGS]]:
|
||||
|
||||
```yaml
|
||||
federate:
|
||||
- uri: silverbullet.md/template
|
||||
```
|
||||
|
||||
If you don’t want to sync _all_ these templates, you can use more specific URIs, e.g.
|
||||
```yaml
|
||||
federate:
|
||||
- uri: silverbullet.md/template/page/
|
||||
```
|
||||
to just get the page templates, for instance.
|
||||
|
||||
To reference a template, use the [[Federation]] syntax, e.g. `[[!silverbullet.md/template/task]]`.
|
||||
|
||||
# Page Templates
|
||||
Use these [[Page Templates]] with the {[Page: From Template]} command.
|
||||
|
||||
```query
|
||||
template where type = "page" render [[template/documented-template]]
|
||||
```
|
||||
|
||||
# Slash Templates
|
||||
These can be used as [[Slash Templates]]:
|
||||
|
||||
```query
|
||||
template where type = "slash" render [[template/documented-template]]
|
||||
```
|
||||
|
||||
# Live Templates
|
||||
Use these as `page` in [[Live Templates]].
|
||||
|
||||
```query
|
||||
template
|
||||
where type = "live"
|
||||
order by order
|
||||
render [[template/documented-template]]
|
||||
```
|
||||
|
||||
# Live Query
|
||||
Use these in your `render` clauses in [[Live Queries]].
|
||||
|
||||
```query
|
||||
template
|
||||
where type = "query"
|
||||
order by order
|
||||
render [[template/documented-template]]
|
||||
```
|
||||
|
||||
# Live Widget Templates
|
||||
Use these to add various useful [[Live Template Widgets]] to your pages.
|
||||
|
||||
```query
|
||||
template
|
||||
where type =~ /^widget:/ and name =~ /^template\//
|
||||
order by order
|
||||
render [[template/documented-template]]
|
||||
```
|
||||
@@ -1,54 +1,52 @@
|
||||
Templates are reusable pieces of markdown content, usually with placeholders that are replaced once instantiated.
|
||||
Templates are reusable pieces of (markdown) content, often containing placeholders that are replaced once instantiated.
|
||||
|
||||
There are two general uses for templates:
|
||||
Templates are kept in your space. They’re effectively regular [[Pages]], and are [[Tags|tagged]] with the `template` tag.
|
||||
|
||||
Templates do not appear in the [[Page Picker]], but instead appear in the [[Template Picker]]. They are not offered as auto complete suggestions when creating regular page links, only when doing so in the context of e.g. a [[Live Queries]] and [[Live Templates]].
|
||||
|
||||
In SilverBullet templates serve a few purposes:
|
||||
|
||||
1. _Live_ uses, where page content is dynamically updated based on templates:
|
||||
* [[Live Queries]]
|
||||
* [[Live Templates]]
|
||||
* [[Live Template Widgets]]
|
||||
2. _One-off_ uses, where a template is instantiated once and inserted into an existing or new page:
|
||||
* [[Slash Templates]]
|
||||
* [[Snippets]]
|
||||
* [[Page Templates]]
|
||||
|
||||
# Creating templates
|
||||
# Definition
|
||||
Templates are regular pages [[Tags|tagged]] with the `#template` tag. Note that, when tagged inline (by putting `#template` at the beginning of the page), the tag will be removed when the template is instantiated.
|
||||
|
||||
**Naming**: it’s common, although not required, to use a `template/` prefix when naming templates.
|
||||
|
||||
Tagging a page with a `#template` tag (either in the [[Frontmatter]] or using a [[Tags]] at the very beginning of the page content) does a few things:
|
||||
|
||||
1. It will make the page appear when completing template names, e.g. in `render` clauses in [[Live Queries]], or after the `page` key in [[Live Templates]].
|
||||
2. It excludes the page from being indexed for [[Objects]], that is: any tasks, items, paragraphs etc. will not appear in your space’s object database. Which is usually what you want.
|
||||
3. It registers your templates to be used as [[Slash Templates]] as well as [[Page Templates]].
|
||||
1. It will make the page appear when completing template names, e.g. in `render` clauses in [[Live Queries]], or after the `page` key in [[Live Templates]].
|
||||
2. The template page no longer appear in the [[Page Picker]], instead you now navigate to it using the [[Template Picker]].
|
||||
4. It can register your templates to be used as [[Snippets]], [[Page Templates]] or [[Live Template Widgets]].
|
||||
|
||||
## Frontmatter
|
||||
[[Frontmatter]] has special meaning in templates. The following attributes are used:
|
||||
|
||||
* `tags`: should always be set to `template`
|
||||
* `type` (optional): should be set to `page` for [[Page Templates]] and to `frontmatter` for [[Live Template Widgets]]
|
||||
* `trigger` (optional): defines the slash command name for [[Slash Templates]]
|
||||
* `displayName` (optional): defines an alternative name to use when e.g. showing the template picker for [[Page Templates]], or when template completing a `render` clause in a [[Live Templates]].
|
||||
* `pageName` (optional, [[Page Templates]] only): specify a (template for a) page name.
|
||||
* `frontmatter` (optional): defines [[Frontmatter]] to be added/used in the rendered template. This can either be specified as a string or as an object.
|
||||
* `description` (optional): may appear in various UIs to give more information about the template.
|
||||
* `frontmatter` (optional): defines [[Frontmatter]] to be added/used in the _rendered_ template. This can either be specified as a string or as an object.
|
||||
* `hooks` (optional): hook the template into various parts of the system, look at [[Page Templates]], [[Snippets]] and [[Live Template Widgets]] for details.
|
||||
|
||||
An example:
|
||||
|
||||
---
|
||||
tags: template
|
||||
type: page
|
||||
trigger: one-on-one
|
||||
displayName: "1:1 template"
|
||||
pageName: "1-1s/"
|
||||
hooks.newPage.suggestedName: "Meetings/{{today}}"
|
||||
frontmatter:
|
||||
dateCreated: "{{today}}"
|
||||
---
|
||||
# {{today}}
|
||||
* |^|
|
||||
|
||||
# Template content
|
||||
Templates consist of markdown, but can also include [Handlebars syntax](https://handlebarsjs.com/), such as `{{today}}`, and `{{#each .}}`.
|
||||
# Content
|
||||
Templates consist of plain markdown text, but can also include [Handlebars syntax](https://handlebarsjs.com/), such as `{{today}}`, and `{{#each .}}`.
|
||||
|
||||
The special `|^|` marker can be used to specify the desired cursor position after the template is included.
|
||||
A special `|^|` marker can be used to specify the desired cursor position after the template is included.
|
||||
|
||||
## Handlebar helpers
|
||||
There are a number of built-in handlebars helpers you can use:
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
#template
|
||||
* Person **{{name}}** has {{age}}
|
||||
@@ -0,0 +1,2 @@
|
||||
#template
|
||||
Today is {{today}}!
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
tags: template
|
||||
type: query
|
||||
order: 100
|
||||
description: |
|
||||
Renders its object value in a `key: value` format
|
||||
usage: |
|
||||
Can be used by passing in a YAML object in a template via `value` or in a `render` clause of a query
|
||||
---
|
||||
{{#each .}}
|
||||
{{@key}}: {{.}}
|
||||
{{/each}}
|
||||
|
||||
---
|
||||
@@ -1,5 +0,0 @@
|
||||
#template
|
||||
* [[{{ref}}|{{#if displayName}}{{displayName}}{{else}}{{ref}}{{/if}}]] {{description}}
|
||||
{{#if usage}}
|
||||
* **Usage:** {{usage}}
|
||||
{{/if}}
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
tags: template
|
||||
type: live
|
||||
description: Lists all pages with ".conflicted" in the name, created as a result of a synchronization conflict.
|
||||
---
|
||||
|
||||
### Conflicting pages
|
||||
```query
|
||||
page where name =~ /\.conflicted/ render [[template/pages/page]]
|
||||
```
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
tags: template
|
||||
type: live
|
||||
description: |
|
||||
Shows all tasks that reference (tag) the current page. For instance a task that references `[[John]]` in its name, would appear on the `John` page if it would use this [[sets/tasks/incoming]] template.
|
||||
order: 2
|
||||
---
|
||||
|
||||
```query
|
||||
task where name =~ /\[\[{{escapeRegexp @page.name}}\]\]/ where done = false render [[template/task]]
|
||||
```
|
||||