Merge pull request #368 from pateljannat/video-and-quiz-field
This commit is contained in:
@@ -15,6 +15,10 @@
|
|||||||
"include_in_preview",
|
"include_in_preview",
|
||||||
"index_label",
|
"index_label",
|
||||||
"section_break_6",
|
"section_break_6",
|
||||||
|
"youtube",
|
||||||
|
"column_break_9",
|
||||||
|
"quiz_id",
|
||||||
|
"section_break_11",
|
||||||
"body",
|
"body",
|
||||||
"help_section",
|
"help_section",
|
||||||
"help"
|
"help"
|
||||||
@@ -81,11 +85,31 @@
|
|||||||
"label": "Course",
|
"label": "Course",
|
||||||
"options": "LMS Course",
|
"options": "LMS Course",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Quiz will appear at the bottom of the lesson.",
|
||||||
|
"fieldname": "quiz_id",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Quiz ID"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_9",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break_11",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "YouTube Video will appear at the top of the lesson.",
|
||||||
|
"fieldname": "youtube",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "YouTube Video URL"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-05-02 17:16:12.450460",
|
"modified": "2022-09-02 11:30:15.450624",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "Course Lesson",
|
"name": "Course Lesson",
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from ...md import find_macros
|
from ...md import find_macros
|
||||||
from lms.lms.utils import get_course_progress, get_lesson_url
|
from lms.lms.utils import get_course_progress, get_lesson_url
|
||||||
@@ -11,6 +12,11 @@ from lms.lms.utils import get_course_progress, get_lesson_url
|
|||||||
class CourseLesson(Document):
|
class CourseLesson(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.check_and_create_folder()
|
self.check_and_create_folder()
|
||||||
|
self.validate_quiz_id()
|
||||||
|
|
||||||
|
def validate_quiz_id(self):
|
||||||
|
if self.quiz_id and not frappe.db.exists("LMS Quiz", self.quiz_id):
|
||||||
|
frappe.throw(_("Invalid Quiz ID"))
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
dynamic_documents = ["Exercise", "Quiz"]
|
dynamic_documents = ["Exercise", "Quiz"]
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ def save_chapter(course, title, chapter_description, idx, chapter):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def save_lesson(title, body, chapter, preview, idx, lesson):
|
def save_lesson(title, body, chapter, preview, idx, lesson, youtube=None, quiz_id=None):
|
||||||
if lesson:
|
if lesson:
|
||||||
doc = frappe.get_doc("Course Lesson", lesson)
|
doc = frappe.get_doc("Course Lesson", lesson)
|
||||||
else:
|
else:
|
||||||
@@ -261,7 +261,9 @@ def save_lesson(title, body, chapter, preview, idx, lesson):
|
|||||||
"chapter": chapter,
|
"chapter": chapter,
|
||||||
"title": title,
|
"title": title,
|
||||||
"body": body,
|
"body": body,
|
||||||
"include_in_preview": preview
|
"include_in_preview": preview,
|
||||||
|
"youtube": youtube,
|
||||||
|
"quiz_id": quiz_id
|
||||||
})
|
})
|
||||||
doc.save(ignore_permissions=True)
|
doc.save(ignore_permissions=True)
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from frappe import _
|
|||||||
|
|
||||||
RE_SLUG_NOTALLOWED = re.compile("[^a-z0-9]+")
|
RE_SLUG_NOTALLOWED = re.compile("[^a-z0-9]+")
|
||||||
|
|
||||||
|
|
||||||
def slugify(title, used_slugs=[]):
|
def slugify(title, used_slugs=[]):
|
||||||
"""Converts title to a slug.
|
"""Converts title to a slug.
|
||||||
|
|
||||||
@@ -59,6 +60,7 @@ def get_membership(course, member, batch=None):
|
|||||||
membership.batch_title = frappe.db.get_value("LMS Batch", membership.batch, "title")
|
membership.batch_title = frappe.db.get_value("LMS Batch", membership.batch, "title")
|
||||||
return membership
|
return membership
|
||||||
|
|
||||||
|
|
||||||
def get_chapters(course):
|
def get_chapters(course):
|
||||||
"""Returns all chapters of this course.
|
"""Returns all chapters of this course.
|
||||||
"""
|
"""
|
||||||
@@ -85,6 +87,7 @@ def get_lessons(course, chapter=None):
|
|||||||
|
|
||||||
return lessons
|
return lessons
|
||||||
|
|
||||||
|
|
||||||
def get_lesson_details(chapter):
|
def get_lesson_details(chapter):
|
||||||
lessons = []
|
lessons = []
|
||||||
lesson_list = frappe.get_all("Lesson Reference",
|
lesson_list = frappe.get_all("Lesson Reference",
|
||||||
@@ -94,10 +97,11 @@ def get_lesson_details(chapter):
|
|||||||
|
|
||||||
for row in lesson_list:
|
for row in lesson_list:
|
||||||
lesson_details = frappe.db.get_value("Course Lesson", row.lesson,
|
lesson_details = frappe.db.get_value("Course Lesson", row.lesson,
|
||||||
["name", "title", "include_in_preview", "body", "creation"], as_dict=True)
|
["name", "title", "include_in_preview", "body", "creation", "youtube", "quiz_id"], as_dict=True)
|
||||||
lesson_details.number = flt("{}.{}".format(chapter.idx, row.idx))
|
lesson_details.number = flt("{}.{}".format(chapter.idx, row.idx))
|
||||||
lesson_details.icon = "icon-list"
|
lesson_details.icon = "icon-list"
|
||||||
macros = find_macros(lesson_details.body)
|
macros = find_macros(lesson_details.body)
|
||||||
|
|
||||||
for macro in macros:
|
for macro in macros:
|
||||||
if macro[0] == "YouTubeVideo":
|
if macro[0] == "YouTubeVideo":
|
||||||
lesson_details.icon = "icon-video"
|
lesson_details.icon = "icon-video"
|
||||||
@@ -106,10 +110,12 @@ def get_lesson_details(chapter):
|
|||||||
lessons.append(lesson_details)
|
lessons.append(lesson_details)
|
||||||
return lessons
|
return lessons
|
||||||
|
|
||||||
|
|
||||||
def get_tags(course):
|
def get_tags(course):
|
||||||
tags = frappe.db.get_value("LMS Course", course, "tags")
|
tags = frappe.db.get_value("LMS Course", course, "tags")
|
||||||
return tags.split(",") if tags else []
|
return tags.split(",") if tags else []
|
||||||
|
|
||||||
|
|
||||||
def get_instructors(course):
|
def get_instructors(course):
|
||||||
instructor_details = []
|
instructor_details = []
|
||||||
instructors = frappe.get_all("Course Instructor", {"parent": course},
|
instructors = frappe.get_all("Course Instructor", {"parent": course},
|
||||||
@@ -123,6 +129,7 @@ def get_instructors(course):
|
|||||||
as_dict=True))
|
as_dict=True))
|
||||||
return instructor_details
|
return instructor_details
|
||||||
|
|
||||||
|
|
||||||
def get_students(course, batch=None):
|
def get_students(course, batch=None):
|
||||||
"""Returns (email, full_name, username) of all the students of this batch as a list of dict.
|
"""Returns (email, full_name, username) of all the students of this batch as a list of dict.
|
||||||
"""
|
"""
|
||||||
@@ -137,12 +144,14 @@ def get_students(course, batch=None):
|
|||||||
filters,
|
filters,
|
||||||
["member"])
|
["member"])
|
||||||
|
|
||||||
|
|
||||||
def get_average_rating(course):
|
def get_average_rating(course):
|
||||||
ratings = [review.rating for review in get_reviews(course)]
|
ratings = [review.rating for review in get_reviews(course)]
|
||||||
if not len(ratings):
|
if not len(ratings):
|
||||||
return None
|
return None
|
||||||
return sum(ratings)/len(ratings)
|
return sum(ratings)/len(ratings)
|
||||||
|
|
||||||
|
|
||||||
def get_reviews(course):
|
def get_reviews(course):
|
||||||
reviews = frappe.get_all("LMS Course Review",
|
reviews = frappe.get_all("LMS Course Review",
|
||||||
{
|
{
|
||||||
@@ -164,6 +173,7 @@ def get_reviews(course):
|
|||||||
|
|
||||||
return reviews
|
return reviews
|
||||||
|
|
||||||
|
|
||||||
def get_sorted_reviews(course):
|
def get_sorted_reviews(course):
|
||||||
rating_count = rating_percent = frappe._dict()
|
rating_count = rating_percent = frappe._dict()
|
||||||
keys = ["5.0", "4.0", "3.0", "2.0", "1.0"]
|
keys = ["5.0", "4.0", "3.0", "2.0", "1.0"]
|
||||||
@@ -180,6 +190,7 @@ def get_sorted_reviews(course):
|
|||||||
|
|
||||||
return rating_percent
|
return rating_percent
|
||||||
|
|
||||||
|
|
||||||
def is_certified(course):
|
def is_certified(course):
|
||||||
certificate = frappe.get_all("LMS Certificate",
|
certificate = frappe.get_all("LMS Certificate",
|
||||||
{
|
{
|
||||||
@@ -190,6 +201,7 @@ def is_certified(course):
|
|||||||
return certificate[0].name
|
return certificate[0].name
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def get_lesson_index(lesson_name):
|
def get_lesson_index(lesson_name):
|
||||||
"""Returns the {chapter_index}.{lesson_index} for the lesson.
|
"""Returns the {chapter_index}.{lesson_index} for the lesson.
|
||||||
"""
|
"""
|
||||||
@@ -205,6 +217,7 @@ def get_lesson_index(lesson_name):
|
|||||||
|
|
||||||
return f"{chapter.idx}.{lesson.idx}"
|
return f"{chapter.idx}.{lesson.idx}"
|
||||||
|
|
||||||
|
|
||||||
def get_lesson_url(course, lesson_number):
|
def get_lesson_url(course, lesson_number):
|
||||||
if not lesson_number:
|
if not lesson_number:
|
||||||
return
|
return
|
||||||
@@ -224,8 +237,16 @@ def get_progress(course, lesson):
|
|||||||
},
|
},
|
||||||
["status"])
|
["status"])
|
||||||
|
|
||||||
def render_html(body):
|
|
||||||
return markdown_to_html(body)
|
def render_html(body, youtube, quiz_id):
|
||||||
|
if "/" in youtube:
|
||||||
|
youtube = youtube.split("/")[-1]
|
||||||
|
|
||||||
|
quiz_id = "{{ Quiz('" + quiz_id + "') }}" if quiz_id else ""
|
||||||
|
youtube = "{{ YouTubeVideo('" + youtube + "') }}" if youtube else ""
|
||||||
|
text = youtube + body + quiz_id
|
||||||
|
return markdown_to_html(text)
|
||||||
|
|
||||||
|
|
||||||
def is_mentor(course, email):
|
def is_mentor(course, email):
|
||||||
"""Checks if given user is a mentor for this course.
|
"""Checks if given user is a mentor for this course.
|
||||||
@@ -238,6 +259,7 @@ def is_mentor(course, email):
|
|||||||
"mentor": email
|
"mentor": email
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def is_cohort_staff(course, user_email):
|
def is_cohort_staff(course, user_email):
|
||||||
"""Returns True if the user is either a mentor or a staff for one or more active cohorts of this course.
|
"""Returns True if the user is either a mentor or a staff for one or more active cohorts of this course.
|
||||||
"""
|
"""
|
||||||
@@ -253,6 +275,7 @@ def is_cohort_staff(course, user_email):
|
|||||||
}
|
}
|
||||||
return frappe.db.exists(staff) or frappe.db.exists(mentor)
|
return frappe.db.exists(staff) or frappe.db.exists(mentor)
|
||||||
|
|
||||||
|
|
||||||
def get_mentors(course):
|
def get_mentors(course):
|
||||||
"""Returns the list of all mentors for this course.
|
"""Returns the list of all mentors for this course.
|
||||||
"""
|
"""
|
||||||
@@ -269,6 +292,7 @@ def get_mentors(course):
|
|||||||
course_mentors.append(member)
|
course_mentors.append(member)
|
||||||
return course_mentors
|
return course_mentors
|
||||||
|
|
||||||
|
|
||||||
def is_eligible_to_review(course, membership):
|
def is_eligible_to_review(course, membership):
|
||||||
""" Checks if user is eligible to review the course """
|
""" Checks if user is eligible to review the course """
|
||||||
if not membership:
|
if not membership:
|
||||||
@@ -281,6 +305,7 @@ def is_eligible_to_review(course, membership):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def get_course_progress(course, member=None):
|
def get_course_progress(course, member=None):
|
||||||
""" Returns the course progress of the session user """
|
""" Returns the course progress of the session user """
|
||||||
lesson_count = len(get_lessons(course))
|
lesson_count = len(get_lessons(course))
|
||||||
@@ -295,6 +320,7 @@ def get_course_progress(course, member=None):
|
|||||||
precision = cint(frappe.db.get_default("float_precision")) or 3
|
precision = cint(frappe.db.get_default("float_precision")) or 3
|
||||||
return flt(((completed_lessons/lesson_count) * 100), precision)
|
return flt(((completed_lessons/lesson_count) * 100), precision)
|
||||||
|
|
||||||
|
|
||||||
def get_initial_members(course):
|
def get_initial_members(course):
|
||||||
members = frappe.get_all("LMS Batch Membership",
|
members = frappe.get_all("LMS Batch Membership",
|
||||||
{
|
{
|
||||||
@@ -310,12 +336,15 @@ def get_initial_members(course):
|
|||||||
|
|
||||||
return member_details
|
return member_details
|
||||||
|
|
||||||
|
|
||||||
def is_instructor(course):
|
def is_instructor(course):
|
||||||
return len(list(filter(lambda x: x.name == frappe.session.user, get_instructors(course)))) > 0
|
return len(list(filter(lambda x: x.name == frappe.session.user, get_instructors(course)))) > 0
|
||||||
|
|
||||||
|
|
||||||
def convert_number_to_character(number):
|
def convert_number_to_character(number):
|
||||||
return string.ascii_uppercase[number]
|
return string.ascii_uppercase[number]
|
||||||
|
|
||||||
|
|
||||||
def get_signup_optin_checks():
|
def get_signup_optin_checks():
|
||||||
|
|
||||||
mapper = frappe._dict({
|
mapper = frappe._dict({
|
||||||
@@ -343,6 +372,7 @@ def get_signup_optin_checks():
|
|||||||
|
|
||||||
return (", ").join(links)
|
return (", ").join(links)
|
||||||
|
|
||||||
|
|
||||||
def get_popular_courses():
|
def get_popular_courses():
|
||||||
courses = frappe.get_all("LMS Course", {"published": 1, "upcoming": 0})
|
courses = frappe.get_all("LMS Course", {"published": 1, "upcoming": 0})
|
||||||
course_membership = []
|
course_membership = []
|
||||||
@@ -356,6 +386,7 @@ def get_popular_courses():
|
|||||||
course_membership = sorted(course_membership, key = lambda x: x.get("members"), reverse=True)
|
course_membership = sorted(course_membership, key = lambda x: x.get("members"), reverse=True)
|
||||||
return course_membership[:3]
|
return course_membership[:3]
|
||||||
|
|
||||||
|
|
||||||
def get_evaluation_details(course, member=None):
|
def get_evaluation_details(course, member=None):
|
||||||
info = frappe.db.get_value("LMS Course", course, ["grant_certificate_after", "max_attempts", "duration"], as_dict=True)
|
info = frappe.db.get_value("LMS Course", course, ["grant_certificate_after", "max_attempts", "duration"], as_dict=True)
|
||||||
request = frappe.db.get_value("LMS Certificate Request", {
|
request = frappe.db.get_value("LMS Certificate Request", {
|
||||||
@@ -378,6 +409,7 @@ def get_evaluation_details(course, member=None):
|
|||||||
"no_of_attempts": no_of_attempts
|
"no_of_attempts": no_of_attempts
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def format_amount(amount, currency):
|
def format_amount(amount, currency):
|
||||||
amount_reduced = amount / 1000
|
amount_reduced = amount / 1000
|
||||||
if amount_reduced < 1:
|
if amount_reduced < 1:
|
||||||
@@ -397,6 +429,7 @@ def first_lesson_exists(course):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def redirect_to_courses_list():
|
def redirect_to_courses_list():
|
||||||
frappe.local.flags.redirect_location = "/courses"
|
frappe.local.flags.redirect_location = "/courses"
|
||||||
raise frappe.Redirect
|
raise frappe.Redirect
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ def get_enrolled_courses():
|
|||||||
}
|
}
|
||||||
|
|
||||||
def get_course_membership(member, member_type=None):
|
def get_course_membership(member, member_type=None):
|
||||||
""" Returns all memberships of the user """
|
""" Returns all memberships of the user. """
|
||||||
filters = {
|
filters = {
|
||||||
"member": member
|
"member": member
|
||||||
}
|
}
|
||||||
@@ -156,8 +156,7 @@ def get_course_membership(member, member_type=None):
|
|||||||
|
|
||||||
|
|
||||||
def get_authored_courses(member, only_published=True):
|
def get_authored_courses(member, only_published=True):
|
||||||
"""Returns the number of courses authored by this user.
|
""" Returns the number of courses authored by this user. """
|
||||||
"""
|
|
||||||
course_details = []
|
course_details = []
|
||||||
|
|
||||||
filters = {
|
filters = {
|
||||||
|
|||||||
@@ -1658,7 +1658,7 @@ li {
|
|||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.help-article {
|
.medium {
|
||||||
font-size: var(--text-base);
|
font-size: var(--text-base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,7 @@
|
|||||||
{% if lesson.edit_mode %}
|
{% if lesson.edit_mode %}
|
||||||
{{ EditLesson(lesson) }}
|
{{ EditLesson(lesson) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ render_html(lesson.body) }}
|
{{ render_html(lesson.body, lesson.youtube, lesson.quiz_id) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
@@ -181,20 +181,34 @@
|
|||||||
|
|
||||||
<!-- Edit Lesson -->
|
<!-- Edit Lesson -->
|
||||||
{% macro EditLesson(lesson) %}
|
{% macro EditLesson(lesson) %}
|
||||||
<div id="body" {% if lesson.body %} data-body="{{ lesson.body }}" {% endif %}></div>
|
|
||||||
|
|
||||||
<label class="preview">
|
<div class="medium mt-2" contenteditable="true" data-placeholder="{{ _('YouTube Video ID') }}"
|
||||||
<input {% if lesson.include_in_preview %} checked {% endif %} type="checkbox"
|
id="youtube">{% if lesson.youtube %}{{ lesson.youtube }}{% endif %}</div>
|
||||||
id="preview"> {{ _("Show preview of this lesson to Guest users.") }}
|
<div id="body" {% if lesson.body %} data-body="{{ lesson.body }}" {% endif %}></div>
|
||||||
</label>
|
<div class="medium mb-4" contenteditable="true" data-placeholder="{{ _('Quiz ID') }}"
|
||||||
|
id="quiz-id">{% if lesson.quiz_id %}{{ lesson.quiz_id }}{% endif %}</div>
|
||||||
|
|
||||||
<div class="mt-4">
|
<label class="preview">
|
||||||
<button class="btn btn-primary btn-sm btn-lesson pull-right ml-2"> {{ _("Save") }} </button>
|
<input {% if lesson.include_in_preview %} checked {% endif %} type="checkbox"
|
||||||
{% if lesson.name %}
|
id="preview"> {{ _("Show preview of this lesson to Guest users.") }}
|
||||||
<button class="btn btn-secondary btn-sm pull-right btn-back ml-2"> {{ _("Back to Lesson") }} </button>
|
</label>
|
||||||
<a class="btn btn-secondary btn-sm pull-right" href="/quizzes"> {{ _("Create Quiz") }} </a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
|
<div class="mt-4">
|
||||||
|
<button class="btn btn-primary btn-sm btn-lesson pull-right ml-2"> {{ _("Save") }} </button>
|
||||||
|
{% if lesson.name %}
|
||||||
|
<button class="btn btn-secondary btn-sm pull-right btn-back ml-2"> {{ _("Back to Lesson") }} </button>
|
||||||
|
<a class="btn btn-secondary btn-sm pull-right" href="/quizzes"> {{ _("Create Quiz") }} </a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{{ UploadAttachments() }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ HelpArticle() }}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
|
{% macro UploadAttachments() %}
|
||||||
<div class="attachments-parent">
|
<div class="attachments-parent">
|
||||||
<div class="attachment-controls">
|
<div class="attachment-controls">
|
||||||
<div class="show-attachments" data-toggle="collapse" data-target="#collapse-attachments" aria-expanded="false">
|
<div class="show-attachments" data-toggle="collapse" data-target="#collapse-attachments" aria-expanded="false">
|
||||||
@@ -214,97 +228,111 @@
|
|||||||
</div>
|
</div>
|
||||||
<table class="attachments common-card-style collapse hide" id="collapse-attachments"></table>
|
<table class="attachments common-card-style collapse hide" id="collapse-attachments"></table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{{ HelpArticle() }}
|
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
<!-- Help Article -->
|
<!-- Help Article -->
|
||||||
{% macro HelpArticle() %}
|
{% macro HelpArticle() %}
|
||||||
<div class="help-article">
|
<div class="medium">
|
||||||
<h3> {{ _("Embed Components") }} </h3>
|
<h3> {{ _("Embed Components") }} </h3>
|
||||||
<p>
|
<p>
|
||||||
{{ _("You can add additional content to the lesson using a special syntax. The table below mentions
|
{{ _("You can add additional content to the lesson using a special syntax. The table below mentions
|
||||||
all types of dynamic content that you can add to the lessons and the syntax for the same.") }}
|
all types of dynamic content that you can add to the lessons and the syntax for the same.") }}
|
||||||
</p>
|
</p>
|
||||||
<table class="table w-100">
|
<ol>
|
||||||
<tr>
|
<li>
|
||||||
<th style="width: 20%;"> {{ _("Content Type") }} </th>
|
<b> {{ _("YouTube Video") }} </b>
|
||||||
<th style="width: 40%;"> {{ _("Syntax") }} </th>
|
<p> To get the YouTube Video ID, follow the steps mentioned below. </p>
|
||||||
<th> {{ _("Description") }} </th>
|
<ul class="px-4">
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
{{ _("YouTube Video") }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{% raw %} {{ YouTubeVideo('Video ID') }} {% endraw %}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span>
|
|
||||||
{{ _("Copy and paste the syntax in the editor. Replace 'Video ID' with the embed source
|
|
||||||
that YouTube provides. To get the source, follow the steps mentioned below.") }}
|
|
||||||
</span>
|
|
||||||
<ul class="p-4">
|
|
||||||
<li>
|
<li>
|
||||||
{{ _("Upload the video on youtube.") }}
|
{{ _("Upload the video on youtube.") }}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
{{ _("When you share a youtube video, it shows an option called Embed.") }}
|
{{ _("When you share a youtube video, it shows a URL") }}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
{{ _("On clicking it, it provides an iframe. Copy the source (src) of the iframe and
|
{{ _("Copy the last parameter of the URL and paste it here.") }}
|
||||||
paste it here.") }}
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</li>
|
||||||
</tr>
|
</ol>
|
||||||
<tr>
|
<!-- <table class="table w-100">
|
||||||
<td>
|
<tr>
|
||||||
{{ _("Quiz") }}
|
<th style="width: 20%;"> {{ _("Content Type") }} </th>
|
||||||
</td>
|
<th style="width: 40%;"> {{ _("Syntax") }} </th>
|
||||||
<td>
|
<th> {{ _("Description") }} </th>
|
||||||
{% raw %} {{ Quiz('Quiz ID') }} {% endraw %}
|
</tr>
|
||||||
</td>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{% set quiz_link = "<a href='/quizzes'> Quiz List </a>" %}
|
{{ _("YouTube Video") }}
|
||||||
{{ _("Copy and paste the syntax in the editor. Replace 'Quiz ID' with the Id of the Quiz.
|
</td>
|
||||||
You can get the Id of the quiz from the {0}.").format(quiz_link) }}
|
<td>
|
||||||
</td>
|
{% raw %} {{ YouTubeVideo('Video ID') }} {% endraw %}
|
||||||
</tr>
|
</td>
|
||||||
</table>
|
<td>
|
||||||
</div>
|
<span>
|
||||||
|
{{ _("Copy and paste the syntax in the editor. Replace 'Video ID' with the embed source
|
||||||
|
that YouTube provides. To get the source, follow the steps mentioned below.") }}
|
||||||
|
</span>
|
||||||
|
<ul class="p-4">
|
||||||
|
<li>
|
||||||
|
{{ _("Upload the video on youtube.") }}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
{{ _("When you share a youtube video, it shows an option called Embed.") }}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
{{ _("On clicking it, it provides an iframe. Copy the source (src) of the iframe and
|
||||||
|
paste it here.") }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{ _("Quiz") }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% raw %} {{ Quiz('Quiz ID') }} {% endraw %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% set quiz_link = "<a href='/quizzes'> Quiz List </a>" %}
|
||||||
|
{{ _("Copy and paste the syntax in the editor. Replace 'Quiz ID' with the Id of the Quiz.
|
||||||
|
You can get the Id of the quiz from the {0}.").format(quiz_link) }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table> -->
|
||||||
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
<!-- Discussions Component -->
|
<!-- Discussions Component -->
|
||||||
{% macro Discussions() %}
|
{% macro Discussions() %}
|
||||||
{% set topics_count = frappe.db.count("Discussion Topic", {
|
{% set topics_count = frappe.db.count("Discussion Topic", {
|
||||||
"reference_doctype": "Course Lesson",
|
"reference_doctype": "Course Lesson",
|
||||||
"reference_docname": lesson.name
|
"reference_docname": lesson.name
|
||||||
}) %}
|
}) %}
|
||||||
{% set is_instructor = frappe.session.user == course.instructor %}
|
{% set is_instructor = frappe.session.user == course.instructor %}
|
||||||
{% set condition = is_instructor if is_instructor else membership %}
|
{% set condition = is_instructor if is_instructor else membership %}
|
||||||
{% set doctype, docname = _("Course Lesson"), lesson.name %}
|
{% set doctype, docname = _("Course Lesson"), lesson.name %}
|
||||||
{% set title = "Questions" if topics_count else "" %}
|
{% set title = "Questions" if topics_count else "" %}
|
||||||
{% set cta_title = "Ask a Question" %}
|
{% set cta_title = "Ask a Question" %}
|
||||||
{% set button_name = _("Start Learning") %}
|
{% set button_name = _("Start Learning") %}
|
||||||
{% set redirect_to = "/courses/" + course.name %}
|
{% set redirect_to = "/courses/" + course.name %}
|
||||||
{% set empty_state_title = _("Have a doubt?") %}
|
{% set empty_state_title = _("Have a doubt?") %}
|
||||||
{% set empty_state_subtitle = _("Post it here, our mentors will help you out.") %}
|
{% set empty_state_subtitle = _("Post it here, our mentors will help you out.") %}
|
||||||
{% include "frappe/templates/discussions/discussions_section.html" %}
|
{% include "frappe/templates/discussions/discussions_section.html" %}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
{%- block script %}
|
{%- block script %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var page_context = {{ page_context | tojson }};
|
var page_context = {{ page_context | tojson }};
|
||||||
</script>
|
</script>
|
||||||
{{ include_script('controls.bundle.js') }}
|
{{ include_script('controls.bundle.js') }}
|
||||||
{% for ext in page_extensions %}
|
{% for ext in page_extensions %}
|
||||||
{{ ext.render_footer() }}
|
{{ ext.render_footer() }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{%- endblock %}
|
{%- endblock %}
|
||||||
|
|||||||
@@ -490,7 +490,9 @@ const save_lesson = (e) => {
|
|||||||
method: "lms.lms.doctype.lms_course.lms_course.save_lesson",
|
method: "lms.lms.doctype.lms_course.lms_course.save_lesson",
|
||||||
args: {
|
args: {
|
||||||
"title": $("#title").text(),
|
"title": $("#title").text(),
|
||||||
"body": this.code_field_group.fields_dict["code_md"].last_value,
|
"body": this.code_field_group.fields_dict["code_md"].value,
|
||||||
|
"youtube": $("#youtube").text(),
|
||||||
|
"quiz_id": $("#quiz-id").text(),
|
||||||
"chapter": $("#title").data("chapter"),
|
"chapter": $("#title").data("chapter"),
|
||||||
"preview": $("#preview").prop("checked") ? 1 : 0,
|
"preview": $("#preview").prop("checked") ? 1 : 0,
|
||||||
"idx": $("#title").data("index"),
|
"idx": $("#title").data("index"),
|
||||||
|
|||||||
Reference in New Issue
Block a user