forked from extern/homer
Merge pull request #175 from luixal/message-remote-fields-mapping
Adds mapping remote field to Homer expected ones when loading message from URL
This commit is contained in:
commit
cc7ff88552
@ -66,6 +66,17 @@ colors:
|
||||
# Optional message
|
||||
message:
|
||||
# url: "https://<my-api-endpoint>" # Can fetch information from an endpoint to override value below.
|
||||
# mapping: # allows to map fields from the remote format to the one expected by Homer
|
||||
# title: 'id' # use value from field 'id' as title
|
||||
# content: 'value' # value from field 'value' as content
|
||||
# refreshInterval: 10000 # Optional: time interval to refresh message
|
||||
#
|
||||
# Real example using chucknorris.io for showing Chuck Norris facts as messages:
|
||||
# url: https://api.chucknorris.io/jokes/random
|
||||
# mapping:
|
||||
# title: 'id'
|
||||
# content: 'value'
|
||||
# refreshInterval: 10000
|
||||
style: "is-warning"
|
||||
title: "Optional message!"
|
||||
icon: "fa fa-exclamation-triangle"
|
||||
@ -118,7 +129,7 @@ services:
|
||||
# background: red # optional color for card to set color directly without custom stylesheet
|
||||
```
|
||||
|
||||
If you choose to fetch message information from an endpoint, the output format should be:
|
||||
If you choose to fetch message information from an endpoint, the output format should be as follows (or you can [custom map fields as shown in tips-and-tricks](./tips-and-tricks.md#mapping-fields)):
|
||||
|
||||
```json
|
||||
{
|
||||
|
@ -113,6 +113,64 @@ docker create \
|
||||
|
||||
|
||||
## Get the news headlines in Homer
|
||||
|
||||
### Mapping Fields
|
||||
Most times, the url you're getting headlines from follows a different schema than the one expected by Homer.
|
||||
|
||||
For example, if you would like to show jokes from ChuckNorris.io, you'll find that the url https://api.chucknorris.io/jokes/random is giving you info like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"categories": [],
|
||||
"created_at": "2020-01-05 13:42:22.089095",
|
||||
"icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
|
||||
"id": "MR2-BnMBR667xSpQBIleUg",
|
||||
"updated_at": "2020-01-05 13:42:22.089095",
|
||||
"url": "https://api.chucknorris.io/jokes/MR2-BnMBR667xSpQBIleUg",
|
||||
"value": "Chuck Norris can quitely sneak up on himself"
|
||||
}
|
||||
```
|
||||
|
||||
but... you need that info to be transformed to something like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "MR2-BnMBR667xSpQBIleUg",
|
||||
"content": "Chuck Norris can quitely sneak up on himself"
|
||||
}
|
||||
```
|
||||
|
||||
Now, you can do that using the `mapping` field in your `message` configuration. This example would be something like this:
|
||||
|
||||
```yml
|
||||
message:
|
||||
url: https://api.chucknorris.io/jokes/random
|
||||
mapping:
|
||||
title: 'id'
|
||||
content: 'value'
|
||||
```
|
||||
|
||||
As you would see, using the ID as a title doesn't seem nice, that's why when a field is empty it would keep the default values, like this:
|
||||
|
||||
```yml
|
||||
message:
|
||||
url: https://api.chucknorris.io/jokes/random
|
||||
mapping:
|
||||
content: 'value'
|
||||
title: "Chuck Norris Facts!"
|
||||
```
|
||||
|
||||
and even an error message in case the `url` didn't respond or threw an error:
|
||||
|
||||
```yml
|
||||
message:
|
||||
url: https://api.chucknorris.io/jokes/random
|
||||
mapping:
|
||||
content: 'value'
|
||||
title: "Chuck Norris Facts!"
|
||||
content: "Message could not be loaded"
|
||||
```
|
||||
|
||||
#### `by @JamiePhonic`
|
||||
|
||||
Homer allows you to set a "message" that will appear at the top of the page, however, you can also supply a `url:`.
|
||||
|
@ -29,19 +29,26 @@ export default {
|
||||
created: async function () {
|
||||
// Look for a new message if an endpoint is provided.
|
||||
this.message = Object.assign({}, this.item);
|
||||
if (this.item && this.item.url) {
|
||||
const fetchedMessage = await this.getMessage(this.item.url);
|
||||
// keep the original config value if no value is provided by the endpoint
|
||||
for (const prop of ["title", "style", "content"]) {
|
||||
if (prop in fetchedMessage && fetchedMessage[prop] !== null) {
|
||||
this.message[prop] = fetchedMessage[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
await this.getMessage();
|
||||
this.show = this.message.title || this.message.content;
|
||||
},
|
||||
|
||||
methods: {
|
||||
getMessage: function (url) {
|
||||
getMessage: async function() {
|
||||
if (this.item && this.item.url) {
|
||||
let fetchedMessage = await this.downloadMessage(this.item.url);
|
||||
if (this.item.mapping) fetchedMessage = this.mapRemoteMessage(fetchedMessage);
|
||||
// keep the original config value if no value is provided by the endpoint
|
||||
for (const prop of ["title", "style", "content"]) {
|
||||
if (prop in fetchedMessage && fetchedMessage[prop] !== null) {
|
||||
this.message[prop] = fetchedMessage[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.item.refreshInterval) setTimeout(this.getMessage, this.item.refreshInterval);
|
||||
},
|
||||
|
||||
downloadMessage: function (url) {
|
||||
return fetch(url).then(function (response) {
|
||||
if (response.status != 200) {
|
||||
return;
|
||||
@ -49,6 +56,13 @@ export default {
|
||||
return response.json();
|
||||
});
|
||||
},
|
||||
|
||||
mapRemoteMessage: function (message) {
|
||||
let mapped = {};
|
||||
// map property from message into mapped according to mapping config (only if field has a value):
|
||||
for (const prop in this.item.mapping) if (message[this.item.mapping[prop]]) mapped[prop] = message[this.item.mapping[prop]];
|
||||
return mapped;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user