diff --git a/commentaries/forms.py b/commentaries/forms.py
index fc65f77015fcbae50435bb230d9e1366cd75ae5d..c1626ab06f3d05be4a47a7401dfebaa765a2ca24 100644
--- a/commentaries/forms.py
+++ b/commentaries/forms.py
@@ -36,3 +36,4 @@ class CommentarySearchForm(forms.Form):
     pub_author = forms.CharField(max_length=100, required=False, label="Author(s)")
     pub_title_keyword = forms.CharField(max_length=100, label="Title", required=False)
     pub_abstract_keyword = forms.CharField(max_length=1000, required=False, label="Abstract")
+
diff --git a/commentaries/templates/commentaries/commentary_detail.html b/commentaries/templates/commentaries/commentary_detail.html
index f4af2c987b372f976b6a4ba00575c1695bd2e25f..45376a36e11dcfe21ea0f28d2e58db3374e98a7e 100644
--- a/commentaries/templates/commentaries/commentary_detail.html
+++ b/commentaries/templates/commentaries/commentary_detail.html
@@ -79,6 +79,17 @@
 	    {% if comment.is_sug %}<li>suggestion for further work</li>{% endif %}
 	  </ul>
 	</div>
+	<br/>
+	<div class="opinionsDisplay">
+	  {% if user.is_authenticated and user.contributor.rank > 0 %}
+	  <form action="{% url 'comments:express_opinion' comment.id %}" method="post">
+	    {% csrf_token %}
+	    {{ opinion_form }}
+	    <input type="submit" value="Submit"/>
+	  </form>
+	  {% endif %}
+	  {{ comment.opinions_as_ul|safe }}
+	</div>
       </div>
 
     </div>
diff --git a/commentaries/views.py b/commentaries/views.py
index 5c7c913cc38ee9c3249f5f052944865e3fb1dc36..518c7f5c75b00d25958bfecc5e70c92909e9a5d3 100644
--- a/commentaries/views.py
+++ b/commentaries/views.py
@@ -14,7 +14,8 @@ from .forms import *
 
 from comments.models import Comment, AuthorReply
 from comments.forms import CommentForm
-from scipost.forms import TITLE_CHOICES, AuthenticationForm
+from scipost.forms import TITLE_CHOICES, AuthenticationForm, OpinionForm
+
 
 title_dict = dict(TITLE_CHOICES) # Convert titles for use in emails
 
@@ -179,5 +180,6 @@ def commentary_detail(request, commentary_id):
         author_replies = AuthorReply.objects.filter(commentary=commentary)
     except AuthorReply.DoesNotExist:
         author_replies = ()
-    context = {'commentary': commentary, 'comments': comments.filter(status__gte=1).order_by('date_submitted'), 'author_replies': author_replies, 'form': form}
+    opinion_form = OpinionForm()
+    context = {'commentary': commentary, 'comments': comments.filter(status__gte=1).order_by('date_submitted'), 'author_replies': author_replies, 'form': form, 'opinion_form': opinion_form}
     return render(request, 'commentaries/commentary_detail.html', context)
diff --git a/comments/models.py b/comments/models.py
index 39e44a3ac0c1b0ba57a72f18c9891284aab99712..74a89b0071fa138a75668f0906a9bdeb9a24b800 100644
--- a/comments/models.py
+++ b/comments/models.py
@@ -11,7 +11,7 @@ from .models import *
 #from submissions.models import *
 
 from commentaries.models import Commentary
-from scipost.models import Contributor
+from scipost.models import Contributor, Opinion
 from submissions.models import Submission, Report
 from theses.models import ThesisLink
 
@@ -62,11 +62,32 @@ class Comment(models.Model):
     comment_text = models.TextField()
     remarks_for_editors = models.TextField(default='', blank=True, verbose_name='optional remarks for the Editors only')
     date_submitted = models.DateTimeField('date submitted')
-
+    # Opinions 
+    nr_FA = models.PositiveIntegerField(default=0)
+    nr_MA = models.PositiveIntegerField(default=0)
+    nr_DIS = models.PositiveIntegerField(default=0)
+    nr_OBJ = models.PositiveIntegerField(default=0)
 
     def __str__ (self):
         return self.comment_text
 
+    def recalculate_nr_opinions(self):
+        self.nr_FA = Opinion.objects.filter(comment=self, opinion='FA').count()
+        self.nr_MA = Opinion.objects.filter(comment=self, opinion='MA').count()
+        self.nr_DIS = Opinion.objects.filter(comment=self, opinion='DIS').count()
+        self.nr_OBJ = Opinion.objects.filter(comment=self, opinion='OBJ').count()
+        self.save()
+
+    def opinions_as_ul(self):
+        output = '<div class="opinionsDisplay"><ul>'
+        output += '<li>Fully agree: ' + str(self.nr_FA) + '</li>'
+        output += '<li>Mostly agree: ' + str(self.nr_MA) + '</li>'
+        output += '<li>Disagree: ' + str(self.nr_DIS) + '</li>'
+        output += '<li>Object: ' + str(self.nr_OBJ) + '</li>'
+        output += '</ul></div>'
+        return output
+
+
     def print_identifier (self):
         output = '<div class="commentid">\n'
         output += '<h3><a id="comment_id' + str(self.id) + '">' + str(self.id) + '</a>'
@@ -96,7 +117,7 @@ class Comment(models.Model):
             header += ' in commentary on <a href="/commentaries/commentary/' + str(self.commentary.id) + '" class="pubtitleli">' + self.commentary.pub_title + '</a> by ' + self.commentary.author_list + '</p></div>'
         if self.thesislink is not None:
             header += '<a href="/theses/thesis/' + str(self.thesislink.id) + '#comment_id' + str(self.id) + '"> \"' + text_cut + '\"</a><p>submitted on ' + self.date_submitted.strftime("%Y-%m-%d")
-            header += ' in thesislink on <a href="/theses/thesis/' + str(self.thesislink.id) + '" class="pubtitleli">' + self.thesislink.pub_title + '</a> by ' + self.thesislink.author_list + '</p></div>'
+            header += ' in thesislink on <a href="/theses/thesis/' + str(self.thesislink.id) + '" class="pubtitleli">' + self.thesislink.title + '</a> by ' + self.thesislink.author + '</p></div>'
         header += '</div></li>'
         return header
 
diff --git a/comments/urls.py b/comments/urls.py
index 9312a6e2f14f955aa17b8978285b8209028acf1f..68a74fcbfa7fea3b8b3c23bdfe1255e3138091fe 100644
--- a/comments/urls.py
+++ b/comments/urls.py
@@ -13,4 +13,5 @@ urlpatterns = [
     url(r'^author_reply_to_report/(?P<report_id>[0-9]+)$', views.author_reply_to_report, name='author_reply_to_report'),
     url(r'^vet_author_replies$', views.vet_author_replies, name='vet_author_replies'),
     url(r'^vet_author_reply_ack/(?P<reply_id>[0-9]+)$', views.vet_author_reply_ack, name='vet_author_reply_ack'),
+    url(r'^express_opinion/(?P<comment_id>[0-9]+)$', views.express_opinion, name='express_opinion'),
 ]
diff --git a/comments/views.py b/comments/views.py
index cbd16f44a49c25b879ab6fef72ffbcf90d1b4483..c4b43b2b635f0f7b88517cb8feed5068908f388a 100644
--- a/comments/views.py
+++ b/comments/views.py
@@ -12,7 +12,8 @@ from django.db.models import Avg
 from .models import *
 from .forms import *
 
-from scipost.models import title_dict
+from scipost.models import title_dict, Opinion
+from scipost.forms import OpinionForm
 
 
 def vet_submitted_comments(request):
@@ -190,3 +191,24 @@ def vet_author_reply_ack(request, reply_id):
     return render(request, 'comments/vet_author_reply_ack.html', context)
 
 
+def express_opinion(request, comment_id):
+    # A contributor has expressed an opinion on a comment
+    contributor = request.user.contributor
+    comment = get_object_or_404(Comment, pk=comment_id)
+    if request.method == 'POST':
+        opinion_form = OpinionForm(request.POST)
+        if opinion_form.is_valid():
+            # delete any previous opinion on this by this contributor
+            Opinion.objects.filter(rater=contributor, comment=comment).delete()
+            newopinion = Opinion(rater=request.user.contributor, comment=comment, opinion=opinion_form.cleaned_data['opinion'])
+            newopinion.save()
+            comment.recalculate_nr_opinions()
+            if comment.submission is not None:
+                return HttpResponseRedirect('/submissions/submission/' + str(comment.submission.id) + '/#comment_id' + str(comment.id))
+            if comment.commentary is not None:
+                return HttpResponseRedirect('/commentaries/commentary/' + str(comment.commentary.id) + '/#comment_id' + str(comment.id))
+            if comment.thesislink is not None:
+                return HttpResponseRedirect('/theses/thesis/' + str(comment.thesislink.id) + '/#comment_id' + str(comment.id))
+    else: 
+        # will never call this
+        return(render(request, 'scipost/index.html'))
diff --git a/scipost/admin.py b/scipost/admin.py
index db488d7cafea8ca1de0456e4d6d6e3253ba66ec1..e81d84d5fe4ba3fa9ea2d77a27dd20e1a881f3d6 100644
--- a/scipost/admin.py
+++ b/scipost/admin.py
@@ -3,7 +3,7 @@ from django.contrib import admin
 from django.contrib.auth.admin import UserAdmin
 from django.contrib.auth.models import User
 
-from scipost.models import Contributor
+from scipost.models import Contributor, Opinion
 
 class ContributorInline(admin.StackedInline):
 #class ContributorInline(admin.TabularInline):
@@ -18,3 +18,5 @@ admin.site.unregister(User)
 admin.site.register(User, UserAdmin)
 
 #admin.site.register(Contributor)
+
+admin.site.register(Opinion)
diff --git a/scipost/forms.py b/scipost/forms.py
index 7381e0fb2b5833ad142910dae3be8a24ddd96472..fb5126aa27592b0c9d126cb52afe1e33d5ea727d 100644
--- a/scipost/forms.py
+++ b/scipost/forms.py
@@ -61,6 +61,10 @@ class PasswordChangeForm(forms.Form):
     password_verif = forms.CharField(label='Reenter new password', widget=forms.PasswordInput())
 
 
+class OpinionForm(forms.Form):
+    opinion = forms.ChoiceField(choices=OPINION_CHOICES, label='Your opinion on this Comment: ')
+
+
 class AssessmentForm(forms.ModelForm):
     class Meta:
         model = Assessment
diff --git a/scipost/models.py b/scipost/models.py
index 2d50923dd7ba6d2656086ccf921754d630ac932e..9b0a0dbe1daed821c384bffd55ec902b4f0d0bf9 100644
--- a/scipost/models.py
+++ b/scipost/models.py
@@ -112,6 +112,24 @@ class Assessment(models.Model):
     significance = models.PositiveSmallIntegerField(choices=ASSESSMENT_CHOICES, default=101)
 
 
+
+### Opinions
+
+OPINION_CHOICES = (
+    ('ABS', '-'),
+    ('FA', 'I fully agree'),
+    ('MA', 'I mostly agree'),
+    ('DIS', 'I disagree'),
+    ('OBJ', 'I object to this'),
+)
+opinion_choices_dict = dict(OPINION_CHOICES)
+
+class Opinion(models.Model):
+    rater = models.ForeignKey(Contributor)
+    comment = models.ForeignKey('comments.Comment')
+    opinion = models.CharField(max_length=3, choices=OPINION_CHOICES, default='ABS')
+
+
 ### AssessmentAggregates
 
 class AssessmentAggregate(models.Model):
diff --git a/scipost/static/scipost/SciPost.css b/scipost/static/scipost/SciPost.css
index a797ca6c69e8d99556da3870a11e65795292d474..c0eefa2800334277bd2e9cbcb3d4f9ecb538c129 100644
--- a/scipost/static/scipost/SciPost.css
+++ b/scipost/static/scipost/SciPost.css
@@ -469,6 +469,30 @@ section form.ratingsdata ul li label {
   color: #ffffff;
 }
 
+.opinionsDisplay {
+  margin: 0px 4px;
+  padding: 1px;
+  display: inline-block;
+  box-shadow: 1px 1px 3px #888888;
+  background: linear-gradient(to right,#fcfcfc, #f0f0f0);
+  font-size: 90%;
+}
+.opinionsDisplay form {
+  display: inline-block;
+}
+.opinionsDisplay ul {
+  border-radius: 2px;
+  color: #ffffff;
+  display: inline-block;
+  margin: 0px;
+  padding: 2px;
+}
+.opinionsDisplay li {
+  display: inline-block;
+  background-color: #204080;
+  margin: 1px 3px;
+  padding: 2px 4px;
+}
 
 article {
   background-color:#eeeeee;
diff --git a/submissions/templates/submissions/submission_detail.html b/submissions/templates/submissions/submission_detail.html
index 0ec0f44eb568059cb8b305fb06649a3b36372444..3e0207afce63e1570f36fd802816314dc6e2aecb 100644
--- a/submissions/templates/submissions/submission_detail.html
+++ b/submissions/templates/submissions/submission_detail.html
@@ -168,6 +168,17 @@
             {% if comment.is_sug %}<li>suggestion for further work</li>{% endif %}
           </ul>
         </div>
+        <br/>
+        <div class="opinionsDisplay">
+          {% if user.is_authenticated and user.contributor.rank > 0 %}
+          <form action="{% url 'comments:express_opinion' comment.id %}" method="post">
+            {% csrf_token %}
+            {{ opinion_form }}
+            <input type="submit" value="Submit"/>
+          </form>
+          {% endif %}
+          {{ comment.opinions_as_ul|safe }}
+        </div>
       </div>
     </div>
     
diff --git a/submissions/views.py b/submissions/views.py
index a518a5a2e3f40e8c22d3e831ce3851e0a45b035b..01f6b949f3f674df81031c128b61c800db4bf505 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -14,6 +14,7 @@ from .forms import *
 
 from comments.models import Comment, AuthorReply
 from scipost.models import Contributor, title_dict
+from scipost.forms import OpinionForm
 from submissions.models import Submission
 
 from comments.forms import CommentForm
@@ -153,7 +154,8 @@ def submission_detail(request, submission_id):
         author_replies = AuthorReply.objects.filter(submission=submission)
     except AuthorReply.DoesNotExist:
         author_replies = ()
-    context = {'submission': submission, 'comments': comments.filter(status__gte=1).order_by('date_submitted'), 'reports': reports.filter(status__gte=1), 'author_replies': author_replies, 'form': form}
+    opinion_form = OpinionForm()
+    context = {'submission': submission, 'comments': comments.filter(status__gte=1).order_by('date_submitted'), 'reports': reports.filter(status__gte=1), 'author_replies': author_replies, 'form': form, 'opinion_form': opinion_form}
     return render(request, 'submissions/submission_detail.html', context)
 
 
diff --git a/theses/templates/theses/thesis_detail.html b/theses/templates/theses/thesis_detail.html
index 6b98eed7a48b9a6981087016c8efd4d6e2e83b0b..1f34666d714e9dea79636e4709cae428d3c17115 100644
--- a/theses/templates/theses/thesis_detail.html
+++ b/theses/templates/theses/thesis_detail.html
@@ -70,6 +70,17 @@
 	    {% if comment.is_sug %}<li>suggestion for further work</li>{% endif %}
 	  </ul>
 	</div>
+        <br/>
+        <div class="opinionsDisplay">
+          {% if user.is_authenticated and user.contributor.rank > 0 %}
+          <form action="{% url 'comments:express_opinion' comment.id %}" method="post">
+            {% csrf_token %}
+            {{ opinion_form }}
+            <input type="submit" value="Submit"/>
+          </form>
+          {% endif %}
+          {{ comment.opinions_as_ul|safe }}
+        </div>
       </div>
 
     </div>
diff --git a/theses/views.py b/theses/views.py
index 975422ebe44d1c3c37b68037407d683ae1292591..811a0766fb4fc4ced8f13aa7e0644fafe4405d83 100644
--- a/theses/views.py
+++ b/theses/views.py
@@ -14,7 +14,7 @@ from .forms import *
 
 from comments.models import Comment, AuthorReply
 from comments.forms import CommentForm
-from scipost.forms import TITLE_CHOICES, AuthenticationForm
+from scipost.forms import TITLE_CHOICES, AuthenticationForm, OpinionForm
 
 title_dict = dict(TITLE_CHOICES) # Convert titles for use in emails
 
@@ -179,5 +179,6 @@ def thesis_detail(request, thesislink_id):
         author_replies = AuthorReply.objects.filter(thesislink=thesislink)
     except AuthorReply.DoesNotExist:
         author_replies = ()
-    context = {'thesislink': thesislink, 'comments': comments.filter(status__gte=1).order_by('date_submitted'), 'author_replies': author_replies, 'form': form}
+    opinion_form = OpinionForm()
+    context = {'thesislink': thesislink, 'comments': comments.filter(status__gte=1).order_by('date_submitted'), 'author_replies': author_replies, 'form': form, 'opinion_form': opinion_form}
     return render(request, 'theses/thesis_detail.html', context)