Problem/Motivation
AKA Entity display route in core
Steps to reproduce
Product managers for Drupal CMS have identified this requirement:
The ability to use nodes as micro-content (e.g. reference fields) without having to decide up-front if you want routing or not. E.g. consider event content-type with a location field. You can model the location as a taxonomy term, but then if you decide at some point you want to treat location as content you have to do a migration. Ideally you could create it as node content but turn off the full page display. At present this would require something like rabbithole.
Proposed resolution
- Resolve #3481362: Add path/pathauto integration in a performant/acceptable fashion
- Adapt the code for core
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #37 | 3483304-nr-bot.txt | 91 bytes | needs-review-queue-bot |
| #23 | oneoff.jpg | 48.48 KB | rkoller |
| #12 | Screenshot 2024-10-30 at 3.47.25 pm.png | 48.74 KB | pameeela |
Issue fork drupal-3483304
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
pameeela commentedUpdating the issue to split out the multiple displays aspect.
Comment #3
pameeela commentedComment #4
pameeela commentedComment #5
pameeela commentedEdit: Couldn't see how to actually disable the page display, but I see it requires enabling the Full content view mode, and then it can be disabled from there.
Comment #6
pameeela commentedComment #7
pameeela commentedFurther to my previous comment / confusion: I think that because this was originally built for the multi display use case, it's fairly complicated for the no display use case. I'm not sure how to resolve this.
Part of the confusion comes from the fact that you have to enable the full page display in order to disable the page route. And the complexity around having this setting per view mode is from the multi requirement.
Basically the ideal UX for the "disable page display" feature is to have a single setting on the content type for whether there is a page display for this content type. I am not sure whether this would then conflict with the multi display later?
Comment #8
larowlanWe can do that and store it in the same spot for any future functionality
Comment #9
larowlanComment #11
larowlanKept it at node-type until #3484255: [PP-1] Support adding additional routes for view modes other than 'full'
Comment #12
pameeela commentedAwesome! This works:
Quick testing highlights a few of things we need to consider:
Feels like we should address these as part of this issue? There are other things like the nodes coming up in the menu UI (separate from the menu settings in the node), and I'm sure other things, that I think could go in a follow up.
Comment #13
larowlanThis is in node.html.twig in the node module, so it is used even in teaser view mode
I think we can fix items 2-4 if we:
* Instead of handling it in the controller, handle it in routing access
* Return a access denied in the routing access which fixes item 2 and 4
* Add a custom exception subscriber that turns the 403 into a 404 in this case _or_ redirects the user to the edit form if they can edit - fixing item 3
Thoughts?
Comment #14
pameeela commentedAh right re: teaser, I should have checked that!
I actually thought of redirecting to edit for #4 already, in which case it also makes sense for #2, even if the flow is a bit unexpected. It is also unexpected to have one listing where in some cases the title links to the view display and some to the form, but it seems like the best option. Though it may need further discussion/thought.
#2 is actually about the menu settings for the node itself, since it's enabled by default, the menu settings option appears in the node edit form. So the routing access change would fix it appearing in the search, but not the menu settings on the form aspect.
Comment #15
pameeela commented... and I just also realised that the URL alias also makes no sense on the form.
Comment #16
catchThe display submitted stuff will eventually be fixed by #2353867: [META] Expose Title and other base fields in Manage Display, hopefully as part of the XB work although I don't think it's been looked at yet. It should not be on this form at all.
Left a comment on the MR: https://drupal.org/node/3155569 already handles this at the routing level, would need an alter (or even directly in the route builder?) to set the route parameter.
I left that comment before I saw the discussion here about links going to 404s etc. and not sure what the implications of all that are. Seems like a 404 listener that checks if we're on a canonical entity route, checks this config, then redirects to the edit form or throws a 403 might be compatible with using the existing router support?
Comment #17
quietone commentedComment #18
larowlan@catch's suggestion to make use of https://www.drupal.org/node/3155569 fixed 3 and 4 in a real nice manner
1 I think we have to leave as is because its used in teaser view mode etc
2 I think we should discuss in a follow up, technically its nice because you _could_ create all the content for a node type and then turn on the display to launch that content type.
I'll work through any remaining test fails. I addressed all the fails locally from the last pipeline except nightwatch, which look random
Comment #19
pameeela commentedYeah this is great! So to confirm:
This makes way more sense to me than redirecting to the edit page. And agree the other things can be follow ups.
Comment #20
pameeela commentedWhich 2 is this referring to? I'm not really sure about this scenario because you'd be creating all of the content without ever being able to see it? Why would you not just use bulk publishing or workspaces for this?
Comment #21
rkollerOne detail to note, the description for the
Display settingsvertical tab only represents the already existing checkbox, so i suppose the description in the vertical tab would have to be adjusted to cover both checkboxes?Comment #22
pameeela commented@rkoller it looks OK in #12, are you seeing something different?
Comment #23
rkolleroh i havent looked at the microcopy of the vertical tab in your screenshot in #12. then yeah for me it looks different, it looks like that:
but after seeing your screenshot i've rechecked the other content types. turns out the content type i'Ve created and you are seeing the screenshot for is showing that old description. but the article and basic page content type have updated that description in line to your screenshot in #12 and i've created another content type now which is also showing the description shown in #12.... NO idea how that could have happened to the content type i'Ve first looked at and tested. sorry :/ update: ok i neeeever realized nor noticed, but the description for vertical tabs is getting updated based on the checked settings. ticked the create page display checkbox again ,now the newly created content type has the same description as the other content types. argh, i put on the hat of shame now. :/
Comment #24
pameeela commentedHa, all good, I am glad it's working!
Comment #25
aaronmchaleMaybe I'm missing something here, but isn't this what you would use content blocks for?
Nodes are already hard to define - are they a page, an article, a post, who knows? - are we just making them even more ambiguous?
Comment #26
larowlan@aaronmchale this requirement came from Drupal CMS/Product managers who don't want people to have to choose upfront. @lauriii and @pameeela would be the best people to discuss it with
Comment #27
pameeela commentedI think the IS summarises the use case well. I can't say that I have ever considered using blocks for microcontent, for a number of reasons, but they and other existing solutions don't offer the flexibility of converting to a normal page in the future.
Comment #28
aaronmchaleSo I do understand where the motivation for this is coming from, but to elaborate further on what concerns me:
Let's imagine for a moment you're delivering a Drupal training session to people who have never used Drupal before but are maybe familiar with other CMS's, you start by trying to explain to them what nodes are. You explain that content types are like pages and posts in WordPress. You then explain that content blocks are reusable pieces of content that can be embedded in other parts of your site, whether that be on a page, in the header, footers, sidebar, etc. There's a pretty clear distinction there, but with this change I worry that we're making it harder for new users to understand what they should be using nodes and blocks for. Because now, with this change, you explain blocks, but then you also explain that nodes can do the same thing, and so someone asks what's the difference between nodes and blocks, and now you probably don't have as good of an answer.
We already have a difficult time describing to new users what nodes are, are they pages, posts, articles, all three... In the Drupalisms working group how we name and describe nodes is a problem that we're very much aware of. I worry that this change would only make it harder to define what nodes are.
A while back, at a usability group meeting we were presented with an issue which would have added a "View" tab to blocks, and after a long discussion our recommendation was not to do that, and at most to add a "Preview" option, so you can still see what the rendered content block looks like, but it's still clear that content blocks are not meant to be pages. Our worry then was the same, that we would be blurring the lines between nodes and blocks.
Drupal by design has a huge amount of flexibility in how you can structure entity types and fields, and as a result of that it may be confusing at first for new users as to what the purpose of all these different types are - blocks, nodes, media, taxonomies, etc - and what makes each different and when to use them. With that in mind, I do feel that Core needs to do its best to make it clear what the purpose of each of these different types are.
An alternative solution to this problem could be to look at the Storage module, it's a module I've personally used, it provides an entity types where the entities can be used for storing arbitrary data, can be embedded in other entities, or can be viewed on their own.
Again, I do understand the motivation here, I'm just not sure that the solution is to blur the lines between nodes and blocks and by doing so make it harder to clearly communicate the differences.
Comment #29
matthieuscarset commentedI join @aaronmchale here. I think the solution to content standardization is to provide a "universal" entity type: Storage is the best solution for this IMO.
Comment #30
pameeela commentedI am struggling to understand your objections @aaronmchale. Firstly, I don't see this affecting the use of blocks, or how to explain them. I really just don't see the link at all to blocks, they are not a solution to this problem in my experience. I agree that it can be hard to define what they are to new users but I don't think this feature adds to that.
Storage or Microcontent are viable alternatives, but as noted in the IS, the intention is to provide flexibility to leverage the display in the future. I have had this happen several times on client sites where we started out with a stub-like content type but later used the full page; or vice versa, we initially had a page but turned it into a stub.
The existence of Rabbit Hole with >60k installs is pretty good evidence that this is a feature people want. Most importantly this doesn't prevent you from using Storage or blocks if you prefer that?
To me (and the others on the Drupal CMS team) the ideal situation would be to make nodes flexible enough that we don't need alternative entity types provide by Storage or Microcontent for this use case. Then all of your content is managed in one place, which to me seems much easier to explain? (Note though I am not suggesting we should replace blocks with nodes, only the node-like content.)
Comment #31
lauriiiExplaining Nodes as pages is already a simplification of the reality because they are not just pages. This is why we are already not calling them Pages, but Content in the product. I believe that for a non-technical user the easiest way to explain Nodes is by the purpose that a Content Type has in the specific site; e.g. product, product collection, event, blog, press release, etc. They may generate a page but often they are used for more than that. For example, a product could generate a page, but it could be also used for "micro-content" because you may want to create a list of products or embed a product as part of a blog post.
When you have a page that is not modeled (i.e. Basic Page), it is just a page because it provides only limited re-use. XB plans to separate this from the re-usable modeled content: #3482259: Landing page integration: new content entity type for unstructured content. Based on user interviews we conducted with content creators this spring, this maps well with their mental model. Here's an anecdote from one of the interviews:
Interviewer:
Participant:
Many products like Webflow, Framer, Wix explain Nodes as CMS collections. I think this is a smart way of explaining modeled content to the site builder. It's communicating that unlike pages, modeled content is something that allows you to create lists besides being able to have a page. While their content modeling capabilities are more limited than what Drupal has, I believe that they do a better job at explaining their content modeling capabilities in relation to unmodeled content. I don't think we can adopt this quite as is because in Drupal you can create lists that combine multiple content types.
How does Block Content fit this thought process? Unlike Nodes, Block Content is for content that you would never want to display as a page or list for the end-user. It could be used for example for a hero that you want to display on multiple pages or a cookie banner. It would be rare for someone to create a page for a hero block or a list of hero blocks for other than administrative purposes.
This allows us to explain why for example Location should be a content type, and not a type of Block Content; because it's something that you may want to be able to list for the end-user, it's something that you may want to expose as a page. This helps explain why we need this change; to allow site builders to create modeled content without forcing them to have a canonical page for it.
Comment #32
aaronmchaleThank you @pameeela and @lauriii for providing more insight and motivations behind this, much appreciated.
When I read this, I think it started to make a lot more sense to me. Initially I was approaching this from the perspective of reusable pieces of content that you might add into a page via layout builder, or embed in a sidebar. Which I think we can all agree is probably what you would use blocks for. But if we consider the example of a Location content type and Location content, which would be structured content and used in a specific way; As you say, you want to display that content not as pages, but instead embedded in a View or elsewhere, that's where I can now see the potential in this.
I was trying to think of other types of content which would be suited to this, and I think a really good example of where this might be used is with a Person/Staff Profile content type. Let's say initially your a small team, and you create a staff profile content type, you only want these to be displayed in a list and you use Views to do that, you don't want people going directly to each individual profile. Over time, the team size grows, so you have more profiles, the fields also start to grow, maybe initially you only had a few basic fields, but gradually more rich fields are needed, like a photo, a biography, links to social media. Eventually you realise you need these profiles to be their own pages, but you still want a list of all of them. That graduate evolution of the content as the needs of the business evolve will defintiely be a lot easier to deal with if you don't have to do any kind of migration or rebuilding of that content!
I think Profiles are actually a really good example of where this feature could be used, it's a good example of a content type that might grow organically over time, I think this is the kind of thing you were getting at @pameeela ?
This then brought me to another though, I was thinking about the example of Locations, and how at The University of Edinburgh, our new course/programme content types are supported by a number of taxonomies, we have a location taxonomy for our various campuses, a taxonomy of awards, a subjects taxonomy, taxonomies of our schools and colleges, and more. We actually don't want people directly navigating to any of these term pages, there's nothing of value on them! These vocabularies all exist to facilitate a common set of terms, being able to filter on those in the backend using Views exposed filters, and to facilitate facet filtering using Search API. This all got me thinking that this option would be even more useful on taxonomy vocabularies. So if this hasn't already been considered, I would strongly support adding this option to vocabularies/terms, in addition to nodes.
Where this leaves content blocks, I agree with what @lauriii said:
Looking more at what Experience Builder is doing, I do wonder if the role of content blocks will be significantly reduced. Right now, a lot individual content in a Layout Builder page is a content block, but Experience Builder won't be taking the same approach, and reusable content could be something different.
So in summary, I now have a much clearer view on how this feature could be used, I no longer think it conflicts with the role that content blocks have, and so I'm very much in support of adding this and even expanding it to taxonomy terms (where it may see even more usage than on than it would on nodes).
Comment #33
catchThe current MR almost supports this, the main (only?) thing missing is the route provider logic which is node-specific. For taxonomy terms that might be further complicated because the taxonomy/term/n page is usually overridden by Views, so maybe a bit extra to make it work for taxonomy terms but otherwise all the bits are there. I think we should have a follow-up for applying this to taxonomy terms, the use-case makes sense.
Could also be good to replace media's
standalone_url: falsesetting with this too? But probably also in its own issue because that would involve bc/deprecation for the existing setting.Comment #34
lauriii+1 for expanding this outside of Node in targeted follow-ups.
Comment #35
pameeela commentedThank you @lauriii for a very helpful explanation of the use case and overall context for this! This description of nodes vs blocks is super helpful.
Totally agree re: taxonomy (and media) follow up as well.
Comment #36
dpiWorking on this to some extent, alongside #3484255: [PP-1] Support adding additional routes for view modes other than 'full', as they share a common base.
Comment #37
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #38
catchTagging for release highlights and a change record. Would be great if we could summarize the discussion above in the CR since I think it will help people understand the new feature.
Comment #42
catchWhat about 'Dedicated content URL'? It's not great but we can change that later.
Comment #43
dpiComment #44
larowlanComment #45
gábor hojtsyDid not get into 11.1.
Comment #46
yesct commented@catch I stubbed follow-up issues for what you mentioned in comment #13.
#3503452: Expand support for disabling a route to all entities#3503453: Replace media's standalone_url: false setting with support for disabling a route
Those issues need more specific details, which I don't know, but at least the issues exist. Anyone who knows more, please edit those issues.
[edit]
Opps. #3484255: [PP-1] Support adding additional routes for view modes other than 'full' looks like it is the followup (based on the CR that larowlan made).
Comment #47
yesct commented@larowlan Thanks for making the change record drafts!
New pageDisplay key added to entity view display entities
https://www.drupal.org/node/3484529
NodeViewController::view is deprecated
Comment #48
gábor hojtsyAlso did not get into 11.2.
Comment #49
pameeela commentedIt would be great to get this into 11.4 :)
Comment #50
dpiComment #51
quietone commentedComment #53
longwaveDo we need an additional boolean flag here? What's the difference between
pageDisplay: false,status: false, and theentity_view_displayconfig entity not existing at all? What does it mean whenpageDisplay: trueis set on a non-full entity view mode?Comment #54
acbramley commented+1 to this, it seems like if an entity type had pageDisplay: false on default/full but true on another you wouldn't get the behaviour you're expecting.
Also really hesitant to +1 this whole approach when we're adding this config to every view display but only Node does anything with it.
I understand the rationale behind this feature, but if it's mainly for Drupal CMS, why can't this be done with a combo of rabbit_hole + some other contrib module to handle redirects etc.
If we were to have this in Core, I would be -1 merging it in its current state. The functionality should be committed as entity type agnostic. NodeForm and NodeTypeForm both extend the generic entity forms so why does this functionality have to live in Node? The only part that's not generic is the route subscriber but we could use a trait there to share code between the generic entity route subscriber and node's one.
Comment #55
pameeela commentedI don't see this as mainly for Drupal CMS, I see it as a way to support more display variety in core, and a way to provide a consolidated content model that includes microcontent without needing contrib. The original driver was for the 1.0 content model which is now obsolete, but I still think this is worthwhile.
Re: only nodes, the idea was to do nodes first and then handle other entities in follow ups, as noted in #34 and #3565621: Add support for disabling a route for user entities. If the preference is to do it generically first, I have no objection to that.
Haven't looked at where the MR is up to in a while, but handling page display for non default/full should be in #3484255: [PP-1] Support adding additional routes for view modes other than 'full'?
Comment #56
acbramley commentedI would definitely prefer a generic solution over baking this into Node from the get go.
It seems like maybe this issue should be postponed on #3484255: [PP-1] Support adding additional routes for view modes other than 'full' - especially considering in that issue @dpi has taken some code from here.
Comment #57
acbramley commentedMoving the NodeViewController deprecation to #3589630: Deprecate NodeViewController
It looks like the main open thread is now https://git.drupalcode.org/project/drupal/-/merge_requests/10002#note_40...
Comment #58
acbramley commentedComment #59
longwaveComing back to #53 do we use/respect the
statuskey in entity_view_display entities at the moment? If not, maybe we should use that to mean "the entity view display is enabled", and false here would disable the view display, which would include removing the route?Comment #60
acbramley commentedTo me storing this on the entity_view_display doesn't really make much sense, perhaps we should try and rethink the solution from the beginning because it seems to be the source of the hesitancy to move this forward (certainly for me anyway).
I don't have a good alternative right now but I think we should try and come up with one. Entity view displays being disabled in a post update hook seems like something that would be concerning for site owners. e.g why is my teaser view mode disabled but still works completely fine everywhere it is used?