Zotero Integration – Import Templates?

Hey folks,

I was wondering if anyone had made templates for @mgmeyers Zotero Desktop Connector plugin.?

There are instructions on how to do it in Nunjucks at this link, but I haven’t thought through it yet and learned nunjucks and thought I’d start this thread to see if anyone else had! Templating.md

20 Likes

Here’s mine!

---
cssclass: literature-note
alias: [{% if shortTitle %}"{{shortTitle | safe}}"{% else %}"{{title | safe}}"{% endif %}]
---
{%- macro colorValueToName(color) -%}
	{%- switch color -%}
		{%- case "#ffff7f" -%}
			Relevant / important
		{%- case "#ff7f7f" -%}
			Disagree
		{%- case "#ffbf7f" -%}
			Questions / confusion
		{%- case "#7fff7f" -%}
			Agree
		{%- case "#7fffff" -%}
			Relevant to current task
		{%- case "#ff7fff" -%}
			TODO / follow up
		{%- case "#bf7fbf" -%}
			Definitions / concepts
		{%- default -%}
			Interesting but not relevant
	{%- endswitch -%}
{%- endmacro -%}

{%- macro calloutHeader(type) -%}
	{%- switch type -%}
		{%- case "highlight" -%}
			Highlight
		{%- case "strike" -%}
			Strikethrough
		{%- case "underline" -%}
			Underline
		{%- case "image" -%}
			Image
		{%- default -%}
			Note
	{%- endswitch -%}
{%- endmacro %}

> [!info]
> - **Cite Key:** [[@{{citekey}}]]
{%- for attachment in attachments | filterby("path", "endswith", ".pdf") %}
> - **Link:** [{{attachment.title}}](file://{{attachment.path | replace(" ", "%20")}})
{%- endfor -%}
{%- if abstractNote %}
> - **Abstract:** {{abstractNote}}
{%- endif -%}
{%- if bibliography %}
> - **Bibliography:** {{bibliography}}
{%- endif %}
{%- if hashTags %}
> - **Tags:** {{hashTags}}
{%- endif %}

## Annotations
{% persist "annotations" %}
{% set annots = annotations | filterby("date", "dateafter", lastImportDate) -%}
{% if annots.length > 0 %}
### Imported on {{importDate | format("YYYY-MM-DD h:mm a")}}

{% for color, annots in annots | groupby("color") -%}
#### {{colorValueToName(color)}}

{% for annot in annots -%}
> [!quote{% if annot.color %}|{{annot.color}}{% endif %}] {{calloutHeader(annot.type)}}
{%- if annot.annotatedText %}
> {{annot.annotatedText | nl2br}}
{%- endif -%}
{%- if annot.imageRelativePath %}
> ![[{{annot.imageRelativePath}}]]
{%- endif %}
{%- if annot.ocrText %}
> {{annot.ocrText}}
{%- endif %}
{%- if annot.comment %}
>
>> {{annot.comment | nl2br}}
{%- endif %}
>
> [Page {{annot.page}}](zotero://open-pdf/library/items/{{annot.attachment.itemKey}}?page={{annot.page}}) [[{{annot.date | format("YYYY-MM-DD#h:mm a")}}]]

{% endfor -%}
{% endfor -%}
{% endif %}
{% endpersist %}

I use it with this CSS snippet to style callouts:

/* Yellow */
.literature-note .callout[data-callout-metadata="#ffff7f"] {
  --callout-color: 255, 204, 0;
}

/* Red */
.literature-note .callout[data-callout-metadata="#ff7f7f"] {
  --callout-color: 255, 59, 48;
}

/* Orange */
.literature-note .callout[data-callout-metadata="#ffbf7f"] {
  --callout-color: 255, 149, 0;
}

/* Green */
.literature-note .callout[data-callout-metadata="#7fff7f"] {
  --callout-color: 40, 205, 65;
}

/* Blue */
.literature-note .callout[data-callout-metadata="#7fffff"] {
  --callout-color: 0, 122, 255;
}

/* Pink */
.literature-note .callout[data-callout-metadata="#ff7fff"] {
  --callout-color: 255, 87, 255;
}

/* Purple */
.literature-note .callout[data-callout-metadata="#bf7fbf"] {
  --callout-color: 125, 84, 222;
}
13 Likes

Here is mine
updated 2002-07-27, incorporates annotation colors;
updated 2022-07-16, incorporates Zotero Integration update that allows to import Zotero 6 annotations directly
updated 2022-08-13 incorporates an option to add new annotations into the same note on second import (if note is not renamed or deleted)

---
cssclass: research-note
type: "{{itemType}}"{% for type, creators in creators | groupby("creatorType") -%}{% if loop.first %}
{% endif %}{{type | replace("interviewee", "author") | replace("director", "author") | replace("presenter", "author") | replace("podcaster", "author") | replace("programmer", "author") | replace("cartographer", "author") | replace("inventor", "author") | replace("sponsor", "author")  | replace("performer", "author") | replace("artist", "author")}}: "{%- for creator in creators -%}{%- if creator.name %}{{creator.name}}{%- else %}{{creator.lastName}}, {{creator.firstName}}{%- endif %}{% if not loop.last %}; {% endif %}{% endfor %}"{% if not loop.last %}
{% endif %}{%- endfor %}{% if title %}
title: "{{title}}"{% endif %}{% if publicationTitle %}
publication: "{{publicationTitle}}"{% endif %}{% if date %}
date: {{date | format("YYYY-MM-DD")}}{% endif %}{% if archive %}
archive: "{{archive}}"{% endif %}{% if archiveLocation %}
archive-location: "{{archiveLocation}}"{% endif %}
citekey: {{citekey}}
---
{{bibliography}}
[online]({{uri}}) [local]({{desktopURI}}) {%- for attachment in attachments | filterby("path", "endswith", ".pdf") %} [pdf](file://{{attachment.path | replace(" ", "%20")}})
{% if loop.last %} 
{% endif %}{%- endfor %}
 
{% if tags.length > 0 -%}{% for t in tags -%}#{% if t.tag == "secondary" %}source/secondary{% if not loop.last %}{% endif %}{% elif t.tag == "primary" %}source/primary{% if not loop.last %}{% endif %}{% elif "-project" in t.tag %}project/{{t.tag | lower | replace(" ", "-") | replace("-project", "")}}{% else %}subject/{{t.tag | lower | replace(" ", "-")}}{% endif %}{% if not loop.last %}
{% endif %}{%- endfor %}{%- endif %}

### Index

start-date:: {% if date %}{{date | format("YYYY-MM-DD")}}{% endif %}
end-date::
page-no:: {% for annotation in annotations %}{% if loop.first %}{{annotation.pageLabel}}{% endif %}{% endfor %}

### Connections

comment:: 

### Note
{% macro calloutHeader(color) -%}
{%- if color == "#ff6666" -%}
Important
{%- endif -%}
{%- if color == "#5fb236" -%}
Reference
{%- endif -%}
{%- if color == "#2ea8e5" -%}
Undefined - Blue
{%- endif -%}
{%- if color == "#a28ae5" -%}
Undefined - Purple
{%- endif -%}
{%- endmacro -%}

{% persist "annotations" %}
{% set annotations = annotations | filterby("date", "dateafter", lastImportDate) -%}
{% if annotations.length > 0 %}
### Imported on {{importDate | format("YYYY-MM-DD h:mm a")}}

{%- for annotation in annotations %}
{% if annotation.color !== "#ffd400" %}
>[!quote{% if annotation.color %}|{{annotation.color}}{% endif %}] {{calloutHeader(annotation.color)}}
>{%- endif -%}{% if annotation.imageRelativePath %}
![[{{annotation.imageRelativePath}}]] {% endif %}{% if annotation.annotatedText %}
{{annotation.annotatedText}} [(p. {{annotation.pageLabel}})](zotero://open-pdf/library/items/{{annotation.attachment.itemKey}}?page={{annotation.pageLabel}}&annotation={{annotation.id}}){%- endif %}{%- if annotation.comment%}
%%{{annotation.comment}}%%{%- endif %}{%- endfor %}{% endif %} {% endpersist %}

For annotation colors, you will need to put this snippet in your vault/.obsidian/snippets/ (adapted from mgmeyers template above)

/* Yellow */
.research-note .callout[data-callout-metadata="#ffd400"] {
  --callout-color: 255, 204, 0;
}

/* Red */
.research-note .callout[data-callout-metadata="#ff6666"] {
  --callout-color: 255, 59, 48;
}

/* Green */
.research-note .callout[data-callout-metadata="#5fb236"] {
  --callout-color: 40, 205, 65;
}

/* Blue */
.research-note .callout[data-callout-metadata="#2ea8e5"] {
  --callout-color: 0, 122, 255;
}

/* Purple */
.research-note .callout[data-callout-metadata="#a28ae5"] {
  --callout-color: 125, 84, 222;
}

My template works with Zotero 6 annotations (using Zotero notes template) rather than via Zotfile.

It separates authors by type so I can use Dataview to search by letter recipient and interviewer. It also imports Zotero tags for type of source and project name. And it includes a template for data entry, including fields for page number and for my comments.

Note: This template does not assign a color to yellow because I use yellow for when I need to export annotations without colors.

See more at 01 Notetaking for Historians - Doing History with Zotero and Obsidian - Obsidian Publish

17 Likes

Thanks for sharing your template, it looks very intriguing. Any chance you could share some screenshots of what the result looks like, and expand a bit on your workflow?

I have two minor, newbee questions:

  1. How can we download or cut-and-paste these templates so they render correctly in Obsidian?
  2. The proper extension for nunjucks templates is .njk. But Obsidian seems to want to add “.md” to the end. Is there a way to avoid this?

Just copy and paste the text into a new markdown note, and remove the ``` at the beginning and end of the template, so it is not treated as a code block.

Then, link to that file in the Zotero Integration settings. No need for the .njk extension to work with this plugin.

Thanks for the tip about the ```. I should have recognized this.

Regarding the .njk, I understand it’s not entirely necessary. But a major feature of Obsidian using MD files is to allow multiple apps to use the files. Suppose I want to set up Vim to be the default editor of nunjucks templates. In such cases, clicking on a .njk file would open it in Vim. The whole point of creating and following such standards is to (a) make such files readily recognizable for what they are and (b) facilitate such things as opening files in the proper app, sed scripts that work a certain way depending on filename extensions, etc. Insisting on adding .md as the file extension to a file that’s not really a markdown file is, IMHO, bad software practice.

1 Like

Here’s my current Template :eyes:

Edits:

The gist linked here is not updated anymore, see: https://forum.obsidian.md/t/zotero-integration-import-templates/36310/96?u=apfelstrudelig

2022-07-19 Updated to add more DV keys to pull info into table, show annotation colours as <mark> highlights, change metadata fields

2022-07-28 Didn’t like the full on mark highlights, opted for spans instead that change the font colour

2022-08-22 Major update! Split my templates into two. One for metadata and notes, the other for highlights and whatever commentary I added. I also snagged a trick from @Leah to get nice little coloured squares instead of coloured notes because I was still feeling iffy about them. You can find the earlier versions by clicking on “Revisions”.

2023-01-09 Updated to use different tags, add non-Templater version, remove some metadata as I don’t use it (all previous versions are still accessible!)

6 Likes

Nice template, thanks for sharing. Could you explain how this part works: replace("**Highlights: Blue**", "Info")?

Where is the highlight information coming from?

This is taken from a Zotfile template with enabled colour grouping. I extract the annotations and the notes all end up having the “Highlights: Colour” as their heading, so I can replace it with the actual meaning. It’s not as sophisticated as I’d like it to be. :sweat_smile:

3 Likes

Hi I was having the same issue as OP but only found this post after making my own template. I’m no expert in nunjucks or Obsidian but this works well for my setup. There’s an image showing roughly what the output is.

Annotations from Zotero 6 internal pdf viewer are imported into an ### Annotations subheading, each annotation is nested inside of an admonition note (ad-note) for easy styling. Rectangle annotations will be pasted into the literature note inside their own block as images, as they are imported into your vault by the desktop connector. If you want to edit the callout (ad-note) blocks that’s easy enough by changing the values in the macro as per the admonition documentation. I find this easier than messing with the CSS options, for just certain files.

New annotations can be added to your literature note without fear of them overwriting the original file as there is a persist block for existing annotations. New annotations will be included under a separate heading with a new timestamp.

The template is here

4 Likes

Here is the section I use specifically for annotations, it is pretty much @mgmeyers template but with the added benefit of working with @Chetachi Highlightr plugin:

## Annotations
{% persist "annotations" %}

{% set annots = annotations | filterby("date", "dateafter", lastImportDate) -%}

{% if annots.length > 0 %}
{% for annot in annots -%}
{%- if annot.annotatedText %}
- <mark style="background: {{annot.color}}">{{annot.annotatedText | nl2br}} </mark>
{%- endif -%}

{%- if annot.imageRelativePath %}
![[{{annot.imageRelativePath}}]]
{%- endif %}

{%- if annot.comment %}
>[!annot] Comment
>{{annot.comment | nl2br}}
 {%- endif %}

{%- endfor %}
{%- endif %}
{%- endpersist %}

It pulls the color hex code from the annotation data and uses that to determine the highlight color. I think you need css-inline enabled in Highlightr to use this.

So you get something that looks like this:

Sidenote: I noticed that any document with pen annotations, like handwritten notes from using an apple pencil on the zotero ios app, will completely fail to import. Is this a known issue? If not, is there somewhere I should post about this?

6 Likes

Thank you so much for this template segment. The annotation format looks really good. Is there a way to add the page numbers and a link to the location in the file on Zotero, though?

1 Like

I am looking for documentation that I can understand (I am not a programmer and have no clear idea how Zotero and Obsidian are linked, technically).
The documentation with the plugin is too complicated for me, and also, seems to start in the middle, so I don’t get a sense of what to do.
Has anyone seen a simpler instruction or examples?

This part I can kind of help with, even though I am not very familiar with the specifics of the plugin. The two programs are not at all linked, by default. They use different file extensions and think about different things. Zotero with the plugin BetterBibTeX knows how to export BibTeX .bib files, which are a plaintext representation of a bibliography. The various Zotero/citation-related plugins for Obsidian are (as far as I know) programs to read that .bib file and help you extract the bibliographic information inside from BibTeX into Markdown (Obsidian’s file format).
Instead of just dumping that bibliographic information directly to a Markdown file, deciding for themselves “oh the title of the file is going to be the citekey and heading 1 is going to be the article title and then there will be a heading 2 with the author names” etc. which would probably not match anyone’s exact preferences, these plugins all try to let their users (you!) decide what order you want the bibliographic information in your Markdown file, and how you want to format it.
Probably the easiest way to experiment with this is to take an existing template like @apfelstrudelig’s, see what order and formatting are produced, and then try to change it around to match what you like!

Good luck!

4 Likes

Hey! So looking at some of the other templates, if you want to add a page number and page link, add the following line in next to any of the annotation types where you want to have a page number link available.

[(pg. {{annot.page}})](zotero://open-pdf/library/items/{{annot.attachment.itemKey}}?page={{annot.page}})

I added a commented version of the annotations section of the previous template, indicating the type of annotation, and where I added the page number and page link. Currently, it is only added to text highlights.

Also, a small change from before, I will highlight headers and section titles in whatever text I am reading, and then directly edit the annotation to include ## to indicate a markdown header. I added a line or two to filter that and format appropriately so you get nice little markdown section headers from those highlights. It is really useful if you are annotating huge books and long review.


# Annotations
{% persist "annotations" %}
{% set annots = annotations | filterby("date", "dateafter", lastImportDate) -%}
{% if annots.length > 0 %}
{% for annot in annots -%}

{#-**Annotations that start with #, to be turned into markdown style section headers**-#}
{% if annot.annotatedText and "#" in annot.annotatedText %}
{{annot.annotatedText|nl2br|lower|title}} 

{#-**Regular text annotations w/ page number and page link**-#}
{%- elif annot.annotatedText %} 
- <mark style="background: {{annot.color}}">{{annot.annotatedText | nl2br}} </mark> [(pg. {{annot.page}})](zotero://open-pdf/library/items/{{annot.attachment.itemKey}}?page={{annot.page}}) {#**page link**#}
{%- endif -%}

{#-**Image annotations**-#}
{%- if annot.imageRelativePath %}
 ![[{{annot.imageRelativePath}}]]
{%- endif %}

{#-**comment annotations**-#}
{%- if annot.comment %}
>[!annot] Comment
>{{annot.comment | nl2br}}
 {%- endif %}

{%- endfor %}
{%- endif -%}
{%- endpersist -%}

Hope it is helpful!

8 Likes

RE: Pen annotations
You could raise this issue in the plugin’s repository, over on GitHub.

3 Likes

Is there any way to modify the template to dedicate a specific Zotero highlight color to output as a header in Obsidian?
i.e. All blue highlights are inputted into the notes as “## Headers”

I love this thread, thanks to everybody for posting their templates! Helps & inspires me a lot :slight_smile:

I really like the “Go to annotation” link that is included after every annotation when (in Zotero) I create a note from my annotations and then import it into obsidian. It brings you to the page and the annotation “flashes up” for a second. I originally wanted to ask for help to include this when importing annotations directly into obsidian, but with the help of @Zocahontas ’ page link code, I figured it out:
I changed the link name to include the citekey, this way I can copy&paste the annotation including the link into other notes. Even if the link didn’t work for some reason, I would know where the annotation originally came from.

[({{citekey}} pg. {{annot.page}})](zotero://open-pdf/library/items/{{annot.attachment.itemKey}}?page={{annot.page}}&annotation={{annot.id}})

Thank you for posting your template! Could you please explain what “nl2br|lower|title” does? Is this HTML?