Merge pull request #5 from fossunited/course-doctype-v1

First cut at the course doctype.
This commit is contained in:
Jannat Patel
2021-03-02 18:52:45 +05:30
committed by GitHub
21 changed files with 399 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
// Copyright (c) 2021, Frappe and contributors
// For license information, please see license.txt
frappe.ui.form.on('Community Course', {
});

View File

@@ -0,0 +1,64 @@
{
"actions": [],
"allow_guest_to_view": 1,
"allow_rename": 1,
"autoname": "field:title",
"creation": "2021-03-01 16:49:33.622422",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"title",
"description",
"is_published"
],
"fields": [
{
"fieldname": "title",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Title",
"reqd": 1,
"unique": 1
},
{
"fieldname": "description",
"fieldtype": "Markdown Editor",
"label": "Description"
},
{
"default": "0",
"fieldname": "is_published",
"fieldtype": "Check",
"label": "Published"
}
],
"index_web_pages_for_search": 1,
"is_published_field": "is_published",
"links": [],
"modified": "2021-03-02 12:25:25.235975",
"modified_by": "Administrator",
"module": "Community",
"name": "Community Course",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"search_fields": "title",
"sort_field": "creation",
"sort_order": "DESC",
"title_field": "title",
"track_changes": 1,
"track_views": 1
}

View File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Frappe and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
# import frappe
from frappe.website.website_generator import WebsiteGenerator
class CommunityCourse(WebsiteGenerator):
pass

View File

@@ -0,0 +1,21 @@
{% extends "templates/web.html" %}
{% block page_content %}
<ol class="breadcrumb" itemscope="" itemtype="http://schema.org/BreadcrumbList">
<li itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ListItem" class="breadcrumb-item">
<a itemprop="item" href="/courses">
<span itemprop="name">&larr; Courses</span>
<meta itemprop="position" content="1">
</a>
<span itemprop="item">
</li>
</ol>
<h1>{{ title }}</h1>
{{description}}
{% endblock %}
<!-- this is a sample default web page template -->

View File

@@ -0,0 +1,7 @@
<div class="card" style="width: 100%; margin: 5px 0px">
<div class="card-body">
<h5 class="card-title"><a href="{{doc.route}}">{{doc.title}}</a></h5>
<p class="card-text">{{doc.description}}</p>
<a href="{{doc.route}}" class="card-link">See more &rarr;</a>
</div>
</div>

View File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Frappe and Contributors
# See license.txt
from __future__ import unicode_literals
# import frappe
import unittest
class TestCommunityCourse(unittest.TestCase):
pass

View File

@@ -0,0 +1,8 @@
// Copyright (c) 2021, Frappe and contributors
// For license information, please see license.txt
frappe.ui.form.on('Community Course Topic', {
// refresh: function(frm) {
// }
});

View File

@@ -0,0 +1,70 @@
{
"actions": [],
"allow_guest_to_view": 1,
"autoname": "format:{title}",
"creation": "2021-03-02 07:20:41.686573",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"title",
"description",
"course",
"order"
],
"fields": [
{
"fieldname": "title",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Title",
"reqd": 1
},
{
"fieldname": "description",
"fieldtype": "Markdown Editor",
"label": "Description"
},
{
"fieldname": "course",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Course",
"options": "Community Course",
"reqd": 1
},
{
"fieldname": "order",
"fieldtype": "Int",
"label": "Order"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-03-02 11:43:47.044344",
"modified_by": "Administrator",
"module": "Community",
"name": "Community Course Topic",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"search_fields": "title",
"sort_field": "creation",
"sort_order": "ASC",
"title_field": "title",
"track_changes": 1,
"track_seen": 1,
"track_views": 1
}

View File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Frappe and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
# import frappe
from frappe.website.website_generator import WebsiteGenerator
class CommunityCourseTopic(WebsiteGenerator):
pass

View File

@@ -0,0 +1,7 @@
{% extends "templates/web.html" %}
{% block page_content %}
<h1>{{ title }}</h1>
{% endblock %}
<!-- this is a sample default web page template -->

View File

@@ -0,0 +1,4 @@
<div>
<a href="{{ doc.route }}">{{ doc.title or doc.name }}</a>
</div>
<!-- this is a sample default list template -->

View File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Frappe and Contributors
# See license.txt
from __future__ import unicode_literals
# import frappe
import unittest
class TestCommunityCourseTopic(unittest.TestCase):
pass

View File

@@ -0,0 +1,35 @@
{% extends "templates/base.html" %}
{% block title %}{{ 'Courses' }}{% endblock %}
{% from "www/courses/macros/card.html" import course_card, topic_card %}
{% block head_include %}
<meta name="description" content="Courses" />
<meta name="keywords" content="Courses {{course.title}}" />
<style>
</style>
{% endblock %}
{% block content %}
<section class="top-section" style="padding: 1rem 0rem;">
<div class='container pb-5'>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item" aria-current="page"><a href="/courses">Courses</a></li>
</ol>
</nav>
<h1>{{ course.title }}</h1>
<div>{{ course.description }}</div>
</div>
<div class='container'>
<div class="list-group">
{% for topic in course.topics %}
<div class="list-group-item">
<h5><a href="/courses/topic?course={{course.name}}&topic={{topic.name}}">{{topic.title}}</a></h5>
<div>{{topic.description}}</div>
</div>
{% endfor %}
</div>
</div>
</section>
{% endblock %}

View File

@@ -0,0 +1,23 @@
import frappe
def get_context(context):
context.no_cache = 1
try:
course_id = frappe.form_dict['course']
except KeyError:
frappe.local.flags.redirect_location = '/courses'
raise frappe.Redirect
context.course = get_course(course_id)
def get_course(name):
course = frappe.db.get_value('Community Course', name,
['name', 'title', 'description'], as_dict=1)
course['topics'] = frappe.db.get_all('Community Course Topic',
filters={
'course': name
},
fields=['name', 'title', 'description'],
order_by='creation'
)
print(course)
return course

View File

@@ -0,0 +1,24 @@
{% extends "templates/base.html" %}
{% block title %}{{ 'Courses' }}{% endblock %}
{% from "www/courses/macros/card.html" import course_card %}
{% block head_include %}
<meta name="description" content="{{ 'Courses' }}" />
<meta name="keywords" content="Courses" />
<style>
</style>
{% endblock %}
{% block content %}
<section class="top-section" style="padding: 1rem 0rem;">
<div class='container pb-5'>
<h1>{{ 'Courses' }}</h1>
</div>
<div class='container'>
<div class="row mt-5">
{% for course in courses %}
{{ course_card(course) }}
{% endfor %}
</div>
</div>
</section>
{% endblock %}

View File

@@ -0,0 +1,13 @@
import frappe
def get_context(context):
context.no_cache = 1
context.courses = get_courses()
def get_courses():
courses = frappe.get_all(
"Community Course",
fields=['name', 'title', 'description']
)
print(courses)
return courses

View File

@@ -0,0 +1,19 @@
{% macro course_card(course) %}
<div class="card mb-5 w-100">
<div class="card-body">
<h5 class="card-title"><a href="/courses/course?course={{course.name}}">{{course.title}}</a></h5>
<p class="card-text">{{course.description}}</p>
<a href="/courses/course?id={{course.name}}" class="card-link">See more &rarr;</a>
</div>
</div>
{% endmacro %}
{% macro topic_card(course, topic) %}
<div class="card mb-5 w-100">
<div class="card-body">
<h5 class="card-title"><a href="/courses/topic?course={{course.name}}&topic={{topic.name}}">{{topic.title}}</a></h5>
<p class="card-text">{{topic.description}}</p>
</div>
</div>
{% endmacro %}

View File

@@ -0,0 +1,25 @@
{% extends "templates/base.html" %}
{% block title %}{{topic.title}} ({{course.title}}){% endblock %}
{% block head_include %}
<meta name="description" content="Topic {{topic.title}} of the course {{course.title}}" />
<meta name="keywords" content="course {{course.title}} {{topic.title}}" />
<style>
</style>
{% endblock %}
{% block content %}
<section class="top-section" style="padding: 1rem 0rem;">
<div class='container pb-5'>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item" aria-current="page"><a href="/courses">Courses</a></li>
<li class="breadcrumb-item" aria-current="page"><a href="/courses/course?course={{course.name}}">{{course.title}}</a></li>
</ol>
</nav>
<h1>{{ topic.title }}</h1>
<div>{{ topic.description }}</div>
</div>
</section>
{% endblock %}

View File

@@ -0,0 +1,34 @@
import frappe
def get_context(context):
context.no_cache = 1
course_name = get_queryparam("course", '/courses')
context.course = get_course(course_name)
topic_name = get_queryparam("topic", '/courses?course=' + course_name)
context.topic = get_topic(course_name, topic_name)
print("topic", context.topic)
def get_queryparam(name, redirect_when_not_found):
try:
return frappe.form_dict[name]
except KeyError:
frappe.local.flags.redirect_location = redirect_when_not_found
raise frappe.Redirect
def get_course(name):
try:
course = frappe.get_doc('Community Course', name)
except frappe.exceptions.DoesNotExistError:
raise frappe.NotFound
return course
def get_topic(course_name, topic_name):
try:
topic = frappe.get_doc('Community Course Topic', topic_name)
except frappe.exceptions.DoesNotExistError:
raise frappe.NotFound
if topic.course != course_name:
raise frappe.NotFound
return topic