diff options
author | Bastien Wirtz <bastien.wirtz@gmail.com> | 2021-03-04 18:40:07 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-04 18:40:07 -0800 |
commit | cc7ff885527283d97f32347210b0370e8477c4ff (patch) | |
tree | 6c2eda44ed25cf2cd91cced7ab159ecd5e6735f7 | |
parent | 7bcfce6bdad32ec392279867af7f3f3c67a972b3 (diff) | |
parent | 9542de6eb25bfa20b376920b607db864c9e20a7a (diff) | |
download | homer-4c8e601eb0fbe8994dc3320ff98943843fe4e508.tar.gz homer-4c8e601eb0fbe8994dc3320ff98943843fe4e508.tar.zst homer-4c8e601eb0fbe8994dc3320ff98943843fe4e508.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.md | 13 | ||||
-rw-r--r-- | docs/tips-and-tricks.md | 58 | ||||
-rw-r--r-- | src/components/Message.vue | 34 |
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 |
67 | message: | 67 | message: |
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 | ||
121 | If you choose to fetch message information from an endpoint, the output format should be: | 132 | 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)): |
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 | ||
118 | Most times, the url you're getting headlines from follows a different schema than the one expected by Homer. | ||
119 | |||
120 | 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: | ||
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 | |||
134 | but... 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 | |||
143 | Now, you can do that using the `mapping` field in your `message` configuration. This example would be something like this: | ||
144 | |||
145 | ```yml | ||
146 | message: | ||
147 | url: https://api.chucknorris.io/jokes/random | ||
148 | mapping: | ||
149 | title: 'id' | ||
150 | content: 'value' | ||
151 | ``` | ||
152 | |||
153 | 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: | ||
154 | |||
155 | ```yml | ||
156 | message: | ||
157 | url: https://api.chucknorris.io/jokes/random | ||
158 | mapping: | ||
159 | content: 'value' | ||
160 | title: "Chuck Norris Facts!" | ||
161 | ``` | ||
162 | |||
163 | and even an error message in case the `url` didn't respond or threw an error: | ||
164 | |||
165 | ```yml | ||
166 | message: | ||
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 | ||
118 | Homer allows you to set a "message" that will appear at the top of the page, however, you can also supply a `url:`. | 176 | Homer 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> |