From ff79968170bc46f0713d78fc77ef722a2e3d8c57 Mon Sep 17 00:00:00 2001
From: airano
Date: Wed, 18 Feb 2026 21:57:48 +0330
Subject: [PATCH] feat(wp): rename OpenPanel plugin to OpenPanel Self-Hosted
for WP.org
- Separate plugin identity for WordPress.org submission
- Text domain, folder, and file renamed to openpanel-self-hosted
- Description updated as fork of official OpenPanel plugin
Co-Authored-By: Claude Opus 4.6
---
README.md | 2 +-
wordpress-plugin/openpanel-self-hosted.zip | Bin 0 -> 11992 bytes
.../LICENSE | 0
.../index.php | 0
.../openpanel-self-hosted.php} | 74 +++++++++---------
.../readme.txt | 6 +-
wordpress-plugin/openpanel.zip | Bin 11702 -> 0 bytes
7 files changed, 42 insertions(+), 40 deletions(-)
create mode 100644 wordpress-plugin/openpanel-self-hosted.zip
rename wordpress-plugin/{openpanel => openpanel-self-hosted}/LICENSE (100%)
rename wordpress-plugin/{openpanel => openpanel-self-hosted}/index.php (100%)
rename wordpress-plugin/{openpanel/openpanel.php => openpanel-self-hosted/openpanel-self-hosted.php} (92%)
rename wordpress-plugin/{openpanel => openpanel-self-hosted}/readme.txt (94%)
delete mode 100644 wordpress-plugin/openpanel.zip
diff --git a/README.md b/README.md
index e62bae9..36c46a7 100644
--- a/README.md
+++ b/README.md
@@ -271,7 +271,7 @@ Some MCP Hub tools require companion WordPress plugins:
| SEO tools (`wordpress_get_post_seo`, etc.) | [SEO API Bridge](wordpress-plugin/seo-api-bridge/) ([Download ZIP](wordpress-plugin/seo-api-bridge.zip)) + Rank Math or Yoast SEO |
| WP-CLI tools (15 tools: `wp_cache_*`, `wp_db_*`, etc.) | Docker socket + `CONTAINER` env var |
| WordPress Advanced database/system tools | Docker socket + `CONTAINER` env var |
-| OpenPanel analytics integration | [OpenPanel](wordpress-plugin/openpanel/) ([Download ZIP](wordpress-plugin/openpanel.zip)) |
+| OpenPanel analytics integration | [OpenPanel Self-Hosted](wordpress-plugin/openpanel-self-hosted/) ([Download ZIP](wordpress-plugin/openpanel-self-hosted.zip)) |
| WooCommerce tools | WooCommerce plugin (separate `WOOCOMMERCE_` config) |
**Docker socket** is needed for WP-CLI and WordPress Advanced system tools. Add to your docker-compose:
diff --git a/wordpress-plugin/openpanel-self-hosted.zip b/wordpress-plugin/openpanel-self-hosted.zip
new file mode 100644
index 0000000000000000000000000000000000000000..4c1e2845248ff1f6fb6e7a7d6cf6918f44d410b4
GIT binary patch
literal 11992
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' . esc_html__('Choose between OpenPanel Cloud or your own Self-Hosted instance.', 'openpanel') . '
';
+ add_settings_section('op_hosting', __('Hosting Mode', 'openpanel-self-hosted'), function() {
+ echo '' . esc_html__('Choose between OpenPanel Cloud or your own Self-Hosted instance.', 'openpanel-self-hosted') . '
';
}, self::OPTION_KEY);
- add_settings_field('hosting_mode', __('Mode', 'openpanel'), function() {
+ add_settings_field('hosting_mode', __('Mode', 'openpanel-self-hosted'), function() {
$opts = get_option(self::OPTION_KEY);
$mode = isset($opts['hosting_mode']) ? $opts['hosting_mode'] : 'cloud';
?>
class="op-hosting-mode">
-
+
class="op-hosting-mode">
-
+
-
+
' . esc_html__('Configure your Self-Hosted OpenPanel URLs. Only required if using Self-Hosted mode.', 'openpanel') . '';
+ add_settings_section('op_selfhosted', __('Self-Hosted Settings', 'openpanel-self-hosted'), function() {
+ echo '' . esc_html__('Configure your Self-Hosted OpenPanel URLs. Only required if using Self-Hosted mode.', 'openpanel-self-hosted') . '
';
}, self::OPTION_KEY);
- add_settings_field('api_url', __('API URL', 'openpanel'), function() {
+ add_settings_field('api_url', __('API URL', 'openpanel-self-hosted'), function() {
$opts = get_option(self::OPTION_KEY);
printf(' ',
esc_attr(self::OPTION_KEY),
isset($opts['api_url']) ? esc_attr($opts['api_url']) : ''
);
- echo '' . esc_html__('Your OpenPanel API endpoint (e.g., https://api.openpanel.yourdomain.com)', 'openpanel') . '
';
+ echo '' . esc_html__('Your OpenPanel API endpoint (e.g., https://api.openpanel.yourdomain.com)', 'openpanel-self-hosted') . '
';
}, self::OPTION_KEY, 'op_selfhosted');
- add_settings_field('dashboard_url', __('Dashboard URL', 'openpanel'), function() {
+ add_settings_field('dashboard_url', __('Dashboard URL', 'openpanel-self-hosted'), function() {
$opts = get_option(self::OPTION_KEY);
printf(' ',
esc_attr(self::OPTION_KEY),
isset($opts['dashboard_url']) ? esc_attr($opts['dashboard_url']) : ''
);
- echo '' . esc_html__('Your OpenPanel Dashboard URL — used to load op1.js from your server instead of the CDN (e.g., https://openpanel.yourdomain.com)', 'openpanel') . '
';
+ echo '' . esc_html__('Your OpenPanel Dashboard URL — used to load op1.js from your server instead of the CDN (e.g., https://openpanel.yourdomain.com)', 'openpanel-self-hosted') . '
';
}, self::OPTION_KEY, 'op_selfhosted');
// Section: Main Settings
- add_settings_section('op_main', __('OpenPanel Settings', 'openpanel'), function() {
- echo '' . esc_html__('Set your OpenPanel Client ID. The SDK and requests are served from your domain to avoid ad blockers.', 'openpanel') . '
';
+ add_settings_section('op_main', __('OpenPanel Settings', 'openpanel-self-hosted'), function() {
+ echo '' . esc_html__('Set your OpenPanel Client ID. The SDK and requests are served from your domain to avoid ad blockers.', 'openpanel-self-hosted') . '
';
}, self::OPTION_KEY);
- add_settings_field('client_id', __('Client ID', 'openpanel'), function() {
+ add_settings_field('client_id', __('Client ID', 'openpanel-self-hosted'), function() {
$opts = get_option(self::OPTION_KEY);
printf(' ',
esc_attr(self::OPTION_KEY),
@@ -110,14 +110,14 @@ final class OP_WP_Proxy {
);
}, self::OPTION_KEY, 'op_main');
- add_settings_field('toggles', __('Auto-tracking (optional)', 'openpanel'), function() {
+ add_settings_field('toggles', __('Auto-tracking (optional)', 'openpanel-self-hosted'), function() {
$o = get_option(self::OPTION_KEY);
// Default track_screen to true if not set
$track_screen = isset($o['track_screen']) ? !empty($o['track_screen']) : true;
?>
- >
- >
- >
+ >
+ >
+ >
' .
- esc_html__('OpenPanel cache cleared successfully. The latest op1.js will be fetched on the next page load.', 'openpanel') .
+ esc_html__('OpenPanel cache cleared successfully. The latest op1.js will be fetched on the next page load.', 'openpanel-self-hosted') .
'
';
});
}
@@ -155,18 +155,18 @@ final class OP_WP_Proxy {
-
-
+
+
0) {
echo '' .
/* translators: %s: human readable time difference */
- sprintf(esc_html__('Cache expires in %s', 'openpanel'), esc_html(human_time_diff(time(), $cached_time))) .
+ sprintf(esc_html__('Cache expires in %s', 'openpanel-self-hosted'), esc_html(human_time_diff(time(), $cached_time))) .
'
';
} else {
echo '' .
- esc_html__('Cache has expired and will refresh on next page load.', 'openpanel') .
+ esc_html__('Cache has expired and will refresh on next page load.', 'openpanel-self-hosted') .
'
';
}
} else {
echo '' .
- esc_html__('No cached version found. op1.js will be fetched on next page load.', 'openpanel') .
+ esc_html__('No cached version found. op1.js will be fetched on next page load.', 'openpanel-self-hosted') .
'
';
}
?>
-
+
-
+
-
+
-
+
get_api_base()); ?>
-
+
get_js_url()); ?>
-
+
diff --git a/wordpress-plugin/openpanel/readme.txt b/wordpress-plugin/openpanel-self-hosted/readme.txt
similarity index 94%
rename from wordpress-plugin/openpanel/readme.txt
rename to wordpress-plugin/openpanel-self-hosted/readme.txt
index be9cad1..4897d03 100644
--- a/wordpress-plugin/openpanel/readme.txt
+++ b/wordpress-plugin/openpanel-self-hosted/readme.txt
@@ -1,4 +1,4 @@
-=== OpenPanel ===
+=== OpenPanel Self-Hosted ===
Contributors: openpanel, airano
Tags: analytics, privacy-friendly, tracking, self-hosted, proxy
Requires at least: 5.8
@@ -12,7 +12,9 @@ Privacy-friendly analytics with ad-blocker resistance. Supports OpenPanel Cloud
== Description ==
-**OpenPanel** is an open-source web and product analytics platform that serves as a privacy-friendly alternative to traditional analytics solutions. This WordPress plugin seamlessly integrates [OpenPanel](https://openpanel.dev) with your WordPress site while maximizing reliability and avoiding ad-blocker interference.
+**OpenPanel Self-Hosted** is a fork of the [official OpenPanel WordPress plugin](https://wordpress.org/plugins/openpanel/) with full **Self-Hosted instance support**. [OpenPanel](https://openpanel.dev) is an open-source web and product analytics platform — a privacy-friendly alternative to Google Analytics. This plugin seamlessly integrates OpenPanel (Cloud or Self-Hosted) with your WordPress site while maximizing reliability and avoiding ad-blocker interference.
+
+Designed to work with [MCP Hub](https://github.com/airano-ir/mcphub) for AI-powered analytics management.
= Key Features =
diff --git a/wordpress-plugin/openpanel.zip b/wordpress-plugin/openpanel.zip
deleted file mode 100644
index 2ed37211898c3849641793c24943bae1bf308369..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 11702
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
b?;!u7d6Z-!q5ky>;-3xuPoi|Xe|i50R|QEK