Skip to content

Changelog: Pro preview teaser + upsell menu (free) - #328

Merged
iftakharul-islam merged 1 commit into
developfrom
feat/changelog-pro-preview
Jul 16, 2026
Merged

iftakharul-islam merged 1 commit into
developfrom
feat/changelog-pro-preview

Conversation

@anik-fahmid

@anik-fahmid anik-fahmid commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Free-side support for the Pro Changelog module.

  • Settings teaser — a locked Changelog tab (ProPreviews) shown in the free plugin when Pro is inactive, using the existing preview + upgrade-overlay pattern. Hidden when Pro is active (wedocs_pro_loaded).
  • Upsell menu — a Changelogs submenu under weDocs (right after Docs) that opens a Pro upsell page; registered only when Pro is not active (no clash with the real Pro screen).

Pairs with weDevsOfficial/wedocs-pro#342.

Summary by CodeRabbit

  • New Features

    • Added a new “Changelogs” admin menu item for users who don’t have Pro enabled.
    • Added a preview of Changelog settings in the admin settings area, including display options, URL setup, header banner, and category chips.
    • The new screen includes an upgrade prompt with a link to Pro pricing.
  • Bug Fixes

    • The new menu item is placed directly under Docs for easier navigation.

- Locked "Changelog" settings tab in the free plugin (ProPreviews) shown
  when Pro is inactive, matching the existing preview/overlay pattern.
- "Changelogs" admin submenu under weDocs (after Docs) that opens a Pro
  upsell page, registered only when Pro is not active.
@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds a "Changelogs" admin submenu upsell (ChangelogUpsell class) shown under weDocs menu when Pro is inactive, wired into Admin.php's constructor. Adds a corresponding React ChangelogSettings preview component registered in ProPreviews' settings menu and templates when Pro is not loaded.

Changes

Changelog Upsell Feature

Layer / File(s) Summary
ChangelogUpsell admin class and wiring
includes/Admin/ChangelogUpsell.php, includes/Admin.php
New class hooks into admin_menu to register and reorder a "Changelogs" submenu under weDocs, rendering an upsell screen with feature list and upgrade link when Pro is inactive; Admin::__construct() instantiates it.
Changelog settings preview component and menu wiring
src/components/ProPreviews/ChangelogSettings.js, src/components/ProPreviews/index.js
New static preview React component for Changelog settings, added to wedocs_settings_menu and wedocs_settings_page_templates filter outputs when Pro isn't loaded.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

Suggested labels: Needs Review

Suggested reviewers: iftakharul-islam

Poem

A rabbit hops through wp-admin's halls,
Spies a menu where "Changelogs" calls,
No Pro? No worry, an upsell will show,
With bullets and buttons all in a row,
Hop, hop, upgrade — off to Pro it goes! 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: a free Changelog preview teaser plus an upsell menu for Pro.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/changelog-pro-preview

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 PHPStan (2.2.2)

PHP Fatal error: Uncaught Error: Undefined constant "ABSPATH" in /includes/functions.php:423
Stack trace:
#0 /includes/functions.php(397): wedocs_is_plugin_active()
#1 /vendor/composer/autoload_real.php(39): require('...')
#2 /vendor/composer/autoload_real.php(43): {closure}()
#3 /vendor/autoload.php(25): ComposerAutoloaderInit66c238beed3e8eafcac8e4833a7b6d7e::getLoader()
#4 phar:///usr/bin/phpstan/bin/phpstan(46): require_once('...')
#5 phar:///usr/bin/phpstan/bin/phpstan(107): _PHPStan_2874a496b{closure}()
#6 /usr/bin/phpstan(7): require('...')
#7 {main}
thrown in /includes/functions.php on line 423
Fatal error: Uncaught Error: Undefined constant "ABSPATH" in /includes/functions.php:423
Stack trace:
#0 /includes/functions.php(397): wedocs_is_plugin_active()
#1 /vendor/composer/autoload_real.php(39): require('...')
#2 /vendor/composer/autoload_real.php(43): {closure}()
#3 /vendor/autoload.php(25): ComposerAutoloaderInit66c238beed3e8eafcac8e4833a7b6d7e::getLoader()
#4 phar:///usr/bin/phpstan/bin/phpstan(46): require_once('...')
#5 phar:///usr/bin/phpstan/bin/phpstan(107): _PHPStan_2874a496b{closure}()
#6 /usr/bin/phpstan(7): require('...')
#7 {main}
thrown in /includes/functions.php on line 423


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@includes/Admin/ChangelogUpsell.php`:
- Around line 57-80: The reorder_menu method in ChangelogUpsell currently
inserts the wedocs-changelog entry at a fixed position, which can place it
before the Docs item. Update the logic to find the existing Docs submenu entry
within $submenu['wedocs'] and splice the Changelogs item immediately after that
entry instead of always using index 1. Keep the existing checks for
is_pro_active() and the wedocs submenu, and reuse the current $submenu['wedocs']
traversal in reorder_menu to locate both items robustly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5726ddae-4b75-429d-97a8-08f12b7d634c

📥 Commits

Reviewing files that changed from the base of the PR and between dd786d1 and 84f4c5e.

📒 Files selected for processing (4)
  • includes/Admin.php
  • includes/Admin/ChangelogUpsell.php
  • src/components/ProPreviews/ChangelogSettings.js
  • src/components/ProPreviews/index.js

Comment on lines +57 to +80
public function reorder_menu() {
global $submenu;

if ( $this->is_pro_active() || empty( $submenu['wedocs'] ) ) {
return;
}

$index = null;
foreach ( $submenu['wedocs'] as $i => $item ) {
if ( isset( $item[2] ) && 'wedocs-changelog' === $item[2] ) {
$index = $i;
break;
}
}

if ( null === $index ) {
return;
}

$entry = $submenu['wedocs'][ $index ];
unset( $submenu['wedocs'][ $index ] );
$submenu['wedocs'] = array_values( $submenu['wedocs'] );
array_splice( $submenu['wedocs'], 1, 0, [ $entry ] );
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect how the Docs submenu page is registered to confirm it always lands at index 0
rg -n "add_submenu_page|add_menu_page" includes/Admin/Docs_List_Table.php includes/Admin.php

Repository: weDevsOfficial/wedocs-plugin

Length of output: 166


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the admin files and inspect menu registration / submenu ordering logic.
git ls-files | rg '^(includes/Admin/|includes/Admin\.php|includes/Admin/Docs_List_Table\.php)'
printf '\n--- search ---\n'
rg -n "add_submenu_page|add_menu_page|wedocs-changelog|wedocs'" includes/Admin includes -g '!vendor' || true

Repository: weDevsOfficial/wedocs-plugin

Length of output: 50384


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the relevant file structure and read the target file around the commented lines.
fd -a "ChangelogUpsell.php|Admin.php|Docs_List_Table.php" .
printf '\n--- outline ---\n'
ast-grep outline includes/Admin/ChangelogUpsell.php --view expanded || true
printf '\n--- target lines ---\n'
sed -n '1,160p' includes/Admin/ChangelogUpsell.php | cat -n

Repository: weDevsOfficial/wedocs-plugin

Length of output: 6091


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the submenu registration block to see whether "Docs" is intentionally inserted first.
sed -n '1,170p' includes/Admin/Menu.php | cat -n

Repository: weDevsOfficial/wedocs-plugin

Length of output: 4430


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check whether anything can prepend or otherwise reorder the wedocs submenu items.
rg -n "wedocs_submenu|add_submenu_page\(\s*'wedocs'|add_submenu_page\(\s*\"wedocs\"" includes .

Repository: weDevsOfficial/wedocs-plugin

Length of output: 370


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "wedocs_submenu|add_submenu_page\(\s*'wedocs'|add_submenu_page\(\s*\"wedocs\"" includes .

Repository: weDevsOfficial/wedocs-plugin

Length of output: 370


🌐 Web query:

WordPress add_menu_page automatically adds first submenu item same slug index 0 submenu order

💡 Result:

In WordPress, when you add a custom top-level menu using add_menu_page, WordPress automatically creates a first submenu item that shares the same name and slug as the parent menu [1][2]. This is default behavior intended to ensure the top-level menu has a clickable page associated with it [3][2]. To manage or remove this duplicate first submenu item, developers typically use one of the following approaches: 1. Matching Slugs (Common Pattern): You can make the top-level menu and the first submenu share the exact same menu_slug [4][2]. This causes the submenu item to effectively override or merge with the parent's default submenu, which is a standard technique when you want the top-level link to point to a specific page or when you want to avoid the appearance of a redundant sub-item [4][5]. 2. Removing the Submenu: You can explicitly remove the automatically generated submenu item using the remove_submenu_page function after it has been registered [1][6]. This is done within an action hooked to admin_menu, ensuring it runs after the menu creation: remove_submenu_page( 'parent_slug', 'menu_slug'); 3. Manipulating the Global Submenu Variable: For more granular control, developers sometimes unset the item directly from the global $submenu array [7]. This is often considered a less "clean" method than using the provided API functions, but it allows for total removal of the index entry that WordPress generates [7]. 4. Using a Dummy Capability: Some developers set a capability that the current user does not have (e.g., 'do_not_allow') for the parent menu, preventing the submenu from appearing or behaving in specific ways, though this can hide the menu entirely if not handled carefully with subsequent add_submenu_page calls that use the correct capabilities [8]. If your goal is to have the top-level menu name be different from the first submenu item, the recommended approach is to ensure the first submenu item is registered with a matching slug as the parent, which prevents the duplication of the label [4][2]. If you wish to entirely remove the first submenu entry from the sidebar, using remove_submenu_page is the most standard and supported method [1].

Citations:


Insert Changelogs after the Docs item, not at a fixed index. WordPress keeps the parent wedocs submenu in the array, and this class appends Changelogs at position 1, which puts it before Docs in the default order. Find the Docs entry and splice after it instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@includes/Admin/ChangelogUpsell.php` around lines 57 - 80, The reorder_menu
method in ChangelogUpsell currently inserts the wedocs-changelog entry at a
fixed position, which can place it before the Docs item. Update the logic to
find the existing Docs submenu entry within $submenu['wedocs'] and splice the
Changelogs item immediately after that entry instead of always using index 1.
Keep the existing checks for is_pro_active() and the wedocs submenu, and reuse
the current $submenu['wedocs'] traversal in reorder_menu to locate both items
robustly.

@iftakharul-islam
iftakharul-islam merged commit e14a98e into develop Jul 16, 2026
1 check passed
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