Closed Photosynthesis closed 4 years ago
One example of a more intuitive and meaningful structure (from @matslats):
{
"title": "Accounting software",
"type": "enumerated",
"options": {
"blockchain": {
"label": "Blockchain"
},
"cyclos": {
"label": "Cyclos"
},
"cmsPlugin": {
"label": "CMS Plugin"
},
"webService": {
"label": "Accounting web service"
}
}
}
Or:
{
"title": "Accounting software",
"type": "enumerated",
"options": [
{
"value": "blockchain",
"label": "Blockchain"
},
{
"value": "cyclos",
"label": "Cyclos"
},
{
"value": "cmsPlugin",
"label": "CMS Plugin"
}
]
}
Bear in mind that a full solution would need to support other languages.
Not only this, your UI might need to have a short label in some cases, and longer descriptions in others. The text may need to be altered to fit the space available - consider the space on a mobile device, vs the space on a desktop.
That makes me think that JSON-Schema isn't sufficient by itself, because would you really want to have human-readable labels in an arbitrary number of languages embedded in the schema? Would it be flexible enough to allow user-friendly UIs?
If you accept these points, I think it suggests that language definitions should be in a separate layer, mapping schema identifiers to words and phrases to be used in various contexts, even if does make life a bit more difficult in some ways.
@Photosynthesis wrote:
But, this is hacky, and doesn't do a good job of making clear the relationship between the labels and the values. This approach also would probably not be handled well by JSON-Editor.
No it doesn't work the way you intend it to in JSON Editor. You end up with two drop-down selection lists: one for the 3 letter code and one for the country name, both of which can be set independently from each other (e.g., you can select "Canada" and "MEX").
Is there a way to do this properly in JSON-Schema that I've missed? Are there examples of selects in JSON-Editor that do this? What solutions should we look at to handle this well?
I think what you're suggesting is beyond the scope of JSON Schema. I agree with @wu-lee that there should be a separate layer for translation that maps the "machine-readable" data in the schema to something "human-readable" (i.e., translated: usa
-> United States of America for a form in English, or États-Unis for a form in French). This translation should happen at the presentation layer/UI, and the mapping from machine to human can be defined in a separate file (maybe in a new translations
directory in the library?) from the field definition.
The presentation layer would need to take the translations and incorporate them into a select
element in the UI:
<select name="country">
<option value="can">Canada</option>
<option value="mex">Mexico</option>
<option value="usa">United States of America</option>
</select>
AFAIK, this is also beyond the scope of the current JSON Schema tools. Yet another reason we may need to "roll our own" in the future. In the short term, for v1, we should stick with the enumerated lists with a view toward adding a translation layer later on as a UI enhancement. IOW, right now the option the user sees will be mex
but with a view toward offering Mexico, Mexique, México, 墨西哥 or any other language option someday.
Thanks for your thoughts on this @wu-lee and @geoffturk.
I agree that multi-language support is a large and important topic. It applies not just to this but also to (for example) titles of fields and field descriptions.
I think we need to handle these two issues separately:
I agree that item 2 needs a translation layer, which is important but can come later, and probably shouldn't exist inside the schema file.
We have a somewhat critical need for item 1 now, for schemas that are currently being built. I think it probably should be included in the schema file (for the same reason that the field title and description are included).
One of the first schemas I will be creating is for ecovillages and intentional communities. The FIC schema includes dozens of enum/multiple choice fields with rather detailed options. There is no practical way for the values of these fields to be both human-friendly and machine-friendly. Attempting this would be either a data nightmare, a UX nightmare, or both!
Other early adopter schemas (at least community currencies, and probably SEA as well) also need this.
So, I don't think we can put off including some mechanism for enum labels in v1.
To me, the question is: how do we include this in a relatively graceful way that makes sense and doesn't break JSON-Schema?
I'm not too concerned about JSON Editor in this case, because I think we will probably need to rewrite how it handles this type of field anyway (to make room for quasi-enumerated fields that allow additional, non-specified options, autofills for frequently used values for wikidata-referenced node types, etc.)
- We need a way include a human-readable label for an enumerated value
Just a train of thought here.
Javascript "enumerations" are just strings, and so if you choose, can be human-readable labels, so long as they're unique.
At the other extreme, you could just use numbers instead of enumerations.
Enumerations are just mnemonics for coders. Coders don't typically want unwieldy enumerations; on the other hand they need to be memorable. It's a trade off.
However, it sounds like the people inventing these enumerations are not going to be coders. Therefore, maybe the same rules don't apply?
Following this line of thinking, I wonder: as the non-coder human wants a phrase, and a machine is happy with numbers, maybe the schema should avoid enumerations entirely and use numbers. If we can't ask the users to invent mnemonics, and computers can't invent them sensibly, then let the users invent the labels, and have the computer map these to numbers, or perhaps some auto-generated identifier - let's call them identifiers. The phrase can be part of the schema description. An added bonus is that spelling mistakes, punctuation etc. aren't baked into the schema.
So Bob the Bryologist isn't a coder and invents an an enumeration:
These are represented in the schema by identifiers. New phrases are allocated identifying numbers in order they are encountered, i.e. arbitrarily. But the schema includes a description for each of these identifiers which based on the names created by Bob. This is more or less equivalent to using the literal phrases as enumerations, from the user's point of view. Yes, coders have to put up with identifiers because they aren't maintaining the lists - but they can work around that.
Later, descriptions in other languages can be added, as in point 2 above.
Adam wrote:
So, I don't think we can put off including some mechanism for enum labels in v1.
To me, the question is: how do we include this in a relatively graceful way that makes sense and doesn't break JSON-Schema?
We can do it with this: https://jsonforms.io/
I've tested it and it works (shows a human readable label like Not for Profit in the form drop down menu but sets nfp
in the profile data object).
This is how it will look in JSON Schema:
{
"type": "object",
"properties": {
"orgType": {
"title": "Type of Organization",
"description": "The legal form of your organization in the country where it is based",
"type": "string",
"oneOf": [
{"const": "coop", "title": "Cooperative"},
{"const": "nfp", "title": "Not For Profit"}
]
}
}
}
The JSON-Schema spec for enumerated fields allows defining a single array of allowed values. Example:
However, in order to build a user friendly input, we need to be able to specify in the schema both a clean, machine-friendly value for the enum option, and also a human-friendly label for the option. For example, the machine-friendly values of a country input might be three-character ISO country codes. The human-friendly labels would be the country name.
To some extent we can do this in JSON-Schema by using an array field type, with each item being an object with "label" and "value" properties, like:
But, this is hacky, and doesn't do a good job of making clear the relationship between the labels and the values. This approach also would probably not be handled well by JSON-Editor.
Is there a way to do this properly in JSON-Schema that I've missed? Are there examples of selects in JSON-Editor that do this? What solutions should we look at to handle this well?