Skip to content

Match WPBakery SEO Settings to Gutenberg Model - #2209

Merged
rudrakshi-gupta merged 3 commits into
feature/1622-video-seo-sitemapfrom
feature/2183-wpbakery-seo-parity
Oct 20, 2026
Merged

rudrakshi-gupta merged 3 commits into
feature/1622-video-seo-sitemapfrom
feature/2183-wpbakery-seo-parity

Conversation

@rudrakshi-gupta

@rudrakshi-gupta rudrakshi-gupta commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

Summary

The SEO Settings tab of the WPBakery GoDAM Video element showed only part of the Video SEO data. The Gutenberg block (Video SEO Schema modal) and the Elementor widget (SEO Settings popover) both show more:

  • Content URL, Upload Date, Duration and Video Thumbnail URL were missing.
  • With Override SEO = No, Headline, Description and Family Friendly were hidden too, so editors couldn't see any of the SEO values being sent to search engines.
  • There were no sync/override notices and no Reset to media library defaults action.

This PR brings the WPBakery tab in line with the Gutenberg modal: same fields, same order, same read-only / editable behaviour, same notices.

Closes #2183. Part of the Video SEO epic #1622.

Before / after

Field Before (WPBakery) After (WPBakery) Gutenberg modal
Override SEO ✅ Dropdown ✅ Dropdown ✅ Toggle
Sync / override notice ❌ Field description only ✅ Info / warning notice ✅
Reset to media library defaults ❌ ✅ Link in the override notice ✅
Content URL ❌ Missing ✅ Read-only ✅ Read-only
Headline ⚠️ Hidden unless Override = Yes ✅ Read-only unless Override = Yes ✅
Description ⚠️ Hidden unless Override = Yes ✅ Read-only unless Override = Yes ✅
Upload Date ❌ Missing ✅ Read-only ✅ Read-only
Duration ❌ Missing ✅ Read-only ✅ Read-only
Video Thumbnail URL ❌ Missing ✅ Read-only ✅ Read-only
Is Family Friendly ⚠️ Hidden unless Override = Yes ✅ Read-only unless Override = Yes ✅
Exclude from video sitemap ✅ ✅ ✅

What's included

1. SEO params (inc/classes/wpbakery-elements/class-wpb-godam-video.php)

  • New params: seo_content_url, seo_upload_date, seo_duration and seo_thumbnail_url.
    • These attribute names were already read by Seo::godam_get_video_seo_data_from_wpbakery(), but there was no field in the editor to show or set them.
  • Every SEO param now depends only on a video being selected (id not empty).
    • Headline, Description and Family Friendly no longer depend on seo_override = 1, so they're always visible.
  • The fields are reordered to match the Gutenberg modal.
  • Labels and help text are aligned with Gutenberg: "Is Family Friendly", "Title of the video", the ISO 8601 examples, and the HLS .m3u8 wording for Content URL.

2. Editor behaviour (assets/src/js/wpbakery/wpbakery-video-selector-param.js)

  • syncSeoPanel() runs when the element's panel opens, when the video changes, and when Override SEO changes.
    • Panel open is detected by the existing MutationObserver when the SEO params are added to the page (WPBakery never fires vc.reload), so it doesn't depend on WPBakery's dependency events.
    • It fetches /wp/v2/media/<id>, using the existing cached fetchAttachmentData().
    • Content URL, Upload Date, Duration and Thumbnail URL are always filled from the video and read-only. Content URL prefers rtgodam_hls_transcoded_url over source_url, matching the schema output from [EPIC] GoDAM Video SEO: correct schema, video sitemap, key moments #1622.
    • Headline, Description and Is Family Friendly show the Media Library values and are read-only while Override = No. They become editable when Override = Yes, keeping their current values, as in Gutenberg.
    • Values are built the same way as the Gutenberg modal: HTML is stripped from title and description, and the upload date uses appendTimezoneOffsetToUTC( date_gmt ).
  • Read-only without disabling.
    • Text fields use readonly. All read-only fields are greyed out.
    • Is Family Friendly on WPBakery 9 is a select2 widget (wpbselect2), so the lock goes on the widget: a CSS rule blocks clicks, select2:opening is cancelled for keyboard access, and the widget's focus box leaves the tab order. The hidden <select> is never touched, because select2 copies its tabindex and would stay out of the tab order after unlocking. A plain <select> (older WPBakery) is locked directly, and its tabindex is restored when unlocked.
    • Nothing is disabled, so WPBakery still saves the values.
  • Notices under Override SEO, with the Gutenberg wording:
    • Override = No: a blue info notice, "SEO data is automatically synced from the media library…".
    • Override = Yes: a yellow warning, "You have overridden the default SEO…", with a Reset to media library defaults link. The link restores the Media Library headline, description and family-friendly values and sets Override back to No.
  • Stale requests are ignored. Each sync gets a request ID, so a slow lookup for a previously selected video can't overwrite the current one. This uses the same pattern as the filename warning from feat(seo): fix VideoObject schema and add video sitemap #2186.
  • The existing filename-title warning and the prefill-on-override behaviour are unchanged.

3. Server side (inc/classes/class-seo.php)

  • Override = No never uses stored copies. Since every SEO param is now saved, godam_get_video_seo_data_from_wpbakery() uses the shortcode's values only when Override = Yes. With Override = No and no usable Media Library data (video deleted, title cleared), nothing is output instead of a stale VideoObject.
  • The video is still tracked in that case (and the page's video list is no longer cleared when the page ends up with no schema), so filling in the Media Library title later re-syncs the page without a re-save.
  • WPBakery's encoding is decoded in overridden values: Seo::decode_wpbakery_param() turns its backtick markers back into ", [ and ] (same mapping as vc_value_from_safe()), so Demo [2026] "Final" comes out right in the schema.
  • With Override = Yes, Content URL, upload date, thumbnail and duration still come from the attachment when it exists.
  • Existing pages: the new params default to empty, so pages work without a re-save, and their schema output is unchanged.
  • No new options, meta or block attributes.

Testing

Automated

  • composer phpunit: all tests pass, including tests/php/VideoSeoWpbakeryTest.php (Override on/off, deleted video, empty title still tracked, encoded characters).
  • vendor/bin/phpcs on class-wpb-godam-video.php: clean.
  • npx wp-scripts lint-js on wpbakery-video-selector-param.js: clean.

Manual

Run npm run build:dev and hard-refresh the editor first.

  1. Edit a page with WPBakery, add or open a GoDAM Video element and go to the SEO Settings tab.
    • ✅ With no video selected, no SEO fields show.
    • ✅ After selecting a video, all 9 fields show, in the Gutenberg order.
  2. Override SEO = No:
    • ✅ All fields are filled from the Media Library and greyed out.
    • ✅ You can't type in Content URL, Headline, Description, Upload Date, Duration or Thumbnail URL, and you can't change Family Friendly.
    • ✅ The blue sync notice shows.
  3. Override SEO = Yes:
    • ✅ Headline, Description and Is Family Friendly become editable; the other four stay read-only.
    • ✅ The yellow notice with Reset to media library defaults shows.
  4. Edit the Headline, then save and reopen the element. ✅ The custom headline is kept.
  5. Click Reset to media library defaults. ✅ The Media Library headline and description come back, and Override returns to No.
  6. Replace the video. ✅ All fields refresh to the new video's values.
  7. Put the same video on a Gutenberg page and compare both page sources.
    • ✅ The VideoObject matches: contentUrl, embedUrl, name, description, uploadDate, duration, thumbnailUrl and isFamilyFriendly.
  8. Open a WPBakery page saved before this branch. ✅ It loads normally, and its schema is unchanged without a re-save.
  9. ✅ The filename-title warning and Exclude from video sitemap still work.
  10. ✅ No changes in the Gutenberg modal or the Elementor SEO popover.

Screenshots

Screenshot 2026-10-19 at 11 57 02 AM Screenshot 2026-10-19 at 11 59 57 AM

@rudrakshi-gupta rudrakshi-gupta self-assigned this Oct 19, 2026
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

🔍 WordPress Plugin Check Report

⚠️ Status: Passed with warnings

📊 Report

🎯 Total Issues ❌ Errors ⚠️ Warnings
15 0 15

⚠️ Warnings (15)

📁 inc/classes/class-video-sitemap.php (1 warning)
📍 Line 🔖 Check 💬 Message
629 WordPress.DB.SlowDBQuery.slow_db_query_meta_key Detected usage of meta_key, possible slow query.
📁 readme.txt (2 warnings)
📍 Line 🔖 Check 💬 Message
0 mismatched_plugin_name Plugin name "GoDAM - Organize WordPress Media Library & File Manager with Unlimited Folders for Images, Videos & more" is different from the name declared in plugin header "GoDAM".
0 trademarked_term The plugin name includes a restricted term. Your chosen plugin name - "GoDAM - Organize WordPress Media Library & File Manager with Unlimited Folders for Images, Videos & more" - contains the restricted term "wordpress" which cannot be used at all in your plugin name.
📁 inc/classes/class-video-sitemap-core-provider.php (1 warning)
📍 Line 🔖 Check 💬 Message
73 WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound Hook names invoked by a theme/plugin should start with the theme/plugin prefix. Found: "wp_sitemaps_index_entry".
📁 assets/build/css/main.css (1 warning)
📍 Line 🔖 Check 💬 Message
0 EnqueuedStylesScope This style is being loaded in all contexts.
📁 assets/src/libs/analytics.min.js (5 warnings)
📍 Line 🔖 Check 💬 Message
0 EnqueuedScriptsScope This script is being loaded in all frontend contexts.
0 NonBlockingScripts.NoStrategy This script on http://localhost:8880 (with handle analytics-library) is loaded in the footer. Consider a defer or async script loading strategy instead.
0 NonBlockingScripts.NoStrategy This script on http://localhost:8880/2026/10/19/hello-world/ (with handle analytics-library) is loaded in the footer. Consider a defer or async script loading strategy instead.
0 NonBlockingScripts.NoStrategy This script on http://localhost:8880/sample-page/ (with handle analytics-library) is loaded in the footer. Consider a defer or async script loading strategy instead.
0 NonBlockingScripts.NoStrategy This script on http://localhost:8880/demo-attachment-post/ (with handle analytics-library) is loaded in the footer. Consider a defer or async script loading strategy instead.
📁 assets/build/js/main.min.js (5 warnings)
📍 Line 🔖 Check 💬 Message
0 EnqueuedScriptsScope This script is being loaded in all frontend contexts.
0 NonBlockingScripts.NoStrategy This script on http://localhost:8880 (with handle rtgodam-script) is loaded in the footer. Consider a defer or async script loading strategy instead.
0 NonBlockingScripts.NoStrategy This script on http://localhost:8880/2026/10/19/hello-world/ (with handle rtgodam-script) is loaded in the footer. Consider a defer or async script loading strategy instead.
0 NonBlockingScripts.NoStrategy This script on http://localhost:8880/sample-page/ (with handle rtgodam-script) is loaded in the footer. Consider a defer or async script loading strategy instead.
0 NonBlockingScripts.NoStrategy This script on http://localhost:8880/demo-attachment-post/ (with handle rtgodam-script) is loaded in the footer. Consider a defer or async script loading strategy instead.

🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check

@subodhr258 subodhr258 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 7dae2aa: read the code, ran PHPUnit (408 pass), ran the PR's JS in jsdom with jQuery, and checked it against the WPBakery 9.0 (beta 3) source on our dev site. Not run in a live WPBakery editor.

Claims

Claim How checked Result
All 9 fields show once a video is picked, in the Gutenberg order Code True
Content URL prefers the HLS URL Code True
Read-only without disabling, so WPBakery still saves Code + WPBakery source Text fields: true. Family Friendly: not on WPBakery 9.0, inline
Fields fill when the panel opens (vc.reload) WPBakery source + jsdom Works, but not through vc.reload, which WPBakery never fires, inline
Stale lookups are ignored jsdom: slow lookup for video A, then a fast one for B True, B's values stay
Reset to media library defaults Code Restores headline, description, Family Friendly = Yes and Override = No, same as Gutenberg
No server-side or data changes Code + a run of godam_get_video_seo_data_from_wpbakery() Elements with Override = No now save copies of the values, and the server can fall back to them, inline
Old pages load and keep their schema without a re-save Code True

POT: five new strings aren't in languages/godam.pot (for example "You have overridden the default SEO..."). The POT check only runs on PRs to develop or main, so it'll fail when this is retargeted. Regenerate with npm run build:prod && composer pot.

Two things that aren't from this PR, noted once:

  • appendTimezoneOffsetToUTC() parses the REST date_gmt (it has no Z) as the browser's local time, so in India the Upload Date field shows 5 h 30 min earlier than the real time. Gutenberg and Elementor share the helper. The server ignores the stored value while the attachment exists. Fix: parse date_gmt + 'Z' at the call sites that pass date_gmt.
  • WPBakery saves " in params as two backticks, and [ and ] as `{` and `}`. godam_get_video_seo_data_from_wpbakery() reads them as-is, so an overridden headline like Demo [2026] "Final" shows up with those markers in the schema.

Not tested: a live WPBakery editor, WPBakery 8.x, WPBakery auto-save.

Comment thread assets/src/js/wpbakery/wpbakery-video-selector-param.js Outdated
Comment thread assets/src/js/wpbakery/wpbakery-video-selector-param.js Outdated
Comment thread inc/classes/wpbakery-elements/class-wpb-godam-video.php

@subodhr258 subodhr258 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed at 74901b3: read the changes since 7dae2aa, ran PHPUnit (425 pass) and the JS unit tests (545 pass), ran the WPBakery script in jsdom with WPBakery 9.0's own select2, and ran godam_get_video_seo_data_from_wpbakery() on the base and on this PR with the same shortcodes. Not run in a live WPBakery editor.

Earlier comments

Comment At 74901b3
Family Friendly isn't locked on WPBakery 9.0 (select2) Fixed: with Override = No the select2 box can't be clicked, opened or changed from the keyboard, and it unlocks when Override is Yes
vc.reload never fires Removed. Small note in the thread
Override = No elements now save copies the server can fall back to Fixed on the server: the copies are ignored when Override is No. A deleted video or a cleared title now outputs nothing instead of the old values
Five strings missing from the POT Still missing, list below

Also fixed here: ", [ and ] in an overridden headline now come out right in the schema (decode_wpbakery_param()), which I'd noted last time as not from this PR.

POT: these five strings are still not in languages/godam.pot:

  • "Description of the video. It is recommended to add a description for better video SEO."
  • "Enable to customize SEO for this element. When disabled, SEO data is synced from the media library."
  • "ISO 8601 datetime format. Example: 2024-01-15T10:30:00+00:00" (the POT has a version with different dashes)
  • "URL of the video file or HLS (.m3u8) stream that search engines index. Filled in from the selected video."
  • "You have overridden the default SEO. Changes to this video in the media library will not update the SEO for this element."

The POT check doesn't run here because the base isn't develop. If this merges into the #2186 branch before that one's POT is regenerated, that one regeneration picks these up too. Otherwise run npm run build:prod && composer pot here.

One small issue, inline: a video whose Media Library title is empty isn't tracked, so filling in the title later doesn't update the page.

Not tested: a live WPBakery editor, WPBakery 8.x, the front-end editor.

Comment thread inc/classes/class-seo.php

@subodhr258 subodhr258 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving at 10968d6. All my comments are fixed, including tracking a video whose Media Library title is empty, with a test. PHPUnit (550) passes.

@rudrakshi-gupta
rudrakshi-gupta merged commit 3bc3818 into feature/1622-video-seo-sitemap Oct 20, 2026
4 checks passed
@rudrakshi-gupta
rudrakshi-gupta deleted the feature/2183-wpbakery-seo-parity branch October 20, 2026 07:51
rudrakshi-gupta added a commit that referenced this pull request Oct 20, 2026
* feat(seo): fix VideoObject schema and add video sitemap (#1622 v1)

Make GoDAM's video schema indexable by Google and add a video sitemap
that plugs into Yoast SEO, Rank Math, All in One SEO or the WordPress
core sitemap. No new public URLs are created.

- Schema contentUrl now uses the HLS (.m3u8) stream, falling back to the
  original file; the DASH .mpd is never output. Resolved at output time,
  so pages cached before this change are fixed without a re-save.
- Add embedUrl pointing at GoDAM's existing video-embed player page.
- Never output an empty description: fall back to a 160-char transcript
  excerpt (fetched on save only, cached in _godam_seo_transcript_excerpt),
  then the page excerpt, otherwise omit the property.
- Output isFamilyFriendly as a real JSON boolean (string values such as
  "false" are parsed correctly) and omit an empty uploadDate.
- Add Video_Sitemap: /godam-video-sitemap.xml with one <url> per
  published page and one <video:video> per video, built from the cached
  video SEO post meta via the shared schema builder so both always agree.
- Exclude drafts, private and password-protected posts, pages noindexed
  in Yoast / Rank Math / AIOSEO, and videos the editor excludes.
- List the sitemap in the Yoast, Rank Math and AIOSEO indexes, or via a
  core sitemap provider when none is active; paginate at 1000 URLs,
  cache per site with version-based invalidation.
- Add GoDAM > Settings > SEO with an "Enable video sitemap" toggle (off
  by default) and a per-video "Exclude from video sitemap" toggle in
  Gutenberg, Elementor and WPBakery.
- Warn editors in all three editors when a video title looks like a
  raw file name.
- Prefer the HLS URL when prefilling SEO contentUrl in the editors.
- Add new filters: godam_video_seo_content_url, godam_video_seo_embed_url,
  godam_video_seo_description, godam_video_sitemap_enabled,
  godam_video_sitemap_entries_per_page, godam_video_sitemap_post_types,
  godam_video_sitemap_exclude_post, godam_video_sitemap_entry.
- Add PHPUnit coverage (VideoSeoSchemaTest, VideoSitemapTest) and Jest
  tests for the filename-title check.

* Resolve feedback

* Resolve feedbacks and regenrate POT file

* Revert the POT file

* Resolve Privacy Issue

* feat(seo): add key moments to video schema from chapters (#1597) (#2194)

Output each GoDAM video chapter as a schema.org Clip in the VideoObject's
hasPart, so Google can show "key moments" (jump-to links) for the video
in search results.

- Add Seo::get_key_moment_clips(): reads the chapters from the
  attachment's rtgodam_meta at output time, so editing chapters updates
  the schema without re-saving the page.
- Each Clip has name, startOffset, endOffset and a deep link of the form
  <page>?t=<seconds>#godam-video-<attachment id>, which the GoDAM player
  already uses to seek on page load.
- A clip ends at the chapter's own endTime, else the next chapter's
  start, else the video duration (clamped to the duration when known).
- Skip chapters with no title, an unreadable start, a start at or past
  the end of the video, or zero length; drop duplicate start times;
  strip HTML from chapter names.
- Parse chapter times as plain seconds, mm:ss or hh:mm:ss(.ms), falling
  back to originalTime when startTime is missing.
- Build clip URLs without add_query_arg(): use & on plain permalinks and
  drop any existing fragment from the page URL.
- Only add hasPart when the video has an attachment and a host page
  (render-time output on archives/404 has nothing to deep-link to).
- Add filters godam_video_seo_key_moments_enabled and
  godam_video_seo_key_moments.
- Move ISO 8601 duration parsing to Seo::iso8601_to_seconds();
  Video_Sitemap::iso8601_duration_to_seconds() now delegates to it.
- Add VideoSeoKeyMomentsTest (27 tests) and a get_permalink() test stub.

* Match WPBakery SEO Settings to Gutenberg Model (#2209)
subodhr258 added a commit that referenced this pull request Oct 22, 2026
* Stop the admin menu jumping when a GoDAM page loads (#2207)

* Fix: stop the admin menu jumping when a GoDAM page loads

pages/style.css restores Tailwind's border reset for every element on the
page. It is injected by page-css.min.js after the page has painted, and
core's a { transition: border .05s } then animates each admin menu link's
border from 3px to 0: every item grows from 34px to 40px and the whole
menu jumps by about 186px, then snaps back. Keep the reset off
#adminmenumain and #wpadminbar.

* Fix: open the Media Editor with the admin menu already folded

The editor folds the menu from React after the page has painted, so the
menu showed at full width and then collapsed. Add the folded body class
on the server when the editor opens a file.

* Keep the reset off the menu and admin bar containers too; test the editor fold

- pages/style.css also excludes #adminmenumain and #wpadminbar themselves,
  not only their descendants.
- MediaEditorMenuFoldTest: the Media Editor with an id gets 'folded';
  its file picker, other GoDAM pages, the Media Library and no screen
  do not.

* Regenerate the POT: 12 references into class-pages.php moved down

Line numbers only; no strings added or changed. Built like CI: Node
22.14.0, npm ci, npm run build:prod, composer pot.

* feat(seo): fix VideoObject schema and add video sitemap (#2186)

* feat(seo): fix VideoObject schema and add video sitemap (#1622 v1)

Make GoDAM's video schema indexable by Google and add a video sitemap
that plugs into Yoast SEO, Rank Math, All in One SEO or the WordPress
core sitemap. No new public URLs are created.

- Schema contentUrl now uses the HLS (.m3u8) stream, falling back to the
  original file; the DASH .mpd is never output. Resolved at output time,
  so pages cached before this change are fixed without a re-save.
- Add embedUrl pointing at GoDAM's existing video-embed player page.
- Never output an empty description: fall back to a 160-char transcript
  excerpt (fetched on save only, cached in _godam_seo_transcript_excerpt),
  then the page excerpt, otherwise omit the property.
- Output isFamilyFriendly as a real JSON boolean (string values such as
  "false" are parsed correctly) and omit an empty uploadDate.
- Add Video_Sitemap: /godam-video-sitemap.xml with one <url> per
  published page and one <video:video> per video, built from the cached
  video SEO post meta via the shared schema builder so both always agree.
- Exclude drafts, private and password-protected posts, pages noindexed
  in Yoast / Rank Math / AIOSEO, and videos the editor excludes.
- List the sitemap in the Yoast, Rank Math and AIOSEO indexes, or via a
  core sitemap provider when none is active; paginate at 1000 URLs,
  cache per site with version-based invalidation.
- Add GoDAM > Settings > SEO with an "Enable video sitemap" toggle (off
  by default) and a per-video "Exclude from video sitemap" toggle in
  Gutenberg, Elementor and WPBakery.
- Warn editors in all three editors when a video title looks like a
  raw file name.
- Prefer the HLS URL when prefilling SEO contentUrl in the editors.
- Add new filters: godam_video_seo_content_url, godam_video_seo_embed_url,
  godam_video_seo_description, godam_video_sitemap_enabled,
  godam_video_sitemap_entries_per_page, godam_video_sitemap_post_types,
  godam_video_sitemap_exclude_post, godam_video_sitemap_entry.
- Add PHPUnit coverage (VideoSeoSchemaTest, VideoSitemapTest) and Jest
  tests for the filename-title check.

* Resolve feedback

* Resolve feedbacks and regenrate POT file

* Revert the POT file

* Resolve Privacy Issue

* feat(seo): add key moments to video schema from chapters (#1597) (#2194)

Output each GoDAM video chapter as a schema.org Clip in the VideoObject's
hasPart, so Google can show "key moments" (jump-to links) for the video
in search results.

- Add Seo::get_key_moment_clips(): reads the chapters from the
  attachment's rtgodam_meta at output time, so editing chapters updates
  the schema without re-saving the page.
- Each Clip has name, startOffset, endOffset and a deep link of the form
  <page>?t=<seconds>#godam-video-<attachment id>, which the GoDAM player
  already uses to seek on page load.
- A clip ends at the chapter's own endTime, else the next chapter's
  start, else the video duration (clamped to the duration when known).
- Skip chapters with no title, an unreadable start, a start at or past
  the end of the video, or zero length; drop duplicate start times;
  strip HTML from chapter names.
- Parse chapter times as plain seconds, mm:ss or hh:mm:ss(.ms), falling
  back to originalTime when startTime is missing.
- Build clip URLs without add_query_arg(): use & on plain permalinks and
  drop any existing fragment from the page URL.
- Only add hasPart when the video has an attachment and a host page
  (render-time output on archives/404 has nothing to deep-link to).
- Add filters godam_video_seo_key_moments_enabled and
  godam_video_seo_key_moments.
- Move ISO 8601 duration parsing to Seo::iso8601_to_seconds();
  Video_Sitemap::iso8601_duration_to_seconds() now delegates to it.
- Add VideoSeoKeyMomentsTest (27 tests) and a get_permalink() test stub.

* Match WPBakery SEO Settings to Gutenberg Model (#2209)

* ci: run the POT check only on PRs into main (#2188)

* ci: run the POT check only on the develop → main merge

Feature PRs into develop no longer have to regenerate languages/godam.pot.
The release PR from develop into main still fails if the committed POT is
stale. PRs into main from any other branch skip the job.

* ci: run the POT check on every PR into main

Patch releases reach main from fix and hotfix branches, not only from
develop, so they need the check too. The branches: [main] trigger
already keeps it off feature PRs into develop.

* Pass only a numeric form ID to the form layer preview (#2223)

Cast the layer id to an integer in the preview template and in the Ninja Forms
and MetForm callbacks, and add unit tests for it.

* Keep the Gravity Forms recorder working after an AJAX page change (#2217)

* Keep the Gravity Forms recorder working after an AJAX page change

Gravity Forms replaces a page's markup on every AJAX page change or failed
submit. The recorder kept pointing at the replaced container, file input and
button, and Uppy had bound its dashboard trigger once to the old button, so
Start Recording opened nothing on the new page.

On every gform_post_render, an uploader whose markup left the page now finds
the new container by its id, reads the input and button from it, binds the
new button once and shows the recording it holds again.

* Regenerate the translation template for the recorder's moved lines

* Stop sending the signed-in viewer's email with video analytics (#2213)

* Stop sending the signed-in viewer's email with video analytics

The page params that GoDAM prints on every front-end page no longer carry
the current user's email address (`emailId`), and the analytics request body
no longer has an `email` field. The WordPress user id is still sent.

Tests: the request-body helper and the page params are both checked for the
absence of the email, including a page cached by an older version.

* Remove the viewer's email from the analytics data listed in the readme

The analytics.godam.io entry under External services no longer lists Email as data sent.

* Keep the signed-in viewer's email out of the player's page data

The player script's page data (godamData.currentLoggedInUserData) carried the current user's email address, which nothing in the browser reads. It now holds the display name and whether someone is signed in. The comments routes still read the email on the server.

* Keep the fixture lines untouched in the JS test

The explanation moves into the test, so the fixture lines this branch leaves alone cannot conflict with the sibling change.

* List the page's user fields instead of removing one

rtgodam_get_current_user_data_for_page() now returns only the display name and the sign-in type, so a field added later to the server-side user data is not printed into the page by accident.

* Regenerate the POT for the new line numbers

The new helper in custom-functions.php moves five strings further down the file, so their source references change. Nothing else in the file differs from develop.

* Clean up video share popup: remove GoDAM Central/Embed links, use Page link, show share button for all videos (#2211)

* Clean up video share popup links and share button gating

- Remove the redundant GoDAM Central and Embed copy fields from the share
  modal footer, keeping only the Page Link field.
- Point the social share links at the WordPress page link instead of the
  GoDAM Central URL, which is private by default and shows a login prompt.
- Show the share button for all videos when sharing is enabled in the
  block settings, instead of only transcoded videos.

Closes #2210

* Address review: keep share anchor and gate button on an ID

- Encode the share link with encodeURIComponent so the #godam-video-{id}
  anchor and any query param travel with the social share URL instead of
  splitting off (encodeURI left #, ? and & intact).
- Hide the share button for players with neither a WordPress attachment ID
  nor a transcoding job ID ("Insert from URL" embeds), since their share
  link could not target the video.
- Remove stale README references to the removed GoDAM Central/Embed links
  and correct the ID described for share links.

---------

Co-authored-by: KMchaudhary <kuldipkumar.chaudhary@rtcamp.com>

* Save converted MP3 audio as audio/mpeg, and fix files already saved as audio/mp3 (#2208)

* Fix: store transcoded MP3 audio as audio/mpeg, not audio/mp3

WordPress registers MP3 as audio/mpeg. Attachments saved as audio/mp3
were left out of REST media_type=audio, and REST ignored a
mime_type=audio/mp3 filter. New conversions are saved as audio/mpeg,
and a one-time migration (2.4.1 batch) fixes the ones saved before.

* Test the saved type, satisfy the hook-integrity check, retry a failed SELECT

- TranscodedAudioMimeTypeTest calls add_transcoded_files() and checks
  that converted audio is saved as audio/mpeg (video stays video/mp4).
  With the old audio/mp3 it fails.
- add_transcoded_files() starts $transcoded_files as array(), not false;
  PHP 8.1+ reported every conversion as a deprecated false-to-array use.
- The migration's two direct queries carry godam-coverage-ignore: the
  runner already runs it once per site.
- A failed SELECT now returns false so the runner retries, instead of
  marking the site done with nothing changed.
- The runner test checks batch order instead of which batch is last.

* Run the MP3 type migration in the 2.5.0 batch

2.4.1 ships without this change but still stores 2.4.1 as each site's
migration version, and the runner skips batches at or below the stored
version. Keyed 2.4.1, the migration would never run on sites that update
through 2.4.1; keyed 2.5.0 it runs for both 2.4.0 and 2.4.1 sites.

* Release prep v2.5.0: version bump, changelog and POT refresh (#2231)

- Version 2.5.0 in godam.php, readme.txt, README.md, package.json and package-lock.json.
- v2.5.0 changelog in readme.txt and CHANGELOG.md; v2.3.2 removed from readme.txt to keep the last three.
- Every @SInCE n.e.x.t replaced with 2.5.0 (51 tags in 6 files).
- languages/godam.pot regenerated from a production build.

* Fix the two new Plugin Check warnings in the Video SEO sitemap code (#2232)

- class-video-sitemap.php: the phpcs:ignore named slow_query_meta_key, which is not a sniff, so it ignored nothing. Use slow_db_query_meta_key.
- class-video-sitemap-core-provider.php: ignore NonPrefixedHooknameFound on WordPress core's own wp_sitemaps_index_entry filter.

* Keep page-builder shortcode text out of the video sitemap description (#2235)

* Keep page-builder shortcode text out of the video sitemap description

The sitemap is served at parse_request priority 1, before WPBakery and Divi
register their shortcodes, so core's strip_shortcodes() left tags such as
[vc_row] in the fallback description taken from the page text. Add the tag
names found in the text to strip_shortcodes()'s own list so unregistered
shortcodes are removed the same way registered ones are, which gives the same
description in the sitemap and on the front end.

The strip_shortcodes() test stub removed every [tag], which hid the bug. It now
follows core: only registered shortcodes are removed.

* Only strip builder-style unregistered shortcode names from the fallback description

Review of the first version found that it also removed ordinary bracketed text
([sic], [1], [b]bold[/b]) from the front-end description, that one very long
bracketed word made core's pattern too large and the description empty, that a
tag another filter had taken off the strip list was re-added, and that the
filter stayed registered if stripping threw.

Only names that look like a builder tag are added now (a letter first, an
underscore or hyphen in the name, 64 characters at most), tags that are
registered are left to core, and the filter is removed in a finally block.
New tests pin the cap, the length limit, the filter removal and the ordinary
bracketed text.

* Set the 2.5.0 changelog date to October 22, 2026 (#2236)

2.5.0 releases on 22 Oct (release ticket rtCamp/godam-plugin-wp#60), but readme.txt and CHANGELOG.md dated it October 21.

---------

Co-authored-by: Kuldip Chaudhary <64731232+KMchaudhary@users.noreply.github.com>
Co-authored-by: Rudrakshi Gupta <109859631+rudrakshi-gupta@users.noreply.github.com>
Co-authored-by: Vishal Kumar <vishnshiv3@gmail.com>
Co-authored-by: KMchaudhary <kuldipkumar.chaudhary@rtcamp.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants