Zotero Integration – Import Templates?

No, it works for me. Runs every time I open Obsidian.

You need to update the script, and likely also apply a fix in the kanban file (see below). Latest script version is 1.4.2, which one do you have? This version fixes the capture of the kanban’s settings and frontmatter.

In older versions of the script, “no match” was output if the settings of the kanban were not captured correctly by the script. It seems like that is what is causing your issue.

To fix it, open the kanban as a markdown file (perhaps with the Kanban plugin disabled), and go to the bottom of the file. Where it says “no match”, replace all the settings (starting from %%) with this default fallback:

%% kanban:settings
```
{kanban-plugin: basic}
```
%%

Or if you are using Kanban version 2.0, replace it with this:

%% kanban:settings
```
{kanban-plugin: "board"}
```
%%

I think that’s enough, but I haven’t tested the minimal setting required by Kanban 2.0. Alternatively, you can create a new kanban, open it as markdown, then copy the content from the old kanban into the new one. This way, you should get the proper settings at the bottom.

Like I said, 1.4.2 fixes the setting capture issue, so you’re unlikely to run into this again.

Btw, I post updates in the #feralflora-kanban-zotero-script thread on Discord: Discord

1 Like

thanks, i’ll have a look

first i saw the issue that running the quickadd script added an extra set of yaml fence
i delete those and then i had the error i shared the screenshot of

i’ll check later, thx

Yeah, that should also be fixed in 1.4.2

1 Like

okay, so took it from here

i tried to diff my version and your update and always had some json error issue
so I was just using the updated code as is
then used my quickadd settings to override the original placeholders and paths, etc.

finally updated the kanban settings to board to be in line with the newer kanban plugin

it’s working

thanks very much

2 Likes

Hi all,

I wanted to share the template I made that combines a lot of the things I found in this forum and other documentation, especially the callouts idea from the Notetaking for Historians outline. Note that I’m using custom admonitions instead of callouts with the Admonitions plugins for different colored annotations, but using default options with the plugin is easy to change. (i.e. change ad-research to ad-info and so on).

The workflow I’m using for this is on top of the typical annotations, I like to add a note in Zotero that describe the relevance of an article to my work, and I wanted to easily import that. The template will also create a link to another page so I can further synthesize ideas and summarize the article within Obsidian. Since I also add tags as I’m reading, I also like to import those.

Remove the “\” in front of the all of the ``` terms. I added these so I could post this as a single code block.

---
year: {{date | format("YYYY")}}
tags: [literature, {% for t in tags %}{{t.tag}}{% if not loop.last %}, {% endif %}{% endfor %}]
Authors: [{% for a in creators %}{{a.firstName}} {{a.lastName}}{% if not loop.last %}, {% endif %}{% endfor %}]
---
# {{citekey}}

Literature Note: [[{{title}}]]
URL: {{url}}
DOI: {{doi}}
Zotero Link: {{pdfZoteroLink}}

\```ad-abstract
title: Abstract
{{abstractNote}}
\```
{% for n in notes %}{% for t in n.tags %}{% if t.tag == "relevance" %}
```ad-seealso
{{n.note}}
\```
{% endif %}{% endfor %}{% endfor %}
## Annotations
{% persist "annotations" %} {% set annots = annotations | filterby("date", "dateafter", lastImportDate) %}
{% if annots.length > 0 %} {% for annot in annots %} {% if annot.annotatedText %} {% if annot.color == "#ffd400" %}
\```ad-main
title: Main Idea
> {{annot.annotatedText}}

{% if annot.comment %}
{{annot.comment}}
{% endif %}
\```
{% elif annot.color == "#f19837" %}
\```ad-explain
title: Extra Info
> {{annot.annotatedText}}

{% if annot.comment %}
{{annot.comment}}
{% endif %}
\```
{% elif annot.color == "#a28ae5" %}
```ad-definition
title: Definition
> {{annot.annotatedText}}

{% if annot.comment %}
{{annot.comment}}
{% endif %}
\```
{% elif annot.color == "#aaaaaa" %}
\```ad-thought
title: Thoughts
> {{annot.annotatedText}}

{% if annot.comment %}
{{annot.comment}}
{% endif %}
\```
{% elif annot.color == "#ff6666" %}
\```ad-question
title: Question
> {{annot.annotatedText}}

{% if annot.comment %}
{{annot.comment}}
{% endif %}
\```
{% elif annot.color == "#2ea8e5" %}
\```ad-reference
title: Further Resources
> {{annot.annotatedText}}

{% if annot.comment %}
{{annot.comment}}
{% endif %}
\```
{% elif annot.color == "#5fb236" %}
\```ad-research
title: Research Idea
> {{annot.annotatedText}}

{% if annot.comment %}
{{annot.comment}}
{% endif %}
\```
{% elif annot.color == "#e56eee" %}
\```ad-fun
title: For Fun
> {{annot.annotatedText}}

{% if annot.comment %}
{{annot.comment}}
{% endif %}
\```
{% else %}
\```ad-error
> {{annot.annotatedText}}

{% if annot.comment %}
{{annot.comment}}
{% endif %}
\```
{% endif %} {% endif %} {% endfor %} {% endif %} {% endpersist %}
1 Like

I am looking for a template something similar to this.

I would to have the journal texts that I highlighted and my comments for each highlighted text part together combined. Currently I use separate callout boxes, i.e., Quote call outs and Comments callouts separated.

I have very little understanding of coding. I would really appreciate if someone can guide me to any templates can support such idea.

Thank you so much!

Hi,
I guess I have a common mistake but I just can’t find the solution. I try to use one of the templates of this forum and it worked I just can’t have the Zotero highlight colors (which is why I came here for in the first place).

There was initially no snippets folder in my .obisidian folder and I created it, pasted the right file in the folder as a .css file and “activated it” in my obsidian account but I still can’t make the colors work.

I think its just that I don’t understand the language used and I can’t connect my documents to the color reference doc.

Here are the 2 codes.

Thanks in advance

cssclass: research-note
Year: {{date | format("YYYY")}}

Auteurs : {{authors}}{{directors}}

{% for t in tags %}{{t.tag}}{% if not loop.last %}, {% endif %}{% endfor %}
{{url}}
{{pdfZoteroLink}}

#### Tags:
# {{title}}
---

### 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 %}


{%- 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 %}

and the document called “calloutHeader.css”

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

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

/* Green */
.research-note .callout[data-callout-metadata="#5fb236"] {
  --callout-color: 95, 178, 54;
}

/* Blue */
.research-note .callout[data-callout-metadata="#2ea8e5"] {
  --callout-color: 46, 168, 229;
}

/* Purple */
.research-note .callout[data-callout-metadata="#a28ae5"] {
  --callout-color: 162, 138, 229;
}

Hey there,

since I want to keep it simple and not overcomplicate some things in my workflow, but still want to have the highlight colors and a link to the note in zotero I implemented the following in my single annotation zt-annot.eta file:

 <%= it.imgEmbed %><mark class="omni omni-<%= it.colorName %>"><%= it.text %></mark>
---
[source:](<%= it.backlink %>)

With this the color of the highlight gets transported without any if/then and the link to the zotero file is there as well.

maybe someone finds this helpful

@Feralflora Hi! Thanks so much for the template, has made my first day as obsidian user amazing! I have a troubleshooting request (sorry for being a complete novice…): everything in importing notes goes perfectly apart from colour blocking my notes. Instead i just get the below screenshot – pretty strange as i followed your GitHub instructions to the letter. Any tips?

image

Hi @glumf, I’m glad to hear that :slight_smile: As for your issue, it looks like you just need to install and enable the List Callouts plugin, which will use the symbols at the start of every list item to color the annotations.

1 Like

Hi @Feralflora ,

I’ve been using your template for almost a year now, and it’s been fantastic! I recently purchased a Boox Tab Mini C and have been using its native reader to annotate PDFs. When I import annotations into Zotero, I notice that the highlight colors from the Boox Tab don’t match the default colors in Zotero. Consequently, when exporting annotations to Obsidian, only highlights made with Zotero’s PDF reader get extracted.

I’ve tried manually adjusting each highlight color to match one of Zotero’s options, which resolves the issue, but it’s quite tedious. The Boox Tab device doesn’t allow changing highlight colors, and I’ve already added the closest color matches to the template color map without success.

Is there any way to automate this process or a workaround you could suggest?

Thanks in advance for your help!

Hi! I’ve been trying the different templates here and, after a lot of imports, I decided I want to keep my note importation simple:

  • Import them sequentially, following the original pdf’s page order (instead of grouping them by colors/categories).
  • Avoid callouts, and just import the text, highlighted in its corresponding color (yellow notes in Zotero imported as yellow-highlighted text in my Obsidian note).

I dislike Zotero’s color palette, so I installed @chetachiezikeuzor’s highlighter plugin to customize it, and tried with @Zocahontas’ template. However, I can’t seem to find a way to turn-on the css that activates the new colors, so I keep getting Zotero’s ugly (and difficult to read) colours.

So my code rn looks like this (following @sandeep_Rj):

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 %}

{%- endif -%}

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

{#-comment annotations-#}
{%- if annot.comment %}

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

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


What else do I need in order to active highlighter colors?

Hi! Can you explain how you used the highlighter plug in? I’m trying to customize the highlight colours from my annotations, so when I import them to Obsidian they don’t look like Zotero’s built in colours.

Hello! Creating and modifying my own template for this plugin has been quite challenging, but I’m almost done. There’s only one issue left, regarding usage of the “persist” tag. Unlike most of the templates I have seen with the persist tag which use it in the annotations section, I would like to have an extensive note-taking and organization section that persists regardless of how many times I import annotations. Unfortunately, there seems to be some odd interaction with markdown headers that I don’t quite understand.

The relevant section from my template is:

{% persist "notes" %}
# Notes and Outline
## Section

{% endpersist %}

Which unsurprisingly reads as follows in the resultant file:

%% begin notes %%
# Notes and Outline
## Section

%% end notes %%

But, every subsequent time I run the plugin, all the headers from the original template are copied. I can input my own new headers, and my own simple text, which is not copied. So, from the previous example if I added content such that the relevant section read as:

%% begin notes %%
# Notes and Outline
## Section
### Subsection
- notes 1
	- notes 2
%% end notes %%

On a second pass it reads as:

%% begin notes %%
# Notes and Outline
## Section
### Subsection
- notes 1
	- notes 2
# Notes and Outline
## Section

%% end notes %%

I’m very confused, and am really not sure why this is the case. This is frustrating given that I would like to have lots of headers in the persisted notes section of my template, but I can’t have them copying themselves over and over again. I also noticed that in the example in the documentation, the persist tag is used after a header, and not before. Is this the only way to consistently use the persist tag?

Thanks

Funnily found out the issue after a few minutes, and I feel really dumb. The issue was that the solution is to just import the note headers once on first import, which is show in the documentation. The correct way my code should be formatted is as follows:

{% persist "notes" %}{% if isFirstImport %}
# Notes and Outline
## Section

{% endif %}{% endpersist %}

Hope this helps someone in the future. Cheers!

With an upcoming deadline, I hope you can help me with removing annotations’ automatic grouping by [highlighting] colour to prevent going down the rabbit hole and missing the deadline.

I use an adapted version (see below) of FeralFlora’s template (see his June 1 2023 post above) and removed what I thought was the automatic sorting function (snippet below), but that did not work.

{%- set grouped_annotations = annotations | groupby("color") -%}
{%- for color, colorValue in colorValueMap -%}
{%- if color in grouped_annotations -%} 

This is the adapted version

---
citekey: {{citekey}}
aliases:
- "{%- if creators -%}
        {{creators[0].lastName}}
        {%- if creators|length == 2 %} & {{creators[1].lastName}}{% endif -%}
        {%- if creators|length > 2 %} et al.{% endif -%}
    {%- endif -%}
    {%- if date %} ({{date | format("YYYY")}}){% endif -%} 
    {%- if shortTitle %} {{shortTitle | safe}} {%- else %} {{title | safe}} {%- endif -%}"{% if itemType == "bookSection" %}
book-title: "{{bookTitle | replace('"',"'")}}"{% endif %}
title: "{{title | replace('"',"'")}}"
{%- set camelRegex = r/([a-z])([A-Z])/g %}
{%- for type, creators in creators | groupby("creatorType") %} 
{% if creators.length > 1 %}{{type | replace(camelRegex, "$1 $2") | lower | trim}}s:{%- for creator in creators %}{% if creator.name %}
- {{creator.name}}{% else%}
- {{creator.firstName}} {{creator.lastName}} {% endif %}{%- endfor %} {% else -%}
{{type | replace(camelRegex, "$1-$2") | lower | trim}}:{%- for creator in creators %}{% if creator.name %} "{{creator.name}}"{% else%} "{{creator.firstName}} {{creator.lastName}}"{% endif -%}{%- endfor -%}{% endif -%}{% endfor %}
year: {% if date %}{{date | format("YYYY")}}{% endif %}
item-type: {{itemType | replace(camelRegex, "$1 $2") | title | trim}}
publisher: {% if publicationTitle %}"{{publicationTitle}}"{% else %}"{{publisher}}"{% endif %}
{%- if notes.length > 0 -%}
{%- set longShortCutoff = 20 -%}
{%- set shortnotes = [] -%}
{%- set longnotes = [] -%}
{%- for note in notes -%}
{%- if note.note | wordcount <= longShortCutoff -%}
{%- set shortnotes = (shortnotes.push(note.note), shortnotes) -%} 
{%- else -%}
{%- set longnotes = (longnotes.push(note), longnotes) -%}
{%- endif -%}{%- endfor -%}{%- endif -%}
{%- for comment in shortnotes %}
{%- if comment and loop.first %}
comments:
{% endif -%}
- "{{comment|replace('"',"'")| replace("\n"," ")}}"{% endfor %}
tags:{% for t in tags %}
- {{t.tag | replace(r/\s+/g, "-")}}{% endfor %}{% if DOI %}
- excalidraw
doi: https://doi.org/{{DOI}}{% endif %}{% if itemType == "book" %}
ISBN: {{ISBN}}{% endif %}
cssclasses: 
- literature-note{% if attachments.length > 0 %}{% for attachment in attachments %}{% if loop.first %}
attachments:{% endif %}
- {{attachment.path}}{% endfor %}{% endif %}
excalidraw-plugin: parsed
excalidraw-open-md: true
---

{% persist "notes" -%}
{%- if isFirstImport %}

{#  ==The following sections (Key takeaways and Processing) are not filled automatically. They are for for you to write into manually.== -#}
## Key takeaways

{#- The following is a cursor placeholder for the Templater plugin. After importing the note, you can jump to each of these with an assigned hotkey like ctrl+J  #}

- <% tp.file.cursor(1) %>




![[<%tp.file.title%>.svg]]

## Processing

- **Status**:: new
- **Connections**:: <% tp.file.cursor(4) %>

### [Project name]
- potentiallyRelevantFor[projectID]::

{% endif %}{% endpersist %}

> [!info]- Info 🔗 [**Zotero**]({{desktopURI}}){% if DOI %} | [**DOI**](https://doi.org/{{DOI}}){% endif %}{% for attachment in attachments | filterby("path", "endswith", ".pdf") %} | [**PDF-{{loop.index}}**](file:///{{attachment.path | replace(" ", "%20")}}){%- endfor %}
>
>{% if bibliography %}**Bibliography**: {{bibliography|replace("\n","" )}}{% endif %}
> 
> **Authors**:: {% for a in creators %} [[03 - Source notes/People/{{a.firstName}} {{a.lastName}}|{{a.firstName}} {{a.lastName}}]]{% if not loop.last %}, {% endif %}{% endfor %}
> 
> {% if tags %}**Tags**: {% for t in tags %}#{{t.tag | replace(r/\s+/g, "-")}}{% if not loop.last %}, {% endif %}{% endfor %}{% endif %}
> 
> **Collections**:: {% for collection in collections %}[[{{collection.name}}]]{% if not loop.last %}, {% endif %}{% endfor -%}
{%- set readingSpeed = 220 %}
{%- set wordsPerPage = 360 %}
{%- if pages %}
    {%- set pageRegex = r/(\d+)\-(\d+)/ %}
    {%- set splitPages = pageRegex.test(pages) %}
    {%- if splitPages %}
        {%- set pageMatch = pageRegex.exec(pages) %}
        {%- set firstPage = pageMatch[1] %}
        {%- set pageCount = pageMatch[2] - pageMatch[1] %}
    {%- else %}
        {%- set pageCount = pages %}
    {%- endif %}
{%- elif numPages %}
    {%- set pageCount = numPages %}
{%- else %}
	{%- set pageCount = 0 %}
{% endif -%}
{%- if firstPage %}
>
> **First-page**:: {{firstPage}}
{%- endif -%}
{%- if pageCount > 0 -%}
    {%- set readingTime = ((pageCount* wordsPerPage)/readingSpeed)/60 %}
> 
> **Page-count**:: {{pageCount}}
> 
> **Reading-time**:: {% if readingTime < 1 %}{{(readingTime * 60) | round + " minutes"}}{% else %}{{readingTime | round(3) + " hours"}}{% endif %}{% endif %}

> [!abstract]-
> {% if abstractNote %}
> {{abstractNote|replace("\n","\n>")|striptags(true)|replace("Objectives", "**Objectives**")|replace("Background", "**Background**")|replace("Methodology", "**Methodology**")|replace("Results","**Results**")|replace("Conclusion","**Conclusion**")}}
> {% endif %}

> [!quote]- Citations
> 
> ```query
> content: "@{{citekey}}" -file:@{{citekey}}
> ```

{%- set headingRegex = r/^#+/ -%}
{%- set titleRegex = r/^#+.*/ -%}
{%- set lineRegex = r/^.*$/m %}
{%- if longnotes.length > 0 -%}
{%- for n in longnotes -%}
{%- if n and loop.first %}

> [!note]- Zotero notes ({{longnotes.length}})
> 
> Notes longer than {{longShortCutoff}} words.
{%- endif %}
>> [!example]- Note {{loop.index}} |{%- if headingRegex.test(n.note) == true %}[{{n.note | replace(n.note,titleRegex.exec(n.note))|replace(headingRegex,"")}}]({{n.uri}}){% else %} [{{lineRegex.exec(n.note | truncate(30))}}]({{n.uri}})
>> {% endif %}
>> {{n.note | replace("\n", "\n>> ")| replace(titleRegex, "")}}{% if n.tags.length > 0 %}
>>
>> Tags:{% for t in n.tags %} #{{t.tag}}{% if not loop.last %}, {% endif %}{% endfor %}{% endif -%}{%- if not loop.last %}
>{%- endif -%}
{%- endfor -%}{%- endif %}

___
## Notes

{% set colorValueMap = {
    "#2ea8e5": {
        "colorCategory": "Blue",
        "heading": "Terms and definitions, methods"
    },
    "#5fb236": {
        "colorCategory": "Green",
        "heading": "Connect"
    },
    "#ffd400": {
        "colorCategory": "Yellow",
        "heading": "Explore"
    },
    "#f19837": {
        "colorCategory": "Orange",
        "heading": "Actionable takeaways"
    },
    "#a28ae5": {
        "colorCategory": "Purple",
        "heading": "Concepts and frameworks"
    },
    "#e56eee": {
        "colorCategory": "Magenta",
        "heading": "Context and connections"
    },
	"#ff6666": {
        "colorCategory": "Red",
        "heading": "Disagree, unclear or Problem, hypothesis, issue, situation"
    },
    "#aaaaaa": {
        "colorCategory": "Gray",
        "heading": "Context"
    }
} -%}

{%- macro tagFormatter(annotation) -%}
    {% if annotation.tags -%}
        {%- for t in annotation.tags %} #{{ t.tag | replace(r/\s+/g, "-") }}{% if not loop.last %}, {% endif %}{%- endfor %}
    {%- endif %}
{%- endmacro -%}

{% persist "annotations" %}
{% set annotations = annotations | filterby("date", "dateafter", lastImportDate) -%}
{% if annotations.length > 0 %}
*Imported on [[{{importDate | format("YYYY-MM-DD")}}]] at {{importDate | format("HH:mm")}}*

{%- set grouped_annotations = annotations | groupby("color") -%}
{%- for color, colorValue in colorValueMap -%}
{%- if color in grouped_annotations -%} 
{%- set annotations = grouped_annotations[color] -%}
{%- for annotation in annotations -%}
{%- set citationLink = '[(p. ' ~ annotation.pageLabel ~ ')](' ~ annotation.desktopURI ~ ')' %}
{%- set tagString = tagFormatter(annotation) %}

{%- if annotation and loop.first %}

### {{colorValue.heading}} %% fold %%
{% endif -%}

{%- if annotation.imageRelativePath %}

> [!cite]+ Image {{citationLink}}
> ![[{{annotation.imageRelativePath}}]]{% if annotation.tags %}
> {{tagString}}{% endif %}{%- if (annotation.comment or []).indexOf("todo ") !== -1 %}
> - [ ] {{annotation.comment | replace("todo ", "")}}{%- elif annotation.comment %}
> {{annotation.comment}}{%- endif %}
{% elif (annotation.comment or []).indexOf("todo ") !== -1 %}
- [ ] {{annotation.comment | replace("todo ", "")}}:{% if not annotation.annotatedText %} {{citationLink}}{% else %}
	>{{colorValue.symbol}}  {{annotation.annotatedText | replace(r/\s+/g, " ")}} {{citationLink}}{{tagString}}{% endif -%}
{% elif annotation.comment %}
- {{annotation.comment}}:{% if not annotation.annotatedText %} {{citationLink}}{% else %}
	>{{colorValue.symbol}}  {{annotation.annotatedText | replace(r/\s+/g, " ") }} {{citationLink}}{{tagString}}{% endif -%}
{%- elif annotation.annotatedText %}
 >	{{colorValue.symbol}}  {{annotation.annotatedText | replace(r/\s+/g, " ") }} {{citationLink}}{{tagString}}
{%- endif -%}{%- endfor %}{%- endif -%}
{% endfor -%}
{% endif %}

{% endpersist %}


## Text Elements (Exalidraw)
%%
## Drawing
```compressed-json (excluded for brevity)

%%

Hey y’all,

I’ve been working on this template, slightly modified for my own use, from @lguenth obsidian-templates/zotero.md at main · lguenth/obsidian-templates · GitHub

and I am having trouble with importing annotations after the first import.

For long books or articles where I will do multiple passthroughs, I would like to reimport new annotations. But with the template, the new annotations are created at the bottom of the note with duplicated section headings instead of being inserted into the original section heading.

So right now it looks like:
Main (heading)

  • annotation 1

but if I re-import new annotations associated with the heading it looks like
Main (heading)

  • annotation 1

Main (heading)

  • new annotation

But I am trying to get

Main (heading)

  • annotation 1
  • new annotation

Any ideas on how to modify the template? My obsidian coding is very poor and chatgpt was unfruitful…

TIA!

created: {{importDate|format("YYYY-MM-DD")}}

modified: {{importDate|format("YYYY-MM-DD")}}

{% if tags.length > 0 -%}
    {% for t in tags -%}
        #{{ t.tag | lower }}{% if not loop.last %} {% endif %}
    {%- endfor -%}
{%- endif %}

citekey: {{citekey}}

{#- METADATA AND PERMANENT INDEX -#}

{#-  This part only gets inserted once -#}

{#-  You can use this space to take permanent notes, e.g. to create an index or write a summary, or link to other notes #}

{% persist "notes" %}{% if isFirstImport %}
# {{title}}

## 📇 Index

> [!Cite]  
> {{bibliography}}  

> [!important] Summary
> 
> 
> 

Keywords: 

Related: 

> [!LINK]  
> {%- for attachment in attachments | filterby("path", "endswith", ".pdf") %}  
> [{{attachment.title}}](file://{{attachment.path | replace(" ", "%20")}}) {%- endfor -%}.  

> {% endif %}{% endpersist %}
{#- WARNING: Everything below this line will get overwritten on re-import! -#}

{% persist "annotations" %}
{#- COLOR VARIABLES -#}
{%-
    set zoteroColors = {
        "#2ea8e5": "blue",
        "#5fb236": "green",
        "#a28ae5": "purple",
        "#ffd400": "yellow",
        "#ff6666": "red",
        "#f19837": "orange",
        "#e56eee": "magenta",
        "#aaaaaa": "grey"
    }
-%}

{%-
   set colorHeading = {
        "yellow": "⭐ Main",
        "green": "✅ Definition",
        "purple": "🧩 Methodology",
        "blue": "📚 References",
        "red": "⭕ Questions",
        "magenta": "📎 Info",
        "other": "Misc"
   }
-%}

{#- ANNOTATION TYPES -#}
{%- macro calloutHeader(type) -%}
    {%- switch type -%}
        {%- case "highlight" -%}
        Highlight
        {%- case "image" -%}
        Image
        {%- default -%}
        Note
    {%- endswitch -%}
{%- endmacro %}

{#- SET CUSTOM ANNOTATION COLORS -#}
{%- set newAnnot = [] -%}
{%- set newAnnotations = [] -%}
{%- set annotations = annotations | filterby("date", "dateafter", lastImportDate) %}

{% if annotations.length > 0 %}*Imported: {{importDate | format("YYYY-MM-DD HH:mm")}}*

{%- for annot in annotations -%}

    {%- if annot.color in zoteroColors -%}
        {%- set customColor = zoteroColors[annot.color] -%}
    {%- elif annot.colorCategory|lower in colorHeading -%}
        {%- set customColor = annot.colorCategory|lower -%}
    {%- else -%}
        {%- set customColor = "other" -%}
    {%- endif -%}

    {%- set newAnnotations = (newAnnotations.push({"annotation": annot, "customColor": customColor}), newAnnotations) -%}

{%- endfor -%}

{#- INSERT ANNOTATIONS -#}
{#- Loops through each of the available colors and only inserts matching annotations -#}
{#- This is a workaround for inserting categories in a predefined order (instead of using groupby & the order in which they appear in the PDF) -#}

{%- for color, heading in colorHeading -%}
{%- for entry in newAnnotations | filterby ("customColor", "startswith", color) -%}
{%- set annot = entry.annotation -%}

{%- if entry and loop.first %}

### {{colorHeading[color]}}
{%- endif %}

> [!quote{{"|" + color if color != "other"}}]+ {{calloutHeader(annot.type)}} ([p. {{annot.pageLabel}}](zotero://open-pdf/library/items/{{annot.attachment.itemKey}}?page={{annot.pageLabel}}&annotation={{annot.id}}))

{%- if annot.annotatedText %}
> {% if annot.hashTags %}[[{{annot.hashTags|replace("#", "")}}]]: {% endif -%}
{{annot.annotatedText|nl2br}}
{%- endif %}

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

{%- if annot.ocrText %}
> {{annot.ocrText}}
{%- endif %}

{%- if annot.comment %}
> → **{{annot.comment|nl2br}}**
{%- endif %}

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

Hi, I’m studying philosophy, and for a few months now, I’ve been using Obsidian and Zotero. A few days ago, I discovered Zotero Integration and this topic. Thanks to many of you who shared your templates, I was able to create my own:

{#- infer latest annotation Date -#}
{%- macro maxAnnotationsDate() -%}
{%- set tempDate = “” -%}
{%- for a in annotations -%}
{%- set testDate = a.date | format(“YYYY-MM-DD#HH:mm:ss”) -%}
{%- if testDate > tempDate or tempDate == “”-%}
{%- set tempDate = testDate -%}
{%- endif -%}
{%- endfor -%}
{{tempDate}}
{%- endmacro -%}

{%- set colorCategoryToMeaning = {
“yellow”: “Idea principal”,
“red”: “Definición (es)”,
“green”: “Idea secundaria o de contexto”,
“blue”: “Dato historico”,
“purple”: “Parrafo”,
“magenta”: “Refencia a personalidades”,
“orange”: “Obras y producciones”,
“gray”: “Preguntas y referencias”
}-%}

{# lookup Zotero colors in annotations with Category #}
{%- macro getMeaning(colorCategory) -%}
{%- if colorCategory-%}
{{- colorCategoryToMeaning[colorCategory] -}}
{%- else -%}
{{- colorCategoryToMeaning[“yellow”] -}}
{%- endif -%}
{%- endmacro -%}

{#- handle space characters in zotero tags -#}
{%- macro printTags(rawTags) -%}
{%- if rawTags.length > 0 -%}
{% set comma = joiner() %}
{%- for tag in rawTags -%}
{{- comma() }} [[Kant/{{ tag.tag }}|{{ tag.tag }}]]
{%- endfor %}
{%- endif %}
{%- endmacro -%}

{%- set inline_fields = {
“abtract”: abstractNote,
“Zotero”: pdfZoteroLink,
“Bibliografía”: ‘"’ ~ bibliography ~ ‘"’
}
-%}

{%- set frontmatter_fields = {
“title”: ‘"’ ~ (title | replace (‘"’,‘’) or caseTitle | replace (‘"’,‘’)) ~ ‘"’,
“authors”: ‘[’ ~ authors | replace (“;”, “, “) ~ ‘]’,
“editors”: ‘[’ ~ editors | replace (”;”, “, “) ~ ‘]’,
“directors”: ‘[’ ~ directors | replace (”;”, “, “) ~ ‘]’,
“translators”: ‘[’ ~ translators | replace (”;”, “, “) ~ ‘]’,
“podcasters”: ‘[’ ~ podcasters | replace (”;”, “, “) ~ ‘]’,
“scriptwriters”: ‘[’ ~ scriptwriters | replace (”;”, ", “) ~ ‘]’,
“Tags”: allTags | replace (” ", ““) | replace (”,”, " "),
“first-entry”: minAnnotationsDate,
“last-entry”: maxAnnotationsDate,
“year”: date | format(“YYYY”),
“date”: date | format(“YYYY-MM-DD”),
“citekey”: citekey,
“pages”: numPages,
“running-time”: runningTime,
“type”: type,
“class”: itemType,
“language”: language,
“url”: url,
“isbn”: ISBN}
-%}

{# generate field safely -#}
{%- macro generateField(prefix, delimiter, f, p) -%}
{%- if p and p != “[undefined]”-%}
{{prefix}}{{f}}{{delimiter}}{{p}}
{% endif %}
{%- endmacro -%}

{#- generate fields based on Zotero properties -#}
{%- macro generateFields(prefix, delimiter, fields) -%}
{%- for field, property in fields -%}
{%- if property.length > 0 -%}
{{- generateField(prefix, delimiter, field, property) -}}
{%- endif -%}
{%- endfor -%}
{%- endmacro -%}


aliases: [“{{title}}”{%- if authors and date-%}, "
{%- for author in authors -%}
{{author}}
{%- endfor -%}
{{" (“+date | format(“YYYY”) +”) “}}{{title}}{{caseTitle}}”{%- endif -%}]
{{generateFields(“”,": ",frontmatter_fields) -}}

[!info]- Metadata
{{generateFields(“”,": ",inline_fields) -}}

[!NOTE]- Abstract
{% if abstractNote.length > 0 %}
{{abstractNote}}
{% else -%}
No se encontró abstract disponible.
{% endif -%}
{% if relations.length > 0 -%}
[!note]- Referencias:

Nota Zotero Link

{%- for r in relations %}

| [[{{r.title}}]] | PDF |
{%- endfor -%}
{%- else -%}

[!note]- Referencias:
No se encontraron referencias.
{%- endif -%}
{{ “” }}

Anotaciones.

{% persist “annotations” %}

{%- set newAnnotations = annotations | filterby(“date”, “dateafter”, lastImportDate) -%}
{% if newAnnotations.length > 0 %}
Fecha importación nuevas anotaciones: {{importDate | format(“YY-MM-DD | HH:mm”)}}
{%- set noteIndex = 1 -%}
{% for annotation in newAnnotations %}
{% if annotation.type == “note” and annotation.color == “#a28ae5”%}

[!zotero-{{annotation.colorCategory | lower}}] {{getMeaning(annotation.colorCategory | lower)}} n. {{ noteIndex }} {%- set noteIndex = noteIndex + 1 %}
N. {{ loop.index }} {{annotation.type|capitalize}}
{%- else %}
[!zotero-{{annotation.colorCategory | lower}}] {{ getMeaning(annotation.colorCategory | lower) }}
N. {{ loop.index }} {{annotation.type|capitalize}}
{%- endif %}
{%- if annotation.tags.length > 0 %}
:label: - {{printTags(annotation.tags)}}
{%- endif %}
{%- if annotation.annotatedText.length > 0 %}
:black_nib: - {{annotation.annotatedText}}
{%- endif %}
{%- if annotation.imageRelativePath %}
![[{{annotation.imageRelativePath}}|300]]
{%- endif %}
{%- if annotation.desktopURI %}
:mag_right: - (p. {{annotation.pageLabel}})
{%- endif %}
{%- if annotation.comment %}
:pencil2: - {{annotation.comment | replace (“”, “”) | replace (“”, “”) | replace ("- ", ">- ")}}
{%- endif %}
%%(Id: {{ annotation.id }})%%
{% endfor %}
{# {% endfor %} #}
{%- endif -%}
{%- endpersist -%}

This is a Frankenstein template based on the work of Feralflora and others I found. I don’t know programming.

I need your help to take my template to the next level.
I want to identify the annotations between two “Purple” “notes” and, based on those annotations, create a list. I need to filter this list by color category and print it in order between the two “Purple” “notes”.
My Purple notes correspond to each paragraph, and my other annotations are categories of highlights, such as primary, secondary, context, etc. That’s why I want to do this.
Tanks for the help.

Thanks in advance for your time. Where exactly can I find the import format?

{#- infer latest annotation Date -#}
{%- macro maxAnnotationsDate() -%}
   {%- set tempDate = "" -%}
	{%- for a in annotations -%}
		{%- set testDate = a.date | format("YYYY-MM-DD#HH:mm:ss") -%}
		{%- if testDate > tempDate or tempDate == ""-%}
			{%- set tempDate = testDate -%}
		{%- endif -%}
	{%- endfor -%}
	{{tempDate}}
{%- endmacro -%}


{%- set colorCategoryToMeaning = {
"yellow": "Idea principal",
"red": "Definición (es)",
"green": "Idea secundaria o de contexto",
"blue": "Dato historico",
"purple": "Parrafo",
"magenta": "Refencia a personalidades",
"orange": "Obras y producciones",
"gray": "Preguntas y referencias"
}-%}


{# lookup Zotero colors in annotations with Category #}
{%- macro getMeaning(colorCategory) -%}
	{%- if colorCategory-%}
	 {{- colorCategoryToMeaning[colorCategory] -}}
	{%- else -%}
		{{- colorCategoryToMeaning["yellow"] -}}
	{%- endif -%}
{%- endmacro -%}

{#- handle space characters in zotero tags -#}
{%- macro printTags(rawTags) -%}
	{%- if rawTags.length > 0 -%}
	{% set comma = joiner() %}
		{%- for tag in rawTags -%}
			{{- comma() }} [[Kant/{{ tag.tag }}|{{ tag.tag }}]]
		{%- endfor %}
	{%- endif %}
{%- endmacro -%}

{%- set inline_fields = {
"abtract": abstractNote,
"Zotero": pdfZoteroLink,
"Bibliografía": '"' ~ bibliography ~ '"'
}
-%}

{%- set frontmatter_fields = {
"title": '"' ~ (title | replace ('"','') or caseTitle | replace ('"','')) ~ '"',
"authors": '[' ~ authors | replace (";", ", ") ~ ']',
"editors": '[' ~ editors | replace (";", ", ") ~ ']',
"directors": '[' ~ directors | replace (";", ", ") ~ ']',
"translators": '[' ~ translators | replace (";", ", ") ~ ']',
"podcasters": '[' ~ podcasters | replace (";", ", ") ~ ']',
"scriptwriters": '[' ~ scriptwriters | replace (";", ", ") ~ ']',
"Tags": allTags | replace (" ", "_") | replace (",_", " "), 
"first-entry": minAnnotationsDate,
"last-entry": maxAnnotationsDate,
"year": date | format("YYYY"),
"date": date | format("YYYY-MM-DD"),
"citekey": citekey,
"pages": numPages,
"running-time": runningTime,
"type": type,
"class": itemType,
"language": language,
"url": url,
"isbn": ISBN}
-%}

{# generate field safely -#}
{%- macro generateField(prefix, delimiter, f, p) -%}
{%- if p and p != "[undefined]"-%}
{{prefix}}{{f}}{{delimiter}}{{p}}
{% endif %}
{%- endmacro -%}

{#- generate fields based on Zotero properties -#}
{%- macro generateFields(prefix, delimiter, fields) -%}
{%- for field, property in fields -%}
{%- if property.length > 0 -%}
{{- generateField(prefix, delimiter, field, property) -}}
{%- endif -%}
{%- endfor -%}
{%- endmacro -%}

---
aliases: ["{{title}}"{%- if authors and date-%}, "
{%- for author in authors -%}
{{author}}
{%- endfor -%}
{{" ("+date | format("YYYY") +") "}}{{title}}{{caseTitle}}"{%- endif -%}]
{{generateFields("",": ",frontmatter_fields) -}}
---
> [!info]- Metadata
{{generateFields("",": ",inline_fields) -}}
> > [!NOTE]- Abstract
{% if abstractNote.length > 0 %}
> > {{abstractNote}}
{% else -%}
> > No se encontró abstract disponible.
{% endif -%}
{% if relations.length > 0 -%}
> > [!note]- Referencias:  
> >
> > | Nota | Zotero Link |
> > | --- | --- |
{%- for r in relations %}
> > | [[{{r.title}}]] | [PDF]({{r.desktopURI}}) |
{%- endfor -%}
{%- else -%}
>
> > [!note]- Referencias:  
> > No se encontraron referencias.
{%- endif -%}
{{ "" }}

**<center>Anotaciones.</center>**

{% persist "annotations" %}

{%- set newAnnotations = annotations | filterby("date", "dateafter", lastImportDate) -%}
{% if newAnnotations.length > 0 %}
*Fecha importación nuevas anotaciones*: {{importDate | format("YY-MM-DD | HH:mm")}}
{%- set noteIndex = 1 -%}
{% for annotation in newAnnotations %}
 {% if annotation.type == "note" and annotation.color == "#a28ae5"%} 
> [!zotero-{{annotation.colorCategory | lower}}] {{getMeaning(annotation.colorCategory | lower)}} n. {{ noteIndex }} {%- set noteIndex = noteIndex + 1 %} <br> N. {{ loop.index }} {{annotation.type|capitalize}}
{%- else %}
> [!zotero-{{annotation.colorCategory | lower}}] {{ getMeaning(annotation.colorCategory | lower) }} <br> N. {{ loop.index }} {{annotation.type|capitalize}}  
{%- endif %} 
{%- if annotation.tags.length > 0 %} 
🏷 - {{printTags(annotation.tags)}}
{%- endif %}
{%- if annotation.annotatedText.length > 0 %}
✒ - {{annotation.annotatedText}} 
{%- endif %}
{%- if annotation.imageRelativePath %}
> ![[{{annotation.imageRelativePath}}|300]]
{%- endif %}
{%- if annotation.desktopURI %} 
🔎 - ([p. {{annotation.pageLabel}}]({{annotation.desktopURI}}))
{%- endif %}
{%- if annotation.comment %} 
✏ - {{annotation.comment | replace ("<b>", "") | replace ("</b>", "") | replace ("- ", ">- ")}}
{%- endif %}
%%(Id: {{ annotation.id }})%%
{% endfor %}
{# {% endfor %} #}
{%- endif -%}
{%- endpersist -%}
2 Likes