|
| 1 | +## Example |
| 2 | + |
| 3 | +This is basic public comment board example: |
| 4 | + |
| 5 | +* anyone can post comment with any name |
| 6 | +* only last N post will be displayed |
| 7 | +* comments stored in SQLite |
| 8 | + |
| 9 | +**Do not use the example in production!** Comments board without authorization it's a bad, very bad idea. |
| 10 | +However, the example should be safe for XSS attacks due to user data escaping. |
| 11 | + |
| 12 | +* Create new project based on python template (UI-> Dashboard -> Python) |
| 13 | +* Click files, then click on app.py file. Copy following content: |
| 14 | + |
| 15 | +```python |
| 16 | +import os |
| 17 | +import sqlite3 |
| 18 | +import html |
| 19 | + |
| 20 | +# how many last comments to show |
| 21 | +last_num = 20 |
| 22 | +# db location |
| 23 | +db_name = 'comments.db' |
| 24 | +# define out database schema |
| 25 | +schema = ''' |
| 26 | +CREATE TABLE IF NOT EXISTS comment( |
| 27 | + id INT PRIMARY KEY, |
| 28 | + name VARCHAR(100) NOT NULL, |
| 29 | + comment VARCHAR(255) NOT NULL |
| 30 | +) |
| 31 | +''' |
| 32 | +# html template |
| 33 | +html_template = '''<html><body> |
| 34 | +<div> |
| 35 | +<form method="post" enctype="application/x-www-form-urlencoded"> |
| 36 | +<input type="text" placeholder="your name" name="name" maxlength="100"/><br/> |
| 37 | +<textarea placeholder="comment" maxlength="255" name="comment"></textarea><br/> |
| 38 | +<button type="submit">send</button> |
| 39 | +</form> |
| 40 | +</div> |
| 41 | +{comments} |
| 42 | +</body></html>''' |
| 43 | + |
| 44 | +# form values |
| 45 | +name = os.getenv('NAME') |
| 46 | +comment = os.getenv('COMMENT') |
| 47 | + |
| 48 | +# connect to local database |
| 49 | +with sqlite3.connect(db_name) as conn: |
| 50 | + cur = conn.cursor() |
| 51 | + cur.execute(schema) |
| 52 | + cur.execute('INSERT INTO comment (name, comment) VALUES (?, ?)', (name, comment)) |
| 53 | + conn.commit() |
| 54 | + latest = cur.execute(f'SELECT id, name, comment FROM comment ORDER BY id DESC LIMIT {last_num}') |
| 55 | + # re-render main page comment block |
| 56 | + blocks = [] |
| 57 | + for (id, name, comment) in latest: |
| 58 | + blocks.append(f'<div id="{id}"><p>From: <b>{html.escape(name)}</b></p><p>{html.escape(comment)}</p></div><hr/>') |
| 59 | + page = html_template.replace('{comments}', "\n".join(blocks)) |
| 60 | + with open('static/index.html', 'wt') as f: |
| 61 | + f.write(page) |
| 62 | +``` |
| 63 | + |
| 64 | +* In UI create directory `static`, click on it, create file `index.html` and put following content: |
| 65 | + |
| 66 | +```html |
| 67 | +<html><body> |
| 68 | +<div> |
| 69 | +<form method="post" enctype="application/x-www-form-urlencoded"> |
| 70 | +<input type="text" placeholder="your name" name="name" maxlength="100"/><br/> |
| 71 | +<textarea placeholder="comment" maxlength="255" name="comment"></textarea><br/> |
| 72 | +<button type="submit">send</button> |
| 73 | +</form> |
| 74 | +</div> |
| 75 | +</body></html> |
| 76 | +``` |
| 77 | + |
| 78 | +* Setup mapping for form values: click on Mapping tab and add: |
| 79 | + * output headers: `Content-Type: text/html` |
| 80 | + * query params should be mapped as: comment to `COMMENT` and name to `NAME` |
| 81 | + * set static dir to `static` |
| 82 | + * click 'save' |
| 83 | + |
| 84 | + |
| 85 | + |
| 86 | + |
| 87 | +Done! |
| 88 | + |
| 89 | +Now open URL from overview section by browser and try to post something. |
| 90 | + |
0 commit comments