You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your enhancement related to a problem? Please describe.
All new 10up projects are based on this repo, but there is very little PHP scaffolding in place. This means that each different project ends up with a slightly different implementation for post types, taxonomies, REST endpoints etc.
This has two effects:
Slows down the initial setup of a project, as the tech lead has to put these scaffolds in place.
Increases the cognitive load for engineers that are switching between projects, as they have to learn the differences in setups.
Designs
Since the auto-initialisation of modules was merged in #158, it's allowed us to create much more modular scaffolds, with no requirement for factory classes etc.
I propose introducing abstract classes that contain all the base information needed to register a CPT/Taxonomy, which can then be extended to implement project-specific ones.
For example, the following abstract post type would then allow us to easily implement further ones:
<?php/** * AbstractPostType * * @package TenUpPlugin */namespaceTenUpPlugin\PostTypes;
useTenUpPlugin\Module;
/** * Abstract class for post types. */abstractclass AbstractPostType extends Module {
/** * Get the post type name. * * @return string */abstractpublicfunctionget_name();
/** * Get the singular post type label. * * @return string */abstractpublicfunctionget_singular_label();
/** * Get the plural post type label. * * @return string */abstractpublicfunctionget_plural_label();
/** * Default post type supported feature names. * * @return array */publicfunctionget_editor_supports() {
$supports = [
'title',
'editor',
'author',
'thumbnail',
'excerpt',
'revisions',
];
return$supports;
}
/** * Get the options for the post type. * * @return array */publicfunctionget_options() {
$options = [
'labels' => $this->get_labels(),
'public' => true,
'has_archive' => true,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => false,
'show_in_rest' => true,
'supports' => $this->get_editor_supports(),
];
return$options;
}
/** * Get the labels for the post type. * * @return array */publicfunctionget_labels() {
$plural_label = $this->get_plural_label();
$singular_label = $this->get_singular_label();
// phpcs:disable -- ignoring template strings without translators placeholder since this is dynamic$labels = array(
'name' => $plural_label,
// Already translated via get_plural_label().'singular_name' => $singular_label,
// Already translated via get_singular_label().'add_new_item' => sprintf( __( 'Add New %s', 'tenup-plugin' ), $singular_label ),
'edit_item' => sprintf( __( 'Edit %s', 'tenup-plugin' ), $singular_label ),
'new_item' => sprintf( __( 'New %s', 'tenup-plugin' ), $singular_label ),
'view_item' => sprintf( __( 'View %s', 'tenup-plugin' ), $singular_label ),
'view_items' => sprintf( __( 'View %s', 'tenup-plugin' ), $plural_label ),
'search_items' => sprintf( __( 'Search %s', 'tenup-plugin' ), $plural_label ),
'not_found' => sprintf( __( 'No %s found.', 'tenup-plugin' ), strtolower( $plural_label ) ),
'not_found_in_trash' => sprintf( __( 'No %s found in Trash.', 'tenup-plugin' ), strtolower( $plural_label ) ),
'parent_item_colon' => sprintf( __( 'Parent %s:', 'tenup-plugin' ), $plural_label ),
'all_items' => sprintf( __( 'All %s', 'tenup-plugin' ), $plural_label ),
'archives' => sprintf( __( '%s Archives', 'tenup-plugin' ), $singular_label ),
'attributes' => sprintf( __( '%s Attributes', 'tenup-plugin' ), $singular_label ),
'insert_into_item' => sprintf( __( 'Insert into %s', 'tenup-plugin' ), strtolower( $singular_label ) ),
'uploaded_to_this_item' => sprintf( __( 'Uploaded to this %s', 'tenup-plugin' ), strtolower( $singular_label ) ),
'filter_items_list' => sprintf( __( 'Filter %s list', 'tenup-plugin' ), strtolower( $plural_label ) ),
'items_list_navigation' => sprintf( __( '%s list navigation', 'tenup-plugin' ), $plural_label ),
'items_list' => sprintf( __( '%s list', 'tenup-plugin' ), $plural_label ),
'item_published' => sprintf( __( '%s published.', 'tenup-plugin' ), $singular_label ),
'item_published_privately' => sprintf( __( '%s published privately.', 'tenup-plugin' ), $singular_label ),
'item_reverted_to_draft' => sprintf( __( '%s reverted to draft.', 'tenup-plugin' ), $singular_label ),
'item_scheduled' => sprintf( __( '%s scheduled.', 'tenup-plugin' ), $singular_label ),
'item_updated' => sprintf( __( '%s updated.', 'tenup-plugin' ), $singular_label ),
'menu_name' => $plural_label,
'name_admin_bar' => $singular_label,
);
// phpcs:enablereturn$labels;
}
/** * Registers a post type and associates its taxonomies. * * @uses $this->get_name() to get the post's type name. * @return Bool Whether this theme has supports for this post type. */publicfunctionregister() {
$this->register_post_type();
$this->register_taxonomies();
$this->after_register();
returntrue;
}
/** * Registers the current post type with WordPress. * * @return void */publicfunctionregister_post_type() {
register_post_type(
$this->get_name(),
$this->get_options()
);
}
/** * Registers the taxonomies declared with the current post type. * * @return void */publicfunctionregister_taxonomies() {
$taxonomies = $this->get_supported_taxonomies();
$object_type = $this->get_name();
if ( ! empty( $taxonomies ) ) {
foreach ( $taxonomiesas$taxonomy ) {
register_taxonomy_for_object_type(
$taxonomy,
$object_type
);
}
}
}
/** * Returns the default supported taxonomies. The subclass should declare the * Taxonomies that it supports here if required. * * @return array */publicfunctionget_supported_taxonomies() {
return [];
}
/** * Run any code after the post type has been registered. * * @return void */publicfunctionafter_register() {
// Do nothing.
}
}
To implement a project-specific CPT, we'd then do something like:
<?php/** * Demo Post Type * * @package TenUpPlugin */namespaceTenUpPlugin\PostTypes;
/** * Demo post type. */class Demo extends AbstractPostType {
/** * Get the post type name. * * @return string */publicfunctionget_name() {
return'tenup-demo';
}
/** * Get the singular post type label. * * @return string */publicfunctionget_singular_label() {
returnesc_html__( 'Demo', 'tenup-plugin' );
}
/** * Get the plural post type label. * * @return string */publicfunctionget_plural_label() {
returnesc_html__( 'Demos', 'tenup-plugin' );
}
/** * Can the class be registered? * * @return bool */publicfunctioncan_register() {
returntrue;
}
/** * Supported post type features. * * @return array */publicfunctionget_editor_supports() {
return [
'title',
'editor',
'thumbnail',
'page-attributes',
'excerpt',
'revisions',
'custom-fields',
];
}
/** * Get the options for the post type. * * @return array */publicfunctionget_options() {
returnarray_merge(
parent::get_options(),
[
'hierarchical' => false,
'rewrite' => [
'slug' => 'demo',
],
]
);
}
/** * Returns the default supported taxonomies. The subclass should declare the * Taxonomies that it supports here if required. * * @return array */publicfunctionget_supported_taxonomies() {
return [
'tenup-tax-demo',
];
}
}
Due to the fact that we have auto-initializing modules, the engineer would only need to create the sub-class and fill it out. There's no need to add anything to a factory, meaning less merge conflicts.
We can also do something very similar for taxonomies.
This solution would provide engineers with:
A standardised, extendable way to register post types
A pre-existing scaffold within the repo
Loss cognitive overhead when switching between projects.
It also gives us a nice lead-in to creating a tool to help scaffold these items quickly, much like has been proposed in #89
Describe alternatives you've considered
Darshan has also submitted #104. I don't feel like this is an alternative to that approach, but it could be complimentary to it by proving a start for that modular scaffold.
Code of Conduct
I agree to follow this project's Code of Conduct
The text was updated successfully, but these errors were encountered:
From my perspective something like this would be very useful because pretty much every single project I've worked on needed multiple CPT's and every project does them slightly differently.
I am in favor of having the CPT's and anything that dictates the information architecture inside a plugin / plugins.
Is your enhancement related to a problem? Please describe.
All new 10up projects are based on this repo, but there is very little PHP scaffolding in place. This means that each different project ends up with a slightly different implementation for post types, taxonomies, REST endpoints etc.
This has two effects:
Designs
Since the auto-initialisation of modules was merged in #158, it's allowed us to create much more modular scaffolds, with no requirement for factory classes etc.
I propose introducing abstract classes that contain all the base information needed to register a CPT/Taxonomy, which can then be extended to implement project-specific ones.
For example, the following abstract post type would then allow us to easily implement further ones:
To implement a project-specific CPT, we'd then do something like:
Due to the fact that we have auto-initializing modules, the engineer would only need to create the sub-class and fill it out. There's no need to add anything to a factory, meaning less merge conflicts.
We can also do something very similar for taxonomies.
This solution would provide engineers with:
It also gives us a nice lead-in to creating a tool to help scaffold these items quickly, much like has been proposed in #89
Describe alternatives you've considered
Darshan has also submitted #104. I don't feel like this is an alternative to that approach, but it could be complimentary to it by proving a start for that modular scaffold.
Code of Conduct
The text was updated successfully, but these errors were encountered: