diff --git a/project_tier/exercises/migrations/0008_auto_20181105_1140.py b/project_tier/exercises/migrations/0008_auto_20181105_1140.py new file mode 100644 index 00000000..5341de82 --- /dev/null +++ b/project_tier/exercises/migrations/0008_auto_20181105_1140.py @@ -0,0 +1,33 @@ +# Generated by Django 2.0.4 on 2018-11-05 16:40 + +from django.db import migrations, models +import django.db.models.deletion +import modelcluster.contrib.taggit +import modelcluster.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('taggit', '0002_auto_20150616_2121'), + ('exercises', '0007_exerciseindexpage_notes'), + ] + + operations = [ + migrations.CreateModel( + name='SoftwareTag', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='software_tags_relationship', to='exercises.ExercisePage')), + ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exercises_softwaretag_items', to='taggit.Tag')), + ], + options={ + 'abstract': False, + }, + ), + migrations.AddField( + model_name='exercisepage', + name='software_tags', + field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', related_name='+', through='exercises.SoftwareTag', to='taggit.Tag', verbose_name='software tags'), + ), + ] diff --git a/project_tier/exercises/models.py b/project_tier/exercises/models.py index 64eb361c..4e5a02b2 100644 --- a/project_tier/exercises/models.py +++ b/project_tier/exercises/models.py @@ -32,6 +32,7 @@ changing the actual tagging API within Wagtail or django-taggit. """ + class DisciplineTag(TaggedItemBase): content_object = ParentalKey( 'exercises.ExercisePage', @@ -59,6 +60,15 @@ class ProtocolTag(TaggedItemBase): ) +class SoftwareTag(TaggedItemBase): + content_object = ParentalKey( + 'exercises.ExercisePage', + # django-modelcluster requires this to be set + related_name='software_tags_relationship', + on_delete=models.CASCADE + ) + + class ExercisePage(Page): cover_sheet = models.ForeignKey( 'wagtaildocs.Document', @@ -120,6 +130,13 @@ class ExercisePage(Page): blank=True, verbose_name="protocol tags" ) + software_tags = ClusterTaggableManager( + through=SoftwareTag, + # disabling reverse accessors solves a naming clash + related_name="+", + blank=True, + verbose_name="software tags" + ) parent_page_types = ['exercises.ExerciseIndexPage'] @@ -130,6 +147,7 @@ class ExercisePage(Page): FieldPanel('discipline_tags'), FieldPanel('course_level_tags'), FieldPanel('protocol_tags'), + FieldPanel('software_tags'), ], heading="tags", ), @@ -170,13 +188,16 @@ def get_context(self, request): exercises_courseleveltag_items__isnull=False).distinct() context['protocol_tags'] = Tag.objects.filter( exercises_protocoltag_items__isnull=False).distinct() + context['software_tags'] = Tag.objects.filter( + exercises_softwaretag_items__isnull=False).distinct() # Filters exercises by the tag name in the URL tag_groups = [ # (The name in the URL, the name of the Python model attribute) ('disciplines', 'discipline'), ('course-levels', 'course_level'), - ('protocols', 'protocol') + ('protocols', 'protocol'), + ('softwares', 'software'), ] # Loop through the given tag groups from above for tag_group in tag_groups: diff --git a/project_tier/exercises/templates/exercises/exercise_index_page.html b/project_tier/exercises/templates/exercises/exercise_index_page.html index 6d9697c4..64f57061 100644 --- a/project_tier/exercises/templates/exercises/exercise_index_page.html +++ b/project_tier/exercises/templates/exercises/exercise_index_page.html @@ -54,6 +54,20 @@
Protocol
{% endif %} + {% if software_tags %} +
+
Software
+ {% for tag in software_tags %} +
+ +
+ {% endfor %} +
+ {% endif %} + {% if results.filtered %} Clear filters @@ -88,6 +102,12 @@
Protocol
{% endfor %} {% endif %} + {% if software_tags_checked %} + {% for tag in software_tags_checked %} + {{ tag }} + {% endfor %} + {% endif %} +
Clear all filters

@@ -118,6 +138,9 @@

{{ exercise.title }}

{% for tag in exercise.specific.protocol_tags.all %} {{ tag }} {% endfor %} + {% for tag in exercise.specific.software_tags.all %} + {{ tag }} + {% endfor %}

{{ exercise.specific.listing_excerpt|truncatechars_html:100 }}

diff --git a/project_tier/static/js/filters.js b/project_tier/static/js/filters.js index 372ee500..a52dceab 100644 --- a/project_tier/static/js/filters.js +++ b/project_tier/static/js/filters.js @@ -16,7 +16,7 @@ function serializeFilters() { var tags = $('.exercise-filter input[type="checkbox"]:checked'); // Loop each tag type and build the query string var queryString = '?'; - var tagTypes = ['disciplines', 'course-levels', 'protocols']; + var tagTypes = ['disciplines', 'course-levels', 'protocols', 'softwares']; for(var i=0; i