diff --git a/README.md b/README.md
index 4964856aaf986dfcde25c82e5ea719ff786481bc..840f8eb6cf8a0ee49903a730e08ce4489d9b70dc 100644
--- a/README.md
+++ b/README.md
@@ -89,13 +89,13 @@ All modules are configured in the `.bootstraprc` file. Most modules are disabled
 In order to collect static files from all `INSTALLED_APPS`, i.e. the assets managed by Webpack, run:
 
 ```shell
-(scipostenv) $ ./manage collectstatic
+(scipostenv) $ ./manage.py collectstatic
 ```
 
 This will put all static files in the `STATIC_ROOT` folder defined in your settings file. It's a good idea to use the clear option in order to remove stale static files:
 
 ```shell
-(scipostenv) $ ./manage collectstatic --clear
+(scipostenv) $ ./manage.py collectstatic --clear
 ```
 
 ### Create and run migrations
diff --git a/SciPost_v1/settings/base.py b/SciPost_v1/settings/base.py
index ec132d3dd4453c2710cf181d9fbda302e98005c3..7758de6ee883377b474cd745ca936f0a56bade95 100644
--- a/SciPost_v1/settings/base.py
+++ b/SciPost_v1/settings/base.py
@@ -86,9 +86,11 @@ INSTALLED_APPS = (
     'commentaries',
     'comments',
     'journals',
+    'news',
     'scipost',
     'submissions',
     'theses',
+    'virtualmeetings',
     'webpack_loader'
 )
 
@@ -154,7 +156,6 @@ TEMPLATES = [
                 'django.template.context_processors.media',
                 'django.contrib.auth.context_processors.auth',
                 'django.contrib.messages.context_processors.messages',
-                'scipost.context_processors.searchform',
             ],
         },
     },
diff --git a/SciPost_v1/settings/local_geert.py b/SciPost_v1/settings/local_geert.py
new file mode 100644
index 0000000000000000000000000000000000000000..4a4066579f22049ce0159958c327d3cf11c97124
--- /dev/null
+++ b/SciPost_v1/settings/local_geert.py
@@ -0,0 +1,11 @@
+from .base import *
+import os
+
+# THE MAIN THING HERE
+DEBUG = True
+
+# Static and media
+STATIC_ROOT = os.path.join(BASE_DIR, 'local_files', 'static')
+MEDIA_ROOT = os.path.join(BASE_DIR, 'local_files', 'media')
+WEBPACK_LOADER['DEFAULT']['BUNDLE_DIR_NAME'] =\
+    os.path.join(BASE_DIR, 'static', 'bundles')
diff --git a/SciPost_v1/settings/local_jorran.py b/SciPost_v1/settings/local_jorran.py
index 1eef068e824bdaaa5e51f1b16a15cf80cee2b724..12dcdcfa68b6054fae82ccda1936723bab419563 100644
--- a/SciPost_v1/settings/local_jorran.py
+++ b/SciPost_v1/settings/local_jorran.py
@@ -3,6 +3,15 @@ from .base import *
 # THE MAIN THING HERE
 DEBUG = True
 
+# Debug toolbar settings
+INSTALLED_APPS += (
+    'debug_toolbar',
+)
+MIDDLEWARE_CLASSES += (
+    'debug_toolbar.middleware.DebugToolbarMiddleware',
+)
+INTERNAL_IPS = ['127.0.0.1', '::1']
+
 # Static and media
 STATIC_ROOT = '/Users/jorranwit/Develop/SciPost/scipost_v1/local_files/static/'
 MEDIA_ROOT = '/Users/jorranwit/Develop/SciPost/scipost_v1/local_files/media/'
diff --git a/SciPost_v1/urls.py b/SciPost_v1/urls.py
index 9b85d34e8e3967fdfc82a646d9d8c76443eb3c9a..11c640116c6bffe41466958b01638c47d83103c9 100644
--- a/SciPost_v1/urls.py
+++ b/SciPost_v1/urls.py
@@ -31,5 +31,11 @@ urlpatterns = [
     url(r'^submission/', include('submissions.urls', namespace="submissions")),
     url(r'^theses/', include('theses.urls', namespace="theses")),
     url(r'^thesis/', include('theses.urls', namespace="theses")),
-    # url(r'^captcha/', include('captcha.urls')),
+    url(r'^news/', include('news.urls', namespace="news")),
 ]
+
+if settings.DEBUG:
+    import debug_toolbar
+    urlpatterns += [
+        url(r'^__debug__/', include(debug_toolbar.urls)),
+    ]
diff --git a/commentaries/views.py b/commentaries/views.py
index 640100a7c22436864ce3aab1e7b49e76f10a0c67..e103063d5ff6074d4a37aa0137a51efb166697cd 100644
--- a/commentaries/views.py
+++ b/commentaries/views.py
@@ -282,7 +282,9 @@ class CommentaryListView(ListView):
         context = super().get_context_data(**kwargs)
 
         # Get newest comments
-        context['comment_list'] = Comment.objects.vetted().order_by('-date_submitted')[:10]
+        context['comment_list'] = Comment.objects.vetted().select_related(
+                                  'author__user', 'submission', 'commentary').order_by(
+                                  '-date_submitted')[:10]
 
         # Form into the context!
         context['form'] = self.form
diff --git a/news/__init__.py b/news/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/news/admin.py b/news/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..43253c6cc5b48d7b606f34ea7e5f57f639625ee2
--- /dev/null
+++ b/news/admin.py
@@ -0,0 +1,10 @@
+from django.contrib import admin
+
+from .models import NewsItem
+
+
+class NewsItemAdmin(admin.ModelAdmin):
+    search_fields = ['blurb', 'followup_link_text']
+
+
+admin.site.register(NewsItem, NewsItemAdmin)
diff --git a/news/apps.py b/news/apps.py
new file mode 100644
index 0000000000000000000000000000000000000000..5a7b92d0f844e1bd89c73e7bba369b07298ae70a
--- /dev/null
+++ b/news/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class NewsConfig(AppConfig):
+    name = 'news'
diff --git a/news/migrations/0001_initial.py b/news/migrations/0001_initial.py
new file mode 100644
index 0000000000000000000000000000000000000000..4df07209043385758fe45a5f4a24096fbfd20415
--- /dev/null
+++ b/news/migrations/0001_initial.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-03-06 07:04
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('scipost', '0039_auto_20170306_0804'),
+    ]
+
+    state_operations = [
+        migrations.CreateModel(
+            name='NewsItem',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('date', models.DateField()),
+                ('headline', models.CharField(max_length=300)),
+                ('blurb', models.TextField()),
+                ('followup_link', models.URLField(blank=True, null=True)),
+                ('followup_link_text', models.CharField(blank=True, max_length=300, null=True)),
+            ],
+            options={
+                'db_table': 'scipost_newsitem',
+            },
+        ),
+    ]
+
+    operations = [
+        migrations.SeparateDatabaseAndState(state_operations=state_operations)
+    ]
diff --git a/news/migrations/__init__.py b/news/migrations/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/news/models.py b/news/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..d421b8c4bbae2b55c595dd0d4fcec7347509dc6f
--- /dev/null
+++ b/news/models.py
@@ -0,0 +1,52 @@
+from django.db import models
+from django.template import Template, Context
+
+
+class NewsItem(models.Model):
+    date = models.DateField()
+    headline = models.CharField(max_length=300)
+    blurb = models.TextField()
+    followup_link = models.URLField(blank=True, null=True)
+    followup_link_text = models.CharField(max_length=300, blank=True, null=True)
+
+    class Meta:
+        db_table = 'scipost_newsitem'
+
+    def __str__(self):
+        return self.date.strftime('%Y-%m-%d') + ', ' + self.headline
+
+    def descriptor_full(self):
+        """ For News page. """
+        descriptor = ('<div class="flex-greybox640">'
+                      '<h3 class="NewsHeadline">{{ headline }}</h3>'
+                      '<p>{{ date }}</p>'
+                      '<p>{{ blurb }}</p>'
+                      )
+        context = Context({'headline': self.headline,
+                           'date': self.date.strftime('%Y-%m-%d'),
+                           'blurb': self.blurb, })
+        if self.followup_link:
+            descriptor += '<p><a href="{{ followup_link }}">{{ followup_link_text }}</a></p>'
+            context['followup_link'] = self.followup_link
+            context['followup_link_text'] = self.followup_link_text
+        descriptor += '</div>'
+        template = Template(descriptor)
+        return template.render(context)
+
+    def descriptor_small(self):
+        """ For index page. """
+        descriptor = ('<h3 class="NewsHeadline">{{ headline }}</h3>'
+                      '<div class="p-2">'
+                      '<p>{{ date }}</p>'
+                      '<p>{{ blurb }}</p>'
+                      )
+        context = Context({'headline': self.headline,
+                           'date': self.date.strftime('%Y-%m-%d'),
+                           'blurb': self.blurb, })
+        if self.followup_link:
+            descriptor += '<p><a href="{{ followup_link }}">{{ followup_link_text }}</a></p>'
+            context['followup_link'] = self.followup_link
+            context['followup_link_text'] = self.followup_link_text
+        descriptor += '</div>'
+        template = Template(descriptor)
+        return template.render(context)
diff --git a/news/tests.py b/news/tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ce503c2dd97ba78597f6ff6e4393132753573f6
--- /dev/null
+++ b/news/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/news/urls.py b/news/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..a84f2906bb39ef2937fe1a6ca284e8e6a77368e7
--- /dev/null
+++ b/news/urls.py
@@ -0,0 +1,7 @@
+from django.conf.urls import url
+
+from . import views
+
+urlpatterns = [
+    url(r'^$', views.news, name='news'),
+]
diff --git a/news/views.py b/news/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..6e6773d73118132b4eeeb2ca1c21b4aa6b1dd138
--- /dev/null
+++ b/news/views.py
@@ -0,0 +1,9 @@
+from django.shortcuts import render
+
+from .models import NewsItem
+
+
+def news(request):
+    newsitems = NewsItem.objects.all().order_by('-date')
+    context = {'newsitems': newsitems}
+    return render(request, 'scipost/news.html', context)
diff --git a/requirements.txt b/requirements.txt
index 4e1cfb752935824e29985016edb1fd1bbd4c30e8..a5406b89e2df28e0fe9829ed55487fbc1455a010 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,6 +3,7 @@ Babel==2.3.4
 Django==1.10.3
 django-countries==4.0
 django-crispy-forms==1.6.1
+django-debug-toolbar==1.7
 django-extensions==1.7.6
 django-filter==1.0.0
 django-guardian==1.4.6
diff --git a/scipost/admin.py b/scipost/admin.py
index 799517e9b63c9541937e8669a9945ea2361b77f9..ccb5be7f2600f04a7c149736635d12225bef97aa 100644
--- a/scipost/admin.py
+++ b/scipost/admin.py
@@ -5,60 +5,74 @@ from django.contrib.auth.models import User, Permission
 
 from guardian.admin import GuardedModelAdmin
 
-from scipost.models import *
+from scipost.models import Contributor, Remark, List,\
+                           DraftInvitation, Node, Arc, Graph, Team, AffiliationObject,\
+                           SupportingPartner, SPBMembershipAgreement, RegistrationInvitation,\
+                           AuthorshipClaim, PrecookedEmail
+from virtualmeetings.models import VGM, Feedback, Nomination, Motion
+
 
 class ContributorInline(admin.StackedInline):
     model = Contributor
 
+
 class UserAdmin(UserAdmin):
     inlines = [
         ContributorInline,
         ]
     search_fields = ['last_name', 'email']
 
+
 admin.site.unregister(User)
 admin.site.register(User, UserAdmin)
 
 
-class VGMAdmin(admin.ModelAdmin):
-    search_fields = ['start_date']
-
-admin.site.register(VGM, VGMAdmin)
-
-
-class FeedbackAdmin(admin.ModelAdmin):
-    search_fields = ['feedback', 'by']
-
-admin.site.register(Feedback, FeedbackAdmin)
-
-
-class NominationAdmin(admin.ModelAdmin):
-    search_fields = ['last_name', 'first_name', 'by']
-
-admin.site.register(Nomination, NominationAdmin)
-
-
-class MotionAdmin(admin.ModelAdmin):
-    search_fields = ['background', 'motion', 'put_forward_by']
-
-admin.site.register(Motion, MotionAdmin)
+# class VGMAdmin(admin.ModelAdmin):
+#     search_fields = ['start_date']
+#
+#
+# admin.site.register(VGM, VGMAdmin)
+#
+#
+# class FeedbackAdmin(admin.ModelAdmin):
+#     search_fields = ['feedback', 'by']
+#
+#
+# admin.site.register(Feedback, FeedbackAdmin)
+#
+#
+# class NominationAdmin(admin.ModelAdmin):
+#     search_fields = ['last_name', 'first_name', 'by']
+#
+#
+# admin.site.register(Nomination, NominationAdmin)
+#
+#
+# class MotionAdmin(admin.ModelAdmin):
+#     search_fields = ['background', 'motion', 'put_forward_by']
+#
+#
+# admin.site.register(Motion, MotionAdmin)
 
 
 class RemarkAdmin(admin.ModelAdmin):
     search_fields = ['contributor', 'remark']
 
+
 admin.site.register(Remark, RemarkAdmin)
 
 
 class DraftInvitationAdmin(admin.ModelAdmin):
     search_fields = ['first_name', 'last_name', 'email', 'processed']
 
+
 admin.site.register(DraftInvitation, DraftInvitationAdmin)
 
 
 class RegistrationInvitationAdmin(admin.ModelAdmin):
     search_fields = ['first_name', 'last_name', 'email', 'invitation_key']
 
+
 admin.site.register(RegistrationInvitation, RegistrationInvitationAdmin)
 
 
@@ -69,34 +83,26 @@ admin.site.register(Permission)
 class PrecookedEmailAdmin(admin.ModelAdmin):
     search_fields = ['email_subject', 'email_text', 'emailed_to']
 
-admin.site.register(PrecookedEmail, PrecookedEmailAdmin)
-
-
-class NewsItemAdmin(admin.ModelAdmin):
-    search_fields = ['blurb', 'followup_link_text']
 
-admin.site.register(NewsItem, NewsItemAdmin)
+admin.site.register(PrecookedEmail, PrecookedEmailAdmin)
 
 
 class ListAdmin(GuardedModelAdmin):
     search_fields = ['owner', 'title']
 
-admin.site.register(List, ListAdmin)
 
+admin.site.register(List, ListAdmin)
 admin.site.register(Team)
 
-#admin.site.register(Graph)
-
-#admin.site.register(Node)
-
-#admin.site.register(Arc)
 
 class NodeInline(admin.StackedInline):
     model = Node
 
+
 class ArcInline(admin.StackedInline):
     model = Arc
 
+
 class GraphAdmin(GuardedModelAdmin):
     inlines = [
         NodeInline,
@@ -104,18 +110,21 @@ class GraphAdmin(GuardedModelAdmin):
         ]
     search_fields = ['owner___user__last_name', 'title']
 
+
 admin.site.register(Graph, GraphAdmin)
 
 
 class AffiliationObjectAdmin(admin.ModelAdmin):
     search_fields = ['country', 'institution', 'subunit']
 
+
 admin.site.register(AffiliationObject, AffiliationObjectAdmin)
 
 
 class SPBMembershipAgreementInline(admin.StackedInline):
     model = SPBMembershipAgreement
 
+
 class SupportingPartnerAdmin(admin.ModelAdmin):
     search_fields = ['institution', 'institution_acronym',
                      'institution_address', 'contact_person']
@@ -123,4 +132,5 @@ class SupportingPartnerAdmin(admin.ModelAdmin):
         SPBMembershipAgreementInline,
     ]
 
+
 admin.site.register(SupportingPartner, SupportingPartnerAdmin)
diff --git a/scipost/context_processors.py b/scipost/context_processors.py
deleted file mode 100644
index 19c0fbf686bb62fb3d3908d1f0a370bc9f23165b..0000000000000000000000000000000000000000
--- a/scipost/context_processors.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from .forms import SearchForm
-
-
-def searchform(request):
-    return {'search_form': SearchForm()}
diff --git a/scipost/feeds.py b/scipost/feeds.py
index 297ea1c779d387687b71a39c3a02abe3f7809c70..29ea0a31d6fced705e0c8fd6ac77381e7ed818f8 100644
--- a/scipost/feeds.py
+++ b/scipost/feeds.py
@@ -5,10 +5,10 @@ from django.utils.feedgenerator import Atom1Feed
 from django.core.urlresolvers import reverse
 from django.db.models import Q
 
-from scipost.models import NewsItem
 from scipost.models import subject_areas_dict
 from comments.models import Comment
 from journals.models import Publication
+from news.models import NewsItem
 from submissions.models import Submission, SUBMISSION_STATUS_PUBLICLY_INVISIBLE
 
 
diff --git a/scipost/forms.py b/scipost/forms.py
index 7c628d2f224eff4db20149f95e7765ffc3137e63..b1fb349c3b77db8289ca530b3eb26ea3b02409e3 100644
--- a/scipost/forms.py
+++ b/scipost/forms.py
@@ -16,8 +16,8 @@ from .models import TITLE_CHOICES, SCIPOST_FROM_ADDRESSES, ARC_LENGTHS,\
                      Contributor, DraftInvitation, RegistrationInvitation,\
                      SupportingPartner, SPBMembershipAgreement,\
                      UnavailabilityPeriod, PrecookedEmail,\
-                     List, Team, Graph, Node,\
-                     Feedback, Nomination, Motion
+                     List, Team, Graph, Node
+from virtualmeetings.models import Feedback, Nomination, Motion
 
 from journals.models import Publication
 from submissions.models import SUBMISSION_STATUS_PUBLICLY_UNLISTED
@@ -210,9 +210,7 @@ class RemarkForm(forms.Form):
 
 
 class SearchForm(forms.Form):
-    query = forms.CharField(max_length=100, label='',
-                            widget=forms.TextInput(attrs={
-                                'class': 'form-control mr-0 mb-2 mr-lg-2 mb-lg-0'}))
+    q = forms.CharField(max_length=100)
 
 
 class EmailGroupMembersForm(forms.Form):
diff --git a/scipost/migrations/0039_auto_20170306_0804.py b/scipost/migrations/0039_auto_20170306_0804.py
new file mode 100644
index 0000000000000000000000000000000000000000..49894a205825fdbe083d86f688b835138d7516ce
--- /dev/null
+++ b/scipost/migrations/0039_auto_20170306_0804.py
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-03-06 07:04
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('scipost', '0038_nomination_webpage'),
+    ]
+
+    state_operations = [
+        migrations.RemoveField(
+            model_name='feedback',
+            name='VGM',
+        ),
+        migrations.RemoveField(
+            model_name='feedback',
+            name='by',
+        ),
+        migrations.RemoveField(
+            model_name='motion',
+            name='VGM',
+        ),
+        migrations.RemoveField(
+            model_name='motion',
+            name='in_agreement',
+        ),
+        migrations.RemoveField(
+            model_name='motion',
+            name='in_disagreement',
+        ),
+        migrations.RemoveField(
+            model_name='motion',
+            name='in_notsure',
+        ),
+        migrations.RemoveField(
+            model_name='motion',
+            name='put_forward_by',
+        ),
+        migrations.DeleteModel(
+            name='NewsItem',
+        ),
+        migrations.RemoveField(
+            model_name='nomination',
+            name='VGM',
+        ),
+        migrations.RemoveField(
+            model_name='nomination',
+            name='by',
+        ),
+        migrations.RemoveField(
+            model_name='nomination',
+            name='in_agreement',
+        ),
+        migrations.RemoveField(
+            model_name='nomination',
+            name='in_disagreement',
+        ),
+        migrations.RemoveField(
+            model_name='nomination',
+            name='in_notsure',
+        ),
+        migrations.AlterField(
+            model_name='remark',
+            name='feedback',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='virtualmeetings.Feedback'),
+        ),
+        migrations.AlterField(
+            model_name='remark',
+            name='motion',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='virtualmeetings.Motion'),
+        ),
+        migrations.AlterField(
+            model_name='remark',
+            name='nomination',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='virtualmeetings.Nomination'),
+        ),
+        migrations.DeleteModel(
+            name='Feedback',
+        ),
+        migrations.DeleteModel(
+            name='Motion',
+        ),
+        migrations.DeleteModel(
+            name='Nomination',
+        ),
+        migrations.DeleteModel(
+            name='VGM',
+        ),
+    ]
+
+    operations = [
+        migrations.SeparateDatabaseAndState(state_operations=state_operations)
+    ]
diff --git a/scipost/models.py b/scipost/models.py
index a29a48f14a27c5181be06a759e02af470a485aba..119cd4ca97bba8bcb05694673499dc7ba9965a07 100644
--- a/scipost/models.py
+++ b/scipost/models.py
@@ -251,11 +251,11 @@ class UnavailabilityPeriod(models.Model):
 
 class Remark(models.Model):
     contributor = models.ForeignKey(Contributor, on_delete=models.CASCADE)
-    feedback = models.ForeignKey('scipost.Feedback', on_delete=models.CASCADE,
+    feedback = models.ForeignKey('virtualmeetings.Feedback', on_delete=models.CASCADE,
                                  blank=True, null=True)
-    nomination = models.ForeignKey('scipost.Nomination', on_delete=models.CASCADE,
+    nomination = models.ForeignKey('virtualmeetings.Nomination', on_delete=models.CASCADE,
                                    blank=True, null=True)
-    motion = models.ForeignKey('scipost.Motion', on_delete=models.CASCADE,
+    motion = models.ForeignKey('virtualmeetings.Motion', on_delete=models.CASCADE,
                                blank=True, null=True)
     submission = models.ForeignKey('submissions.Submission',
                                    on_delete=models.CASCADE,
@@ -428,271 +428,6 @@ class PrecookedEmail(models.Model):
         return self.email_subject
 
 
-#############
-# NewsItems #
-#############
-
-class NewsItem(models.Model):
-    date = models.DateField()
-    headline = models.CharField(max_length=300)
-    blurb = models.TextField()
-    followup_link = models.URLField(blank=True, null=True)
-    followup_link_text = models.CharField(max_length=300, blank=True, null=True)
-
-    def __str__(self):
-        return self.date.strftime('%Y-%m-%d') + ', ' + self.headline
-
-    def descriptor_full(self):
-        """ For News page. """
-        descriptor = ('<div class="flex-greybox640">'
-                      '<h3 class="NewsHeadline">{{ headline }}</h3>'
-                      '<p>{{ date }}</p>'
-                      '<p>{{ blurb }}</p>'
-                      )
-        context = Context({'headline': self.headline,
-                           'date': self.date.strftime('%Y-%m-%d'),
-                           'blurb': self.blurb, })
-        if self.followup_link:
-            descriptor += '<p><a href="{{ followup_link }}">{{ followup_link_text }}</a></p>'
-            context['followup_link'] = self.followup_link
-            context['followup_link_text'] = self.followup_link_text
-        descriptor += '</div>'
-        template = Template(descriptor)
-        return template.render(context)
-
-    def descriptor_small(self):
-        """ For index page. """
-        descriptor = ('<h3 class="NewsHeadline">{{ headline }}</h3>'
-                      '<div class="p-2">'
-                      '<p>{{ date }}</p>'
-                      '<p>{{ blurb }}</p>'
-                      )
-        context = Context({'headline': self.headline,
-                           'date': self.date.strftime('%Y-%m-%d'),
-                           'blurb': self.blurb, })
-        if self.followup_link:
-            descriptor += '<p><a href="{{ followup_link }}">{{ followup_link_text }}</a></p>'
-            context['followup_link'] = self.followup_link
-            context['followup_link_text'] = self.followup_link_text
-        descriptor += '</div>'
-        template = Template(descriptor)
-        return template.render(context)
-
-
-#####################################
-# Virtual General Meetings, Motions #
-#####################################
-
-class VGM(models.Model):
-    """
-    Each year, a Virtual General Meeting is held during which operations at
-    SciPost are discussed. A VGM can be attended by Administrators,
-    Advisory Board members and Editorial Fellows.
-    """
-    start_date = models.DateField()
-    end_date = models.DateField()
-    information = models.TextField(default='')
-
-    def __str__(self):
-        return 'From %s to %s' % (self.start_date.strftime('%Y-%m-%d'),
-                                  self.end_date.strftime('%Y-%m-%d'))
-
-
-class Feedback(models.Model):
-    """
-    Feedback, suggestion or criticism on any aspect of SciPost.
-    """
-    VGM = models.ForeignKey(VGM, blank=True, null=True)
-    by = models.ForeignKey(Contributor)
-    date = models.DateField()
-    feedback = models.TextField()
-
-    def __str__(self):
-        return '%s: %s' % (self.by, self.feedback[:50])
-
-    def as_li(self):
-        html = ('<div class="Feedback">'
-                '<h3><em>by {{ by }}</em></h3>'
-                '<p>{{ feedback|linebreaks }}</p>'
-                '</div>')
-        context = Context({
-            'feedback': self.feedback,
-            'by': '%s %s' % (self.by.user.first_name,
-                             self.by.user.last_name)})
-        template = Template(html)
-        return template.render(context)
-
-
-class Nomination(models.Model):
-    """
-    Nomination to an Editorial Fellowship.
-    """
-    VGM = models.ForeignKey(VGM, blank=True, null=True)
-    by = models.ForeignKey(Contributor)
-    date = models.DateField()
-    first_name = models.CharField(max_length=30, default='')
-    last_name = models.CharField(max_length=30, default='')
-    discipline = models.CharField(max_length=20, choices=SCIPOST_DISCIPLINES,
-                                  default='physics', verbose_name='Main discipline')
-    expertises = ChoiceArrayField(
-        models.CharField(max_length=10, choices=SCIPOST_SUBJECT_AREAS),
-        blank=True, null=True)
-    webpage = models.URLField(default='')
-    nr_A = models.PositiveIntegerField(default=0)
-    in_agreement = models.ManyToManyField(Contributor,
-                                          related_name='in_agreement_with_nomination', blank=True)
-    nr_N = models.PositiveIntegerField(default=0)
-    in_notsure = models.ManyToManyField(Contributor,
-                                        related_name='in_notsure_with_nomination', blank=True)
-    nr_D = models.PositiveIntegerField(default=0)
-    in_disagreement = models.ManyToManyField(Contributor,
-                                             related_name='in_disagreement_with_nomination',
-                                             blank=True)
-    voting_deadline = models.DateTimeField('voting deadline', default=timezone.now)
-    accepted = models.NullBooleanField()
-
-    def __str__(self):
-        return '%s %s (nominated by %s)' % (self.first_name,
-                                            self.last_name,
-                                            self.by)
-
-    def as_li(self):
-        html = ('<div class="Nomination" id="nomination_id{{ nomination_id }}" '
-                'style="background-color: #eeeeee;">'
-                '<div class="row">'
-                '<div class="col-4">'
-                '<h3><em> {{ name }}</em></h3>'
-                '<p>Nominated by {{ proposer }}</p>'
-                '</div>'
-                '<div class="col-4">'
-                '<p><a href="{{ webpage }}">Webpage</a></p>'
-                '<p>Discipline: {{ discipline }}</p></div>'
-                '<div class="col-4"><p>expertise:<ul>')
-        for exp in self.expertises:
-            html += '<li>%s</li>' % subject_areas_dict[exp]
-        html += '</ul></div></div></div>'
-        context = Context({
-            'nomination_id': self.id,
-            'proposer': '%s %s' % (self.by.user.first_name,
-                                   self.by.user.last_name),
-            'name': self.first_name + ' ' + self.last_name,
-            'discipline': disciplines_dict[self.discipline],
-            'webpage': self.webpage,
-        })
-        template = Template(html)
-        return template.render(context)
-
-    def votes_as_ul(self):
-        template = Template('''
-        <ul class="opinionsDisplay">
-        <li style="background-color: #000099">Agree {{ nr_A }}</li>
-        <li style="background-color: #555555">Abstain {{ nr_N }}</li>
-        <li style="background-color: #990000">Disagree {{ nr_D }}</li>
-        </ul>
-        ''')
-        context = Context({'nr_A': self.nr_A, 'nr_N': self.nr_N, 'nr_D': self.nr_D})
-        return template.render(context)
-
-    def update_votes(self, contributor_id, vote):
-        contributor = get_object_or_404(Contributor, pk=contributor_id)
-        self.in_agreement.remove(contributor)
-        self.in_notsure.remove(contributor)
-        self.in_disagreement.remove(contributor)
-        if vote == 'A':
-            self.in_agreement.add(contributor)
-        elif vote == 'N':
-            self.in_notsure.add(contributor)
-        elif vote == 'D':
-            self.in_disagreement.add(contributor)
-        self.nr_A = self.in_agreement.count()
-        self.nr_N = self.in_notsure.count()
-        self.nr_D = self.in_disagreement.count()
-        self.save()
-
-
-MOTION_CATEGORIES = (
-    ('ByLawAmend', 'Amendments to by-laws'),
-    ('Workflow', 'Editorial workflow improvements'),
-    ('General', 'General'),
-)
-motion_categories_dict = dict(MOTION_CATEGORIES)
-
-
-class Motion(models.Model):
-    """
-    Motion instances are put forward to the Advisory Board and Editorial College
-    and detail suggested changes to rules, procedures etc.
-    They are meant to be voted on at the annual VGM.
-    """
-    category = models.CharField(max_length=10, choices=MOTION_CATEGORIES,
-                                default='General')
-    VGM = models.ForeignKey(VGM, blank=True, null=True)
-    background = models.TextField()
-    motion = models.TextField()
-    put_forward_by = models.ForeignKey(Contributor)
-    date = models.DateField()
-    nr_A = models.PositiveIntegerField(default=0)
-    in_agreement = models.ManyToManyField(Contributor,
-                                          related_name='in_agreement_with_motion', blank=True)
-    nr_N = models.PositiveIntegerField(default=0)
-    in_notsure = models.ManyToManyField(Contributor,
-                                        related_name='in_notsure_with_motion', blank=True)
-    nr_D = models.PositiveIntegerField(default=0)
-    in_disagreement = models.ManyToManyField(Contributor,
-                                             related_name='in_disagreement_with_motion',
-                                             blank=True)
-    voting_deadline = models.DateTimeField('voting deadline', default=timezone.now)
-    accepted = models.NullBooleanField()
-
-    def __str__(self):
-        return self.motion[:32]
-
-    def as_li(self):
-        html = ('<div class="Motion" id="motion_id{{ motion_id }}">'
-                '<h3><em>Motion {{ motion_id }}, put forward by {{ proposer }}</em></h3>'
-                '<h3>Background:</h3><p>{{ background|linebreaks }}</p>'
-                '<h3>Motion:</h3>'
-                '<div class="flex-container"><div class="flex-greybox">'
-                '<p style="background-color: #eeeeee;">{{ motion|linebreaks }}</p>'
-                '</div></div>'
-                '</div>')
-        context = Context({
-            'motion_id': self.id,
-            'proposer': '%s %s' % (self.put_forward_by.user.first_name,
-                                   self.put_forward_by.user.last_name),
-            'background': self.background,
-            'motion': self.motion, })
-        template = Template(html)
-        return template.render(context)
-
-    def votes_as_ul(self):
-        template = Template('''
-        <ul class="opinionsDisplay">
-        <li style="background-color: #000099">Agree {{ nr_A }}</li>
-        <li style="background-color: #555555">Abstain {{ nr_N }}</li>
-        <li style="background-color: #990000">Disagree {{ nr_D }}</li>
-        </ul>
-        ''')
-        context = Context({'nr_A': self.nr_A, 'nr_N': self.nr_N, 'nr_D': self.nr_D})
-        return template.render(context)
-
-    def update_votes(self, contributor_id, vote):
-        contributor = get_object_or_404(Contributor, pk=contributor_id)
-        self.in_agreement.remove(contributor)
-        self.in_notsure.remove(contributor)
-        self.in_disagreement.remove(contributor)
-        if vote == 'A':
-            self.in_agreement.add(contributor)
-        elif vote == 'N':
-            self.in_notsure.add(contributor)
-        elif vote == 'D':
-            self.in_disagreement.add(contributor)
-        self.nr_A = self.in_agreement.count()
-        self.nr_N = self.in_notsure.count()
-        self.nr_D = self.in_disagreement.count()
-        self.save()
-
-
 #########
 # Lists #
 #########
diff --git a/scipost/templates/scipost/about.html b/scipost/templates/scipost/about.html
index 110047ecb983230817065416eb8de8739ca60712..03d7103478b3c093637a4c33bcfb65cda022698a 100644
--- a/scipost/templates/scipost/about.html
+++ b/scipost/templates/scipost/about.html
@@ -154,26 +154,34 @@
 	<li>Prof. <a href="https://www.uni-tuebingen.de/en/faculties/faculty-of-science/departments/physics/institutes/institute-for-theoretical-physics/research-groups/andergassen-group.html">Sabine Andergassen</a><br/>(Tübingen)</li>
 	<li>Prof. <a href="http://www.physik.uni-wuerzburg.de/~assaad/">Fakher Assaad</a><br/>(Würzbrug)</li>
 	<li>Dr <a href="http://www.attaccalite.com">Claudio Attaccalite</a><br/>(Marseille)</li>
+	<li>Prof. <a href="https://denis114.wordpress.com">Denis Bartolo</a><br/>(ENS Lyon)</li>
 	<li>Prof. <a href="http://www.physik.unizh.ch/~lbaudis/index.html">Laura Baudis</a><br/>(Zurich)</li>
 	<li>Prof. <a href="http://www.lorentz.leidenuniv.nl/beenakker/">Carlo Beenakker</a><br/>(Leiden)</li>
+	<li>Prof. <a href="https://www.coulomb.univ-montp2.fr/perso/ludovic.berthier/">Ludovic Berthier</a><br/>(Montpellier)</li>
 	<li>Prof. <a href="http://ipht.cea.fr/Pisp/giulio.biroli/index_en.php">Giulio Biroli</a><br/>(CEA Saclay)</li>
 	<li>Prof. <a href="http://www.en.physik.uni-muenchen.de/personen/professoren/bloch/index.html">Immanuel Bloch</a><br/>(LMU Munich)</li>
 	<li>Prof. <a href="https://staff.fnwi.uva.nl/j.deboer/">Jan de Boer</a><br/>(U. van Amsterdam)</li>
 	<li>Prof. <a href="http://www.uva.nl/en/about-the-uva/organisation/staff-members/content/b/o/d.bonn/d.bonn.html">Daniel Bonn</a><br/>(U. van Amsterdam)</li>
 	<li>Prof. <a href="http://www.statphys.sissa.it/wordpress/?page_id=1731">Pasquale Calabrese</a><br/>(SISSA)</li>
+	<li>Prof. <a href="http://personalpages.to.infn.it/~caselle/index_en.html">Michele Caselle</a><br/>(Torino)</li>
 	<li>Prof. <a href="http://www.saha.ac.in/cmp/bikask.chakrabarti/bikas.html">Bikas Chakrabarti</a><br/>(Kolkata)</li>
 	<li>Prof. <a href="http://www.tcm.phy.cam.ac.uk/~nrc25/">Nigel Cooper</a><br/>(Cambridge)</li>
       </ul>
     </div>
     <div class="flex-whitebox">
       <ul>
+	<li>Prof. <a href="http://physics.cornell.edu/csaba-csaki">Csaba Csaki</a><br/>(Cornell)</li>
 	<li>Prof. <a href="http://theory.tifr.res.in/~kedar/">Kedar Damle</a><br/>(TIFR Mumbai)</li>
 	<li>Prof. <a href="http://researchers.uq.edu.au/researcher/1134">Matthew Davis</a><br/>(U. of Queensland)</li>
 	<li>Prof. <a href="http://www-thphys.physics.ox.ac.uk/people/FabianEssler/">Fabian Essler</a><br/>(U. of Oxford)</li>
+	<li>Prof. <a href="http://www.pd.infn.it/~feruglio/">Ferruccio Feruglio</a><br/>(Padova, INFN)</li>
 	<li>Prof. <a href="http://www.ms.unimelb.edu.au/~jdgier@unimelb/">Jan de Gier</a><br/>(U. of Melbourne)</li>
 	<li>Prof. <a href="http://www.desy.de/about_desy/leading_scientists/beate_heinemann/index_eng.html">Beate Heinemann</a><br/>(DESY; Freiburg)</li>
 	<li>Prof. <a href="http://katzgraber.org">Helmut Katzgraber</a><br/>(Texas A&amp;M)</li>
+	<li>Prof. <a href="https://web.physik.rwth-aachen.de/~mkraemer/">Michael Kr&auml;mer</a><br/>(RWTH Aachen)</li>
 	<li>Prof. <a href="https://www.pmmh.espci.fr/~jorge/">Jorge Kurchan</a><br/>(<a href="https://www.pmmh.espci.fr/?-Home-">PMMH</a> Paris, CNRS)</li>
+	<li>Prof. <a href="https://vivo.brown.edu/display/glandsbe">Greg Landsberg</a><br/>(Brown Univ.)</li>
+	<li>Prof. <a href="https://www.mpg.de/6812374/chem_physik_fester_stoffe_mackenzie">Andrew P. MacKenzie</a><br/>(MPICPS Dresden, St-Andrews)</li>
 	<li>Prof. <a href="http://www.ens-lyon.fr/PHYSIQUE/presentation/annuaire/maillet-jean-michel">Jean Michel Maillet</a><br/>(ENS Lyon)</li>
 	<li>Prof. <a href="https://www.mpg.de/343435/physik_komplexer_systeme_wissM28">Roderich Moessner</a><br/>(MPIPKS Dresden)</li>
 	<li>Prof. <a href="https://www.uibk.ac.at/exphys/ultracold/people/christoph.naegerl/">Hanns-Christoph N&auml;gerl</a><br/>(Innsbruck)</li>
@@ -184,17 +192,21 @@
       <ul>
 	<li>Prof. <a href="https://staff.fnwi.uva.nl/b.nienhuis/">Bernard Nienhuis</a><br/>(U. van Amsterdam)</li>
 	<!--<li>Prof. <a href="http://www.kip.uni-heidelberg.de/people/index.php?num=552">Markus Oberthaler</a><br/>(U. Heidelberg)</li>-->
+	<li>Prof. <a href="http://www.lpthe.jussieu.fr/~pioline/">Boris Pioline</a><br/>(LPTHE Jussieu)</li>
 	<li>Prof. <a href="https://www.uu.nl/staff/RHHGvanRoij/0">René van Roij</a><br/>(Utrecht)</li>
 	<li>Prof. <a href="http://www.thp.uni-koeln.de/rosch">Achim Rosch</a><br/>(U. of Cologne)</li>
 	<li>Prof. <a href="http://saleur.sandvox.net">Hubert Saleur</a><br/>(CEA Saclay/USC)</li>
 	<li>Prof. <a href="http://www.phy.ohiou.edu/people/faculty/sandler.html">Nancy Sandler</a><br/>(Ohio)</li>
+	<li>Dr. <a href="http://www.sussex.ac.uk/profiles/320359">Veronica Sanz</a><br/>(Sussex)</li>
 	<li>Prof. <a href="http://www-thphys.physics.ox.ac.uk/people/SubirSarkar/">Subir Sarkar</a><br/>(Oxford; Niels Bohr Institute)</li>
 	<li>Prof. <a href="https://staff.fnwi.uva.nl/c.j.m.schoutens/">Kareljan Schoutens</a><br/>(U. van Amsterdam)</li>
+	<li>Dr <a href="http://www.phys.ens.fr/~guilhem/">Guilhem Semerjian</a><br/>(ENS Paris)</li>
 	<li>Prof. <a href="http://www-thphys.physics.ox.ac.uk/people/SteveSimon/">Steve Simon</a><br/>(U. of Oxford)</li>
 	<li>Prof. <a href="http://bec.science.unitn.it/infm-bec/people/stringari.html">Sandro Stringari</a><br/>(Trento)</li>
 	<li>Prof. <a href="http://www.damtp.cam.ac.uk/user/tong/">David Tong</a><br/>(Cambridge)</li>
 	<li>Prof. <a href="http://www.physique.usherbrooke.ca/pages/en/node/3412">Andr&eacute;-Marie Tremblay</a><br/>(Sherbrooke)</li>
 	<li>Prof. <a href="http://trivediresearch.org.ohio-state.edu">Nandini Trivedi</a><br/>(Ohio State U.)</li>
+	<li>Prof. <a href="http://vergassolalab.ucsd.edu">Massimo Vergassola</a><br/>(UC Sand Diego)</li>
       </ul>
     </div>
 
diff --git a/scipost/templates/scipost/index.html b/scipost/templates/scipost/index.html
index 8cf87d0cdf9e1ee8e18750bca8be04c57df437d2..13a32d48dfa43b1cd37fb8e0d6af8bb5c5fa36cc 100644
--- a/scipost/templates/scipost/index.html
+++ b/scipost/templates/scipost/index.html
@@ -9,7 +9,7 @@
         {% if latest_newsitems %}
         <div class="col-md-6 {% if user.is_authenticated %}col-lg-4{% else %}col-lg-3{% endif %}">
             <div class="panel">
-                <h1><a href="{% url 'scipost:news' %}">News</a><a style="float: right;" href="{% url 'scipost:feeds' %}"><img src="{% static 'scipost/images/feed-icon-14x14.png' %}" alt="Feed logo" width="14"></a></h1>
+                <h1><a href="{% url 'news:news' %}">News</a><a style="float: right;" href="{% url 'scipost:feeds' %}"><img src="{% static 'scipost/images/feed-icon-14x14.png' %}" alt="Feed logo" width="14"></a></h1>
                 <p>Latest news and announcements.</p>
                 {# <hr class="hr6"/>#}
                 <ul class="NewsItemsList">
diff --git a/scipost/templates/scipost/navbar.html b/scipost/templates/scipost/navbar.html
index 04cce9fedff90383eb8df8bf20fd99d4fdc1d979..29161549ed69fbbefbb3dd886868c413b44f1f65 100644
--- a/scipost/templates/scipost/navbar.html
+++ b/scipost/templates/scipost/navbar.html
@@ -38,9 +38,8 @@
       {% endif %}
 
     </ul>
-    <form action="{% url 'scipost:search' %}" method="post" class="form-inline">
-        {% csrf_token %}
-        {{ search_form }}
+    <form action="{% url 'scipost:search' %}" method="get" class="form-inline">
+        <input class="form-control mr-0 mb-2 mr-lg-2 mb-lg-0" id="id_q" maxlength="100" name="q" type="text" required="">
       <button class="btn btn-primary" type="submit">Search</button>
     </form>
   </div>
diff --git a/scipost/templates/scipost/personal_page.html b/scipost/templates/scipost/personal_page.html
index 151c11eb9e901a98ddaf2ab62aa65d523e5e31aa..2506e6f5f49f8fddd69695fc4e08fee6b2a39079 100644
--- a/scipost/templates/scipost/personal_page.html
+++ b/scipost/templates/scipost/personal_page.html
@@ -87,7 +87,7 @@
 
 {% block content %}
 
-{% if not request.user|is_in_group:'Registered Contributors' %}
+{% if 'Registered Contributors' not in user_groups %}
 <div class="row">
     <div class="col-12">
       <hr class="hr12">
@@ -110,7 +110,7 @@
     <div class="col-12">
         <ul class="personalTabMenu">
             <li><a class="TabItem" id="AccountTab">Account</a></li>
-            {% if request.user|is_in_group:'Editorial Administrators' or request.user|is_in_group:'Advisory Board' or request.user|is_in_group:'Editorial College' or request.user|is_in_group:'Vetting Editors' or request.user|is_in_group:'Ambassadors' or request.user|is_in_group:'Junior Ambassadors' %}
+            {% if 'Editorial Administrators' not in user_groups or 'Advisory Board' not in user_groups or 'Editorial College' not in user_groups or 'Vetting Editors' not in user_groups or 'Ambassadors' not in user_groups or 'Junior Ambassadors' not in user_groups %}
                 <li><a class="TabItem" id="EdActionTab">Editorial Actions</a></li>
             {% endif %}
             <li><a class="TabItem" id="RefereeingTab">Refereeing</a></li>
@@ -119,13 +119,13 @@
             <li><a class="TabItem" id="ThesesTab">Theses</a></li>
             <li><a class="TabItem" id="CommentsTab">Comments</a></li>
             <li><a class="TabItem" id="AuthorRepliesTab">Author Replies</a></li>
-            {% if request.user|is_in_group:'Testers' %}
+            {% if 'Testers' in user_groups %}
                 <li><a class="TabItem" id="ListsTab">Lists</a></li>
             {% endif %}
-            {% if request.user|is_in_group:'Testers' %}
+            {% if 'Testers' in user_groups %}
                 <li><a class="TabItem" id="TeamsTab">Teams</a></li>
             {% endif %}
-            {% if request.user|is_in_group:'Testers' %}
+            {% if 'Testers' in user_groups %}
                 <li><a class="TabItem" id="GraphsTab">Graphs</a></li>
             {% endif %}
         </ul>
@@ -160,31 +160,31 @@
             {% endif %}
         </div>
         <div class="col-md-6">
-            {% if request.user|is_in_group:'SciPost Administrators' %}
+            {% if 'SciPost Administrators' in user_groups %}
                 <h3>You are a SciPost Administrator.</h3>
             {% endif %}
-            {% if request.user|is_in_group:'Editorial Administrators' %}
+            {% if 'Editorial Administrators' in user_groups %}
                 <h3>You are a SciPost Editorial Administrator.</h3>
             {% endif %}
-            {% if request.user|is_in_group:'Advisory Board' %}
+            {% if 'Advisory Board' in user_groups %}
                 <h3>You are a member of the Advisory Board.</h3>
             {% endif %}
-            {% if request.user|is_in_group:'Editorial College' %}
+            {% if 'Editorial College' in user_groups %}
                 <h3>You are a member of the Editorial College.</h3>
             {% endif %}
-            {% if request.user|is_in_group:'Vetting Editors' %}
+            {% if 'Vetting Editors' in user_groups %}
                 <h3>You are a SciPost Vetting Editor.</h3>
             {% endif %}
-            {% if request.user|is_in_group:'Registered Contributors' %}
+            {% if 'Registered Contributors' in user_groups %}
                 <h3>You are a Registered Contributor.</h3>
             {% endif %}
-            {% if request.user|is_in_group:'Testers' %}
+            {% if 'Testers' in user_groups %}
                 <h3>You are a SciPost Tester.</h3>
             {% endif %}
-            {% if request.user|is_in_group:'Ambassadors' %}
+            {% if 'Ambassadors' in user_groups %}
                 <h3>You are a SciPost Ambassador.</h3>
             {% endif %}
-            {% if request.user|is_in_group:'Junior Ambassadors' %}
+            {% if 'Junior Ambassadors' in user_groups %}
                 <h3>You are a SciPost Junior Ambassador.</h3>
             {% endif %}
 
@@ -239,7 +239,7 @@
 </div>
 
 
-{% if request.user|is_in_group:'SciPost Administrators' or request.user|is_in_group:'Editorial Administrators' or request.user|is_in_group:'Editorial College' or request.user|is_in_group:'Vetting Editors' or request.user|is_in_group:'Ambassadors' or request.user|is_in_group:'Junior Ambassadors' %}
+{% if 'SciPost Administrators' in user_groups or 'Editorial Administrators' in user_groups or 'Editorial College' in user_groups or 'Vetting Editors' in user_groups or 'Ambassadors' in user_groups or 'Junior Ambassadors' in user_groups %}
 <div class="TabSection" id="EdActions">
 
     <div class="row">
@@ -251,7 +251,7 @@
     </div>
 
     <div class="row">
-        {% if request.user|is_in_group:'SciPost Administrators' or request.user|is_in_group:'Advisory Board' or request.user|is_in_group:'Ambassadors' or request.user|is_in_group:'Junior Ambassadors' %}
+        {% if 'SciPost Administrators' in user_groups or 'Advisory Board' in user_groups or 'Ambassadors' in user_groups or 'Junior Ambassadors' in user_groups %}
         <div class="col-md-4">
             <h3>Registration actions</h3>
             <ul>
@@ -315,7 +315,7 @@
             {% endif %}
         </div>
 
-        {% if request.user|is_in_group:'Editorial Administrators' or request.user|is_in_group:'Editorial College' %}
+        {% if 'Editorial Administrators' in user_groups or 'Editorial College' in user_groups %}
         <div class="col-md-4">
             <h3>Info</h3>
             <ul>
@@ -380,7 +380,7 @@
             {% for task in pending_ref_tasks %}
                 <li>{{ task.submission }}, due {{ task.submission.reporting_deadline }}. &nbsp;
                     <a href="{% url 'submissions:submit_report' arxiv_identifier_w_vn_nr=task.submission.arxiv_identifier_w_vn_nr %}">Submit your Report</a> &nbsp;
-                    <a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=task.submission.arxiv_identifier_w_vn_nr comtype='RtoE' referee_id=request.user.contributor.id %}">Write to the Editor-in-charge</a>.
+                    <a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=task.submission.arxiv_identifier_w_vn_nr comtype='RtoE' referee_id=contributor.user.contributor.id %}">Write to the Editor-in-charge</a>.
                 </li>
             {% endfor %}
             </ul>
@@ -411,7 +411,7 @@
             <ul class="mt-3">
                 {% for sub in own_submissions %}
                     {{ sub.header_as_li_for_authors }}
-                    {% if request.user.contributor == sub.submitted_by %}
+                    {% if contributor.user.contributor == sub.submitted_by %}
                         <p><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=sub.arxiv_identifier_w_vn_nr comtype='AtoE' %}">Write to the Editor-in-charge</a>.</p>
                     {% endif %}
                 {% endfor %}
diff --git a/scipost/templates/scipost/search.html b/scipost/templates/scipost/search.html
index 050dbafd542fae2959975c7f27117d6c7cece837..911e4686ed965a1f8a4ebb054ac3e25b8a0adcaa 100644
--- a/scipost/templates/scipost/search.html
+++ b/scipost/templates/scipost/search.html
@@ -2,125 +2,171 @@
 
 {% block pagetitle %}: list{% endblock pagetitle %}
 
-{% block headsup %}
-
-{% endblock headsup %}
-
-{% block bodysup %}
-
-
-<section>
-  <h1>Search results</h1>
-
-  {% if publication_search_list or commentary_search_list or submission_search_list or thesislink_search_list or comment_search_link %}
-  {% else %}
-  <p>Your search query did not return any result.</p>
-  {% endif %}
-
-  {% if publication_search_list %}
-  <br />
-  <hr class="hr12">
-  <h3>Publications:</h3>
-
-  <ul>
-    {% for publication in publication_search_list %}
-    {{ publication.header_as_li }}
-    {% endfor %}
-  </ul>
-
-  <div class="pagination">
-    <span class="step-links">
-      {% if publication_search_list.has_previous %}
-      <a href="?publication_search_list_page={{ publication_search_list.previous_page_number }}">previous</a>
-      {% endif %}
-      <span class="current">
-	Page {{ publication_search_list.number }} of {{ publication_search_list.paginator.num_pages }}.
-      </span>
-      {% if publication_search_list.has_next %}
-      <a href="?publication_search_list_page={{ publication_search_list.next_page_number }}">next</a>
-      {% endif %}
-    </span>
-  </div>
-
-  {% endif %}
-
-
-  {% if commentary_search_list %}
-  <br />
-  <hr class="hr12">
-  <h3>Commentaries:</h3>
-
-  <ul>
-    {% for commentary in commentary_search_list %}
-    {{ commentary.header_as_li }}
-    {% endfor %}
-  </ul>
-
-  <div class="pagination">
-    <span class="step-links">
-      {% if commentary_search_list.has_previous %}
-      <a href="?commentary_search_list_page={{ commentary_search_list.previous_page_number }}">previous</a>
-      {% endif %}
-      <span class="current">
-	Page {{ commentary_search_list.number }} of {{ commentary_search_list.paginator.num_pages }}.
-      </span>
-      {% if commentary_search_list.has_next %}
-      <a href="?commentary_search_list_page={{ commentary_search_list.next_page_number }}">next</a>
-      {% endif %}
-    </span>
-  </div>
-
-  {% endif %}
-
-
-  {% if submission_search_list %}
-  <br />
-  <hr class="hr12">
-  <h3>Submissions:</h3>
-  <ul>
-    {% for submission in submission_search_list %}
-    {{ submission.header_as_li }}
-    {% endfor %}
-  </ul>
-
-  <div class="pagination">
-    <span class="step-links">
-      {% if submission_search_list.has_previous %}
-      <a href="?submission_search_list_page={{ submission_search_list.previous_page_number }}">previous</a>
-      {% endif %}
-      <span class="current">
-	Page {{ submission_search_list.number }} of {{ submission_search_list.paginator.num_pages }}
-      </span>
-      {% if submission_search_list.has_next %}
-      <a href="?submission_search_list_page={{ submission_search_list.next_page_number }}">next</a>
-      {% endif %}
-    </span>
-  </div>
-
-  {% endif %}
-
-  {% if thesislink_search_list %}
-  <br />
-  <hr class="hr12">
-  <h3>Theses:</h3>
-  <ul>
-    {% for thesislink in thesislink_search_list %}
-        {% include 'theses/_thesislink_header_as_li.html' with thesislink=thesislink %}
-    {% endfor %}
-  </ul>
-  {% endif %}
-
-  {% if comment_search_list %}
-  <br />
-  <hr class="hr12">
-  <h3>Comments:</h3>
-  <ul>
-    {% for comment in comment_search_list %}
-    {{ comment.header_as_li }}
-    {% endfor %}
-  </ul>
-  {% endif %}
-
-</section>
-
-{% endblock bodysup %}
+{% block content %}
+
+<div class="row">
+    <div class="col-12">
+        <h1>Search results{% if search_term %}: <small><i>{{ search_term }}</i></small>{% endif %}</h1>
+        {% if not publication_search_list and not commentary_search_list and not submission_search_list and not thesislink_search_list and not comment_search_link and not comment_search_list %}
+            <p>Your search query did not return any result.</p>
+        {% endif %}
+    </div>
+</div>
+
+{% if publication_search_list %}
+<hr>
+<div class="row">
+    <div class="col-12">
+        <div class="panel">
+            <h2>Publications</h2>
+        </div>
+    </div>
+</div>
+
+<div class="row">
+    <div class="col-12">
+        {% for publication in publication_search_list %}
+            {{ publication.header_as_li }}
+        {% endfor %}
+    </div>
+</div>
+
+<div class="row">
+    <div class="col-12">
+          <div class="pagination">
+            <span class="step-links">
+              {% if publication_search_list.has_previous %}
+              <a href="?publication_search_list_page={{ publication_search_list.previous_page_number }}">previous</a>
+              {% endif %}
+              <span class="current">
+        	Page {{ publication_search_list.number }} of {{ publication_search_list.paginator.num_pages }}.
+              </span>
+              {% if publication_search_list.has_next %}
+              <a href="?publication_search_list_page={{ publication_search_list.next_page_number }}">next</a>
+              {% endif %}
+            </span>
+          </div>
+
+    </div>
+</div>
+{% endif %}
+
+
+{% if commentary_search_list %}
+<hr>
+<div class="row">
+    <div class="col-12">
+        <div class="panel">
+            <h2>Commentaries</h2>
+        </div>
+    </div>
+</div>
+<div class="row">
+    <div class="col-12">
+        <ul>
+            {% for commentary in commentary_search_list %}
+                {{ commentary.header_as_li }}
+            {% endfor %}
+        </ul>
+    </div>
+</div>
+
+<div class="row">
+    <div class="col-12">
+          <div class="pagination">
+            <span class="step-links">
+              {% if commentary_search_list.has_previous %}
+              <a href="?commentary_search_list_page={{ commentary_search_list.previous_page_number }}">previous</a>
+              {% endif %}
+              <span class="current">
+        	Page {{ commentary_search_list.number }} of {{ commentary_search_list.paginator.num_pages }}.
+              </span>
+              {% if commentary_search_list.has_next %}
+              <a href="?commentary_search_list_page={{ commentary_search_list.next_page_number }}">next</a>
+              {% endif %}
+            </span>
+          </div>
+
+    </div>
+</div>
+{% endif %}
+
+
+{% if submission_search_list %}
+<hr>
+<div class="row">
+    <div class="col-12">
+        <div class="panel">
+            <h2>Submissions</h2>
+        </div>
+    </div>
+</div>
+<div class="row">
+    <div class="col-12">
+        <ul>
+            {% for submission in submission_search_list %}
+            {{ submission.header_as_li }}
+            {% endfor %}
+        </ul>
+    </div>
+</div>
+
+<div class="row">
+    <div class="col-12">
+      <div class="pagination">
+        <span class="step-links">
+          {% if submission_search_list.has_previous %}
+          <a href="?submission_search_list_page={{ submission_search_list.previous_page_number }}">previous</a>
+          {% endif %}
+          <span class="current">
+    	Page {{ submission_search_list.number }} of {{ submission_search_list.paginator.num_pages }}
+          </span>
+          {% if submission_search_list.has_next %}
+          <a href="?submission_search_list_page={{ submission_search_list.next_page_number }}">next</a>
+          {% endif %}
+        </span>
+      </div>
+    </div>
+</div>
+{% endif %}
+
+{% if thesislink_search_list %}
+<hr>
+<div class="row">
+    <div class="col-12">
+        <div class="panel">
+            <h2>Theses</h2>
+        </div>
+    </div>
+</div>
+<div class="row">
+    <div class="col-12">
+          <ul>
+            {% for thesislink in thesislink_search_list %}
+                {% include 'theses/_thesislink_header_as_li.html' with thesislink=thesislink %}
+            {% endfor %}
+          </ul>
+          {% endif %}
+
+          {% if comment_search_list %}
+          <div class="row">
+              <div class="col-12">
+                  <div class="panel">
+                      <h2>Comments</h2>
+                  </div>
+              </div>
+          </div>
+          <div class="row">
+              <div class="col-12">
+                  <ul>
+                    {% for comment in comment_search_list %}
+                        {{ comment.header_as_li }}
+                    {% endfor %}
+                  </ul>
+              </div>
+          </div>
+          {% endif %}
+    </div>
+</div>
+
+{% endblock content %}
diff --git a/scipost/templatetags/scipost_extras.py b/scipost/templatetags/scipost_extras.py
index 3a34f87e76bc8559d8943d360f43469a14860f95..40863a5f2d987024c06caeb3c480f2477293a174 100644
--- a/scipost/templatetags/scipost_extras.py
+++ b/scipost/templatetags/scipost_extras.py
@@ -21,8 +21,7 @@ def sort_by(queryset, order):
 
 @register.filter(name='is_in_group')
 def is_in_group(user, group_name):
-    group = Group.objects.get(name=group_name)
-    return True if group in user.groups.all() else False
+    return user.groups.filter(name=group_name).exists()
 
 
 @register.filter(name='associated_contributors')
diff --git a/scipost/urls.py b/scipost/urls.py
index e3b8c573147bbafd6e2541cce29bbeee3d68279e..1ed0f1b6a55fccc4f199d49d5b767102ec62833b 100644
--- a/scipost/urls.py
+++ b/scipost/urls.py
@@ -17,7 +17,6 @@ urlpatterns = [
         name='acknowledgement'),
 
     ## Info
-    url(r'^news$', views.news, name='news'),
     url(r'^about$', TemplateView.as_view(template_name='scipost/about.html'), name='about'),
     url(r'^call$', TemplateView.as_view(template_name='scipost/call.html'), name='call'),
     url(r'^foundation$', TemplateView.as_view(template_name='scipost/foundation.html'),
diff --git a/scipost/views.py b/scipost/views.py
index 940eb79e17a271404a4146d50f13cd427e761907..295f62b52a930e54af13098bbcc530adb54e488e 100644
--- a/scipost/views.py
+++ b/scipost/views.py
@@ -27,11 +27,10 @@ from guardian.shortcuts import assign_perm
 
 from .constants import SCIPOST_SUBJECT_AREAS
 from .models import Contributor, CitationNotification, UnavailabilityPeriod,\
-                    DraftInvitation, RegistrationInvitation, NewsItem,\
+                    DraftInvitation, RegistrationInvitation, Remark,\
                     List, Team, Graph, Node, Arc,\
                     title_dict, SciPost_from_addresses_dict,\
-                    AuthorshipClaim, SupportingPartner, SPBMembershipAgreement,\
-                    VGM, Feedback, Nomination, Remark, Motion, motion_categories_dict
+                    AuthorshipClaim, SupportingPartner, SPBMembershipAgreement
 from .forms import AuthenticationForm, DraftInvitationForm, UnavailabilityPeriodForm,\
                    RegistrationForm, RegistrationInvitationForm, AuthorshipClaimForm,\
                    ModifyPersonalMessageForm, SearchForm, VetRegistrationForm, reg_ref_dict,\
@@ -48,12 +47,15 @@ from commentaries.models import Commentary
 from commentaries.forms import CommentarySearchForm
 from comments.models import Comment
 from journals.models import Publication
+from news.models import NewsItem
 from submissions.models import SUBMISSION_STATUS_PUBLICLY_UNLISTED
 from submissions.models import Submission, EditorialAssignment
 from submissions.models import RefereeInvitation, Report, EICRecommendation
 from submissions.forms import SubmissionSearchForm
 from theses.models import ThesisLink
 from theses.forms import ThesisLinkSearchForm
+from virtualmeetings.models import VGM, Feedback, Nomination, Motion
+from virtualmeetings.constants import motion_categories_dict
 
 
 ##############
@@ -151,17 +153,15 @@ def documentsSearchResults(query):
 
 def search(request):
     """ For the global search form in navbar """
-    if request.method == 'POST':
-        form = SearchForm(request.POST)
-        if form.is_valid():
-            context = documentsSearchResults(form.cleaned_data['query'])
-            request.session['query'] = form.cleaned_data['query']
-        else:
-            context = {}
+    form = SearchForm(request.GET or None)
+    context = {}
+    if form.is_valid():
+        context = documentsSearchResults(form.cleaned_data['q'])
+        request.session['query'] = form.cleaned_data['q']
+        context['search_term'] = form.cleaned_data['q']
     elif 'query' in request.session:
-            context = documentsSearchResults(request.session['query'])
-    else:
-        context = {}
+        context = documentsSearchResults(request.session['query'])
+        context['search_term'] = request.session['query']
 
     if 'publication_search_queryset' in context:
         publication_search_list_paginator = Paginator(context['publication_search_queryset'], 10)
@@ -232,12 +232,6 @@ def base(request):
     return render(request, 'scipost/base.html')
 
 
-def news(request):
-    newsitems = NewsItem.objects.all().order_by('-date')
-    context = {'newsitems': newsitems}
-    return render(request, 'scipost/news.html', context)
-
-
 def feeds(request):
     context = {'subject_areas_physics': SCIPOST_SUBJECT_AREAS[0][1]}
     return render(request, 'scipost/feeds.html', context)
@@ -941,137 +935,135 @@ def mark_unavailable_period(request):
     return redirect('scipost:personal_page')
 
 
+@login_required
 def personal_page(request):
     """
     The Personal Page is the main view for accessing user functions.
     """
-    if request.user.is_authenticated():
-        contributor = Contributor.objects.get(user=request.user)
-
-        # Compile the unavailability periods:
-        now = timezone.now()
-        unavailabilities = UnavailabilityPeriod.objects.filter(
-            contributor=contributor).exclude(end__lt=now).order_by('start')
-        unavailability_form = UnavailabilityPeriodForm()
-
-        # if an editor, count the number of actions required:
-        nr_reg_to_vet = 0
-        nr_reg_awaiting_validation = 0
-        nr_submissions_to_assign = 0
-        nr_recommendations_to_prepare_for_voting = 0
-        if is_SP_Admin(request.user):
-            intwodays = now + timezone.timedelta(days=2)
-
-            # count the number of pending registration requests
-            nr_reg_to_vet = Contributor.objects.filter(user__is_active=True, status=0).count()
-            nr_reg_awaiting_validation = Contributor.objects.filter(
-                user__is_active=False, key_expires__gte=now,
-                key_expires__lte=intwodays, status=0).count()
-            nr_submissions_to_assign = Submission.objects.filter(status__in=['unassigned']).count()
-            nr_recommendations_to_prepare_for_voting = EICRecommendation.objects.filter(
-                submission__status__in=['voting_in_preparation']).count()
-        nr_assignments_to_consider = 0
-        active_assignments = None
-        nr_reports_to_vet = 0
-        if is_MEC(request.user):
-            nr_assignments_to_consider = (EditorialAssignment.objects
-                                          .filter(to=contributor, accepted=None, deprecated=False)
+    contributor = Contributor.objects.select_related('user').get(user=request.user)
+    user_groups = contributor.user.groups.values_list('name', flat=True)
+
+    # Compile the unavailability periods:
+    now = timezone.now()
+    unavailabilities = UnavailabilityPeriod.objects.filter(
+        contributor=contributor).exclude(end__lt=now).order_by('start')
+    unavailability_form = UnavailabilityPeriodForm()
+
+    # if an editor, count the number of actions required:
+    nr_reg_to_vet = 0
+    nr_reg_awaiting_validation = 0
+    nr_submissions_to_assign = 0
+    nr_recommendations_to_prepare_for_voting = 0
+    if is_SP_Admin(contributor.user):
+        intwodays = now + timezone.timedelta(days=2)
+
+        # count the number of pending registration requests
+        nr_reg_to_vet = Contributor.objects.filter(user__is_active=True, status=0).count()
+        nr_reg_awaiting_validation = Contributor.objects.filter(
+            user__is_active=False, key_expires__gte=now,
+            key_expires__lte=intwodays, status=0).count()
+        nr_submissions_to_assign = Submission.objects.filter(status__in=['unassigned']).count()
+        nr_recommendations_to_prepare_for_voting = EICRecommendation.objects.filter(
+            submission__status__in=['voting_in_preparation']).count()
+    nr_assignments_to_consider = 0
+    active_assignments = None
+    nr_reports_to_vet = 0
+    if is_MEC(contributor.user):
+        nr_assignments_to_consider = (EditorialAssignment.objects
+                                      .filter(to=contributor, accepted=None, deprecated=False)
+                                      .count())
+        active_assignments = EditorialAssignment.objects.filter(
+            to=contributor, accepted=True, completed=False)
+        nr_reports_to_vet = Report.objects.filter(
+            status=0, submission__editor_in_charge=contributor).count()
+    nr_commentary_page_requests_to_vet = 0
+    nr_comments_to_vet = 0
+    nr_thesislink_requests_to_vet = 0
+    nr_authorship_claims_to_vet = 0
+    if is_VE(request.user):
+        nr_commentary_page_requests_to_vet = Commentary.objects.filter(vetted=False).count()
+        nr_comments_to_vet = Comment.objects.filter(status=0).count()
+        nr_thesislink_requests_to_vet = ThesisLink.objects.filter(vetted=False).count()
+        nr_authorship_claims_to_vet = AuthorshipClaim.objects.filter(status='0').count()
+    nr_ref_inv_to_consider = RefereeInvitation.objects.filter(
+        referee=contributor, accepted=None, cancelled=False).count()
+    pending_ref_tasks = RefereeInvitation.objects.filter(
+        referee=contributor, accepted=True, fulfilled=False)
+    # Verify if there exist objects authored by this contributor,
+    # whose authorship hasn't been claimed yet
+    own_submissions = (Submission.objects
+                       .filter(authors__in=[contributor], is_current=True)
+                       .order_by('-submission_date'))
+    own_commentaries = (Commentary.objects
+                        .filter(authors__in=[contributor])
+                        .order_by('-latest_activity'))
+    own_thesislinks = ThesisLink.objects.filter(author_as_cont__in=[contributor])
+    nr_submission_authorships_to_claim = (Submission.objects.filter(
+        author_list__contains=contributor.user.last_name)
+                                          .exclude(authors__in=[contributor])
+                                          .exclude(authors_claims__in=[contributor])
+                                          .exclude(authors_false_claims__in=[contributor])
                                           .count())
-            active_assignments = EditorialAssignment.objects.filter(
-                to=contributor, accepted=True, completed=False)
-            nr_reports_to_vet = Report.objects.filter(
-                status=0, submission__editor_in_charge=contributor).count()
-        nr_commentary_page_requests_to_vet = 0
-        nr_comments_to_vet = 0
-        nr_thesislink_requests_to_vet = 0
-        nr_authorship_claims_to_vet = 0
-        if is_VE(request.user):
-            nr_commentary_page_requests_to_vet = Commentary.objects.filter(vetted=False).count()
-            nr_comments_to_vet = Comment.objects.filter(status=0).count()
-            nr_thesislink_requests_to_vet = ThesisLink.objects.filter(vetted=False).count()
-            nr_authorship_claims_to_vet = AuthorshipClaim.objects.filter(status='0').count()
-        nr_ref_inv_to_consider = RefereeInvitation.objects.filter(
-            referee=contributor, accepted=None, cancelled=False).count()
-        pending_ref_tasks = RefereeInvitation.objects.filter(
-            referee=contributor, accepted=True, fulfilled=False)
-        # Verify if there exist objects authored by this contributor,
-        # whose authorship hasn't been claimed yet
-        own_submissions = (Submission.objects
-                           .filter(authors__in=[contributor], is_current=True)
-                           .order_by('-submission_date'))
-        own_commentaries = (Commentary.objects
-                            .filter(authors__in=[contributor])
-                            .order_by('-latest_activity'))
-        own_thesislinks = ThesisLink.objects.filter(author_as_cont__in=[contributor])
-        nr_submission_authorships_to_claim = (Submission.objects.filter(
-            author_list__contains=contributor.user.last_name)
-                                              .exclude(authors__in=[contributor])
-                                              .exclude(authors_claims__in=[contributor])
-                                              .exclude(authors_false_claims__in=[contributor])
-                                              .count())
-        nr_commentary_authorships_to_claim = (Commentary.objects.filter(
-            author_list__contains=contributor.user.last_name)
-                                              .exclude(authors__in=[contributor])
-                                              .exclude(authors_claims__in=[contributor])
-                                              .exclude(authors_false_claims__in=[contributor])
-                                              .count())
-        nr_thesis_authorships_to_claim = (ThesisLink.objects.filter(
-            author__contains=contributor.user.last_name)
-                                          .exclude(author_as_cont__in=[contributor])
-                                          .exclude(author_claims__in=[contributor])
-                                          .exclude(author_false_claims__in=[contributor])
+    nr_commentary_authorships_to_claim = (Commentary.objects.filter(
+        author_list__contains=contributor.user.last_name)
+                                          .exclude(authors__in=[contributor])
+                                          .exclude(authors_claims__in=[contributor])
+                                          .exclude(authors_false_claims__in=[contributor])
                                           .count())
-        own_comments = (Comment.objects
-                        .filter(author=contributor, is_author_reply=False)
-                        .order_by('-date_submitted'))
-        own_authorreplies = (Comment.objects
-                             .filter(author=contributor, is_author_reply=True)
-                             .order_by('-date_submitted'))
-        lists_owned = List.objects.filter(owner=contributor)
-        lists = List.objects.filter(teams_with_access__members__in=[contributor])
-        teams_led = Team.objects.filter(leader=contributor)
-        teams = Team.objects.filter(members__in=[contributor])
-        graphs_owned = Graph.objects.filter(owner=contributor)
-        graphs_private = Graph.objects.filter(Q(teams_with_access__leader=contributor)
-                                              | Q(teams_with_access__members__in=[contributor]))
-        appellation = title_dict[contributor.title] + ' ' + contributor.user.last_name
-        context = {
-            'contributor': contributor,
-            'appellation': appellation,
-            'unavailabilities': unavailabilities,
-            'unavailability_form': unavailability_form,
-            'nr_reg_to_vet': nr_reg_to_vet,
-            'nr_reg_awaiting_validation': nr_reg_awaiting_validation,
-            'nr_commentary_page_requests_to_vet': nr_commentary_page_requests_to_vet,
-            'nr_comments_to_vet': nr_comments_to_vet,
-            'nr_thesislink_requests_to_vet': nr_thesislink_requests_to_vet,
-            'nr_authorship_claims_to_vet': nr_authorship_claims_to_vet,
-            'nr_reports_to_vet': nr_reports_to_vet,
-            'nr_submissions_to_assign': nr_submissions_to_assign,
-            'nr_recommendations_to_prepare_for_voting': nr_recommendations_to_prepare_for_voting,
-            'nr_assignments_to_consider': nr_assignments_to_consider,
-            'active_assignments': active_assignments,
-            'nr_submission_authorships_to_claim': nr_submission_authorships_to_claim,
-            'nr_commentary_authorships_to_claim': nr_commentary_authorships_to_claim,
-            'nr_thesis_authorships_to_claim': nr_thesis_authorships_to_claim,
-            'nr_ref_inv_to_consider': nr_ref_inv_to_consider,
-            'pending_ref_tasks': pending_ref_tasks,
-            'own_submissions': own_submissions,
-            'own_commentaries': own_commentaries,
-            'own_thesislinks': own_thesislinks,
-            'own_comments': own_comments, 'own_authorreplies': own_authorreplies,
-            'lists_owned': lists_owned,
-            'lists': lists,
-            'teams_led': teams_led,
-            'teams': teams,
-            'graphs_owned': graphs_owned,
-            'graphs_private': graphs_private,
-        }
-        return render(request, 'scipost/personal_page.html', context)
-    else:
-        form = AuthenticationForm()
-        context = {'form': form}
-        return render(request, 'scipost/login.html', context)
+    nr_thesis_authorships_to_claim = (ThesisLink.objects.filter(
+        author__contains=contributor.user.last_name)
+                                      .exclude(author_as_cont__in=[contributor])
+                                      .exclude(author_claims__in=[contributor])
+                                      .exclude(author_false_claims__in=[contributor])
+                                      .count())
+    own_comments = (Comment.objects.select_related('author', 'submission')
+                    .filter(author=contributor, is_author_reply=False)
+                    .order_by('-date_submitted'))
+    own_authorreplies = (Comment.objects
+                         .filter(author=contributor, is_author_reply=True)
+                         .order_by('-date_submitted'))
+    lists_owned = List.objects.filter(owner=contributor)
+    lists = List.objects.filter(teams_with_access__members__in=[contributor])
+    teams_led = Team.objects.select_related('leader__user').filter(leader=contributor)
+    teams = Team.objects.select_related('leader__user').filter(members__in=[contributor])
+    graphs_owned = Graph.objects.filter(owner=contributor)
+    graphs_private = Graph.objects.filter(Q(teams_with_access__leader=contributor)
+                                          | Q(teams_with_access__members__in=[contributor]))
+    appellation = title_dict[contributor.title] + ' ' + contributor.user.last_name
+    context = {
+        'contributor': contributor,
+        'user_groups': user_groups,
+        'appellation': appellation,
+        'unavailabilities': unavailabilities,
+        'unavailability_form': unavailability_form,
+        'nr_reg_to_vet': nr_reg_to_vet,
+        'nr_reg_awaiting_validation': nr_reg_awaiting_validation,
+        'nr_commentary_page_requests_to_vet': nr_commentary_page_requests_to_vet,
+        'nr_comments_to_vet': nr_comments_to_vet,
+        'nr_thesislink_requests_to_vet': nr_thesislink_requests_to_vet,
+        'nr_authorship_claims_to_vet': nr_authorship_claims_to_vet,
+        'nr_reports_to_vet': nr_reports_to_vet,
+        'nr_submissions_to_assign': nr_submissions_to_assign,
+        'nr_recommendations_to_prepare_for_voting': nr_recommendations_to_prepare_for_voting,
+        'nr_assignments_to_consider': nr_assignments_to_consider,
+        'active_assignments': active_assignments,
+        'nr_submission_authorships_to_claim': nr_submission_authorships_to_claim,
+        'nr_commentary_authorships_to_claim': nr_commentary_authorships_to_claim,
+        'nr_thesis_authorships_to_claim': nr_thesis_authorships_to_claim,
+        'nr_ref_inv_to_consider': nr_ref_inv_to_consider,
+        'pending_ref_tasks': pending_ref_tasks,
+        'own_submissions': own_submissions,
+        'own_commentaries': own_commentaries,
+        'own_thesislinks': own_thesislinks,
+        'own_comments': own_comments, 'own_authorreplies': own_authorreplies,
+        'lists_owned': lists_owned,
+        'lists': lists,
+        'teams_led': teams_led,
+        'teams': teams,
+        'graphs_owned': graphs_owned,
+        'graphs_private': graphs_private,
+    }
+    return render(request, 'scipost/personal_page.html', context)
 
 
 @login_required
diff --git a/submissions/models.py b/submissions/models.py
index 8ca56af4a8d1d553d10b49041712a5eee45a5a53..7aea9adab2567057eb7c7753c025fa62f2e26c4b 100644
--- a/submissions/models.py
+++ b/submissions/models.py
@@ -634,7 +634,7 @@ class Report(models.Model):
     # -3: rejected (not useful)
     # -4: rejected (not academic in style)
     status = models.SmallIntegerField(default=0)
-    submission = models.ForeignKey(Submission, on_delete=models.CASCADE)
+    submission = models.ForeignKey(Submission, related_name='reports', on_delete=models.CASCADE)
     vetted_by = models.ForeignKey(Contributor, related_name="report_vetted_by",
                                   blank=True, null=True, on_delete=models.CASCADE)
     # `invited' filled from RefereeInvitation objects at moment of report submission
diff --git a/submissions/templatetags/submissions_extras.py b/submissions/templatetags/submissions_extras.py
index 7460a3c30745b62cf6f7ce4f29aff1f7bc5ab83b..b2b785c0357b7be546be77fe2a3eb0d1761022da 100644
--- a/submissions/templatetags/submissions_extras.py
+++ b/submissions/templatetags/submissions_extras.py
@@ -73,7 +73,7 @@ def required_actions(submission):
         todo.append('The refereeing deadline has passed. Please either extend it, '
                     'or formulate your Editorial Recommendation if at least '
                     'one Report has been received.')
-    reports = submission.report_set.all()
+    reports = submission.reports.all()
     for report in reports:
         if report.status == 0:
             todo.append('The Report from %s has been delivered but is not yet vetted. '
diff --git a/submissions/views.py b/submissions/views.py
index 2681da5f9dfafd7d11f42ee3bb6f18a085af8dc5..553e344673c0f4b4ddcf79b1c25bf4d19b2c8cc3 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -271,7 +271,10 @@ def submission_detail_wo_vn_nr(request, arxiv_identifier_wo_vn_nr):
 
 
 def submission_detail(request, arxiv_identifier_w_vn_nr):
-    submission = get_object_or_404(Submission, arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
+    submission = get_object_or_404(Submission.objects.select_related(
+                    'editor_in_charge', 'publication__in_issue__in_volume__in_journal'
+                    ).prefetch_related('authors'),
+                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
     try:
         is_author = request.user.contributor in submission.authors.all()
     except AttributeError:
@@ -288,7 +291,7 @@ def submission_detail(request, arxiv_identifier_w_vn_nr):
 
     form = CommentForm()
 
-    reports = submission.report_set.all()
+    reports = submission.reports.prefetch_related('reports')
     try:
         author_replies = Comment.objects.filter(submission=submission,
                                                 is_author_reply=True,
diff --git a/virtualmeetings/__init__.py b/virtualmeetings/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/virtualmeetings/admin.py b/virtualmeetings/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..c831a447b58b6d95edd086fda5750bbfc5e315c6
--- /dev/null
+++ b/virtualmeetings/admin.py
@@ -0,0 +1,31 @@
+from django.contrib import admin
+
+from .models import VGM, Feedback, Nomination, Motion
+
+
+class VGMAdmin(admin.ModelAdmin):
+    search_fields = ['start_date']
+
+
+admin.site.register(VGM, VGMAdmin)
+
+
+class FeedbackAdmin(admin.ModelAdmin):
+    search_fields = ['feedback', 'by']
+
+
+admin.site.register(Feedback, FeedbackAdmin)
+
+
+class NominationAdmin(admin.ModelAdmin):
+    search_fields = ['last_name', 'first_name', 'by']
+
+
+admin.site.register(Nomination, NominationAdmin)
+
+
+class MotionAdmin(admin.ModelAdmin):
+    search_fields = ['background', 'motion', 'put_forward_by']
+
+
+admin.site.register(Motion, MotionAdmin)
diff --git a/virtualmeetings/apps.py b/virtualmeetings/apps.py
new file mode 100644
index 0000000000000000000000000000000000000000..9bbfd4ea04576759b428cbd1b1127a2767b82216
--- /dev/null
+++ b/virtualmeetings/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class VirtualmeetingsConfig(AppConfig):
+    name = 'virtualmeetings'
diff --git a/virtualmeetings/constants.py b/virtualmeetings/constants.py
new file mode 100644
index 0000000000000000000000000000000000000000..f75281f3af9bd47307eb81ce6542ae3b89b8ffc8
--- /dev/null
+++ b/virtualmeetings/constants.py
@@ -0,0 +1,9 @@
+MOTION_AMENDMENTS = 'ByLawAmend'
+MOTION_WORKFLOW = 'Workflow'
+MOTION_GENERAL = 'General'
+MOTION_CATEGORIES = (
+    (MOTION_AMENDMENTS, 'Amendments to by-laws'),
+    (MOTION_WORKFLOW, 'Editorial workflow improvements'),
+    (MOTION_GENERAL, 'General'),
+)
+motion_categories_dict = dict(MOTION_CATEGORIES)
diff --git a/virtualmeetings/forms.py b/virtualmeetings/forms.py
new file mode 100644
index 0000000000000000000000000000000000000000..54fb4a68e81dfe0f7a1f54be8405a5ae5cfe60e4
--- /dev/null
+++ b/virtualmeetings/forms.py
@@ -0,0 +1,61 @@
+from django import forms
+
+from crispy_forms.helper import FormHelper
+from crispy_forms.layout import Layout, Div, Field, HTML, Submit
+
+from .models import Feedback, Nomination, Motion
+
+from scipost.constants import SCIPOST_SUBJECT_AREAS
+
+
+class FeedbackForm(forms.ModelForm):
+    class Meta:
+        model = Feedback
+        fields = ['feedback']
+
+
+class NominationForm(forms.ModelForm):
+    class Meta:
+        model = Nomination
+        fields = ['first_name', 'last_name',
+                  'discipline', 'expertises', 'webpage']
+
+    def __init__(self, *args, **kwargs):
+        super(NominationForm, self).__init__(*args, **kwargs)
+        self.fields['expertises'].widget = forms.SelectMultiple(choices=SCIPOST_SUBJECT_AREAS)
+
+
+class MotionForm(forms.ModelForm):
+    class Meta:
+        model = Motion
+        fields = ['category', 'background', 'motion']
+
+    def __init__(self, *args, **kwargs):
+        super(MotionForm, self).__init__(*args, **kwargs)
+        self.fields['background'].label = ''
+        self.fields['background'].widget.attrs.update(
+            {'rows': 8, 'cols': 100,
+             'placeholder': 'Provide useful background information on your Motion.'})
+        self.fields['motion'].label = ''
+        self.fields['motion'].widget.attrs.update(
+            {'rows': 8, 'cols': 100,
+             'placeholder': 'Phrase your Motion as clearly and succinctly as possible.'})
+        self.helper = FormHelper()
+        self.helper.layout = Layout(
+            Field('category'),
+            Div(
+                Div(HTML('<p>Background:</p>'),
+                    css_class="col-2"),
+                Div(
+                    Field('background'),
+                    css_class="col-10"),
+                css_class="row"),
+            Div(
+                Div(HTML('<p>Motion:</p>'),
+                    css_class="col-2"),
+                Div(
+                    Field('motion'),
+                    css_class="col-10"),
+                css_class="row"),
+            Submit('submit', 'Submit'),
+        )
diff --git a/virtualmeetings/migrations/0001_initial.py b/virtualmeetings/migrations/0001_initial.py
new file mode 100644
index 0000000000000000000000000000000000000000..567764e57de6f7ee69c5fa158016d95f64917c0a
--- /dev/null
+++ b/virtualmeetings/migrations/0001_initial.py
@@ -0,0 +1,145 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-03-06 07:04
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+import scipost.models
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('scipost', '0039_auto_20170306_0804'),
+    ]
+
+    state_operations = [
+        migrations.CreateModel(
+            name='Feedback',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('date', models.DateField()),
+                ('feedback', models.TextField()),
+            ],
+            options={
+                'db_table': 'scipost_feedback',
+            },
+        ),
+        migrations.CreateModel(
+            name='Motion',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('category', models.CharField(choices=[('ByLawAmend', 'Amendments to by-laws'), ('Workflow', 'Editorial workflow improvements'), ('General', 'General')], default='General', max_length=10)),
+                ('background', models.TextField()),
+                ('motion', models.TextField()),
+                ('date', models.DateField()),
+                ('nr_A', models.PositiveIntegerField(default=0)),
+                ('nr_N', models.PositiveIntegerField(default=0)),
+                ('nr_D', models.PositiveIntegerField(default=0)),
+                ('voting_deadline', models.DateTimeField(default=django.utils.timezone.now, verbose_name='voting deadline')),
+                ('accepted', models.NullBooleanField()),
+            ],
+            options={
+                'db_table': 'scipost_motion',
+            },
+        ),
+        migrations.CreateModel(
+            name='Nomination',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('date', models.DateField()),
+                ('first_name', models.CharField(default='', max_length=30)),
+                ('last_name', models.CharField(default='', max_length=30)),
+                ('discipline', models.CharField(choices=[('physics', 'Physics'), ('astrophysics', 'Astrophysics'), ('mathematics', 'Mathematics'), ('computerscience', 'Computer Science')], default='physics', max_length=20, verbose_name='Main discipline')),
+                ('expertises', scipost.models.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:AE', 'Atomic, Molecular and Optical Physics - Experiment'), ('Phys:AT', 'Atomic, Molecular and Optical Physics - Theory'), ('Phys:BI', 'Biophysics'), ('Phys:CE', 'Condensed Matter Physics - Experiment'), ('Phys:CT', 'Condensed Matter Physics - Theory'), ('Phys:FD', 'Fluid Dynamics'), ('Phys:GR', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:HE', 'High-Energy Physics - Experiment'), ('Phys:HT', 'High-Energy Physics- Theory'), ('Phys:HP', 'High-Energy Physics - Phenomenology'), ('Phys:MP', 'Mathematical Physics'), ('Phys:NE', 'Nuclear Physics - Experiment'), ('Phys:NT', 'Nuclear Physics - Theory'), ('Phys:QP', 'Quantum Physics'), ('Phys:SM', 'Statistical and Soft Matter Physics'))), ('Astrophysics', (('Astro:GA', 'Astrophysics of Galaxies'), ('Astro:CO', 'Cosmology and Nongalactic Astrophysics'), ('Astro:EP', 'Earth and Planetary Astrophysics'), ('Astro:HE', 'High Energy Astrophysical Phenomena'), ('Astro:IM', 'Instrumentation and Methods for Astrophysics'), ('Astro:SR', 'Solar and Stellar Astrophysics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:AP', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:CA', 'Classical Analysis and ODEs'), ('Math:CO', 'Combinatorics'), ('Math:AC', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GN', 'General Topology'), ('Math:GT', 'Geometric Topology'), ('Math:GR', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:LO', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:PR', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SP', 'Spectral Theory'), ('Math:ST', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None)),
+                ('webpage', models.URLField(default='')),
+                ('nr_A', models.PositiveIntegerField(default=0)),
+                ('nr_N', models.PositiveIntegerField(default=0)),
+                ('nr_D', models.PositiveIntegerField(default=0)),
+                ('voting_deadline', models.DateTimeField(default=django.utils.timezone.now, verbose_name='voting deadline')),
+                ('accepted', models.NullBooleanField()),
+            ],
+            options={
+                'db_table': 'scipost_nomination',
+            },
+        ),
+        migrations.CreateModel(
+            name='VGM',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('start_date', models.DateField()),
+                ('end_date', models.DateField()),
+                ('information', models.TextField(default='')),
+            ],
+            options={
+                'db_table': 'scipost_vgm',
+            },
+        ),
+        migrations.AddField(
+            model_name='nomination',
+            name='VGM',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='virtualmeetings.VGM'),
+        ),
+        migrations.AddField(
+            model_name='nomination',
+            name='by',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='scipost.Contributor'),
+        ),
+        migrations.AddField(
+            model_name='nomination',
+            name='in_agreement',
+            field=models.ManyToManyField(blank=True, related_name='in_agreement_with_nomination', to='scipost.Contributor'),
+        ),
+        migrations.AddField(
+            model_name='nomination',
+            name='in_disagreement',
+            field=models.ManyToManyField(blank=True, related_name='in_disagreement_with_nomination', to='scipost.Contributor'),
+        ),
+        migrations.AddField(
+            model_name='nomination',
+            name='in_notsure',
+            field=models.ManyToManyField(blank=True, related_name='in_notsure_with_nomination', to='scipost.Contributor'),
+        ),
+        migrations.AddField(
+            model_name='motion',
+            name='VGM',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='virtualmeetings.VGM'),
+        ),
+        migrations.AddField(
+            model_name='motion',
+            name='in_agreement',
+            field=models.ManyToManyField(blank=True, related_name='in_agreement_with_motion', to='scipost.Contributor'),
+        ),
+        migrations.AddField(
+            model_name='motion',
+            name='in_disagreement',
+            field=models.ManyToManyField(blank=True, related_name='in_disagreement_with_motion', to='scipost.Contributor'),
+        ),
+        migrations.AddField(
+            model_name='motion',
+            name='in_notsure',
+            field=models.ManyToManyField(blank=True, related_name='in_notsure_with_motion', to='scipost.Contributor'),
+        ),
+        migrations.AddField(
+            model_name='motion',
+            name='put_forward_by',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='scipost.Contributor'),
+        ),
+        migrations.AddField(
+            model_name='feedback',
+            name='VGM',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='virtualmeetings.VGM'),
+        ),
+        migrations.AddField(
+            model_name='feedback',
+            name='by',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='scipost.Contributor'),
+        ),
+    ]
+
+    operations = [
+        migrations.SeparateDatabaseAndState(state_operations=state_operations)
+    ]
diff --git a/virtualmeetings/migrations/__init__.py b/virtualmeetings/migrations/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/virtualmeetings/models.py b/virtualmeetings/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..55aaacefe039c513e6f0a63644e44d2d4f59c46c
--- /dev/null
+++ b/virtualmeetings/models.py
@@ -0,0 +1,223 @@
+from django.db import models
+from django.shortcuts import get_object_or_404
+from django.template import Context, Template
+from django.utils import timezone
+
+from .constants import MOTION_CATEGORIES
+
+from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS,\
+                              subject_areas_dict, disciplines_dict
+from scipost.models import Contributor, ChoiceArrayField
+
+
+class VGM(models.Model):
+    """
+    Each year, a Virtual General Meeting is held during which operations at
+    SciPost are discussed. A VGM can be attended by Administrators,
+    Advisory Board members and Editorial Fellows.
+    """
+    start_date = models.DateField()
+    end_date = models.DateField()
+    information = models.TextField(default='')
+
+    class Meta:
+        db_table = 'scipost_vgm'
+
+    def __str__(self):
+        return 'From %s to %s' % (self.start_date.strftime('%Y-%m-%d'),
+                                  self.end_date.strftime('%Y-%m-%d'))
+
+
+class Feedback(models.Model):
+    """
+    Feedback, suggestion or criticism on any aspect of SciPost.
+    """
+    VGM = models.ForeignKey(VGM, blank=True, null=True)
+    by = models.ForeignKey(Contributor)
+    date = models.DateField()
+    feedback = models.TextField()
+
+    class Meta:
+        db_table = 'scipost_feedback'
+
+    def __str__(self):
+        return '%s: %s' % (self.by, self.feedback[:50])
+
+    def as_li(self):
+        html = ('<div class="Feedback">'
+                '<h3><em>by {{ by }}</em></h3>'
+                '<p>{{ feedback|linebreaks }}</p>'
+                '</div>')
+        context = Context({
+            'feedback': self.feedback,
+            'by': '%s %s' % (self.by.user.first_name,
+                             self.by.user.last_name)})
+        template = Template(html)
+        return template.render(context)
+
+
+class Nomination(models.Model):
+    """
+    Nomination to an Editorial Fellowship.
+    """
+    VGM = models.ForeignKey(VGM, blank=True, null=True)
+    by = models.ForeignKey(Contributor)
+    date = models.DateField()
+    first_name = models.CharField(max_length=30, default='')
+    last_name = models.CharField(max_length=30, default='')
+    discipline = models.CharField(max_length=20, choices=SCIPOST_DISCIPLINES,
+                                  default='physics', verbose_name='Main discipline')
+    expertises = ChoiceArrayField(
+        models.CharField(max_length=10, choices=SCIPOST_SUBJECT_AREAS),
+        blank=True, null=True)
+    webpage = models.URLField(default='')
+    nr_A = models.PositiveIntegerField(default=0)
+    in_agreement = models.ManyToManyField(Contributor,
+                                          related_name='in_agreement_with_nomination', blank=True)
+    nr_N = models.PositiveIntegerField(default=0)
+    in_notsure = models.ManyToManyField(Contributor,
+                                        related_name='in_notsure_with_nomination', blank=True)
+    nr_D = models.PositiveIntegerField(default=0)
+    in_disagreement = models.ManyToManyField(Contributor,
+                                             related_name='in_disagreement_with_nomination',
+                                             blank=True)
+    voting_deadline = models.DateTimeField('voting deadline', default=timezone.now)
+    accepted = models.NullBooleanField()
+
+    class Meta:
+        db_table = 'scipost_nomination'
+
+    def __str__(self):
+        return '%s %s (nominated by %s)' % (self.first_name,
+                                            self.last_name,
+                                            self.by)
+
+    def as_li(self):
+        html = ('<div class="Nomination" id="nomination_id{{ nomination_id }}" '
+                'style="background-color: #eeeeee;">'
+                '<div class="row">'
+                '<div class="col-4">'
+                '<h3><em> {{ name }}</em></h3>'
+                '<p>Nominated by {{ proposer }}</p>'
+                '</div>'
+                '<div class="col-4">'
+                '<p><a href="{{ webpage }}">Webpage</a></p>'
+                '<p>Discipline: {{ discipline }}</p></div>'
+                '<div class="col-4"><p>expertise:<ul>')
+        for exp in self.expertises:
+            html += '<li>%s</li>' % subject_areas_dict[exp]
+        html += '</ul></div></div></div>'
+        context = Context({
+            'nomination_id': self.id,
+            'proposer': '%s %s' % (self.by.user.first_name,
+                                   self.by.user.last_name),
+            'name': self.first_name + ' ' + self.last_name,
+            'discipline': disciplines_dict[self.discipline],
+            'webpage': self.webpage,
+        })
+        template = Template(html)
+        return template.render(context)
+
+    def votes_as_ul(self):
+        template = Template('''
+        <ul class="opinionsDisplay">
+        <li style="background-color: #000099">Agree {{ nr_A }}</li>
+        <li style="background-color: #555555">Abstain {{ nr_N }}</li>
+        <li style="background-color: #990000">Disagree {{ nr_D }}</li>
+        </ul>
+        ''')
+        context = Context({'nr_A': self.nr_A, 'nr_N': self.nr_N, 'nr_D': self.nr_D})
+        return template.render(context)
+
+    def update_votes(self, contributor_id, vote):
+        contributor = get_object_or_404(Contributor, pk=contributor_id)
+        self.in_agreement.remove(contributor)
+        self.in_notsure.remove(contributor)
+        self.in_disagreement.remove(contributor)
+        if vote == 'A':
+            self.in_agreement.add(contributor)
+        elif vote == 'N':
+            self.in_notsure.add(contributor)
+        elif vote == 'D':
+            self.in_disagreement.add(contributor)
+        self.nr_A = self.in_agreement.count()
+        self.nr_N = self.in_notsure.count()
+        self.nr_D = self.in_disagreement.count()
+        self.save()
+
+
+class Motion(models.Model):
+    """
+    Motion instances are put forward to the Advisory Board and Editorial College
+    and detail suggested changes to rules, procedures etc.
+    They are meant to be voted on at the annual VGM.
+    """
+    category = models.CharField(max_length=10, choices=MOTION_CATEGORIES, default='General')
+    VGM = models.ForeignKey(VGM, blank=True, null=True)
+    background = models.TextField()
+    motion = models.TextField()
+    put_forward_by = models.ForeignKey(Contributor)
+    date = models.DateField()
+    nr_A = models.PositiveIntegerField(default=0)
+    in_agreement = models.ManyToManyField(Contributor,
+                                          related_name='in_agreement_with_motion', blank=True)
+    nr_N = models.PositiveIntegerField(default=0)
+    in_notsure = models.ManyToManyField(Contributor,
+                                        related_name='in_notsure_with_motion', blank=True)
+    nr_D = models.PositiveIntegerField(default=0)
+    in_disagreement = models.ManyToManyField(Contributor,
+                                             related_name='in_disagreement_with_motion',
+                                             blank=True)
+    voting_deadline = models.DateTimeField('voting deadline', default=timezone.now)
+    accepted = models.NullBooleanField()
+
+    class Meta:
+        db_table = 'scipost_motion'
+
+    def __str__(self):
+        return self.motion[:32]
+
+    def as_li(self):
+        html = ('<div class="Motion" id="motion_id{{ motion_id }}">'
+                '<h3><em>Motion {{ motion_id }}, put forward by {{ proposer }}</em></h3>'
+                '<h3>Background:</h3><p>{{ background|linebreaks }}</p>'
+                '<h3>Motion:</h3>'
+                '<div class="flex-container"><div class="flex-greybox">'
+                '<p style="background-color: #eeeeee;">{{ motion|linebreaks }}</p>'
+                '</div></div>'
+                '</div>')
+        context = Context({
+            'motion_id': self.id,
+            'proposer': '%s %s' % (self.put_forward_by.user.first_name,
+                                   self.put_forward_by.user.last_name),
+            'background': self.background,
+            'motion': self.motion, })
+        template = Template(html)
+        return template.render(context)
+
+    def votes_as_ul(self):
+        template = Template('''
+        <ul class="opinionsDisplay">
+        <li style="background-color: #000099">Agree {{ nr_A }}</li>
+        <li style="background-color: #555555">Abstain {{ nr_N }}</li>
+        <li style="background-color: #990000">Disagree {{ nr_D }}</li>
+        </ul>
+        ''')
+        context = Context({'nr_A': self.nr_A, 'nr_N': self.nr_N, 'nr_D': self.nr_D})
+        return template.render(context)
+
+    def update_votes(self, contributor_id, vote):
+        contributor = get_object_or_404(Contributor, pk=contributor_id)
+        self.in_agreement.remove(contributor)
+        self.in_notsure.remove(contributor)
+        self.in_disagreement.remove(contributor)
+        if vote == 'A':
+            self.in_agreement.add(contributor)
+        elif vote == 'N':
+            self.in_notsure.add(contributor)
+        elif vote == 'D':
+            self.in_disagreement.add(contributor)
+        self.nr_A = self.in_agreement.count()
+        self.nr_N = self.in_notsure.count()
+        self.nr_D = self.in_disagreement.count()
+        self.save()
diff --git a/virtualmeetings/templates/virtualmeetings/VGM_detail.html b/virtualmeetings/templates/virtualmeetings/VGM_detail.html
new file mode 100644
index 0000000000000000000000000000000000000000..0420363c16e093409a430ceee2b8d259bc6f9dd2
--- /dev/null
+++ b/virtualmeetings/templates/virtualmeetings/VGM_detail.html
@@ -0,0 +1,352 @@
+{% extends 'scipost/base.html' %}
+
+{% block pagetitle %}: VGM detail{% endblock pagetitle %}
+
+{% load staticfiles %}
+
+{% block bodysup %}
+
+<script>
+$(document).ready(function(){
+
+  $("#submitFeedbackForm").hide();
+  $("#submitFeedbackButton").click( function() {
+     $(this).next("form").toggle();
+  });
+
+  $("#FellowshipListing").hide();
+  $("#FellowshipListingButton").click( function() {
+      $("#FellowshipListing").toggle();
+  });
+
+  $("#submitNominationForm").hide();
+  $("#submitNominationButton").click( function() {
+     $(this).next("form").toggle();
+  });
+
+  $("#submitMotionForm").hide();
+  $("#submitMotionButton").click( function() {
+     $(this).next("form").toggle();
+  });
+
+  $(".submitRemarkForm").hide();
+
+  $(".submitRemarkButton").click( function() {
+     $(this).next("div").toggle();
+  });
+  });
+
+</script>
+
+<section>
+  <div class="flex-container">
+    <div class="flex-greybox">
+      <h1>SciPost Virtual General Meeting</h1>
+    </div>
+  </div>
+  <div class="flex-container">
+    <div class="flex-whitebox">
+      <h2>On this page:</h2>
+      <ul>
+	<li><a href="#Information">Information message</a></li>
+	<li><a href="#Feedback">Feedback</a></li>
+	<li><a href="#Nominations">Nominations</a></li>
+	<li><a href="#Motions">Motions</a></li>
+      </ul>
+    </div>
+  </div>
+  <hr class="hr12"/>
+</section>
+
+
+<section id="Information">
+  <div class="flex-container">
+    <div class="flex-greybox">
+      <h2>Information message from SciPost Administration</h2>
+    </div>
+  </div>
+  <div class="flex-whitebox">
+    {{ VGM_information }}
+  </div>
+  <br/>
+  <div class="flex-whitebox">
+    <h3>Quick bullet points:</h3>
+    <ul>
+      <li>This VGM is scheduled from {{ VGM.start_date|date:'Y-m-d' }} to {{ VGM.end_date|date:'Y-m-d' }}.</li>
+      <li>Your feedback/suggestions/criticisms on any aspect of SciPost are greatly valued. Provide them by filling the <a href="#FeedbackBox">feedback form</a>.</li>
+      <li>Your nominations to the Editorial College are welcome. Simply fill the <a href="#NominationBox">nomination form</a>, and cast your vote on current nominations.</li>
+      <li>For substantial changes, for example to the by-laws, new Motions can be put forward until the end of the meeting using the <a href="#MotionBox">form</a>.</li>
+      <li>Voting on Motions is open until one week after the meeting.</li>
+      <li>You a referred to the <a href="{% url 'scipost:EdCol_by-laws' %}">by-laws</a>, section 2 for further details about the procedures.</li>
+    </ul>
+  </div>
+  <br/>
+  <hr class="hr12"/>
+</section>
+
+<section id="Feedback">
+  <div class="flex-container">
+    <div class="flex-greybox" id="FeedbackBox">
+      <h2>Feedback on SciPost</h2>
+      <button id="submitFeedbackButton">Provide feedback</button>
+      <form id="submitFeedbackForm" action="{% url 'virtualmeetings:feedback' VGM_id=VGM.id %}" method="post">
+	{% csrf_token %}
+	{{ feedback_form.as_p }}
+	<input type="submit" value="Submit"/>
+      </form>
+    </div>
+  </div>
+  <div class="flex-container">
+    <div class="flex-greybox">
+      <h2>General Feedback provided</h2>
+    </div>
+  </div>
+  <div class="row">
+    <div class="col-1"></div>
+    <div class="col-10">
+      <ul>
+	{% for feedback in feedback_received %}
+	<li>{{ feedback.as_li }}</li>
+	<button class="submitRemarkButton" id="remarkButton{{ nomination.id }}">Add a remark on this Feedback</button>
+	<div class="submitRemarkForm" id="remarkForm{{ feedback.id }}">
+	  <form action="{% url 'virtualmeetings:add_remark_on_feedback' VGM_id=VGM.id feedback_id=feedback.id %}" method="post">
+	    {% csrf_token %}
+	    {{ remark_form.as_p }}
+	    <input type="submit" value="Submit" />
+	  </form>
+	</div>
+	{% if feedback.remark_set.all %}
+	<h3>Remarks on this feedback:</h3>
+	<ul>
+	  {% for rem in feedback.remark_set.all %}
+	  {{ rem.as_li }}
+	  {% endfor %}
+	</ul>
+	{% endif %}
+	{% endfor %}
+      </ul>
+    </div>
+  </div>
+  <hr class="hr12"/>
+</section>
+
+<section id="Nominations">
+  <div class="flex-container">
+    <div class="flex-greybox" id="NominationBox">
+      <h2>Nominations to the Editorial College</h2>
+      <button id="submitNominationButton">Nominate an Editorial Fellow candidate</button>
+      <form id="submitNominationForm" action="{% url 'virtualmeetings:nominate_Fellow' VGM_id=VGM.id %}" method="post">
+	{% csrf_token %}
+	{{ nomination_form.as_p }}
+        <input type="submit" value="Submit"/>
+      </form>
+    </div>
+  </div>
+  <button id="FellowshipListingButton">View/hide Fellows and Invitations listings</button>
+  <div class="row" id="FellowshipListing">
+    <div class="col-6">
+      <div class="flex-container">
+	<div class="flex-greybox">
+	  <h3>Current Fellows</h3>
+	</div>
+      </div>
+      <div class="flex-container">
+	<div class="flex-whitebox">
+	  <table class="tableofInviteesResponded">
+	    {% for Fellow in current_Fellows %}
+	    <tr><td>{{ Fellow }}</td><td>{{ Fellow.discipline_as_string }}</td>
+	      <td>{{ Fellow.expertises_as_string }}</td></tr>
+	    {% endfor %}
+	  </table>
+	</div>
+      </div>
+    </div>
+    <div class="col-6">
+      <div class="flex-container">
+	<div class="flex-greybox">
+	  <h3>Invitations currently outstanding</h3>
+	</div>
+      </div>
+      <div class="flex-container">
+	<div class="flex-whitebox">
+	  <table class="tableofInvitees">
+	    {% for invitee in pending_inv_Fellows %}
+	    <tr><td>{{ invitee.first_name }} {{ invitee.last_name }}</td></tr>
+	    {% endfor %}
+	  </table>
+	</div>
+      </div>
+      <div class="flex-container">
+	<div class="flex-greybox">
+	  <h3>Invitations which have been turned down</h3>
+	</div>
+      </div>
+      <div class="flex-container">
+	<div class="flex-whitebox">
+	  <table class="tableofInviteesDeclined">
+	    {% for invitee in declined_inv_Fellows %}
+	    <tr><td>{{ invitee.first_name }} {{ invitee.last_name }}</td></tr>
+	    {% endfor %}
+	  </table>
+	</div>
+      </div>
+    </div>
+  </div>
+
+  {% if nominations %}
+  <div class="row">
+    <div class="flex-container">
+      <div class="flex-greybox">
+	<h2>Nominations under consideration</h2>
+      </div>
+    </div>
+  </div>
+  <div class="row">
+    <div class="col-1"></div>
+    <div class="col-10">
+    <ul style="list-style-type: none;">
+      {% for nomination in nominations %}
+      <li>
+	{{ nomination.as_li }}
+	<br/>
+	<div class="opinionsDisplay">
+	  <h4>Your opinion on this Nomination (voting deadline: {{ nomination.voting_deadline|date:'y-m-d' }}):</h4>
+	  <form action="{% url 'virtualmeetings:vote_on_nomination' nomination_id=nomination.id vote='A' %}" method="post">
+            {% csrf_token %}
+            <input type="submit" class="agree" value="Agree {{ nomination.nr_A }} "/>
+	  </form>
+	  <form action="{% url 'virtualmeetings:vote_on_nomination' nomination_id=nomination.id vote='N' %}" method="post">
+            {% csrf_token %}
+            <input type="submit" class="notsure" value="Not sure {{ nomination.nr_N }}"/>
+	  </form>
+	  <form action="{% url 'virtualmeetings:vote_on_nomination' nomination_id=nomination.id vote='D'%}" method="post">
+            {% csrf_token %}
+            <input type="submit" class="disagree" value="Disagree {{ nomination.nr_D }}"/>
+	  </form>
+	  {% if request.user.contributor in nomination.in_agreement.all %}
+	  <strong>(you have voted: Agreed)</strong>
+	  {% elif request.user.contributor in nomination.in_notsure.all %}
+	  <strong>(you have voted: Not sure)</strong>
+	  {% elif request.user.contributor in nomination.in_disagreement.all %}
+	  <strong>(you have voted: Disagree)</strong>
+	  {% endif %}
+	</div>
+	<br/><br/>
+	<button class="submitRemarkButton" id="remarkButton{{ nomination.id }}">Add a remark on this Nomination</button>
+	<div class="submitRemarkForm" id="remarkForm{{ nomination.id }}">
+	  <form action="{% url 'virtualmeetings:add_remark_on_nomination' VGM_id=VGM.id nomination_id=nomination.id %}" method="post">
+	    {% csrf_token %}
+	    {{ remark_form.as_p }}
+	    <input type="submit" value="Submit" />
+	  </form>
+	</div>
+	{% if nomination.remark_set.all %}
+	<h3>Remarks on this nomination:</h3>
+	<ul>
+	  {% for rem in nomination.remark_set.all %}
+	  {{ rem.as_li }}
+	  {% endfor %}
+	</ul>
+	{% endif %}
+	<hr class="hr6"/>
+	<br/>
+      </li>
+      {% endfor %}
+    </ul>
+    </div>
+  </div>
+  {% endif %}
+
+  <hr class="hr12"/>
+
+</section>
+
+<section id="Motions">
+  <div class="flex-container">
+    <div class="flex-greybox" id="MotionBox">
+      <h2>Submit a new Motion</h2>
+      <button id="submitMotionButton">Put a new Motion forward</button>
+      <form id="submitMotionForm" action="{% url 'virtualmeetings:put_motion_forward' VGM_id=VGM.id %}" method="post">
+	{% csrf_token %}
+	{% load crispy_forms_tags %}
+	{% crispy motion_form %}
+      </form>
+    </div>
+  </div>
+
+  <div class="row">
+    <div class="flex-container">
+      <div class="flex-greybox">
+	<h2>Motions under consideration</h2>
+      </div>
+    </div>
+  </div>
+  {% for key, val in motion_categories_dict.items %}
+  <div class="row">
+    <div class="col-1"></div>
+    <div class="flex-container">
+      <div class="flex-greybox">
+	<h3>{{ val }}:</h3>
+      </div>
+    </div>
+    <div class="col-1"></div>
+    <div class="col-10">
+    <ul>
+      {% for motion in VGM.motion_set.all %}
+      {% if motion.category == key %}
+      <li>
+	{{ motion.as_li }}
+	<br/>
+	<div class="opinionsDisplay">
+	  <h4>Your opinion on this Motion (voting deadline: {{ motion.voting_deadline|date:'y-m-d' }}):</h4>
+	  <form action="{% url 'virtualmeetings:vote_on_motion' motion_id=motion.id vote='A' %}" method="post">
+            {% csrf_token %}
+            <input type="submit" class="agree" value="Agree {{ motion.nr_A }} "/>
+	  </form>
+	  <form action="{% url 'virtualmeetings:vote_on_motion' motion_id=motion.id vote='N' %}" method="post">
+            {% csrf_token %}
+            <input type="submit" class="notsure" value="Not sure {{ motion.nr_N }}"/>
+	  </form>
+	  <form action="{% url 'virtualmeetings:vote_on_motion' motion_id=motion.id vote='D'%}" method="post">
+            {% csrf_token %}
+            <input type="submit" class="disagree" value="Disagree {{ motion.nr_D }}"/>
+	  </form>
+	  {% if request.user.contributor in motion.in_agreement.all %}
+	  <strong>(you have voted: Agreed)</strong>
+	  {% elif request.user.contributor in motion.in_notsure.all %}
+	  <strong>(you have voted: Not sure)</strong>
+	  {% elif request.user.contributor in motion.in_disagreement.all %}
+	  <strong>(you have voted: Disagree)</strong>
+	  {% endif %}
+	</div>
+	<br/><br/>
+	<button class="submitRemarkButton" id="remarkButton{{ motion.id }}">Add a remark on this Motion</button>
+	<div class="submitRemarkForm" id="remarkForm{{ motion.id }}">
+	  <form action="{% url 'virtualmeetings:add_remark_on_motion' motion_id=motion.id %}" method="post">
+	    {% csrf_token %}
+	    {{ remark_form.as_p }}
+	    <input type="submit" value="Submit" />
+	  </form>
+	</div>
+	{% if motion.remark_set.all %}
+	<h3>Remarks on this motion:</h3>
+	<ul>
+	  {% for rem in motion.remark_set.all %}
+	  {{ rem.as_li }}
+	  {% endfor %}
+	</ul>
+	{% endif %}
+	<hr class="hr6"/>
+	<br/>
+      </li>
+      {% endif %}
+      {% endfor %}
+    </ul>
+    </div>
+  </div>
+  {% endfor %}
+
+</section>
+
+
+{% endblock bodysup %}
diff --git a/virtualmeetings/templates/virtualmeetings/VGMs.html b/virtualmeetings/templates/virtualmeetings/VGMs.html
new file mode 100644
index 0000000000000000000000000000000000000000..a482a21dfadd11a7121e88458dd9bdb2df7ef9a0
--- /dev/null
+++ b/virtualmeetings/templates/virtualmeetings/VGMs.html
@@ -0,0 +1,26 @@
+{% extends 'scipost/base.html' %}
+
+{% block pagetitle %}: VGMs{% endblock pagetitle %}
+
+{% load staticfiles %}
+
+{% block bodysup %}
+
+
+<section>
+  <div class="flex-container">
+    <div class="flex-greybox">
+      <h1>SciPost Virtual General Meetings</h1>
+    </div>
+  </div>
+
+  <ul>
+    {% for VGM in VGM_list %}
+    <li><a href="{% url 'virtualmeetings:VGM_detail' VGM_id=VGM.id %}">{{ VGM }}</a></li>
+    {% endfor %}
+  </ul>
+
+</section>
+
+
+{% endblock bodysup %}
diff --git a/virtualmeetings/tests.py b/virtualmeetings/tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ce503c2dd97ba78597f6ff6e4393132753573f6
--- /dev/null
+++ b/virtualmeetings/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/virtualmeetings/urls.py b/virtualmeetings/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..556a7eb2b1e4dca34f7330c19ab6779aaac8a080
--- /dev/null
+++ b/virtualmeetings/urls.py
@@ -0,0 +1,24 @@
+
+from django.conf.urls import include, url
+from django.views.generic import TemplateView
+
+from . import views
+
+urlpatterns = [
+    url(r'^$', views.VGMs, name='VGMs'),
+    url(r'^VGM/(?P<VGM_id>[0-9]+)/$', views.VGM_detail, name='VGM_detail'),
+    url(r'^feedback/(?P<VGM_id>[0-9]+)$', views.feedback, name='feedback'),
+    url(r'^add_remark_on_feedback/(?P<VGM_id>[0-9]+)/(?P<feedback_id>[0-9]+)$',
+        views.add_remark_on_feedback, name='add_remark_on_feedback'),
+    url(r'^nominate_Fellow/(?P<VGM_id>[0-9]+)$', views.nominate_Fellow, name='nominate_Fellow'),
+    url(r'^add_remark_on_nomination/(?P<VGM_id>[0-9]+)/(?P<nomination_id>[0-9]+)$',
+        views.add_remark_on_nomination, name='add_remark_on_nomination'),
+    url(r'^vote_on_nomination/(?P<nomination_id>[0-9]+)/(?P<vote>[AND])$',
+        views.vote_on_nomination, name='vote_on_nomination'),
+    url(r'^put_motion_forward/(?P<VGM_id>[0-9]+)$',
+        views.put_motion_forward, name='put_motion_forward'),
+    url(r'^add_remark_on_motion/(?P<motion_id>[0-9]+)$',
+        views.add_remark_on_motion, name='add_remark_on_motion'),
+    url(r'^vote_on_motion/(?P<motion_id>[0-9]+)/(?P<vote>[AND])$',
+        views.vote_on_motion, name='vote_on_motion'),
+]
diff --git a/virtualmeetings/views.py b/virtualmeetings/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..ee357ca3f74aac592483d38e4500a75d1c855bba
--- /dev/null
+++ b/virtualmeetings/views.py
@@ -0,0 +1,252 @@
+import datetime
+
+from django.contrib.auth.decorators import login_required, permission_required
+from django.core.urlresolvers import reverse
+from django.http import HttpResponseRedirect
+from django.shortcuts import get_object_or_404, render
+from django.template import Context, Template
+from django.utils import timezone
+
+from .constants import motion_categories_dict
+from .forms import FeedbackForm, NominationForm, MotionForm
+from .models import VGM, Feedback, Nomination, Motion
+
+from scipost.forms import RegistrationInvitation, RemarkForm
+from scipost.models import Contributor, Remark
+
+
+@login_required
+@permission_required('scipost.can_attend_VGMs')
+def VGMs(request):
+    VGM_list = VGM.objects.all().order_by('start_date')
+    context = {'VGM_list': VGM_list}
+    return render(request, 'virtualmeetings/VGMs.html', context)
+
+
+@login_required
+@permission_required('scipost.can_attend_VGMs')
+def VGM_detail(request, VGM_id):
+    VGM_instance = get_object_or_404(VGM, id=VGM_id)
+    VGM_information = Template(VGM_instance.information).render(Context({}))
+    feedback_received = Feedback.objects.filter(VGM=VGM_instance).order_by('date')
+    feedback_form = FeedbackForm()
+    current_Fellows = Contributor.objects.filter(
+        user__groups__name='Editorial College').order_by('user__last_name')
+    sent_inv_Fellows = RegistrationInvitation.objects.filter(
+        invitation_type='F', responded=False)
+    pending_inv_Fellows = sent_inv_Fellows.filter(declined=False).order_by('last_name')
+    declined_inv_Fellows = sent_inv_Fellows.filter(declined=True).order_by('last_name')
+    nomination_form = NominationForm()
+    nominations = Nomination.objects.filter(accepted=None).order_by('last_name')
+    motion_form = MotionForm()
+    remark_form = RemarkForm()
+    context = {
+        'VGM': VGM_instance,
+        'VGM_information': VGM_information,
+        'feedback_received': feedback_received,
+        'feedback_form': feedback_form,
+        'current_Fellows': current_Fellows,
+        'pending_inv_Fellows': pending_inv_Fellows,
+        'declined_inv_Fellows': declined_inv_Fellows,
+        'nominations': nominations,
+        'nomination_form': nomination_form,
+        'motion_categories_dict': motion_categories_dict,
+        'motion_form': motion_form,
+        'remark_form': remark_form,
+    }
+    return render(request, 'virtualmeetings/VGM_detail.html', context)
+
+
+@login_required
+@permission_required('scipost.can_attend_VGMs')
+def feedback(request, VGM_id=None):
+    if request.method == 'POST':
+        feedback_form = FeedbackForm(request.POST)
+        if feedback_form.is_valid():
+            feedback = Feedback(by=request.user.contributor,
+                                date=timezone.now().date(),
+                                feedback=feedback_form.cleaned_data['feedback'],)
+            if VGM_id:
+                VGM_instance = get_object_or_404(VGM, id=VGM_id)
+                feedback.VGM = VGM_instance
+            feedback.save()
+            ack_message = 'Your feedback has been received.'
+            context = {'ack_message': ack_message}
+            if VGM_id:
+                context['followup_message'] = 'Return to the '
+                context['followup_link'] = reverse('virtualmeetings:VGM_detail',
+                                                   kwargs={'VGM_id': VGM_id})
+                context['followup_link_label'] = 'VGM page'
+            return render(request, 'scipost/acknowledgement.html', context)
+        else:
+            errormessage = 'The form was not filled properly.'
+            return render(request, 'scipost/error.html', {'errormessage': errormessage})
+    else:
+        errormessage = 'This view can only be posted to.'
+        return render(request, 'scipost/error.html', {'errormessage': errormessage})
+
+
+@login_required
+@permission_required('scipost.can_attend_VGMs', raise_exception=True)
+def add_remark_on_feedback(request, VGM_id, feedback_id):
+    # contributor = request.user.contributor
+    feedback = get_object_or_404(Feedback, pk=feedback_id)
+    if request.method == 'POST':
+        remark_form = RemarkForm(request.POST)
+        if remark_form.is_valid():
+            remark = Remark(contributor=request.user.contributor,
+                            feedback=feedback,
+                            date=timezone.now(),
+                            remark=remark_form.cleaned_data['remark'])
+            remark.save()
+            return HttpResponseRedirect('/VGM/' + str(VGM_id) +
+                                        '/#feedback_id' + str(feedback.id))
+        else:
+            errormessage = 'The form was invalidly filled.'
+            return render(request, 'scipost/error.html', {'errormessage': errormessage})
+    else:
+        errormessage = 'This view can only be posted to.'
+        return render(request, 'scipost/error.html', {'errormessage': errormessage})
+
+
+@login_required
+@permission_required('scipost.can_attend_VGMs')
+def nominate_Fellow(request, VGM_id):
+    VGM_instance = get_object_or_404(VGM, id=VGM_id)
+    if request.method == 'POST':
+        nomination_form = NominationForm(request.POST)
+        if nomination_form.is_valid():
+            nomination = Nomination(
+                VGM=VGM_instance,
+                by=request.user.contributor,
+                date=timezone.now().date(),
+                first_name=nomination_form.cleaned_data['first_name'],
+                last_name=nomination_form.cleaned_data['last_name'],
+                discipline=nomination_form.cleaned_data['discipline'],
+                expertises=nomination_form.cleaned_data['expertises'],
+                webpage=nomination_form.cleaned_data['webpage'],
+                voting_deadline=VGM_instance.end_date + datetime.timedelta(days=7),
+            )
+            nomination.save()
+            nomination.update_votes(request.user.contributor.id, 'A')
+            ack_message = 'The nomination has been registered.'
+            context = {'ack_message': ack_message,
+                       'followup_message': 'Return to the ',
+                       'followup_link': reverse('virtualmeetings:VGM_detail',
+                                                kwargs={'VGM_id': VGM_id}),
+                       'followup_link_label': 'VGM page'}
+            return render(request, 'scipost/acknowledgement.html', context)
+        else:
+            errormessage = 'The form was not filled properly.'
+            return render(request, 'scipost/error.html', {'errormessage': errormessage})
+    else:
+        errormessage = 'This view can only be posted to.'
+        return render(request, 'scipost/error.html', {'errormessage': errormessage})
+
+
+@login_required
+@permission_required('scipost.can_attend_VGMs', raise_exception=True)
+def add_remark_on_nomination(request, VGM_id, nomination_id):
+    # contributor = request.user.contributor
+    nomination = get_object_or_404(Nomination, pk=nomination_id)
+    if request.method == 'POST':
+        remark_form = RemarkForm(request.POST)
+        if remark_form.is_valid():
+            remark = Remark(contributor=request.user.contributor,
+                            nomination=nomination,
+                            date=timezone.now(),
+                            remark=remark_form.cleaned_data['remark'])
+            remark.save()
+            return HttpResponseRedirect('/VGM/' + str(VGM_id) +
+                                        '/#nomination_id' + str(nomination.id))
+        else:
+            errormessage = 'The form was invalidly filled.'
+            return render(request, 'scipost/error.html', {'errormessage': errormessage})
+    else:
+        errormessage = 'This view can only be posted to.'
+        return render(request, 'scipost/error.html', {'errormessage': errormessage})
+
+
+@login_required
+@permission_required('scipost.can_attend_VGMs', raise_exception=True)
+def vote_on_nomination(request, nomination_id, vote):
+    contributor = request.user.contributor
+    nomination = get_object_or_404(Nomination, pk=nomination_id)
+    if timezone.now() > nomination.voting_deadline:
+        errormessage = 'The voting deadline on this nomination has passed.'
+        return render(request, 'scipost/error.html', {'errormessage': errormessage})
+    nomination.update_votes(contributor.id, vote)
+    return HttpResponseRedirect('/VGM/' + str(nomination.VGM.id) +
+                                '/#nomination_id' + str(nomination.id))
+
+
+@login_required
+@permission_required('scipost.can_attend_VGMs')
+def put_motion_forward(request, VGM_id):
+    VGM_instance = get_object_or_404(VGM, id=VGM_id)
+    if timezone.now().date() > VGM_instance.end_date:
+        errormessage = 'This VGM has ended. No new motions can be put forward.'
+        return render(request, 'scipost/error.html', {'errormessage': errormessage})
+    if request.method == 'POST':
+        motion_form = MotionForm(request.POST)
+        if motion_form.is_valid():
+            motion = Motion(
+                category=motion_form.cleaned_data['category'],
+                VGM=VGM_instance,
+                background=motion_form.cleaned_data['background'],
+                motion=motion_form.cleaned_data['motion'],
+                put_forward_by=request.user.contributor,
+                date=timezone.now().date(),
+                voting_deadline=VGM_instance.end_date + datetime.timedelta(days=7),
+            )
+            motion.save()
+            motion.update_votes(request.user.contributor.id, 'A')
+            ack_message = 'Your motion has been registered.'
+            context = {'ack_message': ack_message,
+                       'followup_message': 'Return to the ',
+                       'followup_link': reverse('virtualmeetings:VGM_detail',
+                                                kwargs={'VGM_id': VGM_id}),
+                       'followup_link_label': 'VGM page'}
+            return render(request, 'scipost/acknowledgement.html', context)
+        else:
+            errormessage = 'The form was not filled properly.'
+            return render(request, 'scipost/error.html', {'errormessage': errormessage})
+    else:
+        errormessage = 'This view can only be posted to.'
+        return render(request, 'scipost/error.html', {'errormessage': errormessage})
+
+
+@login_required
+@permission_required('scipost.can_attend_VGMs', raise_exception=True)
+def add_remark_on_motion(request, motion_id):
+    # contributor = request.user.contributor
+    motion = get_object_or_404(Motion, pk=motion_id)
+    if request.method == 'POST':
+        remark_form = RemarkForm(request.POST)
+        if remark_form.is_valid():
+            remark = Remark(contributor=request.user.contributor,
+                            motion=motion,
+                            date=timezone.now(),
+                            remark=remark_form.cleaned_data['remark'])
+            remark.save()
+            return HttpResponseRedirect('/VGM/' + str(motion.VGM.id) +
+                                        '/#motion_id' + str(motion.id))
+        else:
+            errormessage = 'The form was invalidly filled.'
+            return render(request, 'scipost/error.html', {'errormessage': errormessage})
+    else:
+        errormessage = 'This view can only be posted to.'
+        return render(request, 'scipost/error.html', {'errormessage': errormessage})
+
+
+@login_required
+@permission_required('scipost.can_attend_VGMs', raise_exception=True)
+def vote_on_motion(request, motion_id, vote):
+    contributor = request.user.contributor
+    motion = get_object_or_404(Motion, pk=motion_id)
+    if timezone.now() > motion.voting_deadline:
+        errormessage = 'The voting deadline on this motion has passed.'
+        return render(request, 'scipost/error.html', {'errormessage': errormessage})
+    motion.update_votes(contributor.id, vote)
+    return HttpResponseRedirect('/VGM/' + str(motion.VGM.id) +
+                                '/#motion_id' + str(motion.id))