Problem/Motivation
The division of features among content, taxonomy, and blocks--publishability, revisionability, hierarchy, display path, block display, etc.--is somewhat arbitrary, and the community has demonstrated that the original assumptions of mutual exclusivity between concepts is not always sufficient. Consider for example all the contrib modules that add hierarchy to nodes, allow placement of nodes as blocks, or (for a while there) just made everything into nodes. Just because something serves a taxonomic function, for example, doesn't mean it isn't also content.
The effect of the present dynamic is that site builders are often forced into awkward architectural choices. Imagine a zoology website with pages for animal phyla, classes, orders, families, genera, and species. Taxonomy seems like the obvious choice to represent this data--it's practically the canonical example. However, if the pages need to go through workflow, taxonomy is ruled out because terms (currently) aren't revisionable or publishable. The site architect will probably create a content type, therefore, and try to find a bolt-on solution for hierarchy.
In other words, content, taxonomy, and blocks are not mutually exclusive categories, and the distinction between them in business terms is in no way clear or absolute. Whereas in Drupal as it stands, the reverse is true. And it is unsurprising therefore internally to see inconsistent APIs, user interfaces, and permissions between the systems, as we do; and externally a large number of contributed modules compensating for the misalignment and a lot of blog posts trying to explain when to use which approach, as we do.
Proposed resolution
Align our technological assumptions with how users actually view content:
- Abstract the currently distinguishing features of nodes, taxonomy terms, and blocks and make them configurable--much as we did with comments, which used to be an on/off feature of content types exclusively but can now be applied arbitrarily to (basically) any content entity type as a field.
- Eliminate the mutually exclusive distinction between content, taxonomy, and blocks and just make everything "content". Unify the APIs, and if a distinction is still necessary or valuable at the UI layer, make it configurable.
This is a radical proposal, I realize, but I cannot but suppose that it would result in great savings in terms of reducing code in core and complexity in contrib. (Imagine writing code with the knowledge that any content was just a node with fields and properties!) In business terms, it seems like nothing other than an acknowledgment of the manifest facts.
Remaining tasks
TBD
User interface changes
TBD
API changes
TBD
Data model changes
TBD
Comments
Comment #2
amateescu commentedCore is already heading in a direction that's similar to the one proposed in the issue summary by standardizing most entity types on the
EditorialContentEntityBasebase class. Incidentally, this is also one the main goals of the Workflow Initiative :)However, your full proposal basically means "move all the code/logic from the entity type level to the field type level", and I don't think that's a good place to end up. See the media entity for example,
\Drupal\media\Entity\Media, would you imagine all that logic sitting one level below, in a "media field type"?Comment #3
gabesulliceThis is a very interesting proposal. It is radical too. I like the cut of your gib :)
I tried to make a similar case here: https://events.drupal.org/baltimore2017/sessions/type-system-tomorrow
The argument really boils down to composition over inheritance. Ideally, we could pick and choose from features like "hierarchy" (taxonomy) or "revisioning" (content_moderation) to compose the ideal set of content types for our sites.
However, the practical difficulty is that it is really hard to imagine actually implementing this. Our basic type hierarchy (entity type, bundle, field, etc) is based on inheritance not composition (because it's built on top of PHP).
There may be an opportunity to do something like this as TypedData matures though. By working with typed data we might be able to replace raw PHP calls like
$entity instanceof RevisionableInterfacewith something like$typed_data->hasTrait(RevisionableTrait::class);whereRevisionableTraitmight be a set of typed data property definitions and methods that could be dynamically injected into the entity's typed data definition when it is first constructed.One could then get type safety back (if one insists on it, PHP really isn't a typed language to begin with) by doing a little dance:
Idk, just spewing some raw ideas to imagine how your idea might work in practice :)
Comment #4
wim leersFirst: yes, this would be an enormous leap forward! Thanks for proposing it in more concrete terms and articulating the pain points that this brings!
Second: we're already heading in this direction, but it's a long, slow process. Both because it's lots of work and because it must be evolved over time in this direction, to minimize disruption.
One of the things @amateescu didn't mention which surprised me, is @amateescu's plan for the concept of treeability — which would allow any entity type to get taxonomy-like capabilities. See his work in https://www.drupal.org/project/tree and mentions of this in #2543726: Make $term->parent behave like any other entity reference field, to fix REST and Migrate support and de-customize its Views integration (that patch was specifically changed to better allow this treeability to be added in the future).
He's already been heading up the process/work of making all entity types revisionable, publishable etc, so he has lots of experience in making more things more *-able, which makes me hopeful that this will actually happen! :)
Comment #5
webchickCould you clarify this by chance? I'm not sure how the proposed unification of these things necessarily equates with also moving all logic "down" a level.
Comment #6
amateescu commented@webchick, what I was trying to say there is that the only concept that we have in core at the moment which allows site builders to add a configurable behavior to an entity type is the field system.
Comment #7
gabesulliceHere are some thoughts about how "hierarchy" (taxonomy) might be made "à la carte": #267855-9: Provide an entity hierarchy API
Comment #8
gabesulliceOn a different note, going back to my comment in #3 🙄. I've found a word for the concept I was trying to get at with the
->hasTraitidea 😀In JavaScript, some new features and libraries that are working with a concept of "protocols". These so called protocols enable runtime polymorphism. See:
https://github.com/Gozala/protocol
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iterat...
Why is that important here? It's because PHP interfaces must be declared in code (this is "compile time"), while a "protocol" could be satisfied at runtime (this is when the code is actually evaluated). We might be able to write an idea of Protocols into TypedData or the Entity API and then have a nice and "type-safe" way of doing things. For example, the following "compile-time" code:
would become the following "run-time" code:
A really interesting feature of protocols is that they can be implemented by third-parties. I.e. if you wanted to invent a
RevisionableProtocoland automatically have everything that already implementsRevisionableInterfacework, you would be entirely free to do so :) Then, for entity types which don't implement the interface, you could provide your own implementations by usinghook_base_field_info_alterand writing some glue-code that does the wrapping/unwrapping I was doing in #3 so anyone using your protocol wouldn't need to go through the same hoops.Further reading:
https://gozala.github.io/2012/03/21/protocol-based-polymorphism.html
https://github.com/Schuck-Johnson/PHP-Protocol/blob/master/Details.md
Edit: Extra thoughts...
Thinking of this in the context of hierarchy (linked to in comment above), one can begin to imagine how powerful this feature would be for Drupal.
For example, let's say you wanted to put users into a hierarchy (like an org-chart), how would one do that? (today, you simply can't)
You could create a new entity type like Profile and on that class you could define methods for managing hierarchy. Then you'd have to write all kinds of other customizations to make it as easy to manage your profile picture as it is to update your password because the admin UI presumes that users are editing their user entity.
OTOH, Drupal core could decide that all ContentEntityInterfaces should extend some hypothetical HierarchicalEntityInterface, but for 90% of Drupal sites, that complexity wouldn't be needed.
Taking contrib into account, maybe contrib could provide a hierarchical_user module that overrides the user module somehow. But then that might conflict with some other revisionable_user module.
With the protocol approach, Drupal core could ship with a HierarchyProtocol and UIs to deal with entities in hierarchies, from there, all that would be needed is for a contrib module to implement the protocal for the user entity type. Another module could implement a protocol for revisions. A site builder would install the user_hierarchy module and go to hierarchy admin screen "Create a new hierarchy" and name it "org chart" and start adding users to it.
Comment #9
quietone commentedThe Ideas project is being deprecated. This issue is moved to the Drupal project. Check that the selected component is correct. Also, add the relevant tags, especially any 'needs manager review' tags.
Since it has been quiet on this issue for about 7 years, checking in to see if this is still valid.
Is there interest in this feature request?
Comment #10
traviscarden commentedI'm certainly still interested. I still think it's one of the biggest potential improvements for content modeling in Drupal.