Querying extensions: Allow ContentAtRoot() to accept culture#20129
Querying extensions: Allow ContentAtRoot() to accept culture#20129AndyButland merged 8 commits intoumbraco:v13/devfrom
ContentAtRoot() to accept culture#20129Conversation
|
Hi there @bjarnef, thank you for this contribution! 👍 While we wait for one of the Core Collaborators team to have a look at your work, we wanted to let you know about that we have a checklist for some of the things we will consider during review:
Don't worry if you got something wrong. We like to think of a pull request as the start of a conversation, we're happy to provide guidance on improving your contribution. If you realize that you might want to make some changes then you can do that by adding new commits to the branch you created for this work and pushing new commits. They should then automatically show up as updates to this pull request. Thanks, from your friendly Umbraco GitHub bot 🤖 🙂 |
There was a problem hiding this comment.
Pull Request Overview
This PR enhances the ContentAtRoot() method to accept an optional culture parameter, allowing developers to query root content for specific cultures, bringing consistency with the existing GetAtRoot() method in published content query.
Key Changes:
- Added culture parameter support to
ContentAtRoot()method across the API surface - Updated documentation comments to reference the correct method name
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Umbraco.Web.Common/UmbracoHelper.cs | Added overload of ContentAtRoot() with optional culture parameter |
| src/Umbraco.Infrastructure/IPublishedContentQuery.cs | Added interface method signature for culture-aware ContentAtRoot() |
| src/Umbraco.Infrastructure/PublishedContentQuery.cs | Implemented culture-aware ContentAtRoot() and updated helper method |
| src/Umbraco.Web.Common/Extensions/FriendlyPublishedContentExtensions.cs | Updated documentation comments to reference correct method name |
| src/Umbraco.Core/Extensions/PublishedContentExtensions.cs | Updated documentation comments to reference correct method name |
|
@AndyButland any chance this can be included in next minor of v13? |
|
Hi @bjarnef , Thanks a lot for your PR to fix #20117, where the ContentAtRoot() and GetAtRoot() return null if the content varies by culture. One of the Core Collaborators team will review this as soon as possible - I've noticed you've tagged Andy on this, so we'll likely wait to see what comes out of that conversation :) Best regards Emma |
|
Its breaking to refactor the method (even with a default parameter), we should probably just make an overload that takes a culture instead 😁 |
|
@Zeegaan I wondered about that, but it didn't seem to break the existing usage it the template of the "old" method. I am not sure in which case it will break though as the parameter is optional and it didn't have any before, but otherwise we can add an overload as I originally did. |
|
@Zeegaan perhaps it also make sense to include this in v16 as
|
|
This pull request has been mentioned on Umbraco community forum. There might be relevant details there: https://forum.umbraco.com/t/replacement-for-ipublishedcache-getatroot/5874/1 |
AndyButland
left a comment
There was a problem hiding this comment.
Thanks @bjarnef - I had a quick look over. To resolve the breaking change that's being flagged in conversation and in the automated checks, I think you'll need to have the interface like this:
IEnumerable<IPublishedContent> ContentAtRoot();
IEnumerable<IPublishedContent> ContentAtRoot(string culture) => throw new NotSupportedException();
That way the old method is still there and the new method has a default implementation so it won't be binary breaking in the rare chance that someone has a custom implementation of IPublishedContentQuery. By making the culture parameter not nullable, we also avoid an ambiguous method exception.
Then in PublishedContentQuery you could implement like this:
public IEnumerable<IPublishedContent> ContentAtRoot() => ItemsAtRoot(_publishedSnapshot.Content);
public IEnumerable<IPublishedContent> ContentAtRoot(string culture) => ItemsAtRoot(_publishedSnapshot.Content, culture);
You need similar on UmbracoHelper as that's also a public class so changing a method parameter is a binary breaking change.
|
@AndyButland I have modified the code with overload Seems to align with |
|
I would have thought that would have led to an ambiguous method runtime issue, as a call to |
|
@AndyButland I didn't seen any errors.
Inspecting I guess the use of the second overload without parameter isn't really used directly. In notification handler:
|
|
A bit more info and linking to this article: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/named-and-optional-arguments
|
|
Nice bit of investigative work you and your AI buddy have done there. Sounds convincing. So if you can't find any issues with what you have we can go with that, but can then modify the interface as follows (as long-term, there's no point keeping the overload taking no parameters), and we can have a default implementation that delegates to the orginal. |
ContentAtRoot() to accept cultureContentAtRoot() to accept culture
|
@AndyButland shouldn't it be |
|
Sorry, missed updating with a comment as well as pushing the update.
Yes, I see what you mean. Again the confusion comes from the ambiguous methods - even if the compiler does understand it, it's a bit odd for the human reading the code I agree. In an ideal world we would just remove the one with no parameters, but given we can't within 13 for backward compatibility reasons, on balance think it's best we go for the "old school" overloads that we had earlier. That'll be quite clear from intellisense. The only thing is you can't pass "null" as the culture parameter, but I think that's OK when you have a clear overload to use that just doesn't take this parameter. I've pushed that to your branch. Please let me know if you are happy with that and it works as you expect in your tests, and then we can include.
Yes, that'll work actually and restore the ability to pass null. I've updated to that now too. |
Yeah, I am note sure what would happen as The changes looks fine to me :) I had a brief look at the It seems |
|
Cherry-picked via 2c3a2e2 to 16. |
|
@AndyButland great, no more or searching code base I found these. I guess it is broken anyway as |
|
This pull request has been mentioned on Umbraco community forum. There might be relevant details there: https://forum.umbraco.com/t/replacement-for-ipublishedcache-getatroot/5874/2 |
|
@AndyButland it seems this has been included in v16, but not v17 yet: However in v17 it no longer use as in v16: and |
|
Yes, both IPublishedContentQuery & UmbracoHelper ContentAtRoot both seem to be missing the culture parameter. |
|
Yes, I think I may have run into this problem when merging the improvement up from 13, via 16 to 17, got stuck (and then presumably moved onto other things). So although we added it late as a feature for 13, as the existing cache architecture supported it quite easily, it wasn't feasible to bring it up for 17. Seems to me it needs a fair bit of rework to support, and so at the moment, looks like it's necessary to get all root items and filter for the culture afterwards. |











Prerequisites
If there's an existing issue for this PR then this fixes #20117
Description
This PR allow
ContentAtRoot()to query specific culture just likeGetAtRoot()in published content query.