WP Manifestindependent plugin directory
manifest / developer / adpcoreplugin

adpCore

A lot of tools to help make life easier for wordpress developers

★ 1stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/appsdevpk/adpcoreplugin/archive/refs/heads/main.zip
Updates itself. It ships its own updater (Plugin Update Checker), so new versions appear under Dashboard → Updates.

AdpCore - WordPress Plugin Framework

A comprehensive WordPress plugin framework that supercharges your development workflow with Blade templating, web components, custom post types, conditionals, and much more — all configurable through simple JSON files.

Version: 2.0.0
Requires PHP: 7.4+
License: GPL-2.0-or-later


Table of Contents


Installation

  1. Install the Plugin

    Clone or download this repository into your WordPress wp-content/plugins/ directory:

    wp-content/plugins/adpcore/
  2. Install Dependencies

    cd wp-content/plugins/adpcore
    composer install
  3. Copy the App Folder

    Copy the AdpApp folder to your active theme directory:

    wp-content/themes/your-active-theme/AdpApp/
  4. Activate the Plugin

    Go to WordPress Admin → Plugins and activate Adp Core.

  5. Start Using

    Navigate to Adp Tools in the WordPress admin menu to access all features.


Quick Start

Once installed, the plugin works out of the box. Here's how to get started with the most common features:

Create a Custom Post Type

Create a JSON file at AdpApp/posttypes/product.json:

{
    "singular": "Product",
    "plural": "Products"
}

Create a Custom Shortcode

Create a Blade template at AdpApp/shortcodes/hello.blade.php:

<h1>Hello, {{ $name ?? 'World' }}!</h1>

Use it anywhere: [hello name="WordPress"]

Create a Server Component

Create a Blade template at AdpApp/servercomponents/my-alert.blade.php:

<div class="alert">{{ $message }}</div>

Use it anywhere: <my-alert message="Hello!"></my-alert>


App Folder Structure

The AdpApp folder should be placed in your active theme directory. Here's the complete structure:

your-theme/
└── AdpApp/
    ├── admindashwidgets/     # Custom dashboard widgets
    │   ├── {name}.blade.php  # Widget template
    │   └── {name}.json       # Widget config
    ├── annotations/          # (auto-created for annotation storage)
    ├── cache/                # Blade template cache (auto-created)
    ├── conditionals/         # Conditional display templates
    │   ├── {name}.blade.php  # Conditional template
    │   └── {name}.json       # Conditional config
    ├── css/                  # Dynamic CSS files
    │   └── {location}-{context}[-{ids}].css
    ├── helptabs/             # Custom help tabs
    │   ├── {name}.blade.php  # Help tab template
    │   └── {name}.json       # Help tab config
    ├── js/                   # Dynamic JS files
    │   └── {location}-{context}[-{ids}].js
    ├── livecomponents/       # Live (SSE) web components
    │   ├── {name}.blade.php  # Component template
    │   ├── {name}.json       # Component config
    │   └── {name}-flows/     # Component event flows
    ├── metaboxes/            # Custom meta boxes
    │   └── {name}.json       # CMB2 meta box config
    ├── pages/                # Custom page routing
    │   └── {page-name}/
    │       └── {param}.blade.php
    ├── posttypes/            # Custom post types
    │   └── {name}.json       # Post type config
    ├── servercomponents/     # Server-side web components
    │   ├── {name}.blade.php  # Component template
    │   ├── {name}.json       # Component config
    │   ├── {name}-flows/     # Component event flows
    │   └── global-states.json # Global state definitions
    ├── shortcodes/           # Custom shortcodes
    │   └── {name}.blade.php  # Shortcode template
    ├── taxonomies/           # Custom taxonomies
    │   └── {name}.json       # Taxonomy config
    ├── widgetareas/          # Custom widget areas
    │   └── {name}.json       # Widget area config
    └── widgets/              # Custom widgets
        ├── {name}.blade.php  # Widget template
        └── {name}.json       # Widget config

Features

Conditionals

Conditionals allow you to show or hide Blade templates based on configurable conditions through an admin UI.

Setup:

  1. Create a Blade template in AdpApp/conditionals/ (e.g., hero-banner.blade.php)
  2. Create a matching JSON config file (hero-banner.json)

Config file format:

{
    "Name": "Hero Banner",
    "Contents": {
        "title": "Default Title",
        "description": "Default Description"
    }
}

Available conditions (via admin UI):

  • Post Type Is — Show/hide based on current post type
  • Post ID In — Show/hide on specific post IDs
  • Url Is — Show/hide on specific URLs
  • Function Is — Call a whitelisted WordPress function
  • Taxonomy Is — Show/hide on taxonomy archives
  • Terms In — Show/hide on specific taxonomy terms
  • Is Mobile / Is Desktop — Device-based display

Usage in templates:

@include('conditionals.hero-banner')

Or via shortcode:

[adpConditionals slug="hero-banner"]

Conditionals Admin UI


Shortcodes

Place a Blade file in AdpApp/shortcodes/ and it automatically becomes a shortcode with the file name.

Example: Create AdpApp/shortcodes/greeting.blade.php:

<h2>Hello, {{ $name }}!</h2>
<p>Welcome to {{ $site_name }}.</p>

Usage:

[greeting name="John" site_name="My Site"]

All shortcode attributes are available as variables in the Blade template.


Custom Post Types

Create a JSON file in AdpApp/posttypes/ to register a custom post type.

Minimal config (product.json):

{
    "singular": "Product",
    "plural": "Products"
}

Full config with extra arguments:

{
    "singular": "Product",
    "plural": "Products",
    "extraArgs": {
        "supports": ["title", "editor", "thumbnail", "custom-fields"],
        "menu_icon": "dashicons-cart",
        "has_archive": true,
        "rewrite": { "slug": "products" }
    }
}

The filename becomes the post type slug (e.g., product → product post type).


Custom Taxonomies

Create a JSON file in AdpApp/taxonomies/ to register a custom taxonomy.

Config (product-category.json):

{
    "posttype": "product",
    "singular": "Product Category",
    "plural": "Product Categories"
}

With extra arguments:

{
    "posttype": "product",
    "singular": "Product Tag",
    "plural": "Product Tags",
    "extraArgs": {
        "hierarchical": false,
        "rewrite": { "slug": "product-tags" }
    }
}

Custom Meta Boxes

The plugin uses CMB2 for meta box registration. Place a JSON config file in AdpApp/metaboxes/.

Config (page-settings.json):

{
    "config": {
        "id": "page-settings",
        "title": "Page Settings",
        "object_types": ["page"],
        "context": "normal",
        "priority": "high"
    },
    "fields": {
        "subtitle": {
            "name": "Subtitle",
            "type": "text",
            "showinadmin": true
        },
        "hero_image": {
            "name": "Hero Image",
            "type": "file"
        }
    }
}

Special field options:

  • showinadmin: true — Shows the field as a column in the admin post list
  • showon — Conditionally show the meta box:
    "showon": {
        "ids": "1,2,3"
    }

    or by template:

    "showon": {
        "templates": "template-about.php,template-contact.php"
    }

Front-end usage:

[adpMetaForm metaboxid="page-settings" objectid="21"]

Server Components

Server components are reusable HTML web components powered by the Realm.js framework. They render on the server and can be used as HTML tags anywhere in your WordPress site.

Naming convention: Component names must be at least two words separated by dashes (e.g., my-alert, user-card).

Required files:

  1. AdpApp/servercomponents/my-alert.blade.php — The template
  2. AdpApp/servercomponents/my-alert.json — The config

Config (my-alert.json):

{
    "attributes": {
        "message": {
            "type": "string",
            "default": "Hello World"
        },
        "type": {
            "type": "string",
            "default": "info"
        }
    },
    "states": {
        "isVisible": {
            "type": "boolean",
            "default": true
        }
    }
}

Template (my-alert.blade.php):

<div class="alert alert-{{ $type }}" x-show="isVisible">
    {{ $message }}
</div>

Event flows (optional): Create a directory AdpApp/servercomponents/my-alert-flows/ with PHP files:

  • listen-click.php — Handles click events
  • listen-mounted.php — Runs when component is mounted
  • trigger-update.php — Triggers custom events

Usage anywhere:

<my-alert message="Success!" type="success"></my-alert>

Global states (AdpApp/servercomponents/global-states.json):

{
    "theme": {
        "type": "string",
        "default": "light",
        "storage": "local"
    },
    "userLoggedIn": {
        "type": "boolean",
        "default": false
    }
}

Live Components

Same as server components but with real-time updates via Server-Sent Events (SSE). The component automatically re-renders when data changes on the server.

Setup: Same as server components, but place files in AdpApp/livecomponents/.

Important: Live component names must be different from server component names.

Example (live-stock-ticker.blade.php):

<div class="stock-ticker">
    <span class="symbol">{{ $symbol }}</span>
    <span class="price">{{ $price }}</span>
</div>

The SSE connection is automatically established and updates are pushed to the component without page reloads.


Conditional CSS & JS

Optimize performance by conditionally loading CSS and JS files only where needed.

File naming convention:

{location}-{context}[-{ids}].css
{location}-{context}[-{ids}].js
Part Values Description
location header, footer Where to load the file
context template, page, single When to load it
ids Comma-separated IDs Specific template/page/post IDs (optional)

Examples:

Filename Loads when
header-page.css On any page
footer-single.css On any single post
header-template-about.php.css On the "About" page template
footer-page-1,2,3.css On pages with IDs 1, 2, or 3
header-single-42.js On post with ID 42

Place files in AdpApp/css/ or AdpApp/js/.


Custom Widgets & Widget Areas

Register a widget area:

Create AdpApp/widgetareas/sidebar-main.json:

{
    "id": "sidebar-main",
    "name": "Main Sidebar",
    "description": "Widgets in this area will appear in the main sidebar.",
    "before_widget": "<div class=\"widget %2$s\">",
    "after_widget": "</div>",
    "before_title": "<h3 class=\"widget-title\">",
    "after_title": "</h3>"
}

Embed in your theme:

<?php echo adpEmbedWidgetArea('sidebar-main'); ?>

Register a custom widget:

  1. Create AdpApp/widgets/recent-posts-widget.blade.php:

    <ul>
    @foreach($instance['posts'] as $post)
     <li><a href="{{ get_permalink($post->ID) }}">{{ $post->post_title }}</a></li>
    @endforeach
    </ul>
  2. Create AdpApp/widgets/recent-posts-widget.json:

    {
     "Config": {
         "Name": "Recent Posts Widget",
         "ClassName": "AdpRecentPostsWidget",
         "before_title": "<h4>",
         "after_title": "</h4>"
     },
     "Fields": {
         "title": {
             "label": "Title",
             "type": "input-text"
         },
         "count": {
             "label": "Number of Posts",
             "type": "input-number"
         }
     }
    }

Admin Dashboard Widgets

Create a Blade template and JSON config in AdpApp/admindashwidgets/:

stats-widget.json:

{
    "Title": "Site Statistics"
}

stats-widget.blade.php:

<div class="stats">
    <p>Total Posts: <?php echo wp_count_posts()->publish; ?></p>
    <p>Total Pages: <?php echo wp_count_posts('page')->publish; ?></p>
</div>

The widget automatically appears on the WordPress dashboard.


Custom Help Tabs

Create a Blade template and JSON config in AdpApp/helptabs/:

getting-started.json:

{
    "Title": "Getting Started"
}

getting-started.blade.php:

<h3>Welcome to AdpCore</h3>
<p>This plugin provides many tools to help you build WordPress sites faster.</p>

The help tab appears in the WordPress help menu on all admin screens.


Custom Pages (Page Routing)

Register custom URLs and execute code when they're accessed.

URL pattern:

{site-url}/?{page-name}={parameter}

Setup:

  1. Create a folder in AdpApp/pages/ with the page name (e.g., testpage/)
  2. Create a Blade template with the parameter as filename (e.g., 123.blade.php)

When someone visits yoursite.com/?testpage=123, the code in 123.blade.php executes.

Set page title:

<?php $pageTitle = "My Custom Page"; ?>
<h1>{{ $pageTitle }}</h1>

Annotations

Enable collaborative feedback directly on your website. Logged-in users can annotate any part of a page.

Text annotations:

  • Select any text on the page
  • An annotation icon appears
  • Click to open a comment popup
  • Add comments and save

Image annotations:

  • Add the annotate class to any image: <img class="annotate" src="...">
  • Draw a selection on the image with your mouse
  • Add comments in the popup

All annotations are stored as custom post types (adpannotations) and can be managed in the WordPress admin.


CDN Libraries

Access the Libraries sub-page under Adp Tools to search for JS/CSS libraries from cdnjs.

Search Similar — Finds libraries matching your keyword
Search Exact — Finds the exact library by name

Features:

  • Copy CDN URLs to clipboard
  • Save libraries to your personal collection
  • Create reusable presets with keywords

Libraries Search


Admin Tools

The Adp Tools menu provides a collection of useful developer tools. Each tool can be:

  • Open Here — Opens inside WordPress admin via iframe
  • Open Separate — Opens in a new browser tab

Tools are filterable by category and loaded from tools/adpTools.json.


Wizards

Wizards provide a visual interface for creating configuration and template files. No need to manually create the AdpApp folder structure — wizards generate everything for you.

Access via Adp Tools → Wizards in the WordPress admin.

Wizards


Built-in Shortcodes Reference

Shortcode Description Example
[adpPostLoop] Loop through posts with WP_Query [adpPostLoop post_type="product" posts_per_page="5"]...[/adpPostLoop]
[adpPostField] Display a post field [adpPostField field="post_title"]
[adpHiddenPostField] Hidden input for post field [adpHiddenPostField field="ID" fieldname="post_id"]
[adpPostMeta] Display post meta [adpPostMeta field="custom_field"]
[adpPostThumb] Display post thumbnail [adpPostThumb size="thumbnail" cssclass="thumb"]
[adpFunctionCall] Call a whitelisted function [adpFunctionCall functionname="adp_my_func"]
[adpIfIsPost] Conditional on POST data [adpIfIsPost variable="submitted"]...[/adpIfIsPost]
[adpUpdatePostMeta] Update post meta [adpUpdatePostMeta metakey="field" metaval="frompost"]
[adpDumpVar] Debug variable dump [adpDumpVar variable="wp_query"]
[adpConditionals] Render conditional [adpConditionals slug="hero-banner"]
[adpContentView] Content CRUD view [adpContentView contenttype="post" isajaxed="Yes"]

Event Hooks System

AdpCore provides 50+ event hooks for extending functionality without modifying core code.

Quick Example

// Validate content before creation
add_filter('content_before_create', function($postData) {
    if (strlen($postData['post_title']) < 5) {
        $postData['post_title'] .= ' (auto-extended)';
    }
    return $postData;
});

// Send notification after deletion
add_action('content_after_delete', function($postId) {
    wp_mail(get_option('admin_email'), 'Content Deleted', "Post {$postId} was deleted.");
});

// Log all API requests
add_action('api_after_request', function($url, $result, $httpCode) {
    error_log("[AdpCore API] {$url} - {$httpCode}");
}, 10, 3);

Available Hook Categories

Category Hooks Description
Plugin Lifecycle plugin_loaded, plugin_initialized Plugin startup events
Content CRUD content_before_create, content_after_create, content_before_update, content_after_update, content_before_delete, content_after_delete, content_list_query_args, content_list_result, content_meta_before_create, content_meta_before_update Content operations
Post Types post_type_before_register, post_type_after_register, post_type_args_{name} Post type registration
Taxonomies taxonomy_before_register, taxonomy_after_register, taxonomy_args_{name} Taxonomy registration
Blocks block_before_register, block_after_register, block_render_{name} Gutenberg blocks
API api_before_request, api_after_request, api_request_error External API calls
Components component_before_render, component_after_render, component_import_name, component_global_states, component_list, component_sse_data Web components
Libraries library_before_save, library_after_save, library_before_remove, library_after_remove, library_search_results, library_search_error, user_library_list, library_presets_list CDN library management
Conditionals conditional_before_render, conditional_after_render, conditional_render_args, conditionals_list Conditional display
Widgets widgets_before_register, widgets_after_register, widget_area_*, widget_* Widget operations
Shortcodes shortcode_before_execute, shortcode_after_execute, shortcode_{tag}_args, shortcode_{tag}_content, shortcode_{tag}_output Shortcode execution
Security security_nonce_failed, security_permission_denied Security events

Using EventManager Directly

use AdpCore\Core\EventManager;

// Register a listener
EventManager::on('my_custom_event', function($data) {
    // Handle event
});

// Trigger an action
EventManager::doAction('my_custom_event', $data);

// Trigger and get filtered result
$result = EventManager::trigger('my_filter_event', $data);

// Check if event has listeners
if (EventManager::hasListeners('my_event')) {
    // Event has listeners
}

// Get all fired events (debugging)
$firedEvents = EventManager::getFiredEvents();

For the complete hooks reference with all parameters and examples, see docs/hooks.md.


Namespaced Classes

The plugin uses PSR-4 autoloading with the AdpCore\ namespace:

src/
├── Core/
│   ├── Plugin.php           # Main plugin singleton
│   ├── AdpBlade.php         # Blade template engine extension
│   ├── EventManager.php     # Event/hook management
│   ├── Content.php          # Content CRUD operations
│   ├── Conditionals.php     # Conditional display logic
│   ├── Animations.php       # AOS animation management
│   └── Annotations.php      # Text & image annotations
├── Api/
│   └── ApiClient.php        # External API client
├── Admin/
│   ├── AdminTools.php       # Admin pages & menus
│   ├── DashboardWidgets.php # Dashboard widget registration
│   ├── HelpTabs.php         # Help tab registration
│   ├── Libraries.php        # CDN library management
│   ├── MetaBoxes.php        # CMB2 metabox registration
│   ├── Widgets.php          # Widget & widget area registration
│   └── Wizards.php          # Admin wizards
├── Blocks/
│   ├── Blocks.php           # Gutenberg block registration
│   └── PostTypes.php        # Post type & taxonomy registration
├── Components/
│   ├── ServerComponents.php # Server-side web components
│   └── LiveComponents.php   # Live (SSE) web components
├── Shortcodes/
│   └── Shortcodes.php       # All shortcode handlers
└── Helpers/
    ├── Security.php         # Security utilities
    └── Utils.php            # General utilities

Using Classes Directly

use AdpCore\Helpers\Security;
use AdpCore\Helpers\Utils;
use AdpCore\Api\ApiClient;
use AdpCore\Core\EventManager;

// Safe JSON decode
$data = Security::safeJsonDecode($jsonString);

// Safe redirect (validates referer)
Security::safeRedirect('/dashboard');

// Get sanitized request value
$value = Security::get('my_param', 'default');

// Make API call
$response = ApiClient::get('https://api.example.com/data');

// Render a Blade view
$html = Utils::renderBladeView('my-view', 'widgets', ['name' => 'World']);

Backward Compatibility

All existing code continues to work without changes. The lib/ directory files are thin wrappers that delegate to the new namespaced classes:

// These global functions still work:
adpGetUserRole($userId);
adpSafeJsonDecode($json);
adpSendApiCall($url);
adpConditionals($slug);
adpEmbedWidgetArea('sidebar-main');

Security Features

AdpCore includes enterprise-level security hardening:

Protection Implementation
SQL Injection All queries use $wpdb->prepare()
XSS All output escaped with esc_html(), esc_attr(), esc_url()
CSRF Nonce verification on all forms
Path Traversal sanitize_file_name(), realpath() verification, .. removal
Privilege Escalation current_user_can() checks on all operations
Open Redirects HTTP_REFERER domain validation
JSON Injection Safe json_decode() wrapper with error handling
Arbitrary Code Execution Function whitelists for adpFunctionCall and "Function Is" condition
Content Security Policy CSP headers whitelisting trusted CDN sources
API Security URL validation, HTTPS enforcement, timeouts, SSL verification

Architecture

adpcore/
├── src/                    # PSR-4 namespaced classes (22 classes)
├── lib/                    # Backward compatibility wrappers
├── vendor/                 # Composer dependencies
├── docs/                   # Documentation
│   └── hooks.md            # Event hooks reference
├── tools/                  # Admin tools configuration
├── js/                     # Plugin JavaScript files
├── composer.json           # Autoloading configuration
├── adpCore.php             # Plugin entry point
├── CHANGELOG.md            # Version history
└── README.md               # This file

Requirements

  • WordPress 5.0+
  • PHP 7.4+
  • Composer (for autoloading)
  • cURL extension (for API calls)

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run composer dump-autoload
  5. Submit a pull request

License

GPL-2.0-or-later — See LICENSE for details.