# Creating a note template

Source: https://developers.inkdrop.app/guides/create-a-note-template

Once Inkdrop becomes a part of your daily workflow, you may want to save time and effort with note templates.
Inkdrop provides powerful APIs to let you do that.
Here is a walkthrough to make a note template for journaling.

## Create a note for template

Let's create a note something like this. Nothing special.

![Create a note for template](https://developers.inkdrop.app/images/creating-a-note-template_create-note.png)

You will need the note ID of the note template.
Right-click the note and click *Copy Note Link* menu.

![Get note ID](https://developers.inkdrop.app/images/creating-a-note-template_get-note-id.png)

Now you've got a string in clipboard like so:

```
[journal template](inkdrop://note:bSU-gSHd_)
```

`note:bSU-gSHd_` is the note ID in this case.

## Create a command that duplicates the template

Most of Inkdrop's operations are executed by [commands](https://developers.inkdrop.app/guides/list-of-commands).
For example, when you open a note, Inkdrop runs `core:open-note` command internally.
You can define a [custom command](https://developers.inkdrop.app/modules/command-registry) via [the init file](https://developers.inkdrop.app/guides/the-init-file).
Let's make a command that creates new note based on your template.

In this example, you define a command named `custom:new-journal`.
Create `init.js` in [your data directory](https://docs.inkdrop.app/manual/basic-usage#user-data-directory) and write some JavaScript like the following:

```js
inkdrop.commands.add(document.body, 'custom:new-journal', async () => {
  const db = inkdrop.localDB
  const template = await db.notes.get('note:bSU-gSHd_')
  const note = {
    ...template,
    _id: db.notes.createId(),
    _rev: undefined,
    title: new Date().toLocaleDateString(),
    createdAt: +new Date(),
    updatedAt: +new Date(),
    pinned: false
  }
  try {
    await db.notes.put(note)
    inkdrop.commands.dispatch(document.body, 'core:open-note', {
      noteId: note._id
    })
    inkdrop.commands.dispatch(document.body, 'editor:focus-mde')
  } catch (e) {
    console.error(e)
  }
})
```

Let's look at the lines we've added.

```js
const db = inkdrop.localDB
```

It gets an instance of [the local Inkdrop database](https://developers.inkdrop.app/guides/access-the-local-database).

```js
const template = await db.notes.get('note:bSU-gSHd_')
```

Then, it loads the note with ID `note:bSU-gSHd_` by calling [DBNote's `get` method](https://developers.inkdrop.app/data-access/notes#retrieve-a-note).
It returns an object that represents [Note](https://developers.inkdrop.app/data-access/notes#the-note-model) data.

```js
const note = {
  ...template,
  _id: db.notes.createId(),
  _rev: undefined,
  title: new Date().toLocaleDateString(),
  createdAt: +new Date(),
  updatedAt: +new Date()
}
```

It builds a new note from the template data.
The new note should have a unique ID, so it sets new one generated with [DBNote's `createId` method](https://developers.inkdrop.app/data-access/notes#create-a-note-id) to `_id` field.
The `_rev` is a special field to handle revisions, which should be `undefined`.
It sets a new title based on date time by calling [Date::toLocaleDateString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString).

```js
await db.notes.put(note)
```

It saves the manipulated note to the local database by calling [DBNote's `put` method](https://developers.inkdrop.app/data-access/notes#create-or-update-a-note).

```js
inkdrop.commands.dispatch(document.body, 'core:open-note', { noteId: note._id })
```

It invokes `core:open-note` to open the new note.

```js
inkdrop.commands.dispatch(document.body, 'editor:focus-mde')
```

Finally, it invokes `editor:focus-mde` to move focus to the editor.

## Add a menu to invoke the command

Next, we need a way to invoke the command we've made.
Inkdrop allows you to add custom [menus](https://developers.inkdrop.app/modules/menu-manager) to run arbitrary commands.
The below code adds a menu to *File -> Templates -> Create a journal*, which runs `custom:new-journal` command.

```js
inkdrop.menu.add([
  {
    label: 'File',
    submenu: [
      {
        label: 'Templates',
        submenu: [
          {
            label: 'Create a journal',
            command: 'custom:new-journal'
          }
        ]
      }
    ]
  }
])
```

Now, let's check out what it looks like.
Inkdrop will evaluate `init.js` file every time you launch.
So, let's reload the app from menu: *Developer -> Reload*.
And you should see the menu is added like this:

![Add a menu](https://developers.inkdrop.app/images/creating-a-note-template_add-menu.png)

Okay, let's run the command...

![Run it](https://developers.inkdrop.app/images/creating-a-note-template_run-it.png)

Boom! You've got a new note with the template content!

## Add a keymap for the command

It would be more useful to associate the command with [keybinding](https://docs.inkdrop.app/manual/customizing-keybindings).
Here is an example keybinding configuration:

```yaml
'body':
  'cmd-shift-j': 'custom:new-journal'
```

So you can quickly create notes with the template!

## Override default behavior of "core:new-note"

You can create new note by pressing *Cmd-N* on macOS and *Ctrl-N* on Windows and Linux by default.
That's because the keystroke invokes `core:new-note` command.

You may want to use the same keystroke to create a note based on the template automatically if you are selecting "Journal" notebook on sidebar.
You can accomplish that by creating new command and associating it with the same keystroke.

Let's make a command named `custom:new-note` in your `init.js`:

```js
;(async () => {
  const db = inkdrop.localDB
  const template = await db.notes.get('note:08zdMqQyj')

  inkdrop.commands.add(document.body, 'custom:new-journal', async e => {
    const note = {
      ...template,
      _id: db.notes.createId(),
      _rev: undefined,
      title: new Date().toISOString().slice(0, 10),
      createdAt: +new Date(),
      updatedAt: +new Date()
    }
    try {
      await db.notes.put(note)
      inkdrop.commands.dispatch(document.body, 'core:open-note', {
        noteId: note._id
      })
      inkdrop.commands.dispatch(document.body, 'editor:focus-mde')
    } catch (e) {
      console.error(e)
    }
  })

  inkdrop.commands.add(document.body, 'custom:new-note', async () => {
    const { queryContext } = inkdrop.store.getState()
    if (
      queryContext.mode === 'book' &&
      queryContext.bookId === template.bookId
    ) {
      inkdrop.commands.dispatch(document.body, 'custom:new-journal')
    } else {
      inkdrop.commands.dispatch(document.body, 'core:new-note')
    }
  })
})()
```

Let's look at the lines we've added.

```js
(async () => {
  const db = inkdrop.localDB
  const template = await db.notes.get("note:08zdMqQyj")
```

First, it loads the template note.

```js
inkdrop.commands.add(document.body, 'custom:new-journal', async e => {
  // ...
})
```

It is equivalent to the command we've created before.

```js
inkdrop.commands.add(document.body, 'custom:new-note', async () => {
  const { queryContext } = inkdrop.store.getState()
  if (queryContext.mode === 'book' && queryContext.bookId === template.bookId) {
    inkdrop.commands.dispatch(document.body, 'custom:new-journal')
  } else {
    inkdrop.commands.dispatch(document.body, 'core:new-note')
  }
})
```

We defined a command `custom:new-note`.

It checks if [query context](https://developers.inkdrop.app/states/query-context) mode is `"book"` and its `bookId` is same as your template, which means you are selecting "Journal" notebook on sidebar in this example.
Then, if true, it invokes `custom:new-journal` command.
Otherwise, it invokes `core:new-note`.

> **Note:**
>
> Learn more about [getting & setting the app state](https://developers.inkdrop.app/guides/flux-architecture).

Now, let's associate the command with the keystroke in your [keymap.cson](https://docs.inkdrop.app/manual/customizing-keybindings)! On macOS:

```yaml
'body':
  'cmd-n': 'custom:new-note'
```

On Windows and Linux:

```yaml
'body':
  'ctrl-n': 'custom:new-note'
```

Now you don't have to remember the keystroke nor select the menu to invoke `custom:new-journal` command!
