Skip to content

Experiment: Content types tracking issue #77600

Description

@ntsekouras

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:

  1. Basic post type and taxonomy management (current focus)
  2. Managing custom fields of post types and taxonomies, with built-in extensibility for custom field types
  3. Managing existing core- and plugin-registered types (potentially under a constant or developer flag)

Architecture

Taxonomy fields

  • Add more fields. Right now we've only added all labels. This task should be implemented incrementally for easier testing. Visibility fields PR. Advanced fields part 1
  • Users should have a way to auto-fill labels based on the required singular and plural labels. PR: Experiment: Taxonomies implement auto-fill labels #77786
  • Investigate how/if labels are internationalized. Maybe adding some filters that 3rd party plugins is the way to go here.

Enhancements

Bugs

Cross-cutting concerns

Post Types

Integrations

  • Make sure post types and taxonomies relationships are integrated and synchronized.
  • When deleting or changing the slug of a taxonomy, "Post Terms" block instances are orphaned.

Notes

This is a living issue, and any suggestions are welcome.

Metadata

Metadata

Labels

Content types (experimental)Affects the content types experiment[Status] In ProgressTracking issues with work in progress[Type] Tracking IssueTactical breakdown of efforts across the codebase and/or tied to Overview issues.

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions