Skip to content

Commit

Permalink
✨(frontend) add faqs to a category and get from a course
Browse files Browse the repository at this point in the history
- add course_faq placeholder to category detail page
- get the course_faq placeholder from the course detail page using the category reverse_id page
  • Loading branch information
Tiago-Salles committed Oct 24, 2024
1 parent 1bf03e4 commit d8391d3
Show file tree
Hide file tree
Showing 6 changed files with 509 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/richie/apps/courses/settings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,11 @@ def richie_placeholder_conf(name):
"plugins": ["CKEditorPlugin"],
"limits": {"CKEditorPlugin": 1},
},
"courses/cms/category_detail.html course_faq": {
"name": _("Faq"),
"plugins": ["NestedItemPlugin"],
"child_classes": {"NestedItemPlugin": ["NestedItemPlugin"]},
},
# Person detail
"courses/cms/person_detail.html categories": {
"name": _("Categories"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,15 @@ <h2 class="category-detail__title">{% trans "Related blogposts" %}</h2>
{% endif %}
{% endwith %}

<div id="page{{ page_suffix }}" class="category-detail__course_faq category-detail__block">
<div class="category-detail__row">
<h2 class="category-detail__title">{% trans "Category FAQ's" %}</h2>
{% placeholder "course_faq" or %}
<p class="category-detail__empty">{% trans 'Enter a FAQ for this category' %}</p>
{% endplaceholder %}
</div>
</div>

{% with persons=category.get_persons %}
{% if persons %}
{% autopaginate persons GLIMPSE_PAGINATION_PERSONS %}
Expand Down
18 changes: 18 additions & 0 deletions src/richie/apps/courses/templates/courses/cms/course_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,24 @@ <h2 class="course-detail__title">
{% endif %}
{% endblock team %}

{% block course_faq %}
{% get_categories_pages_have_faqs current_page.course as pages_have_faqs %}
{% if pages_have_faqs %}
<div class="course-detail__faqs course-detail__block course-detail__row">
{% with is_syllabus_property=True %}
<h2 class="course-detail__title">{% blocktrans context "course_detail__title" %}Crucial information{% endblocktrans %}</h2>

{% for page in pages_have_faqs %}
{% with reverse_id=page.reverse_id %}
<h3 class="course-detail__faq_title">{{ page.get_title }}</h3>
{% show_placeholder "course_faq" reverse_id %}
{% endwith %}
{% endfor %}
{% endwith %}
</div>
{% endif %}
{% endblock course_faq %}

{% block organizations %}
{% if current_page.publisher_is_draft or not current_page|is_empty_placeholder:"course_organizations" %}
<div class="course-detail__organizations course-detail__block">
Expand Down
33 changes: 33 additions & 0 deletions src/richie/apps/courses/templatetags/extra_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from classytags.arguments import Argument, MultiValueArgument
from classytags.core import Options, Tag
from classytags.utils import flatten_context
from cms.api import Page
from cms.templatetags.cms_tags import (
Placeholder,
PlaceholderOptions,
Expand All @@ -23,6 +24,8 @@
from cms.utils.plugins import get_plugins

from richie.apps.courses.defaults import RICHIE_MAX_ARCHIVED_COURSE_RUNS
from richie.apps.courses.models.category import Category
from richie.apps.courses.models.course import Course

from ..lms import LMSHandler
from ..models import CourseRunCatalogVisibility
Expand Down Expand Up @@ -271,6 +274,36 @@ def joanie_product_widget_props(context):
return json.dumps({"productId": product_id, "courseCode": course_code})


@register.simple_tag()
def get_categories_pages_have_faqs(course: Course) -> list[Page]:
"""
Return a list with all pages have faq
usage: `{% get_categories_pages_have_faqs current_page.course as pages_have_faqs %}`
"""

categories_pages: list[Category] = course.get_categories()
categories_pages = categories_pages.filter(
extended_object__reverse_id__isnull=False
)

categories_with_faq: list[Category] = []
for category in categories_pages:
plugins = (
category.extended_object.get_placeholders()
.get(slot="course_faq")
.get_plugins()
)
if len(plugins) > 0:
categories_with_faq.append(category)

pages_have_faq: list[Page] = [
category.extended_object for category in categories_with_faq
]

return pages_have_faq


@register.simple_tag(takes_context=True)
def course_runs_list_widget_props(context):
"""
Expand Down
70 changes: 70 additions & 0 deletions tests/apps/courses/test_templates_category_detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
OrganizationFactory,
PersonFactory,
)
from richie.plugins.nesteditem.defaults import ACCORDION


class CategoryCMSTestCase(CMSTestCase):
Expand Down Expand Up @@ -553,3 +554,72 @@ def test_template_category_detail_meta_description_empty(self):
response,
'<meta name="description"',
)

def test_template_category_detail_has_course_faq(self):
"""
Validates the creation of FAQ's for a category and its content
"""

faq_quantity = 3
category = CategoryFactory.create(page_title="Accessible", should_publish=True)
placeholder = category.extended_object.placeholders.get(slot="course_faq")
container = add_plugin(
language="en",
placeholder=placeholder,
plugin_type="NestedItemPlugin",
variant=ACCORDION,
)

for question in range(1, faq_quantity):
question_container = add_plugin(
language="en",
placeholder=placeholder,
plugin_type="NestedItemPlugin",
target=container,
content=f"{question}. question?",
variant=ACCORDION,
)

add_plugin(
language="en",
placeholder=placeholder,
plugin_type="NestedItemPlugin",
target=question_container,
content=f"Answer of question {question}.",
variant=ACCORDION,
)

page = category.get_page()
page.publish("en")
url = page.get_absolute_url()
response = self.client.get(url)

self.assertEqual(response.status_code, 200)
self.assertContains(
response, '<h2 class="category-detail__title">Category FAQ\'s</h2>'
)

for question in range(1, faq_quantity):
self.assertContains(response, f"{question}. question?")
self.assertContains(response, f"Answer of question {question}.")

def test_template_category_detail_empty_course_faq(self):
"""
Validates when a category does not have FAQ's it renders a message indicating
"""

category = CategoryFactory.create(page_title="Accessible", should_publish=True)

page = category.get_page()
page.publish("en")
url = page.get_absolute_url()
response = self.client.get(url)

self.assertEqual(response.status_code, 200)
self.assertContains(
response, '<h2 class="category-detail__title">Category FAQ\'s</h2>'
)
self.assertContains(
response,
'<p class="category-detail__empty">Enter a FAQ for this category</p>',
)
Loading

0 comments on commit d8391d3

Please sign in to comment.