Post Models
Custom post types extend \wpmvc\models\Post_Model. Any public property declared on the subclass beyond the standard WP_Post fields is automatically treated as post meta — read and written via get_post_meta() / update_post_meta():
class Event extends \wpmvc\models\Post_Model {
public $post_type = 'event';
// Stored as post meta, with optional defaults:
public $event_date;
public $event_location = 'Bratislava';
protected function registry() : array {
return array(
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
);
}
protected function registry_labels() : array {
return array(
'name' => __( 'Event' ),
);
}
}Registering the post type
Hook the model's static register() to the init WordPress action. register() takes no arguments — the post type args come from the model's registry(), registry_labels(), registry_supports() and registry_rewrite() methods:
add_action( 'init', array( Event::class, 'register' ) );register() also wires the model's meta boxes.
Querying
$event = Event::find_one( 24 );
$events = Event::find_all();
$events = Event::find()
->published()
->all();
$events = Event::find()
->where_taxonomy( Event_Category::class, array( 'slug' => 'conferences' ) )
->all();
$event = Event::find()->one();Attributes, saving, deleting
$event = new Event();
$event->set_attribute( 'post_title', 'Great Event' );
$event->set_attributes( array(
'post_title' => 'Great Event',
'event_location' => 'Bratislava',
) );
$event->save();
$event->delete();Convenience getters: get_id(), get_title(), get_content(), get_link(), get_thumbnail( $size, $args ). Lifecycle hooks: before_save() and after_save().
Loading request data
load() expects data keyed by the short class name — matching the field names generated by the Form helper:
$event->load( array(
'Event' => array(
'post_title' => 'Great Event',
'event_location' => 'Bratislava',
),
) );
// Typically:
$event->load( Theme::$app->request->post() );Validation
Define rules on the model; validate() runs them and collects errors:
public function rules() : array {
return array(
array( array( 'post_title', 'event_location' ), 'required' ),
array( 'event_email', 'email' ),
array( 'event_capacity', 'number' ),
);
}if ( ! $event->validate() ) {
$errors = $event->get_errors();
}save() validates by default — pass save( false ) to skip.
For AJAX handlers, to_response() sends the model state via wp_send_json_success() / wp_send_json_error() depending on the validation result.