Anki 2.1.20: Updates to card template rendering

Damien Elmes's Avatar

Damien Elmes

17 Jan, 2020 04:37 AM

The card template rendering process in Anki 2.1.20 has changed significantly under the hood, and most of the code that was in the anki/templates folder has gone away. Add-ons that were relying on hooks to modify the card rendering should continue to function, but add-ons that were using or monkey patching methods in the templates module will break, as those methods no longer exist.

I have looked through the add-ons on AnkiWeb that modify the card template, and believe most of them should be able to accomplish what they were doing before by using the new card_did_render and/or field_filter hooks. Examples of how each of them can be used are available here:

https://github.com/ankitects/anki-addons/blob/master/demos/

For add-ons that were using the furigana/hint field modifiers, they are available for copying in the template_legacy.py file.

If the hooks are insufficient for what your add-on is doing, please let me know within the next few weeks. If you're an end user and an add-on you use has broken, please let the add-on author know of this post.

In terms of user-visible changes:

  • The limit of 100 replacements on a template has been dropped.
  • The new approach allow add-ons to add fields without 'unknown field' messages appearing on mobile devices (once they've been updated)
  • Fields with a ':' character are no longer allowed. If you have a ':' in your fields, you can open and close the Cards screen to automatically remove the colon.
  • Templates that reference a field that doesn't exist will now only show an error, instead of partially rendering.
  • {{field}} references are ignored inside fields, so there is no risk of LaTeX/MathJax being interpreted as a field reference.
  • The <% %> alternate syntax is deprecated, as it is no longer necessary due to the above change.
  • Clearer errors when the user forgets to close a {{field}} reference, or mismatches open and close conditionals.

If you have any feedback, please let me know.

  1. 1 Posted by arthur on 20 Jan, 2020 02:00 PM

    arthur's Avatar

    I see you have introduced a way to let users know with which anki version an add-on as been tested. That's, really useful, thank you.
    Is there any way to upload two distinct add-ons, depending on the version ? Or do I need to check version number to see which file I want to import when an add-on needs to change ?

  2. 2 Posted by lovac42 on 20 Jan, 2020 10:57 PM

    lovac42's Avatar

    @arthur, it is much better if you control the versions yourself. If a user zips up the addon and distributes it outside of ankiweb, the zipped package should work with anki regardless of version changes.

  3. Support Staff 3 Posted by Damien Elmes on 21 Jan, 2020 09:23 AM

    Damien Elmes's Avatar

    I'll wager a fair few add-on authors don't want to have to go to the trouble of adding compatibility shims in and supporting multiple versions, so providing a way that authors can focus on the latest build while still providing an older build for users on old versions does make sense. The .ankiaddon manifest format also needs to be updated to support a version specifier as well.

  4. 4 Posted by arthur on 22 Jan, 2020 01:51 AM

    arthur's Avatar

    This comment was split into a new discussion: Problems running from source

    Thank you very much for taking this into consideration.

    I've already received three bugs report related to beta. So I think that
    updating the add-on is already going to take work, and it's far better
    if I can simply concentrate on the new version.

    Sadly, I have never been able to start github's beta on my computer
    (ubuntu), which means I can't debug those add-on immediately.

    Le 21/01/2020 à 01:23, Damien Elmes a écrit :

  5. 5 Posted by arthur on 22 Jan, 2020 12:09 PM

    arthur's Avatar

    Is there a way to have access to version number from add-on anymore ?
    It has been removed from anki/init.py since 2.1.17 it seems.
    I find the number in meta/version and in rspy/Cargo.toml, but I can't figure out how to access it.

    As far as I can tell, meta/version is used only by the setup file. And I've no clue what is Cargo.

  6. Support Staff 6 Posted by Damien Elmes on 23 Jan, 2020 06:38 AM

    Damien Elmes's Avatar

    'from anki import version' should still work.

  7. 7 Posted by arthur on 23 Jan, 2020 11:10 AM

    arthur's Avatar

    Thanks

    Le 22/01/2020 à 22:38, Damien Elmes a écrit :

  8. 8 Posted by dmg on 30 Apr, 2020 10:42 PM

    dmg's Avatar

    The filter mechanism available to addons ( using {abc:field}) is working, but it has a disadvantage. The following will work as expected {abc:furigana:field}. The field is processed by the furigana filter, and then passed to the abc filter. However, the opposite is not truth: {furigana:abc:field}.

    it would be advantageous that once a filter is applied, the resulting text is processed by all the filters again. This will not lead to an infinite loop, as the number of filters is finite, at at every pass, one filter is removed from it.

  9. Support Staff 9 Posted by Damien Elmes on 01 May, 2020 06:41 AM

    Damien Elmes's Avatar

    I'm afraid such a change is unlikely. If you wish to apply stock filters after custom ones, you'll need to implement that functionality in another custom filter. The old stock filters are in the template_legacy.py file and can be largely copied and pasted into your own add-on.

  10. 10 Posted by dmg on 01 May, 2020 07:01 AM

    dmg's Avatar

    Fair enough.

    Another related issue is, there is no way to use the output of a filter to
    make a conditional section.

    For instance, there is no equivalent for:

    {{#{filter:field}}
    optional text if filter:field returns a string.
    {{/filter:field}}

    could this be implemented in anki? it would make custom filters much more
    powerful.

  11. Support Staff 11 Posted by Damien Elmes on 01 May, 2020 10:35 AM

    Damien Elmes's Avatar

    Again unlikely I'm afraid, as if filters had to be applied to conditionals it could considerably slow down card generation in the future.

  12. 12 Posted by dmg on 03 May, 2020 07:15 PM

    dmg's Avatar

    That sounds fair too.

    One last question. Filters require a field text to work. For instance the
    filter

    Is there a way to pass arbitrary text to the filter? Using quotes ie
    {{myfilterOne:"my text"}}. It simply assumes that the quotes are part of a
    field

    this would be very useful to customized the presentation of the card during
    a review based on data of the status of the card (i.e. is the card new? is
    it a review?).
    So far I have been able to do this with fields, but not with text that is
    not in fields (for example, a header). Basically, if were allowed to pass
    any text, it will become a more powerful filtering system.

    thank again for your reply and help,

  13. Support Staff 13 Posted by Damien Elmes on 04 May, 2020 12:35 AM

    Damien Elmes's Avatar

    There is a separate hook to apply a transform to the fully rendered card template, so you could wrap the text in [myflag]some text[/myflag] and then transform that as you wish in an add-on.

    For filters that don't need any input, see how the additional_card_fields add-on works.

Comments are closed, but you can start a new discussion.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac