The problem
WordPress introduced registration of custom taxonomies in WordPress 2.3 (September 2007) and custom post types in WordPress 2.9 (December 2009). Both of them have been exceptionally important to shape and position WordPress as a CMS, and to provide the necessary flexibility in allowing different types of expression in content. However, WordPress never provided a core way to manage them, leaving those fundamental structural mechanisms available only for developers, and historically relied on plugins for that. Plugins, unfortunately which never came up with a consistent, coherent way to manage these fundamental content structures. The plugins do the job, but using them transfers trust and longevity to a third party for what is arguably a primitive of the platform. Not to mention that this creates a dependency on those third party plugins - orphan content is a known failure when those plugins are deactivated.
Why solve it in Core
Existing plugins are great, and we're not trying to replace what they do well. The argument for Core ownership is the same argument that's applied historically to navigation menus, templates, patterns, and fonts: when something is a fundamental primitive of the platform, the platform should ship a baseline, and plugins should extend that.
A few specific reasons:
- Data ownership - When a plugin registers post types in PHP at runtime, the site's structure is bound to that plugin's lifecycle. Core ownership means user-defined content types are first-class data, not plugin state.
- Consistency. The new admin paradigm (DataViews, DataForm, the site editor) is where users already manage structural concepts. Content types eventually belong there too. Asking users to context-switch into a plugin's bespoke UI for one of the most fundamental concepts in WordPress is a coherence problem.
- Foundation for other work. Block bindings, query loop, block-based templates, DataViews, DataForms, and a lot of the upcoming editor surface area increasingly assume the site can model its content. The editor has been outpacing what non-developer users can actually configure.
- Built-in extensibility. "Simple cases in Core, complex in plugins" is the line we're drawing. Custom field types, complex relationships, conditional logic, advanced UI — those are where plugins add value, and they're explicitly out of scope here.
- Discoverability. A WordPress user opens the admin and sees Posts, Pages, Media, Comments. The fact that their site could model "Books," "Recipes," or "Events" is invisible — that capability simply doesn't surface in the admin. Users who could benefit from custom content types often don't know the option exists.
Goal
Allow the WordPress admin to let you express the primitives that WordPress runs on. In a nutshell, this entails:
- A user who wants a basic, categorizable content type can do it from the admin without code, plugins, or the REST API.
- Stable and consistent storage and REST shape that we'd be willing to commit to long-term.
- Internationalization story for labels resolved, even if left for 3rd party extensions to fully cover (this is one of the genuinely hard open questions; see the tracking issue).
- DataViews / DataForm / related primitives are absorbing various cross-cutting concerns that this work surfaced.
- Existing CPTs and taxonomies registered in PHP keep working untouched alongside user-defined ones, and disabling the experiment doesn't damage data.
Success/promotion criteria
We would consider promoting the experiment to core when:
- The simple-case bar above is met and tested with real users.
- Storage/REST shape has been through enough churn to feel stable.
- Performance is profiled and acceptable
- There's a comprehensive test suite covering the REST API functionality and all basic flows
- Edge cases like slug changes, deletion of unrelated entities, and others, are handled properly
Failure criteria
We could consider dropping the experiment in case:
- The storage model doesn't meet real-world scale, performance, or extensibility expectations.
- The i18n story for labels can't be solved without major compromises that defeat the purpose.
- We've failed the extensibility bar and the "simple cases" bar requires us to keep adding surface area until we've effectively rebuilt one of the plugins inside Core, at which point Core ownership stops being the right answer.
- User research shows the addressable audience is too narrow to justify the Core surface area.
Phases
Longer-term, we're considering splitting the work in the following phases, which most likely will end up being individual experiments:
- Basic post type and taxonomy management (current focus)
- Managing custom fields of post types and taxonomies, with built-in extensibility for custom field types
- Managing existing core- and plugin-registered types (potentially under a constant or developer flag)
Architecture
Taxonomy fields
Enhancements
Bugs
Cross-cutting concerns
Post Types
Integrations
Notes
This is a living issue, and any suggestions are welcome.
The problem
WordPress introduced registration of custom taxonomies in WordPress 2.3 (September 2007) and custom post types in WordPress 2.9 (December 2009). Both of them have been exceptionally important to shape and position WordPress as a CMS, and to provide the necessary flexibility in allowing different types of expression in content. However, WordPress never provided a core way to manage them, leaving those fundamental structural mechanisms available only for developers, and historically relied on plugins for that. Plugins, unfortunately which never came up with a consistent, coherent way to manage these fundamental content structures. The plugins do the job, but using them transfers trust and longevity to a third party for what is arguably a primitive of the platform. Not to mention that this creates a dependency on those third party plugins - orphan content is a known failure when those plugins are deactivated.
Why solve it in Core
Existing plugins are great, and we're not trying to replace what they do well. The argument for Core ownership is the same argument that's applied historically to navigation menus, templates, patterns, and fonts: when something is a fundamental primitive of the platform, the platform should ship a baseline, and plugins should extend that.
A few specific reasons:
Goal
Allow the WordPress admin to let you express the primitives that WordPress runs on. In a nutshell, this entails:
Success/promotion criteria
We would consider promoting the experiment to core when:
Failure criteria
We could consider dropping the experiment in case:
Phases
Longer-term, we're considering splitting the work in the following phases, which most likely will end up being individual experiments:
Architecture
add/editscreens #77657editandaddtaxonomy. PR: Experiment: Taxonomies new package andadd/editscreens #77657editaction toquick editand createeditaction that redirects to a separate page. PR: Experiment: Taxonomies new package andadd/editscreens #77657taxonomy_object_typeas post meta. See 1, 2, 3.revisionssupportTaxonomy fields
auto-fill labels#77786labelsare internationalized. Maybe adding some filters that 3rd party plugins is the way to go here.Enhancements
taxonomy-keypattern validation. See ongoing discussion here: Experiment: Add custom taxonomies #77497 (comment)post type. This is related to how we end up storing the config. PR for post type filter: Experiment: User Taxonomies REST controller #77697Deleteaction should also have a way to delete the terms created. Consider having a checkbox for deleting terms in the delete dialog. It should also check and delete anydefault termset for the taxonomy (see here. PR: Content Types: Add checkbox for deletion of terms #78629create/savebutton based on form validity. PR: Experimental: Content types - disable create/save button based on form validity #77931slugfrom singular label for taxonomies and post types #77938useViewto preserve search, filters, etc.. PR: Experiment: IntegrateuseViewin content types lists #78197Bugs
taxonomiesDataViews height #77603Cross-cutting concerns
auto-filllabels in add/edit taxonomy. Another thing we could consider is supporting ReactNode in the FormField description, though this is not serializable.editaction. This will inform us whether is good for our use case and whether thequick editin site editor can use it too.createPostutils to handle easier creation of different post types. See: https://github.com/WordPress/gutenberg/pull/77998/changes#r3194246751. PR: Testing: AddcreateRecorde2e request util #78017isVisibleAPI that also have validation can make a DataForm invalid, even if we only want validation when the field is visible. There is a workaround by usingcustomvalidation but it should probably be baked in the DataForm handling. An example is thedefault term namefor user taxonomies (current experiment) introduced here.Post Types
flush_rewrite_rules()on change of has_archive, public, or renaming the CPT slug - Content types: flush rewrite rules on rewrite-impacting changes #78058menu_iconandmenu_positionfields #78285Integrations
taxonomies) should retrieve inactive user taxonomies too. See: Experiment: Sync user taxonomies with post types #77997 (review)object_type(or a post type with a changedtaxonomiesfield) syncs the relationship server-side, but the client doesn't invalidate getEntityRecords for the other domain. Switching tabs after such a save can show stale rows. PR: Experiment: Content types invaidate cache for synced taxonomies-post types #78143Notes
This is a living issue, and any suggestions are welcome.