=== Course Layouts – Elementor Addon for TutorLMS === Contributors: userelements Tags: elementor, tutorlms, course, online courses, lms Requires at least: 6.0 Tested up to: 6.8 Requires PHP: 7.4 Stable tag: 1.0.2 Requires Plugins: elementor, tutor License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Build TutorLMS course catalogs, filters, student dashboards, and instructor directories in Elementor—with AJAX, dynamic tags, and schema markup. == Description == Course Layouts – Elementor Addon for TutorLMS gives you a complete set of Elementor widgets to design course discovery pages, student dashboards, and instructor directories for Tutor LMS—without writing code. Place filters in a sidebar, search in a header, and the course grid anywhere on the page. Link them with a shared **Listing ID** and they work together instantly via AJAX. Every layout is fully customizable in Elementor, with responsive column controls, extensive style options, and optional Elementor Loop Item templates for pixel-perfect course cards. = Why use Course Layouts? = * **All-in-one course discovery** — Grid, filters, search, sort, chips, and pagination in one cohesive system * **Design freedom** — Built-in cards or your own Elementor Loop Item / Saved Template designs * **Composable layouts** — Split discovery controls across your page (sidebar filters, top search, bottom grid) * **Personalized experiences** — Show enrolled, in-progress, completed, or wishlisted courses per student * **Theme Builder ready** — "Current Query" mode respects archive taxonomies, authors, and search in AJAX * **Conversion-focused cards** — Smart price labels, enrollment CTAs, progress bars, badges, and wishlist * **SEO support** — Optional ItemList / Course JSON-LD schema on course grids (3+ courses) * **Accessible & fast** — ARIA labels, live result announcements, skeleton loading, and debounced AJAX = Elementor Widgets (10) = All widgets live under the **Essential TutorLMS** category in Elementor. **Course Directory Grid** The main course listing widget. Responsive 1–6 column grid, built-in card or Loop Item skin, embedded or standalone filters/search, pagination, and full styling controls. **Course Categories Grid** Display course categories in a card or list layout with image, title, description, course count, and optional view button. Sort by name, slug, ID, course count, description, or random. **Course Filter Panel** Standalone filter sidebar or horizontal bar. Connects to any Course Directory Grid via Listing ID. Up to 8 configurable filter fields with Clear All. **Course Search** Standalone debounced search box linked to a course listing by Listing ID. **Active Filter Chips** Removable filter pills that reflect the current filter state—ideal for zero-results recovery and quick filter removal. **Sort & Result Count** Standalone sort dropdown (newest, title, popularity, price) plus live "Showing X–Y of Z" result count. **My Courses** Student dashboard grid (extends Course Directory Grid) pre-set for enrolled, in-progress, completed, or wishlisted courses with progress display. **Continue Learning** Highlights the student's most recent in-progress course with thumbnail, next lesson, progress bar, and resume button. **Instructor Directory** Browse Tutor instructors in a responsive grid with search, category filter, ratings, course/student counts, bio, and profile CTA. = Composable Discovery (Listing ID + CLETA.Bus) = Version 1.3 introduces a pub/sub architecture so discovery widgets can live anywhere on the page: 1. Set a **Listing ID** on the Course Directory Grid (default: `courses`). 2. Add Filter Panel, Search, Active Filter Chips, and Sort & Result Count widgets anywhere. 3. Give each the same Listing ID—they sync automatically via `CLETA.Bus`. Filters, search, sort, and pagination update the grid over AJAX without a full page reload. Filter state can be written to URL parameters for bookmarking, sharing, and browser Back/Forward navigation. = Filtering & Search = **Filter field types:** category, level (Tutor 4.x meta), tags, instructor, price, rating, duration, and custom meta key. **Filter styles:** dropdown, checkbox, radio buttons, and range slider (price, rating, duration use real catalog min/max/step values, cached for performance). **Smart facets:** option counts beside each value; empty options hidden automatically. **Auto-apply:** filters apply on change; range sliders debounce before reload. **Search:** debounced AJAX search across course titles and related fields; works embedded in the grid or via the standalone Search widget. **Combine filters:** up to 6 filter fields in the grid widget, up to 8 in the standalone Filter Panel. = Query Sources = Control which courses appear in the grid: * **All courses** — full catalog (optionally limited by category) * **Current Query** — respects Theme Builder archive context (category, tag, author, search) * **Enrolled** — courses the logged-in student is enrolled in * **Not enrolled** — courses the student has not joined * **In progress** — started but not completed * **Completed** — finished courses * **Wishlisted** — courses on the student's wishlist Personalised sources require a logged-in student. My Courses defaults to enrolled with quick switching between student-specific lists. = Course Cards = **Built-in card skin** toggles for: * Featured image with configurable size * Title, excerpt (configurable length), and whole-card link * Price (free, sale, membership, subscription-aware labels) * Rating, duration, lesson count, enrollment count * Instructor name and link * Categories, level, tags, and benefits * State-aware CTA: Enroll / Buy / Start / Continue * Progress bar for enrolled students * Badges: New, Free, Bestseller (enrollment threshold filterable) * Wishlist heart (integrates with Tutor LMS wishlist) * Skeleton loading placeholders during AJAX updates **Loop Item / Saved Template skin** lets you design cards in Elementor Pro Loop Items or any Saved Template, bind Tutor Dynamic Tags, and use them in the grid—including during AJAX filter, load-more, and pagination responses. = Elementor Dynamic Tags = A **Tutor LMS (CLETA)** dynamic tag group exposes course fields for use in any Elementor widget or Loop Item: * Course Title * Course Price * Course Level * Course Duration * Course Lesson Count * Course Enrollment Count * Course Rating * Course Instructor Name * Course Instructor URL * Course Progress % * Course Enrollment Status * Course URL (permalink) = Pagination = * **Page numbers** — classic numbered pagination with position control * **Load More** — append next page on button click * **Infinite scroll** — auto-load as the user scrolls * Configurable courses per page (1–100) * Accurate "Showing X–Y of Z" counts = Sorting = Default sort in widget settings or via the Sort & Result Count bar: * Date (newest / oldest) * Title (A–Z / Z–A) * Popular (review count) * Price (low to high / high to low) * ID, name, modified, menu order, random = Instructor Directory = * Responsive 1–4 column grid * Filter by course categories taught * Minimum rating threshold (3+, 4+, 5 stars) * Sort by name, newest, or highest rated * Front-end search and category filter * Card toggles: avatar, name, job title, bio (truncated), course count, rating, student count, profile CTA * Pagination = SEO Schema Markup = The Course Directory Grid outputs JSON-LD **ItemList** schema with nested **Course** entities when 3 or more courses are displayed. Includes title, description, URL, image, instructor, provider, and pricing where available. Auto-injection on single course pages is intentionally disabled to avoid conflicts with Tutor LMS, Yoast SEO, or Rank Math. = Performance & Security = * Assets register globally; widgets enqueue only what they need * Widget settings cached in transients (server-authoritative on AJAX—client cannot override) * Filter catalog stats (price, duration, level facets) cached and busted on course save/delete * Nonce verification on all AJAX endpoints * Debounced search and range sliders to reduce server requests = Accessibility = * ARIA labels on filter and search controls * `aria-live` regions for result count and grid updates * `aria-busy` during AJAX loading * Enter-key handling for search and filter fields * Screen-reader text on sort controls = Responsive Design = Both course and category grids include responsive column breakpoints for desktop, tablet, and mobile. Filter panels support vertical (sidebar) and horizontal (toolbar) layouts. == Tutorials & Guides == - [17 Awesome Websites Made with Tutor LMS](https://www.userelements.com/list/tutor-lms-website-examples/) - [The Complete List of Tutor LMS Shortcodes and How to Use Them – Tutor LMS](https://www.userelements.com/tutor-lms-shortcodes/) - [Sending Reminder Emails to Inactive Students – Tutor LMS](https://www.userelements.com/sending-reminder-emails-to-inactive-students-tutor-lms/) - [Tutor LMS – Get Student Information in PHP](https://www.userelements.com/tutor-lms-get-student-information-in-php/) - [How to Hide, Remove or Disable Reviews or Star Rating in Tutor LMS](https://www.userelements.com/remove-tutor-reviews/) - [Create a User Directory with Elementor](https://userelements.com/create-user-directory-elementor/) - [Best WordPress LMS Plugins to Create and Sell Courses Online](https://www.userelements.com/list/best-wordpress-lms-plugins/) == More Plugins by UserElements == - [Personalized User Menu for TutorLMS](https://www.userelements.com/mightymenu-tutorlms/) - [WP User Data](https://www.userelements.com/wp-user-data/) - [User Broadcast Email](https://www.userelements.com/user-broadcast-email/) - [Elementor Product Table for WooCommerce](https://wordpress.org/plugins/product-table-for-elementor) == Support == For technical support, feature requests, or general questions, please visit userelements.com or create a support ticket in the WordPress.org plugin forum. == Installation == 1. Upload the plugin files to the `/wp-content/plugins/course-layouts-elementor-addon-for-tutorlms` directory, or install through the WordPress plugins screen. 2. Activate the plugin through the **Plugins** screen in WordPress. 3. Ensure both **Elementor** and **Tutor LMS** are installed and activated. 4. Edit any page with Elementor and find widgets under **Essential TutorLMS**. 5. For a basic course catalog: add **Course Directory Grid**, configure columns and card options, enable pagination if needed. 6. For a composable layout: set a **Listing ID** on the grid, then add **Course Filter Panel**, **Course Search**, **Active Filter Chips**, and **Sort & Result Count** with the same ID. 7. For student dashboards: add **Continue Learning** and **My Courses** to your dashboard page. 8. For custom card designs: create an Elementor Loop Item template, bind Tutor Dynamic Tags, then select it under **Card Skin → Loop Item / Template** on the grid. == Frequently Asked Questions == = Does this plugin require Tutor LMS? = Yes. Course Layouts extends Tutor LMS with Elementor widgets. Tutor LMS must be installed and active. = Does this plugin require Elementor? = Yes. All widgets are built for the Elementor page builder. Elementor Pro is optional but recommended for Loop Item templates. = How do standalone filters connect to the course grid? = Set the same **Listing ID** on the Course Directory Grid and on any standalone widget (Filter Panel, Search, Chips, Sort bar). They communicate via the built-in CLETA.Bus without extra configuration. = Can I customize the course grid layout? = Yes. Choose 1–6 responsive columns, toggle every card element, and style cards, titles, meta, pagination, and filters in Elementor. For fully custom designs, switch to the Loop Item / Saved Template card skin. List and masonry layouts for the course grid are planned for a future release. = Can I design my own course cards? = Yes. Set **Card Skin** to **Loop Item / Template**, create a Loop Item in Elementor Theme Builder (or pick a Saved Template), bind **Tutor LMS (CLETA)** Dynamic Tags, and select the template on the widget. Custom cards work with AJAX filtering, load more, and pagination. = Does the plugin support filtering and search? = Yes. Filter by category, level, instructor, tags, price, rating, and duration—with facet counts, range sliders, and auto-apply. Search is available embedded in the grid or via the standalone Search widget. = Can I build a student dashboard? = Yes. Use **Continue Learning** for the latest in-progress course and **My Courses** for enrolled, in-progress, completed, or wishlisted course grids with progress bars and resume CTAs. = Does the plugin support instructor listings? = Yes. The **Instructor Directory** widget lists Tutor instructors with search, category filter, ratings, course/student counts, bios, and profile links. = Is the plugin responsive? = Yes. Course and category grids include responsive column breakpoints. Filter panels support vertical and horizontal layouts. = Does the plugin support SEO? = The Course Directory Grid outputs ItemList / Course JSON-LD schema when displaying 3 or more courses. Single-course schema auto-injection is disabled to avoid duplicate markup from Tutor LMS or SEO plugins. = Can I use pagination with the course grid? = Yes. Choose numbered pagination, a load-more button, or infinite scroll. Configure courses per page from 1 to 100. = Does the plugin work with WooCommerce? = Yes. Course prices and purchasable state come from Tutor LMS, including WooCommerce monetization. CTAs link to the course page for enrollment or checkout. = Can I filter courses by multiple criteria? = Yes. Combine up to 6 filter fields in the grid (or 8 in the standalone Filter Panel). Active Filter Chips show applied filters and let visitors remove them individually. = Are filter selections shareable via URL? = Yes. Enable **URL Parameters** on the grid. Filter and search state is written to the URL and restored on page load and browser Back/Forward. = Is the plugin accessible? = Filter and search controls include ARIA labels, live region announcements for result updates, and Enter-key handling. Skeleton loading uses `aria-busy` during AJAX requests. = Does the plugin support Theme Builder archives? = Yes. Set **Query Source** to **Current Query** inside an Elementor Theme Builder archive template. The widget snapshots the archive tax/author/search context so AJAX filtering stays scoped to the archive. == Screenshots == 1. Course Directory Grid Widget in Elementor Editor 2. Course Categories Grid Widget Configuration 3. Composable discovery layout with Filter Panel, Search, and Sort bar 4. Course grid styling options in Elementor == Changelog == = 1.0.2 = * Honest readme: removed claims for layouts, columns, price/CTA display, and filters that were not implemented * Assets register-only; enqueued via Elementor widget dependencies * Removed site-wide Elementor post scan on AJAX fallback; settings cached in a transient at render time * Fixed Tutor 4.x price API usage (get_raw_course_price) for schema and meta helpers * Fixed load-more ignoring sort order; fixed pagination "Showing X–Y of Z" count * Guarded frontend JS against missing localized widget settings * Schema: use real course duration meta; stop fabricating timeRequired; stop truncating descriptions to 60 chars * Removed empty content_template that blanked the Elementor editor preview * Removed shadow of Tutor core get_tutor_course_duration_context(); disabled auto schema on single course pages * Listing ID + CLETA.Bus pub/sub: standalone filters, search, chips, and sort drive any Course Grid * New widgets: Course Filter Panel, Course Search, Active Filter Chips, Sort & Result Count * New widgets: Continue Learning, My Courses (student dashboard) * Elementor Dynamic Tags group for Tutor course fields (price, level, duration, rating, progress, instructor, and more) * Course Grid Listing ID control; URL params work with external filters * Loop Item / Saved Template card skin for Course Directory Grid and My Courses (AJAX + load-more aware) * Instructor Directory widget: search, category filter, sort, ratings, course/student counts, profile CTA * Responsive 1–6 column control on the course grid * Price display (free, sale, membership, subscription-aware labels) * State-aware Enroll / Buy / Start / Continue CTA and enrolled progress bar * Working level filter via `_tutor_course_level` meta; price, rating, and duration filters applied in the query * Filter repeater raised to 6 fields; courses_count capped at 100 * URL filter state restored on load and on browser Back (popstate); Clear All unchecks checkboxes/radios * Price sort uses Tutor 4.x `tutor_course_price` meta key * excerpt_length control now honored in the card * Filters auto-apply on change; range sliders debounce reload * Default level filter uses Tutor course_levels() meta (not course-level taxonomy) * AJAX settings are server-authoritative only (no client widget_settings override) * Removed unused search_fields control and dead render_course_meta stub * ARIA labels and Enter-key handling always on (removed feature-flag toggles) * Removed non-functional rating/enrollment/duration/lesson sort options until a sort index exists * Packaging: index.php silencers, uninstall.php (clears cleta_ws_* transients), load_plugin_textdomain + languages/ * Query Source: All / Current Query (archive) / Enrolled / Not enrolled / In progress / Completed / Wishlisted * Current Query snapshots archive tax/author/search for AJAX so Theme Builder course archives work * Price and duration filter buckets derived from catalog data + site currency (cached) * Range sliders use real min/max/step for price, rating, and duration * Facet counts on category/tag/level filters; empty options hidden * Zero-results recovery with removable filter chips * Course badges (New / Free / Bestseller), wishlist heart, whole-card stretched link * Skeleton loading states and aria-live result announcements = 1.0.1 = * Fixed wp_enqueue_scripts and other WordPress integration issues * Improved AJAX error handling and security * Enhanced widget settings management * Added better fallback handling for missing dependencies = 1.0.0 = * Initial release with Course Directory Grid widget * Course Categories Grid widget * Advanced filtering and search functionality * AJAX-powered pagination and load more * SEO schema markup integration * Responsive design and accessibility features * Extensive customization options