Library provides a functionality for associating your models with WordPress WP_Post model. Each instance holds a WP_Post, creating one only when no existing post or ID is supplied.
| Signal | Stable 1.0 baseline |
|---|---|
| Unit suite | 70 tests / 970 assertions |
| Source coverage | 192/192 executable lines and 43/43 methods (100%) |
| Required CI | PHP 7.4 and 8.4 quality; coverage/package; WordPress minimum/latest |
| Production package | Eight reviewed root entries, frozen 19-method API, no development dependencies |
| CI profile | PHP | WordPress |
|---|---|---|
| Minimum supported | 7.4 | 6.0 |
| Current compatibility | 8.4 | Latest stable |
The coverage badge represents an enforced merge threshold, not an approximate hosted metric: CI fails if executable source line or method coverage falls below 100%. See Testing and coverage for the individual unit, package-install, persistent WordPress, and isolated integration gates.
- Versioning and compatibility policy
- 1.0 API reference
- Upgrading from 0.7.x to 1.0
- Changelog
- Local WordPress development
- Testing and coverage
- Release runbook
- Contributing
- 1.0 delivery plan
The 1.0 interface has 19 methods. The most common operations include
$instance->getTitle();$instance->setTitle();$instance->getSlug();$instance->setSlug();$instance->getMenuOrder();$instance->setMenuOrder();$instance->getMetaField();$instance->setMetaField();$instance->getStatus();$instance->setStatus();$instance->getPost();$instance->getPostType();$instance->savePost();$instance->publish();$instance->draft();
See the API reference for exact PHP 7.4-compatible signatures, return behavior, exceptions, hooks, and persistence rules. There is no public reload or rebind operation; create another model instance to load another post.
Use
$instance->getParam();$instance->setParam();
to manage the JSON parameter map stored in WP_Post::post_content_filtered.
setParam() changes the in-memory post, returns void, and requires
savePost() for persistence.
-
Create your own class based on wpPostAble interface
use iTRON\wpPostAble\wpPostAble; use iTRON\wpPostAble\wpPostAbleTrait; use iTRON\wpPostAble\Exceptions\wppaCreatePostException; use iTRON\wpPostAble\Exceptions\wppaLoadPostException; class Item implements wpPostAble { use wpPostAbleTrait; const POST_TYPE = 'item'; }
-
Call the private
wpPostAble()trait initializer at the beginning of the__construct()method of the class that imports the trait.Pass to it two parameters
$post_typestring WP post type, associated with your class$post_idint|WP_Post|nullExisting post or ID, or nothing for creating a new post/** * @param int|WP_Post|null $post_id * * @throws wppaLoadPostException * @throws wppaCreatePostException */ public function __construct( $post_id = null ) { $this->wpPostAble( self::POST_TYPE, $post_id ); // Do anything you need }
wpPostAble()is a required constructor-only trait-composition seam. It is not public, protected, or overridable. The associated$postproperty and theloadPost()/loadPostObject()helpers are also private. UsegetPost()for supported access to the mutableWP_Post, and construct a new model when a different post must be loaded.
Create new post
$item = new Item();or load from existing one
$item = new Item( $post_id );or reuse an existing WP_Post without looking it up again:
$post = get_post( $post_id );
if ( ! $post instanceof WP_Post ) {
throw new RuntimeException( 'Post not found.' );
}
$item = new Item( $post );Passing null or 0 creates a new post. Passing a non-zero integer loads by ID.
Passing a WP_Post validates its post type, retains the same object instance,
loads metadata, and runs the normal loading filters and actions.
Other input types, including numeric strings, throw TypeError.
When you create an instance without an existing post or ID, wpPostAble creates a new draft in WordPress.
Let's try change the title
$item->setTitle('The best item');Set a slug through the same in-memory, chainable API:
$item->setSlug('the-best-item');Set WordPress's integer menu_order field in memory in the same way:
$item->setMenuOrder(-7);The title, slug, and menu order are still only in memory. Persist them explicitly:
$item->savePost();setSlug() keeps the supplied value on the current WP_Post and does not save
automatically. During savePost(), WordPress Core may normalize the slug or make
it unique. Reload the model to observe the persisted Core value:
$item = new Item( $item->getPost()->ID );
$slug = $item->getSlug();
$menuOrder = $item->getMenuOrder();New posts start with menu order 0. setMenuOrder() accepts any integer and
does not save automatically. The library does not impose a range, reorder other
posts, or change how WordPress queries use menu_order.
Maybe it's time to publish?
$item->publish();You can do it by single line
$item->setTitle('The best item')->setSlug('the-best-item')->setMenuOrder(-7)->publish();For the complete contract, see API.md. Consumers moving from
0.7.x should follow UPGRADING-1.0.md, especially when
they implement the interface manually, override trait methods, or previously
accessed protected $post directly.