The sling:message dictionaries are merged globally, respecting the search path (so a string in /apps overrides one in /libs, but multiple strings with the same key in /apps have an undefined winner). It does not know anything about components or resource types.
But there is the <cq:setContentBundle> JSP tag which will look for those strings as properties in the local component instance node first before it asks the resource bundle from the sling request object aka the i18n dictionaries.
Thanks for the suggestion, that sounds exactly what I need to use, but I am not seeing the expected result.
Do you see anything wrong with the node structure listed below?
mycomponent.jsp - uses <cq:setContentBundle /> in code along with <fmt:message key="mykey"/> to get value
I place "mycomponent" from the "extendedproject" onto a page. That component has a supertype referencing the component in the baseproject, where the jsp logic lives.
I expect to see the "extended message" appear, since cq:setContentBundle should tell the page to use the i18n message assigned to this component itself from "extendedproject".
However, what I see is whichever sling message was saved last is the one that displayed. I think what you listed above for " (so a string in /apps overrides one in /libs, but multiple strings with the same key in /apps have an undefined winner)" is still being applied, and the cq:setContentBundle doesn't seem to find the message tied to the component itself in the context of the app it lives within.
This i18n folder you have in the component location (say /apps/foo/components/mycomponent) is wrong. It would be picked up as normal dictionary.
What I meant with the cq:setContentBundle tag was those properties in each component instance. For example, /content/mysite/de/page/jcr:content/par/comp. The structure would not be a dictionary, so no jcr:language, no sling:Message etc. but plain properties that have the same name as the keys = original strings.
- Word = "Wort"
- House = "Haus"
- Tree = "Baum"
This way you can easily make this settable in the edit dialog of the component, using "Word", "House" etc. as field names. There is a little restriction for the keys since they must be valid JCR property names (e.g. no colons), but that should be rare.
You might have picked up the /libs/foundation/components/search/i18n example - this is only there for backwards compatibility for that specific component.
It works correctly once I define those properties on the instance of the component itself. However, I that approach won't will work for us, the values we want to set for the components shouldn't be edited in a dialog, and we don't want them to be configured per an instance, but instead per the component in a given app folder.
We will have components that are used by several sites (the sites are all in english). We want to be able to define a component in a location like /apps/baseapp/components/mycomponent, and be able to define the default text header for that component. Let's say that heading is "Recent Stories".
In site A, we have a component located at /apps/sitea/components/mycomponent, and it's supertype is /apps/baseapp/components/mycomponent, and we rely on the supertype jsp to render the component.
We want to be able to have the heading of the component, when referenced anywhere in site A, be overridden to say "Recent Blogs" instead. If we didn't override the heading, it would default to the supertype's heading of "Recent Stories".
So the only thing we want to change about our component in siteA is the heading, everything else rendered is just inherited from it's supertype.
I take it what I describe above we won't get OOTB with Sling and AEM, is that correct?
We can look at implementing our own custom solution to solve this if we need to.