diff --git a/AnkiConnect.py b/AnkiConnect.py
index c82b098..22c51ab 100644
--- a/AnkiConnect.py
+++ b/AnkiConnect.py
@@ -947,6 +947,64 @@ class AnkiConnect:
return templates
+ @api()
+ def modelTemplates(self, modelName):
+ model = self.collection().models.byName(modelName)
+ if model is None:
+ raise Exception('model was not found: {}'.format(modelName))
+
+ templates = {}
+ for template in model['tmpls']:
+ templates[template['name']] = {'Front': template['qfmt'], 'Back': template['afmt']}
+
+ return templates
+
+
+ @api()
+ def modelStyling(self, modelName):
+ model = self.collection().models.byName(modelName)
+ if model is None:
+ raise Exception('model was not found: {}'.format(modelName))
+
+ return {'css': model['css']}
+
+
+ @api()
+ def updateModelTemplates(self, model):
+ models = self.collection().models
+ ankiModel = models.byName(model['name'])
+ if ankiModel is None:
+ raise Exception('model was not found: {}'.format(model['name']))
+
+ templates = model['templates']
+
+ for ankiTemplate in ankiModel['tmpls']:
+ template = templates.get(ankiTemplate['name'])
+ if template:
+ qfmt = template.get('Front')
+ if qfmt:
+ ankiTemplate['qfmt'] = qfmt
+
+ afmt = template.get('Back')
+ if afmt:
+ ankiTemplate['afmt'] = afmt
+
+ models.save(ankiModel, True)
+ models.flush()
+
+
+ @api()
+ def updateModelStyling(self, model):
+ models = self.collection().models
+ ankiModel = models.byName(model['name'])
+ if ankiModel is None:
+ raise Exception('model was not found: {}'.format(model['name']))
+
+ ankiModel['css'] = model['css']
+
+ models.save(ankiModel, True)
+ models.flush()
+
@api()
def deckNameFromId(self, deckId):
diff --git a/README.md b/README.md
index 74a3fa4..08195a6 100644
--- a/README.md
+++ b/README.md
@@ -820,6 +820,125 @@ guarantee that your application continues to function properly in the future.
}
```
+
+* **modelTemplates**
+
+ Returns an object indicating the template content for each card connected to the provided model by name.
+
+ *Sample request*:
+ ```json
+ {
+ "action": "modelTemplates",
+ "version": 6,
+ "params": {
+ "modelName": "Basic (and reversed card)"
+ }
+ }
+ ```
+
+ *Sample result*
+ ```json
+ {
+ "result": {
+ "Card 1": {
+ "Front": "{{Front}}",
+ "Back": "{{FrontSide}}\n\n
\n\n{{Back}}"
+ },
+ "Card 2": {
+ "Front": "{{Back}}",
+ "Back": "{{FrontSide}}\n\n
\n\n{{Front}}"
+ }
+ },
+ "error": null
+ }
+ ```
+
+
+* **modelStyling**
+
+ Gets the CSS styling for the provided model by name.
+
+ *Sample request*:
+ ```json
+ {
+ "action": "modelStyling",
+ "version": 6,
+ "params": {
+ "modelName": "Basic (and reversed card)"
+ }
+ }
+ ```
+
+ *Sample result*
+ ```json
+ {
+ "result": {
+ "css": ".card {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n"
+ },
+ "error": null
+ }
+ ```
+
+
+* **updateModelTemplates**
+
+ Modify the templates of an existing model by name. Only specifies cards and specified sides will be modified.
+ If an existing card or side is not included in the request, it will be left unchanged.
+
+ *Sample request*:
+ ```json
+ {
+ "action": "updateModelTemplates",
+ "version": 6,
+ "params": {
+ "model": {
+ "name": "Custom",
+ "templates": {
+ "Card 1": {
+ "Front": "{{Question}}?",
+ "Back": "{{Answer}}!"
+ }
+ }
+ }
+ }
+ }
+ ```
+
+ *Sample result*:
+ ```json
+ {
+ "result": null,
+ "error": null
+ }
+ ```
+
+
+* **updateModelStyling**
+
+ Modify the CSS styling of an existing model by name.
+
+ *Sample request*:
+ ```json
+ {
+ "action": "updateModelStyling",
+ "version": 6,
+ "params": {
+ "model": {
+ "name": "Custom",
+ "css": "p { color: blue; }"
+ }
+ }
+ }
+ ```
+
+ *Sample result*:
+ ```json
+ {
+ "result": null,
+ "error": null
+ }
+ ```
+
#### Notes ####
* **addNote**
diff --git a/tests/test_models.py b/tests/test_models.py
index d30490c..ea83c3f 100755
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -4,6 +4,16 @@ import unittest
import util
+MODEL_1_NAME = 'testModel'
+MODEL_2_NAME = 'testModel-second'
+
+CSS = 'some random css'
+NEW_CSS = 'new random css'
+
+CARD_1_TEMPLATE = {'Front': 'field1', 'Back': 'field2'}
+NEW_CARD_1_TEMPLATE = {'Front': 'question: field1', 'Back': 'answer: field2'}
+
+
class TestModels(unittest.TestCase):
def runTest(self):
# modelNames
@@ -21,10 +31,29 @@ class TestModels(unittest.TestCase):
modelFieldsOnTemplates = util.invoke('modelFieldsOnTemplates', modelName=modelNames[0])
# createModel with css
- newModel = util.invoke('createModel', modelName='testModel', inOrderFields=['field1', 'field2'], cardTemplates=[{'Front':'field1','Back':'field2'}], css='some random css')
+ newModel = util.invoke('createModel', modelName=MODEL_1_NAME, inOrderFields=['field1', 'field2'], cardTemplates=[CARD_1_TEMPLATE], css=CSS)
# createModel without css
- newModel = util.invoke('createModel', modelName='testModel-second', inOrderFields=['field1', 'field2'], cardTemplates=[{'Front':'field1','Back':'field2'}])
+ newModel = util.invoke('createModel', modelName=MODEL_2_NAME, inOrderFields=['field1', 'field2'], cardTemplates=[CARD_1_TEMPLATE])
+
+ # modelStyling: get model 1 css
+ css = util.invoke('modelStyling', modelName=MODEL_1_NAME)
+ self.assertEqual({'css': CSS}, css)
+
+ # modelTemplates: get model 1 templates
+ templates = util.invoke('modelTemplates', modelName=MODEL_1_NAME)
+ self.assertEqual({'Card 1': CARD_1_TEMPLATE}, templates)
+
+ # updateModelStyling: change and verify model css
+ util.invoke('updateModelStyling', model={'name': MODEL_1_NAME, 'css': NEW_CSS})
+ new_css = util.invoke('modelStyling', modelName=MODEL_1_NAME)
+ self.assertEqual({'css': NEW_CSS}, new_css)
+
+ # updateModelTemplates: change and verify model 1 templates
+ util.invoke('updateModelTemplates', model={'name': MODEL_1_NAME, 'templates': {'Card 1': NEW_CARD_1_TEMPLATE}})
+ templates = util.invoke('modelTemplates', modelName=MODEL_1_NAME)
+ self.assertEqual({'Card 1': NEW_CARD_1_TEMPLATE}, templates)
+
if __name__ == '__main__':
unittest.main()