Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨(frontend) add faqs to a category and get them from a course #2517

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 %}
<div class="course-detail__faqs course-detail__block course-detail__row">
{% with is_syllabus_property=True %}
{% get_categories_pages_have_faqs current_page.course as pages_have_faqs %}
{% if pages_have_faqs %}
<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 %}
{% endif %}
{% endwith %}
</div>
{% 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
13 changes: 13 additions & 0 deletions src/richie/apps/courses/templatetags/extra_tags.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Custom template tags for the courses application of Richie."""

import json
from typing import List

from django import template
from django.conf import settings
Expand All @@ -21,8 +22,10 @@
from cms.toolbar.utils import get_toolbar_from_request
from cms.utils import get_site_id
from cms.utils.plugins import get_plugins
from cms.api import Page

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

from ..lms import LMSHandler
from ..models import CourseRunCatalogVisibility
Expand Down Expand Up @@ -270,6 +273,16 @@ 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
"""

categories_pages: list[Page] = course.get_root_to_leaf_public_category_pages().filter(reverse_id__isnull=False)
pages_have_faq: list[Page] = [page for page in categories_pages if not page.get_placeholders().get(slot="course_faq") is None]

return pages_have_faq

@register.simple_tag(takes_context=True)
def course_runs_list_widget_props(context):
Expand Down
38 changes: 38 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,40 @@ def test_template_category_detail_meta_description_empty(self):
response,
'<meta name="description"',
)

def test_template_category_detail_add_course_faq(self):
"""
Validate the creation of a FAQ for a category
"""

category = CategoryFactory()
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, 3):
question_container = add_plugin(
language="en",
placeholder=placeholder,
plugin_type="NestedItemPlugin",
target=container,
content=f"{question}. question?",
variant=ACCORDION,
)

for answer in range(1, 3):
add_plugin(
language="en",
placeholder=placeholder,
plugin_type="NestedItemPlugin",
target=question_container,
content=f"{question}.{answer} - Answer of question {question}.",
variant=ACCORDION,
)

url = category.extended_object.get_absolute_url()
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""Test suite for the get_categories_pages_have_faqs template tag."""

from django.db import transaction

from cms.api import add_plugin
from cms.test_utils.testcases import CMSTestCase

from richie.apps.courses.factories import CategoryFactory, CourseFactory
from richie.plugins.nesteditem.defaults import ACCORDION

from richie.apps.courses.templatetags.extra_tags import get_categories_pages_have_faqs
from cms.templatetags.cms_tags import (
Placeholder,
PlaceholderOptions,
_get_page_by_untyped_arg,
)

class GetCategoriesPagesHaveFAQsTemplateTagsTestCase(CMSTestCase):
"""
Integration tests to validate the behavior of the `get_categories_pages_have_faqs` template tag.
"""

@transaction.atomic
def test_templatetags_get_categories_pages_have_faqs_current_page(self):

category1: CategoryFactory = CategoryFactory.create(page_title="Accessible", should_publish=True)
category2 = CategoryFactory.create(
page_title="Earth and universe sciences", should_publish=True
)

placeholder = category1.extended_object.placeholders.get(slot="course_faq")
container = add_plugin(
language="en",
placeholder=placeholder,
plugin_type="NestedItemPlugin",
variant=ACCORDION,
)

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

for answer in range(1, 3):
add_plugin(
language="en",
placeholder=placeholder,
plugin_type="NestedItemPlugin",
target=question_container,
content=f"{question}.{answer} - Answer of question {question}.",
variant=ACCORDION,
)

course = CourseFactory(fill_categories=[category1, category2])

pages_have_faq = get_categories_pages_have_faqs(course)

course_faq: Placeholder = category1.extended_object.get_placeholders().get(slot="course_faq")
self.assertTrue(course_faq != None)
self.assertTrue(len(course_faq.get_plugins_list()) > 0)