jekyll-open-sdg-plugins 1.0.0.rc21 → 1.2.0.pre.beta1

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.
@@ -1,410 +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
- # Make any goal/target/indicator number suitable for use in sorting.
22
- def get_sort_order(number)
23
- if number.is_a? Numeric
24
- number = number.to_s
25
- end
26
- sort_order = ''
27
- parts = number.split('.')
28
- parts.each do |part|
29
- if part.length == 1
30
- part = '0' + part
31
- end
32
- sort_order += part
33
- end
34
- sort_order
35
- end
36
-
37
- # The Jekyll baseurl is user-configured, and can be inconsistent. This
38
- # ensure it is consistent in whether it starts/ends with a slash.
39
- def normalize_baseurl(baseurl)
40
- if baseurl == ''
41
- baseurl = '/'
42
- end
43
- if !baseurl.start_with? '/'
44
- baseurl = '/' + baseurl
45
- end
46
- if !baseurl.end_with? '/'
47
- baseurl = baseurl + '/'
48
- end
49
- baseurl
50
- end
51
-
52
- # Compute a URL for an item, given it's number.
53
- def get_url(baseurl, language, number, languages, languages_public)
54
-
55
- baseurl = normalize_baseurl(baseurl)
56
-
57
- default_language = languages[0]
58
- language_public = language
59
- if languages_public && languages_public[language]
60
- language_public = languages_public[language]
61
- end
62
- if default_language != language
63
- baseurl += language_public + '/'
64
- end
65
-
66
- number = number.gsub('.', '-')
67
- baseurl + number
68
- end
69
-
70
- # Get a Hash of all the URLs based on one particular one.
71
- def get_all_urls(url, language, languages, languages_public, baseurl)
72
-
73
- baseurl = normalize_baseurl(baseurl)
74
-
75
- language_public = language
76
- if languages_public && languages_public[language]
77
- language_public = languages_public[language]
78
- end
79
-
80
- # First figure out the language-free URL.
81
- default_language = languages[0]
82
- if language == default_language
83
- url_without_language = url
84
- else
85
- url_without_language = url.gsub('/' + language_public + '/', '/')
86
- end
87
-
88
- urls = {
89
- language => url
90
- }
91
- if language != default_language
92
- default_language_url = baseurl + url_without_language
93
- # Fix potential double-slash.
94
- default_language_url = default_language_url.gsub('//', '/')
95
- urls[default_language] = default_language_url
96
- end
97
- languages.each do |other_language|
98
- if other_language == language
99
- next
100
- end
101
- if other_language == default_language
102
- next
103
- end
104
- other_language_public = other_language
105
- if languages_public && languages_public[other_language]
106
- other_language_public = languages_public[other_language]
107
- end
108
- urls[other_language] = baseurl + other_language_public + url_without_language
109
- end
110
- urls
111
- end
112
-
113
- # Compute a URL for tha goal image, given it's number.
114
- def get_goal_image(goal_image_base, language, number)
115
- goal_image_base + '/' + language + '/' + number + '.png'
116
- end
117
-
118
- # This creates variables for use in Liquid templates under "page".
119
- # We'll create lists of goals, targets, and indicators. These will be put
120
- # on the page object. Eg: page.goals. In order to generate these lists
121
- # we will make use of the metadata. Each item in the list will be a hash
122
- # containing these keys:
123
- # - name (translated)
124
- # - number (the "id" or number, eg: 1, 1.2, 1.2.1, etc.)
125
- # - slug (version of 'number' but with dashes instead of dots)
126
- # - sort (for the purposes of sorting the items, if needed)
127
- # - global (a Hash containing any equivalent global metadata)
128
- # The goal hashes contain additional keys:
129
- # - short (the translated short version of the name)
130
- # - icon (path to the translated icon)
131
- # - url (path to the goal page)
132
- # The target hashes contain additional keys:
133
- # - goal_number (the goal number for this target)
134
- # The indicator hashes contain additional keys:
135
- # - url (path to the indicator page)
136
- # - goal_number (the goal number for this indicator)
137
- # - target_number (the target number for this indicator)
138
- # - [all metadata fields from the indicator]
139
- # The lists are:
140
- # - goals
141
- # - targets
142
- # - indicators
143
- # Additionally, on indicator pages themselves, there are variables for
144
- # the current goal/target/indicator:
145
- # - goal
146
- # - target
147
- # - indicator
148
- # Similarly, on goal pages themselves, there are variables for the current
149
- # goal:
150
- # - goal
151
- def generate(site)
152
-
153
- # Some general variables needed below.
154
- translations = site.data['translations']
155
- languages = site.config['languages']
156
- languages_public = site.config['languages_public']
157
- default_language = languages[0]
158
- baseurl = site.config['baseurl']
159
- goal_image_base = site.config['goal_image_base']
160
-
161
- # These keys are flagged as "protected" here so that we can make sure that
162
- # country-specific metadata doesn't use any of these fields.
163
- protected_keys = ['goals', 'goal', 'targets', 'target', 'indicators',
164
- 'indicator', 'language', 'name', 'number', 'sort', 'global', 'url',
165
- 'goal_number', 'target_number'
166
- ]
167
-
168
- # Figure out from our translations the global indicator numbers.
169
- global_inids = translations[default_language]['global_indicators'].keys
170
- global_inids = global_inids.select { |x| x.end_with? '-title' }
171
- global_inids = global_inids.map { |x| x.gsub('-title', '').gsub('-', '.') }
172
-
173
- # For available indicators, we simply map the "indicators" collection.
174
- available_inids = site.collections['indicators'].docs.select { |x| x.data['language'] == default_language }
175
- available_inids = available_inids.map { |x| x.data['indicator'] }
176
- available_indicators = {}
177
- available_targets = {}
178
- available_goals = {}
179
-
180
- # Some throwaway variables to keep track of what has been added.
181
- already_added = {}
182
-
183
- # Set up some empty hashes, per language.
184
- languages.each do |language|
185
- available_goals[language] = []
186
- available_targets[language] = []
187
- available_indicators[language] = []
188
- already_added[language] = []
189
- end
190
-
191
- # Populate the hashes.
192
- available_inids.each do |indicator_number|
193
- goal_number = get_goal_number(indicator_number)
194
- target_number = get_target_number(indicator_number)
195
- is_global_indicator = global_inids.index(indicator_number) != nil
196
- # To get the name of global stuff, we can use predicable translation
197
- # keys from the SDG Translations project. Eg: global_goals.1-title
198
- goal_translation_key = 'global_goals.' + goal_number
199
- target_translation_key = 'global_targets.' + target_number.gsub('.', '-')
200
- indicator_translation_key = 'global_indicators.' + indicator_number.gsub('.', '-')
201
-
202
- languages.each do |language|
203
- global_goal = {
204
- 'name' => opensdg_translate_key(goal_translation_key + '-title', translations, language),
205
- # TODO: More global metadata about goals?
206
- }
207
- global_target = {
208
- 'name' => opensdg_translate_key(target_translation_key + '-title', translations, language),
209
- # TODO: More global metadata about targets?
210
- }
211
- global_indicator = {}
212
- if is_global_indicator
213
- global_indicator = {
214
- 'name' => opensdg_translate_key(indicator_translation_key + '-title', translations, language),
215
- # TODO: More global metadata about indicators?
216
- }
217
- end
218
-
219
- # We have to get the metadata for the indicator/language.
220
- meta = {}
221
- # Currently the meta keys are dash-delimited. This is a little
222
- # arbitrary (it's because they came from filenames) and could maybe
223
- # be changed eventually to dot-delimited for consistency.
224
- meta_key = indicator_number.gsub('.', '-')
225
- # The location of the metadata is different depending on whether we are
226
- # using "translated_builds" or not.
227
- if opensdg_translated_builds(site)
228
- meta = site.data[language]['meta'][meta_key]
229
- else
230
- meta = site.data['meta'][meta_key]
231
- end
232
-
233
- # Set the goal for this language, once only.
234
- if already_added[language].index(goal_number) == nil
235
- already_added[language].push(goal_number)
236
- available_goal = {
237
- 'number' => goal_number,
238
- 'slug' => goal_number.gsub('.', '-'),
239
- 'name' => opensdg_translate_key(goal_translation_key + '-title', translations, language),
240
- 'short' => opensdg_translate_key(goal_translation_key + '-short', translations, language),
241
- 'url' => get_url(baseurl, language, goal_number, languages, languages_public),
242
- 'icon' => get_goal_image(goal_image_base, language, goal_number),
243
- 'sort' => get_sort_order(goal_number),
244
- 'global' => global_goal,
245
- }
246
- available_goals[language].push(available_goal)
247
- end
248
- # Set the target for this language, once only.
249
- if already_added[language].index(target_number) == nil
250
- already_added[language].push(target_number)
251
- available_target = {
252
- 'number' => target_number,
253
- 'slug' => target_number.gsub('.', '-'),
254
- 'name' => opensdg_translate_key(target_translation_key + '-title', translations, language),
255
- 'sort' => get_sort_order(target_number),
256
- 'goal_number' => goal_number,
257
- 'global' => global_target,
258
- }
259
- available_targets[language].push(available_target)
260
- end
261
- # Set the indicator for this language. Unfortunately we are currently
262
- # using two possible fields for the indicator name:
263
- # - indicator_name
264
- # - indicator_name_national
265
- # TODO: Eventually standardize around 'indicator_name' and drop support
266
- # for 'indicator_name_national'.
267
- indicator_name = ''
268
- if meta.has_key? 'indicator_name_national'
269
- indicator_name = meta['indicator_name_national']
270
- else
271
- indicator_name = meta['indicator_name']
272
- end
273
- available_indicator = {
274
- 'number' => indicator_number,
275
- 'slug' => indicator_number.gsub('.', '-'),
276
- 'name' => opensdg_translate_key(indicator_name, translations, language),
277
- 'url' => get_url(baseurl, language, indicator_number, languages, languages_public),
278
- 'sort' => get_sort_order(indicator_number),
279
- 'goal_number' => goal_number,
280
- 'target_number' => target_number,
281
- 'global' => global_indicator,
282
- }
283
- # Translate and add any metadata.
284
- meta.each do |key, value|
285
- if !protected_keys.include? key
286
- available_indicator[key] = opensdg_translate_key(value, translations, language)
287
- end
288
- end
289
- available_indicators[language].push(available_indicator)
290
- end
291
- end
292
-
293
- # Sort all the items.
294
- languages.each do |lang|
295
- available_goals[lang] = available_goals[lang].sort_by { |x| x['sort'] }
296
- available_targets[lang] = available_targets[lang].sort_by { |x| x['sort'] }
297
- available_indicators[lang] = available_indicators[lang].sort_by { |x| x['sort'] }
298
- end
299
-
300
- # Next set the stuff on each doc in certain collections, according
301
- # to the doc's language. We'll be putting the global stuff on every
302
- # page, goal, and indicator across the site. This may be a bit memory-
303
- # intensive during the Jekyll build, but it is nice to have it available
304
- # for consistency.
305
- site.collections.keys.each do |collection|
306
- site.collections[collection].docs.each do |doc|
307
- # Ensure it has a language.
308
- if !doc.data.has_key? 'language'
309
- doc.data['language'] = default_language
310
- end
311
- language = doc.data['language']
312
- # Set these on the page object.
313
- doc.data['goals'] = available_goals[language]
314
- doc.data['targets'] = available_targets[language]
315
- doc.data['indicators'] = available_indicators[language]
316
- doc.data['baseurl'] = get_url(baseurl, language, '', languages, languages_public)
317
- doc.data['url_by_language'] = get_all_urls(doc.url, language, languages, languages_public, baseurl)
318
- doc.data['t'] = site.data['translations'][language]
319
-
320
- # Set the remote_data_prefix for this page.
321
- if site.config.has_key? 'remote_data_prefix'
322
- doc.data['remote_data_prefix'] = site.config['remote_data_prefix']
323
- elsif site.config.has_key? 'local_data_folder'
324
- doc.data['remote_data_prefix'] = normalize_baseurl(baseurl)
325
- end
326
- if opensdg_translated_builds(site)
327
- doc.data['remote_data_prefix'] = File.join(doc.data['remote_data_prefix'], language)
328
- end
329
-
330
- if collection == 'indicators'
331
- # For indicators we also set the current indicator/target/goal.
332
- if doc.data.has_key? 'indicator_number'
333
- indicator_number = doc.data['indicator_number']
334
- elsif doc.data.has_key? 'indicator'
335
- # Backwards compatibility.
336
- indicator_number = doc.data['indicator']
337
- else
338
- raise "Error: An indicator does not have 'indicator_number' property."
339
- end
340
- # Force the indicator number to be a string.
341
- if indicator_number.is_a? Numeric
342
- indicator_number = indicator_number.to_s
343
- end
344
- goal_number = get_goal_number(indicator_number)
345
- target_number = get_target_number(indicator_number)
346
- doc.data['goal'] = available_goals[language].find {|x| x['number'] == goal_number}
347
- doc.data['target'] = available_targets[language].find {|x| x['number'] == target_number}
348
- doc.data['indicator'] = available_indicators[language].find {|x| x['number'] == indicator_number}
349
- elsif collection == 'goals'
350
- # For goals we also set the current goal.
351
- if doc.data.has_key? 'goal_number'
352
- goal_number = doc.data['goal_number']
353
- elsif doc.data.has_key? 'sdg_goal'
354
- # Backwards compatibility.
355
- goal_number = doc.data['sdg_goal']
356
- else
357
- raise "Error: A goal does not have 'goal_number' property."
358
- end
359
- # Force the goal number to be a string.
360
- if goal_number.is_a? Numeric
361
- goal_number = goal_number.to_s
362
- end
363
- doc.data['goal'] = available_goals[language].find {|x| x['number'] == goal_number}
364
- end
365
- end
366
- end
367
-
368
- # Finally let's set all these on the site object so that they can be
369
- # easily looked up later.
370
- lookup = {}
371
- available_goals.each do |language, items|
372
- lookup[language] = {}
373
- items.each do |item|
374
- number = item['number']
375
- lookup[language][number] = item
376
- end
377
- end
378
- available_targets.each do |language, items|
379
- items.each do |item|
380
- number = item['number']
381
- lookup[language][number] = item
382
- end
383
- end
384
- available_indicators.each do |language, items|
385
- items.each do |item|
386
- number = item['number']
387
- lookup[language][number] = item
388
- end
389
- end
390
- site.data['sdg_lookup'] = lookup
391
-
392
- end
393
- end
394
- end
395
-
396
- module Jekyll
397
- module SDGLookup
398
- # This provides a "sdg_lookup" filter that takes an id and returns a hash
399
- # representation of a goal, target, or indicator.
400
- def sdg_lookup(number)
401
- number = number.gsub('-', '.')
402
- data = @context.registers[:site].data
403
- page = @context.environments.first['page']
404
- language = page['language']
405
- return data['sdg_lookup'][language][number]
406
- end
407
- end
408
- end
409
-
410
- Liquid::Template.register_filter(Jekyll::SDGLookup)
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' && opensdg_is_path_remote(site.config['remote_data_prefix'])
351
+ doc.data['remote_data_prefix'] = site.config['remote_data_prefix']
352
+ else
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)