You can search and find note templates from the community here.
One-click to import.
- Copy the template below (just an example).
Click to show the example template
# This template is specifically for importing/sharing, using better
# notes 'import from clipboard': copy the content and
# goto Zotero menu bar, click Edit->New Template from Clipboard.
# Do not copy-paste this to better notes template editor directly.
name: "[Text] Current Time"
content: |-
// @use-markdown
// @author windingwind
// @link https://github.com/windingwind/zotero-better-notes/blob/master/docs/about-note-template.md
# Template Example: Current Time
> Author: windingwind
>
> from: [GitHub-Zotero Better Notes: Write Note Template](https://github.com/windingwind/zotero-better-notes/blob/master/docs/about-note-template.md)
**Current Time**: ${new Date().toLocaleString()}
- Goto Zotero menubar, click
Edit
->New Template from Clipboard
. - Click OK.
Now you can open a note/the workspace and in editor toolbar, click Insert Template to cursor line
. Select the template, it is inserted to the note.
Only available in Better Notes v1.1.4-2 or higher
Copy the template code for importing by:
- Open template editor via menu->
Note Template Editor
- Select the template you want to share in the template list
- Click
Options
->Copy share code
This section aims to help you writing a note template of Better Notes. See here for the introduction of the note template.
Use Markdown/HTML to write a note template. If you want to execute scripts in the template, you may want to use JavaScript.
💡It's OK if you don't know them. Creating your own template is very easy!
- Note Template Structure
- Pragma
- Script in Note Template
- Template Type
- Style Syntax
- Script Syntax
- Share Your Template
A template consists of two parts:
Name: The name of template. starts with [TYPE]
, where the TYPE
should be the actual type of the template, e.g. Item
, Text
, etc.
Content: The template code.
Pragmas are lines start with // @
. They have special effect and will not be rendered.
Let the compiler know you are using markdown. Otherwise the template will be processed as HTML.
Allow the generated content to be updated using the Update content from templates
in the note editor.
The generated content will be wrapped in separators with a YAML metadata section for update.
The template with this pragma should not contain any separator (
---
or<hr>
) in the content.
Mark the code belongs to you. Your GitHub account or your email.
Link to the page where the template is published so that users can contact you and give feedback.
The Item
template supports three stages and others only support default
stage.
If not specified, the whole template will be recognized as default
.
Code wrapped by // @${stage}-begin
and // @${stage}-end
will be processed during the corresponding stage. Here the ${stage}
should be replaced by the actual stage name, like beforeloop
.
Note template supports JavaScript.
Wrap one-line code with ${code here}
. The example in Import Note Template uses ${new Date().toLocaleString()}
to render the current time.
Wrap lines with ${{code here}}$
. The example below will be rendered as 3
(the return value of the function).
${{
const a = 1;
const b = 2;
return a + b;
}}$
Each template has its own global variables. See Template Type for more information.
All templates share a global variable _env = {dryRun: boolean}
. In preview mode (in template editor), the _env.dryRun
is true
and in that case you must not modify the library.
Process one or more item(s). The input items are from the item picker window or the selected items.
There are three stages (beforeloop
, default
, afterloop
) in this template. Use pragmas to wrap the template code to indicate on which stage it should be processed.
If no stage pragma is given, the whole template will be processed on the default stage.
Click to show the example template
# This template is specifically for importing/sharing, using better
# notes 'import from clipboard': copy the content and
# goto Zotero menu bar, click Edit->New Template from Clipboard.
# Do not copy-paste this to better notes template editor directly.
name: "[Item] Example Item Template"
content: |-
// @beforeloop-begin
// @use-markdown
# Hi! This only renders once
// @beforeloop-end
// @default-begin
<p>Title: <span style="color: #ffcb00">${topItem.getField("title")}</span></p>
// @default-end
// @afterloop-begin
> Done! But Markdown is not rendered correctly. Try to add
\`// @use-markdown\` pragma before this line.
// @afterloop-end
Stages and Global Variables
beforeloop
stage:
Processed before loop.
- items: an array of Zotero item, the input
- targetNoteItem: The note item that accepts the rendered template. Undefined in preview mode (
_env.dryRun
istrue
) - copyNoteImage: a function that accepts a Zotero item. If the rendered result contains contents from another note, you should call
copyNoteImage(anotherNote)
to copy images fromanotherNote
. - sharedObj: for temporary variables, shared between all stages
default
stage:
Processed in a loop of input items. Run once for each item.
- topItem: Current item
- targetNoteItem
- itemNotes: The child notes of current item (Deprecated)
- copyNoteImage
- sharedObj
afterloop
stage:
Processed after loop.
- items
- targetNoteItem
- copyNoteImage
- sharedObj
Basic user template.
Global Variables
- targetNoteItem
- sharedObj
The name of builtin templates are not allowed to be modified.
Every time there is a breaking change, the corresponding builtin template will be updated and renamed to
{TEMPLATE_NAME}V{n+1}
, wheren
is the version number of the old builtin template and{TEMPLATE_NAME}
is the name of the template. The old builtin template will be kept for compatibility.For example, the builtin template
[ExportMDFileNameV2]
may be renamed to[ExportMDFileNameV3]
in the future.
Name | Description | Variables |
---|---|---|
QuickInsert | For forward link. | link, linkText, subNoteItem, noteItem |
QuickBackLink | For back link. | link, linkText, subNoteItem, noteItem |
QuickImport | For importing note link content. | link, noteItem |
QuickNote | For generating note from annotation. | annotationItem, topItem, noteItem |
ExportMDFileName | For generating Markdown file name when exporting. | noteItem |
ExportMDFileHeader | For generating Markdown file yaml header when exporting. | noteItem |
ExportMDFileContent | For processing Markdown file content when exporting. | noteItem, mdContent |
We recommend using Markdown for styles.
Element | Markdown Syntax |
---|---|
Heading | # H1 ## H2 ### H3 |
Bold | **bold text** |
Italic | *italicized text* |
Underline | <u>Underline Text</u> |
Strike Trough | ~~Deleted Text~~ |
Superscript | N/m<sup>2</sup> |
Subscript | x<sub>i</sub> |
Blockquote | > blockquote |
Ordered List | 1. First item 2. Second item 3. Third item |
Unordered List | - First item - Second item - Third item |
Code | `code` |
Code Block (Monospaced) | ``` function add(x) {return x+1} ``` |
Horizontal Rule | --- |
Link | [title](https://www.example.com) |
Highlight Text | <span style="background-color: #5fb23680">highlighted<span> |
Text Color | <span style="color: #ffcb00">colored<span> |
Math Inline | $y=x^2$ |
Math Block | $$y=x^2$$ |
JS scripts are supported. Here are some helpful script snippets.
Script | Scope | |
Get array of tags from current item |
${topItem.getTags().map(tagObj=>tagObj.tag)}` |
Item:default |
Get title of current item |
${topItem.getField("title")} |
Item:default |
Get authors of current item |
${topItem.getCreators().map((au) => au.firstName + " " + au.lastName).join("; ")} |
Item:default |
Get PDF link of current item |
Click to show${{
async function getPDFLink(item) {
const att = await item.getBestAttachment();
if (!att || !att.isPDFAttachment()) {
return "";
}
key = att.key;
if (att.libraryID === 1) {
return `zotero://open-pdf/library/items/${key}`;
} else {
groupID = Zotero.Libraries.get(att.libraryID).id;
return `zotero://open-pdf/groups/${groupID}/items/${key}`;
}
}
sharedObj.getPDFLink = getPDFLink;
return await getPDFLink(topItem);
}}$ |
Item:default |
Get (author, year) with PDF link of current item |
Click to show${{
const creators = topItem.getCreators();
let content = "";
const year = topItem.getField("year");
if (creators.length === 0) {
content = "no author";
} else if (creators.length === 1) {
content = `${creators[0].lastName}, ${year}`;
} else {
content = `${creators[0].lastName} etal., ${year}`;
}
// The getPDFLink is from above
const link = await sharedObj.getPDFLink(topItem);
let str = `<a href="${link}">${content}</a>`;
return str;
}}$ |
Item:default |
Get pub date of current item |
${topItem.getField("date")} |
Item:default |
Get DOI of current item |
[${topItem.getField("DOI")}]("https://doi.org/${topItem.getField('DOI')}") |
Item:default |
Get other fields of current item |
${topItem.getField("FIELD_KEY")}
|
Item:default |
Get CitationKey of current item |
${topItem.citationKey ? topItem.citationKey : ""} |
Item:default |
Users can use Import Note Template to copy and import the published templates.
A template snippet should be in YAML format (YAML has better support for multi-line content):
# This template is specifically for importing/sharing, using better
# notes 'import from clipboard': copy the content and
# goto Zotero menu bar, click Edit->New Template from Clipboard.
# Do not copy-paste this to better notes template editor directly.
name: "[TYPE] TEMPLATE NAME"
content: |-
// @author YOUR NAME
// @link PUBLISH PAGE URL
TEMPLATE CONTENT HERE
or JSON format:
{
"name": "[TYPE] TEMPLATE NAME",
"content": "// @author YOUR NAME\n// @link PUBLISH PAGE URL\nTEMPLATE CONTENT HERE"
}
All templates should be posted here