Fix website typos (#584)
This commit is contained in:
parent
fc6165000c
commit
6922bde451
@ -1,4 +1,4 @@
|
||||
Attribute syntax can contribute additional [[Metadata]] to various [[Objects]] including:
|
||||
Attribute syntax can contribute additional [[Metadata]] to various [[Objects]], including:
|
||||
|
||||
* Pages
|
||||
* Items
|
||||
@ -13,7 +13,7 @@ The syntax is as follows:
|
||||
|
||||
For Obsidian/LogSeq compatibility, you can also double the colon like this: `[attributeName:: value]`
|
||||
|
||||
Attribute names need to be alpha numeric. Values are interpreted as [[YAML]] values. So here are some examples of valid attribute definitions:
|
||||
Attribute names need to be alpha-numeric. Values are interpreted as [[YAML]] values. So here are some examples of valid attribute definitions:
|
||||
|
||||
* string: [attribute1: sup]
|
||||
* number: [attribute2: 10]
|
||||
@ -28,7 +28,7 @@ Depending on where these attributes appear, they attach to different things. For
|
||||
|
||||
[pageAttribute: hello]
|
||||
|
||||
However, usually [[Frontmatter]] is be used for this purpose instead.
|
||||
However, usually, [[Frontmatter]] is used for this purpose instead.
|
||||
|
||||
Example query:
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
How to setup SilverBullet with Authelia
|
||||
|
||||
In order for SilverBullet to work as intended, some files will need to be excluded from your authentication method of choice. These files need to always be accessible, for example for offline or [[PWA]] support.
|
||||
For SilverBullet to work as intended, some files will need to be excluded from your authentication method of choice. These files always need to be accessible, for example for offline or [[PWA]] support.
|
||||
|
||||
The files are the following:
|
||||
- The web manifest
|
||||
|
@ -12,7 +12,7 @@ silverbullet --user pete:1234 .
|
||||
Will let `pete` authenticate with password `1234`.
|
||||
|
||||
## Multiple users
|
||||
Although multi-user support is still rudimentary, it is possible to have multiple users authenticate. These users can be configured using an JSON authentication file that SB can generate for you. It is usually named `.auth.json`.
|
||||
Although multi-user support is still rudimentary, it is possible to have multiple users authenticate. These users can be configured using a JSON authentication file that SB can generate for you. It is usually named `.auth.json`.
|
||||
|
||||
You can enable authentication as follows:
|
||||
|
||||
@ -20,7 +20,7 @@ You can enable authentication as follows:
|
||||
silverbullet --auth /path/to/.auth.json
|
||||
```
|
||||
|
||||
To create and manage an `.auth.json` file you can use the following commands:
|
||||
To create and manage an `.auth.json` file, you can use the following commands:
|
||||
|
||||
* `silverbullet user:add --auth /path/to/.auth.json [username]` to add a user
|
||||
* `silverbullet user:delete --auth /path/to/.auth.json [username]` to delete a user
|
||||
@ -31,7 +31,7 @@ If the `.auth.json` file does not yet exist, it will be created.
|
||||
When SB is run with a `--auth` flag, this fill will automatically be reloaded upon change.
|
||||
|
||||
### Group management
|
||||
While this functionality is not yet used, users can also be added to groups, which can be arbitrarily named. Likely the `admin` group will have special meaning down the line.
|
||||
While this functionality is not yet used, users can also be added to groups which can be arbitrarily named. The `admin` group will likely have a special meaning down the line.
|
||||
|
||||
When adding a user, you can add one more `-G` or `--group` flags:
|
||||
|
||||
|
@ -5,7 +5,7 @@ SilverBullet currently supports two modes for its client (the part of SilverBull
|
||||
|
||||
You can toggle between these two modes by toggling the 🔄 button in the top bar.
|
||||
|
||||
You can switch modes any time, and use different modes on different devices.
|
||||
You can switch modes any time and use different modes on different devices.
|
||||
|
||||
**Note:** It is technically possible to _switch off online mode_ (and allow synced mode only) by running the SilverBullet server with the `--sync-only` flag (or setting the `SB_SYNC_ONLY` environment variable to something). With this flag on, the sync button will not appear in the UI.
|
||||
|
||||
@ -14,11 +14,11 @@ In online mode, all content in your space is kept on the server, and a lot of th
|
||||
|
||||
Advantages:
|
||||
* **Keeps content on the server**: this mode does not synchronize all your content to your client (browser), making this a better fit for large spaces or for cases where you only need to quickly login to SilverBullet to check something, e.g. on a device you don’t usually use. This use case is the reason why this is the default mode.
|
||||
* **Lighter-weight** in terms of memory and CPU use of the client.
|
||||
* **Lighter weight** in terms of memory and CPU use of the client.
|
||||
|
||||
Disadvantages:
|
||||
* **Requires a working network connection** to the server. You can not load pages, nor successfully persist changes without it.
|
||||
* **Higher latency**, since more interactions require calls to the server, this may be notable e.g., when completing page names.
|
||||
* **Requires a working network connection** to the server. You can not load pages nor successfully persist changes without it.
|
||||
* **Higher latency** since more interactions require calls to the server, this may be notable e.g., when completing page names.
|
||||
|
||||
## Synced mode
|
||||
In this mode, all content is synchronized to the client, and all processing happens there. The server effectively acts as a “dumb data store.” All SilverBullet functionality is available even when there is no network connection available.
|
||||
|
@ -1,6 +1,6 @@
|
||||
Frontmatter is a common format to attach additional metadata (data about data) to markdown documents.
|
||||
|
||||
In SilverBullet there are multiple ways to attach [[Metadata]] to a page, frontmatter is one of them.
|
||||
In SilverBullet, there are multiple ways to attach [[Metadata]] to a page; frontmatter is one of them.
|
||||
|
||||
You create it by starting your markdown document with `---` followed by [[YAML]] encoded attributes and then ending with `---` again. Followed by the regular body of your document.
|
||||
|
||||
@ -18,6 +18,6 @@ Here is an example:
|
||||
SilverBullet allows arbitrary metadata to be added to pages this way, with two exceptions:
|
||||
|
||||
* `name` is an attribute used for page names, so don’t attempt to override it in frontmatter
|
||||
* `tags` can be specified (as in the example) and are in effect another way of adding tags to your page, you can achieve the same result by simply adding hashtags in the body of your document, e.g. `#tag1 #tag2`.
|
||||
* `tags` can be specified (as in the example) and are, in effect, another way of adding tags to your page. You can achieve the same result by simply adding hashtags in the body of your document, e.g. `#tag1 #tag2`.
|
||||
|
||||
SilverBullet also has the _convention_ of using attributes starting with a `$` for internal use. For instance, the sharing capability uses the `$share` attribute, and `$disableDirectives: true` has the special meaning of disabling [[🔌 Directive]] processing on a page.
|
@ -1,17 +1,17 @@
|
||||
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.
|
||||
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 Clouflare in Portainer
|
||||
# 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.
|
||||
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**".
|
||||
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**".
|
||||
![](Guide/Deployment/Cloudflare%20and%20Portainer/create-custom-template.png)
|
||||
|
||||
### Name
|
||||
@ -20,7 +20,7 @@ Choose a name for the silverbullet stack, we chose "**silverbullet-docker**", ve
|
||||
|
||||
### Description
|
||||
|
||||
Fill the description with your own words, this is up to you because is optional.
|
||||
Fill the description with your own words; this is up to you because it is optional.
|
||||
|
||||
### Icon Url
|
||||
|
||||
@ -36,7 +36,7 @@ Standalone
|
||||
|
||||
### Build Method
|
||||
|
||||
As for the Build method choose “**Web Editor**” and copy paste this ==docker-compose.yaml== configuraiton:
|
||||
As for the Build method choose “**Web Editor**” and copy-paste this ==docker-compose.yaml== configuration:
|
||||
|
||||
```yaml
|
||||
version: '3.9'
|
||||
@ -102,7 +102,7 @@ You can leave all the other options by default or change them to suit your netwo
|
||||
Click **Create Network** at the bottom of the page.
|
||||
![](Guide/Deployment/Cloudflare%20and%20Portainer/create-network-4.png)
|
||||
|
||||
## Depolying the Stack
|
||||
## Deploying the Stack
|
||||
|
||||
Go to **Home** > **Local** > **App Templates** > **Custom Templates**.
|
||||
|
||||
@ -112,29 +112,29 @@ Click on **Deploy the stack**.
|
||||
![](Guide/Deployment/Cloudflare%20and%20Portainer/deploy-stack-2.png)
|
||||
Give it a few seconds and you will get a notification that both containers are running. 😇
|
||||
|
||||
Only silverbullet cointaer should be working properly by this point, as we haven't finished with cloudflare yet.
|
||||
Only the silverbullet container should be working properly by this point, as we haven't finished with Cloudflare yet.
|
||||
![](Guide/Deployment/Cloudflare%20and%20Portainer/view-containers-1.png)
|
||||
|
||||
## 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:
|
||||
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 conecttion to silverbullet is **HTTP** and PWA([Progressive Web Apps](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps)) an 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.
|
||||
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.
|
||||
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).
|
||||
* 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.
|
||||
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
|
||||
|
||||
@ -151,15 +151,15 @@ Click on **Zero Trust** once you have added your site/domain name.
|
||||
![](Guide/Deployment/Cloudflare%20and%20Portainer/setup-tunnel-1.png)
|
||||
Click on **Create Tunnel**.
|
||||
![](Guide/Deployment/Cloudflare%20and%20Portainer/setup-tunnels-2.png)
|
||||
Choose a name for your tunnel, I chose "myhome", very imaginative again 😛. And click on **Save Tunnel**.
|
||||
Choose a name for your tunnel, I chose "myhome", very imaginative again 😛. And then click on **Save Tunnel**.
|
||||
![](Guide/Deployment/Cloudflare%20and%20Portainer/setup-tunnels-3.png)
|
||||
|
||||
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 will be able to make a tunnel connection to your server.
|
||||
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.
|
||||
![](Guide/Deployment/Cloudflare%20and%20Portainer/setup-tunnels-4_2.png)
|
||||
|
||||
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 Tempaltes** > **Custom Templates** > **Edit**.
|
||||
Go to **App Templates** > **Custom Templates** > **Edit**.
|
||||
![](Guide/Deployment/Cloudflare%20and%20Portainer/deploy-stack-3.png)
|
||||
Replace “your-token-value-here!” with your token value.
|
||||
![](Guide/Deployment/Cloudflare%20and%20Portainer/setup-tunnels-6.png)
|
||||
@ -199,21 +199,21 @@ Leave the rest of the page as default and click **Next** at the bottom of the pa
|
||||
|
||||
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 by default.
|
||||
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 range of IPs, specific countries...) for verification, and enter the emails you want to allow access to Silverbullet.
|
||||
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.
|
||||
![](Guide/Deployment/Cloudflare%20and%20Portainer/add-application-clodflare-5.png)
|
||||
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 **silberbullet.your-domain-name.com** and you should see a page like this:
|
||||
Go to **silverbullet.your-domain-name.com** and you should see a page like this:
|
||||
![](Guide/Deployment/Cloudflare%20and%20Portainer/add-application-clodflare-6.png)
|
||||
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 followings **pahts**:
|
||||
And add the following **paths**:
|
||||
|
||||
```
|
||||
.client/manifest.json
|
||||
@ -223,16 +223,16 @@ service_worker.js
|
||||
|
||||
Leave the rest as default and click **Next** at the bottom of the page.
|
||||
![](Guide/Deployment/Cloudflare%20and%20Portainer/add-application-clodflare-7.png)
|
||||
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.
|
||||
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.
|
||||
![](Guide/Deployment/Cloudflare%20and%20Portainer/add-application-clodflare-8.png)
|
||||
These rules only take affect on the specific paths, you can read more about [Policy inheritance on Cloudflare.](https://developers.cloudflare.com/cloudflare-one/policies/access/app-paths/)
|
||||
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.
|
||||
|
||||
Right now the conecttion to silverbullet is **HTTPS** and PWA ([Progressive Web Apps](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps)) an offline mode will work now.
|
||||
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.
|
@ -1,7 +1,7 @@
|
||||
Live Queries enable a (quasi) live view on various data sources, usually [[Objects]], and renders their results inline via [[Live Preview]] either as a template, or using [[Templates]].
|
||||
Live Queries enable a (quasi) live view on various data sources, usually [[Objects]], and renders their results inline via [[Live Preview]] either as a template or using [[Templates]].
|
||||
|
||||
# Syntax
|
||||
The syntax of live queries are inspired by [SQL](https://en.wikipedia.org/wiki/SQL). Below is a query that demonstrates some of the supported clauses, hover over the result and click the edit icon to shows the code that generates the view:
|
||||
The syntax of live queries is inspired by [SQL](https://en.wikipedia.org/wiki/SQL). Below is a query that demonstrates some of the supported clauses. Hover over the result and click the edit icon to show the code that generates the view:
|
||||
```query
|
||||
page
|
||||
order by lastModified desc
|
||||
@ -12,7 +12,7 @@ render [[template/page]]
|
||||
```
|
||||
It’s most convenient to use `/query` [[Slash Commands]] 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).
|
||||
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.
|
||||
|
||||
@ -36,7 +36,7 @@ To query all `person`s that are above age 21, we can use the following `where` c
|
||||
person where page = "{{@page.name}}" and age > 21
|
||||
```
|
||||
## `order by` [[@expression]]
|
||||
In order to sort results, a `order by` clause can be used, optionally with `desc` to order in descending order (ascending is the default):
|
||||
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
|
||||
@ -48,7 +48,7 @@ To limit the number of results, you can use a `limit` clause:
|
||||
person where page = "{{@page.name}}" limit 1
|
||||
```
|
||||
## `select`
|
||||
To select only specific attributes from the result set, you can use the `select` clause. 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:
|
||||
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
|
||||
person
|
||||
@ -58,7 +58,7 @@ select name, age, age + 1 as nextYear
|
||||
|
||||
## `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):
|
||||
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
|
||||
@ -66,7 +66,7 @@ where page = "{{@page.name}}"
|
||||
render each [[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 [[template/people]] template, for instance):
|
||||
|
||||
```query
|
||||
person
|
||||
@ -94,8 +94,8 @@ Logical expressions:
|
||||
|
||||
Binary expressions:
|
||||
* `=` equals.
|
||||
* For scalar values this performance an equivalence tests (e.g. `10 = 10`)
|
||||
* If the left operand is an array and the right operand is _not_, this will will check if the right operand is _included_ in the left operand’s value, e.g. `[1, 2, 3] = 2` will be true.
|
||||
* For scalar values this performs an equivalence test (e.g. `10 = 10`)
|
||||
* If the left operand is an array and the right operand is _not_, this will check if the right operand is _included_ in the left operand’s value, e.g. `[1, 2, 3] = 2` will be true.
|
||||
* If both operands are arrays, they will be compared for equivalence ignoring order, so this will be true: `[1, 2, 3] = [3, 2, 1]`
|
||||
* `!=` the exact inverse of the meaning of `=`, e.g. `name != "Pete"`
|
||||
* `<` less than, e.g. `age < 10`
|
||||
|
@ -1,9 +1,9 @@
|
||||
Welcome to wonderful world of SilverBullet. The goal of this manual is to give you a broad sense of how to use this tool, and what it’s capable of. However, its full capabilities are yet to be discovered. Every day people are finding new and creative ways to use the various SilverBullet features in ways that nobody previously thought of. Perhaps you will be one of those people.
|
||||
Welcome to wonderful world of SilverBullet. The goal of this manual is to give you a broad sense of how to use this tool and what it’s capable of. However, its full capabilities are yet to be discovered. Every day, people find new and creative ways to use the various SilverBullet features in ways nobody previously thought of. Perhaps you will be one of those people.
|
||||
|
||||
That is unlikely to happen unless you understand some of the basics, however. So let’s start tjere.
|
||||
However, that is unlikely to happen unless you understand some of the basics. So let’s start there.
|
||||
|
||||
> **warning** Warning
|
||||
> This manual is **very** much a work in progress
|
||||
> This manual is **very** much a work in progress.
|
||||
|
||||
## Keeping up-to-date
|
||||
* [[CHANGELOG]]: what’s new in SilverBullet
|
||||
@ -13,7 +13,7 @@ That is unlikely to happen unless you understand some of the basics, however. So
|
||||
* [[Deployments]]: various deployment options
|
||||
* [[Install/Deno Deploy|Deploying on Deno Deploy with S3]] (experimental)
|
||||
* [[Authelia]]: configuring SilverBullet with [Authelia](https://www.authelia.com/) authentication.
|
||||
* [[Guide/Deployment/Cloudflare and Portainer]]: configuring SilverBullet with a Cloudflare tunnel, portainer and optionall Cloudflare zero trust authentication.
|
||||
* [[Guide/Deployment/Cloudflare and Portainer]]: configuring SilverBullet with a Cloudflare tunnel, portainer and optional Cloudflare zero trust authentication.
|
||||
|
||||
## Use
|
||||
* [[Markdown]]
|
||||
|
@ -1,6 +1,6 @@
|
||||
Markdown is a plain text formatting system [originally developed by John Gruber](https://daringfireball.net/projects/markdown/). It has since been standardized into [CommonMark](https://commonmark.org/), which is what SilverBullet uses (with [[Markdown/Extensions]]). While a bit more technical than [WYSIWYG](https://pl.wikipedia.org/wiki/WYSIWYG)-style editing (like MS Word), the nice thing about markdown is that is a (relatively) easy to implement standard and you can read files even without special tools (like SilverBullet). This means that even if you switch tools, you’ll always have access to the content. It also means that you can use multiple tools at the same time to edit these files. You don’t have to use SilverBullet exclusively.
|
||||
Markdown is a plain text formatting system [originally developed by John Gruber](https://daringfireball.net/projects/markdown/). It has since been standardized into [CommonMark](https://commonmark.org/), which is what SilverBullet uses (with [[Markdown/Extensions]]). While a bit more technical than [WYSIWYG](https://pl.wikipedia.org/wiki/WYSIWYG)-style editing (like MS Word), the nice thing about markdown is that it is a (relatively) easy-to-implement standard, and you can read files even without special tools (like SilverBullet). This means that you’ll always have access to the content even if you switch tools. It also means that you can use multiple tools at the same time to edit these files. You don’t have to use SilverBullet exclusively.
|
||||
|
||||
There is a bit of a caveat here: Markdown is limited in certain ways, and various tools using markdown as the underlying file format (like SilverBullet) need features that are not directly supported by markdown. As a result, different tools introduce extensions to markdown that are not standard nor interoperable. While in some cases these tools converge on particular pieces of syntax (such as the non-standard `[[page link]]` syntax), some level of divergence in the markdown that each tool supports is unavoidable. SilverBullet is complicit in this as well, it adds a few extensions that are not widely supported, and assigns new meaning certain markdown features to implement novel features. In its defense, all these features are optional. If you want to just write plain markdown, you can.
|
||||
There is a bit of a caveat here: Markdown is limited in certain ways, and various tools using markdown as the underlying file format (like SilverBullet) need features that are not directly supported by markdown. As a result, different tools introduce extensions to markdown that are not standard nor interoperable. While in some cases, these tools converge on particular pieces of syntax (such as the non-standard `[[page link]]` syntax), some level of divergence in the markdown that each tool supports is unavoidable. SilverBullet is complicit in this as well. It adds a few extensions that are not widely supported and assigns new meaning to certain markdown features to implement novel features. In its defense, all these features are optional. If you want to just write plain markdown, you can.
|
||||
|
||||
See [[Markdown/Extensions]] for more details on these SilverBullet-specific extensions.
|
||||
|
||||
|
@ -91,7 +91,7 @@ quote where tags = "item" select name, by
|
||||
|
||||
## paragraph
|
||||
$paragraph
|
||||
Top-level paragraphs (that is: paragraphs not embedded in a list) are indexed using the `paragraph` tag, any additional tags can be added usin [[Tags]].
|
||||
Top-level paragraphs (that is: paragraphs not embedded in a list) are indexed using the `paragraph` tag, any additional tags can be added using [[Tags]].
|
||||
|
||||
A paragraph with a #paragraph-tag.
|
||||
|
||||
@ -125,7 +125,7 @@ In addition, the `snippet` attribute attempts to capture a little bit of context
|
||||
|
||||
_Note_: this is the data source used for the {[Mentions: Toggle]} feature as well page {[Page: Rename]}.
|
||||
|
||||
Here is an query that shows all links that appear in this particular page:
|
||||
Here is a query that shows all links that appear in this particular page:
|
||||
|
||||
```query
|
||||
link where page = "{{@page.name}}" and inDirective = false
|
||||
|
@ -1,14 +1,14 @@
|
||||
So here’s a secret — [[SilverBullet]] is really just a trojan horse to test a potentially much more widely applicable idea, the idea to _make applications extensible at different levels of its stack_ in a controlled manner.
|
||||
So here’s a secret — [[SilverBullet]] is really just a Trojan horse to test a potentially much more widely applicable idea, the idea to _make applications extensible at different levels of its stack_ in a controlled manner.
|
||||
|
||||
## Background
|
||||
I’ve long appreciated the simplicity and flexibility of [AWS’s lambda functions](https://aws.amazon.com/lambda/). The idea is simple: you write a function using some language (JavaScript, Python, Java or whatever floats your boat), package it up, and ship it to AWS (think: zip file). Then, you configure the triggers that invoke those functions (such as certain events) and that’s it. The rest is managed for you.
|
||||
I’ve long appreciated the simplicity and flexibility of [AWS’s Lambda functions](https://aws.amazon.com/lambda/). The idea is simple: you write a function using some language (JavaScript, Python, Java or whatever floats your boat), package it up, and ship it to AWS (think: zip file). Then, you configure the triggers that invoke those functions (such as certain events), and that’s it. The rest is managed for you.
|
||||
|
||||
The AWS infrastructure fully manages the lifecycle of these functions: it ensures there are sufficient servers ready to invoke them, runs the code, recycles the processes when appropriate, and kills them when they misbehave. All this machinery is completely hidden from the user. It is referred to as **serverless** because it abstracts away the concept of a server.
|
||||
|
||||
Of course, this requires functions to be written in a specific way:
|
||||
|
||||
* **Stateless:** while the runtime may keep functions running and reuse an instance to perform multiple invocations, functions have to be written without this assumption. Therefore any state needs to be maintained outside of the function.
|
||||
* **Self contained:** they make limited assumptions on the environment other than a language runtime, typically.
|
||||
* **Self contained:** they typically make limited assumptions on the environment other than a language runtime.
|
||||
* **Short lived:** the assumption is that functions run for a limited amount of time, usually a few milliseconds, perhaps seconds, but a minute at most.
|
||||
|
||||
While they can perform arbitrary computations, they do have constraints:
|
||||
@ -16,20 +16,20 @@ While they can perform arbitrary computations, they do have constraints:
|
||||
1. They have to be stateless: while the runtime may keep functions running and reuse an instance to perform multiple invocations, they cannot assume this is the case. They have to assume that every invocation happens in a fresh environment.
|
||||
2. They have limited access to the host machine, such as no direct access to a (persistent) file system.
|
||||
|
||||
What can these functions do? In principle, anything, while being limited to access to the host. They generally cannot write to the host’s filesystem for instance. They also tend to be constrained in allocated run time and memory. All communication with the outside world tends to happen
|
||||
What can these functions do? In principle, anything, while being limited to access to the host. They generally cannot write to the host’s filesystem, for instance. They also tend to be constrained in allocated run time and memory. All communication with the outside world tends to happen
|
||||
|
||||
Then, you configure when it should be triggered.
|
||||
|
||||
This concept is not only interesting in terms of **scalability** — such a function can quickly scale to millions of invocations per second when necessary, and down to zero when that demand vanishes — but also in terms of **portability**. Couldn’t such functions conceptually run _everywhere_? And indeed, recently such functions have been moving to what’s called “the edge” as well, such as [Lambda@Edge](https://aws.amazon.com/lambda/edge/), [Vercel’s Edge Functions](https://vercel.com/blog/edge-functions-generally-available), or [Netlify’s Edge Functions](https://docs.netlify.com/edge-functions/overview/). What is the “edge” here? Generally, the closest data center these providers offer near the user. The goal? Lower latency.
|
||||
|
||||
But is that is as _edgy_ as we can get? What about the _real_ edge: the user’s device?
|
||||
But is that as _edgy_ as we can get? What about the _real_ edge: the user’s device?
|
||||
|
||||
## Introducing PlugOS
|
||||
PlugOS is a JavaScript (TypeScript) library that brings these concepts to _applications_: allowing applications, [[SilverBullet]] to be extended in a safe way, by allowing plugins — named “plugs” — to _hook_ into various aspects of the application, run custom code as a result, which in turn can affect the application again via _syscalls_.
|
||||
PlugOS is a JavaScript (TypeScript) library that brings these concepts to _applications_: allowing applications such as [[SilverBullet]] to be extended in a safe way, by allowing plugins — named “plugs” — to _hook_ into various aspects of the application, run custom code as a result, which in turn can affect the application again via _syscalls_.
|
||||
|
||||
## Concepts
|
||||
* _Functions_: are pieces of code, written in JavaScript or TypeScript that add custom functionality to a hosting application.
|
||||
* _Hooks_: are application-specific extension points, they can range from defining new commands, to timer based hooks (cron-like), to HTTP endpoints to be defined.
|
||||
* _Syscalls_: expose (often) application-specific functionality to functions, allowing it to e.g. manipulate the UI, access various data stores etc.
|
||||
* _Manifests_: wire the whole thing together, they are [[YAML]] files that define the functions and what they hook into.
|
||||
* _Sandbox_: each plug is run in its own sandbox, in the browser this is a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API), on the server as well (although Deno enables [deeper sandboxing](https://deno.land/manual@v1.36.3/runtime/workers#instantiation-permissions) than the browser). Sandboxes can, in principle, be flushed out and restarted at any time. In fact, this is how _hot reloading_ of plugs is implemented.
|
||||
* _Functions_: are pieces of code, written in JavaScript or TypeScript, that add custom functionality to a hosting application.
|
||||
* _Hooks_: are application-specific extension points. They can range from defining new commands to timer-based hooks (cron-like) to defining HTTP endpoints.
|
||||
* _Syscalls_: expose (often) application-specific functionality to functions, allowing it to e.g. manipulate the UI, access various data stores, etc.
|
||||
* _Manifests_: wire the whole thing together. They are [[YAML]] files that define the functions and what they hook into.
|
||||
* _Sandbox_: each plug is run in its own sandbox. In the browser this is a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API). On the server as well (although Deno enables [deeper sandboxing](https://deno.land/manual@v1.36.3/runtime/workers#instantiation-permissions) than the browser). Sandboxes can, in principle, be flushed out and restarted at any time. In fact, this is how _hot reloading_ of plugs is implemented.
|
Loading…
Reference in New Issue
Block a user