PHPackages                             clubdeuce/wpmvc-redux - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. clubdeuce/wpmvc-redux

ActiveLibrary[Framework](/categories/framework)

clubdeuce/wpmvc-redux
=====================

An MVC library for WordPress application development

1.0.0(2mo ago)01MITPHPPHP &gt;=8.3

Since Nov 3Pushed 2mo agoCompare

[ Source](https://github.com/clubdeuce/wpmvc-redux)[ Packagist](https://packagist.org/packages/clubdeuce/wpmvc-redux)[ RSS](/packages/clubdeuce-wpmvc-redux/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (3)Versions (4)Used By (0)

wpmvc-redux
===========

[](#wpmvc-redux)

[![Scrutinizer Code Quality](https://camo.githubusercontent.com/c1b32061c93f7b5f336d1581808842b050f36b016f5429dab0564d3af3c778b2/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f636c756264657563652f77706d76632d72656475782f6261646765732f7175616c6974792d73636f72652e706e673f623d6d61696e)](https://scrutinizer-ci.com/g/clubdeuce/wpmvc-redux/?branch=main)[![Build Status](https://camo.githubusercontent.com/69c49cef28b85039b10f82990576fe974376e24c8fd48cd65429cd1c44c1529c/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f636c756264657563652f77706d76632d72656475782f6261646765732f6275696c642e706e673f623d6d61696e)](https://scrutinizer-ci.com/g/clubdeuce/wpmvc-redux/build-status/main)

An MVC base library for WordPress plugin and theme development. Provides typed base classes for models, custom post types, and taxonomies, following PSR-4 autoloading standards.

**Requires PHP 8.3+**

Installation
------------

[](#installation)

```
composer require clubdeuce/wpmvc-redux
```

---

Architecture
------------

[](#architecture)

```
Application          – plugin/theme entry point
Base\Base            – root base; bulk property setter via set_state()
Base\Model           – abstract model; enforces ID() contract
  Base\Post          – wraps WP_Post; exposes typed accessors
  Base\Term          – wraps WP_Term; exposes typed accessors
Controllers\Post_Type (abstract) – registers a custom post type on init
Controllers\Taxonomy  (abstract) – registers a custom taxonomy on init
Contracts\HasActions  – interface for Application subclasses with hook registration

```

---

Usage
-----

[](#usage)

### Application

[](#application)

Extend `Application` to create your plugin entry point. Implement `HasActions` to register WordPress hooks automatically on construction.

```
use Clubdeuce\Wpmvc_Redux\Application;
use Clubdeuce\Wpmvc_Redux\Contracts\HasActions;

class My_Plugin extends Application implements HasActions
{
    public function add_actions(): void
    {
        add_action( 'init', [ $this, 'register_stuff' ] );
    }
}

$plugin = new My_Plugin();
echo $plugin->getVersion(); // '1.0.0'
```

A `?ContainerInterface $container` property is available for dependency injection. Assign it via `set_state()` or a subclass constructor.

---

### Post model

[](#post-model)

Extend `Base\Post` to wrap a custom post type. All `WP_Post` properties are available via typed accessors — no raw property access needed.

```
use Clubdeuce\Wpmvc_Redux\Base\Post;

class Book extends Post
{
    // override any accessor or add custom methods
    public function isbn(): string
    {
        return get_post_meta( $this->ID(), '_isbn', true ) ?: '';
    }
}

$book = new Book( get_post( 42 ) );
echo $book->title();      // post_title
echo $book->slug();       // post_name
echo $book->status();     // post_status  (e.g. 'publish')
echo $book->type();       // post_type
echo $book->date();       // post_date    (MySQL datetime string)
echo $book->modified();   // post_modified
echo $book->excerpt();    // post_excerpt
$book->author_id();       // (int) post_author
$book->parent_id();       // (int) post_parent
$book->menu_order();      // (int) menu_order
$book->get_content_html(); // apply_filters('the_content', post_content)
$book->the_title();        // echoes esc_html( get_the_title() )
```

#### Template rendering

[](#template-rendering)

`the_template()` locates and renders a `.php` template file. Lookup order: child theme → parent theme → module dir (if `module_dir()` is overridden).

```
// Renders templates/book-card.php from the active theme
$book->the_template( 'book-card', [ 'show_date' => true ] );
```

Inside the template, `$item` is automatically available as a reference to the model instance, alongside any variables passed in the second argument:

```
// templates/book-card.php
echo $item->title();
if ( $show_date ) {
    echo $item->date();
}
```

Override `templates_subdir()` to change the theme subdirectory (defaults to `templates`, or `WPLIB_TEMPLATES_SUBDIR` if defined). Override `module_dir()` to enable a plugin-level template fallback.

---

### Term model

[](#term-model)

Extend `Base\Term` to wrap a taxonomy term.

```
use Clubdeuce\Wpmvc_Redux\Base\Term;

class Genre extends Term {}

$genre = new Genre( get_term( 7, 'genre' ) );
echo $genre->ID();          // term_id
echo $genre->name();        // name
echo $genre->slug();        // slug
echo $genre->taxonomy();    // taxonomy
echo $genre->description(); // description
$genre->parent_id();        // (int) parent
$genre->count();            // (int) count
```

---

### Post\_Type controller

[](#post_type-controller)

Extend `Controllers\Post_Type` (abstract) to register a custom post type. Define `const ?string POST_TYPE` and set `$arguments`.

```
use Clubdeuce\Wpmvc_Redux\Controllers\Post_Type;

class Book_Post_Type extends Post_Type
{
    const ?string POST_TYPE = 'book';

    protected array $arguments = [
        'public'    => true,
        'label'     => 'Books',
        'supports'  => [ 'title', 'editor', 'thumbnail' ],
    ];
}

new Book_Post_Type(); // registers on wp 'init' hook automatically
```

`slug()` returns the `POST_TYPE` constant value.

---

### Taxonomy controller

[](#taxonomy-controller)

Extend `Controllers\Taxonomy` (abstract) to register a custom taxonomy.

```
use Clubdeuce\Wpmvc_Redux\Controllers\Taxonomy;

class Genre_Taxonomy extends Taxonomy
{
    const ?string TAXONOMY = 'genre';

    protected array $object_type = [ 'book' ];

    protected array $arguments = [
        'hierarchical' => true,
        'label'        => 'Genres',
    ];
}

new Genre_Taxonomy(); // registers on wp 'init' hook automatically
```

`slug()` returns the `TAXONOMY` constant value.

---

### HasActions interface

[](#hasactions-interface)

Implement `Contracts\HasActions` on any `Application` subclass that needs to register hooks. The constructor calls `add_actions()` automatically when the interface is detected.

```
use Clubdeuce\Wpmvc_Redux\Contracts\HasActions;

interface HasActions
{
    public function add_actions(): void;
}
```

---

Development
-----------

[](#development)

### Requirements

[](#requirements)

- PHP 8.3+
- Composer

### Install dependencies

[](#install-dependencies)

```
composer install
```

### Run tests

[](#run-tests)

```
./vendor/bin/phpunit
```

### Static analysis

[](#static-analysis)

```
composer phpstan
```

Configuration is in `phpstan.neon.dist`. Create a local `phpstan.neon` for environment-specific overrides — do not edit `phpstan.neon.dist` directly.

---

PSR-4 namespaces
----------------

[](#psr-4-namespaces)

NamespaceDirectory`Clubdeuce\Wpmvc_Redux``src/``Clubdeuce\Wpmvc_Redux\Tests``tests/`---

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance86

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 94.1% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~121 days

Total

2

Last Release

70d ago

Major Versions

0.0.1 → 1.0.02026-03-04

PHP version history (2 changes)0.0.1PHP &gt;=8.0

1.0.0PHP &gt;=8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/59ae303db5f3f217efd33f76e9e49d0ff2084cd2824c41db6a0a88d4eb2a1a97?d=identicon)[clubdeuce](/maintainers/clubdeuce)

---

Top Contributors

[![clubdeuce](https://avatars.githubusercontent.com/u/2600497?v=4)](https://github.com/clubdeuce "clubdeuce (32 commits)")[![Copilot](https://avatars.githubusercontent.com/in/1143301?v=4)](https://github.com/Copilot "Copilot (2 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/clubdeuce-wpmvc-redux/health.svg)

```
[![Health](https://phpackages.com/badges/clubdeuce-wpmvc-redux/health.svg)](https://phpackages.com/packages/clubdeuce-wpmvc-redux)
```

###  Alternatives

[slim/slim-skeleton

A Slim Framework skeleton application for rapid development

1.6k458.7k6](/packages/slim-slim-skeleton)[elgg/elgg

Elgg is an award-winning social networking engine, delivering the building blocks that enable businesses, schools, universities and associations to create their own fully-featured social networks and applications.

1.7k15.7k5](/packages/elgg-elgg)[php-di/slim-bridge

PHP-DI integration in Slim

1786.7M98](/packages/php-di-slim-bridge)[php-di/silex-bridge

PHP-DI integration in Silex

2465.4k1](/packages/php-di-silex-bridge)[forme/framework

An MVC framework for WordPress.

175.0k3](/packages/forme-framework)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
