Meta Bind offers a JavaScript API that allows you to interact with the Meta Bind internals via JavaScript.
Documentation for the API can be found here .
Usage
To use the API you need some way to execute JavaScript. This can be done with another plugin like JS Engine or Dataview .
Before you can use the API, you need to get a reference to it. This can be done via first getting an instance to the loaded Meta Bind plugin and then getting the API from it.
// First we get an instance of the Meta Bind plugin, then we access the API.
// If the plugin is not loaded, this will return `undefined`.
const mb = engine. getPlugin ( ' obsidian-meta-bind-plugin ' )?.api;
// Optional: Handle the case where the plugin is not loaded.
// Now we can use the API!
// `app` refers to the Obsidian App object, depending on how you execute JavaScript you might need to get it from somewhere.
// First we get an instance of the Meta Bind plugin, then we access the API.
// If the plugin is not loaded, this will return `null`.
const mb = app.plugins. getPlugin ( ' obsidian-meta-bind-plugin ' )?.api;
// Optional: Handle the case where the plugin is not loaded.
// Now we can use the API!
Caution
Do not try to use API methods as standalone functions. This will lead to errors, as the class method looses it’s reference to itself via this
.
const { someAPIMethod } = app.plugins. getPlugin ( ' obsidian-meta-bind-plugin ' )?.api;
someAPIMethod (); // will most likely error
const someAPIMethod = app.plugins. getPlugin ( ' obsidian-meta-bind-plugin ' )?.api.someAPIMethod;
someAPIMethod (); // will most likely error
const mb = app.plugins. getPlugin ( ' obsidian-meta-bind-plugin ' )?.api;
mb. someAPIMethod (); // works
This is a general issue with JavaScript classes.
// `baz` became a standalone function and thus `this` is now `undefined`.
baz (); // error: can't access property `bar`, `this` is `undefined`
// `baz2` became a standalone function and thus `this` is now `undefined`.
baz2 (); // error: can't access property `bar`, `this` is `undefined`
Lifecycle Management
Lifecycle management is very important when working with the Meta Bind API. You need to make sure that you clean up after yourself to prevent memory leaks and other bugs.
Most things that need lifecycle managment inherit from Mountable
, which has a mount
and unmount
method.
If you call mount
, you need to call unmount
at some point.
The API provides a helper function called wrapInMDRC
that can be used to handle the lifecycle of a mountable object for you.
// Create a mountable object.
// Mount the mountable via the helper function.
// `container` is the parent HTMLElement that the mountable should be mounted to.
// `component` is an Obsidian `Component` object.
mb. wrapInMDRC (mountable, container, component);
In the background this will create a MarkdownRenderChild
which mounts and unmounts the mountable on load and unload respectivly and then registers that MarkdownRenderChild
as a child of the component.
You can also handle the lifecycle yourself by mounting the mountable to the DOM and then registering a callback to unmount it when the component is destroyed.
// Create a mountable object.
// Mount the mountable to the DOM.
mountable. mount (container);
// Register a callback to unmount the mountable when the component is destroyed.
component. register (() => mountable. unmount ());
Examples
Note
The following examples use js-engine
code blocks from the JS Engine plugin.
To use the examples as they are, make sure you have the JS Engine plugin installed and enabled.
Though the API is usable without it, the examples might not work without JS Engine .
The used globals that are exclusive to JS Engine are as follows.
For more information on them refer to the JS Engine documentation .
engine
- Refers to the JS Engine API.
context.file
- The TFile
object for file containing the js-engine
code block. This is only available in the context of a note.
container
- The container for the rendered content. This is of type HTMLElement
.
component
- An Obsidian Component
for lifecycle management.
Creating a button via the API.
// First we get an instance of the Meta Bind plugin, then we access the API.
const mb = app.plugins. getPlugin ( ' obsidian-meta-bind-plugin ' )?.api;
// We create a button configuration object.
label : ' Greet the World ' ,
code : " console.log('Hello World!'); " ,
// We specify the button options.
declaration : buttonConfig,
// We create the button. This will return something that inherits from `Mountable` and can be mounted to the DOM.
const button = mb. createButtonMountable (context.file.path, buttonOptions);
// Mount the button to the DOM and make sure it gets unmounted when the component is destroyed.
mb. wrapInMDRC (button, container, component);
If you are daring you can skipt the intermediate objects.
// First we get an instance of the Meta Bind plugin, then we access the API.
const mb = app.plugins. getPlugin ( ' obsidian-meta-bind-plugin ' )?.api;
// We create the button. This will return something that inherits from `Mountable` and can be mounted to the DOM.
const button = mb. createButtonMountable (context.file.path, {
label : ' Greet the World ' ,
code : " console.log('Hello World!'); " ,
// Mount the button to the DOM and make sure it gets unmounted when the component is destroyed.
mb. wrapInMDRC (button, container, component);
Creating an input field via the API.
const mb = engine. getPlugin ( ' obsidian-meta-bind-plugin ' ).api;
const primeNumberBound = 200 ;
* A function to calculate prime numbers up to a given bound.
function calculatePrimeNumbers ( bound ) {
const primeNumbers = [ 2 ];
for ( let i = 3 ; i <= bound; i ++ ) {
for ( const p of primeNumbers) {
// Create the input field declaration with the bind target and arguments.
inputFieldType : ' suggester ' ,
bindTarget : mb. createBindTarget ( ' frontmatter ' , context.file.path, [ ' favoritePrime ' ]),
arguments : calculatePrimeNumbers (primeNumberBound). map ( x => {
// Create the input field options.
declaration : declaration,
renderChildType : ' block ' ,
// Create the input field.
const inputField = mb. createInputFieldMountable (context.file.path, options);
// Mount the input field to the DOM and make sure it gets unmounted when the component is destroyed.
mb. wrapInMDRC (inputField, container, component);