diff --git a/server.py b/server.py
index 9122ff4862cb7f2f1bdc37ec5568478a86dbee0d..1acfce89d7f209aca3ead0dbc915ca7387b2effd 100755
--- a/server.py
+++ b/server.py
@@ -248,25 +248,28 @@ def logout():
 	session.pop('user')
 	return redirect(request.values.get('ref', url_for('index')))
 
+tabs = {
+	'courses': ('courses_data', 'id', ['visible', 'listed', 'title', 'short',
+			'handle', 'organizer', 'subject', 'semester', 'downloadable',
+			'internal', 'responsible','deleted']),
+	'lectures': ('lectures_data', 'id', ['visible', 'title', 'comment',
+			'internal', 'speaker', 'place', 'time', 'duration', 'jumplist','deleted']),
+	'videos': ('videos_data', 'id', ['visible','deleted']),
+	'chapters': ('chapters', 'id', ['time', 'text', 'visible', 'deleted']),
+	'announcements': ('announcements', 'id', ['text', 'internal', 'level', 'visible', 'deleted'])
+}
+
 @app.route('/edit', methods=['GET', 'POST'])
 @mod_required
 def edit(prefix="", ignore=[]):
 	# All editable tables are expected to have a 'time_updated' field
-	tabs = {
-		'courses': ('courses_data', 'id', ['visible', 'listed', 'title', 'short',
-				'handle', 'organizer', 'subject', 'semester', 'downloadable',
-				'internal', 'responsible','deleted']),
-		'lectures': ('lectures_data', 'id', ['visible', 'title', 'comment',
-				'internal', 'speaker', 'place', 'time', 'duration', 'jumplist','deleted']),
-		'videos': ('videos_data', 'id', ['visible','deleted']),
-		'chapters': ('chapters', 'id', ['time', 'text', 'visible', 'deleted']),
-		'announcements': ('announcements', 'id', ['text', 'internal', 'level', 'visible', 'deleted'])
-	}
+	ignore.append('ref')
 	modify('BEGIN')
 	if request.is_json:
 		changes = request.get_json().items()
 	else:
 		changes = request.args.items()
+	created = {}
 	for key, val in changes:
 		if key in ignore:
 			continue
@@ -277,8 +280,21 @@ def edit(prefix="", ignore=[]):
 		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']['givenName'])
 		modify('UPDATE %s SET %s = ?, time_updated = ? WHERE %s = ?'%(tabs[table][0], column, tabs[table][1]), val, datetime.now(), id)
 	modify('COMMIT')
+	if 'ref' in request.values:
+		return redirect(request.values['ref'])
 	return "OK", 200
 
+@app.route('/new/<table>', methods=['GET', 'POST'])
+@mod_required
+def create(table):
+	assert table in tabs
+	id = modify('INSERT INTO %s (created_by, time_created, time_updated) VALUES (?, ?, ?)'%tabs[table][0],
+			session['user']['dbid'], datetime.now(), datetime.now())
+	edit(prefix=table+'.'+str(id)+'.')
+	if 'ref' in request.values:
+		return redirect(request.values['ref'])
+	return str(id), 200
+
 @app.route('/newcourse', methods=['GET', 'POST'])
 @mod_required
 def new_course():