A GitHub template repository for building WordPress plugins that extend
LearnDash LMS. It ships a working, minimal plugin
— a LearnDash-aware dynamic block, an example custom post type, a REST endpoint,
local dev via wp-env, and a tag-driven release workflow — so you start from a
buildable, installable plugin instead of a blank folder.
This template's conventions are extracted from ld-lesson-journal.
-
Click Use this template → Create a new repository on GitHub (or clone this repo and point it at your own remote).
-
Run the one-time setup script to rename the placeholders:
bin/setup.sh "My Plugin Name" my-plugin-slug mypIt replaces every placeholder, renames the placeholder files, and deletes itself. The three arguments are optional — omit them to be prompted.
Arg Placeholder Becomes Used for Name LD Plugin Templateyour title plugin header, labels Slug ld-plugin-templateyour slug folder, text domain, main file Prefix ldpt/LDPTyour prefix functions, constants, classes, block namespace, CSS/JS handles -
Build and start hacking (see Development).
bin/setup.sh performs a case-sensitive find/replace across the repo:
LD Plugin Template→ your plugin nameld-plugin-template→ your slug (src/ld-plugin-template.php, text domain,.wp-env.jsonmapping, release workflow)LDPT→ your uppercase prefix (LDPT_VERSION, class names likeLDPT_REST)ldpt→ your lowercase prefix (ldpt_init, block nameldpt/example,ldpt-frontendhandles, CSS classes)
and renames src/ld-plugin-template.php and src/includes/class-ldpt-*.php accordingly.
- WordPress 6.5+
- PHP 8.1+
- LearnDash LMS 4.0+
The plugin checks for LearnDash at runtime (defined( 'LEARNDASH_VERSION' ))
and shows an admin notice instead of fatally erroring when it is missing.
- LearnDash dependency check — features only register when LearnDash is active.
- Shared block category — registers a
LearnDash LMS Blocksinserter category (idempotent). - Example dynamic block (
ldpt/example) — a server-rendered block with a course picker fed by the REST route, plus editableRichTextfields. - Example CPT + taxonomy + meta (
ldpt_item) — hidden from the front end, nested under the LearnDash admin menu, exposed to REST, with a side meta box. - Example REST routes (
ldpt/v1/courses,ldpt/v1/lessons) — capability-checked endpoints for editor-side course/lesson pickers. - Activation / deactivation / uninstall hooks with clear extension points for custom tables.
wp-envconfig for local WordPress.- Release workflow — pushing a
v*tag builds, version-stamps, zips, and publishes a GitHub Release.
src/
ld-plugin-template.php # Plugin bootstrap: constants, hooks, dependency check
uninstall.php # Clean removal
includes/
class-ldpt-post-type.php # Example CPT + taxonomy + meta box
class-ldpt-rest.php # Example REST routes (courses / lessons)
blocks/
example/ # Example dynamic block (block.json, index.js, render.php)
assets/
css/ldpt-frontend.css # Shared frontend styles (handle: ldpt-frontend)
css/ldpt-admin.css # Admin styles
js/ldpt-frontend.js # Shared frontend script (handle: ldpt-frontend)
bin/
setup.sh # One-time rename script (self-deleting)
.github/workflows/release.yml # Tag-driven build & release
webpack.config.js # One entry per block under src/blocks/*
.wp-env.json # Local WordPress environment
- Node.js 20 LTS —
wp-env(via@wordpress/scripts@30/@wordpress/env@11) is not compatible with very new Node majors (e.g. 24/26), wherewp-env startcan silently fail to bring up the WordPress container. The release workflow pins Node 20. - Docker (running, for
wp-env)
npm installLearnDash is not publicly downloadable, so wp-env expects it locally. Place a
copy of the sfwd-lms plugin at wp-content/plugins/sfwd-lms (this path is
git-ignored), then start the environment.
npm run build # Build block JS/CSS into src/build/
npm run start # Watch mode for development
npm run lint:js # Lint block JavaScript
npm run env:start # Start local WordPress via wp-env
npm run env:stop # Stop wp-env- Create
src/blocks/<name>/withblock.json,index.js, andrender.php(copyblocks/example/as a starting point). - Add an entry to
webpack.config.js:'<name>/index': path.resolve( __dirname, 'src/blocks/<name>/index.js' ). - Register it in the bootstrap's
ldpt_register_blocks():register_block_type( LDPT_PATH . 'blocks/<name>' ).
git tag v0.1.0
git push origin v0.1.0The workflow stamps the version into the plugin header and LDPT_VERSION,
builds the blocks, zips src/ into an installable plugin folder, and attaches
the zip to an auto-generated GitHub Release. Tags containing a hyphen
(e.g. v0.2.0-beta.1) are marked as prereleases.
MIT — see LICENSE. MIT is GPL-compatible, so plugins built from this template remain fine to distribute on WordPress.org.