Complete redo of content indexing and querying (#517)
Complete redo of data store Introduces live queries and live templates
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Anchor represent named locations within a page and are defined using the $anchor syntax. They can then be referenced withing the page using [[@anchor]], or cross-page via [[Anchors@anchor]].
|
||||
+16
-20
@@ -1,4 +1,4 @@
|
||||
Attributes can contribute additional [[Metadata]] to various entities:
|
||||
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 alphanumeric. 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]
|
||||
@@ -26,36 +26,32 @@ Multiple attributes can be attached to a single entity, e.g. like so:
|
||||
## Scope
|
||||
Depending on where these attributes appear, they attach to different things. For instance, this attaches an attribute to a page:
|
||||
|
||||
[pageAttribute:: hello]
|
||||
[pageAttribute: hello]
|
||||
|
||||
However, usually [[Frontmatter]] is be used for this purpose instead.
|
||||
|
||||
Example query:
|
||||
|
||||
<!-- #query page where name = "Attributes" select name, pageAttribute -->
|
||||
|name |pageAttribute|
|
||||
|----------|-----|
|
||||
|Attributes|hello|
|
||||
<!-- /query -->
|
||||
```query
|
||||
page where name = "{{@page.name}}" select name, pageAttribute
|
||||
```
|
||||
|
||||
This attaches an attribute to an item:
|
||||
|
||||
* Item [itemAttribute:: hello]
|
||||
* Item [itemAttribute: hello] #specialitem
|
||||
|
||||
Example query:
|
||||
|
||||
<!-- #query item where page = "Attributes" and itemAttribute = "hello" select name, itemAttribute -->
|
||||
|name|itemAttribute|
|
||||
|----|-----|
|
||||
|Item|hello|
|
||||
<!-- /query -->
|
||||
```query
|
||||
specialitem where itemAttribute = "hello" select name, itemAttribute
|
||||
```
|
||||
|
||||
This attaches an attribute to a task:
|
||||
|
||||
* [ ] Task [taskAttribute:: hello]
|
||||
* [ ] Task [taskAttribute: hello]
|
||||
|
||||
Example query:
|
||||
|
||||
<!-- #query task where page = "Attributes" and taskAttribute = "hello" select name, taskAttribute -->
|
||||
|name|taskAttribute|
|
||||
|----|-----|
|
||||
|Task|hello|
|
||||
<!-- /query -->
|
||||
```query
|
||||
task where page = "Attributes" and taskAttribute = "hello" select name, taskAttribute
|
||||
```
|
||||
|
||||
+14
-1
@@ -3,6 +3,19 @@ release.
|
||||
|
||||
---
|
||||
|
||||
## 0.5.0
|
||||
Oh boy, this is a big one. This release brings you the following:
|
||||
|
||||
* [[Objects]]: a more generic system to 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.
|
||||
* 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).
|
||||
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## 0.4.0
|
||||
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]].
|
||||
|
||||
@@ -144,7 +157,7 @@ Besides these architectural changes, a few other breaking changes were made to s
|
||||
|
||||
## 0.2.13
|
||||
|
||||
* Support for multiple `order by` clauses in [[🔌 Directive/Query]] by [Siddhant Sanyam](https://github.com/silverbulletmd/silverbullet/pull/387)
|
||||
* Support for multiple `order by` clauses in [[Live Queries]] by [Siddhant Sanyam](https://github.com/silverbulletmd/silverbullet/pull/387)
|
||||
* Tags included in `tags` [[Frontmatter]] now included in hash tag auto complete
|
||||
* Regression fix: when instantiating a page from a template it would always claim the page already existed (even if it didn't)
|
||||
|
||||
|
||||
@@ -22,20 +22,9 @@ You will notice this whole page section is wrapped in a strange type of block. T
|
||||
|
||||
Don’t believe me, check this out, here’s a list of (max 10) pages in your space ordered by name, it updates (somewhat) dynamically 🤯. Create some new pages and come back here to see that it works:
|
||||
|
||||
<!-- #query page select name order by name limit 10 -->
|
||||
|name |
|
||||
|---------------|
|
||||
|API |
|
||||
|Attributes |
|
||||
|Authelia |
|
||||
|Authentication |
|
||||
|CHANGELOG |
|
||||
|Cloud Links |
|
||||
|Deployments |
|
||||
|Federation |
|
||||
|Frontmatter |
|
||||
|Getting Started|
|
||||
<!-- /query -->
|
||||
```query
|
||||
page select name order by name limit 10
|
||||
```
|
||||
|
||||
That said, the directive used wrapping this page section is `#use` which uses the content of another page as a template and inlines it. Directives recalculate their bodies in two scenarios:
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Linked mentions
|
||||
@@ -1,3 +1,5 @@
|
||||
SilverBullet uses a “live preview” markdown editor. This mechanism is heavily inspired by [Obsidian’s live preview mode](https://help.obsidian.md/Live+preview+update).
|
||||
|
||||
It reduces visual noise by not constantly showing [[Markdown]] codes such as `[SilverBullet website](https://silverbullet.md)`, only showing the underlying Markdown when the cursor is placed inside.
|
||||
It reduces visual noise by not constantly showing [[Markdown]] codes such as `[SilverBullet website](https://silverbullet.md)`, only showing the underlying Markdown when the cursor is placed inside.
|
||||
|
||||
In addition, live preview is also heavily leveraged to implement [[Live Queries]] and [[Live Templates]].
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
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:
|
||||
```query
|
||||
page
|
||||
order by lastModified desc
|
||||
where size > 100
|
||||
select name
|
||||
limit 10
|
||||
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).
|
||||
|
||||
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]]
|
||||
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):
|
||||
|
||||
```#person
|
||||
name: John
|
||||
age: 7
|
||||
---
|
||||
name: Pete
|
||||
age: 25
|
||||
```
|
||||
|
||||
To query all `person`s that are above age 21, we can use the following `where` clause:
|
||||
|
||||
```query
|
||||
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):
|
||||
|
||||
```query
|
||||
person where page = "{{@page.name}}" order by age desc
|
||||
```
|
||||
## `limit` [[@expression]]
|
||||
To limit the number of results, you can use a `limit` clause:
|
||||
|
||||
```query
|
||||
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:
|
||||
|
||||
```query
|
||||
person
|
||||
where page = "{{@page.name}}"
|
||||
select name, age, age + 1 as nextYear
|
||||
```
|
||||
### `render [[template]]`
|
||||
By default results are rendered as a table, to instead render each result item using [[Templates|a template]], use the `render` clause:
|
||||
|
||||
```query
|
||||
person
|
||||
where page = "{{@page.name}}"
|
||||
render [[template/person]]
|
||||
```
|
||||
## Expressions
|
||||
$expression
|
||||
|
||||
Primitives:
|
||||
|
||||
* strings: `"a string"`
|
||||
* numbers: `10`
|
||||
* booleans: `true` or `false`
|
||||
* regular expressions: `/[a-z]+/`
|
||||
* null: `null`
|
||||
* lists: `["value 1", 10, false]`
|
||||
|
||||
Attributes can be accessed via the `attribute` syntax, and nested attributes via `attribute.subattribute.subsubattribute`.
|
||||
|
||||
Logical expressions:
|
||||
|
||||
* and: `name = "this" and age > 10`
|
||||
* or: `name = "this" or age > 10`
|
||||
|
||||
Binary expressions:
|
||||
- `=` equals, e.g. `name = "Pete"`
|
||||
- `!=` not equals, e.g. `name != "Pete"`
|
||||
- `<` less than, e.g. `age < 10`
|
||||
- `<=` less than or equals, e.g. `age <= 10`
|
||||
- `>` greater than, e.g. `age > 10`
|
||||
- `>=` greater than or equals, e.g. `age >= 10`
|
||||
- `=~` to match against a regular expression, e.g. `name =~ /^template\//`
|
||||
- `!=~` to not match a regular expression, e.g. `name !=~ /^template\//`
|
||||
- `in` member of a list (e.g. `prop in ["foo", "bar"]`)
|
||||
* `+` addition (can also concatenate strings), e.g. `10 + 12` or `name + "!!!"`
|
||||
* `-` subtraction, e.g. `10 - 12`
|
||||
* `/` addition, e.g. `10 / 12`
|
||||
* `*` multiplication, e.g. `10 * 12`
|
||||
* `%` modulo, e.g. `10 % 12`
|
||||
|
||||
Operator precedence follows standard rules, use parentheses when in doubt, e.g. `(age > 10) or (name = "Pete")`
|
||||
@@ -0,0 +1,34 @@
|
||||
Live templates rendering [[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.
|
||||
|
||||
Generally you’d use it in one of two ways, either using a `page` template reference, or an inline `template`:
|
||||
|
||||
Here’s an example using `page`:
|
||||
|
||||
```template
|
||||
page: "[[template/today]]"
|
||||
```
|
||||
And here’s an example using `template`:
|
||||
|
||||
```template
|
||||
template: |
|
||||
Today is {{today}}!
|
||||
```
|
||||
To pass in a value to the template, you can specify the optional `value` attribute:
|
||||
|
||||
```template
|
||||
template: |
|
||||
Hello, {{name}}! Today is _{{today}}_
|
||||
value:
|
||||
name: Pete
|
||||
```
|
||||
If you just want to render the raw markdown without handling it as a handlebars template, set `raw` to true:
|
||||
|
||||
```template
|
||||
template: |
|
||||
This is not going to be {{processed}} by Handlebars
|
||||
raw: true
|
||||
```
|
||||
|
||||
+3
-3
@@ -14,9 +14,9 @@ A full manual is still missing, but this is an attempt to give pointers on topic
|
||||
* [[Markdown]]
|
||||
* [[Markdown/Syntax Highlighting]]
|
||||
* [[Markdown/Code Widgets]]
|
||||
* [[Metadata]]
|
||||
* [[Live Queries]]
|
||||
* [[Live Templates]]
|
||||
* [[Objects]]
|
||||
* [[Frontmatter]]
|
||||
* [[Attributes]]
|
||||
* [[🔌 Directive|Directives]]
|
||||
* [[🔌 Directive/Query]]
|
||||
* [[SETTINGS]]: A few settings you can tweak
|
||||
|
||||
@@ -9,6 +9,7 @@ We mentioned markdown _extensions_, here are the ones currently supported:
|
||||
* Hashtags, e.g. `#mytag`.
|
||||
* Command link syntax: `{[Stats: Show]}` rendered into a clickable button {[Stats: Show]}.
|
||||
* [[Markdown/Code Widgets]]
|
||||
* [[Anchors]]
|
||||
* [Tables](https://www.markdownguide.org/extended-syntax/#tables)
|
||||
* [Fenced code blocks](https://www.markdownguide.org/extended-syntax/#fenced-code-blocks)
|
||||
* [Task lists](https://www.markdownguide.org/extended-syntax/#task-lists)
|
||||
|
||||
@@ -60,4 +60,11 @@ class MyClass {
|
||||
void main() {
|
||||
print('Hello, World!');
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
```c
|
||||
void main() {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+3
-27
@@ -1,29 +1,5 @@
|
||||
Metadata is data about data. There are a few entities you can add meta data to:
|
||||
Metadata is data about data. Most [[Objects]] have a set of default attributes that can be augmented in a few additional ways:
|
||||
|
||||
* **page**: Pages have a default set of meta data built-in, but this can be expanded through mechanisms described below. The available metadata for a page is:
|
||||
* `name`: The full name of the page
|
||||
* `lastModified`: a timestamp (in ms since 1970-01-01) of when the page was last modified
|
||||
* `perm`: either `ro` (read-only) or `rw`: this determines whether the editor opens in read-write or read-only mode.
|
||||
* `contentType`: for pages always `text/markdown`
|
||||
* `size`: the size of the file in bytes
|
||||
* `tags`: A list of tags used in the top-level of the page (if any)
|
||||
* **item**: Every list item appearing in a numbered, or unordered list is indexed and contains the following default set of metadata:
|
||||
* `name`: The full content of the item minus attributes (see later)
|
||||
* `page`: The page the item appears in
|
||||
* `pos`: The offset (number of characters from the beginning of the page) where the item starts
|
||||
* `tags`: A list of tags used in the item (if any)
|
||||
* **task**: Every task defined in the space using the `* [ ] Task name` syntax
|
||||
* `name`: The full task name/description
|
||||
* `done`: Whether the task has been marked as done
|
||||
* `page`: The page where the task appears
|
||||
* `pos`: The offset (number of characters from the beginning of the page) where the item starts
|
||||
* `tags`: A list of tags used in the task (if any)
|
||||
* **tag**: Every tag used in the space
|
||||
* `name`: The name of the tag (without `#`)
|
||||
* `freq`: The frequency of the use of the tag
|
||||
|
||||
In addition, this metadata can be augmented in a few additional ways:
|
||||
|
||||
* [[Tags]]: adds to the `tags` attribute
|
||||
* [[Tags]]: to tag the object (and add to the `tags` attribute directly)
|
||||
* [[Frontmatter]]: at the top of pages, a [[YAML]] encoded block can be used to define additional attributes to a page
|
||||
* [[Attributes]]
|
||||
* [[Attributes]] syntax
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
#meta-tag
|
||||
|
||||
SilverBullet automatically builds and maintains an index of _objects_ extracted from all markdown pages in your space. It subsequently allows you to [[Live Queries]] this database in (potentially) useful ways.
|
||||
|
||||
Some examples of things you can query for:
|
||||
* Give me a list of all books that I have marked as _want to read_
|
||||
* Give me a list of all tasks not yet completed that have today as a due date
|
||||
* Give me a list of items tagged with `#quote`
|
||||
* Give me a list of not-completed tasks that reference the current page
|
||||
|
||||
By design, the truth remains in the markdown: all data indexed into objects will have a representation in markdown text as well. The index can be flushed at any time and be rebuilt from markdown files.
|
||||
|
||||
# Object representation
|
||||
Every object has a set of [[Attributes]].
|
||||
|
||||
At the very least:
|
||||
* `ref`: a unique _identifier_ (unique to the page, at least), often represented as a pointer to the place (page, position) in your space where the object is defined. For instance, a _page_ object will use the page name as its `ref` attribute, and a `task` will use `page@pos` (where `pos` is the location the task appears in `page`).
|
||||
* `tags`: an array of type(s) of an object, see [[@tags]].
|
||||
|
||||
In addition, any number of additional tag-specific and custom [[Attributes]] can be defined (see below).
|
||||
|
||||
# Tags
|
||||
$tags
|
||||
Every object has one or more tags, defining the types of an object. Some tags are built-in (as described below), but you can easily define new tags by simply using the #hashtag notation in strategic locations (more on these locations later).
|
||||
|
||||
Here are the currently built-in tags:
|
||||
|
||||
## page
|
||||
Every page in your space is available via the `page` tag. You can attach _additional tags_ to a page, by either specifying them in the `tags` attribute [[Frontmatter]], or by putting additional [[Tags]] in the _first paragraph of your page_, as is done in this particular page with a #meta-tag.
|
||||
|
||||
In addition to `ref` and `tags`, the `page` tag defines a bunch of additional attributes as can be seen in this example query:
|
||||
|
||||
```query
|
||||
page where name = "{{@page.name}}"
|
||||
```
|
||||
|
||||
## task
|
||||
Every task in your space is tagged with the `task` tag by default. You tag it with additional tags by using [[Tags]] in the task name, e.g.
|
||||
|
||||
* [ ] My task #upnext
|
||||
|
||||
And can then be queried via either `task` or `upnext`.
|
||||
|
||||
The following query shows all attributes available for tasks:
|
||||
|
||||
```query
|
||||
upnext
|
||||
```
|
||||
Although you may want to render it using a template such as [[template/task]] instead:
|
||||
|
||||
```query
|
||||
upnext render [[template/task]]
|
||||
```
|
||||
|
||||
## item
|
||||
List items are not currently indexed unless explicitly tagged (for performance reasons). Like other things, an an item can be tagged using [[Tags]].
|
||||
|
||||
Here is an example of a #quote item using a custom [[Attributes|attribute]]:
|
||||
|
||||
* “If you don’t know where you’re going you may not get there.” [by: Yogi Berra] #quote
|
||||
|
||||
And then queried via the #quote tag:
|
||||
|
||||
```query
|
||||
quote select by, name
|
||||
```
|
||||
|
||||
## data
|
||||
You can also embed arbitrary YAML data blocks in pages via fenced code blocks and use a tag as a coding language, e.g.
|
||||
|
||||
```#person
|
||||
name: Pete
|
||||
age: 55
|
||||
```
|
||||
|
||||
Which then becomes queriable via the `person` tag:
|
||||
|
||||
```query
|
||||
person
|
||||
```
|
||||
|
||||
## link
|
||||
All page _links_ are tagged with `link`. You cannot attach additional tags to links. The main two attributes of a link are:
|
||||
|
||||
* `toPage` the page the link is linking _to_
|
||||
* `page` the page the link appears on
|
||||
|
||||
In addition, the `snippet` attribute attempts to capture a little bit of context on where the link appears.
|
||||
|
||||
_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:
|
||||
|
||||
```query
|
||||
link where page = "{{@page.name}}" and inDirective = false
|
||||
```
|
||||
|
||||
## anchor
|
||||
$myanchor
|
||||
|
||||
[[Anchors]] use the `$myanchor` notation to allow deeplinking into a page and are also indexed and queryable. It is not possible to attach additional tags to an anchor.
|
||||
|
||||
Here is an example query:
|
||||
|
||||
```query
|
||||
anchor where page = "{{@page.name}}"
|
||||
```
|
||||
|
||||
## tag
|
||||
The ultimate meta tag is _tag_ itself, which indexes for all tags used, in which page they appear and what their “parent tag” is (the context of the tag: either `page`, `item` or `task`).
|
||||
|
||||
Here are the tags used/defined in this page:
|
||||
|
||||
```query
|
||||
tag where page = "{{@page.name}}"
|
||||
```
|
||||
|
||||
## attribute
|
||||
This is another meta tag, which is used to index all [[Attributes]] used in your space. This is used by e.g. attribute completion in various contexts. You likely don’t need to use this tag directly, but it’s there.
|
||||
|
||||
```query
|
||||
attribute where page = "{{@page.name}}" limit 1
|
||||
```
|
||||
@@ -9,12 +9,12 @@ Now that we got that out of the way let’s have a look at some of SilverBullet
|
||||
## Features
|
||||
* Runs in any modern browser (including on mobile) as a [[PWA]] in two potential [[Client Modes]] (_online_ and _synced_ mode), where the _synced mode_ enables **100% offline operation**, keeping a copy of content in the browser, syncing back to the server when a network connection is available.
|
||||
* 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.
|
||||
* Supports wiki-style **page linking** using the `[[page link]]` syntax, even keeping links up-to-date when pages are renamed.
|
||||
* 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_.
|
||||
* 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 [[🔌 Core/Slash Commands|slash commands]] to perform common text editing operations.
|
||||
* Provides a platform for [end-user programming](https://www.inkandswitch.com/end-user-programming/) through its support for annotating pages with [[Frontmatter]] and [[🔌 Directive|directives]] (such as [[🔌 Directive/Query|#query]]), making parts of pages _dynamic_.
|
||||
* Use [[Slash Commands]] to perform common text editing operations.
|
||||
* Provides a platform for [end-user programming](https://www.inkandswitch.com/end-user-programming/) through its support for [[Objects]], [[Live Queries]] and [[Live Templates]].
|
||||
* Robust extension mechanism using [[🔌 Plugs]].
|
||||
* **Self-hosted**: you own your data. All content is stored as plain files in a folder on disk. Back up, sync, edit, publish, script with any additional tools you like.
|
||||
* SilverBullet is [open source, MIT licensed](https://github.com/silverbulletmd/silverbullet) software.
|
||||
@@ -80,4 +80,4 @@ Have a lock at our work-in-progress [[Manual]].
|
||||
## Support
|
||||
If you (hypothetically) find bugs or have feature requests, post them in [our issue tracker](https://github.com/silverbulletmd/silverbullet/issues). Want to contribute? [Check out the code](https://github.com/silverbulletmd/silverbullet).
|
||||
|
||||
Want to chat with us? [Join our Discord](https://discord.gg/EvXbFucTxn)!
|
||||
Want to chat with us? [Join our Discord](https://discord.gg/EvXbFucTxn)!
|
||||
+2
-30
@@ -1,32 +1,4 @@
|
||||
Tags in SilverBullet can be added in two ways:
|
||||
Tags in SilverBullet are used to encode types of [[Objects]].
|
||||
|
||||
1. Through the `tags` attribute in [[Frontmatter]]
|
||||
2. By putting a `#tag` at the top level (to tag a page), or at the task or item level to tag those blocks specifically.
|
||||
See [[Objects@tags]] for more information.
|
||||
|
||||
For instance, by using the #core-tag in this page, it has been tagged and can be used in a [[🔌 Directive/Query]]:
|
||||
|
||||
<!-- #query page where tags = "core-tag" render [[template/page]] -->
|
||||
* [[Tags]]
|
||||
<!-- /query -->
|
||||
|
||||
Similarly, tags can be applied to list **items**:
|
||||
|
||||
* This is a tagged item #core-tag
|
||||
|
||||
and be queried:
|
||||
|
||||
<!-- #query item where tags = "core-tag" -->
|
||||
|name |tags |page|pos|
|
||||
|-------------------------------|--------|----|---|
|
||||
|This is a tagged item #core-tag|core-tag|Tags|494|
|
||||
<!-- /query -->
|
||||
|
||||
and **tags**:
|
||||
|
||||
* [ ] This is a tagged task #core-tag
|
||||
|
||||
And they can be queried this way:
|
||||
|
||||
<!-- #query task where tags = "core-tag" render [[template/task]] -->
|
||||
* [ ] [[Tags@808]] This is a tagged task #core-tag
|
||||
<!-- /query -->
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
For various use cases, SilverBullet uses [Handlebars templates](https://handlebarsjs.com/).
|
||||
|
||||
Generally templates are stored in your space as regular pages, which allows for reuse. Some examples include [[template/task]] and [[template/page]].
|
||||
As a convention, we often name templates with a `template/` prefix, although this is purely a convention.
|
||||
|
||||
[[Live Templates]] allow templates to be define inline, for instance:
|
||||
```template
|
||||
template: |
|
||||
Hello, {{name}}! Today is _{{today}}_
|
||||
value:
|
||||
name: Pete
|
||||
```
|
||||
### Template helpers
|
||||
There are a number of built-in handlebars helpers you can use
|
||||
|
||||
- `{{today}}`: Today’s date in the usual YYYY-MM-DD format
|
||||
- `{{tomorrow}}`: Tomorrow’s date in the usual YYY-MM-DD format
|
||||
- `{{yesterday}}`: Yesterday’s date in the usual YYY-MM-DD format
|
||||
- `{{lastWeek}}`: Current date - 7 days
|
||||
- `{{nextWeek}}`: Current date + 7 days
|
||||
- `{{escapeRegexp "hello/there"}}` to escape a regexp, useful when injecting e.g. a page name into a query — think `name =~ /{{escapeRegexp @page.name}}/
|
||||
`* `{{replaceRegexp string regexp replacement}}`: replace a regular expression in a string, example use: `{{replaceRegexp name "#[^#\d\s\[\]]+\w+" ""}}` to remove hashtags from a task name
|
||||
- `{{json @page}}` translate any (object) value to JSON, mostly useful for debugging
|
||||
- `{{relativePath @page.name}}` translate a path to a relative one (to the current page), useful when injecting page names, e.g. `{{relativePath name}}`.
|
||||
- `{{substring "my string" 0 3}}` performs a substring operation on the first argument, which in this example would result in `my `
|
||||
- `{{prefixLines "my string\nanother" " "}}` prefixes each line (except the first) with the given prefix.
|
||||
- `{{niceDate @page.lastModified}}` translates any timestamp into a “nice” format (e.g. `2023-06-20`).
|
||||
- The `@page` variable contains all page meta data (`name`, `lastModified`, `contentType`, as well as any custom [[Frontmatter]] attributes). You can address it like so: `{{@page.name}}`
|
||||
@@ -0,0 +1 @@
|
||||
* Person **{{name}}** has {{age}}
|
||||
@@ -1 +1 @@
|
||||
* [{{state}}] [[{{page}}@{{pos}}]] {{name}}
|
||||
* [{{state}}] [[{{ref}}]] {{name}}
|
||||
@@ -0,0 +1 @@
|
||||
Today is {{today}}!
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
type: plug
|
||||
uri: github:silverbulletmd/silverbullet-backlinks/backlinks.plug.js
|
||||
repo: https://github.com/silverbulletmd/silverbullet-backlinks
|
||||
author: Guillermo Vayá
|
||||
---
|
||||
|
||||
<!-- #include [[https://raw.githubusercontent.com/silverbulletmd/silverbullet-backlinks/main/README.md]] -->
|
||||
# SilverBullet plug for Backlinks
|
||||
|
||||
Provides access to pages that link to the one currently being edited.
|
||||
|
||||
## Wait, SilverBullet?
|
||||
|
||||
If you don't know what it is, check its [webpage](https://silverbullet.md), but if you want me to spoil the fun: it is an extensible note taking app with markdown and plain files at its core (well... there is a bit of magic in there too, but what good it would be without a little magic?)
|
||||
|
||||
## Installation
|
||||
|
||||
Open (`cmd+k`) your `PLUGS` note in SilverBullet and add this plug to the list:
|
||||
|
||||
```yaml
|
||||
- github:silverbulletmd/silverbullet-backlinks/backlinks.plug.js
|
||||
```
|
||||
|
||||
Then run the `Plugs: Update` command and off you go!
|
||||
<!-- /include -->
|
||||
@@ -3,9 +3,12 @@ type: plug
|
||||
repo: https://github.com/silverbulletmd/silverbullet
|
||||
---
|
||||
|
||||
> **Warning** Deprecated
|
||||
> Directives are now deprecated and will likely soon be removed, use [[Live Templates]] and [[Live Queries]] instead.
|
||||
|
||||
The directive plug is a built-in plug implementing various so-called “directive” that all take the form of `<!-- #directiveName ... -->` and close with `<!-- /directiveName -->`. Currently the following directives are supported:
|
||||
|
||||
* `#query` to perform queries: [[🔌 Directive/Query]]
|
||||
* `#query` to perform queries: [[Live Queries]]
|
||||
* `#include` to inline the content of another page verbatim: [[@include]]
|
||||
* `#use` to use the content of another as a [handlebars](https://handlebarsjs.com/) template: [[@use]]
|
||||
* `#eval` to evaluate an arbitrary JavaScript expression and inline the result: [[@eval]]
|
||||
@@ -63,7 +66,7 @@ However, you can also invoke arbitrary plug functions, e.g. the `titleUnfurlOpti
|
||||
|title-unfurl|Extract title|
|
||||
<!-- /eval -->
|
||||
|
||||
Optionally, you can use a `render` clause to render the result as a template, similar to [[🔌 Directive/Query]]:
|
||||
Optionally, you can use a `render` clause to render the result as a template, similar to [[Live Queries]]:
|
||||
|
||||
<!-- #eval editor.titleUnfurlOptions() render [[template/debug]] -->
|
||||
id: title-unfurl
|
||||
|
||||
@@ -1,224 +0,0 @@
|
||||
## Query
|
||||
The `#query` is the most widely used directive. It can be used to query various data sources and render results in various ways.
|
||||
|
||||
### Syntax
|
||||
1. _start with_: `<!-- #query [QUERY GOES HERE] -->`
|
||||
2. _end with_: `<!-- /query -->`
|
||||
3. _write your query_: replace `[QUERY GOES HERE]` with any query you want using the options below.
|
||||
4. _available query options_: Usage of options is similar to SQL except for the special `render` option. The `render` option is used to display the data in a format that you created in a separate template.
|
||||
* `where`
|
||||
* `order by`
|
||||
* `limit`
|
||||
* `select`
|
||||
* `render`
|
||||
|
||||
P.S.: If you are a developer or have a technical knowledge to read a code and would like to know more about syntax, please check out
|
||||
[query grammar](https://github.com/silverbulletmd/silverbullet/blob/main/common/markdown_parser/query.grammar).
|
||||
|
||||
#### 2.1. Available query operators:
|
||||
|
||||
- `=` equals
|
||||
- `!=` not equals
|
||||
- `<` less than
|
||||
- `<=` less than or equals
|
||||
- `>` greater than
|
||||
- `>=` greater than or equals
|
||||
- `=~` to match against a regular expression
|
||||
- `!=~` does not match this regular expression
|
||||
- `in` member of a list (e.g. `prop in ["foo", "bar"]`)
|
||||
|
||||
Further, you can combine multiple of these with `and`. Example
|
||||
`prop =~ /something/ and prop != “something”`.
|
||||
|
||||
### 3. How to run a query?
|
||||
After writing the query, there are three options:
|
||||
|
||||
1. Open the **command palette** and run {[Directives: Update]}
|
||||
2. Use shortcut: hit **Alt-q** (Windows, Linux) or **Option-q** (Mac)
|
||||
3. Go to another page and come back to the page where the query is located, it always updates when a page is loaded
|
||||
|
||||
After using one of the options, the “body” of the query is replaced with the new results of the query data will be displayed.
|
||||
|
||||
### 4. Data sources
|
||||
|
||||
Available data sources can be categorized as:
|
||||
|
||||
1. Builtin data sources
|
||||
2. Data that can be inserted by users
|
||||
3. Plug’s data sources
|
||||
|
||||
The best part about data sources: there is auto-completion. 🎉
|
||||
|
||||
Start writing `<!— #query` or simply use `/query` slash command, it will show you all available data sources. 🤯
|
||||
|
||||
Additionally there are [[🔌 Template@vars|special variables]] you can use in your queries.
|
||||
|
||||
For example, if you wanted a query for all the tasks from a previous day's daily note, you could use the following query:
|
||||
`<!-- #query task where page = "📅 {{yesterday}}" -->`
|
||||
|
||||
#### 4.1. Available data sources
|
||||
|
||||
- `page`: list of all pages
|
||||
- `attachment`: list of all attachments
|
||||
- `task`: list of all tasks (created with `[ ]`) across all pages
|
||||
- `full-text`: use it with `where phrase = "SOME_TEXT"`. List of all pages where `SOME_TEXT` is mentioned
|
||||
- `item`: list of ordered and unordered items such as bulleted lists across all pages
|
||||
- `tag`: list of all hashtags used in all pages
|
||||
- `link`: list of all pages giving a link to the page where query is written
|
||||
- `data`: You can insert data using the syntax below. You can query the data using the `data` source.
|
||||
|
||||
```data
|
||||
name: John
|
||||
age: 50
|
||||
city: Milan
|
||||
country: Italy
|
||||
---
|
||||
name: Jane
|
||||
age: 53
|
||||
city: Rome
|
||||
country: Italy
|
||||
---
|
||||
name: Francesco
|
||||
age: 28
|
||||
city: Berlin
|
||||
country: Germany
|
||||
```
|
||||
|
||||
Example:
|
||||
<!-- #query data where age > 20 and country = "Italy" -->
|
||||
|name|age|city |country|page |pos |
|
||||
|----|--|-----|-----|------------------|----|
|
||||
|John|50|Milan|Italy|🔌 Directive/Query|2933|
|
||||
|Jane|53|Rome |Italy|🔌 Directive/Query|2934|
|
||||
<!-- /query -->
|
||||
|
||||
#### 4.2 Plugs’ data sources
|
||||
|
||||
Certain plugs can also provide special data sources to query specific data. Some examples are:
|
||||
|
||||
- [[🔌 Github]] provides `gh-pull` to query PRs for selected repo
|
||||
- [[🔌 Mattermost]] provides `mm-saved` to fetch (by default 15) saved posts in
|
||||
Mattermost
|
||||
|
||||
For a complete list of data sources, please check plugs’ own pages.
|
||||
|
||||
### 5. Templates
|
||||
|
||||
Templates are predefined formats to render the body of the query.
|
||||
|
||||
#### 5.1 How to create a template?
|
||||
|
||||
It is pretty easy. You just need to create a new page. However, it is
|
||||
recommended to create your templates using `template/[TEMPLATE_NAME]`
|
||||
convention. For this guide, we will create `template/plug` to display list of Plugs available in SilverBullet. We will use this template in the Examples section below.
|
||||
|
||||
#### 5.2 What is the syntax?
|
||||
|
||||
We are using Handlebars which is a simple templating language. It is using double curly braces and the name of the parameter to be injected. For our `template/plug`, we are using simple template like below.
|
||||
|
||||
* [[{{name}}]] by **{{author}}** ([repo]({{repo}}))
|
||||
|
||||
Let me break it down for you
|
||||
|
||||
- `*` is creating a bullet point for each item in SilverBullet
|
||||
- `[[{{name}}]]` is injecting the name of Plug and creating an internal link to
|
||||
the page of the Plug
|
||||
- `**{{author}}**` is injecting the author of the Plug and making it bold
|
||||
- `([repo]({{repo}}))` is injecting the name of the Plug and creating an
|
||||
external link to the GitHub page of the Plug
|
||||
|
||||
For more information on the Handlebars syntax, you can read the
|
||||
[official documentation](https://handlebarsjs.com/).
|
||||
|
||||
#### 5.3 How to use the template?
|
||||
|
||||
You just need to add the `render` keyword followed by the link of the template to the query like below:
|
||||
|
||||
<!-- #query page where type = "plug" render [[template/plug]] -->
|
||||
<!-- /query-->
|
||||
`#query page where type = "plug" render [[template/plug]]`
|
||||
|
||||
You can see the usage of our template in example 6.4 below.
|
||||
|
||||
### 6. Examples
|
||||
|
||||
We will walk you through a set of examples starting from a very basic one
|
||||
through one formatting the data using templates.
|
||||
|
||||
Our goal in this exercise is to (i) get all plug pages (ii) ordered by last modified time and (iii) display in a nice format.
|
||||
|
||||
For the sake of simplicity, we will use the `page` data source and limit the results not to spoil the page.
|
||||
|
||||
#### 6.1 Simple query without any condition
|
||||
|
||||
**Goal:** We would like to get the list of all pages.
|
||||
|
||||
**Result:** Look at the data. This is more than we need. The query even gives us template pages. Let's try to limit it in the next step.
|
||||
|
||||
<!-- #query page limit 3 -->
|
||||
|name |lastModified |contentType |size|perm|pageAttribute|
|
||||
|----------|-------------|-------------|----|--|-----|
|
||||
|API |1692191260028|text/markdown|2200|rw| |
|
||||
|Attributes|1691176701257|text/markdown|1466|rw|hello|
|
||||
|Authelia |1688482500313|text/markdown|866 |rw| |
|
||||
<!-- /query -->
|
||||
|
||||
|
||||
#### 6.2 Simple query with a condition
|
||||
|
||||
**Goal:** We would like to get all plug pages sorted by last modified time.
|
||||
|
||||
**Result:** Okay, this is what we wanted but there is also information such as `perm`, `type` and `lastModified` that we don't need.
|
||||
|
||||
<!-- #query page where type = "plug" order by lastModified desc limit 5 -->
|
||||
|name |lastModified |contentType |size|perm|type|uri |repo |author |share-support|
|
||||
|--|--|--|--|--|--|--|--|--|--|
|
||||
|🔌 Twitter |1692810059854|text/markdown|1266|rw|plug|github:silverbulletmd/silverbullet-twitter/twitter.plug.js |https://github.com/silverbulletmd/silverbullet-twitter |SilverBullet Authors| |
|
||||
|🔌 Share |1691177844386|text/markdown|693 |rw|plug| |https://github.com/silverbulletmd/silverbullet | | |
|
||||
|🔌 Github |1691137925014|text/markdown|2206|rw|plug|github:silverbulletmd/silverbullet-github/github.plug.js |https://github.com/silverbulletmd/silverbullet-github |Zef Hemel |true|
|
||||
|🔌 Mattermost|1691137924741|text/markdown|3535|rw|plug|github:silverbulletmd/silverbullet-mattermost/mattermost.plug.json|https://github.com/silverbulletmd/silverbullet-mattermost|Zef Hemel |true|
|
||||
|🔌 Git |1691137924435|text/markdown|1112|rw|plug|github:silverbulletmd/silverbullet-git/git.plug.js |https://github.com/silverbulletmd/silverbullet-git |Zef Hemel | |
|
||||
<!-- /query -->
|
||||
|
||||
#### 6.3 Query to select only certain fields
|
||||
|
||||
**Goal:** We would like to get all plug pages, selecting only `name`, `author`
|
||||
and `repo` columns and then sort by last modified time.
|
||||
|
||||
**Result:** Okay, this is much better. However, I believe this needs a touch
|
||||
from a visual perspective.
|
||||
|
||||
<!-- #query page select name, author, repo where type = "plug" order by lastModified desc limit 5 -->
|
||||
|name |author |repo |
|
||||
|--|--|--|
|
||||
|🔌 Twitter |SilverBullet Authors|https://github.com/silverbulletmd/silverbullet-twitter |
|
||||
|🔌 Share | |https://github.com/silverbulletmd/silverbullet |
|
||||
|🔌 Github |Zef Hemel |https://github.com/silverbulletmd/silverbullet-github |
|
||||
|🔌 Mattermost|Zef Hemel |https://github.com/silverbulletmd/silverbullet-mattermost|
|
||||
|🔌 Git |Zef Hemel |https://github.com/silverbulletmd/silverbullet-git |
|
||||
<!-- /query -->
|
||||
|
||||
#### 6.4 Display the data in a format defined by a template
|
||||
|
||||
**Goal:** We would like to display the data from step 5.3 in a nice format using bullet points with links to Plug pages, with the author name and a link to their GitHub repo.
|
||||
|
||||
**Result:** Here you go. This is the result we would like to achieve 🎉. Did you see how I used `render` and `template/plug` in a query? 🚀
|
||||
|
||||
<!-- #query page where type = "plug" order by lastModified desc limit 5 render [[template/plug]] -->
|
||||
* [[🔌 Twitter]] by **SilverBullet Authors** ([repo](https://github.com/silverbulletmd/silverbullet-twitter))
|
||||
* [[🔌 Share]]
|
||||
* [[🔌 Github]] by **Zef Hemel** ([repo](https://github.com/silverbulletmd/silverbullet-github))
|
||||
* [[🔌 Mattermost]] by **Zef Hemel** ([repo](https://github.com/silverbulletmd/silverbullet-mattermost))
|
||||
* [[🔌 Git]] by **Zef Hemel** ([repo](https://github.com/silverbulletmd/silverbullet-git))
|
||||
<!-- /query -->
|
||||
|
||||
PS: You don't need to select only certain fields to use templates. Templates are
|
||||
smart enough to get only the information needed to render the data. Therefore,
|
||||
the following queries are the same in terms of end result when using the
|
||||
templates.
|
||||
|
||||
<!-- #query page select name author repo uri where type = "plug" order by lastModified desc limit 5 render [[template/plug]] -->
|
||||
|
||||
and:
|
||||
|
||||
<!-- #query page where type = "plug" order by lastModified desc limit 5 render [[template/plug]] -->
|
||||
+4
-54
@@ -6,57 +6,7 @@ author: Zef Hemel
|
||||
share-support: true
|
||||
---
|
||||
|
||||
<!-- #include [[https://raw.githubusercontent.com/silverbulletmd/silverbullet-ghost/main/README.md]] -->
|
||||
# Ghost plug for Silver Bullet
|
||||
|
||||
This allows you to publish your pages as [Ghost](https://ghost.org/) pages or posts. I use it to publish [Zef+](https://zef.plus).
|
||||
|
||||
## Configuration
|
||||
|
||||
In your `SETTINGS` specify the following settings:
|
||||
|
||||
```yaml
|
||||
ghost:
|
||||
myblog:
|
||||
url: https://your-ghost-blog.ghost.io
|
||||
```
|
||||
|
||||
Then, create a Custom Integration (in your Ghost control panel under Settings > Advanced > Integrations > Add Custom Integration). Enter a name (whatever you want), then copy the full Admin API Key in your `SECRETS` file, mirroring the
|
||||
structure of SETTINGS:
|
||||
|
||||
```yaml
|
||||
ghost:
|
||||
myblog: your:adminkey
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
The plugin hooks into Silver Bullet's [Share infrastructure](https://silverbullet.md/%F0%9F%94%8C_Share). Therefore to
|
||||
share a page as either a Ghost page or post, add a `$share` front matter key. For posts this should take the shape of:
|
||||
|
||||
---
|
||||
$share:
|
||||
- ghost:myblog:post:my-post-slug
|
||||
---
|
||||
|
||||
And for pages:
|
||||
|
||||
---
|
||||
$share:
|
||||
- ghost:myblog:page:my-page-slug
|
||||
---
|
||||
|
||||
Now, when you {[Share: Publish]} (Cmd-s/Ctrl-s) your post will automatically be created (as a draft) or updated if it already exists.
|
||||
|
||||
Enjoy!
|
||||
|
||||
## Installation
|
||||
|
||||
Open your `PLUGS` note in SilverBullet and add this plug to the list, or simply use the `Plugs: Add` command:
|
||||
|
||||
```
|
||||
- github:silverbulletmd/silverbullet-ghost/ghost.plug.js
|
||||
```
|
||||
|
||||
Then run the `Plugs: Update` command and off you go!
|
||||
<!-- /include -->
|
||||
```template
|
||||
page: "[[!raw.githubusercontent.com/silverbulletmd/silverbullet-ghost/main/README]]"
|
||||
raw: true
|
||||
```
|
||||
+4
-37
@@ -5,40 +5,7 @@ repo: https://github.com/silverbulletmd/silverbullet-git
|
||||
author: Zef Hemel
|
||||
---
|
||||
|
||||
<!-- #include [[https://raw.githubusercontent.com/silverbulletmd/silverbullet-git/main/README.md]] -->
|
||||
# SilverBullet plug for Git
|
||||
|
||||
Very basic in functionality, it assumes you have git configured for push and pull in your space. What it does, roughly speaking:
|
||||
|
||||
{[Git: Sync]}:
|
||||
|
||||
- Adds all files in your folder to git
|
||||
- It commits them with a "Snapshot" commit message
|
||||
- It `git pull`s changes from the remote server
|
||||
- It `git push`es changes to the remote server
|
||||
|
||||
{[Git: Snapshot]}:
|
||||
|
||||
- Asks you for a commit message
|
||||
- Commits
|
||||
|
||||
{[Github: Clone]}:
|
||||
|
||||
Clones into your space from a Github repository. This will do authentication based on a [personal access token](https://github.com/settings/tokens).
|
||||
|
||||
## Installation
|
||||
|
||||
Open your `PLUGS` note in SilverBullet and add this plug to the list:
|
||||
|
||||
```
|
||||
- github:silverbulletmd/silverbullet-git/git.plug.js
|
||||
```
|
||||
|
||||
Then run the `Plugs: Update` command and off you go!
|
||||
|
||||
## To Build
|
||||
|
||||
```shell
|
||||
deno task build
|
||||
```
|
||||
<!-- /include -->
|
||||
```template
|
||||
page: "[[!raw.githubusercontent.com/silverbulletmd/silverbullet-git/main/README]]"
|
||||
raw: true
|
||||
```
|
||||
+4
-56
@@ -6,59 +6,7 @@ author: Zef Hemel
|
||||
share-support: true
|
||||
---
|
||||
|
||||
<!-- #include [[https://raw.githubusercontent.com/silverbulletmd/silverbullet-github/main/README.md]] -->
|
||||
# SilverBullet plug for Github
|
||||
Provides various integrations with Github:
|
||||
|
||||
* Query sources for events, notifications and pull requests
|
||||
* Ability to load and share pages as Gists
|
||||
|
||||
## Installation
|
||||
Open your `PLUGS` note in SilverBullet and add this plug to the list:
|
||||
|
||||
```
|
||||
- github:silverbulletmd/silverbullet-github/github.plug.js
|
||||
```
|
||||
|
||||
Then run the `Plugs: Update` command and off you go!
|
||||
|
||||
## Configuration
|
||||
To configure, add a `githubToken` key to your `SECRETS` page, this should be a [personal access token](https://github.com/settings/tokens):
|
||||
|
||||
```yaml
|
||||
githubToken: your-github-token
|
||||
```
|
||||
|
||||
## Query sources
|
||||
|
||||
* `gh-event` List events of a user
|
||||
* `username`: the user whose events to query
|
||||
* `gh-pull`: List pull requests in a repository
|
||||
* `repo`: the repo to query PRs for
|
||||
* `gh-search-issue`: Search for issues and pull requests
|
||||
* `query`: [the search query](https://docs.github.com/en/rest/search#search-issues-and-pull-requests)
|
||||
* `gh-notification` requires a `githubToken` to be configured in `SECRETS`.
|
||||
|
||||
## Share as Gist support
|
||||
|
||||
To use: navigate to a page, and run the {[Share: Gist: Public Gist]} command, this will perform an initial publish, and add a `$share` attribute to your page's front matter. Subsequent updates can be performed via {[Share: Publish]}.
|
||||
|
||||
To pull an *existing* gist into your space, use the {[Share: Gist: Load]} command and paste the URL to the gist.
|
||||
## Example
|
||||
|
||||
Example uses of the query providers:
|
||||
|
||||
## Recent pushes
|
||||
<!-- #query gh-event where username = "zefhemel" and type = "PushEvent" select type, actor_login, created_at, payload_ref limit 3 -->
|
||||
|
||||
<!-- /query -->
|
||||
|
||||
## Recent PRs
|
||||
<!-- #query gh-pull where repo = "silverbulletmd/silverbullet" and user_login = "zefhemel" limit 3 render "template/gh-pull" -->
|
||||
|
||||
<!-- /query -->
|
||||
|
||||
Where the `template/gh-pull` looks as follows:
|
||||
|
||||
* ({{state}}) [{{title}}]({{html_url}})
|
||||
<!-- /include -->
|
||||
```template
|
||||
page: "[[!raw.githubusercontent.com/silverbulletmd/silverbullet-github/main/README]]"
|
||||
raw: true
|
||||
```
|
||||
+4
-68
@@ -5,71 +5,7 @@ repo: https://github.com/silverbulletmd/silverbullet-graphview
|
||||
author: Bertjan Broeksema
|
||||
---
|
||||
|
||||
<!-- #include [[https://raw.githubusercontent.com/silverbulletmd/silverbullet-graphview/main/README.md]] -->
|
||||
# SilverBullet plug for showing a graph view of the documents
|
||||
|
||||
This plug aims to bring similar functionality as the Obsidian Graph view to
|
||||
Silver Bullet.
|
||||
|
||||
This repo is a fork of
|
||||
[Bertjan Broeksema's original repo](https://github.com/bbroeksema/silverbullet-graphview)
|
||||
|
||||
## Installation
|
||||
|
||||
Open (`cmd+k`) your `PLUGS` note in SilverBullet and add this plug to the list:
|
||||
|
||||
```yaml
|
||||
- github:silverbulletmd/silverbullet-graphview/graphview.plug.js
|
||||
```
|
||||
|
||||
Then run the `Plugs: Update` command and off you go!
|
||||
|
||||
## Usage
|
||||
|
||||
Run the `Show Global Graph` command to open up the graph view. Zoom and pan is
|
||||
supported by scroll and pinch gestures with the mouse(pad).
|
||||
|
||||
### Tags & Paths
|
||||
|
||||
Set tags on the pages to customize their appearance in the graph
|
||||
|
||||
- `#node_color=ff0000` → Change node color to red
|
||||
- `#.graphignore` → Hide the page from the graph
|
||||
|
||||
You can also use other custom tags to define node colors: Create a colormap with
|
||||
HEX-colorcodes in `SETTINGS.md`. In this example, a node of a page where the tag
|
||||
`#garden` is set will be rendered as green:
|
||||
|
||||
```yaml
|
||||
# Graphview
|
||||
graphview:
|
||||
default_color: "000000"
|
||||
colormap:
|
||||
path:
|
||||
⚙ services: "01017a"
|
||||
📓 notes: "02bdb6"
|
||||
🚧 projects: "ffc533"
|
||||
🧰 how-to: "96020e"
|
||||
tag:
|
||||
garden: "0bbd02"
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
Click on the node labels to directly navigate to pages in your space
|
||||
|
||||
## Label-shortening
|
||||
|
||||
Long labels are shortened for readability. E.g.
|
||||
`notesarecool/somethingverylong/subsubsubsub/foo` → `notes./somet./subsu./foo`
|
||||
|
||||
## For offline development
|
||||
|
||||
To ease development of the visual part, the offline folder contains a copy of
|
||||
the html and custom javascript. As well as a simple graph model.
|
||||
|
||||
```bash
|
||||
$ cd offline
|
||||
$ python -m http.server
|
||||
```
|
||||
<!-- /include -->
|
||||
```template
|
||||
page: "[[!raw.githubusercontent.com/silverbulletmd/silverbullet-graphview/main/README]]"
|
||||
raw: true
|
||||
```
|
||||
+4
-41
@@ -5,44 +5,7 @@ repo: https://github.com/silverbulletmd/silverbullet-katex
|
||||
author: Zef Hemel
|
||||
---
|
||||
|
||||
<!-- #include [[https://raw.githubusercontent.com/silverbulletmd/silverbullet-katex/main/README.md]] -->
|
||||
# Silver Bullet KaTeX plug
|
||||
|
||||
## Installation
|
||||
Run the {[Plugs: Add]} command and paste in: `github:silverbulletmd/silverbullet-katex/katex.plug.js`
|
||||
|
||||
That's all!
|
||||
|
||||
## Use
|
||||
|
||||
Put a latex block in your markdown:
|
||||
|
||||
```latex
|
||||
c = \pm\sqrt{a^2 + b^2}
|
||||
```
|
||||
|
||||
And move your cursor outside of the block to live preview it!
|
||||
|
||||
**Note:** [KaTeX](https://katex.org) itself is not bundled with this plug, it pulls the JavaScript, CSS and fonts from the JSDelivr CDN. This means _this plug will not work without an Internet connection_. The reason for this limitation is that it is not yet possible to distribute font files via plugs, and KaTeX depends on specific web fonts.
|
||||
|
||||
## Build
|
||||
Assuming you have Deno and Silver Bullet installed, simply build using:
|
||||
|
||||
```shell
|
||||
deno task build
|
||||
```
|
||||
|
||||
Or to watch for changes and rebuild automatically
|
||||
|
||||
```shell
|
||||
deno task watch
|
||||
```
|
||||
|
||||
Then, load the locally built plug, add it to your `PLUGS` note with an absolute path, for instance:
|
||||
|
||||
```
|
||||
- file:/Users/you/path/to/katex.plug.json
|
||||
```
|
||||
|
||||
And run the `Plugs: Update` command in SilverBullet.
|
||||
<!-- /include -->
|
||||
```template
|
||||
page: "[[!raw.githubusercontent.com/silverbulletmd/silverbullet-katex/main/README]]"
|
||||
raw: true
|
||||
```
|
||||
+4
-64
@@ -6,67 +6,7 @@ author: Zef Hemel
|
||||
share-support: true
|
||||
---
|
||||
|
||||
<!-- #include [[https://raw.githubusercontent.com/silverbulletmd/silverbullet-mattermost/main/README.md]] -->
|
||||
# Mattermost for Silver Bullet
|
||||
This plug provides various integrations with the [Mattermost suite](https://www.mattermost.com) of products. Please follow the installation, configuration sections, and have a look at the example.
|
||||
|
||||
Features:
|
||||
|
||||
* Integration with [Silver Bullet Share](https://silverbullet.md/%F0%9F%94%8C_Share), allowing you to publish and update a page as a post on Mattermost, as well as load existing posts into SB as a page using the {[Share: Mattermost Post: Publish]} (to publish an existing page as a Mattermost post) and {[Share: Mattermost Post: Load]} (to load an existing post into SB) commands.
|
||||
* Access your saved posts via the `mm-saved` query provider
|
||||
* Unfurl support for posts (after dumping a permalink URL to a post in a page, use the {[Link: Unfurl]} command).
|
||||
* Boards support is WIP
|
||||
|
||||
## Installation
|
||||
Run the {[Plugs: Add]} command and paste in the following URI: `github:silverbulletmd/silverbullet-mattermost/mattermost.plug.json`
|
||||
|
||||
## Configuration
|
||||
In `SETTINGS` provide the `mattermost` key with a `url` and `defaultTeam` for each server (you can name them arbitrarily):
|
||||
|
||||
```yaml
|
||||
mattermost:
|
||||
community:
|
||||
url: https://community.mattermost.com
|
||||
defaultTeam: core
|
||||
silverbullet:
|
||||
url: https://silverbullet.cloud.mattermost.com
|
||||
defaultTeam: main
|
||||
```
|
||||
|
||||
In `SECRETS` provide a Mattermost personal access token (or hijack one from your current session) for each server:
|
||||
|
||||
```yaml
|
||||
mattermost:
|
||||
community: 1234
|
||||
silverbullet: 1234
|
||||
```
|
||||
|
||||
|
||||
## Query sources
|
||||
|
||||
* `mm-saved` fetches (by default 15) saved posts in Mattermost, you need to add a `where server = "community"` (with server name) clause to your query to select the mattermost server to query.
|
||||
|
||||
To make the `mm-saved` query results look good, it's recommended you render your query results a template. Here is one to start with, you can keep it in e.g. `templates/mm-saved`:
|
||||
|
||||
[{{username}}]({{url}}) in {{#if channelName}}**{{channelName}}**{{else}}a DM{{/if}} at _{{updatedAt}}_ {[Unsave]}:
|
||||
|
||||
{{prefixLines (substring message 0 300 " ... (More)") "> "}}
|
||||
|
||||
---
|
||||
|
||||
Note that the `{[Unsave]}` button when clicked, will unsave the post automatically 😎
|
||||
|
||||
Example use of `mm-saved` (using the `template/mm-saved` template above):
|
||||
|
||||
<!-- #query mm-saved where server = "community" order by updatedAt desc limit 5 render "template/mm-saved" -->
|
||||
|
||||
<!-- /query -->
|
||||
|
||||
## Posting to a channel
|
||||
|
||||
You can use the {[Share: Mattermost Post: Publish]} command to publish the current page to a channel. You will be prompted to select the server and channel to post to. A `$share` key will be injected into frontmatter after the initial post. Subsequent post edits can be published via the standard {[Share: Publish]} command.
|
||||
|
||||
## Loading a post into SB
|
||||
|
||||
Using the {[Share: Mattermost Post: Load]} command you can load an existing post into your space. All you need for this is to have the Mattermost authentication configured as described above. You will be prompted for a post permalink and a page to save it to. If you are the author of the post, the `$share` frontmatter will also be set up so you can change the page and push changes back into Mattermost.
|
||||
<!-- /include -->
|
||||
```template
|
||||
page: "[[!raw.githubusercontent.com/silverbulletmd/silverbullet-mattermost/main/README]]"
|
||||
raw: true
|
||||
```
|
||||
+9
-21
@@ -5,25 +5,13 @@ repo: https://github.com/silverbulletmd/silverbullet-mermaid
|
||||
author: Zef Hemel
|
||||
---
|
||||
|
||||
<!-- #include [[https://raw.githubusercontent.com/silverbulletmd/silverbullet-mermaid/main/README.md]] -->
|
||||
# Silver Bullet plug for Mermaid diagrams
|
||||
This plug adds basic [Mermaid](https://mermaid.js.org/) support to Silver Bullet.
|
||||
Example use:
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start --> Stop
|
||||
```
|
||||
|
||||
**Note:** The Mermaid library itself is not bundled with this plug, it pulls the JavaScript from the JSDelivr CDN. This means _this plug will not work without an Internet connection_. The reason for this is primarily plug size (bundling the library would amount to 1.1MB). This way Mermaid is only loaded on pages with actual Mermaid diagrams rather than on every SB load.
|
||||
|
||||
## Installation
|
||||
Run the {[Plugs: Add]} command and paste in: `github:silverbulletmd/silverbullet-mermaid/mermaid.plug.js`
|
||||
|
||||
That's all!
|
||||
|
||||
## Use
|
||||
|
||||
Put a mermaid block in your markdown:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start --> Stop
|
||||
```
|
||||
|
||||
And move your cursor outside of the block to live preview it!
|
||||
<!-- /include -->
|
||||
```template
|
||||
page: "[[!raw.githubusercontent.com/silverbulletmd/silverbullet-mermaid/main/README]]"
|
||||
raw: true
|
||||
```
|
||||
+6
-23
@@ -16,31 +16,14 @@ 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 page where type = "plug" and uri = null order by name render [[template/plug]] -->
|
||||
* [[🔌 Directive]]
|
||||
* [[🔌 Editor]]
|
||||
* [[🔌 Emoji]]
|
||||
* [[🔌 Index]]
|
||||
* [[🔌 Markdown]]
|
||||
* [[🔌 Share]]
|
||||
* [[🔌 Tasks]]
|
||||
* [[🔌 Template]]
|
||||
<!-- /query -->
|
||||
|
||||
```query
|
||||
page where type = "plug" and uri = null order by name render [[template/plug]]
|
||||
```
|
||||
## Third-party plugs
|
||||
These plugs are written either by third parties or distributed separately from the main SB distribution:
|
||||
<!-- #query page where type = "plug" and uri != null order by name render [[template/plug]] -->
|
||||
* [[🔌 Backlinks]] by **Guillermo Vayá** ([repo](https://github.com/silverbulletmd/silverbullet-backlinks))
|
||||
* [[🔌 Ghost]] by **Zef Hemel** ([repo](https://github.com/silverbulletmd/silverbullet-ghost))
|
||||
* [[🔌 Git]] by **Zef Hemel** ([repo](https://github.com/silverbulletmd/silverbullet-git))
|
||||
* [[🔌 Github]] by **Zef Hemel** ([repo](https://github.com/silverbulletmd/silverbullet-github))
|
||||
* [[🔌 Graph View]] by **Bertjan Broeksema** ([repo](https://github.com/silverbulletmd/silverbullet-graphview))
|
||||
* [[🔌 KaTeX]] by **Zef Hemel** ([repo](https://github.com/silverbulletmd/silverbullet-katex))
|
||||
* [[🔌 Mattermost]] by **Zef Hemel** ([repo](https://github.com/silverbulletmd/silverbullet-mattermost))
|
||||
* [[🔌 Mermaid]] by **Zef Hemel** ([repo](https://github.com/silverbulletmd/silverbullet-mermaid))
|
||||
* [[🔌 Serendipity]] by **Pantelis Vratsalis** ([repo](https://github.com/m1lt0n/silverbullet-serendipity))
|
||||
* [[🔌 Twitter]] by **SilverBullet Authors** ([repo](https://github.com/silverbulletmd/silverbullet-twitter))
|
||||
<!-- /query -->
|
||||
```query
|
||||
page where type = "plug" and uri != null order by name render [[template/plug]]
|
||||
```
|
||||
|
||||
## How to develop your own plug
|
||||
The easiest way to get started is to click the “Use this template” on the [silverbullet-plug-template](https://github.com/silverbulletmd/silverbullet-plug-template) repo.
|
||||
|
||||
@@ -5,27 +5,7 @@ repo: https://github.com/m1lt0n/silverbullet-serendipity
|
||||
author: Pantelis Vratsalis
|
||||
---
|
||||
|
||||
<!-- #include [[https://raw.githubusercontent.com/m1lt0n/silverbullet-serendipity/main/README.md]] -->
|
||||
# Serendipity plug for SilverBullet
|
||||
|
||||
Serendipity introduces randomness in your navigation to your pages and notes in [silverbullet](https://silverbullet.md/).
|
||||
|
||||
The plug includes 3 commands:
|
||||
|
||||
* Open a random page: navigates to a totally random page
|
||||
* Open a random page that contains a tag (e.g. `#hobbies`): narrows down the random pages to only those that have a specific tag
|
||||
* Open a random page based on a search term (e.g. `performance management`): narrows down the random pages to only those that match the search term.
|
||||
|
||||
In order to easily access the commands, all of their names are prefixed with `Serendipity:`.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
Open (`cmd+k` in Mac and `ctrl+k` in other systems) your `PLUGS` note in SilverBullet and add this plug to the list:
|
||||
|
||||
```yaml
|
||||
- github:m1lt0n/silverbullet-serendipity/serendipity.plug.json
|
||||
```
|
||||
|
||||
Then run the `Plugs: Update` command and you're ready!
|
||||
<!-- /include -->
|
||||
```template
|
||||
page: "[[!raw.githubusercontent.com/m1lt0n/silverbullet-serendipity/main/README]]"
|
||||
raw: true
|
||||
```
|
||||
+3
-6
@@ -8,9 +8,6 @@ The Share plug provides infrastructure for sharing pages outside of your space.
|
||||
See the [original RFC](https://github.com/silverbulletmd/silverbullet/discussions/117) for implementation details.
|
||||
|
||||
Specific implementations for sharing are implemented in other plugs, specifically:
|
||||
<!-- #query page where share-support = true render [[template/page]] -->
|
||||
* [[🔌 Ghost]]
|
||||
* [[🔌 Github]]
|
||||
* [[🔌 Markdown]]
|
||||
* [[🔌 Mattermost]]
|
||||
<!-- /query -->
|
||||
```query
|
||||
page where share-support = true render [[template/page]]
|
||||
```
|
||||
|
||||
+7
-18
@@ -38,30 +38,19 @@ Tasks can specify deadlines:
|
||||
When the cursor is positioned inside of a due date, the {[Task: Postpone]} command can be used to postpone the task for a certain period.
|
||||
|
||||
## Querying
|
||||
All meta data (`done` status, `state`, `tags`, `deadline` and custom attributes) is extracted and available via the `task` query source to [[🔌 Directive/Query]]:
|
||||
All meta data (`done` status, `state`, `tags`, `deadline` and custom attributes) is extracted and available via the `task` query source to [[Live Queries]]:
|
||||
|
||||
<!-- #query task where page = "{{@page.name}}" -->
|
||||
|name |done |state |page |pos |tags |taskAttribute|deadline |
|
||||
|--|--|--|--|--|--|--|--|
|
||||
|Remote toggle me |false| |🔌 Tasks|3056| | | |
|
||||
|This is a task (toggle me!) |false| |🔌 Tasks|321 | | | |
|
||||
|This task is still to do |false|TODO |🔌 Tasks|420 | | | |
|
||||
|In progress task |false|IN PROGRESS|🔌 Tasks|454 | | | |
|
||||
|A resolved task |false|RESOLVED |🔌 Tasks|487 | | | |
|
||||
|Whatever this state means |false|- |🔌 Tasks|516 | | | |
|
||||
|Or this one |false|/ |🔌 Tasks|548 | | | |
|
||||
|This is a tagged task #my-tag |false| |🔌 Tasks|824 |my-tag| | |
|
||||
|This is a task with attributes|false| |🔌 Tasks|889 | |true| |
|
||||
|This is due |false| |🔌 Tasks|993 | | |2022-11-26|
|
||||
<!-- /query -->
|
||||
```query
|
||||
task where page = "{{@page.name}}"
|
||||
```
|
||||
|
||||
## Rendering
|
||||
There is a [[!silverbullet.md/template/task]] template you can use to render tasks nicely rather than using the default table (as demonstrated above). When you use this template, you can even cycle through the states of the task by click on its state _inside_ the rendered query, and it will update the state of the _original_ task automatically (although not yet in reverse) — this works across pages.
|
||||
|
||||
Try it (by clicking on the checkbox inside of the directive):
|
||||
|
||||
<!-- #query task where page = "{{@page.name}}" and name = "Remote toggle me" render [[template/task]] -->
|
||||
* [ ] [[🔌 Tasks@3056]] Remote toggle me
|
||||
<!-- /query -->
|
||||
```query
|
||||
task where page = "{{@page.name}}" and name = "Remote toggle me" render [[template/task]]
|
||||
```
|
||||
|
||||
* [ ] Remote toggle me
|
||||
|
||||
+4
-21
@@ -5,24 +5,7 @@ repo: https://github.com/silverbulletmd/silverbullet-twitter
|
||||
author: SilverBullet Authors
|
||||
---
|
||||
|
||||
<!-- #include [[https://raw.githubusercontent.com/silverbulletmd/silverbullet-twitter/main/README.md]] -->
|
||||
# SilverBullet for Twitter
|
||||
Currently the only thing this plug offers is unfurling links to tweets. To use, paste in a link to a Tweet like `https://twitter.com/zef/status/1547943418403295232`, then run the `Link: Unfurl` command and select `Tweet content` to "enrich" the tweet URL with the content of the linked tweet, e.g.
|
||||
|
||||
https://twitter.com/zef/status/1547687321679511552
|
||||
|
||||
Turns into:
|
||||
|
||||
[Zef Hemel](https://twitter.com/zef/status/1547687321679511552):
|
||||
> For those who missed my earlier posts on Silver Bullet: it’s my new powerful note taking/PKM app. Demo video from a user’s perspective: https://t.co/MKauSTcUG3 How it works technically (plugins all the way down): https://t.co/sqCkAa0pem Repo: https://t.co/rrxQdyxze1
|
||||
|
||||
## Installation
|
||||
|
||||
Open (`cmd+k`) your `PLUGS` note in SilverBullet and add this plug to the list:
|
||||
|
||||
```yaml
|
||||
- github:silverbulletmd/silverbullet-twitter/twitter.plug.js
|
||||
```
|
||||
|
||||
Then run the `Plugs: Update` command and off you go!
|
||||
<!-- /include -->
|
||||
```template
|
||||
page: "[[!raw.githubusercontent.com/silverbulletmd/silverbullet-twitter/main/README]]"
|
||||
raw: true
|
||||
```
|
||||
Reference in New Issue
Block a user