Zotlit (previously Obsidian-Zotero) import templates?

Here’s a new and improved version of the templates, based on trial and error and feedback from @aidenlx.

Changes

The zt-annots.eta template was simplified and made easier to read by using the human-readable color names stored under the colorName key, rather than using hex codes. However, there is a bug where the colorName of gray is not gray but the hex code #aaaaaa.This will be fixed in the next release, according to @aidenlx. For now, I just put #aaaaaa as the name when mapping it to its heading.

I added some more information to the info callout in the zt-note.eta template. Because of a workaround for some funky whitespace behavior, which I think is due to the standard Eta configuration, the info callout looks a bit strange, but it will look right when used.

The zt-annot.eta template now also puts tags associated with annotations at the end of the annotation, after the page backlink. Furthermore, it now uses \n rather than two spaces to ensure proper linebreaks in the bullet list. This is cleaner, as \n doesn’t leave any extra spaces trailing the list items. I will share two versions of the zt-annot.eta template, one with block-ids and one without. As the block-ids don’t work in this template for now, I suggest not using them. But if these issues are fixed, then the block-id version can be used.

Template and plugin limitations

  1. Despite adding block-ids to list items, unwrapping the annotations from callouts to enabled the list format is not compatible with the In-place Update of Existing Annotations feature. As is, when updating a literature note, all annotations are reimported and duplicated. Each update adds a full set of annotations, making the literature note longer and longer. So keep that in mind. See this Github comment.

    • This is a pretty big limitation, because it leaves the Overwrite Existing Note setting as the only viable way to update literature notes. However, this means that anything added to literature notes after importing will be lost upon updating the literature note. This also excludes the possibility of linking to blocks in the literature note, as the block-ids will be lost upon updating.
  2. That brings me to another limitation: The block-ids that Obsidian-Zotero adds to annotations are not reused by Obsidian. Obsidian supports custom block-ids like ^something or even random characters like ^JKHFD4reKFG, which it will reuse if you link to that block. For some reason, this is not the case for block-ids added by Obsidian-Zotero (e.g. ^MNEN5JMTaCNYXGZ59p2). They are not reused, and Obsidian will add another block-id, if you link to a block that already has an Obsidian-Zotero block-id. See this Github comment.

  3. This limitation is not related to the template, but the plugin in general. When mapping tags as a yaml value to import under the plugin settings, only manually created tags are imported. Auto generated tags such as those made by the Zotero Tag addon will not be added to the yaml, but they are added to the info callout in the zt-note.eta template. This will probably be fixed.

  4. Some keys or metadata fields from Zotero are not available to import. This includes the Collections and the full PDF path. See this Github comment.

  5. Yaml values can only be formatted as a multi-line list, and not as single-line arrays. According to @aidenlx, this is due to limitations of stringifyYaml in the Obsidian API, but perhaps someone can contribute some solutions or workarounds in this Github issue.

Overall, there are some reliability, templating and feature implementation issues when using custom templates with the Obsidian-Zotero plugin, compared to Zotero Integration, but the result is still pretty satisfactory. The main pro is the speed. In my experience, searching for and importing a literature note is probably 10x faster using Obsidian-Zotero compared to Zotero Integration. Search and import speed is a noted issue with Zotero Integration. However, Obsidian-Zotero does offer an API with the latest release which allows other plugins to access the Zotero database through it, so that could be a solution there. Obsidian-Zotero also overcomes the annoyance of the native Zotero citation picker, which most often appears in the background rather than displaying over Obsidian.

Code

zt-note.eta

# [<%= it.title %>](<%= it.backlink %>)


> [!info]+ Links and info
> 
>**Publication:** <%= it.publicationTitle %>

>**Pages:** <%= it.pages %>

><% if (it.tags && it.tags.length > 0) { %>**Tags:** <%= it.tags.map(tag => '#' + tag.name).join(", ") %><% } %> 
> 
> [**Open in Zotero**](<%= it.backlink %>)
> [**DOI**](https://doi.org/<%= it.DOI %>)


> [!abstract]- Abstract
><%= it.abstractNote %>



## Notes
<%~  include("annots", it.annotations) %>

zt-annot.eta with block-ids

---
callout: false
---

<% if (it.imgEmbed) { %>
- <%= it.imgEmbed %> ^<%= it.blockID %>\n
<% } %>
<% if (it.comment) { %>
- <% if (it.comment.startsWith('todo ')) { %>[ ] **<%= it.comment.substring(5) %>:**<% } else { %>**<%= it.comment %>:**<% } %> ^<%= it.blockID %>\n
	- ==<%= it.text %>== [p. <%= it.pageLabel %>](zotero://open-pdf/library/items/<%= it.parentItem %>?page=<%= it.pageLabel %>&annotation=<%= it.key %>)<% if (it.tags && it.tags.length > 0) { %> <% = it.tags.map(tag => '#' + tag.name).join(", ") %><% } %>\n
<% } else if (it.text) { %>
- ==<%= it.text %>== [p. <%= it.pageLabel %>](zotero://open-pdf/library/items/<%= it.parentItem %>?page=<%= it.pageLabel %>&annotation=<%= it.key %>)<% if (it.tags && it.tags.length > 0) { %> <% = it.tags.map(tag => '#' + tag.name).join(", ") %><% } %> ^<%= it.blockID %>\n
<% } %>

zt-annot.eta without block-ids

---
callout: false
---

<% if (it.imgEmbed) { %>
- <%= it.imgEmbed %>\n
<% } %>
<% if (it.comment) { %>
- <% if (it.comment.startsWith('todo ')) { %>[ ] **<%= it.comment.substring(5) %>:**<% } else { %>**<%= it.comment %>:**<% } %>\n
	- ==<%= it.text %>== [p. <%= it.pageLabel %>](zotero://open-pdf/library/items/<%= it.parentItem %>?page=<%= it.pageLabel %>&annotation=<%= it.key %>) <% if (it.tags && it.tags.length > 0) { %> <% = it.tags.map(tag => '#' + tag.name).join(", ") %><% } %>\n
<% } else if (it.text) { %>
- ==<%= it.text %>== [p. <%= it.pageLabel %>](zotero://open-pdf/library/items/<%= it.parentItem %>?page=<%= it.pageLabel %>&annotation=<%= it.key %>) <% if (it.tags && it.tags.length > 0) { %> <% = it.tags.map(tag => '#' + tag.name).join(", ") %><% } %>\n
<% } %>

zt-annots.eta

<% 
const colorGroups = it.group(annotation => annotation.colorName);
const colorLabel = {
  'blue': '⚡ Hypotheses',
  'green': '💡 Main ideas and conclusions',
  'orange': '⚙️ Method',
  'blue': '❔ Questions',
  'yellow': '⭐ Important',
  'purple': '🧩 Definitions and concepts',
  'red': '⛔ Weaknesses and caveats',
  '#aaaaaa': '📣 Survey instruments'
};
for (const [color, annotations] of Object.entries(colorGroups)) {
%>\n
### <%= colorLabel[color] ?? 'Group' %>
\n
<% for (const annotation of annotations) { %>
<%~ include("annotation", annotation) %>
<% } %>
<% } %>

Screenshots

Metadata and link callout, abstract and annotations grouped by color under custom headings. todo at the start of comments is transformed into a proper task. Comments are bolded and annotations are highlighted using ==. This can be changed in the zt-annot.eta template. Page backlinks open the right annotation in Zotero reader.

Addition of tags:

Multi-line yaml, which is controlled in the plugin settings, not in the template files. The Zotero-key makes the plugin recognize the file as a literature note:

7 Likes