Unmarshal.md - hugo - [fork] hugo port for 9front
(HTM) git clone https://git.drkhsh.at/hugo.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
Unmarshal.md (9632B)
---
1 ---
2 title: transform.Unmarshal
3 description: Parses serialized data and returns a map or an array. Supports CSV, JSON, TOML, YAML, and XML.
4 categories: []
5 keywords: []
6 params:
7 functions_and_methods:
8 aliases: [unmarshal]
9 returnType: any
10 signatures: ['transform.Unmarshal [OPTIONS] INPUT']
11 aliases: [/functions/transform.unmarshal]
12 ---
13
14 The input can be a string or a [resource](g).
15
16 ## Unmarshal a string
17
18 ```go-html-template
19 {{ $string := `
20 title: Les Misérables
21 author: Victor Hugo
22 `}}
23
24 {{ $book := unmarshal $string }}
25 {{ $book.title }} → Les Misérables
26 {{ $book.author }} → Victor Hugo
27 ```
28
29 ## Unmarshal a resource
30
31 Use the `transform.Unmarshal` function with global, page, and remote resources.
32
33 ### Global resource
34
35 A global resource is a file within the `assets` directory, or within any directory mounted to the `assets` directory.
36
37 ```text
38 assets/
39 └── data/
40 └── books.json
41 ```
42
43 ```go-html-template
44 {{ $data := dict }}
45 {{ $path := "data/books.json" }}
46 {{ with resources.Get $path }}
47 {{ with . | transform.Unmarshal }}
48 {{ $data = . }}
49 {{ end }}
50 {{ else }}
51 {{ errorf "Unable to get global resource %q" $path }}
52 {{ end }}
53
54 {{ range where $data "author" "Victor Hugo" }}
55 {{ .title }} → Les Misérables
56 {{ end }}
57 ```
58
59 ### Page resource
60
61 A page resource is a file within a [page bundle].
62
63 ```text
64 content/
65 ├── post/
66 │ └── book-reviews/
67 │ ├── books.json
68 │ └── index.md
69 └── _index.md
70 ```
71
72 ```go-html-template
73 {{ $data := dict }}
74 {{ $path := "books.json" }}
75 {{ with .Resources.Get $path }}
76 {{ with . | transform.Unmarshal }}
77 {{ $data = . }}
78 {{ end }}
79 {{ else }}
80 {{ errorf "Unable to get page resource %q" $path }}
81 {{ end }}
82
83 {{ range where $data "author" "Victor Hugo" }}
84 {{ .title }} → Les Misérables
85 {{ end }}
86 ```
87
88 ### Remote resource
89
90 A remote resource is a file on a remote server, accessible via HTTP or HTTPS.
91
92 ```go-html-template
93 {{ $data := dict }}
94 {{ $url := "https://example.org/books.json" }}
95 {{ with try (resources.GetRemote $url) }}
96 {{ with .Err }}
97 {{ errorf "%s" . }}
98 {{ else with .Value }}
99 {{ $data = . | transform.Unmarshal }}
100 {{ else }}
101 {{ errorf "Unable to get remote resource %q" $url }}
102 {{ end }}
103 {{ end }}
104
105 {{ range where $data "author" "Victor Hugo" }}
106 {{ .title }} → Les Misérables
107 {{ end }}
108 ```
109
110 > [!note]
111 > When retrieving remote data, a misconfigured server may send a response header with an incorrect [Content-Type]. For example, the server may set the Content-Type header to `application/octet-stream` instead of `application/json`.
112 >
113 > In these cases, pass the resource `Content` through the `transform.Unmarshal` function instead of passing the resource itself. For example, in the above, do this instead:
114 >
115 > `{{ $data = .Content | transform.Unmarshal }}`
116
117 ## Working with CSV
118
119 ### Options
120
121 When unmarshaling a CSV file, provide an optional map of options.
122
123 delimiter
124 : (`string`) The delimiter used. Default is `,`.
125
126 comment
127 : (`string`) The comment character used in the CSV. If set, lines beginning with the comment character without preceding whitespace are ignored.
128
129 lazyQuotes
130 : {{< new-in 0.122.0 />}}
131 : (`bool`) Whether to allow a quote in an unquoted field, or to allow a non-doubled quote in a quoted field. Default is `false`.
132
133 targetType
134 : {{< new-in 0.146.7 />}}
135 : (`string`) The target data type, either `slice` or `map`. Default is `slice`.
136
137 ### Examples
138
139 The examples below use this CSV file:
140
141 ```csv
142 "name","type","breed","age"
143 "Spot","dog","Collie",3
144 "Rover","dog","Boxer",5
145 "Felix","cat","Calico",7
146 ```
147
148 To render an HTML table from a CSV file:
149
150 ```go-html-template
151 {{ $data := slice }}
152 {{ $file := "pets.csv" }}
153 {{ with or (.Resources.Get $file) (resources.Get $file) }}
154 {{ $opts := dict "targetType" "slice" }}
155 {{ $data = transform.Unmarshal $opts . }}
156 {{ end }}
157
158 {{ with $data }}
159 <table>
160 <thead>
161 <tr>
162 {{ range index . 0 }}
163 <th>{{ . }}</th>
164 {{ end }}
165 </tr>
166 </thead>
167 <tbody>
168 {{ range . | after 1 }}
169 <tr>
170 {{ range . }}
171 <td>{{ . }}</td>
172 {{ end }}
173 </tr>
174 {{ end }}
175 </tbody>
176 </table>
177 {{ end }}
178 ```
179
180 To extract a subset of the data, or to sort the data, unmarshal to a map instead of a slice:
181
182 ```go-html-template
183 {{ $data := dict }}
184 {{ $file := "pets.csv" }}
185 {{ with or (.Resources.Get $file) (resources.Get $file) }}
186 {{ $opts := dict "targetType" "map" }}
187 {{ $data = transform.Unmarshal $opts . }}
188 {{ end }}
189
190 {{ with sort (where $data "type" "dog") "name" "asc" }}
191 <table>
192 <thead>
193 <tr>
194 <th>name</th>
195 <th>type</th>
196 <th>breed</th>
197 <th>age</th>
198 </tr>
199 </thead>
200 <tbody>
201 {{ range . }}
202 <tr>
203 <td>{{ .name }}</td>
204 <td>{{ .type }}</td>
205 <td>{{ .breed }}</td>
206 <td>{{ .age }}</td>
207 </tr>
208 {{ end }}
209 </tbody>
210 </table>
211 {{ end }}
212 ```
213
214 ## Working with XML
215
216 When unmarshaling an XML file, do not include the root node when accessing data. For example, after unmarshaling the RSS feed below, access the feed title with `$data.channel.title`.
217
218 ```xml
219 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
220 <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
221 <channel>
222 <title>Books on Example Site</title>
223 <link>https://example.org/books/</link>
224 <description>Recent content in Books on Example Site</description>
225 <language>en-US</language>
226 <atom:link href="https://example.org/books/index.xml" rel="self" type="application/rss+xml" />
227 <item>
228 <title>The Hunchback of Notre Dame</title>
229 <description>Written by Victor Hugo</description>
230 <link>https://example.org/books/the-hunchback-of-notre-dame/</link>
231 <pubDate>Mon, 09 Oct 2023 09:27:12 -0700</pubDate>
232 <guid>https://example.org/books/the-hunchback-of-notre-dame/</guid>
233 </item>
234 <item>
235 <title>Les Misérables</title>
236 <description>Written by Victor Hugo</description>
237 <link>https://example.org/books/les-miserables/</link>
238 <pubDate>Mon, 09 Oct 2023 09:27:11 -0700</pubDate>
239 <guid>https://example.org/books/les-miserables/</guid>
240 </item>
241 </channel>
242 </rss>
243 ```
244
245 Get the remote data:
246
247 ```go-html-template
248 {{ $data := dict }}
249 {{ $url := "https://example.org/books/index.xml" }}
250 {{ with try (resources.GetRemote $url) }}
251 {{ with .Err }}
252 {{ errorf "%s" . }}
253 {{ else with .Value }}
254 {{ $data = . | transform.Unmarshal }}
255 {{ else }}
256 {{ errorf "Unable to get remote resource %q" $url }}
257 {{ end }}
258 {{ end }}
259 ```
260
261 Inspect the data structure:
262
263 ```go-html-template
264 <pre>{{ debug.Dump $data }}</pre>
265 ```
266
267 List the book titles:
268
269 ```go-html-template
270 {{ with $data.channel.item }}
271 <ul>
272 {{ range . }}
273 <li>{{ .title }}</li>
274 {{ end }}
275 </ul>
276 {{ end }}
277 ```
278
279 Hugo renders this to:
280
281 ```html
282 <ul>
283 <li>The Hunchback of Notre Dame</li>
284 <li>Les Misérables</li>
285 </ul>
286 ```
287
288 ### XML attributes and namespaces
289
290 Let's add a `lang` attribute to the `title` nodes of our RSS feed, and a namespaced node for the ISBN number:
291
292 ```xml
293 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
294 <rss version="2.0"
295 xmlns:atom="http://www.w3.org/2005/Atom"
296 xmlns:isbn="http://schemas.isbn.org/ns/1999/basic.dtd"
297 >
298 <channel>
299 <title>Books on Example Site</title>
300 <link>https://example.org/books/</link>
301 <description>Recent content in Books on Example Site</description>
302 <language>en-US</language>
303 <atom:link href="https://example.org/books/index.xml" rel="self" type="application/rss+xml" />
304 <item>
305 <title lang="en">The Hunchback of Notre Dame</title>
306 <description>Written by Victor Hugo</description>
307 <isbn:number>9780140443530</isbn:number>
308 <link>https://example.org/books/the-hunchback-of-notre-dame/</link>
309 <pubDate>Mon, 09 Oct 2023 09:27:12 -0700</pubDate>
310 <guid>https://example.org/books/the-hunchback-of-notre-dame/</guid>
311 </item>
312 <item>
313 <title lang="fr">Les Misérables</title>
314 <description>Written by Victor Hugo</description>
315 <isbn:number>9780451419439</isbn:number>
316 <link>https://example.org/books/les-miserables/</link>
317 <pubDate>Mon, 09 Oct 2023 09:27:11 -0700</pubDate>
318 <guid>https://example.org/books/les-miserables/</guid>
319 </item>
320 </channel>
321 </rss>
322 ```
323
324 After retrieving the remote data, inspect the data structure:
325
326 ```go-html-template
327 <pre>{{ debug.Dump $data }}</pre>
328 ```
329
330 Each item node looks like this:
331
332 ```json
333 {
334 "description": "Written by Victor Hugo",
335 "guid": "https://example.org/books/the-hunchback-of-notre-dame/",
336 "link": "https://example.org/books/the-hunchback-of-notre-dame/",
337 "number": "9780140443530",
338 "pubDate": "Mon, 09 Oct 2023 09:27:12 -0700",
339 "title": {
340 "#text": "The Hunchback of Notre Dame",
341 "-lang": "en"
342 }
343 }
344 ```
345
346 The title keys do not begin with an underscore or a letter---they are not valid [identifiers](g). Use the [`index`] function to access the values:
347
348 ```go-html-template
349 {{ with $data.channel.item }}
350 <ul>
351 {{ range . }}
352 {{ $title := index .title "#text" }}
353 {{ $lang := index .title "-lang" }}
354 {{ $ISBN := .number }}
355 <li>{{ $title }} ({{ $lang }}) {{ $ISBN }}</li>
356 {{ end }}
357 </ul>
358 {{ end }}
359 ```
360
361 Hugo renders this to:
362
363 ```html
364 <ul>
365 <li>The Hunchback of Notre Dame (en) 9780140443530</li>
366 <li>Les Misérables (fr) 9780451419439</li>
367 </ul>
368 ```
369
370 [`index`]: /functions/collections/indexfunction/
371 [Content-Type]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
372 [page bundle]: /content-management/page-bundles/