diff --git a/editapi.py b/editapi.py
index 8b566e68d7db7a2f95fe7e55c5639f65ec1f46e6..2a235c6d9ff2d86a7098027f5ff42aa961844cf8 100644
--- a/editapi.py
+++ b/editapi.py
@@ -1,28 +1,112 @@
 from server import *
 
 # name: (tablename, idcolumn, [editable_fields], [fields_to_set_at_creation_time])
-tabs = {
-	'courses': ('courses_data', 'id', ['visible', 'listed', 'title', 'short',
-			'handle', 'organizer', 'subject', 'semester', 'downloadable',
-			'internal', 'responsible','deleted','description'],
-			['created_by', 'time_created', 'time_updated']),
-	'lectures': ('lectures_data', 'id', ['visible', 'title', 'comment',
-			'internal', 'speaker', 'place', 'time', 'duration', 'jumplist','deleted'],
-			['course_id', 'time_created', 'time_updated']),
-	'videos': ('videos_data', 'id', ['visible','deleted'],
-			['created_by', 'time_created', 'time_updated']),
-	'chapters': ('chapters', 'id', ['time', 'text', 'visible', 'deleted'],
-			['created_by', 'time_created', 'time_updated']),
-	'announcements': ('announcements', 'id', ['text', 'level', 'visible',
-			'deleted', 'time_publish', 'time_expire'],
-			['created_by', 'time_created', 'time_updated']),
-	'featured': ('featured', 'id', ['title', 'text', 'internal', 'visible', 'deleted', 'param', 'param2', 'order'],
-			['created_by', 'time_created', 'time_updated', 'type']),
-	'perm': ('perm', 'id', ['type', 'param1', 'param2', 'deleted'],
-			['course_id', 'lecture_id', 'video_id', 'created_by', 'time_created', 'time_updated']),
-	'sorterrorlog': ('sorterrorlog_data', 'id', ['deleted'],
-			['time_created', 'time_updated'])
-}
+# field types:
+# 	boolean
+# 	shortstring
+# 	text
+# 	datetime
+# 	duration
+# 	videotime
+editable_tables = {
+	'courses': {
+		'table': 'courses_data',
+		'idcolumn': 'id',
+		'editable_fields': {
+			'visible':	{'type': 'boolean'},
+			'listed':	{'type': 'boolean'},
+			'title':	{'type': 'shortstring'},
+			'short':	{'type': 'shortstring'},
+			'handle':	{'type': 'shortstring'},
+			'organizer':	{'type': 'shortstring'},
+			'subject':	{'type': 'shortstring'},
+			'semester':	{'type': 'shortstring'},
+			'downloadable':	{'type': 'boolean'},
+			'internal':	{'type': 'text'},
+			'responsible':	{'type': 'shortstring'},
+			'deleted':	{'type': 'boolean'},
+			'description':	{'type': 'text'} },
+		'creationtime_fields': ['created_by', 'time_created', 'time_updated'] },
+	'lectures': {
+		'table': 'lectures_data',
+		'idcolumn': 'id',
+		'editable_fields': {
+			'visible':	{'type': 'boolean'},
+			'title':	{'type': 'shortstring'},
+			'comment':	{'type': 'text'},
+			'internal':	{'type': 'text'},
+			'speaker':	{'type': 'shortstring'},
+			'place':	{'type': 'shortstring'},
+			'time':		{'type': 'datetime'},
+			'duration':	{'type': 'duration'},
+			'jumplist':	{'type': ''},
+			'deleted':	{'type': 'boolean'}},
+		'creationtime_fields': ['course_id', 'time_created', 'time_updated'] },
+	'videos': {
+		'table': 'videos_data',
+		'idcolumn': 'id',
+		'editable_fields': {
+			'visible':	{'type': 'boolean'},
+			'deleted':	{'type': 'boolean'}},
+		'creationtime_fields': ['created_by', 'time_created', 'time_updated'] },
+	'chapters': {
+		'table': 'chapters',
+		'idcolumn': 'id',
+		'editable_fields': {
+			'time':		{'type': 'videotime'},
+			'text':		{'type': 'shortstring'},
+			'visible':	{'type': 'boolean'},
+			'deleted':	{'type': 'boolean'}},
+		'creationtime_fields': ['created_by', 'time_created', 'time_updated'] },
+	'announcements': {
+		'table': 'announcements',
+		'idcolumn': 'id',
+		'editable_fields': {
+			'text':		{'type': 'text'},
+			'level':	{'type': 'integer'},
+			'visible':	{'type': 'boolean'},
+			'deleted':	{'type': 'boolean'},
+			'time_publish':	{'type': 'datetime'},
+			'time_expire':	{'type': 'datetime'}},
+		'creationtime_fields': ['created_by', 'time_created', 'time_updated'] },
+	'featured': {
+		'table': 'featured',
+		'idcolumn': 'id',
+		'editable_fields':	{
+			'title':	{'type': 'shortstring'},
+			'text':		{'type': 'text'},
+			'internal':	{'type': 'text'},
+			'visible':	{'type': 'boolean'},
+			'deleted':	{'type': 'boolean'},
+			'param':	{'type': 'shortstring'},
+			'param2':	{'type': 'shortstring'},
+			'order':	{'type': 'integer' }},
+		'creationtime_fields': ['created_by', 'time_created', 'time_updated', 'type'] },
+	'perm': {
+		'table': 'perm',
+		'idcolumn': 'id',
+		'editable_fields': {
+			'type':		{'type': 'shortstring'},
+			'param1':	{'type': 'shortstring'},
+			'param2':	{'type': 'shortstring'},
+			'deleted':	{'type': 'boolean'}},
+		'creationtime_fields': ['course_id', 'lecture_id', 'video_id', 'created_by', 'time_created', 'time_updated'] },
+	'sorterrorlog': {
+		'table': 'sorterrorlog_data',
+		'idcolumn': 'id',
+		'editable_fields': {
+			'deleted':	{'type': 'boolean'}},
+		'creationtime_fields': ['time_created', 'time_updated'] }
+	}
+
+#parses the path to a dict, containing the table, id, field and field type
+@app.template_filter(name='parseeditpath')
+def parseeditpath(path):
+	table, id, column = path.split('.', 2)
+	assert table in editable_tables
+	assert column in editable_tables[table]['editable_fields']
+	type = editable_tables[table]['editable_fields'][column]['type']
+	return {'table': table, 'id': id, 'column': column, 'type': type, 'tableinfo': editable_tables[table]}
 
 @app.route('/internal/edit', methods=['GET', 'POST'])
 @mod_required
@@ -41,12 +125,11 @@ def edit(prefix='', ignore=[]):
 		if key in ignore:
 			continue
 		key = prefix+key
-		table, id, column = key.split('.', 2)
-		assert table in tabs
-		assert column in tabs[table][2]
-		modify('INSERT INTO changelog (`table`,id_value, id_key, field, value_new, value_old, `when`, who, executed) VALUES (?,?,?,?,?,(SELECT `%s` FROM %s WHERE %s = ?),?,?,1)'%(column, tabs[table][0], tabs[table][1]),
-				table, id, tabs[table][1], column, val, id, datetime.now(), session['user']['dbid'])
-		modify('UPDATE %s SET `%s` = ?, time_updated = ? WHERE `%s` = ?'%(tabs[table][0], column, tabs[table][1]), val, datetime.now(), id)
+		path = parseeditpath(key)
+		modify('INSERT INTO changelog (`table`,id_value, id_key, field, value_new, value_old, `when`, who, executed) \
+			VALUES (?,?,?,?,?,(SELECT `%s` FROM %s WHERE %s = ?),?,?,1)'%(path['column'], path['tableinfo']['table'], path['tableinfo']['idcolumn']),
+				path['table'], path['id'], path['tableinfo']['idcolumn'], path['column'], val, path['id'], datetime.now(), session['user']['dbid'])
+		modify('UPDATE %s SET `%s` = ?, time_updated = ? WHERE `%s` = ?'%(path['tableinfo']['table'], path['column'], path['tableinfo']['idcolumn']), val, datetime.now(),path['id'])
 	if 'ref' in request.values:
 		return redirect(request.values['ref'])
 	return "OK", 200
@@ -55,12 +138,12 @@ def edit(prefix='', ignore=[]):
 @mod_required
 @csrf_protect
 def create(table):
-	assert table in tabs
+	assert table in editable_tables
 	defaults = {'created_by': session['user']['dbid'], 'time_created': datetime.now(), 'time_updated': datetime.now()}
 	columns = []
 	values = []
 	for column, val in defaults.items():
-		if column in tabs[table][3]:
+		if column in editable_tables[table]['creationtime_fields']:
 			columns.append(column)
 			values.append(val)
 	args = request.values.items()
@@ -69,11 +152,11 @@ def create(table):
 	for column, val in args:
 		if (column == 'ref') or (column == '_csrf_token'):
 			continue
-		assert column in tabs[table][2]+tabs[table][3]
+		assert column in list(editable_tables[table]['editable_fields'].keys())+editable_tables[table]['creationtime_fields']
 		assert column not in defaults
 		columns.append('`'+column+'`')
 		values.append(val)
-	id = modify('INSERT INTO %s (%s) VALUES (%s)'%(tabs[table][0],
+	id = modify('INSERT INTO %s (%s) VALUES (%s)'%(editable_tables[table]['table'],
 				','.join(columns), ','.join(['?']*len(values))), *values)
 	if 'ref' in request.values:
 		return redirect(request.values['ref'])