jekyll-open-sdg-plugins 1.6.1 → 1.8.0.pre.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +16 -16
  3. data/.github/workflows/test-pull-requests.yml +17 -17
  4. data/.gitignore +6 -6
  5. data/LICENSE +21 -21
  6. data/Makefile +33 -33
  7. data/README.md +7 -7
  8. data/jekyll-open-sdg-plugins.gemspec +18 -18
  9. data/lib/jekyll-open-sdg-plugins/backwards_compatibility.rb +97 -64
  10. data/lib/jekyll-open-sdg-plugins/create_goals.rb +88 -85
  11. data/lib/jekyll-open-sdg-plugins/create_indicators.rb +209 -206
  12. data/lib/jekyll-open-sdg-plugins/create_pages.rb +150 -135
  13. data/lib/jekyll-open-sdg-plugins/fetch_remote_data.rb +188 -188
  14. data/lib/jekyll-open-sdg-plugins/helpers.rb +132 -132
  15. data/lib/jekyll-open-sdg-plugins/metadata_schema_to_config.rb +72 -72
  16. data/lib/jekyll-open-sdg-plugins/schema-indicator-config.json +787 -709
  17. data/lib/jekyll-open-sdg-plugins/schema-site-config.json +1712 -1607
  18. data/lib/jekyll-open-sdg-plugins/sdg_variables.rb +614 -549
  19. data/lib/jekyll-open-sdg-plugins/search_index.rb +102 -102
  20. data/lib/jekyll-open-sdg-plugins/site_configuration.rb +87 -73
  21. data/lib/jekyll-open-sdg-plugins/translate_date.rb +122 -122
  22. data/lib/jekyll-open-sdg-plugins/translate_key.rb +20 -20
  23. data/lib/jekyll-open-sdg-plugins/translate_metadata_field.rb +111 -111
  24. data/lib/jekyll-open-sdg-plugins/validate_indicator_config.rb +52 -52
  25. data/lib/jekyll-open-sdg-plugins/validate_site_config.rb +34 -34
  26. data/lib/jekyll-open-sdg-plugins/version.rb +3 -3
  27. data/lib/jekyll-open-sdg-plugins.rb +18 -18
  28. data/tests/Gemfile +7 -7
  29. data/tests/_config.yml +168 -168
  30. metadata +5 -5
@@ -1,102 +1,102 @@
1
- require "jekyll"
2
- require_relative "helpers"
3
-
4
- module JekyllOpenSdgPlugins
5
- class SearchIndex < Jekyll::Generator
6
- safe true
7
- priority :lowest
8
- # NOTE: This must be executed **after** the sdg_variables.rb file, since it
9
- # relies heavily on the variables created there.
10
-
11
- # Helper function to prepare content for the search index.
12
- def prepare_content(site, content, language)
13
-
14
- # Handle nil content.
15
- if !content
16
- content = ''
17
- end
18
-
19
- # Strip whitespace.
20
- content = content.strip
21
- # Translate if needed.
22
- content = opensdg_translate_key(content, site.data['translations'], language)
23
- # Next compile any Markdown.
24
- converter = site.find_converter_instance(::Jekyll::Converters::Markdown)
25
- content = converter.convert(content)
26
- # Now strip any HTML.
27
- content = content.gsub(/<\/?[^>]*>/, "")
28
- return content
29
- end
30
-
31
- def generate(site)
32
-
33
- # Generate a hash of items to include in the search index.
34
- search_items = {}
35
-
36
- site.collections.keys.each do |collection|
37
- site.collections[collection].docs.each do |doc|
38
- # Do not index configuration forms.
39
- if doc.data.has_key?('layout') && doc.data['layout'] == 'config-builder'
40
- next
41
- end
42
- # We segregate the search items by language.
43
- language = doc.data['language']
44
- if !search_items.has_key? language
45
- search_items[language] = {}
46
- end
47
- # We'll be adding properties to this basic hash.
48
- item = {
49
- # The 'type' can be used on the front-end to describe a search result.
50
- # It is assumed that all the collection names are translated in the
51
- # "general" translation group. Eg: general.indicators, general.goals
52
- 'type' => opensdg_translate_key('general.' + collection, site.data['translations'], language)
53
- }
54
- if collection == 'indicators'
55
- # For indicators, we assign the following properties for each item.
56
- # The URL of the page.
57
- item['url'] = doc.data['indicator']['url']
58
- # For the title, use the indicator name.
59
- indicator_label = opensdg_translate_key('general.indicator', site.data['translations'], language)
60
- item['title'] = indicator_label + ' ' + doc.data['indicator']['number'] + ' - ' + doc.data['indicator']['name']
61
- # For the content, use the 'page_content' field.
62
- item['content'] = prepare_content(site, doc.data['indicator']['page_content'], language)
63
- # For the id field, use the ID number.
64
- item['id'] = doc.data['indicator']['number']
65
- # Also index any additional metadata fields.
66
- if site.config['search_index_extra_fields']
67
- site.config['search_index_extra_fields'].each do |field|
68
- if doc.data['indicator'].has_key? field
69
- item[field] = prepare_content(site, doc.data['indicator'][field], language)
70
- end
71
- end
72
- end
73
- elsif collection == 'goals'
74
- # For goals, we assign the following properties for each item.
75
- # The URL of the page.
76
- item['url'] = doc.data['goal']['url']
77
- # For the title we use the goal name.
78
- goal_label = opensdg_translate_key('general.goal', site.data['translations'], language)
79
- item['title'] = goal_label + ' ' + doc.data['goal']['number'] + ' - ' + doc.data['goal']['name']
80
- # For the content, currently nothing here.
81
- item['content'] = ''
82
- # For the id field, use the ID number.
83
- item['id'] = doc.data['goal']['number']
84
- else
85
- # Otherwise assume it is a normal Jekyll document.
86
- item['url'] = File.join(doc.data['baseurl'], doc.url)
87
- item['title'] = prepare_content(site, doc.data['title'], language)
88
- item['content'] = prepare_content(site, doc.content, language)
89
- item['id'] = ''
90
- end
91
-
92
- # Save this item in the language-specific search index.
93
- search_items[language][item['url']] = item
94
- end
95
- end
96
-
97
- # Stow the data for later use in Jekyll templates.
98
- site.data['search_items'] = search_items
99
-
100
- end
101
- end
102
- end
1
+ require "jekyll"
2
+ require_relative "helpers"
3
+
4
+ module JekyllOpenSdgPlugins
5
+ class SearchIndex < Jekyll::Generator
6
+ safe true
7
+ priority :lowest
8
+ # NOTE: This must be executed **after** the sdg_variables.rb file, since it
9
+ # relies heavily on the variables created there.
10
+
11
+ # Helper function to prepare content for the search index.
12
+ def prepare_content(site, content, language)
13
+
14
+ # Handle nil content.
15
+ if !content
16
+ content = ''
17
+ end
18
+
19
+ # Strip whitespace.
20
+ content = content.strip
21
+ # Translate if needed.
22
+ content = opensdg_translate_key(content, site.data['translations'], language)
23
+ # Next compile any Markdown.
24
+ converter = site.find_converter_instance(::Jekyll::Converters::Markdown)
25
+ content = converter.convert(content)
26
+ # Now strip any HTML.
27
+ content = content.gsub(/<\/?[^>]*>/, "")
28
+ return content
29
+ end
30
+
31
+ def generate(site)
32
+
33
+ # Generate a hash of items to include in the search index.
34
+ search_items = {}
35
+
36
+ site.collections.keys.each do |collection|
37
+ site.collections[collection].docs.each do |doc|
38
+ # Do not index configuration forms.
39
+ if doc.data.has_key?('layout') && doc.data['layout'] == 'config-builder'
40
+ next
41
+ end
42
+ # We segregate the search items by language.
43
+ language = doc.data['language']
44
+ if !search_items.has_key? language
45
+ search_items[language] = {}
46
+ end
47
+ # We'll be adding properties to this basic hash.
48
+ item = {
49
+ # The 'type' can be used on the front-end to describe a search result.
50
+ # It is assumed that all the collection names are translated in the
51
+ # "general" translation group. Eg: general.indicators, general.goals
52
+ 'type' => opensdg_translate_key('general.' + collection, site.data['translations'], language)
53
+ }
54
+ if collection == 'indicators'
55
+ # For indicators, we assign the following properties for each item.
56
+ # The URL of the page.
57
+ item['url'] = doc.data['indicator']['url']
58
+ # For the title, use the indicator name.
59
+ indicator_label = opensdg_translate_key('general.indicator', site.data['translations'], language)
60
+ item['title'] = indicator_label + ' ' + doc.data['indicator']['number'] + ' - ' + doc.data['indicator']['name']
61
+ # For the content, use the 'page_content' field.
62
+ item['content'] = prepare_content(site, doc.data['indicator']['page_content'], language)
63
+ # For the id field, use the ID number.
64
+ item['id'] = doc.data['indicator']['number']
65
+ # Also index any additional metadata fields.
66
+ if site.config['search_index_extra_fields']
67
+ site.config['search_index_extra_fields'].each do |field|
68
+ if doc.data['indicator'].has_key? field
69
+ item[field] = prepare_content(site, doc.data['indicator'][field], language)
70
+ end
71
+ end
72
+ end
73
+ elsif collection == 'goals'
74
+ # For goals, we assign the following properties for each item.
75
+ # The URL of the page.
76
+ item['url'] = doc.data['goal']['url']
77
+ # For the title we use the goal name.
78
+ goal_label = opensdg_translate_key('general.goal', site.data['translations'], language)
79
+ item['title'] = goal_label + ' ' + doc.data['goal']['number'] + ' - ' + doc.data['goal']['name']
80
+ # For the content, currently nothing here.
81
+ item['content'] = ''
82
+ # For the id field, use the ID number.
83
+ item['id'] = doc.data['goal']['number']
84
+ else
85
+ # Otherwise assume it is a normal Jekyll document.
86
+ item['url'] = File.join(doc.data['baseurl'], doc.url)
87
+ item['title'] = prepare_content(site, doc.data['title'], language)
88
+ item['content'] = prepare_content(site, doc.content, language)
89
+ item['id'] = ''
90
+ end
91
+
92
+ # Save this item in the language-specific search index.
93
+ search_items[language][item['url']] = item
94
+ end
95
+ end
96
+
97
+ # Stow the data for later use in Jekyll templates.
98
+ site.data['search_items'] = search_items
99
+
100
+ end
101
+ end
102
+ end
@@ -1,73 +1,87 @@
1
- require "jekyll"
2
- require_relative "helpers"
3
-
4
- module JekyllOpenSdgPlugins
5
- class SiteConfiguration < Jekyll::Generator
6
- safe true
7
- priority :highest
8
-
9
- # This looks for site configuration in the data directory, and if found, copies it to
10
- # the "site" object, as if it had been in _config.yml. It looks in "site_config" for
11
- # configuration to move. In addition, if jekyll.environment or site.environment is
12
- # specifically "production", then it also moves data from "site_config_prod".
13
- #
14
- # This allows you to keep all OpenSDG-specific config out of _config.yml, and instead
15
- # place it in site_config and/or site_config_prod in your data directory.
16
- def generate(site)
17
-
18
- if site.data.has_key?('site_config')
19
- hash_to_hash(site.data['site_config'], site.config)
20
- end
21
-
22
- production = false
23
- if Jekyll.env == 'production'
24
- production = true
25
- end
26
- if site.config.has_key?('environment') && site.config['environment'] == 'production'
27
- production = true
28
- end
29
-
30
- if production && site.data.has_key?('site_config_prod')
31
- hash_to_hash(site.data['site_config_prod'], site.config)
32
- end
33
-
34
- # Look for environment variables for some settings.
35
- env_settings = [
36
- 'REPOSITORY_URL_SITE',
37
- ]
38
- env_settings.each do |setting|
39
- if ENV.has_key?(setting)
40
- site.config[setting.downcase] = ENV[setting]
41
- end
42
- end
43
-
44
- # Hardcode some variables.
45
- site.config['disaggregation_status'] = {}
46
- site.config['disaggregation_status']['status_types'] = [
47
- {
48
- 'value' => 'complete',
49
- 'label' => 'status.disaggregation_status_complete',
50
- },
51
- {
52
- 'value' => 'inprogress',
53
- 'label' => 'status.disaggregation_status_inprogress',
54
- },
55
- {
56
- 'value' => 'notstarted',
57
- 'label' => 'status.disaggregation_status_notstarted',
58
- },
59
- {
60
- 'value' => 'notapplicable',
61
- 'label' => 'status.disaggregation_status_notapplicable',
62
- },
63
- ]
64
- end
65
-
66
- # Copy properties from a hash onto another hash.
67
- def hash_to_hash(hash_from, hash_to)
68
- hash_from.each do |key, value|
69
- hash_to[key] = value
70
- end
71
- end
72
- end
73
- end
1
+ require "jekyll"
2
+ require_relative "helpers"
3
+
4
+ module JekyllOpenSdgPlugins
5
+ class SiteConfiguration < Jekyll::Generator
6
+ safe true
7
+ priority :highest
8
+
9
+ # This looks for site configuration in the data directory, and if found, copies it to
10
+ # the "site" object, as if it had been in _config.yml. It looks in "site_config" for
11
+ # configuration to move. In addition, if jekyll.environment or site.environment is
12
+ # specifically "production", then it also moves data from "site_config_prod".
13
+ #
14
+ # This allows you to keep all OpenSDG-specific config out of _config.yml, and instead
15
+ # place it in site_config and/or site_config_prod in your data directory.
16
+ def generate(site)
17
+
18
+ if site.data.has_key?('site_config')
19
+ hash_to_hash(site.data['site_config'], site.config)
20
+ end
21
+
22
+ production = false
23
+ if Jekyll.env == 'production'
24
+ production = true
25
+ end
26
+ if site.config.has_key?('environment') && site.config['environment'] == 'production'
27
+ production = true
28
+ end
29
+
30
+ if production && site.data.has_key?('site_config_prod')
31
+ hash_to_hash(site.data['site_config_prod'], site.config)
32
+ end
33
+
34
+ # Look for environment variables for some settings.
35
+ env_settings = [
36
+ 'REPOSITORY_URL_SITE',
37
+ ]
38
+ env_settings.each do |setting|
39
+ if ENV.has_key?(setting)
40
+ site.config[setting.downcase] = ENV[setting]
41
+ end
42
+ end
43
+
44
+ # Hardcode some variables.
45
+ site.config['disaggregation_status'] = {}
46
+ site.config['disaggregation_status']['status_types'] = [
47
+ {
48
+ 'value' => 'complete',
49
+ 'label' => 'status.disaggregation_status_complete',
50
+ },
51
+ {
52
+ 'value' => 'inprogress',
53
+ 'label' => 'status.disaggregation_status_inprogress',
54
+ },
55
+ {
56
+ 'value' => 'notstarted',
57
+ 'label' => 'status.disaggregation_status_notstarted',
58
+ },
59
+ {
60
+ 'value' => 'notapplicable',
61
+ 'label' => 'status.disaggregation_status_notapplicable',
62
+ },
63
+ ]
64
+
65
+ # Provide some defaults.
66
+ if !site.config.has_key?('time_series_attributes') or site.config['time_series_attributes'].length == 0
67
+ site.config['time_series_attributes'] = [
68
+ {
69
+ 'field' => 'COMMENT_TS',
70
+ 'label' => 'indicator.footnote',
71
+ },
72
+ {
73
+ 'field' => 'DATA_LAST_UPDATE',
74
+ 'label' => 'metadata_fields.national_data_update_url'
75
+ },
76
+ ]
77
+ end
78
+ end
79
+
80
+ # Copy properties from a hash onto another hash.
81
+ def hash_to_hash(hash_from, hash_to)
82
+ hash_from.each do |key, value|
83
+ hash_to[key] = value
84
+ end
85
+ end
86
+ end
87
+ end
@@ -1,122 +1,122 @@
1
- require "jekyll"
2
- require_relative "helpers"
3
-
4
- module Jekyll
5
- module TranslateDate
6
-
7
- # Takes a raw Jekyll date and returns a translated string according to the
8
- # language of the current page and a date format given.
9
- def t_date(date, format_type)
10
-
11
- original = date
12
-
13
- # Determine the language of the current page.
14
- config = @context.registers[:site].config
15
- translations = @context.registers[:site].data['translations']
16
- language = @context.environments.first['page']['language']
17
-
18
- # Try to find the specified date format in the site config. It needs to be
19
- # something like this, assuming the "format_type" param is "standard":
20
- #
21
- # date_formats:
22
- # - type: standard
23
- # language: en
24
- # format: "%b %d, %Y"
25
- # - type: standard
26
- # language: es
27
- # format: "%d de %b de %Y"
28
- #
29
- # However the following deprecated structure is also supported:
30
- #
31
- # date_formats:
32
- # standard:
33
- # en: "%b %d, %Y"
34
- # es: "%d de %b de %Y"
35
- # etc...
36
- date_format = '%b %d, %Y'
37
- if config.has_key?('date_formats')
38
-
39
- # @deprecated start
40
- # In a deprecated form of date_formats, it was a nested hash keyed first
41
- # by the format type and then by the language.
42
- if config['date_formats'].is_a?(Hash) && config['date_formats'].has_key?(format_type)
43
- if config['date_formats'][format_type].has_key?(language)
44
- date_format = config['date_formats'][format_type][language]
45
- end
46
- end
47
- # @deprecated end
48
-
49
- # In the current form of data_formats, it is an array of hashes, each
50
- # containing "type", "language", and "format" keys.
51
- if config['date_formats'].is_a?(Array)
52
- date_format_config = config['date_formats'].find {|d| d['type'] == format_type && d['language'] == language }
53
- if date_format_config
54
- date_format = date_format_config['format']
55
- end
56
- end
57
-
58
- end
59
-
60
- # Support timestamps.
61
- if date.is_a? Integer
62
- # Convert milliseconds to seconds if necessary.
63
- if date > 9000000000
64
- date = date / 1000
65
- end
66
- begin
67
- date = Time.at(date).utc
68
- rescue => err
69
- return original
70
- end
71
- end
72
-
73
- # Support other strings.
74
- if date.is_a? String
75
- begin
76
- date = Time.parse(date).utc
77
- rescue => err
78
- return original
79
- end
80
- end
81
-
82
- # Avoid nil errors.
83
- unless date.is_a? Time
84
- return original
85
- end
86
-
87
- # Convert the date into English.
88
- english = date.strftime(date_format)
89
-
90
- # Now "tokenize" that date by spaces.
91
- parts = english.split(' ')
92
-
93
- translated_parts = []
94
- parts.each do |part|
95
- # Special case: see if we need to remove a comma from the end.
96
- removed_comma = false
97
- if part.end_with? ','
98
- part = part.delete_suffix(',')
99
- removed_comma = true
100
- end
101
- # Look for a translation in the "calendar" translation group.
102
- key = 'calendar.' + part
103
- translated_part = opensdg_translate_key(key, translations, language)
104
- # If it changed from the key, that means it was a working key.
105
- if key != translated_part
106
- part = translated_part
107
- end
108
-
109
- # Add back the comma if needed.
110
- if removed_comma
111
- part = part + ','
112
- end
113
-
114
- translated_parts.push(part)
115
- end
116
-
117
- return translated_parts.join(' ')
118
- end
119
- end
120
- end
121
-
122
- Liquid::Template.register_filter(Jekyll::TranslateDate)
1
+ require "jekyll"
2
+ require_relative "helpers"
3
+
4
+ module Jekyll
5
+ module TranslateDate
6
+
7
+ # Takes a raw Jekyll date and returns a translated string according to the
8
+ # language of the current page and a date format given.
9
+ def t_date(date, format_type)
10
+
11
+ original = date
12
+
13
+ # Determine the language of the current page.
14
+ config = @context.registers[:site].config
15
+ translations = @context.registers[:site].data['translations']
16
+ language = @context.environments.first['page']['language']
17
+
18
+ # Try to find the specified date format in the site config. It needs to be
19
+ # something like this, assuming the "format_type" param is "standard":
20
+ #
21
+ # date_formats:
22
+ # - type: standard
23
+ # language: en
24
+ # format: "%b %d, %Y"
25
+ # - type: standard
26
+ # language: es
27
+ # format: "%d de %b de %Y"
28
+ #
29
+ # However the following deprecated structure is also supported:
30
+ #
31
+ # date_formats:
32
+ # standard:
33
+ # en: "%b %d, %Y"
34
+ # es: "%d de %b de %Y"
35
+ # etc...
36
+ date_format = '%b %d, %Y'
37
+ if config.has_key?('date_formats')
38
+
39
+ # @deprecated start
40
+ # In a deprecated form of date_formats, it was a nested hash keyed first
41
+ # by the format type and then by the language.
42
+ if config['date_formats'].is_a?(Hash) && config['date_formats'].has_key?(format_type)
43
+ if config['date_formats'][format_type].has_key?(language)
44
+ date_format = config['date_formats'][format_type][language]
45
+ end
46
+ end
47
+ # @deprecated end
48
+
49
+ # In the current form of data_formats, it is an array of hashes, each
50
+ # containing "type", "language", and "format" keys.
51
+ if config['date_formats'].is_a?(Array)
52
+ date_format_config = config['date_formats'].find {|d| d['type'] == format_type && d['language'] == language }
53
+ if date_format_config
54
+ date_format = date_format_config['format']
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ # Support timestamps.
61
+ if date.is_a? Integer
62
+ # Convert milliseconds to seconds if necessary.
63
+ if date > 9000000000
64
+ date = date / 1000
65
+ end
66
+ begin
67
+ date = Time.at(date).utc
68
+ rescue => err
69
+ return original
70
+ end
71
+ end
72
+
73
+ # Support other strings.
74
+ if date.is_a? String
75
+ begin
76
+ date = Time.parse(date).utc
77
+ rescue => err
78
+ return original
79
+ end
80
+ end
81
+
82
+ # Avoid nil errors.
83
+ unless date.is_a? Time
84
+ return original
85
+ end
86
+
87
+ # Convert the date into English.
88
+ english = date.strftime(date_format)
89
+
90
+ # Now "tokenize" that date by spaces.
91
+ parts = english.split(' ')
92
+
93
+ translated_parts = []
94
+ parts.each do |part|
95
+ # Special case: see if we need to remove a comma from the end.
96
+ removed_comma = false
97
+ if part.end_with? ','
98
+ part = part.delete_suffix(',')
99
+ removed_comma = true
100
+ end
101
+ # Look for a translation in the "calendar" translation group.
102
+ key = 'calendar.' + part
103
+ translated_part = opensdg_translate_key(key, translations, language)
104
+ # If it changed from the key, that means it was a working key.
105
+ if key != translated_part
106
+ part = translated_part
107
+ end
108
+
109
+ # Add back the comma if needed.
110
+ if removed_comma
111
+ part = part + ','
112
+ end
113
+
114
+ translated_parts.push(part)
115
+ end
116
+
117
+ return translated_parts.join(' ')
118
+ end
119
+ end
120
+ end
121
+
122
+ Liquid::Template.register_filter(Jekyll::TranslateDate)
@@ -1,20 +1,20 @@
1
- require "jekyll"
2
- require_relative "helpers"
3
-
4
- module Jekyll
5
- module TranslateKey
6
- # Takes a translation key and returns a translated string according to the
7
- # language of the current page. Or if none is found, returns the original
8
- # key.
9
- def t(key)
10
-
11
- # Determine the language of the current page.
12
- translations = @context.registers[:site].data['translations']
13
- language = @context.environments.first["page"]['language']
14
-
15
- return opensdg_translate_key(key, translations, language)
16
- end
17
- end
18
- end
19
-
20
- Liquid::Template.register_filter(Jekyll::TranslateKey)
1
+ require "jekyll"
2
+ require_relative "helpers"
3
+
4
+ module Jekyll
5
+ module TranslateKey
6
+ # Takes a translation key and returns a translated string according to the
7
+ # language of the current page. Or if none is found, returns the original
8
+ # key.
9
+ def t(key)
10
+
11
+ # Determine the language of the current page.
12
+ translations = @context.registers[:site].data['translations']
13
+ language = @context.environments.first["page"]['language']
14
+
15
+ return opensdg_translate_key(key, translations, language)
16
+ end
17
+ end
18
+ end
19
+
20
+ Liquid::Template.register_filter(Jekyll::TranslateKey)