Metadata
- Source
- FLUID-6223
- Type
- Bug
- Priority
- Major
- Status
- Closed
- Resolution
- Fixed
- Assignee
- Antranig Basman
- Reporter
- Tony Atkins [RtF]
- Created
2017-11-14T05:52:19.891-0500 - Updated
2024-07-22T10:35:18.882-0400 - Versions
- N/A
- Fixed Versions
- N/A
- Component
-
- Framework
Description
Currently, fluid.stringTemplate
only supports a single top-level key within the terms object, as in:
fluid.stringTemplate("%foo.bar", { foo: { bar: "baz" }}); // returns "[object Object].bar"
In part to help with variable handling in i18n message bundles, I would like to improve upon this by:
- Looking for all valid EL path characters to the right of each percent sign.
- Breaking those down into segments by period characters.
- Iterate through using the segments as input to fluid.get, lopping off the trailing segment until a match is found (or not).
This would allow deep referencing of material, such that:
fluid.stringTemplate("%foo.bar", { foo: { bar: "baz" }}); // returns "baz"
cc: @@Antranig Basman
Comments
-
Tony Atkins [RtF] commented
2017-11-14T06:10:29.052-0500 I just realised that we would also need to support incomplete segments, so that we can substitute variables that are not separated from non-key textual content, as in:
fluid.stringTemplate("%variable", { varia: "flexi"}); // returns "flexible"
-
Tony Atkins [RtF] commented
2017-11-14T06:29:29.009-0500 In chats with @@Antranig Basman, we are discussing keeping this function data-centric, i.e. having it search based on material that is known to exist in
terms
. We would add support for deeper references by providing a mechanism to "flatten" a deeper structure in to an object with only top-level elements, keyed by EL Path, as in:my.magic.converter({ deep:{ path: "some text" } }) // becomes { "deep.path": "some text" }
With this structure, "%deep.path" would work as expected. This should minimally impact existing users, as they in essence are already only able to refer to single-segment EL paths within their templates.
-
Tony Atkins [RtF] commented
2017-11-14T07:21:02.064-0500 In looking at the tests for fluid.stringTemplate, I see that we do use arrays and indices, as in:
fluid.stringTemplate("%0", ["a value"]); // returns "a value"
In flattening the terms, we discussed using
fluid.each
on any objects or arrays, such that:my.magic.converter({ array: [1,2,3], object: { deep: "value"}}); /* Returns: { "array.0": 1, "array.1": 2, "array.2": 3, "object.deep": "value" } */
Given that directly referring to
%object
in a string template results in[Object object]
at the moment, we can reasonably expect people to only be directly referring to string, number, and boolean values. -
Tony Atkins [RtF] commented
2018-01-22T05:21:23.416-0500 @@Antranig Basman, now that my previous infusion pull is merged, I am preparing to spike this as we have discussed. Unless you have new thoughts on the subject, I would follow the approach outlined in the comments above, i.e.:
- Before iterating through keys in the values supplied to fluid.stringTemplate, the structure would be "flattened" as described above.
- The rest of the logic would be as before, iterate through the keys in the flattened object in reverse order by length, attempting to replace the longest key possible after the percent sign.
-
Tony Atkins [RtF] commented
2018-01-22T09:25:13.397-0500 -
Gregor Moss commented
2018-01-25T15:18:15.440-0500 I'm greatly interested in progress on this issue, and look forward to being able to make use of it! 🙂
I have a case where I would like to have a reference within an array or object that refers to a value within another array/object that is a sibling of the first. That is to say, some way to indicate that the value I'd like to get is both up a level and then down into a collection in the way you've described.
// E.g. the following object... var exempliGratia = { collectionA: { valueA: "foo" }, collectionB: { valueB: "%..collectionA.valueA" // This ".." notation is something I've just made up, there is likely a more elegant solution } }; // ... would resolve into: { collectionA: { valueA: "foo" }, collectionB: { valueB: "foo" } }
Am I correct in understanding that this functionality is not present in your PR, @@Tony Atkins [RtF]?
Edit: after reviewing fluid.flattenObjectPaths, it seems like this may already be available, and I would only make reference to %collectionA.valueA, without any need to go "up" the chain first.
-
Tony Atkins [RtF] commented
2018-01-26T04:25:30.141-0500 @@Gregor Moss, the underlying concept of an EL Path does not support this type of "go up to the parent, then down" mechanism directly. However, depending on your context, there may be other options. For example, in my related i18n work with Handlebars templates, there is always the option to pass a different part of the current context to the handlebars helper, so that although you can only represent "downward-facing" material from your currently location using EL Paths, you can choose to start a particular evaluation higher in the context. Handlebars provides the ability to pass in material relative to where you are, so in that environment you can indeed tree up, then down, you just have to do part of it with Handlebars.
Anyway, if you can give a concrete example, I might be able to advise you further.
cc: @@Antranig Basman
-
Tony Atkins [RtF] commented
2018-01-26T06:03:08.784-0500 Sorry, I guess I mean context for your example, i.e. what are you using fluid.stringTemplate with that would be expected to make sense of the paths?