Hi @mapiq I’m about to get a Boox device and I was worried about the same issue. Did you find a good workaround for this?
Hello @apfelstrudelig, I like very much the way annotations are rendered in callouts! But I’m struggling with 2 things:
- All the callouts are grey, are you using some css or special callouts to render them in different colors?
- I prefer having the annotations listes in the order they appear in the sources, how can I achieve this? (ie. which lines should I erase or modify to have them unordered?
Thanks!
I have been working with this template a little while now, and after returning from fieldwork after a year, and starting to do literature reviews again, I needed to update the buttons plugin.
And here starts my problem, and I hope I can get some imput from you all.
The button template and the meta bind do work, I get updates when hitting the button.
However, there are two problems
When going back to the PDF in zotero, and higlights new parts and when hitting the update button in obsidian, the highlights are placed under the last one instead of grouped.
Secondly; when higlights are removed from the PDF in zotero, it is not removed from the literature note in zotero
I try to illustrate it with these screenshots
After deleting (1stred higlight )and re-higlighting (green, red, yellow) in zotero:
I Guess I should adjust some of the script in the template, which refers to this grouping.
Does some see where I do go wrong?:
{% 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 ~ ‘)](zotero://open-pdf/library/items/’ ~ annotation.attachment.itemKey ~ ‘?page=’ ~ annotation.pageLabel ~ ‘&annotation=’ ~ annotation.id ~ ‘)’ %}
{%- if annotation and loop.first %}
Hi, thanks for creating and sharing your very neat template! I am trying to setup the “Update literature note” button but I can’t seem to get it to work. If I run the “Import ‘import format’” (i.e. a Zotero integration shortcut), I can see the additional annotations and the date/time when they were added appear. However, clicking on the button does nothing. Is there anything wrong with my meta bind command:
actions:
- type: command
command: templater-obsidian:07 - Templates/runImport.md
Hey everyone.
I’ve created a patchwork template for my taste by copy-pasting what I like from the others. It works just fine so far but I’m trying to add one more feature. In the Related Works callout, I’d like to have a column for the authors.
Here is the relevant part:
{%- if relations.length > 0 %}
{{ "" }}
> [!example]- Related Works ({{ relations.length}}):
>
> | Title | Author | Citekey | Links |
> | --- | --- | --- | --- |
{%- for r in relations %}
> | {{formatCell(r.title)}} | {{r.authors}} | [[{{r.citekey}}]] | [Zotero]({{r.desktopURI}}){%- for rAttachment in r.attachments | filterby("path", "endswith", ".pdf") %} [PDF](zotero://open-pdf/library/items/{{rAttachment.itemKey}}){% endfor %} |
{%- endfor -%}
{{ "" }}
{%- endif %}
What I seek for is a working code for {{r.authors}}. Is there anyone knowing how to fix this? Maybe @Feralflora ?
Here is the full template code:
---
citekey: {{citekey}}
aliases:
- "{%- if creators -%}
{{creators[0].lastName or creators[0].name }}
{%- if creators|length == 2 %} & {{creators[1].lastName or creators[1].name}}{% 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 %}
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 %}
libraryID: {{libraryID}}
---
#### {{title}}
**Author(s):** [[{{authors}}]]
**Date:** {{date | format ("YYYY")}}
**Publisher:** {{publisher}}{{publicationTitle}}
**Format:** {{itemType | replace(camelRegex, "$1 $2") | title | trim}}
**Bibliography:** {{bibliography}}
**Collections**:: {% for collection in collections %}[[{{collection.name}}]]{% if not loop.last %}, {% endif %}{% endfor %}
**Keywords:** {% for t in tags %} [[{{t.tag}}]]{% if not loop.last %}, {% endif %}{% endfor %}
**Tags:**
{#- handle | characters in zotero strings used in MD -#}
{%- macro formatCell(cellText) -%}
{{ cellText | replace("|","❕")}}
{%- endmacro -%}
{#- Macros for handling annotations -#}
{%- macro formatAnnotation(annotation, calloutString) -%}
{%- if annotation.imageRelativePath -%}
- {{calloutString}} ![[{{annotation.imageRelativePath}}]] [Zotero, p. {{annotation.pageLabel}}](zotero://open-pdf/library/items/{{annotation.attachment.itemKey}}?page={{annotation.page}}&annotation={{annotation.id}}){% if annotation.hashTags %} {{annotation.hashTags}}{% endif %} ^{{annotation.id-}}
{% if annotation.comment.substring(2) | trim | length > 0 %}
- {{annotation.comment.substring(2) | trim}}
{% else %}
{% endif -%}
{%- elif annotation.comment.substring(2, 3) === "-" -%}
- {{calloutString}} {{annotation.annotatedText}}
{%- elif annotation.comment.substring(2, 3) === "+" %} {{annotation.annotatedText}} [Zotero, p. {{annotation.pageLabel}}](zotero://open-pdf/library/items/{{annotation.attachment.itemKey}}?page={{annotation.page}}&annotation={{annotation.id}}){% if annotation.hashTags %} {{annotation.hashTags}}{% endif %} ^{{annotation.id-}}
{% if annotation.comment.substring(3) | trim | length > 0 %}
- {{annotation.comment.substring(3) | trim}}
{% else %}
{% endif -%}
{%- elif annotation.annotatedText -%}
- {{calloutString}} {{annotation.annotatedText}} [Zotero, p. {{annotation.pageLabel}}](zotero://open-pdf/library/items/{{annotation.attachment.itemKey}}?page={{annotation.page}}&annotation={{annotation.id}}){% if annotation.hashTags %} {{annotation.hashTags}}{% endif %} ^{{annotation.id-}}
{% if annotation.comment.substring(2) | trim | length > 0 %}
- {{annotation.comment.substring(2) | trim}}
{% else %}
{% endif -%}
{%- endif -%}
{%- endmacro %}
### :luc_lightbulb:<mark style="background: #D2B3FFA6;">Key Ideas</mark>
- The author
### :luc_search:<mark style="background: #ADCCFFA6;">Definitions</mark>
- 1.
### :luc_arrow_left_right:<mark style="background: #BBFABBA6;">Related Issues</mark>
- 1.
### :luc_expand:<mark style="background: #FF5582A6;">Subtle Points</mark>
- 1.
### :luc_quote:<mark style="background: #FFF3A3A6;">Key Quotes</mark>
- 1.
### ...
---
> [!info]- Abstract
> {% if abstractNote %}
> {{abstractNote|replace("\n"," ")}}
> {% endif %}
{%- set headingRegex = r/^#+/ -%}
{%- set titleRegex = r/^#+.*/ -%}
{%- set lineRegex = r/^.*$/m %}
{%- if longnotes.length > 0 -%}
{%- for n in longnotes -%}
{%- if n and loop.first %}
> [!note]- Notes ({{longnotes.length}})
{%- 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 %}
> [!quote]- Highlights ({{ annotations.length}}):
> {% 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> [(p. {{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 | nl2br}}
> {%- endif %}
>
> {%- endfor %}
> {%- endif -%}
> {%- endpersist -%}
{%- if relations.length > 0 %}
{{ "" }}
> [!example]- Related Works ({{ relations.length}}):
>
> | Title | Author | Citekey | Links |
> | --- | --- | --- | --- |
{%- for r in relations %}
> | {{formatCell(r.title)}} | {{r.authors}} | [[{{r.citekey}}]] | [Zotero]({{r.desktopURI}}){%- for rAttachment in r.attachments | filterby("path", "endswith", ".pdf") %} [PDF](zotero://open-pdf/library/items/{{rAttachment.itemKey}}){% endfor %} |
{%- endfor -%}
{{ "" }}
{%- endif %}
----
### ...
### :luc_fast_forward: <mark style="background: #FF5582A6;">Progress Log</mark>
- 1.
I have been reading along here for some time because I use zotero to manage my literature and obsidian to analyse my annotations and notes in zotero and prepare and sort them for publication.
From the number of posts in this thread I see that there is obviously a need for exchange on the connection between zotero and obsidian, but no real place for such an exchange.
That would be a separate topic for obsidian templates, for example, where working templates and template development issues could be discussed.
People like me don’t need highly differentiated templates in which red and yellow annotations are compared by date. They need very simple templates that import annotations from zotero into obsidian.
It should be possible to set up a directory of templates somewhere that people who don’t speak a programming language can easily access and use.
For me as an obsidian user this would be a fundamental help.
Does anyone know how to update this template so it would group by color? I found this template here on the forum and works very well, but doesn’t group. It uses a CSS snippet as well which I updated a little bit as some of my Zotero colors weren’t picked up.
Non grouping template
---
{% if title %}Title: "{{title}}"{% endif %}
Authors: {{authors}}{{directors}}
{% if publicationTitle %}Publication: "{{publicationTitle}}"{% endif %}
{% if date %}Date: {{date | format("YYYY-MM-DD")}}{% endif %}
citekey: {{citekey}}
tags: {{hashTags}}
---
## {{title}}
**Bibliographie :** {{bibliography}}
**Link to publication :** {{url}}
**Link Zotero :** {{pdfZoteroLink}}
**Tags :** {{hashTags}}
>[!abstract]+
>*« {{abstractNote}} »*
{% for annotation in annotations -%}
>[!Annotation|{{annotation.color}}]+
>{%- if annotation.annotatedText -%}*« {{annotation.annotatedText}} »*([{{annotation.page}}](zotero://open-pdf/library/items/{{annotation.attachment.itemKey}}?page={{annotation.page}}&annotation={{annotation.id}})){% endif %}{% if annotation.imageRelativePath %}![[{{annotation.imageRelativePath}}]]{% endif %}{% if annotation.comment %}
>
>{{annotation.comment}}{%- endif %}
{% endfor %}
CSS snippet
/* Red */
.callout[data-callout-metadata="#ff6666"],
.callout[data-callout-metadata="#ff4c4c"],
.callout[data-callout-metadata="#ff8080"] {
--callout-color: 205, 52, 92;
}
/* Green */
.callout[data-callout-metadata="#5fb236"],
.callout[data-callout-metadata="#6fbf47"],
.callout[data-callout-metadata="#4fa224"] {
--callout-color: 114, 162, 100;
}
/* Blue */
.callout[data-callout-metadata="#2ea8e5"],
.callout[data-callout-metadata="#4caff0"],
.callout[data-callout-metadata="#1e92d1"] {
--callout-color: 52, 82, 255;
}
/* Purple */
.callout[data-callout-metadata="#a28ae5"],
.callout[data-callout-metadata="#b19ae8"],
.callout[data-callout-metadata="#9377d9"] {
--callout-color: 157, 131, 242;
}
/* Orange */
.callout[data-callout-metadata="#f19837"],
.callout[data-callout-metadata="#ffa347"],
.callout[data-callout-metadata="#e68b27"] {
--callout-color: 244, 164, 96;
}
/* Yellow */
.callout[data-callout-metadata="#ffff11"],
.callout[data-callout-metadata="#ffffe0"],
.callout[data-callout-metadata="##fff8dc"],
.callout[data-callout-metadata="#fffacd"],
.callout[data-callout-metadata="#fff700"],
.callout[data-callout-metadata="##ffef00"],
.callout[data-callout-metadata="#ffffd4"],
.callout[data-callout-metadata="#ffffdd"],
.callout[data-callout-metadata="#ffd400"],
.callout[data-callout-metadata="#ffffd4"],
.callout[data-callout-metadata="#ffeb33"],
.callout[data-callout-metadata="#ffe600"] {
--callout-color: 255, 236, 0;
}
/* Magenta */
.callout[data-callout-metadata="#e56eee"],
.callout[data-callout-metadata="#f080f0"],
.callout[data-callout-metadata="#d154d8"] {
--callout-color: 255, 33, 255;
}
/* Gray */
.callout[data-callout-metadata="#aaaaaa"],
.callout[data-callout-metadata="#bbbbbb"],
.callout[data-callout-metadata="#999999"] {
--callout-color: 152, 152, 152;
}
/* Hide callout icons */
.callout-icon {
display: none;
}
Wow, this is an amazing thread. And a long thread. And a thread with much innovation and change spanning almost three years.
Like many, I’ve cobbled together a template based on snippets from @Feralflora in particular. My issue is, as a non-coder, I don’t know how the template actually works. And that’s not where I want to be as templates are a major building block of an academic workflow.
If anyone finds time and has an interest, I’d be so very grateful for an introductory document or video on coding templates. Or perhaps such basic documentation already exists? If so, I’d be grateful for a pointer.
Thanks very much to all the contributors in this thread
As a start I’ve found a video and related document from Danny Hatcher which are pitched at my level. And of course there’s the Zotero Integration documentation which is clear and quite understandable. The documentation for the template language that the plugin uses, Nunjucks, is more a reference guide to individual template functions for general web use, rather than a ‘How To’ specific to Obsidian templates. Still, it helps in deconstructing the very useful template that @Feralflora has so kindly provided (thank you!).
sure, I can help you with this!
In your template, duplicate this section multiple times, once for each color you want to separate:
{% for annotation in annotations -%}
>[!Annotation|{{annotation.color}}]+
>{%- if annotation.annotatedText -%}*« {{annotation.annotatedText}} »*([{{annotation.page}}](zotero://open-pdf/library/items/{{annotation.attachment.itemKey}}?page={{annotation.page}}&annotation={{annotation.id}})){% endif %}{% if annotation.imageRelativePath %}![[{{annotation.imageRelativePath}}]]{% endif %}{% if annotation.comment %}
>
>{{annotation.comment}}{%- endif %}
{% endfor %}
Next, in each section, change this line
{% for annotation in annotations -%}
to:
{% for annotation in annotations | filterby("colorCategory", "contains", "Blue") -%}
substituting "Blue"
in each block for the name of whatever color of annotations you want to have appear in that block.
Instead of “colorCategory”, you could also technically filter by “color”, but this does not work with the zotero-integrated names of colors (Blue, Green, Yellow, Magenta etc.), and you would then need to specify the color exactly as a hexcode value (e.g. “#5fb236”). For readability, I therefore suggest you use colorCategory.
Try using the zotero integration plugin’s data explorer to inspect the properties of the “annotations” object to see what other properties you might filter for. You can also chain filters together to add multiple conditions, e.g. {% for annotation in annotations | filterby("colorCategory", "contains", "Blue") | filterby("type", "contains", "highlight") -%}
to only get the blue highlights. More info here.
Happy templating!
请问,目前obsidian支持zotero的版本是哪一种?谢谢