Zum Inhalt springen

Anki-Kartenvorlagen, CSS und Medien wiederverwenden

Verwende dasselbe Anki-Kartendesign in mehreren Stapeln: Bewahre die Vorlagen, das CSS und die Medien eines Notiztyps in einem Verzeichnis auf und lade es für normale Karten oder Cloze-Karten. Die Beispiele verwenden Rust; Python und Node.js laden Pakete mit NoteType.from_bundle und NoteType.fromBundle (siehe Python-API und Node-API).

Ein Vorlagenpaket umfasst eine wiederverwendbare Modelldeklaration, Vorlagentext, CSS und alle ausdrücklich deklarierten Medienabhängigkeiten. NoteType::from_bundle(directory) validiert das vollständige Paket und erstellt Snapshots mit eigenem Datenbesitz, bevor es denselben unveränderlichen NoteType zurückgibt, der auch bei der Definition im Code verwendet wird. Es verändert ein Projekt nicht teilweise.

Terminal-Fenster
cargo run --locked -p ankiforge --example docs_workflow -- target/docs-examples

Der Ablauf lädt das Testpaket für einen eigenen Cloze-Typ und schreibt target/docs-examples/template.apkg. Seine Vorlage weist Karten dem Stapel Languages::Cloze zu. Eine Notiz erzeugt zwei Karten.

Die Manifestdatei heißt anki-template.yaml. Nur das neue Format wird akzeptiert:

format_version: template-bundle-v2
note_type:
key: language-cloze
name: Language Cloze
cloze_field: text
fields:
- key: text
name: Sentence
sort: true
required: true
- key: extra
name: Extra
templates:
- key: cloze
name: Cloze
front_file: front.html
back_file: back.html
browser_front_file: browser-front.html
target_deck: Languages::Cloze
css_file: style.css

note_type.key, Feldschlüssel und Vorlagenschlüssel sind erforderliche stabile Bezeichner. name ist optional und entspricht standardmäßig dem jeweiligen Schlüssel. cloze_field wählt ein Cloze-Modell; eine separate Typdeklaration ist nicht nötig. Ein Feld ohne required: true darf fehlen. Unbekannte Manifesteigenschaften werden zurückgewiesen.

Jede Vorlage verwendet Feldschlüssel, auch für Vorderseite, Rückseite und Kartenbrowser: {{cloze:text}}, {{extra}} und bedingte Abschnitte wie {{#extra}}. Anzeigenamen wie Sentence und Extra werden nach der Bindung für Anki erzeugt. Der Lader erhält ursprüngliche Dateipfade und Bytebereiche der Vorlagen in Fehlermeldungen.

Ein Modell laden und wiederverwenden

Abschnitt „Ein Modell laden und wiederverwenden“
fn bundle(output: &Path, template_directory: &Path) -> anyhow::Result<()> {
let model = NoteType::from_bundle(template_directory)?;
let mut project = Project::new("docs-languages")?;
project.add(
"capital",
model
.note()
.field("text", "{{c1::Madrid}} is in {{c2::Spain}}.")
.field("extra", "A city and its country."),
)?;
let built = project.build(BuildOptions::to(output.join("template.apkg")))?;
verify(&built, 1, 2, 0)?;
Ok(())
}

Für eine unabhängige Anwendung erwartet dieses vollständige Beispiel dasselbe Paket unter fixtures/template-bundle:

use ankiforge::{BuildOptions, NoteType, Project};
fn main() -> anyhow::Result<()> {
let model = NoteType::from_bundle("fixtures/template-bundle")?;
let mut project = Project::new("bundle-example")?;
project.add("capital", model.note()
.field("text", "{{c1::Madrid}} is in {{c2::Spain}}.")
.field("extra", "A city and its country."))?;
let output = project.build(BuildOptions::to("bundle-example.apkg"))?;
assert_eq!(output.report().counts().cards, 2);
Ok(())
}

Das zurückgegebene Modell ist vom Quellverzeichnis unabhängig. Du kannst es mit einem anderen Projekt teilen oder nach dem Entfernen dieses Verzeichnisses verwenden. Ein Ladefehler liefert kein unvollständiges Modell und räumt die nicht anderweitig gehaltenen Snapshots auf.

Deklariere jede Datei, die direkt von Vorlagen, CSS oder Skripten verwendet wird, ausdrücklich. Jeder assets-Eintrag verwendet einen zum Paket relativen Pfad und einen festen Exportnamen:

assets:
- path: assets/badge.png
export_as: badge.png
- path: assets/labels.woff
export_as: labels.woff

Anschließend können Vorlagen <img src="badge.png"> und CSS url('labels.woff') verwenden. Die Eigenschaft css_file gibt die CSS-Quelldatei an; Medien werden nicht aus beliebigem HTML, CSS oder JavaScript abgeleitet. Deklarierte Medien bleiben auch ohne erkannte statische Referenz im APKG. Exportnamen unterliegen denselben Regeln für portable Namen und Unicode-/Groß-/Kleinschreibungskonflikte wie Media. Der vollständige Exportname ist einschließlich Endung auf 255 UTF-8-Bytes begrenzt. Das JSON-Schema prüft Syntax und Zeichenanzahl; NoteType::from_bundle prüft zusätzlich Bytebudget, Dateiinhalte und Referenzen, bevor es ein validiertes Modell zurückgibt. Eine erfolgreiche Schemaprüfung allein garantiert kein erfolgreiches Laden.

Absolute Pfade, Pfadwechsel außerhalb des Pakets und symbolische Links auf Ziele außerhalb des Pakets werden zurückgewiesen. Das Manifest ist auf 256 KiB begrenzt; jede Vorlagen-/CSS-Textdatei auf 2 MiB und muss UTF-8 verwenden. Mediensnapshots verwenden das Standard-Medienbudget oder vom Aufrufer über NoteType::from_bundle_with_limits bereitgestellte MediaLimits. Sowohl vorab ermittelte Längen als auch tatsächlich gelesene Bytes werden geprüft.

Paketfehler erhalten Art und Code, Quellpfad, gegebenenfalls Byteposition und den zugrunde liegenden Schema-, E/A-, YAML-, UTF-8- oder Medienfehler. Der Modellabschluss validiert das Schema; das Hinzufügen von Notizen prüft separat Konflikte auf Projektebene. Siehe Eigene Notiztypen und Fehlersuche.

Markdown anzeigen