jekyll-open-sdg-plugins 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.editorconfig +16 -16
- data/.github/workflows/test-pull-requests.yml +17 -0
- data/.gitignore +6 -4
- data/Makefile +33 -0
- data/README.md +7 -7
- data/jekyll-open-sdg-plugins.gemspec +17 -17
- data/lib/jekyll-open-sdg-plugins.rb +14 -13
- data/lib/jekyll-open-sdg-plugins/create_goals.rb +75 -75
- data/lib/jekyll-open-sdg-plugins/create_indicators.rb +67 -67
- data/lib/jekyll-open-sdg-plugins/create_pages.rb +112 -99
- data/lib/jekyll-open-sdg-plugins/fetch_remote_data.rb +167 -167
- data/lib/jekyll-open-sdg-plugins/helpers.rb +94 -66
- data/lib/jekyll-open-sdg-plugins/sdg_variables.rb +439 -417
- data/lib/jekyll-open-sdg-plugins/search_index.rb +92 -92
- data/lib/jekyll-open-sdg-plugins/site_configuration.rb +43 -0
- data/lib/jekyll-open-sdg-plugins/translate_date.rb +98 -72
- data/lib/jekyll-open-sdg-plugins/translate_key.rb +20 -20
- data/lib/jekyll-open-sdg-plugins/translate_metadata_field.rb +111 -111
- data/lib/jekyll-open-sdg-plugins/version.rb +3 -3
- data/tests/Gemfile +6 -0
- data/tests/_config.yml +145 -0
- metadata +8 -4
@@ -1,66 +1,94 @@
|
|
1
|
-
# Simple collection of helper functions for use in these plugins.
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
# key
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
levels
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
if drilled.
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
site
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
1
|
+
# Simple collection of helper functions for use in these plugins.
|
2
|
+
|
3
|
+
require "jekyll"
|
4
|
+
|
5
|
+
# Takes a translation key and returns a translated string according to the
|
6
|
+
# language of the current page. Or if none is found, returns the original
|
7
|
+
# key.
|
8
|
+
def opensdg_translate_key(key, translations, language)
|
9
|
+
|
10
|
+
# Safety code - abort now if key is nil.
|
11
|
+
if key.nil?
|
12
|
+
return ""
|
13
|
+
end
|
14
|
+
|
15
|
+
# Also make sure it is a string, and other just return it.
|
16
|
+
if not key.is_a? String
|
17
|
+
return key
|
18
|
+
end
|
19
|
+
|
20
|
+
# More safety code - abort now if key is empty.
|
21
|
+
if key.empty?
|
22
|
+
return ""
|
23
|
+
end
|
24
|
+
|
25
|
+
# Keep track of the last thing we drilled to.
|
26
|
+
drilled = translations[language]
|
27
|
+
|
28
|
+
# Keep track of how many levels we have drilled.
|
29
|
+
levels_drilled = 0
|
30
|
+
levels = key.split('.')
|
31
|
+
|
32
|
+
# Loop through each level.
|
33
|
+
levels.each do |level|
|
34
|
+
|
35
|
+
# If we have drilled down to a scalar value too soon, abort.
|
36
|
+
break if drilled.class != Hash
|
37
|
+
|
38
|
+
if drilled.has_key? level
|
39
|
+
# If we find something, continue drilling.
|
40
|
+
drilled = drilled[level]
|
41
|
+
levels_drilled += 1
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
# If we didn't drill the right number of levels, return the
|
47
|
+
# original string.
|
48
|
+
if levels.length != levels_drilled
|
49
|
+
return key
|
50
|
+
end
|
51
|
+
|
52
|
+
# Otherwise we must have drilled all they way.
|
53
|
+
return drilled
|
54
|
+
end
|
55
|
+
|
56
|
+
# Takes a site object and decides whether it is using translated builds.
|
57
|
+
def opensdg_translated_builds(site)
|
58
|
+
# Assume the site is using translated builds.
|
59
|
+
translated_builds = true
|
60
|
+
site.config['languages'].each do |language|
|
61
|
+
# If any languages don't have a key in site.data, the site is not using
|
62
|
+
# translated builds.
|
63
|
+
if !site.data.has_key? language
|
64
|
+
translated_builds = false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
return translated_builds
|
68
|
+
end
|
69
|
+
|
70
|
+
# Print a notice during compilation.
|
71
|
+
def opensdg_notice(message)
|
72
|
+
Jekyll.logger.warn message.yellow
|
73
|
+
end
|
74
|
+
|
75
|
+
# Get the public language codes for a site, keyed by the actual language codes.
|
76
|
+
def opensdg_languages_public(site)
|
77
|
+
languages_public = site.config['languages_public']
|
78
|
+
|
79
|
+
# The current structure of the setting is an array of hashes, each containing
|
80
|
+
# keys for "language" and "language_public".
|
81
|
+
if languages_public.is_a?(Array)
|
82
|
+
converted_languages_public = Hash.new
|
83
|
+
languages_public.each do |language_public|
|
84
|
+
language_code = language_public['language']
|
85
|
+
language_code_public = language_public['language_public']
|
86
|
+
converted_languages_public[language_code] = language_code_public
|
87
|
+
end
|
88
|
+
return converted_languages_public
|
89
|
+
end
|
90
|
+
|
91
|
+
# Fallback to exactly what was retrieved from site.confg['languages_public'],
|
92
|
+
# since the deprecated structure is exactly what this function wants.
|
93
|
+
return languages_public
|
94
|
+
end
|
@@ -1,417 +1,439 @@
|
|
1
|
-
require "jekyll"
|
2
|
-
require_relative "helpers"
|
3
|
-
|
4
|
-
module JekyllOpenSdgPlugins
|
5
|
-
class SDGVariables < Jekyll::Generator
|
6
|
-
safe true
|
7
|
-
priority :low
|
8
|
-
|
9
|
-
# Get a goal number from an indicator number.
|
10
|
-
def get_goal_number(indicator_number)
|
11
|
-
parts = indicator_number.split('.')
|
12
|
-
parts[0]
|
13
|
-
end
|
14
|
-
|
15
|
-
# Get a target number from an indicator number.
|
16
|
-
def get_target_number(indicator_number)
|
17
|
-
parts = indicator_number.split('.')
|
18
|
-
parts[0] + '.' + parts[1]
|
19
|
-
end
|
20
|
-
|
21
|
-
#
|
22
|
-
def
|
23
|
-
if
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
baseurl
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
baseurl
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
if language
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
#
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
#
|
128
|
-
#
|
129
|
-
#
|
130
|
-
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
# -
|
134
|
-
#
|
135
|
-
# -
|
136
|
-
# -
|
137
|
-
#
|
138
|
-
# -
|
139
|
-
#
|
140
|
-
# -
|
141
|
-
#
|
142
|
-
# -
|
143
|
-
#
|
144
|
-
# the
|
145
|
-
# - goal
|
146
|
-
# - target
|
147
|
-
# - indicator
|
148
|
-
#
|
149
|
-
#
|
150
|
-
# -
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
#
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
]
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
end
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
'
|
261
|
-
'
|
262
|
-
'
|
263
|
-
'
|
264
|
-
'
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
#
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
meta.
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
end
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
doc.data['
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
1
|
+
require "jekyll"
|
2
|
+
require_relative "helpers"
|
3
|
+
|
4
|
+
module JekyllOpenSdgPlugins
|
5
|
+
class SDGVariables < Jekyll::Generator
|
6
|
+
safe true
|
7
|
+
priority :low
|
8
|
+
|
9
|
+
# Get a goal number from an indicator number.
|
10
|
+
def get_goal_number(indicator_number)
|
11
|
+
parts = indicator_number.split('.')
|
12
|
+
parts[0]
|
13
|
+
end
|
14
|
+
|
15
|
+
# Get a target number from an indicator number.
|
16
|
+
def get_target_number(indicator_number)
|
17
|
+
parts = indicator_number.split('.')
|
18
|
+
parts[0] + '.' + parts[1]
|
19
|
+
end
|
20
|
+
|
21
|
+
# Is this string numeric?
|
22
|
+
def is_number? string
|
23
|
+
true if Float(string) rescue false
|
24
|
+
end
|
25
|
+
|
26
|
+
# Make any goal/target/indicator number suitable for use in sorting.
|
27
|
+
def get_sort_order(number)
|
28
|
+
if number.is_a? Numeric
|
29
|
+
number = number.to_s
|
30
|
+
end
|
31
|
+
sort_order = ''
|
32
|
+
parts = number.split('.')
|
33
|
+
parts.each do |part|
|
34
|
+
if part.length == 1
|
35
|
+
if is_number?(part)
|
36
|
+
part = '0' + part
|
37
|
+
else
|
38
|
+
part = part + part
|
39
|
+
end
|
40
|
+
end
|
41
|
+
sort_order += part
|
42
|
+
end
|
43
|
+
sort_order
|
44
|
+
end
|
45
|
+
|
46
|
+
# The Jekyll baseurl is user-configured, and can be inconsistent. This
|
47
|
+
# ensure it is consistent in whether it starts/ends with a slash.
|
48
|
+
def normalize_baseurl(baseurl)
|
49
|
+
if baseurl == ''
|
50
|
+
baseurl = '/'
|
51
|
+
end
|
52
|
+
if !baseurl.start_with? '/'
|
53
|
+
baseurl = '/' + baseurl
|
54
|
+
end
|
55
|
+
if !baseurl.end_with? '/'
|
56
|
+
baseurl = baseurl + '/'
|
57
|
+
end
|
58
|
+
baseurl
|
59
|
+
end
|
60
|
+
|
61
|
+
# Compute a URL for an item, given it's number.
|
62
|
+
def get_url(baseurl, language, number, languages, languages_public)
|
63
|
+
|
64
|
+
baseurl = normalize_baseurl(baseurl)
|
65
|
+
|
66
|
+
default_language = languages[0]
|
67
|
+
language_public = language
|
68
|
+
if languages_public && languages_public[language]
|
69
|
+
language_public = languages_public[language]
|
70
|
+
end
|
71
|
+
if default_language != language
|
72
|
+
baseurl += language_public + '/'
|
73
|
+
end
|
74
|
+
|
75
|
+
number = number.gsub('.', '-')
|
76
|
+
baseurl + number
|
77
|
+
end
|
78
|
+
|
79
|
+
# Get a Hash of all the URLs based on one particular one.
|
80
|
+
def get_all_urls(url, language, languages, languages_public, baseurl)
|
81
|
+
|
82
|
+
baseurl = normalize_baseurl(baseurl)
|
83
|
+
|
84
|
+
language_public = language
|
85
|
+
if languages_public && languages_public[language]
|
86
|
+
language_public = languages_public[language]
|
87
|
+
end
|
88
|
+
|
89
|
+
# First figure out the language-free URL.
|
90
|
+
default_language = languages[0]
|
91
|
+
if language == default_language
|
92
|
+
url_without_language = url
|
93
|
+
else
|
94
|
+
url_without_language = url.gsub('/' + language_public + '/', '/')
|
95
|
+
end
|
96
|
+
|
97
|
+
urls = {
|
98
|
+
language => url
|
99
|
+
}
|
100
|
+
if language != default_language
|
101
|
+
default_language_url = baseurl + url_without_language
|
102
|
+
# Fix potential double-slash.
|
103
|
+
default_language_url = default_language_url.gsub('//', '/')
|
104
|
+
urls[default_language] = default_language_url
|
105
|
+
end
|
106
|
+
languages.each do |other_language|
|
107
|
+
if other_language == language
|
108
|
+
next
|
109
|
+
end
|
110
|
+
if other_language == default_language
|
111
|
+
next
|
112
|
+
end
|
113
|
+
other_language_public = other_language
|
114
|
+
if languages_public && languages_public[other_language]
|
115
|
+
other_language_public = languages_public[other_language]
|
116
|
+
end
|
117
|
+
urls[other_language] = baseurl + other_language_public + url_without_language
|
118
|
+
end
|
119
|
+
urls
|
120
|
+
end
|
121
|
+
|
122
|
+
# Compute a URL for tha goal image, given it's number.
|
123
|
+
def get_goal_image(goal_image_base, language, number, extension)
|
124
|
+
goal_image_base + '/' + language + '/' + number + '.' + extension
|
125
|
+
end
|
126
|
+
|
127
|
+
# This creates variables for use in Liquid templates under "page".
|
128
|
+
# We'll create lists of goals, targets, and indicators. These will be put
|
129
|
+
# on the page object. Eg: page.goals. In order to generate these lists
|
130
|
+
# we will make use of the metadata. Each item in the list will be a hash
|
131
|
+
# containing these keys:
|
132
|
+
# - name (translated)
|
133
|
+
# - number (the "id" or number, eg: 1, 1.2, 1.2.1, etc.)
|
134
|
+
# - slug (version of 'number' but with dashes instead of dots)
|
135
|
+
# - sort (for the purposes of sorting the items, if needed)
|
136
|
+
# - global (a Hash containing any equivalent global metadata)
|
137
|
+
# The goal hashes contain additional keys:
|
138
|
+
# - short (the translated short version of the name)
|
139
|
+
# - icon (path to the translated icon)
|
140
|
+
# - url (path to the goal page)
|
141
|
+
# The target hashes contain additional keys:
|
142
|
+
# - goal_number (the goal number for this target)
|
143
|
+
# The indicator hashes contain additional keys:
|
144
|
+
# - url (path to the indicator page)
|
145
|
+
# - goal_number (the goal number for this indicator)
|
146
|
+
# - target_number (the target number for this indicator)
|
147
|
+
# - [all metadata fields from the indicator]
|
148
|
+
# The lists are:
|
149
|
+
# - goals
|
150
|
+
# - targets
|
151
|
+
# - indicators
|
152
|
+
# Additionally, on indicator pages themselves, there are variables for
|
153
|
+
# the current goal/target/indicator:
|
154
|
+
# - goal
|
155
|
+
# - target
|
156
|
+
# - indicator
|
157
|
+
# Similarly, on goal pages themselves, there are variables for the current
|
158
|
+
# goal:
|
159
|
+
# - goal
|
160
|
+
def generate(site)
|
161
|
+
|
162
|
+
# Some general variables needed below.
|
163
|
+
translations = site.data['translations']
|
164
|
+
languages = site.config['languages']
|
165
|
+
languages_public = opensdg_languages_public(site)
|
166
|
+
default_language = languages[0]
|
167
|
+
baseurl = site.config['baseurl']
|
168
|
+
goal_image_base = 'https://open-sdg.org/sdg-translations/assets/img/goals'
|
169
|
+
if site.config.has_key? 'goal_image_base'
|
170
|
+
goal_image_base = site.config['goal_image_base']
|
171
|
+
end
|
172
|
+
goal_image_extension = 'png'
|
173
|
+
if site.config.has_key? 'goal_image_extension'
|
174
|
+
goal_image_extension = site.config['goal_image_extension']
|
175
|
+
end
|
176
|
+
|
177
|
+
# These keys are flagged as "protected" here so that we can make sure that
|
178
|
+
# country-specific metadata doesn't use any of these fields.
|
179
|
+
protected_keys = ['goals', 'goal', 'targets', 'target', 'indicators',
|
180
|
+
'indicator', 'language', 'name', 'number', 'sort', 'global', 'url',
|
181
|
+
'goal_number', 'target_number'
|
182
|
+
]
|
183
|
+
|
184
|
+
# Figure out from our translations the global indicator numbers.
|
185
|
+
global_inids = translations[default_language]['global_indicators'].keys
|
186
|
+
global_inids = global_inids.select { |x| x.end_with? '-title' }
|
187
|
+
global_inids = global_inids.map { |x| x.gsub('-title', '').gsub('-', '.') }
|
188
|
+
|
189
|
+
# For available indicators, we simply map the "indicators" collection.
|
190
|
+
available_inids = site.collections['indicators'].docs.select { |x| x.data['language'] == default_language }
|
191
|
+
available_inids = available_inids.map { |x| x.data['indicator'] }
|
192
|
+
available_indicators = {}
|
193
|
+
available_targets = {}
|
194
|
+
available_goals = {}
|
195
|
+
|
196
|
+
# Some throwaway variables to keep track of what has been added.
|
197
|
+
already_added = {}
|
198
|
+
|
199
|
+
# Set up some empty hashes, per language.
|
200
|
+
languages.each do |language|
|
201
|
+
available_goals[language] = []
|
202
|
+
available_targets[language] = []
|
203
|
+
available_indicators[language] = []
|
204
|
+
already_added[language] = []
|
205
|
+
end
|
206
|
+
|
207
|
+
# Populate the hashes.
|
208
|
+
available_inids.each do |indicator_number|
|
209
|
+
goal_number = get_goal_number(indicator_number)
|
210
|
+
target_number = get_target_number(indicator_number)
|
211
|
+
is_global_indicator = global_inids.index(indicator_number) != nil
|
212
|
+
# To get the name of global stuff, we can use predicable translation
|
213
|
+
# keys from the SDG Translations project. Eg: global_goals.1-title
|
214
|
+
goal_translation_key = 'global_goals.' + goal_number
|
215
|
+
target_translation_key = 'global_targets.' + target_number.gsub('.', '-')
|
216
|
+
indicator_translation_key = 'global_indicators.' + indicator_number.gsub('.', '-')
|
217
|
+
|
218
|
+
languages.each do |language|
|
219
|
+
global_goal = {
|
220
|
+
'name' => opensdg_translate_key(goal_translation_key + '-title', translations, language),
|
221
|
+
# TODO: More global metadata about goals?
|
222
|
+
}
|
223
|
+
global_target = {
|
224
|
+
'name' => opensdg_translate_key(target_translation_key + '-title', translations, language),
|
225
|
+
# TODO: More global metadata about targets?
|
226
|
+
}
|
227
|
+
global_indicator = {}
|
228
|
+
if is_global_indicator
|
229
|
+
global_indicator = {
|
230
|
+
'name' => opensdg_translate_key(indicator_translation_key + '-title', translations, language),
|
231
|
+
# TODO: More global metadata about indicators?
|
232
|
+
}
|
233
|
+
end
|
234
|
+
|
235
|
+
# We have to get the metadata for the indicator/language.
|
236
|
+
meta = {}
|
237
|
+
# Currently the meta keys are dash-delimited. This is a little
|
238
|
+
# arbitrary (it's because they came from filenames) and could maybe
|
239
|
+
# be changed eventually to dot-delimited for consistency.
|
240
|
+
meta_key = indicator_number.gsub('.', '-')
|
241
|
+
# The location of the metadata is different depending on whether we are
|
242
|
+
# using "translated_builds" or not.
|
243
|
+
if opensdg_translated_builds(site)
|
244
|
+
meta = site.data[language]['meta'][meta_key]
|
245
|
+
else
|
246
|
+
meta = site.data['meta'][meta_key]
|
247
|
+
# Also for untranslated builds, we need to support the "subfolder"
|
248
|
+
# approach for metadata translation. (This is handled at build-time
|
249
|
+
# for translated builds.)
|
250
|
+
if meta.has_key? language
|
251
|
+
meta = meta.merge(meta[language])
|
252
|
+
meta.delete(language)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
# Set the goal for this language, once only.
|
257
|
+
if already_added[language].index(goal_number) == nil
|
258
|
+
already_added[language].push(goal_number)
|
259
|
+
available_goal = {
|
260
|
+
'number' => goal_number,
|
261
|
+
'slug' => goal_number.gsub('.', '-'),
|
262
|
+
'name' => opensdg_translate_key(goal_translation_key + '-title', translations, language),
|
263
|
+
'short' => opensdg_translate_key(goal_translation_key + '-short', translations, language),
|
264
|
+
'url' => get_url(baseurl, language, goal_number, languages, languages_public),
|
265
|
+
'icon' => get_goal_image(goal_image_base, language, goal_number, goal_image_extension),
|
266
|
+
'sort' => get_sort_order(goal_number),
|
267
|
+
'global' => global_goal,
|
268
|
+
}
|
269
|
+
available_goals[language].push(available_goal)
|
270
|
+
end
|
271
|
+
# Set the target for this language, once only.
|
272
|
+
if already_added[language].index(target_number) == nil
|
273
|
+
already_added[language].push(target_number)
|
274
|
+
available_target = {
|
275
|
+
'number' => target_number,
|
276
|
+
'slug' => target_number.gsub('.', '-'),
|
277
|
+
'name' => opensdg_translate_key(target_translation_key + '-title', translations, language),
|
278
|
+
'sort' => get_sort_order(target_number),
|
279
|
+
'goal_number' => goal_number,
|
280
|
+
'global' => global_target,
|
281
|
+
}
|
282
|
+
available_targets[language].push(available_target)
|
283
|
+
end
|
284
|
+
# Set the indicator for this language. Unfortunately we are currently
|
285
|
+
# using two possible fields for the indicator name:
|
286
|
+
# - indicator_name
|
287
|
+
# - indicator_name_national
|
288
|
+
# TODO: Eventually standardize around 'indicator_name' and drop support
|
289
|
+
# for 'indicator_name_national'.
|
290
|
+
indicator_name = ''
|
291
|
+
if meta.has_key? 'indicator_name_national'
|
292
|
+
indicator_name = meta['indicator_name_national']
|
293
|
+
else
|
294
|
+
indicator_name = meta['indicator_name']
|
295
|
+
end
|
296
|
+
available_indicator = {
|
297
|
+
'number' => indicator_number,
|
298
|
+
'slug' => indicator_number.gsub('.', '-'),
|
299
|
+
'name' => opensdg_translate_key(indicator_name, translations, language),
|
300
|
+
'url' => get_url(baseurl, language, indicator_number, languages, languages_public),
|
301
|
+
'sort' => get_sort_order(indicator_number),
|
302
|
+
'goal_number' => goal_number,
|
303
|
+
'target_number' => target_number,
|
304
|
+
'global' => global_indicator,
|
305
|
+
}
|
306
|
+
# Translate and add any metadata.
|
307
|
+
meta.each do |key, value|
|
308
|
+
if !protected_keys.include? key
|
309
|
+
available_indicator[key] = opensdg_translate_key(value, translations, language)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
available_indicators[language].push(available_indicator)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
# Sort all the items.
|
317
|
+
languages.each do |lang|
|
318
|
+
available_goals[lang] = available_goals[lang].sort_by { |x| x['sort'] }
|
319
|
+
available_targets[lang] = available_targets[lang].sort_by { |x| x['sort'] }
|
320
|
+
available_indicators[lang] = available_indicators[lang].sort_by { |x| x['sort'] }
|
321
|
+
end
|
322
|
+
|
323
|
+
# Next set the stuff on each doc in certain collections, according
|
324
|
+
# to the doc's language. We'll be putting the global stuff on every
|
325
|
+
# page, goal, and indicator across the site. This may be a bit memory-
|
326
|
+
# intensive during the Jekyll build, but it is nice to have it available
|
327
|
+
# for consistency.
|
328
|
+
site.collections.keys.each do |collection|
|
329
|
+
site.collections[collection].docs.each do |doc|
|
330
|
+
# Ensure it has a language.
|
331
|
+
if !doc.data.has_key? 'language'
|
332
|
+
doc.data['language'] = default_language
|
333
|
+
end
|
334
|
+
# Ensure it has a valid language.
|
335
|
+
if !languages.include? doc.data['language']
|
336
|
+
message = "NOTICE: The document '#{doc.basename}' has an unexpected language '#{doc.data['language']}' so we are using the default language '#{default_language}' instead."
|
337
|
+
opensdg_notice(message)
|
338
|
+
doc.data['language'] = default_language
|
339
|
+
end
|
340
|
+
language = doc.data['language']
|
341
|
+
# Set these on the page object.
|
342
|
+
doc.data['goals'] = available_goals[language]
|
343
|
+
doc.data['targets'] = available_targets[language]
|
344
|
+
doc.data['indicators'] = available_indicators[language]
|
345
|
+
doc.data['baseurl'] = get_url(baseurl, language, '', languages, languages_public)
|
346
|
+
doc.data['url_by_language'] = get_all_urls(doc.url, language, languages, languages_public, baseurl)
|
347
|
+
doc.data['t'] = site.data['translations'][language]
|
348
|
+
|
349
|
+
# Set the remote_data_prefix for this page.
|
350
|
+
if site.config.has_key? 'remote_data_prefix'
|
351
|
+
doc.data['remote_data_prefix'] = site.config['remote_data_prefix']
|
352
|
+
elsif site.config.has_key? 'local_data_folder'
|
353
|
+
doc.data['remote_data_prefix'] = normalize_baseurl(baseurl)
|
354
|
+
end
|
355
|
+
if opensdg_translated_builds(site)
|
356
|
+
doc.data['remote_data_prefix'] = File.join(doc.data['remote_data_prefix'], language)
|
357
|
+
end
|
358
|
+
|
359
|
+
if collection == 'indicators'
|
360
|
+
# For indicators we also set the current indicator/target/goal.
|
361
|
+
if doc.data.has_key? 'indicator_number'
|
362
|
+
indicator_number = doc.data['indicator_number']
|
363
|
+
elsif doc.data.has_key? 'indicator'
|
364
|
+
# Backwards compatibility.
|
365
|
+
indicator_number = doc.data['indicator']
|
366
|
+
else
|
367
|
+
raise "Error: An indicator does not have 'indicator_number' property."
|
368
|
+
end
|
369
|
+
# Force the indicator number to be a string.
|
370
|
+
if indicator_number.is_a? Numeric
|
371
|
+
indicator_number = indicator_number.to_s
|
372
|
+
end
|
373
|
+
goal_number = get_goal_number(indicator_number)
|
374
|
+
target_number = get_target_number(indicator_number)
|
375
|
+
doc.data['goal'] = available_goals[language].find {|x| x['number'] == goal_number}
|
376
|
+
doc.data['target'] = available_targets[language].find {|x| x['number'] == target_number}
|
377
|
+
doc.data['indicator'] = available_indicators[language].find {|x| x['number'] == indicator_number}
|
378
|
+
elsif collection == 'goals'
|
379
|
+
# For goals we also set the current goal.
|
380
|
+
if doc.data.has_key? 'goal_number'
|
381
|
+
goal_number = doc.data['goal_number']
|
382
|
+
elsif doc.data.has_key? 'sdg_goal'
|
383
|
+
# Backwards compatibility.
|
384
|
+
goal_number = doc.data['sdg_goal']
|
385
|
+
else
|
386
|
+
raise "Error: A goal does not have 'goal_number' property."
|
387
|
+
end
|
388
|
+
# Force the goal number to be a string.
|
389
|
+
if goal_number.is_a? Numeric
|
390
|
+
goal_number = goal_number.to_s
|
391
|
+
end
|
392
|
+
doc.data['goal'] = available_goals[language].find {|x| x['number'] == goal_number}
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
# Finally let's set all these on the site object so that they can be
|
398
|
+
# easily looked up later.
|
399
|
+
lookup = {}
|
400
|
+
available_goals.each do |language, items|
|
401
|
+
lookup[language] = {}
|
402
|
+
items.each do |item|
|
403
|
+
number = item['number']
|
404
|
+
lookup[language][number] = item
|
405
|
+
end
|
406
|
+
end
|
407
|
+
available_targets.each do |language, items|
|
408
|
+
items.each do |item|
|
409
|
+
number = item['number']
|
410
|
+
lookup[language][number] = item
|
411
|
+
end
|
412
|
+
end
|
413
|
+
available_indicators.each do |language, items|
|
414
|
+
items.each do |item|
|
415
|
+
number = item['number']
|
416
|
+
lookup[language][number] = item
|
417
|
+
end
|
418
|
+
end
|
419
|
+
site.data['sdg_lookup'] = lookup
|
420
|
+
|
421
|
+
end
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
module Jekyll
|
426
|
+
module SDGLookup
|
427
|
+
# This provides a "sdg_lookup" filter that takes an id and returns a hash
|
428
|
+
# representation of a goal, target, or indicator.
|
429
|
+
def sdg_lookup(number)
|
430
|
+
number = number.gsub('-', '.')
|
431
|
+
data = @context.registers[:site].data
|
432
|
+
page = @context.environments.first['page']
|
433
|
+
language = page['language']
|
434
|
+
return data['sdg_lookup'][language][number]
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
Liquid::Template.register_filter(Jekyll::SDGLookup)
|