PHPackages                             camalote-wp/models - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. camalote-wp/models

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

camalote-wp/models
==================

CamaloteWP Models provides abstract base classes for registering WordPress content models (post types, taxonomies, metadata, blocks).

v0.2.0(1mo ago)012GPL-2.0-or-laterPHPPHP ^8.2CI passing

Since Jul 3Pushed 1mo agoCompare

[ Source](https://github.com/camalote-wp/models)[ Packagist](https://packagist.org/packages/camalote-wp/models)[ RSS](/packages/camalote-wp-models/feed)WikiDiscussions main Synced 2w ago

READMEChangelog (1)Dependencies (7)Versions (5)Used By (0)

CamaloteWP Models
=================

[](#camalotewp-models)

Abstract base classes for registering WordPress content models (post types, meta, blocks, REST hooks, admin pages). Reduces boilerplate when spinning up the same registration logic across multiple plugins.

Usage
-----

[](#usage)

1. Extend the abstracts for your content model
2. Implement the abstract methods
3. List your components in a Bootstrap class
4. Run the BootstrapRunner

```
use CamaloteWP\Models\Core\BootstrapRunner;

// Standard usage (creates internal Loader)
$runner = new BootstrapRunner;
$runner->register([Page\Bootstrap::class])->run();

// With dependency injection (shares Loader instance)
$loader = new Loader;
$runner = new BootstrapRunner($loader);
$runner->register([Page\Bootstrap::class])->run();

// You can also access the shared loader for additional hook registration
$loader->add_action('plugins_loaded', $this, 'load_textdomain');
```

Complete Example
----------------

[](#complete-example)

```
// PagePostType.php
namespace MyPlugin\Page;

use CamaloteWP\Models\Abstracts\AbstractPostType;

class PagePostType extends AbstractPostType
{
    protected string $model_name = 'page';

    protected function args(): array
    {
        return [
            'public'       => true,
            'has_archive'  => true,
            'show_in_rest' => true,
            'labels' => [
                'name' => 'Pages',
                'singular_name' => 'Page',
            ],
        ];
    }
}
```

```
// PageMeta.php
namespace MyPlugin\Page;

use CamaloteWP\Models\Abstracts\AbstractMeta;

class PageMeta extends AbstractMeta
{
    protected string $model_name = 'page';

    protected function schema(): array
    {
        return [
            'subtitle' => ['type' => 'string'],
            'color'    => ['type' => 'string'],
        ];
    }

    protected function get_meta_prefix(): string
    {
        return 'page_';
    }
}
```

```
// PageBlocks.php
namespace MyPlugin\Page;

use CamaloteWP\Models\Abstracts\AbstractBlocks;

class PageBlocks extends AbstractBlocks
{
    protected string $model_name = 'page';

    protected function get_block_paths(): array
    {
        return [get_template_directory() . '/blocks'];
    }
}
```

```
// Bootstrap.php
namespace MyPlugin\Page;

use CamaloteWP\Models\Abstracts\AbstractBootstrap;

class Bootstrap extends AbstractBootstrap
{
    protected string $model_name = 'page';

    public function get_components(): array
    {
        return [
            PagePostType::class,
            PageMeta::class,
            PageBlocks::class,
        ];
    }
}
```

```
// In your plugin's main file or service provider
use CamaloteWP\Models\Core\BootstrapRunner;
use MyPlugin\Page\Bootstrap;

$runner = new BootstrapRunner;
$runner->register([Bootstrap::class])->run();
```

Reference
---------

[](#reference)

### AbstractPostType

[](#abstractposttype)

What to extend`AbstractPostType`**Implements**`Registerable`**Must implement**`args(): array`**Can override**(none)**You get**`register()` — calls `\register_post_type()` with `$model_name` and `args()`### AbstractMeta

[](#abstractmeta)

What to extend`AbstractMeta`**Implements**`Registerable`**Must implement**`schema(): array`**Can override**`get_meta_prefix(): string` (default: empty string)**You get**`register()` — loops schema and calls `\register_post_meta()` per entry, prefixing keys with `get_meta_prefix()`### AbstractBlocks

[](#abstractblocks)

What to extend`AbstractBlocks`**Implements**`Registerable`, `Hookable`**Must implement**`get_block_paths(): array`**Can override**`get_hooks(): array` (default: empty)**You get**`register()` — scans each path for `block.json` files and calls `\register_block_type()`### AbstractRest

[](#abstractrest)

What to extend`AbstractRest`**Implements**`Hookable`**Must implement**(none)**Can override**`get_hooks(): array` (default: empty)**You get**A Hookable base for adding REST filters/actions via `get_hooks()`### AbstractModelAdminPage

[](#abstractmodeladminpage)

What to extend`AbstractModelAdminPage`**Implements**`Hookable`, `AdminPage`**Must implement**`get_page_config(): array`, `get_asset_config(): array`, `render_page(): void`**Can override**`get_hooks(): array` (default: empty)**You get**`register_submenu_page()`, `register_menu_page()`, `enqueue_assets()`### AbstractBootstrap

[](#abstractbootstrap)

What to extend`AbstractBootstrap`**Must implement**`get_components(): array`**Can override**`register()` (default: empty)**You get**`get_model_name()`### BootstrapRunner

[](#bootstraprunner)

Orchestrates registration. Instantiate, pass Bootstrap class names to `register()`, then call `run()`. Accepts an optional `Loader` instance for dependency injection.

```
// Default constructor (backward compatible)
$runner = new BootstrapRunner;
$runner->register([Bootstrap::class])->run();

// With dependency injection
$loader = new Loader;
$runner = new BootstrapRunner($loader);
$runner->register([Bootstrap::class])->run();

// Access shared loader (optional)
$loader = $runner->get_loader();
$loader->add_action('init', $this, 'custom_init');
```

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

[](#installation)

```
composer require camalote-wp/models
```

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

[](#development)

```
composer test          # Run tests
composer stan          # Run static analysis
composer pint          # Check code style
composer check         # Run all three
```

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance92

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity39

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% 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 ~1 days

Total

4

Last Release

40d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/613b5dffc2a77238dc8d4c194e5c412cc17ce151b46006c991ef153c279693e4?d=identicon)[tingeka](/maintainers/tingeka)

---

Top Contributors

[![tingeka](https://avatars.githubusercontent.com/u/53122864?v=4)](https://github.com/tingeka "tingeka (58 commits)")

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/camalote-wp-models/health.svg)

```
[![Health](https://phpackages.com/badges/camalote-wp-models/health.svg)](https://phpackages.com/packages/camalote-wp-models)
```

###  Alternatives

[harishdurga/laravel-quiz

Provides Quiz Functionality

1736.8k](/packages/harishdurga-laravel-quiz)

PHPackages © 2026

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