Browse Source

Add schema and json-editor

master
The Dod 9 months ago
parent
commit
677b53ae90

+ 25
- 2
app.py View File

@@ -1,7 +1,9 @@
1
-from flask import Flask, render_template, request
1
+from flask import Flask, render_template, request, abort, send_from_directory
2 2
 from dotenv import load_dotenv
3 3
 from markdown import markdown
4
+from glob import glob
4 5
 import json
6
+import os
5 7
 
6 8
 def preprocess_payload(payload):
7 9
     for column in payload.get('columns', []):
@@ -14,7 +16,7 @@ def preprocess_payload(payload):
14 16
                 slide['content'] = markdown(md)
15 17
 
16 18
 load_dotenv()
17
-payload = json.load(open("slides.json"))
19
+payload = json.load(open("static/slides.json"))
18 20
 preprocess_payload(payload)
19 21
 
20 22
 application = Flask(__name__)
@@ -23,3 +25,24 @@ application = Flask(__name__)
23 25
 def home():
24 26
     return render_template("slides.html", **payload)
25 27
 
28
+@application.get("/choices/<topic>")
29
+def choices(topic):
30
+    if topic in ["img", "bg"]:
31
+        return {"type": "string", "enum": glob("static/{}/*.*".format(topic))}
32
+    abort(404)
33
+
34
+@application.get("/schema.json")
35
+def schema():
36
+    return render_template("slides.schema.json", backgrounds=choices("bg"))
37
+
38
+def home():
39
+    return render_template("slides.html", **payload)
40
+
41
+@application.get("/editor")
42
+def editor():
43
+    return render_template("editor.html")
44
+
45
+@application.route('/favicon.ico')
46
+def favicon():
47
+    return send_from_directory(os.path.join(application.root_path, 'static'),
48
+                               'favicon.ico', mimetype='image/vnd.microsoft.icon')

static/img/bekir-donmez-stones-4.png → static/bg/bekir-donmez-stones-4.png View File


static/img/bekir-donmez-stones-5.png → static/bg/bekir-donmez-stones-5.png View File


static/img/bekir-donmez-stones-6.png → static/bg/bekir-donmez-stones-6.png View File


static/img/bekir-donmez-stones-7.png → static/bg/bekir-donmez-stones-7.png View File


static/img/bekir-donmez-stones-8.png → static/bg/bekir-donmez-stones-8.png View File


BIN
static/bg/cat-resting.png View File


static/img/particles-1.svg → static/bg/particles-1.svg View File


static/img/valley-1.svg → static/bg/valley-1.svg View File


BIN
static/favicon.ico View File


slides.json → static/slides.json View File

@@ -7,8 +7,7 @@
7 7
             "params": {
8 8
                 "theme": "sky",
9 9
                 "background-image": "static/img/valley-1.svg",
10
-                "background-opacity": "0.25",
11
-                "background-position": "top left"
10
+                "background-opacity": "0.25"
12 11
             },
13 12
             "markdown": "This is my **farewell ceremony**.\n\nI [love](https://en.wikipedia.org/wiki/Love) you all."
14 13
         },
@@ -37,7 +36,6 @@
37 36
                     "params": {
38 37
                         "theme": "moon",
39 38
                         "background-image": "static/img/particles-1.png",
40
-                        "background-position": "center middle",
41 39
                         "background-size": "contain"
42 40
                     },
43 41
                     "markdown": "#### I've rested like a cat.\n\n![A cat resting|w-66 centered](static/img/cat-resting.png)"
@@ -63,7 +61,6 @@
63 61
                     "id": "cat",
64 62
                     "title": "My cat",
65 63
                     "params": {
66
-                        "background-position": "center middle",
67 64
                         "background-size": "contain"
68 65
                     },
69 66
                     "markdown": "![My cat|w-50 float-left](static/img/cat-resting.png)\n\nPlease forgive me, cat, for that and this"

+ 130
- 0
static/slides.schema.json View File

@@ -0,0 +1,130 @@
1
+{
2
+  "type": "object",
3
+  "title": "Presentation",
4
+  "properties": {
5
+    "title": {
6
+      "type": "string"
7
+    },
8
+    "columns": {
9
+      "type": "array",
10
+      "title": "Columns",
11
+      "items": {
12
+        "type": "object",
13
+        "title": "Column",
14
+        "properties": {
15
+          "id": {
16
+            "type": "string"
17
+          },
18
+          "title": {
19
+            "type": "string"
20
+          },
21
+          "params": {
22
+            "$ref": "#/definitions/params"
23
+          },
24
+          "markdown": {
25
+            "$ref": "#/definitions/markdown"
26
+          },
27
+          "slides": {
28
+            "type": "array",
29
+            "options": {
30
+              "collapsed": "true"
31
+            },
32
+            "items": {
33
+              "type": "object",
34
+              "title": "Slide",
35
+              "properties": {
36
+                "id": {
37
+                  "type": "string"
38
+                },
39
+                "title": {
40
+                  "type": "string"
41
+                },
42
+                "params": {
43
+                  "$ref": "#/definitions/params"
44
+                },
45
+                "markdown": {
46
+                  "$ref": "#/definitions/markdown"
47
+                }
48
+              },
49
+              "required": [
50
+                "title",
51
+                "params",
52
+                "markdown"
53
+              ]
54
+            }
55
+          }
56
+        },
57
+        "required": [
58
+          "title",
59
+          "params",
60
+          "markdown"
61
+        ]
62
+      }
63
+    }
64
+  },
65
+  "definitions": {
66
+    "params": {
67
+      "type": "object",
68
+      "title": "Parameters",
69
+      "options": {
70
+        "collapsed": "true"
71
+      },
72
+      "properties": {
73
+        "theme": {
74
+          "type": "string",
75
+          "title": "Theme",
76
+          "enum": [
77
+            "beige",
78
+            "black",
79
+            "blood",
80
+            "league",
81
+            "moon",
82
+            "night",
83
+            "serif",
84
+            "simple",
85
+            "sky",
86
+            "solarized",
87
+            "white"
88
+          ],
89
+          "default": "simple"
90
+        },
91
+        "background-image": {
92
+          "$ref": "/choices/bg",
93
+          "title": "Background image",
94
+          "links": [
95
+            {
96
+              "rel": "Preview image",
97
+              "class": "link-info",
98
+              "href": "{{self}}"
99
+            }
100
+          ]
101
+        },
102
+        "background-opacity": {
103
+          "type": "string",
104
+          "title": "Background opacity",
105
+          "enum": [
106
+            "0.25",
107
+            "0.5",
108
+            "0.75",
109
+            "1"
110
+          ],
111
+          "default": "0.5"
112
+        },
113
+        "background-size": {
114
+          "type": "string",
115
+          "title": "Background size",
116
+          "enum": [
117
+            "contain",
118
+            "cover"
119
+          ],
120
+          "default": "cover"
121
+        }
122
+      }
123
+    },
124
+    "markdown": {
125
+      "type": "string",
126
+      "title": "Content",
127
+      "format": "markdown"
128
+    }
129
+  }
130
+}

+ 51
- 0
templates/editor.html View File

@@ -0,0 +1,51 @@
1
+<!doctype html>
2
+<html lang="en">
3
+  <head>
4
+    <meta charset="utf-8">
5
+    <meta name="viewport" content="width=device-width, initial-scale=1">
6
+    <title>Presentation editor</title>
7
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
8
+    <link rel="stylesheet" href=
9
+        "https://use.fontawesome.com/releases/v5.6.3/css/all.css"
10
+        integrity=
11
+            "sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/"
12
+            crossorigin="anonymous">
13
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css">
14
+  </head>
15
+  <body>
16
+    <div class="container">
17
+      <h1>Presentation editor</h1>
18
+      <div id='editor_holder'></div>
19
+      <button class="btn btn-success" id='submit'>Submit (console.log)</button>
20
+    </div>
21
+    <script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>
22
+    <script src="https://cdn.jsdelivr.net/npm/@json-editor/json-editor@latest/dist/jsoneditor.min.js"></script>
23
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
24
+    <script>
25
+      fetch("/static/slides.schema.json")
26
+        .then(res => res.json())
27
+        .then(schema => {
28
+          console.log(schema);
29
+          fetch("/static/slides.json")
30
+            .then(res => res.json())
31
+            .then(slides => {
32
+              console.log(slides);
33
+              // Initialize the editor with a JSON schema
34
+              var editor = new JSONEditor(
35
+                document.getElementById('editor_holder'), {
36
+                  theme: "bootstrap5",
37
+                  iconlib: "fontawesome5",
38
+                  ajax: true,
39
+                  schema: schema,
40
+                  startval: slides
41
+                });
42
+              // Hook up the submit button to log to the console
43
+              document.getElementById('submit').addEventListener('click',() => {
44
+                // Get the value from the editor
45
+                console.log(editor.getValue());
46
+              });
47
+            });
48
+          });
49
+    </script>
50
+  </body>
51
+</html>

Loading…
Cancel
Save