A combination of supportedLocales and fallbackLocale doesn't prevent UI5 from requesting unexisting i18n-localizations - sapui5

To configure the i18n functionality in UI5, I'm using the following snippet in the sap.ui5 of manifest.json:
"models": {
"i18n": {
"preload": true,
"settings": {
"bundleName": "webapp.i18n.i18n",
"bundleUrl": "i18n/i18n.properties",
"fallbackLocale": "en",
"supportedLocales": [
"en"
]
},
"type": "sap.ui.model.resource.ResourceModel"
}
},
Thanks to supportedLocales and fallbackLocale I don't expect that UI5 will request unexisting localizations, but in fact I still observe unwanted 404-requests for i18n_en_US.properties:
GET http://localhost:3000/i18n/i18n_en_US.properties 404 (Not Found)
I assumed that the whole idea behind of supportedLocales and fallbackLocale is to reduce amount of requests of localizations, which don't exist and are not specified in supportedLocales.
My questions:
Why UI5 anyway tries to request i18n_en_US.properties although en_US doesn't appear in a list of supportedLocales?
Is it possible to get rid of extra requests for unsupported locales?

I figured out the reason for the unwanted 404-requests.
Initially, I've defined fallbackLocale and supportedLocales for the sap.ui5/models/i18n section, but there is also an i18n section in sap.app, which also requires fallbackLocale and supportedLocales configuration.
The final solution is to add the following code-snippet into sap.app section of manifest.json:
"i18n": {
"bundleName": "webapp.i18n.i18n",
"fallbackLocale": "en",
"supportedLocales": [
"en"
]
},

Related

Content-Language metadata field in GCS object not allowing ISO-639-2 from API

While trying to update the Content-Language metadata field of an object to ISO-639-2 field from the UI works fine, when trying to do the same from http API, it fails with an invalid argument error. The official documentation page states that ISO-639-1 codes are supported (although the link goes to 639-2).
Any ideas on how to update the Content-Language via http/json for objects in ISO-639-2 ? Or it's possible the UI treats it differently?
Response from GetObject for an object with ISO-639-2 updated via ui
{
"kind": "storage#object",
"id": "XXXXXXXXX/textfile.txt/XXXXXXX",
"selfLink": ...,
"mediaLink": ...,
"name": "textfile.txt",
"bucket": "XXXXXX",
"generation": "XXXXXX",
"metageneration": "2",
"contentType": "text/plain; charset=utf-8",
"storageClass": "STANDARD",
"size": "29",
"md5Hash": "f510qpm7Jh30uKbBcN4e0A==",
**"contentLanguage": "ach",**
"crc32c": "4fnpOw==",
"etag": "COet043XpPcCEAI=",
"temporaryHold": false,
"eventBasedHold": false,
"timeCreated": "2022-04-21T07:56:14.769Z",
"updated": "2022-04-21T07:57:14.321Z",
"timeStorageClassUpdated": "2022-04-21T07:56:14.769Z",
"metadata": {
"gcsfuse_mtime": "2022-04-21T07:56:13.375009661Z"
}
}
Error when trying to set the same value as received in the above call via json
{
"error": {
"code": 400,
"message": "Invalid argument.",
"errors": [
{
"message": "Invalid argument.",
"domain": "global",
"reason": "invalid"
}
]
}
}
I reproduced your case, and it seems like you are right. Content-Language only allows ISO 639-1 language codes for the supported values of this metadata.
When Content-Language was set to “ach” in JSON POST API call it gave me errors “curl: (3) Failed to convert ach” to ACE; string contains a disallowed character” but when set to “en”/ “de”/ “aa” it works fine and gives a HTTP 200 response. I think the logic which works here, checks for ISO 639-1 format.
I have gone through the documentation, and it says clearly “Refer to ISO 639-1 language codes for the supported values of this metadata.” Maybe it routes to ISO 639-2 page, because it contains both ISO 639-1 and ISO 639-2 codes, out of which it mentions it only supports ISO 639-1 language codes. You can check out this documentation as well.
Raise a feature request here so that the Content-Language supports ISO 639-2 language code in API calls.

Docsearch on subpath '/docs' not scraping side navigation

A Docusaurus documentation website: https://slovakia-atmo-plan.marvintest.vito.be/docs/ is rendered in Docs only mode.
The Algolia Docsearch scraper is not scraping root level pages, instead it logs Ignored: from start url. This issue only seems to arise when the Docusaurus build is nested under {baseUrl}/docs.
Why is this being ignored? This is my docsearch config:
{
"index_name": "atmoplan-documentation",
"start_urls": ["https://slovakia-atmo-plan.marvintest.vito.be/docs"],
"sitemap_urls": ["https://slovakia-atmo-plan.marvintest.vito.be/docs/sitemap.xml"],
"sitemap_alternate_links": true,
"stop_urls": ["/tests"],
"selectors": {
"lvl0": {
"selector": "(//ul[contains(#class,'menu__list')]//a[contains(#class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(#class, 'navbar')]//a[contains(#class, 'navbar__link--active')]/text())[last()]",
"type": "xpath",
"global": true,
"default_value": "Documentation"
},
"lvl1": "header h1",
"lvl2": "article h2",
"lvl3": "article h3",
"lvl4": "article h4",
"lvl5": "article h5, article td:first-child",
"lvl6": "article h6",
"text": "article p, article li, article td:last-child"
},
"strip_chars": " .,;:#",
"custom_settings": {
"separatorsToIndex": "_",
"attributesForFaceting": ["language", "version", "type", "docusaurus_tag"],
"attributesToRetrieve": ["hierarchy", "content", "anchor", "url", "url_without_anchor", "type"]
},
"conversation_id": ["833762294"],
"nb_hits": 46250
}
Inside your docusaurus.config.js you should set the url parameter with the actual website where you will be hosting your docs. Something like:
module.exports = {
url: 'https://slovakia-atmo-plan.marvintest.vito.be/docs',
[…]
}
This will be used by your docusaurus to generate the sitemap.xml, used by algolia to locate your pages.
REFERENCE: https://docusaurus.io/docs/docusaurus.config.js/#url
DISCLAIMER
I noted something strange inside your sitemap.xml. For example the first link was https://www.vito.be/docs/markdown-page, but defined URL for Algolia is https://slovakia-atmo-plan.marvintest.vito.be/docs.

Firebase redirect example from the docs throws error: Unexpected token. Why?

I wanted to add redirects to my firebase project, so I pasted the example from the offical docs as a test:
"hosting": {
// ...
"redirects": [ {
"regex": "/blog/(?P<post>.+)", // if you're familiar with PCRE, be aware that RE2 requires named capture groups to begin with ?P
"destination": "https://blog.myapp.com/:post", // includes the entire URL segment identified and captured by the `regex` value
"type": 301
}, {
"regex": "/users/(\d+)/profile", // uses the \d directive to only match numerical path segments
"destination": "/users/:1/newProfile", // the first capture group to be seen in the `regex` value is named 1, and so on
"type": 301
} ]
}
When I tried to deploy I got the error:
Error: There was an error loading firebase.json:
Unexpected token 'd' at 28:26
"regex": "/users/(\d+)/profile",
^
How come the official example gets a syntax error? What is the problem?
You need to escape the backslash \\d.

"The agent returned an empty TTS" when action is not opened separately to asking an intent

When I invoke the skill with 'okay Google, ask {skillname} to {utterance}' I get the response 'The agent returned an empty tts" and the conversation closes. It doesn't even seem to hit my backend - I've tried hosting the backend code on both a local server and on AWS and the same issue happens in both cases. There's no log of the request being made either on Stackdriver on Google or on CloudWatch on AWS. The only response I get is the following in the debug tab:
{
"response": "The agent returned an empty TTS.",
"expectUserResponse": false,
"conversationToken": "EosDS2o4d0...",
"audioResponse": "",
"ssmlMarkList": [],
"debugInfo": {
"sharedDebugInfoList": [
{
"name": "Response Validation",
"debugInfo": "The agent returned an empty TTS.",
"subDebugEntryList": []
}
],
"conversationBuilderExecutionEventsList": []
},
"visualResponse": {
"visualElementsList": [
{
"displayText": {
"content": "The agent returned an empty TTS."
}
}
],
"suggestionsList": [],
"agentLogoUrl": ""
},
"clientError": 0,
"is3pResponse": true,
"clientOperationList": [],
"projectName": "",
"renderedHtml": ""
}
Nothing in any of the other tabs. When I try invoking the phrases in the same way on my phone, I just see a loading symbol and again nothing in the logs to say it's even hitting the backend.
Weirdly, this doesn't happen when I say 'okay Google, talk to {skillname} {utterance}' - this works absolutely fine.
All the intents work perfectly well when I've opened my action first, and then invoke them. I've built this using Jovo and published on Alexa also and the problem is only happening on Google.

WireMock: Temp disable stub response

I use WireMock to stub responses from remote server.
In folder wiremock/mappings I have many files that set rules for stub.
Here example:
{
"request": {
"method": "GET",
"url": "/merchant"
},
"response": {
"headers": {
"Content-Type": "application/json"
},
"status": 200,
"fixedDelayMilliseconds": 3000,
"bodyFileName": "stub_response.json"
}
}
As you can see, when I get request /merchant then return stubbed response from file stub_response.json.
Nice. It's work fine.
But suppose I need temporary to disable this response. Is it possible to turn off stub response and return real response from remote server?
I need flag like this : "disable" : true
Is it possible in WireMock?
You can disable a rule by using the WireMock admin interface. If you invoke a DELETE command against http://.../__admin/mappings/<guid>, then the mapping will be deleted.
You can get a list of all the guids by performing a GET command against http://.../__admin/
If you want to replace a mapping with a real response instead of a stubbed response, you can add a second mapping that has a lower priority than the stubbed response and that proxies through to the real address. Normally, your stubbed response ill be used, but when you then delete the stubbed response, Wiremock will proxy through to the real address as it will then become the highest priority mapping.
To add a proxy, add the following into the response mapping
"proxyBaseUrl" : "http://otherhost.com",
To set the priority of mappings, add the following into your mapping JSON.
"priority": 1,
There presently isn't a disable attribute to a rule. You can remove a wiremock rule and re-add it later, which would functionally be the same.
If you running Wiremock as a Stand-alone process, you can set it into recording mode, effectively this will proxy all requests to a target URL.
Open http://localhost:8080/__admin/recorder (assuming you started WireMock on the default port of 8080), on that screen you have to enter the target URL and click the "Record" button. Until you stop recording it will make this Wiremock acting as a proxy.
If the recording is not something you actually need, you can dismiss recorded stub mappings. Although this is slightly misusing the Recorder feature it is a fast and easy way to temporarily turn your Wiremock into a proxy, instead of responding with stubs.
Wiremock can select which fixture to use depending on in which state of a scenario it runs. In different states, even for same request, it can have different mappings thus behave in different ways (in one of the states can respond from a fixture, and in another state it can be forwarded to the real API).
Say if there is a Proxy scenario, which is currently in the default Started state, then all the queries will be served by stubs that are not specific to any scenario state.
But if the Proxy scenario is in Active state, and we have a mapping that is specific for that scenario state (requiredScenarioState property), and it has a higher priority than default, then this mapping will be executed for any URI to this Wiremock instance:
{
"scenarioName": "Proxy",
"requiredScenarioState": "Activated",
"priority": 2,
"request": {
"urlPattern": ".*"
},
"response": {
"proxyBaseUrl": "https://swapi.dev/api"
}
}
The value for response.proxyBaseUrl, will make all the requests to be forwarded to provided host, when this mapping is matched.
Now we need to be able to toggle Proxy scenario to Activated state and back,
so we define two more mappings for POST /proxy endpoint on this Wiremock. They will have even higher priority - 1, so they can override even the mapping for "urlPattern": ".*".
Drop a JSON file containing all three mappings to your wiremock/mappings:
{
"mappings": [
{
"scenarioName": "Proxy",
"requiredScenarioState": "Activated",
"priority": 2,
"request": {
"urlPattern": ".*"
},
"response": {
"proxyBaseUrl": "https://swapi.dev/api"
}
},
{
"priority": 1,
"scenarioName": "Proxy",
"requiredScenarioState": "Activated",
"newScenarioState": "Started",
"request": { "method": "POST", "url": "/proxy"},
"response": { "status": 201, "body": "Proxy De-activated (Stubs will be used)" }
},
{
"priority": 1,
"scenarioName": "Proxy",
"requiredScenarioState": "Started",
"newScenarioState": "Activated",
"request": { "method": "POST", "url": "/proxy" },
"response": { "status": 201, "body": "Proxy Activated (Will forward all requests)" }
}
]
}
Now you can switch the Proxy scenario to Activated state,
and after switch it back to Started state with:
curl http://localhost:8080/proxy -XPOST
Good thing about this approach that this mapping file can be copied from project to project with minimal changes.