Skip to content

Commit 0a51cde

Browse files
authored
Merge pull request #32 from DataManagementLab/#2_Frontend/Content_Allow_to_add_contents
#2 frontend/content allow to add contents
2 parents d153eb2 + 039f395 commit 0a51cde

10 files changed

Lines changed: 251 additions & 42 deletions

File tree

content/forms.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from django import forms
2+
from content.models import YTVideoContent, ImageContent
3+
4+
5+
class AddContentFormYoutubeVideo(forms.ModelForm):
6+
class Meta:
7+
model = YTVideoContent
8+
exclude = ['content']
9+
10+
11+
class AddContentFormImage(forms.ModelForm):
12+
class Meta:
13+
model = ImageContent
14+
exclude = ['content']
15+
16+
17+
CONTENT_TYPE_FORMS = {
18+
YTVideoContent.TYPE: AddContentFormYoutubeVideo,
19+
ImageContent.TYPE: AddContentFormImage,
20+
}

frontend/forms/addcontent.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from django import forms
2+
from base.models.content import Content
3+
from content.models import YTVideoContent, ImageContent
4+
5+
6+
class AddContentForm(forms.ModelForm):
7+
"""
8+
The Form for adding new content to a topic
9+
"""
10+
class Meta: # pylint: disable=too-few-public-methods
11+
model = Content
12+
exclude = ['topic', 'author', 'creation_date', 'ratings', 'preview', 'type']

frontend/locale/de_DE/LC_MESSAGES/django.po

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,27 +33,40 @@ msgstr "Diese Software ist Open Source"
3333
msgid "Are you sure you want to delete the following comment?"
3434
msgstr "Soll der folgende Kommentar wirklich gelöscht werden?"
3535

36+
#: frontend/templates/frontend/content/addcontent.html:23
37+
#: frontend/templates/frontend/course/create.html:29
38+
msgid "Create"
39+
msgstr "Erzeugen"
40+
41+
#: frontend/templates/frontend/content/addcontent.html:24
42+
#: frontend/templates/frontend/content/detail.html:80
43+
#: frontend/templates/frontend/course/create.html:30
44+
#: frontend/templates/frontend/profile/profile_edit.html:19
45+
msgid "Cancel"
46+
msgstr "Abbrechen"
47+
3648
#: frontend/templates/frontend/content/detail.html:18
49+
#: frontend/templates/frontend/course/view.html:25
3750
msgid "Actions"
3851
msgstr "Aktionen"
3952

40-
#: frontend/templates/frontend/content/detail.html:46
53+
#: frontend/templates/frontend/content/detail.html:43
4154
msgid "Back to course "
4255
msgstr "Zurück zum Kurs "
4356

44-
#: frontend/templates/frontend/content/detail.html:52
57+
#: frontend/templates/frontend/content/detail.html:49
4558
msgid "By"
4659
msgstr "Von"
4760

48-
#: frontend/templates/frontend/content/detail.html:62
61+
#: frontend/templates/frontend/content/detail.html:59
4962
msgid "Created at"
5063
msgstr "Erstellt am"
5164

52-
#: frontend/templates/frontend/content/detail.html:70
65+
#: frontend/templates/frontend/content/detail.html:67
5366
msgid "Delete"
5467
msgstr "Löschen"
5568

56-
#: frontend/templates/frontend/content/detail.html:74
69+
#: frontend/templates/frontend/content/detail.html:71
5770
#, python-format
5871
msgid ""
5972
"\n"
@@ -67,43 +80,31 @@ msgstr ""
6780
" "
6881

6982
#: frontend/templates/frontend/content/detail.html:83
70-
#: frontend/templates/frontend/course/create.html:30
71-
#: frontend/templates/frontend/profile/profile_edit.html:19
72-
msgid "Cancel"
73-
msgstr "Abbrechen"
74-
75-
#: frontend/templates/frontend/content/detail.html:86
7683
msgid "Confirm"
7784
msgstr "Bestätigen"
7885

79-
#: frontend/templates/frontend/content/detail.html:102
86+
#: frontend/templates/frontend/content/detail.html:99
8087
#: frontend/templates/frontend/course/topic_contents.html:29
8188
msgid "Rating"
8289
msgstr "Bewertung"
8390

84-
#: frontend/templates/frontend/content/detail.html:112
91+
#: frontend/templates/frontend/content/detail.html:109
8592
msgid "Comments"
8693
msgstr "Kommentare"
8794

88-
#: frontend/templates/frontend/content/detail.html:118
95+
#: frontend/templates/frontend/content/detail.html:115
8996
msgid "Add comment"
9097
msgstr "Kommentar hinzufügen"
9198

9299
#: frontend/templates/frontend/course/create.html:11
93100
msgid "Create a new course"
94101
msgstr "Neuen Kurs anlegen"
95102

96-
#: frontend/templates/frontend/course/create.html:29
97-
msgid "Create"
98-
msgstr "Erzeugen"
99-
100-
#: frontend/templates/frontend/course/view.html:26
101-
#: frontend/templates/frontend/course/view_course.html:36
102-
msgid "Delete Course"
103-
msgstr "Kurs löschen"
103+
#: frontend/templates/frontend/course/dropdown_topic.html:10
104+
msgid "Add Content"
105+
msgstr "Inhalte hinzufügen"
104106

105-
#: frontend/templates/frontend/course/view.html:62
106-
#: frontend/templates/frontend/course/view_course.html:58
107+
#: frontend/templates/frontend/course/view.html:78
107108
msgid "No topics yet"
108109
msgstr "Bisher keine Themen"
109110

@@ -223,10 +224,21 @@ msgstr "Kommentar erfolgreich gelöscht."
223224
msgid "Successfully edited Comment."
224225
msgstr "Kommentar erfolgreich bearbeitet."
225226

227+
#: frontend/views/content.py:28
228+
msgid "Content '{cleaned_data['type']}' successfully added"
229+
msgstr "Inhalt '{cleaned_data['type']}' erfolgreich hinzugefügt"
230+
231+
#: frontend/views/content.py:35
232+
msgid "An error occurred while processing the request"
233+
msgstr "Es trat ein Fehler beim Verarbeiten der Anfrage auf"
234+
226235
#: frontend/views/course.py:26
227236
msgid "Course '{cleaned_data['title']}' successfully created"
228237
msgstr "Kurs '{cleaned_data['title']}' erfolgreich angelegt"
229238

230-
#: frontend/views/profile.py:26
239+
#: frontend/views/profile.py:25
231240
msgid "Profile updated"
232241
msgstr "Profil aktualisiert"
242+
243+
#~ msgid "Delete Course"
244+
#~ msgstr "Kurs löschen"
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{% extends 'frontend/base_logged_in.html' %}
2+
3+
{# Load the tag library #}
4+
{% load bootstrap4 %}
5+
{% load cc_frontend_tags %}
6+
{% load fontawesome_5 %}
7+
{% load static %}
8+
{% load i18n %}
9+
10+
{% block imports %}
11+
<link href="{% static 'css/content_detail.css' %}" type="text/css" rel="stylesheet"/>
12+
{% endblock %}
13+
14+
{% block content %}
15+
<form method="post" enctype=multipart/form-data>
16+
{% csrf_token %}
17+
{% bootstrap_form form %}
18+
{% bootstrap_form content_type_form %}
19+
20+
{{ form.media }}
21+
<div>
22+
23+
<button type="submit" class="btn btn-primary float-right">{% fa5_icon 'plus-circle' 'fas' %} {% trans "Create" %}</button>
24+
<a href="{% url 'frontend:dashboard' %}" class="btn btn-danger">{% fa5_icon 'times' 'fas' %} {% trans "Cancel" %}</a>
25+
</div>
26+
27+
</form>
28+
{% endblock %}

frontend/templates/frontend/content/detail.html

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,9 @@
2323
{# url 'readingmode' course.id topic.id content.id #}{% if ending %}{{ ending }}{% endif %}">{% fa5_icon 'eye' 'far' %}
2424
Reading Mode</a>
2525
{% if user.is_authenticated %}
26-
<a class="dropdown-item" href="{# url 'favourite_content' course.id topic.id content.id #}?onDetailPage=True">
27-
{% if favourite %}{% fa5_icon 'bookmark' 'fas' %} Unsave {% else %}{% fa5_icon 'bookmark' 'far' %} Save{% endif %}</a>
28-
<div class="dropdown-divider"></div>
29-
{% if markdown %}
26+
{% if content.type|is_content_editable %}
3027
<a class="dropdown-item"
31-
href="{% url 'edit_md_file' course.id topic.id content.id %}">{% fa5_icon 'pencil-alt' 'fas' %}
28+
href="{#{% url 'edit_md_file' course.id topic.id content.id %}#}">{% fa5_icon 'pencil-alt' 'fas' %}
3229
Edit</a>
3330

3431
{% endif %}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{% load i18n %}
2+
{# Load the tag library #}
3+
{% load bootstrap4 %}
4+
{% load fontawesome_5 %}
5+
{% load cc_frontend_tags %}
6+
7+
<div class="float-right text-right">
8+
<div class="dropdown show">
9+
<button class="btn btn-primary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
10+
{% trans "Add Content" %}
11+
</button>
12+
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuLink">
13+
{% if user.is_authenticated %}
14+
{% for content in content_data %}
15+
<a class="dropdown-item"
16+
href="{% url 'frontend:content-add' course_id=course_id topic_id=topic_id type=content.0 %}">{% trans content.1 %}</a>
17+
{% endfor %}
18+
{% endif %}
19+
</div>
20+
</div>
21+
</div>

frontend/templates/frontend/course/view.html

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,31 @@
1818

1919
{% block content %}
2020
<!-- Course markings and actions -->
21-
<div class="float-right">
22-
{% if course in user.profile.stared_courses.all %}
23-
{% fa5_icon 'bookmark' 'fas' %}
24-
{% endif %}
25-
{% if user.profile in course.owners.all %}
26-
<a href="{% url 'frontend:course-delete' pk=course.pk %}" class="btn btn-warning">{% fa5_icon "trash" "fas" %} {% trans "Delete Course" %}</a>
27-
{% endif %}
21+
22+
<div class="float-right text-right">
23+
<div class="dropdown show">
24+
<button class="btn btn-primary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
25+
{% trans "Actions" %}
26+
</button>
27+
28+
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuLink">
29+
{% if user.is_authenticated %}
30+
<a class="dropdown-item" href="{# url 'favourite_content' course.id topic.id content.id ?onDetailPage=True#}">
31+
{% if favourite %}{% fa5_icon 'bookmark' 'fas' %} Unsave {% else %}{% fa5_icon 'bookmark' 'far' %} Save{% endif %}</a>
32+
33+
<div class="dropdown-divider"></div>
34+
35+
{% if isCurrentUserOwner or user.is_superuser or content.author == user %}
36+
<a href="{% url 'frontend:course-delete' pk=course.pk %}" class="dropdown-item text-danger"
37+
>{% fa5_icon 'trash' 'fas' %} Delete</a>
38+
{% endif %}
39+
{% endif %}
40+
41+
</div>
42+
</div>
2843
</div>
2944

45+
3046
<!-- Course header: Title, owners, description -->
3147
<h1>{{ course.title }}</h1>
3248

@@ -73,14 +89,19 @@ <h5 style="margin-top: 20px;">
7389
{% for entry in structure %}
7490
<div style="margin-top: 30px;">
7591
{% with forloop.counter as outer_index %}
76-
<h3 class="text-info">{{ outer_index }}. {{ entry.topic.title }}</h3>
77-
92+
{% with entry.topic as topic_replace %}
93+
{% add_content_button user course.id topic_replace.id %}
94+
{% endwith %}
95+
<h3 class="text-info">{{ outer_index }}. {{ topic.title }}</h3>
7896
{% with entry.topic.contents.all as topic_contents %}
7997
{% include "frontend/course/topic_contents.html" %}
8098
{% endwith %}
8199
{% if entry.subtopics %}
82100
{% for subtopic in entry.subtopics %}
83101
<div style="margin-top: 15px;">
102+
{% with subtopic as topic_replace %}
103+
{% add_content_button user course.id topic_replace.id %}
104+
{% endwith %}
84105
<h4 class="text-info">{{ outer_index }}.{{ forloop.counter }}. {{ subtopic.title }}</h4>
85106
{% with subtopic.contents.all as topic_contents %}
86107
{% include "frontend/course/topic_contents.html" %}

frontend/templatetags/cc_frontend_tags.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,24 @@ def content_card(type):
8686
if type in CONTENT_TYPES.keys():
8787
return f"content/cards/{type}.html"
8888
return "content/cards/blank.html"
89+
90+
91+
@register.filter
92+
def is_content_editable(type):
93+
# TODO: implement check
94+
return False
95+
96+
97+
@register.inclusion_tag("frontend/course/dropdown_topic.html")
98+
def add_content_button(user, course_id, topic_id):
99+
"""
100+
generate dropdown-button containing list of available content types
101+
:param User user: the user
102+
:param int course_id: id of the course
103+
:param int topic_id: id of the topic
104+
:return: dropdown button as html div
105+
:rtype: dict
106+
"""
107+
# generate list of tuple (content type, content verbose name) for add content dropdown
108+
content_data = [(content_type, content_model.DESC) for content_type, content_model in CONTENT_TYPES.items()]
109+
return {'user': user, 'course_id': course_id, 'topic_id': topic_id, 'content_data': content_data}

frontend/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from django.urls import path, re_path, include
22

3+
from content.models import CONTENT_TYPES
34
from frontend import views
45

56
app_name = "frontend"
@@ -20,6 +21,7 @@
2021
path('delete/', views.CourseDeleteView.as_view(), name='course-delete'),
2122
])),
2223
path('<int:course_id>/topic/<int:topic_id>/content/', include([
24+
re_path(r'add/(?P<type>' + '|'.join([key for key in CONTENT_TYPES.keys()]) + ')/$', views.content.AddContentView.as_view(), name='content-add'),
2325
path('<int:content_id>/comment/<int:pk>/delete/', views.DeleteComment.as_view(), name='comment-delete'),
2426
path('<int:content_id>/comment/<int:pk>/edit/', views.EditComment.as_view(), name='comment-edit'),
2527
path('<pk>/', views.ContentView.as_view(), name='content'),

0 commit comments

Comments
 (0)