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 content from the category detail page
  • Loading branch information
Tiago-Salles committed Dec 2, 2024
1 parent 51d6014 commit cd1e241
Show file tree
Hide file tree
Showing 7 changed files with 634 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic
Versioning](https://semver.org/spec/v2.0.0.html).



## [Unrealeased]

### Added

- Add Additional Information section for a category and
use them in a course page
- Add Slider plugin

## [2.32.0] - 2024-11-27
Expand Down
19 changes: 19 additions & 0 deletions src/richie/apps/courses/settings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,25 @@ def richie_placeholder_conf(name):
"plugins": ["CKEditorPlugin"],
"limits": {"CKEditorPlugin": 1},
},
"courses/cms/category_detail.html additional_information": {
"name": _("Additional Information"),
"plugins": ["SectionPlugin"],
"parent_classes": {
"CKEditorPlugin": ["SectionPlugin"],
"SimplePicturePlugin": ["SectionPlugin"],
"GlimpsePlugin": ["SectionPlugin"],
"NestedItemPlugin": ["SectionPlugin"],
},
"child_classes": {
"SectionPlugin": [
"CKEditorPlugin",
"SimplePicturePlugin",
"GlimpsePlugin",
"NestedItemPlugin",
],
"NestedItemPlugin": ["NestedItemPlugin"],
},
},
# Person detail
"courses/cms/person_detail.html categories": {
"name": _("Categories"),
Expand Down
13 changes: 13 additions & 0 deletions src/richie/apps/courses/templates/courses/cms/category_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,19 @@ <h2 class="category-detail__title">{% trans "Related blogposts" %}</h2>
{% endif %}
{% endwith %}

<div id="page{{ page_suffix }}" class="category-detail__additional-info category-detail__block">
<div class="category-detail__row">
{% if not current_page|is_empty_placeholder:"additional_information" and not current_page.reverse_id %}
<p class="category-detail__empty">{% trans 'Configure this page id to show this additional information on all related course pages' %}</p>
{% endif %}
{% placeholder "additional_information" or %}
{% if request.toolbar.edit_mode_active %}
<p class="category-detail__empty">{% trans 'Enter additional information for this category' %}</p>
{% endif %}
{% endplaceholder %}
</div>
</div>

{% with persons=category.get_persons %}
{% if persons %}
{% autopaginate persons GLIMPSE_PAGINATION_PERSONS %}
Expand Down
17 changes: 17 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 @@ -472,6 +472,23 @@ <h2 class="course-detail__title">
{% endif %}
{% endblock information %}

{% block category_additional_information %}
<!-- Showing all categories additional information of categories pages that have a page id -->

{% get_categories_pages_additional_information current_page.course as pages %}
{% if pages %}
<div class="course-detail__additional-info course-detail__block course-detail__row">
{% with is_syllabus_property=True %}
{% for page in pages %}
{% with reverse_id=page.reverse_id %}
{% show_placeholder "additional_information" reverse_id %}
{% endwith %}
{% endfor %}
{% endwith %}
</div>
{% endif %}
{% endblock category_additional_information %}

{% block licenses %}
{% if current_page.publisher_is_draft or not current_page|is_empty_placeholder:"course_license_content" or not current_page|is_empty_placeholder:"course_license_participation" %}
<div class="course-detail__license course-detail__block course-detail__block--divider">
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_additional_information(course: Course) -> list[Page]:
"""
Return categories pages have additional information and also have a page id.
usage: `{% get_categories_pages_additional_information current_page.course as pages %}`
"""

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

categories_with_information: list[Category] = []
for category in categories_pages:
additional_information = category.extended_object.get_placeholders().get(
slot="additional_information"
)
plugins = additional_information.get_plugins()

if len(plugins) > 0:
categories_with_information.append(category)

pages_have_additional_information: list[Page] = [
category.extended_object for category in categories_with_information
]

return pages_have_additional_information


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


class CategoryAdditionalInfoCMSTestCase(CMSTestCase):
"""
End-to-end test suite to validate the content and Ux of the category detail view
in terms of the additional information section
"""

def test_template_category_detail_additional_information(self):
"""
Validates the creation of additional information for a category and its content
"""

info_quantity = 3
category = CategoryFactory.create(page_title="Accessible", should_publish=True)
placeholder = category.extended_object.placeholders.get(
slot="additional_information"
)

section = add_plugin(
language="en",
placeholder=placeholder,
plugin_type="SectionPlugin",
title="Additional Information",
)

container = add_plugin(
language="en",
placeholder=placeholder,
plugin_type="NestedItemPlugin",
variant=ACCORDION,
target=section,
)

for question in range(1, info_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, "Additional Information")

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

def test_template_category_detail_no_additional_info_edit_mode(self):
"""
Validates the behavior whether editing the page or not to show
the message indicating that it is possible to enter data to
the section of additional information
"""

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.assertNotContains(
response, "Enter additional information for this category"
)

staff = UserFactory(is_staff=True, is_superuser=True)
self.client.login(username=staff.username, password="password")
url = f"{url:s}?edit"
response = self.client.get(url)

self.assertEqual(response.status_code, 200)
self.assertContains(response, "Enter additional information for this category")

def test_template_category_detail_additional_info_page_id(self):
"""
Validates the behavior when the page has additional information
but without page id, it shows the message indicating to register
the page id
"""

category = CategoryFactory.create(page_title="Accessible", should_publish=True)
placeholder = category.extended_object.placeholders.get(
slot="additional_information"
)

section = add_plugin(
language="en",
placeholder=placeholder,
plugin_type="SectionPlugin",
title="Additional Information",
)

container = add_plugin(
language="en",
placeholder=placeholder,
plugin_type="NestedItemPlugin",
variant=ACCORDION,
target=section,
)

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,
)

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

message = (
"Configure this page id to show this additional "
"information on all related course pages"
)

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, message)

page.reverse_id = "accessible"
page.save()
page.publish("en")

response = self.client.get(url)

self.assertEqual(response.status_code, 200)
self.assertNotContains(response, message)
Loading

0 comments on commit cd1e241

Please sign in to comment.