embedpress
Last commit date
Core
2 months ago
EmbedPress
2 months ago
assets
2 months ago
languages
2 months ago
vendor
3 months ago
.env.example
2 months ago
CLAUDE.md
2 months ago
autoloader.php
10 months ago
embedpress.php
2 months ago
includes.php
2 months ago
index.html
9 years ago
milestone-demo.html
8 months ago
providers.php
6 months ago
readme.txt
2 months ago
tsconfig.node.json
10 months ago
wpml-config.xml
4 years ago
CLAUDE.md
153 lines
| 1 | # EmbedPress |
| 2 | |
| 3 | Free WordPress plugin that embeds content from 250+ providers (YouTube, Vimeo, Google Docs/Drive/Maps, PDFs, Twitch, Wistia, etc.) via Gutenberg blocks, an Elementor widget, and a classic shortcode. Sister repo `embedpress-pro` adds Pro features on top of this codebase. |
| 4 | |
| 5 | - **Plugin entry:** `embedpress.php` (current version in header — bump on release) |
| 6 | - **PHP namespace root:** `EmbedPress\` (`EmbedPress/` directory) + bootstrap helpers in `Core/` |
| 7 | - **Source roots (two parallel ones):** |
| 8 | - `static/` — hand-written admin & frontend JS/CSS (admin.js, front.js, `initplyr.js`, ep-player-ui.js, settings.js, plyr.css, lightbox, lazy-load, carousel, etc.). **This is the main source folder for runtime scripts/styles.** Vite copies it verbatim into `assets/` during build. |
| 9 | - `src/` — React/Vite-compiled sources for Gutenberg blocks and the AdminUI app (Dashboard, Settings, Onboarding, CustomPlayer, MilestoneNotification). |
| 10 | - **Build output:** `assets/` (everything from `static/` plus the compiled `src/` bundles) |
| 11 | - **Min runtime:** PHP per `composer.json`, Node ≥ 20, npm ≥ 10 |
| 12 | |
| 13 | ## Project Management — FluentBoards |
| 14 | |
| 15 | Tasks live on **FluentBoards** at https://projects.startise.com (NOT Zoobbe — that's deprecated for this project as of 2026-04-28). |
| 16 | |
| 17 | - **Board:** `Development - EmbedPress` (board ID `17`) |
| 18 | - **Daily-work stage:** `My Day (Akash)` — Akash drags cards in each morning; standup/report scripts pull only from this stage |
| 19 | - **Akash's user ID:** `35` |
| 20 | - **Tooling:** use the `fluentboards` skill (REST API via WP App Password). Do NOT call `zb` / `zoobbe` for this project. |
| 21 | - **Work week:** Sun–Thu (Fri/Sat are public off-days in BD) |
| 22 | |
| 23 | When asked to create a card, do it autonomously — infer priority, label, stage, description from the request. Default stage `To-Do`; default priority `Medium`. Always assign to the logged-in user. |
| 24 | |
| 25 | When asked to "fix it": |
| 26 | 1. Implement the fix in code, run tests where possible |
| 27 | 2. Branch `fix/<short-description>`, commit, note hash |
| 28 | 3. Move card to the done stage and mark complete |
| 29 | 4. **Mandatory:** comment on the card with branch name, files changed, commit hash |
| 30 | |
| 31 | The fluentboards skill forbids creating stages via API — if a stage is missing, ask the user to create it in the UI. |
| 32 | |
| 33 | ## Repository layout |
| 34 | |
| 35 | ``` |
| 36 | embedpress.php Plugin bootstrap, hooks, version header |
| 37 | providers.php Map of provider classes → URL patterns (250+ providers) |
| 38 | includes.php Wires constants and autoload |
| 39 | autoloader.php PSR-4-ish autoloader for EmbedPress\ |
| 40 | composer.json / package.json |
| 41 | |
| 42 | Core/ Plugin lifecycle: AssetManager, LocalizationManager, init.php |
| 43 | EmbedPress/ Main PHP namespace |
| 44 | AMP/ AMP compatibility |
| 45 | Analytics/ View tracking |
| 46 | Elementor/ Widget integration (Embedpress_Elementor_Integration) |
| 47 | Ends/ Front/Back ends |
| 48 | Gutenberg/ Block registration & server-side rendering |
| 49 | BlockManager.php |
| 50 | EmbedPressBlockRenderer.php ← build_player_options() — must mirror JS getPlayerOptions() |
| 51 | FallbackHandler.php |
| 52 | InitBlocks.php |
| 53 | Includes/Classes/ Helper, Feature_Enhancer, PlayerPresets, Notices, etc. |
| 54 | Plugins/ Per-provider integrations |
| 55 | Providers/ Provider classes referenced in providers.php |
| 56 | RestAPI.php |
| 57 | Shortcode.php Classic [embed]/[embedpress] shortcode |
| 58 | |
| 59 | static/ PRIMARY source folder — hand-written runtime JS/CSS (copied as-is to assets/) |
| 60 | js/ admin.js, front.js, initplyr.js, ep-player-ui.js, settings.js, |
| 61 | ep-pdf-lightbox.js, lazy-load.js, gallery-justify.js, instafeed.js, |
| 62 | carousel.js, gutneberg-script.js, analytics-tracker.js, feature-notices.js, |
| 63 | license.js, meetup-timezone.js, pdf-gallery*.js, preview.js, sponsored.js |
| 64 | css/ admin.css, embedpress.css, ep-player.css, plyr.css, modal.css, |
| 65 | settings.css, pdf-gallery.css, lazy-load.css, carousel.min.css, etc. |
| 66 | fonts/, images/, pdf/, pdf-flip-book/, embedpress.pdf |
| 67 | |
| 68 | src/ Compiled sources (Vite + React) — blocks and admin SPAs |
| 69 | AdminUI/ Dashboard, Settings, Onboarding, CustomPlayer, MilestoneNotification |
| 70 | Analytics/ |
| 71 | Blocks/ All Gutenberg blocks (see "Blocks" below) |
| 72 | Frontend/ Frontend React/runtime modules |
| 73 | Shared/ Cross-block components/helpers |
| 74 | utils/ |
| 75 | |
| 76 | tests/ |
| 77 | bootstrap.php, stubs.php PHPUnit setup |
| 78 | unit/ PHPUnit |
| 79 | e2e/ Playwright (classic, gutenberg, elementor, dashboard projects) |
| 80 | |
| 81 | assets/ Build output (gitignored / committed per repo policy) |
| 82 | languages/ i18n (.pot via `npm run pot`) |
| 83 | docs/, scripts/, static/ |
| 84 | ``` |
| 85 | |
| 86 | ### Blocks (`src/Blocks/`) |
| 87 | |
| 88 | `EmbedPress`, `document`, `embedpress-calendar`, `embedpress-pdf`, `google-docs`, `google-drawings`, `google-forms`, `google-maps`, `google-sheets`, `google-slides`, `pdf-gallery`, `twitch`, `wistia`, `youtube`, plus shared `GlobalCoponents/`, `placeholders/`, `assets/`, `styles.js`. |
| 89 | |
| 90 | Each block typically has `src/components/{index.js, save.js, edit.js, deprecated.js, helper.js}`. The main `EmbedPress` block's `helper.js` `getPlayerOptions()` is the canonical example — its shape must match `EmbedPressBlockRenderer::build_player_options()` on the PHP side. |
| 91 | |
| 92 | ## Build / dev / test |
| 93 | |
| 94 | ```bash |
| 95 | npm run start # Vite watch (development build) |
| 96 | npm run build # production build → assets/ |
| 97 | npm run lint # ESLint over src/ |
| 98 | npm run lint:fix |
| 99 | npm run type-check # tsc --noEmit |
| 100 | npm run format # Prettier write |
| 101 | npm run pot # regenerate languages/embedpress.pot |
| 102 | |
| 103 | npm test # Vitest unit |
| 104 | npm run test:e2e # Playwright (all projects) |
| 105 | npm run test:e2e:gutenberg # narrow to one project: classic|gutenberg|elementor|dashboard |
| 106 | npm run test:e2e:headed # headed mode for debugging |
| 107 | npm run test:e2e:ui # Playwright UI runner |
| 108 | |
| 109 | composer install # PHP deps |
| 110 | vendor/bin/phpunit # PHP unit tests (phpunit.xml) |
| 111 | vendor/bin/phpcs # phpcs.xml ruleset |
| 112 | ``` |
| 113 | |
| 114 | E2E auth flow runs through `tests/e2e/auth.setup.js` and `global-setup.ts` — point the test runner at the WordPress site provisioned by `embedpress-docker`. |
| 115 | |
| 116 | ### Release build |
| 117 | `bash build.sh` (or `build.xml` Phing target) packages a distributable zip. WP-CLI alternative from a WordPress root: `wp dist-archive wp-content/plugins/embedpress embedpress`. |
| 118 | |
| 119 | ## Conventions |
| 120 | |
| 121 | ### Gutenberg blocks — backwards compatibility (applies to ALL blocks under `src/Blocks/`) |
| 122 | |
| 123 | Changing a block's `save()` output — markup, attributes, `data-options` shape, wrapper classes — breaks old posts: Gutenberg validates current `save()` against saved HTML and shows the *"Block contains unexpected or invalid content. Attempt recovery"* prompt on every mismatch, wiping the user's configuration. |
| 124 | |
| 125 | **Order of preference:** |
| 126 | |
| 127 | 1. **Conditional emission.** If the change is additive (new attributes off-by-default), emit the new keys/markup only when their toggle is `true`. Old posts (where new attrs read as defaults) regenerate the original markup byte-for-byte. |
| 128 | - Pattern: `...(playerEmailCapture && { email_capture: build() })` — not `email_capture: build() || false`. |
| 129 | - This was the working fix for #81243 in `src/Blocks/EmbedPress/src/components/helper.js` `getPlayerOptions()`. |
| 130 | |
| 131 | 2. **`deprecated[]` entry** in the block's `deprecated.js` (e.g. `src/Blocks/EmbedPress/src/components/deprecated.js`) when the markup change is unconditional. Provide a `save()` reproducing the previous markup and an identity `migrate`. New entries go at the **front** of the array. Wire `deprecated` into `registerBlockType` in the block's `index.js`. |
| 132 | |
| 133 | 3. **`isEligible: () => true`** as a safety-net catch-all forces WP to apply a deprecation even when its `save()` doesn't byte-match — useful when shared rendering (e.g. `DynamicStyles`) varies across revisions. |
| 134 | |
| 135 | **Mirror PHP and JS:** when a JS save shape changes, also update the matching PHP renderer (e.g. `EmbedPress/Gutenberg/EmbedPressBlockRenderer.php` `build_player_options()`). Both feed the same `data-options` JSON that frontend scripts in `static/js/` (`initplyr.js`, `ep-player-ui.js`, etc.) parse — drift between them ships broken embeds. |
| 136 | |
| 137 | ### Editing runtime scripts/styles |
| 138 | Most user-visible runtime behavior (player UI, lightbox, lazy-load, carousels, PDF gallery, settings page) lives in `static/js/` and `static/css/` as **hand-written, non-compiled** files. Edit them directly — Vite copies them to `assets/` on build. Don't add a build step for these unless converting them deliberately. |
| 139 | |
| 140 | ### Adding a provider |
| 141 | 1. Add a class under `EmbedPress/Providers/<Name>.php` |
| 142 | 2. Register it in `providers.php` with the URL patterns it should claim |
| 143 | 3. If it needs a dedicated block, scaffold under `src/Blocks/<name>/` |
| 144 | 4. If it needs server-rendered options, extend `EmbedPressBlockRenderer` accordingly |
| 145 | |
| 146 | ### Pro features |
| 147 | Pro lives in the sibling `embedpress-pro` repo and hooks into this codebase via filters/actions registered in `EmbedPress/`. When adding a Pro-gated key to block output, **always** make it conditional (see rule #1 above) so free-version users with the same posts don't get the recovery prompt. |
| 148 | |
| 149 | ## Related repos |
| 150 | - `embedpress-pro` — Pro extension (shares the FluentBoards board) |
| 151 | - `embedpress-docker` — local WP dev environment, also hosts the standup/report scripts and Playwright runners |
| 152 | - `embedpress-playwright-automation` — extra E2E suites |
| 153 |