### Clone and Install Frappe UI Starter Source: https://github.com/frappe/lms/blob/develop/frontend/README.md Steps to clone the starter template into an existing Frappe app and install dependencies. ```bash cd apps/todo npx degit netchampfaris/frappe-ui-starter frontend cd frontend yarn yarn dev ``` -------------------------------- ### Download Easy Install Script Source: https://github.com/frappe/lms/blob/develop/README.md Use wget to download the easy install script for Frappe Learning. This script automates the setup process for self-hosting. ```bash wget https://frappe.io/easy-install.py ``` -------------------------------- ### Set up Frappe LMS Site Locally Source: https://github.com/frappe/lms/blob/develop/README.md Commands to create a new Frappe site, add it to the host file, install necessary Frappe apps (payments and lms), and then install the lms app on the site. Requires bench to be installed. ```sh $ bench new-site learning.test $ bench --site learning.test add-to-hosts $ bench get-app https://github.com/frappe/payments $ bench get-app https://github.com/frappe/lms $ bench --site learning.test install-app lms ``` -------------------------------- ### Start Docker Services Source: https://github.com/frappe/lms/blob/develop/docker-installation.md Run the docker-compose command to start the Frappe LMS services for local development. ```bash $ docker-compose up ``` -------------------------------- ### Install LMS App on Site Source: https://github.com/frappe/lms/blob/develop/bench-installation.md Install the fetched LMS app onto your specified Frappe site. This command links the app to your site. ```bash bench --site lms.test install-app lms ``` -------------------------------- ### Start Frappe Bench Server Source: https://github.com/frappe/lms/blob/develop/README.md Initiate the Frappe development server. This command is used after setting up a Frappe bench directory. ```sh $ bench start ``` -------------------------------- ### Download Docker Compose and Init Script Source: https://github.com/frappe/lms/blob/develop/README.md Download the necessary Docker configuration files for Frappe LMS. Ensure you have Docker and docker-compose installed. ```bash mkdir frappe-learning cd frappe-learning # Download the docker-compose file wget -O docker-compose.yml https://raw.githubusercontent.com/frappe/lms/develop/docker/docker-compose.yml # Download the setup script wget -O init.sh https://raw.githubusercontent.com/frappe/lms/develop/docker/init.sh ``` -------------------------------- ### Clone Frappe LMS Repository Source: https://github.com/frappe/lms/blob/develop/docker-installation.md Clone the Frappe LMS repository and navigate into the docker directory to prepare for setup. ```bash $ git clone https://github.com/frappe/lms.git $ cd lms $ cd docker ``` -------------------------------- ### Get LMS App Source: https://github.com/frappe/lms/blob/develop/bench-installation.md Fetch the LMS application from its repository URL. Ensure you have the correct URL for your fork. ```bash bench get-app ``` -------------------------------- ### Run Frappe LMS with Docker Source: https://github.com/frappe/lms/blob/develop/README.md Start the Frappe LMS containers in detached mode using Docker Compose. Access the LMS at http://lms.localhost:8000/lms with default credentials 'Administrator'/'admin'. ```bash docker compose up -d ``` -------------------------------- ### Deploy Frappe Learning Instance Source: https://github.com/frappe/lms/blob/develop/README.md Execute the deployment command using the downloaded easy-install.py script. This command sets up a production-ready Frappe Learning instance with specified configurations. Ensure you replace placeholder values for email, domain, and other parameters. ```bash python3 ./easy-install.py deploy \ --project=learning_prod_setup \ --email=your_email.example.com \ --image=ghcr.io/frappe/lms \ --version=stable \ --app=lms \ --sitename subdomain.domain.tld ``` -------------------------------- ### Onboarding Logic in Jinja Template Source: https://github.com/frappe/lms/blob/develop/lms/templates/onboarding_header.html Conditionally displays onboarding prompts based on user role and onboarding completion status. Includes links to create courses, add chapters, or add lessons. ```html {% set onboarding_status = is_onboarding_complete() %} {% if has_moderator_role() and not onboarding_status.is_onboarded %} {{ _("Skip") }} {{ _("Get Started") }} {{ _("Lets start setting up your content on the LMS so that you can reclaim time and focus on growth.") }} [{{ _("Create a Course") }}](/courses/new-course/edit) [{{ _("Add a Chapter") }}](/courses/{{ onboarding_status.first_course }}/outline) [{{ _("Add a Lesson") }}](/courses/{{ onboarding_status.first_course }}/learn/1.1/edit) {% endif %} ``` -------------------------------- ### Load Demo Data Source: https://github.com/frappe/lms/blob/develop/docker-installation.md Execute a command within the running Docker container to create sample course, instructor, and learner data for evaluation. ```bash $ docker-compose exec frappe bash -lc "cd frappe-bench && bench --site lms.localhost execute lms.demo.demo_data.create_demo_data" ``` -------------------------------- ### Map Site to Localhost Source: https://github.com/frappe/lms/blob/develop/bench-installation.md Add your site to the host file to enable access via localhost. This is crucial for local development and testing. ```bash bench --site lms.test add-to-hosts ``` -------------------------------- ### Create New Frappe Site Source: https://github.com/frappe/lms/blob/develop/bench-installation.md Use this command to create a new site for your Frappe application. Replace 'lms.test' with your desired site name. ```bash bench new-site lms.test ``` -------------------------------- ### Create a HelloWorld Widget Source: https://github.com/frappe/lms/blob/develop/lms/lms/widgets/HelloWorld.html This snippet shows how to define a simple reusable widget in Frappe. Widgets can be called from other templates using the `widgets` object. ```html {# Widget to demonostrate how to write a widget. A wiget is a reusable template, that can be used in other templates. To this widget can be called as: {{ widgets.HelloWorld(name="World") }} #} {{ _("Hello"), _{{ name }}_! ``` -------------------------------- ### Skip Onboarding Functionality Source: https://github.com/frappe/lms/blob/develop/lms/templates/onboarding_header.html Handles the click event for the 'Skip' button, calling a Frappe client method to set the onboarding complete status and then reloading the page. ```javascript frappe.ready(() => { $(".onboarding-skip").click((e) => { skip_onboarding(e); }); }); const skip_onboarding = (e) => { frappe.call({ method: "frappe.client.set_value", args: { doctype: "LMS Settings", name: "LMS Settings", fieldname: "is_onboarding_complete", value: 1, }, freeze: true, callback: function (data) { window.location.reload(); } }) } ``` -------------------------------- ### Signup Form HTML with Jinja Templating Source: https://github.com/frappe/lms/blob/develop/lms/templates/signup-form.html Renders the signup form fields using Jinja templating. It dynamically includes a 'User Category' field based on LMS settings and displays custom content if configured. ```html {% set custom_signup_content = frappe.db.get_single_value("LMS Settings", "custom_signup_content") %} {{ _("Full Name") }} {{ _("Email") }} {% if frappe.db.get_single_value("LMS Settings", "user_category") %} {{ _("User Category") }} {{ _("Category") }} {{ _("Business Owner") }} {{ _("Manager (Sales/Marketing/Customer)") }} {{ _("Employee") }} {{ _("Student") }} {{ _("Freelancer/Just looking") }} {{ _("Others") }} {% endif %} {% if custom_signup_content %} {{ custom_signup_content }} {% endif %} {{ _("Sign up") }} [{{ _("Have an account? Login") }}](#login) ``` -------------------------------- ### Display Exercise and Submission Code Source: https://github.com/frappe/lms/blob/develop/lms/templates/exercise.html Renders the exercise title, description, and either the user's submission or the default exercise code. Uses Jinja templating for dynamic content. ```html {% set submission = exercise.get_user_submission() %} {{ submission.solution if submission else exercise.code }} ``` -------------------------------- ### Signup Form JavaScript Event Handlers Source: https://github.com/frappe/lms/blob/develop/lms/templates/signup-form.html Initializes event listeners for the signup form. It attaches a change handler to the user category select and a submit handler to the form itself. ```javascript frappe.ready(function () { $("#user_category").on("change", (e) => { style_category(e); }); $(".signup-form").on("submit", (e) => { signup(e); }); }); ``` -------------------------------- ### Handle New Sign Up Form Submission Source: https://github.com/frappe/lms/blob/develop/lms/www/new-sign-up.html This JavaScript code handles the submission of the new sign-up form. It collects user input, sends it to the server using a POST request, and displays a success message or redirects the user upon successful account creation. ```javascript frappe.ready(() => { $("#submit").click(function () { var data = { full_name: $("#full_name").val(), signup_email: $("#signup_email").val(), username: $("#username").val(), password: $("#password").val(), invite_code: $("#invite_code").val(), }; frappe.call({ type: "POST", method: "lms.lms.doctype.invite_request.invite_request.update_invite", args: { "data": data }, callback: (data) => { $("input").val(""); if (data.message == "OK") { frappe.msgprint({ message: __("Your Account has been successfully created!"), clear: true }); setTimeout(function() { window.location.href = "/login"; }, 2000); } } }); return false; }); }) ``` -------------------------------- ### Display Courses Under Review (Jinja) Source: https://github.com/frappe/lms/blob/develop/lms/templates/courses_under_review.html This Jinja template code fetches courses under review and displays them using a CourseCard widget. If no courses are found, it shows a message indicating this. ```html {% set courses = get_courses_under_review() %} {% if courses | length %} {% for course in courses %} {{ widgets.CourseCard(course=course) }} {% endfor %} {% else %} ![](/assets/lms/icons/comment.svg) {{ _("No courses under review") }} {{ _("When a course gets submitted for review, it will be listed here.") }} {% endif %} ``` -------------------------------- ### Handle Invite Request Submission Source: https://github.com/frappe/lms/blob/develop/lms/lms/widgets/RequestInvite.html Attaches a click event listener to the submit button. It captures the email, calls a Frappe API to create an invite request, and displays messages based on the API response (e.g., invalid email, success, already used, user exists). ```javascript frappe.ready(() => { $("#submit-invite-request").click(function () { var invite_email = $("#invite_email").val() frappe.call({ method: "lms.lms.doctype.invite_request.invite_request.create_invite_request", args: { invite_email: invite_email }, callback: (data) => { if (data.message == "invalid email") { $(".email-validation") && $(".email-validation").remove(); if (invite_email) { var message = `
`; } else { var message = `
`; } $("#invite-request-form").append(message); } else { $("#invite-request-form").hide(); if (data.message == "OK") { var message = `

Thanks for your interest in Mon School. We have recorded your interest and we will get back to you shortly.

`; } else if (data.message == "invite") { var message = `

Email ${invite_email} has already been used to request an invitation.

`; } else if (data.message == "user") { var message = `

Looks like there is already an account with email ${invite_email}. Would you like to login?

`; } $(".jumbotron").append(message); } } }) }) }) ``` -------------------------------- ### Fetch and Display Recently Published Courses Source: https://github.com/frappe/lms/blob/develop/lms/lms/web_template/recently_published_courses/recently_published_courses.html Fetches a list of LMS courses ordered by publication date and iterates through them to display course cards. Use this to populate a section with the latest courses. ```html {% set courses = frappe.db.get_list('LMS Course', fields=["name", "short_introduction", "upcoming", "title", "image", "currency", "enable_certification", "paid_course"], order_by="published_on desc", page_length=courses_count) %} {% for course in courses %} {{ widgets.CourseCard(course=course, read_only=False) }} {% endfor %} ``` -------------------------------- ### Live Code Editor for Exercises Source: https://github.com/frappe/lms/blob/develop/lms/lms/widgets/Exercise.html Renders an interactive code editor for exercises. It can display user submissions or default exercise code and tracks the last submission time. ```html {% from "www/macros/livecode.html" import LiveCodeEditorJS, LiveCodeEditor with context %} Exercise {{exercise.index_label}}: {{ exercise.title }} -------------------------------------------------------- {{frappe.utils.md_to_html(exercise.description)}} {% if exercise.image %} {{exercise.image}} {% endif %} {% set submission = exercise.get_user_submission() %} {{ LiveCodeEditor(exercise.name, code=submission.solution if submission else exercise.code, reset_code=exercise.code, is_exercise=True, last_submitted=submission and submission.creation) }} ``` -------------------------------- ### JavaScript Function for User Signup Source: https://github.com/frappe/lms/blob/develop/lms/templates/signup-form.html Handles the signup form submission. It prevents the default form submission, validates email and name, and makes a Frappe API call to sign up the user. ```javascript const signup = (e) => { e.preventDefault(); const email = ($("#signup_email").val() || "").trim(); const full_name = frappe.utils.xss_sanitise(($("#signup_fullname").val() || "").trim()); if (!email || !validate_email(email) || !full_name) { login.set_status('{{ _("Valid email and name required") }}', 'red'); return false; } frappe.call({ method: "lms.lms.user.sign_up", args: { "email": email, "full_name": full_name, "verify_terms": $("#signup-terms").prop("checked") ? 1 : 0, "user_category": $("#user_category").length ? $("#user_category").val() : "" }, statusCode: login.login_handlers }) return false; } ``` -------------------------------- ### Display Courses or No Courses Message (Jinja) Source: https://github.com/frappe/lms/blob/develop/lms/templates/course_list.html This Jinja template snippet checks if the 'courses' list has any items. If it does, it iterates through the list and renders a 'CourseCard' widget for each course. Otherwise, it displays a message indicating that there are no courses. ```html {% if courses | length %} {% for course in courses %} {{ widgets.CourseCard(course=course, read_only=False) }} {% endfor %} {% else %} ![](/assets/lms/icons/comment.svg) {{ _("No {0}").format(title) }} {{ _("There are no {0} on this site.").format(title.lower()) }} {% endif %} ``` -------------------------------- ### Render Course Cards in HTML Source: https://github.com/frappe/lms/blob/develop/lms/lms/web_template/course_cards/course_cards.html This Jinja2 template code iterates over a list of courses, retrieves detailed information for each course from the database, and then renders a CourseCard widget for each. It's used to display a list of courses on a page. ```html {% for course_row in courses %} {% set course = frappe.db.get_value("LMS Course", course_row.course, ["name", "short_introduction", "upcoming", "title", "image", "currency", "enable_certification", "paid_course", "course_price"], as_dict=True) %} {{ widgets.CourseCard(course=course, read_only=False) }} {% endfor %} ``` -------------------------------- ### Explore More Courses Link Source: https://github.com/frappe/lms/blob/develop/lms/lms/web_template/course_cards/course_cards.html This Jinja2 snippet generates a localized link to the main courses page. It's typically used at the end of a course listing to allow users to view all available courses. ```html [{{ _("Explore More") }}]({{ get_lms_route('courses') }}) ``` -------------------------------- ### Configure Development Server CSRF Source: https://github.com/frappe/lms/blob/develop/frontend/README.md Add this key-value pair to your `site_config.json` to prevent CSRFToken errors during development with the Vite dev server. ```json "ignore_csrf": 1 ``` -------------------------------- ### Display Enrolled Courses in HTML Source: https://github.com/frappe/lms/blob/develop/lms/lms/web_template/courses_enrolled/courses_enrolled.html This Jinja template code checks if a user has any enrolled courses (in progress or completed) and then iterates through them to display a course card for each. ```html {% set enrolled = get_enrolled_courses().in_progress + get_enrolled_courses().completed %} {% if enrolled | length %} {% for course in enrolled %} {{ widgets.CourseCard(course=course) }} {% endfor %} {% endif %} ``` -------------------------------- ### Stop Docker Services Source: https://github.com/frappe/lms/blob/develop/docker-installation.md Stop the running Docker services using docker-compose down. Use the --volumes flag to completely reset the instance. ```bash $ docker-compose down --volumes $ docker-compose up ``` -------------------------------- ### Display User Notifications Source: https://github.com/frappe/lms/blob/develop/lms/templates/notifications.html Iterates through notifications, fetches user details, and displays notification subject, date, and a link. Includes avatar display. ```html {% if notifications | length %} {% for notification in notifications %} {% set member = frappe.db.get_value("User", notification.from_user, ["username", "full_name", "user_image"], as_dict=1) %} {{ widgets.Avatar(member=member, avatar_class="avatar-medium") }} {{ notification.subject }} {{ frappe.utils.pretty_date(notification.creation) }} []({{ notification.url }}) {% endfor %} {% else %} ![](/assets/lms/icons/comment.svg) {{ _("No Notifications") }} {{ _("You don't have any notifications.") }} {% endif %} ``` -------------------------------- ### JavaScript Function to Style User Category Source: https://github.com/frappe/lms/blob/develop/lms/templates/signup-form.html Dynamically sets the text color for the user category select element based on whether a value is selected. Uses CSS variables for theming. ```javascript const style_category = (e) => { let category_color = $(e.currentTarget).val() ? "var(--text-color)" : "var(--text-muted)"; $("#user_category").css("color", category_color); } ``` -------------------------------- ### Change Production Base URL Source: https://github.com/frappe/lms/blob/develop/frontend/README.md Modify the base URL for your frontend app in production by updating the `createWebHistory` argument in `src/router.js`. ```javascript createWebHistory('/frontend/') ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.