diff --git a/frontend/components.d.ts b/frontend/components.d.ts index 4389972d..93deddcf 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -68,7 +68,6 @@ declare module 'vue' { NoPermission: typeof import('./src/components/NoPermission.vue')['default'] NoSidebarLayout: typeof import('./src/components/NoSidebarLayout.vue')['default'] NotPermitted: typeof import('./src/components/NotPermitted.vue')['default'] - OnboardingBanner: typeof import('./src/components/OnboardingBanner.vue')['default'] PageModal: typeof import('./src/components/Modals/PageModal.vue')['default'] PaymentSettings: typeof import('./src/components/PaymentSettings.vue')['default'] ProgressBar: typeof import('./src/components/ProgressBar.vue')['default'] diff --git a/frontend/src/components/Modals/Settings.vue b/frontend/src/components/Modals/Settings.vue index 290416a8..8f876e0f 100644 --- a/frontend/src/components/Modals/Settings.vue +++ b/frontend/src/components/Modals/Settings.vue @@ -350,6 +350,20 @@ const tabsStructure = computed(() => { }, ], }, + { + label: 'SEO', + icon: 'Search', + fields: [ + { + label: 'Meta Description', + name: 'meta_description', + type: 'textarea', + rows: 5, + description: + "This description will be shown on lists and pages that don't have meta description", + }, + ], + }, ], }, ] diff --git a/frontend/src/components/OnboardingBanner.vue b/frontend/src/components/OnboardingBanner.vue deleted file mode 100644 index b743ea82..00000000 --- a/frontend/src/components/OnboardingBanner.vue +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - - - - - - 1 - - - {{ __('Create a course') }} - - - - - - - - 2 - - - {{ __('Add a chapter') }} - - - - - - - - 3 - - - {{ __('Add a lesson') }} - - - - - - diff --git a/frontend/src/pages/CourseForm.vue b/frontend/src/pages/CourseForm.vue index 1117e649..2a2b2d07 100644 --- a/frontend/src/pages/CourseForm.vue +++ b/frontend/src/pages/CourseForm.vue @@ -310,11 +310,7 @@ const course = reactive({ }) onMounted(() => { - if ( - props.courseName == 'new' && - !user.data?.is_moderator && - !user.data?.is_instructor - ) { + if (!user.data?.is_moderator && !user.data?.is_instructor) { router.push({ name: 'Courses' }) } diff --git a/lms/lms/doctype/lms_settings/lms_settings.json b/lms/lms/doctype/lms_settings/lms_settings.json index 4c1fb733..c263bf5e 100644 --- a/lms/lms/doctype/lms_settings/lms_settings.json +++ b/lms/lms/doctype/lms_settings/lms_settings.json @@ -8,7 +8,6 @@ "general_tab", "default_home", "send_calendar_invite_for_evaluations", - "is_onboarding_complete", "column_break_zdel", "allow_guest_access", "enable_learning_paths", @@ -60,7 +59,9 @@ "batch_confirmation_template", "column_break_uwsp", "assignment_submission_template", - "payment_reminder_template" + "payment_reminder_template", + "seo_tab", + "meta_description" ], "fields": [ { @@ -107,13 +108,6 @@ "fieldtype": "Check", "label": "Identify User Persona" }, - { - "default": "0", - "fieldname": "is_onboarding_complete", - "fieldtype": "Check", - "label": "Is Onboarding Complete", - "read_only": 1 - }, { "default": "0", "fieldname": "default_home", @@ -372,14 +366,25 @@ "fieldname": "disable_signup", "fieldtype": "Check", "label": "Disable Signup" + }, + { + "fieldname": "seo_tab", + "fieldtype": "Tab Break", + "label": "SEO" + }, + { + "description": "This description will be shown on lists and pages without meta description", + "fieldname": "meta_description", + "fieldtype": "Small Text", + "label": "Meta Description" } ], "grid_page_length": 50, "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2025-04-07 18:05:52.000651", - "modified_by": "Administrator", + "modified": "2025-04-10 16:17:00.658698", + "modified_by": "sayali@frappe.io", "module": "LMS", "name": "LMS Settings", "owner": "Administrator", diff --git a/lms/www/lms.py b/lms/www/lms.py index 2131a6a8..c0445361 100644 --- a/lms/www/lms.py +++ b/lms/www/lms.py @@ -3,7 +3,6 @@ import re from bs4 import BeautifulSoup from frappe import _ from frappe.utils.telemetry import capture -from frappe.utils import cint no_cache = 1 @@ -15,22 +14,23 @@ def get_context(): or "/assets/lms/frontend/favicon.png" ) title = frappe.db.get_single_value("Website Settings", "app_name") or "Frappe Learning" + description = frappe.db.get_single_value("LMS Settings", "meta_description") csrf_token = frappe.sessions.get_csrf_token() frappe.db.commit() context = frappe._dict() context.csrf_token = csrf_token - context.meta = get_meta(app_path, title, favicon) + context.meta = get_meta(app_path, title, favicon, description) capture("active_site", "lms") context.title = title context.favicon = favicon return context -def get_meta(app_path, title, favicon): +def get_meta(app_path, title, favicon, description): meta = {} if app_path: - meta = get_meta_from_document(app_path, favicon) + meta = get_meta_from_document(app_path) route_meta = frappe.get_all("Website Meta Tag", {"parent": app_path}, ["key", "value"]) @@ -47,22 +47,26 @@ def get_meta(app_path, title, favicon): elif row.key == "link": meta["link"] = row.value + if not meta.get("description"): + meta["description"] = description + + if not meta.get("image"): + meta["image"] = favicon + if not meta: meta = { "title": title, "image": favicon, - "description": "Easy to use Learning Management System", + "description": description, } return meta -def get_meta_from_document(app_path, favicon): +def get_meta_from_document(app_path): if app_path == "courses": return { "title": _("Course List"), - "image": favicon, - "description": "This page lists all the courses published on our website", "keywords": "All Courses, Courses, Learn", "link": "/courses", } @@ -72,7 +76,6 @@ def get_meta_from_document(app_path, favicon): return { "title": _("New Course"), "image": frappe.db.get_single_value("Website Settings", "banner_image"), - "description": "Create a new course", "keywords": "New Course, Create Course", "link": "/lms/courses/new/edit", } @@ -99,8 +102,6 @@ def get_meta_from_document(app_path, favicon): if app_path == "batches": return { "title": _("Batches"), - "image": favicon, - "description": "This page lists all the batches published on our website", "keywords": "All Batches, Batches, Learn", "link": "/batches", } @@ -130,8 +131,6 @@ def get_meta_from_document(app_path, favicon): if "new/edit" in app_path: return { "title": _("New Batch"), - "image": favicon, - "description": "Create a new batch", "keywords": "New Batch, Create Batch", "link": "/lms/batches/new/edit", } @@ -157,8 +156,6 @@ def get_meta_from_document(app_path, favicon): if app_path == "job-openings": return { "title": _("Job Openings"), - "image": favicon, - "description": "This page lists all the job openings published on our website", "keywords": "Job Openings, Jobs, Vacancies", "link": "/job-openings", } @@ -182,8 +179,6 @@ def get_meta_from_document(app_path, favicon): if app_path == "statistics": return { "title": _("Statistics"), - "image": favicon, - "description": "This page lists all the statistics of this platform", "keywords": "Enrollment Count, Completion, Signups", "link": "/statistics", } @@ -231,8 +226,6 @@ def get_meta_from_document(app_path, favicon): if app_path == "quizzes": return { "title": _("Quizzes"), - "image": favicon, - "description": _("Test your knowledge with interactive quizzes and more."), "keywords": "Quizzes, interactive quizzes, online quizzes", "link": "/quizzes", } @@ -248,8 +241,6 @@ def get_meta_from_document(app_path, favicon): if quiz: return { "title": quiz.title, - "image": favicon, - "description": "Test your knowledge with interactive quizzes.", "keywords": quiz.title, "link": f"/quizzes/{quiz_name}", } @@ -257,8 +248,6 @@ def get_meta_from_document(app_path, favicon): if app_path == "assignments": return { "title": _("Assignments"), - "image": favicon, - "description": _("Test your knowledge with interactive assignments and more."), "keywords": "Assignments, interactive assignments, online assignments", "link": "/assignments", } @@ -274,8 +263,6 @@ def get_meta_from_document(app_path, favicon): if assignment: return { "title": assignment.title, - "image": favicon, - "description": "Test your knowledge with interactive assignments.", "keywords": assignment.title, "link": f"/assignments/{assignment_name}", } @@ -283,8 +270,6 @@ def get_meta_from_document(app_path, favicon): if app_path == "programs": return { "title": _("Programs"), - "image": favicon, - "description": "This page lists all the programs published on our website", "keywords": "All Programs, Programs, Learn", "link": "/programs", }