Merge pull request #76 from duongban/main

Add tag feature and some utility helpful
This commit is contained in:
John Washam
2021-06-25 08:56:46 -07:00
committed by GitHub
15 changed files with 521 additions and 117 deletions

View File

@@ -0,0 +1,4 @@
create table if not exists tags (
id integer primary key autoincrement,
tagName text not null
);

View File

@@ -1,4 +1,4 @@
drop table if exists cards; -- drop table if exists cards;
create table cards ( create table cards (
id integer primary key autoincrement, id integer primary key autoincrement,
type tinyint not null, /* 1 for vocab, 2 for code */ type tinyint not null, /* 1 for vocab, 2 for code */
@@ -6,3 +6,8 @@ create table cards (
back text not null, back text not null,
known boolean default 0 known boolean default 0
); );
create table tags (
id integer primary key autoincrement,
tagName text not null
);

View File

@@ -5,16 +5,20 @@ from flask import Flask, request, session, g, redirect, url_for, abort, \
app = Flask(__name__) app = Flask(__name__)
app.config.from_object(__name__) app.config.from_object(__name__)
nameDB='cards.db'
pathDB='db'
# Load default config and override config from an environment variable def load_config():
app.config.update(dict( app.config.update(dict(
DATABASE=os.path.join(app.root_path, 'db', 'cards.db'), DATABASE=os.path.join(app.root_path, pathDB, nameDB),
SECRET_KEY='development key', SECRET_KEY='development key',
USERNAME='admin', USERNAME='admin',
PASSWORD='default' PASSWORD='default'
)) ))
app.config.from_envvar('CARDS_SETTINGS', silent=True) app.config.from_envvar('CARDS_SETTINGS', silent=True)
if __name__ == "__main__":
load_config()
def connect_db(): def connect_db():
rv = sqlite3.connect(app.config['DATABASE']) rv = sqlite3.connect(app.config['DATABASE'])
@@ -28,7 +32,6 @@ def init_db():
db.cursor().executescript(f.read()) db.cursor().executescript(f.read())
db.commit() db.commit()
def get_db(): def get_db():
"""Opens a new database connection if there is none yet for the """Opens a new database connection if there is none yet for the
current application context. current application context.
@@ -44,21 +47,10 @@ def close_db(error):
if hasattr(g, 'sqlite_db'): if hasattr(g, 'sqlite_db'):
g.sqlite_db.close() g.sqlite_db.close()
# -----------------------------------------------------------
# Uncomment and use this to initialize database, then comment it
# You can rerun it to pave the database and start over
# @app.route('/initdb')
# def initdb():
# init_db()
# return 'Initialized the database.'
@app.route('/') @app.route('/')
def index(): def index():
if session.get('logged_in'): if session.get('logged_in'):
return redirect(url_for('general')) return redirect(url_for('list_db'))
else: else:
return redirect(url_for('login')) return redirect(url_for('login'))
@@ -75,7 +67,8 @@ def cards():
''' '''
cur = db.execute(query) cur = db.execute(query)
cards = cur.fetchall() cards = cur.fetchall()
return render_template('cards.html', cards=cards, filter_name="all") tags = getAllTag()
return render_template('cards.html', cards=cards, tags=tags, filter_name="all")
@app.route('/filter_cards/<filter_name>') @app.route('/filter_cards/<filter_name>')
@@ -92,15 +85,20 @@ def filter_cards(filter_name):
} }
query = filters.get(filter_name) query = filters.get(filter_name)
if(query is None):
query = "where type = {0}".format(filter_name)
filter_name = int(filter_name)
if not query: if not query:
return redirect(url_for('cards')) return redirect(url_for('show'))
db = get_db() db = get_db()
fullquery = "SELECT id, type, front, back, known FROM cards " + query + " ORDER BY id DESC" fullquery = "SELECT id, type, front, back, known FROM cards " + \
query + " ORDER BY id DESC"
cur = db.execute(fullquery) cur = db.execute(fullquery)
cards = cur.fetchall() cards = cur.fetchall()
return render_template('cards.html', cards=cards, filter_name=filter_name) tags = getAllTag()
return render_template('show.html', cards=cards, tags=tags, filter_name=filter_name)
@app.route('/add', methods=['POST']) @app.route('/add', methods=['POST'])
@@ -130,7 +128,8 @@ def edit(card_id):
''' '''
cur = db.execute(query, [card_id]) cur = db.execute(query, [card_id])
card = cur.fetchone() card = cur.fetchone()
return render_template('edit.html', card=card) tags = getAllTag()
return render_template('edit.html', card=card, tags=tags)
@app.route('/edit_card', methods=['POST']) @app.route('/edit_card', methods=['POST'])
@@ -158,7 +157,7 @@ def edit_card():
]) ])
db.commit() db.commit()
flash('Card saved.') flash('Card saved.')
return redirect(url_for('cards')) return redirect(url_for('show'))
@app.route('/delete/<card_id>') @app.route('/delete/<card_id>')
@@ -171,43 +170,51 @@ def delete(card_id):
flash('Card deleted.') flash('Card deleted.')
return redirect(url_for('cards')) return redirect(url_for('cards'))
@app.route('/memorize')
@app.route('/general') @app.route('/memorize/<card_id>')
@app.route('/general/<card_id>') @app.route('/memorize/<card_type>')
def general(card_id=None): def memorize(card_type, card_id=None):
if not session.get('logged_in'): tag = getTag(card_type)
return redirect(url_for('login')) if tag is None:
return memorize("general", card_id)
@app.route('/code')
@app.route('/code/<card_id>')
def code(card_id=None):
if not session.get('logged_in'):
return redirect(url_for('login'))
return memorize("code", card_id)
def memorize(card_type, card_id):
if card_type == "general":
type = 1
elif card_type == "code":
type = 2
else:
return redirect(url_for('cards')) return redirect(url_for('cards'))
if card_id: if card_id:
card = get_card_by_id(card_id) card = get_card_by_id(card_id)
else: else:
card = get_card(type) card = get_card(card_type)
if not card: if not card:
flash("You've learned all the " + card_type + " cards.") flash("You've learned all the '" + tag[1] + "' cards.")
return redirect(url_for('cards')) return redirect(url_for('show'))
short_answer = (len(card['back']) < 75) short_answer = (len(card['back']) < 75)
tags = getAllTag()
card_type = int(card_type)
return render_template('memorize.html', return render_template('memorize.html',
card=card, card=card,
card_type=card_type, card_type=card_type,
short_answer=short_answer) short_answer=short_answer, tags=tags)
@app.route('/memorize_known')
@app.route('/memorize_known/<card_id>')
@app.route('/memorize_known/<card_type>')
def memorize_known(card_type, card_id=None):
tag = getTag(card_type)
if tag is None:
return redirect(url_for('cards'))
if card_id:
card = get_card_by_id(card_id)
else:
card = get_card_already_known(card_type)
if not card:
flash("You haven't learned any '" + tag[1] + "' cards yet.")
return redirect(url_for('show'))
short_answer = (len(card['back']) < 75)
tags = getAllTag()
card_type = int(card_type)
return render_template('memorize_known.html',
card=card,
card_type=card_type,
short_answer=short_answer, tags=tags)
def get_card(type): def get_card(type):
@@ -252,8 +259,7 @@ def mark_known(card_id, card_type):
db.execute('UPDATE cards SET known = 1 WHERE id = ?', [card_id]) db.execute('UPDATE cards SET known = 1 WHERE id = ?', [card_id])
db.commit() db.commit()
flash('Card marked as known.') flash('Card marked as known.')
return redirect(url_for(card_type)) return redirect(url_for('memorize', card_type=card_type))
@app.route('/login', methods=['GET', 'POST']) @app.route('/login', methods=['GET', 'POST'])
def login(): def login():
@@ -266,7 +272,7 @@ def login():
else: else:
session['logged_in'] = True session['logged_in'] = True
session.permanent = True # stay logged in session.permanent = True # stay logged in
return redirect(url_for('cards')) return redirect(url_for('index'))
return render_template('login.html', error=error) return render_template('login.html', error=error)
@@ -277,5 +283,191 @@ def logout():
return redirect(url_for('index')) return redirect(url_for('index'))
def getAllTag():
if not session.get('logged_in'):
return redirect(url_for('login'))
db = get_db()
query = '''
SELECT id, tagName
FROM tags
ORDER BY id ASC
'''
cur = db.execute(query)
tags = cur.fetchall()
return tags
@app.route('/tags')
def tags():
if not session.get('logged_in'):
return redirect(url_for('login'))
tags = getAllTag()
return render_template('tags.html', tags=tags, filter_name="all")
@app.route('/addTag', methods=['POST'])
def add_tag():
if not session.get('logged_in'):
return redirect(url_for('login'))
db = get_db()
db.execute('INSERT INTO tags (tagName) VALUES (?)',
[request.form['tagName']])
db.commit()
flash('New tag was successfully added.')
return redirect(url_for('tags'))
@app.route('/editTag/<tag_id>')
def edit_tag(tag_id):
if not session.get('logged_in'):
return redirect(url_for('login'))
tag = getTag(tag_id)
return render_template('editTag.html', tag=tag)
@app.route('/updateTag', methods=['POST'])
def update_tag():
if not session.get('logged_in'):
return redirect(url_for('login'))
db = get_db()
command = '''
UPDATE tags
SET
tagName = ?
WHERE id = ?
'''
db.execute(command,
[request.form['tagName'],
request.form['tag_id']
])
db.commit()
flash('Tag saved.')
return redirect(url_for('tags'))
def init_tag():
if not session.get('logged_in'):
return redirect(url_for('login'))
db = get_db()
db.execute('INSERT INTO tags (tagName) VALUES (?)',
["general"])
db.commit()
db.execute('INSERT INTO tags (tagName) VALUES (?)',
["code"])
db.commit()
db.execute('INSERT INTO tags (tagName) VALUES (?)',
["bookmark"])
db.commit()
@app.route('/show')
def show():
if not session.get('logged_in'):
return redirect(url_for('login'))
tags = getAllTag()
return render_template('show.html', tags=tags, filter_name="")
def getTag(tag_id):
if not session.get('logged_in'):
return redirect(url_for('login'))
db = get_db()
query = '''
SELECT id, tagName
FROM tags
WHERE id = ?
'''
cur = db.execute(query, [tag_id])
tag = cur.fetchone()
return tag
@app.route('/bookmark/<card_type>/<card_id>')
def bookmark(card_type, card_id):
if not session.get('logged_in'):
return redirect(url_for('login'))
db = get_db()
db.execute('UPDATE cards SET type = ? WHERE id = ?',[card_type,card_id])
db.commit()
flash('Card saved.')
return redirect(url_for('memorize', card_type=card_type))
@app.route('/list_db')
def list_db():
if not session.get('logged_in'):
return redirect(url_for('login'))
dbs = [f for f in os.listdir(pathDB) if os.path.isfile(os.path.join(pathDB, f))]
dbs = list(filter(lambda k: '.db' in k, dbs))
return render_template('listDb.html', dbs=dbs)
@app.route('/load_db/<name>')
def load_db(name):
if not session.get('logged_in'):
return redirect(url_for('login'))
global nameDB
nameDB=name
load_config()
handle_old_schema()
return redirect(url_for('memorize', card_type="1"))
@app.route('/create_db')
def create_db():
if not session.get('logged_in'):
return redirect(url_for('login'))
return render_template('createDb.html')
@app.route('/init', methods=['POST'])
def init():
if not session.get('logged_in'):
return redirect(url_for('login'))
global nameDB
nameDB = request.form['dbName'] + '.db'
load_config()
init_db()
init_tag()
return redirect(url_for('index'))
def check_table_tag_exists():
db = get_db()
cur = db.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='tags'")
result = cur.fetchone()
print("Table tag : ",result)
return result
def create_tag_table():
db = get_db()
with app.open_resource('data/handle_old_schema.sql', mode='r') as f:
db.cursor().executescript(f.read())
db.commit()
def handle_old_schema():
result = check_table_tag_exists()
if(result is None):
create_tag_table()
init_tag()
def get_card_already_known(type):
db = get_db()
query = '''
SELECT
id, type, front, back, known
FROM cards
WHERE
type = ?
and known = 1
ORDER BY RANDOM()
LIMIT 1
'''
cur = db.execute(query, [type])
return cur.fetchone()
@app.route('/mark_unknown/<card_id>/<card_type>')
def mark_unknown(card_id, card_type):
if not session.get('logged_in'):
return redirect(url_for('login'))
db = get_db()
db.execute('UPDATE cards SET known = 0 WHERE id = ?', [card_id])
db.commit()
flash('Card marked as unknown.')
return redirect(url_for('memorize_known', card_type=card_type))
if __name__ == '__main__': if __name__ == '__main__':
app.run(host='0.0.0.0') app.run(host='0.0.0.0')

View File

@@ -40,11 +40,11 @@ $(document).ready(function(){
$('.toggleButton').removeClass('toggleSelected'); $('.toggleButton').removeClass('toggleSelected');
$(this).addClass('toggleSelected'); $(this).addClass('toggleSelected');
if (checkedVal == '1') { // if (checkedVal == '1') {
$('textarea[name=back]').attr('rows', 5); // $('textarea[name=back]').attr('rows', 5);
} else { // } else {
$('textarea[name=back]').attr('rows', 12); // $('textarea[name=back]').attr('rows', 12);
} // }
$('.fieldFront').show(); $('.fieldFront').show();
$('.fieldBack').show(); $('.fieldBack').show();

View File

@@ -7,7 +7,7 @@ textarea {
font-family: monospace; font-family: monospace;
} }
.cardContent h4 { .cardContent .tagContent h4 {
margin-top: 0; margin-top: 0;
} }

View File

@@ -5,12 +5,11 @@
<h2>Add a Card</h2> <h2>Add a Card</h2>
<form action="{{ url_for('add_card') }}" method="post" class="cardForm"> <form action="{{ url_for('add_card') }}" method="post" class="cardForm">
<div class="form-group"> <div class="form-group">
<label for="general" class="toggleButton btn btn-default btn-lg">General &nbsp; {% for tag in tags %}
<input type="radio" name="type" value="1" id="general"/> <label for={{tag.tagName}} class="toggleButton btn btn-default btn-lg">{{tag.tagName}} &nbsp;
</label> <input type="radio" name="type" value={{tag.id}} id={{tag.tagName}}>
<label for="code" class="toggleButton btn btn-default btn-lg">Code &nbsp;
<input type="radio" name="type" value="2" id="code"/>
</label> </label>
{% endfor %}
</div> </div>
<div class="form-group fieldFront"> <div class="form-group fieldFront">
<label for="front">Front of Card</label> <label for="front">Front of Card</label>
@@ -33,44 +32,5 @@
<div class="page-header"> <div class="page-header">
<h2>{{ cards|length }} Card{{ '' if (cards|length == 1) else 's' }}</h2> <h2>{{ cards|length }} Card{{ '' if (cards|length == 1) else 's' }}</h2>
</div> </div>
<div class="btn-group btn-group-md" role="group" aria-label="filters">
<a href="{{ url_for('filter_cards', filter_name="all") }}" class="btn btn-{{ "primary" if filter_name == "all" else "default" }}">All</a>
<a href="{{ url_for('filter_cards', filter_name="general") }}" class="btn btn-{{ "primary" if filter_name == "general" else "default" }}">General</a>
<a href="{{ url_for('filter_cards', filter_name="code") }}" class="btn btn-{{ "primary" if filter_name == "code" else "default" }}">Code</a>
<a href="{{ url_for('filter_cards', filter_name="known") }}" class="btn btn-{{ "primary" if filter_name == "known" else "default" }}">Known</a>
<a href="{{ url_for('filter_cards', filter_name="unknown") }}" class="btn btn-{{ "primary" if filter_name == "unknown" else "default" }}">Unknown</a>
</div>
<br />
<br />
<table class="table table-bordered">
{% for card in cards %}
<tr>
<td>
<a href="{{ url_for('edit', card_id=card.id) }}" class="btn btn-xs btn-primary"><i class="fa fa-pencil" aria-hidden="true"></i></a>
</td>
<td class="cardContent">
<h4>
{{ card.front }}
</h4>
{% if card.type == 1 %}
{{ card.back|replace("\n", "<br />")|safe }}
{% else %}
<pre><code>{{ card.back|escape }}</code></pre>
{% endif %}
</td>
</tr>
{% else %}
<tr>
<td>
<em>No cards to show.</em>
</td>
</tr>
{% endfor %}
</table>
{% endblock %} {% endblock %}

17
templates/createDb.html Normal file
View File

@@ -0,0 +1,17 @@
{% extends "layout.html" %}
{% block body %}
<div class="well editPanelTag">
<h2>Init database</h2>
<form action="{{ url_for('init') }}" method="post" class="dbForm">
<div class="form-group fieldDbName">
<label for="dbName">Database name</label>
<input type="text" name="dbName" id="dbName" class="form-control">
</div>
<div class="form-group">
<button type="submit" class="saveButton btn btn-lg btn-primary">Create</button>
</div>
</form>
</div>
{% endblock %}

View File

@@ -1,17 +1,24 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block body %} {% block body %}
<div class="well"> <div class="well editPanel">
<h2>Edit Card #{{ card.id }}</h2> <h2>Edit Card #{{ card.id }}</h2>
<form action="{{ url_for('edit_card') }}" method="post" class="cardForm"> <form action="{{ url_for('edit_card') }}" method="post" class="cardForm">
<div class="form-group"> <div class="form-group">
<label for="general" class="btn btn-default btn-lg">General &nbsp; {% for tag in tags %}
<label for={{tag.tagName}} class="toggleButton btn btn-default btn-lg">{{tag.tagName}} &nbsp;
<input type="radio" name="type" value={{tag.id}}
id={{tag.tagName}} {{ "checked" if (card.type == tag.id) else "" }} />
</label>
{% endfor %}
<!-- <label for="general" class="btn btn-default btn-lg">General &nbsp;
<input type="radio" name="type" value="1" <input type="radio" name="type" value="1"
id="general" {{ "checked" if (card.type == 1) else "" }} /> id="general" {{ "checked" if (card.type == 1) else "" }} />
</label> </label>
<label for="code" class="btn btn-default btn-lg">Code &nbsp; <label for="code" class="btn btn-default btn-lg">Code &nbsp;
<input type="radio" name="type" value="2" id="code" {{ "checked" if (card.type == 2) else "" }} /> <input type="radio" name="type" value="2" id="code" {{ "checked" if (card.type == 2) else "" }} />
</label> </label> -->
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="front">Front of Card</label> <label for="front">Front of Card</label>

18
templates/editTag.html Normal file
View File

@@ -0,0 +1,18 @@
{% extends "layout.html" %}
{% block body %}
<div class="well">
<h2>Edit Tag #{{ tag.id }}</h2>
<form action="{{ url_for('update_tag') }}" method="post" class="tagForm">
<div class="form-group">
<label for="tagName">Tag name</label>
<input type="text" name="tagName" id="tagName" class="form-control" value="{{ tag.tagName|e }}">
</div>
<hr />
<div class="form-group">
<input type="hidden" name="tag_id" value="{{ tag.id|e }}" />
<button type="submit" class="saveButton btn btn-lg btn-primary">Save</button>
</div>
</form>
</div>
{% endblock %}

View File

@@ -24,8 +24,12 @@
<li><a href="{{ url_for('login') }}">log in</a></li> <li><a href="{{ url_for('login') }}">log in</a></li>
{% else %} {% else %}
<li><a href="{{ url_for('cards') }}">cards</a></li> <li><a href="{{ url_for('cards') }}">cards</a></li>
<li><a href="{{ url_for('general') }}">general</a></li> <li><a href="{{ url_for('tags') }}">tags</a></li>
<li><a href="{{ url_for('code') }}">code</a></li> <li><a href="{{ url_for('show') }}">show</a></li>
<li><a href="{{ url_for('list_db') }}">list database</a></li>
<li><a href="{{ url_for('create_db') }}">create database</a></li>
<li><a href="{{ url_for('memorize', card_type='1') }}">memorize</a></li>
<li><a href="{{ url_for('memorize_known', card_type='1') }}">memorize known items</a></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;</li> <li>&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li><a href="{{ url_for('logout') }}">log out</a></li> <li><a href="{{ url_for('logout') }}">log out</a></li>
{% endif %} {% endif %}

25
templates/listDb.html Normal file
View File

@@ -0,0 +1,25 @@
{% extends "layout.html" %}
{% block body %}
<table class="table table-bordered">
{% for db in dbs %}
<tr>
<td>
<a href="{{ url_for('load_db', name=db) }}" class="btn btn-lg btn-primary">Load</a>
</td>
<td class="dbContent">
<h4>
{{ db }}
</h4>
</td>
</tr>
{% else %}
<tr>
<td>
<em>No dbs to show.</em>
</td>
</tr>
{% endfor %}
</table>
{% endblock %}

View File

@@ -4,8 +4,9 @@
<div class="row"> <div class="row">
<div class="col-xs-12 text-center"> <div class="col-xs-12 text-center">
<div class="btn-group btn-group-lg" role="group" aria-label="card type"> <div class="btn-group btn-group-lg" role="group" aria-label="card type">
<a href="{{ url_for('general') }}" class="btn btn-{{ "primary" if card_type == "general" else "default" }}">General</a> {% for tag in tags %}
<a href="{{ url_for('code') }}" class="btn btn-{{ "primary" if card_type == "code" else "default" }}">Code</a> <a href="{{ url_for('memorize', card_type=tag.id) }}" class="btn btn-{{ "primary" if card_type == tag.id else "default" }}">{{tag.tagName}}</a>
{% endfor %}
</div> </div>
</div> </div>
</div> </div>
@@ -81,7 +82,7 @@
</a> </a>
&nbsp; &nbsp;
&nbsp; &nbsp;
<a href="{{ url_for(card_type) }}" class="btn btn-primary btn-lg"> <a href="{{ url_for('memorize', card_type=card_type) }}" class="btn btn-primary btn-lg">
Next Card Next Card
<i class="fa fa-arrow-right"></i> <i class="fa fa-arrow-right"></i>
</a> </a>
@@ -92,7 +93,7 @@
<br /> <br />
<br /> <br />
<br /> <br />
<a href="{{ url_for(card_type, card_id=card.id) }}" class="btn btn-default btn-sm"> <a href="{{ url_for('bookmark', card_type=3, card_id=card.id) }}" class="btn btn-default btn-sm">
<i class="fa fa-bookmark"></i> <i class="fa fa-bookmark"></i>
bookmark this card (#{{ card.id }}) bookmark this card (#{{ card.id }})
</a> </a>

View File

@@ -0,0 +1,82 @@
{% extends "layout.html" %}
{% block body %}
<div class="row">
<div class="col-xs-12 text-center">
<div class="btn-group btn-group-lg" role="group" aria-label="card type">
{% for tag in tags %}
<a href="{{ url_for('memorize_known', card_type=tag.id) }}" class="btn btn-{{ "primary" if card_type == tag.id else "default" }}">{{tag.tagName}}</a>
{% endfor %}
</div>
</div>
</div>
<hr/>
<div class="row memorizePanel">
<div class="col-xs-8 col-xs-offset-2">
<div class="panel panel-default cardFront">
<div class="panel-body">
<div class="alignContainer">
<div class="alignMiddle frontText">
<h3 class="text-center">{{ card.front }}</h3>
</div>
</div>
</div>
</div>
<div class="panel panel-primary cardBack">
<div class="panel-body">
<div class="alignContainer">
<div class="alignMiddle frontText">
{% if card.type == 1 %}
{% if short_answer %}
<div class="text-center largerText">
{% endif %}
{{ card.back|replace("\n", "<br />")|safe }}
{% if short_answer %}
</div>
{% endif %}
{% else %}
<pre><code>{{ card.back|escape }}</code></pre>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 text-center">
<a href="javascript:" class="btn btn-primary btn-lg flipCard">
<i class="fa fa-exchange"></i>
Flip Card
</a>
&nbsp;
&nbsp;
<a href="{{ url_for('mark_unknown', card_id=card.id, card_type=card_type) }}" class="btn btn-success btn-lg">
<i class="fa fa-check"></i>
I Unknow It
</a>
&nbsp;
&nbsp;
<a href="{{ url_for('memorize_known', card_type=card_type) }}" class="btn btn-primary btn-lg">
Next Card
<i class="fa fa-arrow-right"></i>
</a>
</div>
</div>
<div class="row">
<div class="col-xs-12 text-center">
<br />
<br />
<br />
<a href="{{ url_for('bookmark', card_type=3, card_id=card.id) }}" class="btn btn-default btn-sm">
<i class="fa fa-bookmark"></i>
bookmark this card (#{{ card.id }})
</a>
</div>
</div>
{% endblock %}

45
templates/show.html Normal file
View File

@@ -0,0 +1,45 @@
{% extends "layout.html" %}
{% block body %}
<div class="page-header">
<h2>{{ cards|length }} Card{{ '' if (cards|length == 1) else 's' }}</h2>
</div>
<div class="btn-group btn-group-md" role="group" aria-label="filters">
<a href="{{ url_for('filter_cards', filter_name="all") }}" class="btn btn-{{ "primary" if filter_name == "all" else "default" }}">all</a>
{% for tag in tags %}
<a href="{{ url_for('filter_cards', filter_name=tag.id) }}" class="btn btn-{{ "primary" if filter_name == tag.id else "default" }}">{{tag.tagName}}</a>
{% endfor %}
<a href="{{ url_for('filter_cards', filter_name="known") }}" class="btn btn-{{ "primary" if filter_name == "known" else "default" }}">known</a>
<a href="{{ url_for('filter_cards', filter_name="unknown") }}" class="btn btn-{{ "primary" if filter_name == "unknown" else "default" }}">unknown</a>
</div>
<br />
<br />
<table class="table table-bordered">
{% for card in cards %}
<tr>
<td>
<a href="{{ url_for('edit', card_id=card.id) }}" class="btn btn-xs btn-primary"><i class="fa fa-pencil" aria-hidden="true"></i></a>
</td>
<td class="cardContent">
<h4>
{{ card.front }}
</h4>
{% if card.type == 1 %}
{{ card.back|replace("\n", "<br />")|safe }}
{% else %}
<pre><code>{{ card.back|escape }}</code></pre>
{% endif %}
</td>
</tr>
{% else %}
<tr>
<td>
<em>No cards to show.</em>
</td>
</tr>
{% endfor %}
</table>
{% endblock %}

44
templates/tags.html Normal file
View File

@@ -0,0 +1,44 @@
{% extends "layout.html" %}
{% block body %}
<div class="well editPanelTag">
<h2>Add a Tag</h2>
<form action="{{ url_for('add_tag') }}" method="post" class="tagForm">
<div class="form-group fieldTagName">
<label for="tagName">Tag name</label>
<input type="text" name="tagName" id="tagName" class="form-control">
</div>
<div class="form-group">
<button type="submit" class="saveButton btn btn-lg btn-primary">Save</button>
</div>
</form>
</div>
<div class="page-header">
<h2>{{ tags|length }} Tag{{ '' if (tags|length == 1) else 's' }}</h2>
</div>
<br />
<br />
<table class="table table-bordered">
{% for tag in tags %}
<tr>
<td>
<a href="{{ url_for('edit_tag', tag_id=tag.id) }}" class="btn btn-xs btn-primary"><i class="fa fa-pencil" aria-hidden="true"></i></a>
</td>
<td class="tagContent">
<h4>
{{ tag.tagName }}
</h4>
</td>
</tr>
{% else %}
<tr>
<td>
<em>No tags to show.</em>
</td>
</tr>
{% endfor %}
</table>
{% endblock %}