From bce75809d548ebb1dba4b05198d0686cf7266f81 Mon Sep 17 00:00:00 2001 From: milovanderlinden Date: Sat, 8 Dec 2018 10:49:12 +0100 Subject: [PATCH 1/5] work in progress; generate code.json at site init --- .gitignore | 1 + src/_plugins/code_json_generate_once.rb | 40 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/_plugins/code_json_generate_once.rb diff --git a/.gitignore b/.gitignore index fa33a9af..5890d46b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .bundle/ .jekyll-cache/ .sass-cache/ +src/_data/code.json public/ diff --git a/src/_plugins/code_json_generate_once.rb b/src/_plugins/code_json_generate_once.rb new file mode 100644 index 00000000..89d79a63 --- /dev/null +++ b/src/_plugins/code_json_generate_once.rb @@ -0,0 +1,40 @@ +## +# +# This module will generate an code.json file inside the src/_data directory +# BEFORE the site is generated. The code.json can therefor be used inside +# page templating syntax by using the variables +# `data.code.` +# +## + +module RunMeOnce + + def self.process(site, payload) + return if @processed + input_dir ||= File.expand_path('../_releases', __dir__) + file_paths ||= Dir.glob(File.join(input_dir, '**', '*.json')).sort + output = { + agency: 'DOD', + version: '2.0.0', + measurementType: { + method: 'projects' + }, + releases: [] + } + + file_paths.each do |file_path| + output[:releases] << JSON.parse(File.read(file_path)) + end + + path = 'src/_data/code.json' + FileUtils.mkdir_p(File.dirname(path)) + File.open(path, 'w') do |f| + f.write(JSON.pretty_generate(output)) + end + @processed = true + end + end + + Jekyll::Hooks.register :site, :after_init do |site, payload| + RunMeOnce.process(site, payload) + end \ No newline at end of file From 07a18f9207aeec63234cb26c80adbc97970cd480 Mon Sep 17 00:00:00 2001 From: milovanderlinden Date: Sun, 9 Dec 2018 11:05:10 +0100 Subject: [PATCH 2/5] First prototype for #241 --- _config.yml | 12 +++ src/_data/navigation.yml | 3 + src/_layouts/project.html | 8 ++ src/_plugins/data_page_generator.rb | 138 ++++++++++++++++++++++++++++ src/projects.md | 13 +++ 5 files changed, 174 insertions(+) create mode 100644 src/_layouts/project.html create mode 100644 src/_plugins/data_page_generator.rb create mode 100644 src/projects.md diff --git a/_config.yml b/_config.yml index 3b7ace1c..1663346e 100644 --- a/_config.yml +++ b/_config.yml @@ -26,6 +26,10 @@ defaults: path: "code.json" values: layout: null + - scope: + path: "projects" + values: + layout: project theme: uswds-jekyll @@ -36,3 +40,11 @@ scripts: styles: - /assets/css/main.css - /assets/css/custom.css + +page_gen: +- index_files: true + data: code.releases + name: name + template: project + dir: projects +page_gen-dirs: true \ No newline at end of file diff --git a/src/_data/navigation.yml b/src/_data/navigation.yml index 95a75cc8..82b459c4 100644 --- a/src/_data/navigation.yml +++ b/src/_data/navigation.yml @@ -3,9 +3,12 @@ secondary: &secondary_navigation href: /why-open-source.html - text: Getting Started href: /getting-started.html + - text: Projects + href: /projects.html - text: How to Open Source href: /how-to-open-source.html - text: FAQs href: /frequently-asked-questions.html + sidebar: *secondary_navigation diff --git a/src/_layouts/project.html b/src/_layouts/project.html new file mode 100644 index 00000000..050e1587 --- /dev/null +++ b/src/_layouts/project.html @@ -0,0 +1,8 @@ +--- +layout: default +--- +

{{ page.title }}

+{{ page.organization }} +

+{{ page.description }} +

\ No newline at end of file diff --git a/src/_plugins/data_page_generator.rb b/src/_plugins/data_page_generator.rb new file mode 100644 index 00000000..7d6cbcdf --- /dev/null +++ b/src/_plugins/data_page_generator.rb @@ -0,0 +1,138 @@ +# coding: utf-8 +# Generate pages from individual records in yml files +# (c) 2014-2016 Adolfo Villafiorita +# Distributed under the conditions of the MIT License + +module Jekyll + + module Sanitizer + # strip characters and whitespace to create valid filenames, also lowercase + def sanitize_filename(name) + if(name.is_a? Integer) + return name.to_s + end + return name.tr( + "ÀÁÂÃÄÅàáâãäåĀāĂ㥹ÇçĆćĈĉĊċČčÐðĎďĐđÈÉÊËèéêëĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħÌÍÎÏìíîïĨĩĪīĬĭĮįİıĴĵĶķĸĹĺĻļĽľĿŀŁłÑñŃńŅņŇňʼnŊŋÑñÒÓÔÕÖØòóôõöøŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšſŢţŤťŦŧÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųŴŵÝýÿŶŷŸŹźŻżŽž", + "AAAAAAaaaaaaAaAaAaCcCcCcCcCcDdDdDdEEEEeeeeEeEeEeEeEeGgGgGgGgHhHhIIIIiiiiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnNnnNnNnOOOOOOooooooOoOoOoRrRrRrSsSsSsSssTtTtTtUUUUuuuuUuUuUuUuUuUuWwYyyYyYZzZzZz" + ).downcase.strip.gsub(' ', '-').gsub(/[^\w.-]/, '') + end + end + + # this class is used to tell Jekyll to generate a page + class DataPage < Jekyll::Page + include Sanitizer + + # - site and base are copied from other plugins: to be honest, I am not sure what they do + # + # - `index_files` specifies if we want to generate named folders (true) or not (false) + # - `dir` is the default output directory + # - `data` is the data defined in `_data.yml` of the record for which we are generating a page + # - `name` is the key in `data` which determines the output filename + # - `template` is the name of the template for generating the page + # - `extension` is the extension for the generated file + def initialize(site, base, index_files, dir, data, name, template, extension) + @site = site + @base = base + + # @dir is the directory where we want to output the page + # @name is the name of the page to generate + # + # the value of these variables changes according to whether we + # want to generate named folders or not + if data[name] == nil + puts "error (datapage_gen). empty value for field '#{name}' in record #{data}" + else + filename = sanitize_filename(data[name]).to_s + + @dir = dir + (index_files ? "/" + filename + "/" : "") + @name = (index_files ? "index" : filename) + "." + extension.to_s + + self.process(@name) + self.read_yaml(File.join(base, '_layouts'), template + ".html") + self.data['title'] = data[name] + # add all the information defined in _data for the current record to the + # current page (so that we can access it with liquid tags) + self.data.merge!(data) + end + end + end + + class DataPagesGenerator < Jekyll::Generator + safe true + + # generate loops over _config.yml/page_gen invoking the DataPage + # constructor for each record for which we want to generate a page + + def generate(site) + # page_gen_dirs determines whether we want to generate index pages + # (name/index.html) or standard files (name.html). This information + # is passed to the DataPage constructor, which sets the @dir variable + # as required by this directive + index_files = site.config['page_gen-dirs'] == true + + # data contains the specification of the data for which we want to generate + # the pages (look at the README file for its specification) + data = site.config['page_gen'] + if data + data.each do |data_spec| + index_files_for_this_data = data_spec['index_files'] != nil ? data_spec['index_files'] : index_files + template = data_spec['template'] || data_spec['data'] + name = data_spec['name'] + dir = data_spec['dir'] || data_spec['data'] + extension = data_spec['extension'] || "html" + + if site.layouts.key? template + # records is the list of records defined in _data.yml + # for which we want to generate different pages + records = nil + data_spec['data'].split('.').each do |level| + if records.nil? + records = site.data[level] + else + records = records[level] + end + end + + # apply filtering conditions: + # - filter requires the name of a boolean field + # - filter_condition evals a ruby expression + records = records.select { |r| r[data_spec['filter']] } if data_spec['filter'] + records = records.select { |record| eval(data_spec['filter_condition']) } if data_spec['filter_condition'] + + records.each do |record| + site.pages << DataPage.new(site, site.source, index_files_for_this_data, dir, record, name, template, extension) + end + else + puts "error (datapage_gen). could not find template #{template}" if not site.layouts.key? template + end + end + end + end + end + + module DataPageLinkGenerator + include Sanitizer + + # use it like this: {{input | datapage_url: dir}} + # to generate a link to a data_page. + # + # the filter is smart enough to generate different link styles + # according to the data_page-dirs directive ... + # + # ... however, the filter is not smart enough to support different + # extensions for filenames. + # + # Thus, if you use the `extension` feature of this plugin, you + # need to generate the links by hand + def datapage_url(input, dir) + extension = Jekyll.configuration({})['page_gen-dirs'] ? '/' : '.html' + "#{dir}/#{sanitize_filename(input)}#{extension}" + end + end + + end + + Liquid::Template.register_filter(Jekyll::DataPageLinkGenerator) + Jekyll::Hooks.register :site, :after_init do |site, payload| + RunMeOnce.process(site, payload) + end \ No newline at end of file diff --git a/src/projects.md b/src/projects.md new file mode 100644 index 00000000..add999d9 --- /dev/null +++ b/src/projects.md @@ -0,0 +1,13 @@ +--- +title: Projects +layout: page +--- + +
+ +This is an incomplete list of projects that are available as open source. + +{% for project in site.data.code.releases %} +* [{{ project.name}}]("/projects{{project.name | datapage_url: dir}}"); {{ project.description}} +{% endfor %} +
\ No newline at end of file From 2cae4506605b13f01367574acdb1226fb18a9802 Mon Sep 17 00:00:00 2001 From: milovanderlinden Date: Sun, 9 Dec 2018 13:16:24 +0100 Subject: [PATCH 3/5] Prettify project pages --- src/_layouts/project.html | 30 +++++++++++++++++++++++++----- src/projects.md | 2 +- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/_layouts/project.html b/src/_layouts/project.html index 050e1587..0fa42361 100644 --- a/src/_layouts/project.html +++ b/src/_layouts/project.html @@ -1,8 +1,28 @@ --- layout: default +main: + class: usa-grid usa-section usa-content usa-layout-docs --- -

{{ page.title }}

-{{ page.organization }} -

-{{ page.description }} -

\ No newline at end of file + +
+
+
+ {%- if page.title -%} +

{{ page.title }}

+ + {%- if page.date.created -%} + Last updated + {%- endif -%} + {%- endif -%} +
+ +

+ {{ page.description }} +

+

Status: {{ page.status }}

+

Organization: {{ page.organization }}

+

Source: {{ page.repositoryURL }}

+

License: {{ page.permissions.licenses[0].name }}

+

Contact: {% if page.contact.name %} {{ page.contact.name }} {% else %} email {% endif %}

+
+
\ No newline at end of file diff --git a/src/projects.md b/src/projects.md index add999d9..3f6d34df 100644 --- a/src/projects.md +++ b/src/projects.md @@ -8,6 +8,6 @@ layout: page This is an incomplete list of projects that are available as open source. {% for project in site.data.code.releases %} -* [{{ project.name}}]("/projects{{project.name | datapage_url: dir}}"); {{ project.description}} +* [{{ project.name}}](/projects{{project.name | datapage_url: dir}}); {{ project.description}} {% endfor %} \ No newline at end of file From 2a0a90a2c431e76ee59bad936b3e1bccac150cc0 Mon Sep 17 00:00:00 2001 From: milovanderlinden Date: Mon, 10 Dec 2018 10:55:32 +0100 Subject: [PATCH 4/5] Changed paragraphs to and added various checks in project.html --- src/_layouts/project.html | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/_layouts/project.html b/src/_layouts/project.html index 0fa42361..c4eaed75 100644 --- a/src/_layouts/project.html +++ b/src/_layouts/project.html @@ -19,10 +19,26 @@

{{ page.title }}

{{ page.description }}

-

Status: {{ page.status }}

-

Organization: {{ page.organization }}

-

Source: {{ page.repositoryURL }}

-

License: {{ page.permissions.licenses[0].name }}

-

Contact: {% if page.contact.name %} {{ page.contact.name }} {% else %} email {% endif %}

- + + \ No newline at end of file From b7d136a589be303f79b671f5567c4d2e3d5481c0 Mon Sep 17 00:00:00 2001 From: milovanderlinden Date: Mon, 10 Dec 2018 11:20:18 +0100 Subject: [PATCH 5/5] Removed the "old" code.json generator and added a landing page that grabs from --- src/_plugins/code_gov_inventory_generator.rb | 44 -------------------- src/code.html | 5 +++ 2 files changed, 5 insertions(+), 44 deletions(-) delete mode 100644 src/_plugins/code_gov_inventory_generator.rb create mode 100644 src/code.html diff --git a/src/_plugins/code_gov_inventory_generator.rb b/src/_plugins/code_gov_inventory_generator.rb deleted file mode 100644 index 4e82446c..00000000 --- a/src/_plugins/code_gov_inventory_generator.rb +++ /dev/null @@ -1,44 +0,0 @@ -module Jekyll - module CodeGovInventory - class Generator < Jekyll::Generator - safe true - priority :low - - def generate(site) - raise "No JSON files found in `#{input_dir}`!" unless file_paths.any? - - page = PageWithoutAFile.new(site, __dir__, '', 'code.json') - page.content = page_content - - site.pages << page - end - - private - - def input_dir - @input_dir ||= File.expand_path('../_releases', __dir__) - end - - def file_paths - @file_paths ||= Dir.glob(File.join(input_dir, '**', '*.json')).sort - end - - def page_content - output = { - agency: 'DOD', - version: '2.0.0', - measurementType: { - method: 'projects' - }, - releases: [] - } - - file_paths.each do |file_path| - output[:releases] << JSON.parse(File.read(file_path)) - end - - JSON.pretty_generate(output) - end - end - end -end diff --git a/src/code.html b/src/code.html new file mode 100644 index 00000000..cbdc5f96 --- /dev/null +++ b/src/code.html @@ -0,0 +1,5 @@ +--- +layout: null +permalink: code.json +--- +{{ site.data.code | jsonify | strip_html}} \ No newline at end of file