aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBastien Wirtz <bastien.wirtz@gmail.com>2021-03-04 18:40:07 -0800
committerGitHub <noreply@github.com>2021-03-04 18:40:07 -0800
commitcc7ff885527283d97f32347210b0370e8477c4ff (patch)
tree6c2eda44ed25cf2cd91cced7ab159ecd5e6735f7
parent7bcfce6bdad32ec392279867af7f3f3c67a972b3 (diff)
parent9542de6eb25bfa20b376920b607db864c9e20a7a (diff)
downloadhomer-21.03.1.tar.gz
homer-21.03.1.tar.zst
homer-21.03.1.zip
Merge pull request #175 from luixal/message-remote-fields-mappingv21.03.1
Adds mapping remote field to Homer expected ones when loading message from URL
-rw-r--r--docs/configuration.md13
-rw-r--r--docs/tips-and-tricks.md58
-rw-r--r--src/components/Message.vue34
3 files changed, 94 insertions, 11 deletions
diff --git a/docs/configuration.md b/docs/configuration.md
index a43d7f1..5785e56 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -66,6 +66,17 @@ colors:
66# Optional message 66# Optional message
67message: 67message:
68 # url: "https://<my-api-endpoint>" # Can fetch information from an endpoint to override value below. 68 # url: "https://<my-api-endpoint>" # Can fetch information from an endpoint to override value below.
69 # mapping: # allows to map fields from the remote format to the one expected by Homer
70 # title: 'id' # use value from field 'id' as title
71 # content: 'value' # value from field 'value' as content
72 # refreshInterval: 10000 # Optional: time interval to refresh message
73 #
74 # Real example using chucknorris.io for showing Chuck Norris facts as messages:
75 # url: https://api.chucknorris.io/jokes/random
76 # mapping:
77 # title: 'id'
78 # content: 'value'
79 # refreshInterval: 10000
69 style: "is-warning" 80 style: "is-warning"
70 title: "Optional message!" 81 title: "Optional message!"
71 icon: "fa fa-exclamation-triangle" 82 icon: "fa fa-exclamation-triangle"
@@ -118,7 +129,7 @@ services:
118 # background: red # optional color for card to set color directly without custom stylesheet 129 # background: red # optional color for card to set color directly without custom stylesheet
119``` 130```
120 131
121If you choose to fetch message information from an endpoint, the output format should be: 132If 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)):
122 133
123```json 134```json
124{ 135{
diff --git a/docs/tips-and-tricks.md b/docs/tips-and-tricks.md
index 2719fc5..94167fb 100644
--- a/docs/tips-and-tricks.md
+++ b/docs/tips-and-tricks.md
@@ -113,6 +113,64 @@ docker create \
113 113
114 114
115## Get the news headlines in Homer 115## Get the news headlines in Homer
116
117### Mapping Fields
118Most times, the url you're getting headlines from follows a different schema than the one expected by Homer.
119
120For 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:
121
122```json
123{
124 "categories": [],
125 "created_at": "2020-01-05 13:42:22.089095",
126 "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
127 "id": "MR2-BnMBR667xSpQBIleUg",
128 "updated_at": "2020-01-05 13:42:22.089095",
129 "url": "https://api.chucknorris.io/jokes/MR2-BnMBR667xSpQBIleUg",
130 "value": "Chuck Norris can quitely sneak up on himself"
131}
132```
133
134but... you need that info to be transformed to something like this:
135
136```json
137{
138 "title": "MR2-BnMBR667xSpQBIleUg",
139 "content": "Chuck Norris can quitely sneak up on himself"
140}
141```
142
143Now, you can do that using the `mapping` field in your `message` configuration. This example would be something like this:
144
145```yml
146message:
147 url: https://api.chucknorris.io/jokes/random
148 mapping:
149 title: 'id'
150 content: 'value'
151```
152
153As 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:
154
155```yml
156message:
157 url: https://api.chucknorris.io/jokes/random
158 mapping:
159 content: 'value'
160 title: "Chuck Norris Facts!"
161```
162
163and even an error message in case the `url` didn't respond or threw an error:
164
165```yml
166message:
167 url: https://api.chucknorris.io/jokes/random
168 mapping:
169 content: 'value'
170 title: "Chuck Norris Facts!"
171 content: "Message could not be loaded"
172```
173
116#### `by @JamiePhonic` 174#### `by @JamiePhonic`
117 175
118Homer allows you to set a "message" that will appear at the top of the page, however, you can also supply a `url:`. 176Homer allows you to set a "message" that will appear at the top of the page, however, you can also supply a `url:`.
diff --git a/src/components/Message.vue b/src/components/Message.vue
index 5a1e0ea..2f71f3f 100644
--- a/src/components/Message.vue
+++ b/src/components/Message.vue
@@ -29,19 +29,26 @@ export default {
29 created: async function () { 29 created: async function () {
30 // Look for a new message if an endpoint is provided. 30 // Look for a new message if an endpoint is provided.
31 this.message = Object.assign({}, this.item); 31 this.message = Object.assign({}, this.item);
32 if (this.item && this.item.url) { 32 await this.getMessage();
33 const fetchedMessage = await this.getMessage(this.item.url);
34 // keep the original config value if no value is provided by the endpoint
35 for (const prop of ["title", "style", "content"]) {
36 if (prop in fetchedMessage && fetchedMessage[prop] !== null) {
37 this.message[prop] = fetchedMessage[prop];
38 }
39 }
40 }
41 this.show = this.message.title || this.message.content; 33 this.show = this.message.title || this.message.content;
42 }, 34 },
35
43 methods: { 36 methods: {
44 getMessage: function (url) { 37 getMessage: async function() {
38 if (this.item && this.item.url) {
39 let fetchedMessage = await this.downloadMessage(this.item.url);
40 if (this.item.mapping) fetchedMessage = this.mapRemoteMessage(fetchedMessage);
41 // keep the original config value if no value is provided by the endpoint
42 for (const prop of ["title", "style", "content"]) {
43 if (prop in fetchedMessage && fetchedMessage[prop] !== null) {
44 this.message[prop] = fetchedMessage[prop];
45 }
46 }
47 }
48 if (this.item.refreshInterval) setTimeout(this.getMessage, this.item.refreshInterval);
49 },
50
51 downloadMessage: function (url) {
45 return fetch(url).then(function (response) { 52 return fetch(url).then(function (response) {
46 if (response.status != 200) { 53 if (response.status != 200) {
47 return; 54 return;
@@ -49,6 +56,13 @@ export default {
49 return response.json(); 56 return response.json();
50 }); 57 });
51 }, 58 },
59
60 mapRemoteMessage: function (message) {
61 let mapped = {};
62 // map property from message into mapped according to mapping config (only if field has a value):
63 for (const prop in this.item.mapping) if (message[this.item.mapping[prop]]) mapped[prop] = message[this.item.mapping[prop]];
64 return mapped;
65 },
52 }, 66 },
53}; 67};
54</script> 68</script>