This originally came from a discussion [years ago] on this issue #252846: Add XML Sitemap to Core, the original discussion on that issue no longer seems to be relevant but the ideas it spawned here are. Those relevant ideas are:
- An abstract mechanism that can handle both hierarchical (such as the menu and the book mechanisms) and non hierarchical relations between nodes (such as taxonomy and several contributed modules), and offer this knowledge to contributed modules through an API.
- This new mechanism could handle the relationships that the menu and book Core Modules require, and provide structural data to modules like XML sitemap, Sitemap, etc.
It would be the goal of something like a "structure.module" or "relationships.module" to manage and maintain the different kinds of relations between Entities (mainly Nodes). If the relations are hierarchical, they could be offered to something like "book.module" that handles displaying the structure to users.
This new mechanism would not be a subset of Menu, Taxonomy, Books or another Core Module since this API and the relations it establishes would have to be more low-level and not specific to one modules data structure or workflow, as well as providing the ability to *all* content a Drupal site consists of so that moules like Menu, Taxonomy and Books could be based on this API.
The Problem
Drupal Core does not know much about the relations of content in a Drupal site; some "connections" are created through taxonomy, others through the menu and book modules. Also, there is a plethora of contributed modules trying to add this information about parent-child-relations, etc.. All those modules try to solve similar problems and to generate similar data, thus multiplying the effort to maintain this knowledge about a site's structure. Additionally, most of those approaches do not make good use of data already available in other modules. When building a site, this can lead to unnecessary complex site structures with different navigation themes, different hierarchies, performance issues, etc. We all know these problems. That's the reason, why a solution in Core is needed.
Similar Approaches
Many contributed modules try to add knowlede about a Site to Drupal; some examples:
There are many more modules with similar requirements.
These modules have completely different goals, and different "targets":
- "Simple Sitemap" and "XML Sitemap" are targeted to machines like search engines; they generated internal representations of a website's structure, but don't offer this to the site's human users
- "Site map" and "Site menu" are targeted to end users; they build a visual representation about a site and provide a page with links, that a user can click
- The core "Book" and "Menu" modules provide tools to edit relations between nodes, and/or to represent them in form of a table of contents page, or a menu.
- Modules like "Node Hierarchy" or "Node Relativity" mostly help creating relations between nodes but don't display them to end users; also, they don't provide their data to other tools like "XML sitemap"
- Modules like "Node Relativity" allows to create parent-child relationships, similar to the book mechanism, but don't integrate well to other structural tools.
Why does this need to be in Core and not in a contributed module?
IMHO it's as simple as this: Drupal is a framework offering an infrastructure to build intelligent websites. Knowledge about structural relations between nodes is such an infrastructure.
- Harvesting a site for node's relations creates severe performance issues, especially on large sites; every contributed module has to find a solution on it's own. The developers of the "XML sitemap" module solved a lot of these issues during the last months, otheres like "Site Map" or "Site Menu" didn't; knowlegde in Core about a site's structure would provide the data to contributed modules, making a Drupal site perform better and reduce overhead;
- Drupal Core already has mechanisms to manage hierarchical relations between nodes (book, and menu modules); but it can't handle non-hierarchical relations, and both modules should be integrated on a more abstract basis.
- Contributed modules could concentrate fully on their specific goals (e.g. providing a XML sitemap to search engines, or provide a human-readable sitemap to users, or provide navigational menues, etc.)
I'm searching for quite some time for solutions to the described problems; so far, I only discovered approaches targeting parts of it. This feature request is intended to
- either start a discussion about getting structural knowledge about a site's content into core,
- or to point to already existing discussions about this topic if I missed those.
[Thanks & Greetings, -asb]
Comments
Comment #1
jscheel commentedI wonder if the push for getting RDF into D7 would help with this. Honestly, I don't even know if that is going to happen anymore, I've been out of the loop for a while...
Well, subscribing anyways.
Comment #2
mdupontI guess the most promising work in this direction currently is Relation module.
Comment #6
colanI've reviving this based on the discussion we've been having in #1261130: [PP-1] Rewrite book module to use a standard, reusable API for creating hierarchies.
It makes perfect sense for use by Menu, Taxonomy, and Book. The Book module could be kicked into Contrib or not (separate issue), but either way, it would use the API.
As far as storage goes, we would need to store a parent ID (at least).
This would help a certain class of issues that have been popping up:
There's an Entity Reference Hierarchy module that may serve as a useful model. It already has a #2862096: Replace Book module issue.
Comment #7
aaronmchaleUpdated the original idea text to be a little more generic and more relevant to the state of Drupal today, as well as fixed some formatting.
@colan also added the issues you linked as related issues
To me it seems like an obvious implementation of this API could centre around the Entity Reference Field Types, which would probably be a good basis to work from since it already has the ability to create the relationships we are talking about. Additionally since they are fields it means they are very easily useable by other parts of the system, such as when creating Views.
So running with that train of thought, here are some questions we should consider answering and some of my thoughts:
Thinking on that a potential issue I see with 2 (question 2 above) is that it would be hard for a module like Books to know which relationships to use when using this abstraction layer. For example if a node has a Entity Reference Field relating to a Book but also relating to a Taxonomy and another relating it to a parent item in a menu, which could cause some confusion. So we'd either need some kind of identifier when returning the Entities from the API Methods indicating what field the relationship came from. That could be in the form of a "Entity Reference Results Object" or a multi-dimension array.
For example getParents() returns the above mentioned object which has methods such as:
Personally I'm in favour of the object approach since it's better for those like myself using IDEs such as PhpStorm.
Another potential issue is that right now Entity Reference Fields don't have the concept of defining Parent, Child and Sibling relationships, so we'd need a way for this identifier to be implemented. Most likely an additional configuration property for each Entity Reference Field which allows the admin creating the Field to define if Entities added to this field are parents, children or siblings. You wouldn't want this to show for users when they are adding the individual Entity References, as that could just be confusing, and in the majority of cases the way each Field is used implies if Entities added are parents, children or siblings.
Implementing this idea with a small API extension to the Fieldale Entity API being just based on Entity Reference Fields I think would be both the most minimal amount of work but also provide the highest reward, since it would then be easy to maintain and provide a very solid foundation for other Core and Contrib modules to hook into with minimal effort.
Assuming we agree on all of this question then becomes, what does the UI look like and how does the user interact with this when it comes to modules actually implementing it such as Book, Menu and Taxonomy?
At the moment that is what I'm unsure of, because while this is a great solution from an API point of view it has the potential to be difficult for inexperienced users to work with. Right now users just enable the Books module, they can then start creating Books, they don't have to worry about adding Entity Reference Fields and making sure the Book module knows about them. So I think it's important for us to find a way to make this work which doesn't result in users seeing any more complexity.
Thanks
Aaron
Comment #8
giorgio79 commentedhttps://www.drupal.org/project/tree
Comment #9
gabesullice@AaronMcHale,
Thinking about a potential API and looking at the (high-level) approach taken by tree for D7. I think there needs to be two things:
Defining hierarchies as entities means an entity will be able to belong to many hierarchies, not just one. It also provides the ability to load and moderate a hierarchy.
The new field type would have two entity reference properties, a
childproperty that would be a reference to another entity and amember_ofproperty that would be a reference to the hierarchy entity.To make an entity type "treeable" one would only need a "hierarchy" field to store items of this new field type. A
hierarchy_parentfield could be computed (like termparent).To get parents/children for a distinct hierarchy, one could just filter the field items by the
member_ofproperty (the filter callback could be provided by the hierarchy entity).This approach also makes it fast to load all entities belonging to a hierarchy because the entity query system already allows filtering on properties of a field:
This could be implemented using a new hierarchy entity type. Bundles of the hierarchy type would be tied to a target entity type (i.e. you could create a new hierarchy type that can contain terms, or a new hierarchy type that can contain nodes, or link items). These hierarchy types could be fieldable (to contain a menu title, for example).
In whatever module adds this, one would then implement
hook_base_field_info_alterto add the hierarchy field to any entity type which is targeted by a hierarchy bundle.What I particularly like about the approach above is that (in theory) this can all be done without changing much of the Field API. One doesn't need to add any new core interfaces to find out if an entity can be in a hierarchy for example. Instead, you can just do:
All of the specific methods for managing a hierarchy would be contained to the new hierarchy entity type or the new field type (which could be done in core or contrib!).
In terms of a UI, the draggable things like taxonomy has would be managed from each particular hierarchy entity edit page.
Comment #10
heddnRe #9: term parent calculation has gone away in 8.6 of Drupal. It now uses a normal entity reference field. The child or the parent can be automatically calculated (depending on the direction of the relationship), so storing both is probably not needed.
Can you expound on the intermediary hierarchy entity and what problems it solves that entity reference fields do not?
Comment #11
colanGood question. I typically get by with a single Entity Reference field for pointing to a parent entity.
Comment #12
gabesullice@heddn, as far as I'm aware, it's still a computed field in 8.6, no? Perhaps we're saying the same thing differently?
I wouldn't label the hierarchy entity as "intermediary", it's more like a grouping mechanism.
Let's say I have user entities and I want to represent family trees and org-charts in the same application (bizarre, but let's roll with it).
A user might be the biological parent of some other user and simultaneously also be another user's boss. The family and the org chart are distinct hierarchies.
How do I differentiate between entity reference items that target child entities for the family tree and child entities for some org chart? If all the child entities are in a vanilla entity reference field, there would be no way to do so. Getting the children of that user would turn up both the user's biological children and the user's direct reports.
To solve that, the "hierarchy entity" would be the thing that represented say, the "Smith Family Tree" or the "Widget Corp Org Chart". The new field type would pair an entity reference to a child entity with a reference to the "hierarchy" to differentiate the nature of the relationship.
With a pure entity reference field, you'd need to have distinct fields for every possible tree to which an entity could belong. That's a bit how terms work now, they can just belong to one hierarchy, based on the vocabulary config entity. Thus, having a distinct field for every hierarchy type would quickly become unscalable. It would also prevent content authors from creating new hierarchies (in the same way that they can't create vocabularies without the 'administer taxonomy' permission).
The new field type I'm proposing would be a composition of two EntityReferenceItems, one would reference a child entity and one would reference the hierarchy to which the relationship "belongs."
Comment #13
heddnAh, that makes more sense now. Thanks for the detailed explanation. Does the hierarchy API need to support more than a single hierarchy without multiple fields? I guess that deserves an answer.
BTW, here's the CR where term parents was converted in 8.6: https://www.drupal.org/node/2936675
Comment #14
gabesulliceDerp. I really don't know what I was thinking of (just my imagination I guess).
You're absolutely right though! So, thank you for the explanation :)
Comment #15
gabesulliceI believe it would be a really frustrating constraint if it didn't. To take another family tree example, it would be impossible to create a kind of genealogy site.
For example, if person A is in the Foo Family tree and marries person B in Bar Family tree, the only way to reconcile that with would be a new field for the Foo family and a new field for the Bar family. You'd quickly end up with hundreds or thousands of fields. (or you'd have to put them all in one mega-tree that would not be at all performant).
Does the hierarchy "need" to support that? It certainly couldn't, but I believe it would be a real lost-opportunity if it didn't.
Edit: Another more familiar example: adding a node to many books.
Comment #16
giorgio79 commentedAlso some movement here https://www.drupal.org/project/entity_hierarchy
Comment #17
giorgio79 commentedComment #18
aaronmchaleI don't think we should go as far as to define a new Entity Type for hierarchies, as for most practical cases you would have no use for such an Entity, for example Books has a hierarchy but it just uses the top level node as the entity which the hierarchy sits under, Taxonomy, Menu and others already define their own Entity Types.
So adding a new Entity that the system has to keep track of might be a bit overkill and might limit the potential use case of this API.
We have to look at fundamentally what we are trying to accomplish here and to it in the most flexible way. As such it seems like the easiest approach is just to extend the scope of the existing Entity Reference Field Type to include the concept of parent and child relationships like I suggested in #7. Since fields can already have multiple values it wouldn't be a problem to have an Entity Reference Field reference multiple other Entities to make the current Entity part of multiple hierarchies.
In summary we shouldn't be thinking about defining what the hierarchy is, we should just focus on extending Core APIs to provide the building blocks for the concept of "hierarchical relationships between Entities" to allow other modules like Books, Menus, Taxonomy, etc to define what the Hierarchy is. Doing this is the most extensible and least restrictive approach.
Comment #19
neograph734It might also be an idea to look into a model similar to the relation module for Drupal 7. That module uses 'entity references' that are fieldable entities themselves. It would allow a menu or taxonomy term to be a (many-to-one) reference to childs, whilst also providing field for storing metadata such as the menu link text or the taxonomy term name.
Comment #20
murzVery light and easy example of Entity Hierarchy implementation is Bricks module for 8.x, and it's predecessor - Tree module for 7.x. So if Drupal will provide API for building hierarchy based on Entity Reference - this will already large step.
Next step is to provide more effective storage for large hierarchy trees and queries on this tree, because current "Flat table" storage (like in Bricks) is good only when we always operate with all tree, not with part of it.
For large trees good implementation is Entity Reference Hierarchy module, that have better storage based on
previousnext/nested-setlibrary.Comment #21
nod_Comment #22
dat deaf drupaler commentedBeen experimenting with closing gaps between core Content Types + Storage Entities module + Entity Reference Hierarchy module, and proposed 'Junction of content type and entity storage type' issue.. would something like this be a possibility to include in part of this development track?
Concept #1: Content type - works well!
Concept #2: Storage type - works well!
Concept #3: Parent content type + child storage type - works however children does not show up when viewing parent content's children page (node/%/children)..?
Was wondering if it would be possible to close the gap between both entity bundles?
Storage Entities is quite powerful which offers the most appropriate (lightweight) content bundling alternative to paragraphs in regard to content modeling designs.
Thank you for your consideration.
Comment #23
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.