jekyll-open-sdg-plugins 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,99 +1,112 @@
1
- require "jekyll"
2
-
3
- module JekyllOpenSdgPlugins
4
- class CreatePages < Jekyll::Generator
5
- safe true
6
- priority :normal
7
-
8
- def generate(site)
9
- # If site.create_pages is set, create the 4 required pages. These include:
10
- # - the home page: /
11
- # - the indicators json page: /indicators.json
12
- # - the search results page: /search
13
- # - the reporting status page: /reporting-status
14
- #
15
- # These can be overridden though, with a create_pages.pages setting in
16
- # _config.yml, like so:
17
- #
18
- # create_pages:
19
- # pages:
20
- # - folder: ''
21
- # layout: frontpage
22
- # - filename: my-json-file.json
23
- # folder: my-subfolder
24
- # layout: indicator-json
25
- #
26
- # Note the optional "filename" setting for when the page needs a specific
27
- # filename (as opposed to being "index.html" inside a named folder).
28
- #
29
- # To use the default 4 pages, simply put:
30
- #
31
- # create_pages: true
32
- if site.config['languages'] and site.config['create_pages']
33
-
34
- default_pages = [
35
- {
36
- 'folder' => '/',
37
- 'layout' => 'frontpage'
38
- },
39
- {
40
- 'folder' => '/reporting-status',
41
- 'layout' => 'reportingstatus'
42
- },
43
- {
44
- 'filename' => 'indicators.json',
45
- 'folder' => '/',
46
- 'layout' => 'indicator-json',
47
- },
48
- {
49
- 'folder' => '/search',
50
- 'layout' => 'search'
51
- }
52
- ]
53
- pages = default_pages
54
- if site.config['create_pages'].is_a?(Hash) and site.config['create_pages'].key?('pages')
55
- pages = site.config['create_pages']['pages']
56
- end
57
-
58
- # See if we need to "map" any language codes.
59
- languages_public = Hash.new
60
- if site.config['languages_public']
61
- languages_public = site.config['languages_public']
62
- end
63
-
64
- # Loop through the languages.
65
- site.config['languages'].each_with_index do |language, index|
66
- # Get the "public language" (for URLs) which may be different.
67
- language_public = language
68
- if languages_public[language]
69
- language_public = languages_public[language]
70
- end
71
- # Loop through the pages.
72
- pages.each do |page|
73
- # Add the language subfolder for all except the default (first) language.
74
- dir = index == 0 ? page['folder'] : File.join(language_public, page['folder'])
75
- # Create the page.
76
- site.collections['pages'].docs << OpenSdgPage.new(site, site.source, dir, page, language)
77
- end
78
- end
79
- end
80
- end
81
- end
82
-
83
- # A Page subclass used in the `CreatePages` class.
84
- class OpenSdgPage < Jekyll::Page
85
- def initialize(site, base, dir, page, language)
86
- @site = site
87
- @base = base
88
-
89
- index_files = (!page.key?('filename') or page['filename'] == 'index.html')
90
- @dir = index_files ? File.join(dir, '/') : dir
91
- @name = index_files ? 'index.html' : page['filename']
92
-
93
- self.process(@name)
94
- self.data = {}
95
- self.data['layout'] = page['layout']
96
- self.data['language'] = language
97
- end
98
- end
99
- end
1
+ require "jekyll"
2
+ require_relative "helpers"
3
+
4
+ module JekyllOpenSdgPlugins
5
+ class CreatePages < Jekyll::Generator
6
+ safe true
7
+ priority :normal
8
+
9
+ def generate(site)
10
+ # If site.create_pages is set, create the 4 required pages. These include:
11
+ # - the home page: /
12
+ # - the indicators json page: /indicators.json
13
+ # - the search results page: /search
14
+ # - the reporting status page: /reporting-status
15
+ #
16
+ # These can be overridden though, with a create_pages.pages setting in
17
+ # _config.yml, like so:
18
+ #
19
+ # create_pages:
20
+ # pages:
21
+ # - folder: ''
22
+ # layout: frontpage
23
+ # - filename: my-json-file.json
24
+ # folder: my-subfolder
25
+ # layout: indicator-json
26
+ #
27
+ # Note the optional "filename" setting for when the page needs a specific
28
+ # filename (as opposed to being "index.html" inside a named folder).
29
+ #
30
+ # To use the default 4 pages, simply put:
31
+ #
32
+ # create_pages: true
33
+ if site.config['languages'] and site.config['create_pages']
34
+
35
+ default_pages = [
36
+ {
37
+ 'folder' => '/',
38
+ 'layout' => 'frontpage'
39
+ },
40
+ {
41
+ 'folder' => '/reporting-status',
42
+ 'layout' => 'reportingstatus',
43
+ 'title' => 'status.reporting_status',
44
+ },
45
+ {
46
+ 'filename' => 'indicators.json',
47
+ 'folder' => '/',
48
+ 'layout' => 'indicator-json',
49
+ },
50
+ {
51
+ 'folder' => '/search',
52
+ 'layout' => 'search',
53
+ 'title' => 'search.search',
54
+ }
55
+ ]
56
+ pages = default_pages
57
+ if site.config['create_pages'].is_a?(Hash) and site.config['create_pages'].key?('pages')
58
+ # Backwards compatability to support the deprecated "pages" key.
59
+ pages = site.config['create_pages']['pages']
60
+ elsif site.config['create_pages'].is_a?(Array)
61
+ pages = site.config['create_pages']
62
+ end
63
+
64
+ # See if we need to "map" any language codes.
65
+ languages_public = Hash.new
66
+ if site.config['languages_public']
67
+ languages_public = opensdg_languages_public(site)
68
+ end
69
+
70
+ # Loop through the languages.
71
+ site.config['languages'].each_with_index do |language, index|
72
+ # Get the "public language" (for URLs) which may be different.
73
+ language_public = language
74
+ if languages_public[language]
75
+ language_public = languages_public[language]
76
+ end
77
+ # Loop through the pages.
78
+ pages.each do |page|
79
+ # Add the language subfolder for all except the default (first) language.
80
+ dir = index == 0 ? page['folder'] : File.join(language_public, page['folder'])
81
+ # Create the page.
82
+ site.collections['pages'].docs << OpenSdgPage.new(site, site.source, dir, page, language)
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ # A Page subclass used in the `CreatePages` class.
90
+ class OpenSdgPage < Jekyll::Page
91
+ def initialize(site, base, dir, page, language)
92
+ @site = site
93
+ @base = base
94
+
95
+ index_files = (!page.key?('filename') or page['filename'] == 'index.html')
96
+ @dir = index_files ? File.join(dir, '/') : dir
97
+ @name = index_files ? 'index.html' : page['filename']
98
+
99
+ self.process(@name)
100
+ self.data = {}
101
+ self.data['language'] = language
102
+
103
+ # Add anything else besides "folder" and "filename". This will catch
104
+ # things like "layout" and "title", and anything else.
105
+ page.each do |key, value|
106
+ if key != 'folder' && key != 'filename'
107
+ self.data[key] = value
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -1,167 +1,167 @@
1
- require "jekyll"
2
- require 'json'
3
- require 'deep_merge'
4
- require 'open-uri'
5
- require_relative "helpers"
6
-
7
- module JekyllOpenSdgPlugins
8
- class FetchRemoteData < Jekyll::Generator
9
- safe true
10
- priority :highest
11
-
12
- # Fix a Unix path in case we are on Windows.
13
- def fix_path(path)
14
- path_parts = path.split('/')
15
- return path_parts.join(File::SEPARATOR)
16
- end
17
-
18
- # Our hardcoded list of pieces of the build that we expect.
19
- def get_endpoints()
20
- return {
21
- 'meta' => 'meta/all.json',
22
- 'headlines' => 'headline/all.json',
23
- 'schema' => 'meta/schema.json',
24
- 'reporting' => 'stats/reporting.json',
25
- 'translations' => 'translations/translations.json',
26
- 'zip' => 'zip/all_indicators.json'
27
- }
28
- end
29
-
30
- # Is this path a remote path?
31
- def is_path_remote(path)
32
- return path.start_with?('http')
33
- end
34
-
35
- # Get a build from a local folder on disk or a remote URL on the Internet.
36
- def fetch_build(path)
37
-
38
- is_remote = is_path_remote(path)
39
- build = {}
40
- get_endpoints().each do |key, value|
41
- endpoint = is_remote ? path + '/' + value : File.join(path, fix_path(value))
42
-
43
- begin
44
- json_file = is_remote ? open(endpoint) : File.open(endpoint)
45
- build[key] = JSON.load(json_file)
46
- rescue StandardError => e
47
- # For backwards compatibility, we allow 'translations' to be missing.
48
- if key != 'translations'
49
- puts e.message
50
- abort 'Unable to read data from: ' + endpoint
51
- end
52
- end
53
- end
54
-
55
- return build
56
- end
57
-
58
- # Predict (before data has been fetched) whether the site is using
59
- # translated builds or not.
60
- def site_uses_translated_builds(path)
61
-
62
- is_remote = is_path_remote(path)
63
- endpoints = get_endpoints()
64
- # For a quick test, we just use 'meta'.
65
- meta = endpoints['meta']
66
- endpoint = is_remote ? path + '/' + meta : File.join(path, fix_path(meta))
67
-
68
- begin
69
- json_file = is_remote ? open(endpoint) : File.open(endpoint)
70
- rescue StandardError => e
71
- # If we didn't find an untranslated 'meta', we assume translated builds.
72
- return true
73
- end
74
-
75
- # Other wise assume untranslated builds.
76
- return false
77
- end
78
-
79
- def generate(site)
80
-
81
- # For below, make sure there is at least an empty hash at
82
- # site.data.translations.
83
- if !site.data.has_key?('translations')
84
- site.data['translations'] = {}
85
- end
86
-
87
- remote = site.config['remote_data_prefix']
88
- local = site.config['local_data_folder']
89
-
90
- if !remote && !local
91
- abort 'Site config must include either "remote_data_prefix" or "local_data_folder".'
92
- end
93
-
94
- build_location = remote ? remote : File.join(Dir.pwd, local)
95
- translated_builds = site_uses_translated_builds(build_location)
96
-
97
- if translated_builds
98
- # For translated builds, we get a build for each language, and
99
- # place them in "subfolders" (so to speak) of site.data.
100
- site.config['languages'].each do |language|
101
- data_target = site.data[language]
102
- translated_build = remote ? build_location + '/' + language : File.join(build_location, language)
103
- data_source = fetch_build(translated_build)
104
- if data_target
105
- data_target.deep_merge(data_source)
106
- else
107
- site.data[language] = data_source
108
- end
109
- end
110
- # We move the language-specific translations to the
111
- # site.data.translations location, where all translations are kept.
112
- site.config['languages'].each do |language|
113
- translation_target = site.data['translations'][language]
114
- translation_source = site.data[language]['translations']
115
- if translation_target
116
- translation_target.deep_merge(translation_source)
117
- else
118
- site.data['translations'][language] = translation_source
119
- end
120
- end
121
- # And there are some parts of the build that don't need to be translated
122
- # and should be moved to the top level.
123
- first_language = site.config['languages'][0]
124
- site.data['reporting'] = site.data[first_language]['reporting']
125
- site.data['schema'] = site.data[first_language]['schema']
126
- site.data['zip'] = site.data[first_language]['zip']
127
- else
128
- # For untranslated builds, we download one build only, and place it
129
- # in the "root" (so to speak) of site.data. Nothing else is needed.
130
- target = site.data
131
- source = fetch_build(build_location)
132
- target.deep_merge(source)
133
- end
134
-
135
- # Finally support the deprecated 'remote_translations' option.
136
- # This is deprecated because translations should now be in the
137
- # data repository, where they will be fetched in fetch_build().
138
- if site.config['remote_translations']
139
- key = 'translations'
140
- target = site.data[key]
141
- site.config['remote_translations'].each do |endpoint|
142
- begin
143
- source = JSON.load(open(endpoint))
144
- if target
145
- target.deep_merge(source)
146
- else
147
- site.data[key] = source
148
- end
149
- rescue StandardError => e
150
- puts e.message
151
- abort 'Unable to fetch remote translation from: ' + endpoint
152
- end
153
- end
154
- end
155
- end
156
- end
157
-
158
- # This makes sure that the contents of the "local_data_folder" get copied
159
- # into the Jekyll build, so that they can be served from the website.
160
- Jekyll::Hooks.register :site, :post_write do |site|
161
- if site.config['local_data_folder']
162
- source = File.join(Dir.pwd, site.config['local_data_folder'], '.')
163
- destination = site.config['destination']
164
- FileUtils.cp_r(source, destination)
165
- end
166
- end
167
- end
1
+ require "jekyll"
2
+ require 'json'
3
+ require 'deep_merge'
4
+ require 'open-uri'
5
+ require_relative "helpers"
6
+
7
+ module JekyllOpenSdgPlugins
8
+ class FetchRemoteData < Jekyll::Generator
9
+ safe true
10
+ priority :highest
11
+
12
+ # Fix a Unix path in case we are on Windows.
13
+ def fix_path(path)
14
+ path_parts = path.split('/')
15
+ return path_parts.join(File::SEPARATOR)
16
+ end
17
+
18
+ # Our hardcoded list of pieces of the build that we expect.
19
+ def get_endpoints()
20
+ return {
21
+ 'meta' => 'meta/all.json',
22
+ 'headlines' => 'headline/all.json',
23
+ 'schema' => 'meta/schema.json',
24
+ 'reporting' => 'stats/reporting.json',
25
+ 'translations' => 'translations/translations.json',
26
+ 'zip' => 'zip/all_indicators.json'
27
+ }
28
+ end
29
+
30
+ # Is this path a remote path?
31
+ def is_path_remote(path)
32
+ return path.start_with?('http')
33
+ end
34
+
35
+ # Get a build from a local folder on disk or a remote URL on the Internet.
36
+ def fetch_build(path)
37
+
38
+ is_remote = is_path_remote(path)
39
+ build = {}
40
+ get_endpoints().each do |key, value|
41
+ endpoint = is_remote ? path + '/' + value : File.join(path, fix_path(value))
42
+
43
+ begin
44
+ json_file = is_remote ? open(endpoint) : File.open(endpoint)
45
+ build[key] = JSON.load(json_file)
46
+ rescue StandardError => e
47
+ # For backwards compatibility, we allow 'translations' to be missing.
48
+ if key != 'translations'
49
+ puts e.message
50
+ abort 'Unable to read data from: ' + endpoint
51
+ end
52
+ end
53
+ end
54
+
55
+ return build
56
+ end
57
+
58
+ # Predict (before data has been fetched) whether the site is using
59
+ # translated builds or not.
60
+ def site_uses_translated_builds(path)
61
+
62
+ is_remote = is_path_remote(path)
63
+ endpoints = get_endpoints()
64
+ # For a quick test, we just use 'meta'.
65
+ meta = endpoints['meta']
66
+ endpoint = is_remote ? path + '/' + meta : File.join(path, fix_path(meta))
67
+
68
+ begin
69
+ json_file = is_remote ? open(endpoint) : File.open(endpoint)
70
+ rescue StandardError => e
71
+ # If we didn't find an untranslated 'meta', we assume translated builds.
72
+ return true
73
+ end
74
+
75
+ # Other wise assume untranslated builds.
76
+ return false
77
+ end
78
+
79
+ def generate(site)
80
+
81
+ # For below, make sure there is at least an empty hash at
82
+ # site.data.translations.
83
+ if !site.data.has_key?('translations')
84
+ site.data['translations'] = {}
85
+ end
86
+
87
+ remote = site.config['remote_data_prefix']
88
+ local = site.config['local_data_folder']
89
+
90
+ if !remote && !local
91
+ abort 'Site config must include either "remote_data_prefix" or "local_data_folder".'
92
+ end
93
+
94
+ build_location = remote ? remote : File.join(Dir.pwd, local)
95
+ translated_builds = site_uses_translated_builds(build_location)
96
+
97
+ if translated_builds
98
+ # For translated builds, we get a build for each language, and
99
+ # place them in "subfolders" (so to speak) of site.data.
100
+ site.config['languages'].each do |language|
101
+ data_target = site.data[language]
102
+ translated_build = remote ? build_location + '/' + language : File.join(build_location, language)
103
+ data_source = fetch_build(translated_build)
104
+ if data_target
105
+ data_target.deep_merge(data_source)
106
+ else
107
+ site.data[language] = data_source
108
+ end
109
+ end
110
+ # We move the language-specific translations to the
111
+ # site.data.translations location, where all translations are kept.
112
+ site.config['languages'].each do |language|
113
+ translation_target = site.data['translations'][language]
114
+ translation_source = site.data[language]['translations']
115
+ if translation_target
116
+ translation_target.deep_merge(translation_source)
117
+ else
118
+ site.data['translations'][language] = translation_source
119
+ end
120
+ end
121
+ # And there are some parts of the build that don't need to be translated
122
+ # and should be moved to the top level.
123
+ first_language = site.config['languages'][0]
124
+ site.data['reporting'] = site.data[first_language]['reporting']
125
+ site.data['schema'] = site.data[first_language]['schema']
126
+ site.data['zip'] = site.data[first_language]['zip']
127
+ else
128
+ # For untranslated builds, we download one build only, and place it
129
+ # in the "root" (so to speak) of site.data. Nothing else is needed.
130
+ target = site.data
131
+ source = fetch_build(build_location)
132
+ target.deep_merge(source)
133
+ end
134
+
135
+ # Finally support the deprecated 'remote_translations' option.
136
+ # This is deprecated because translations should now be in the
137
+ # data repository, where they will be fetched in fetch_build().
138
+ if site.config['remote_translations']
139
+ key = 'translations'
140
+ target = site.data[key]
141
+ site.config['remote_translations'].each do |endpoint|
142
+ begin
143
+ source = JSON.load(open(endpoint))
144
+ if target
145
+ target.deep_merge(source)
146
+ else
147
+ site.data[key] = source
148
+ end
149
+ rescue StandardError => e
150
+ puts e.message
151
+ abort 'Unable to fetch remote translation from: ' + endpoint
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+
158
+ # This makes sure that the contents of the "local_data_folder" get copied
159
+ # into the Jekyll build, so that they can be served from the website.
160
+ Jekyll::Hooks.register :site, :post_write do |site|
161
+ if site.config['local_data_folder']
162
+ source = File.join(Dir.pwd, site.config['local_data_folder'], '.')
163
+ destination = site.config['destination']
164
+ FileUtils.cp_r(source, destination)
165
+ end
166
+ end
167
+ end