Funded by {{ entity.funder_name }}
{% endif %} -- {{ contributors[page.contributor].bio }} + {{ entity.bio }}
{% endif %} - {% if page.has_philosophy %} - - {% endif %} - - {% if contributors[page.contributor].github != false %} - - {% endif %} - - {% if contributors[page.contributor].funding_id %} - Grant ID: - {% if contributors[page.contributor].funding_system %} - {% if contributors[page.contributor].funding_system == "cordis" %} - - {{ contributors[page.contributor].funding_id }} - - {% elsif contributors[page.contributor].funding_system == "erasmusplus" %} - - {{ contributors[page.contributor].funding_id }} - - {% elsif contributors[page.contributor].funding_system == "ukri" %} - - {{ contributors[page.contributor].funding_id }} - - {% endif %} - {% else %} - {{ contributors[page.contributor].funding_id }} - {% endif %} - {% endif %} - - {% if contributors[page.contributor].email %} - - {% endif %} - - {% if contributors[page.contributor].matrix %} - - {% endif %} - - {% if contributors[page.contributor].fediverse %} -{{ entity.in_memoriam | markdownify }}
These individuals have noted that they are affiliated in some way with this organisation. This list is non-exhaustive.
+Funded by {{ contributors[page.contributor].funder_name }}
- {% endif %} - - {% if contributors[page.contributor].funder %} -{{ contributors[page.contributor].in_memoriam | markdownify }}
-
The following list includes only slides and tutorials where the individual has been added to the contributor list. This may not include the sum total of their contributions to the training materials (e.g. GTN css or design, tutorial datasets, workflow development, etc.) unless described by a news post.
- {% unless contributors[page.contributor].github == false %}
+ {% unless entity.github == false %}
- {% unless contributors[page.contributor].funder %}
+ {% unless entity.funder %}
Favourite Topics
+ +Favourite Formats
+ + +- - - - - - - - - - - - - - - - - -
+@misc{% raw %}{{% endraw %}{{topic.name}}-{{page.tutorial_name}},
-{% assign authors = page.contributors | filter_authors:page.contributions -%}
+{% assign authors = page | filter_authors -%}
author = "{%- include _includes/contributor-list.html contributors=authors sep=" and " -%}",
title = "{{ page.title }} (Galaxy Training Materials)",
year = "{{ page.last_modified_at | date: "%Y"}}",
diff --git a/_plugins/api.rb b/_plugins/api.rb
index c76d3df1643ba6..2a5c754abe1aa5 100644
--- a/_plugins/api.rb
+++ b/_plugins/api.rb
@@ -14,20 +14,6 @@ module Jekyll
##
# This class generates the GTN's "api" by writing out a folder full of JSON files.
class APIGenerator < Generator
- ##
- # Returns contributors, regardless of whether they are 'contributor' or 'contributions' style
- # Params:
- # +data+:: +Hash+ of the YAML frontmatter from a material
- # Returns:
- # +Array+ of contributor IDs
- def get_contributors(data)
- if data.key?('contributors')
- data['contributors']
- elsif data.key?('contributions')
- data['contributions'].keys.map { |k| data['contributions'][k] }.flatten
- end
- end
-
##
# Use Jekyll's Markdown converter to convert text to HTML
# Params:
@@ -70,13 +56,13 @@ def visitAndMarkdownify(site, f)
# Returns:
# +Hash+ of contributor information
def mapContributor(site, c)
- x = site.data['contributors']
- .fetch(c, {})
- .merge({
- 'id' => c,
- 'url' => site.config['url'] + site.config['baseurl'] + "/api/contributors/#{c}.json",
- 'page' => site.config['url'] + site.config['baseurl'] + "/hall-of-fame/#{c}/",
- })
+ contrib_type, contrib = Gtn::Contributors.fetch(site, c)
+ x = contrib
+ .merge({
+ 'id' => c,
+ 'url' => site.config['url'] + site.config['baseurl'] + "/api/#{contrib_type}s/#{c}.json",
+ 'page' => site.config['url'] + site.config['baseurl'] + "/hall-of-fame/#{c}/",
+ })
visitAndMarkdownify(site, x)
end
@@ -158,16 +144,18 @@ def generate(site)
site.pages << page2
# Contributors
- puts '[GTN/API] Contributors'
- page2 = PageWithoutAFile.new(site, '', 'api/', 'contributors.json')
- page2.content = JSON.pretty_generate(site.data['contributors'].map { |c, _| mapContributor(site, c) })
- page2.data['layout'] = nil
- site.pages << page2
- site.data['contributors'].each do |c, _|
- page4 = PageWithoutAFile.new(site, '', 'api/', "contributors/#{c}.json")
- page4.content = JSON.pretty_generate(mapContributor(site, c))
- page4.data['layout'] = nil
- site.pages << page4
+ puts '[GTN/API] Contributors, Funders, Organisations'
+ %w[contributors funders organisations].each do |type|
+ page2 = PageWithoutAFile.new(site, '', 'api/', "#{type}.json")
+ page2.content = JSON.pretty_generate(site.data[type].map { |c, _| mapContributor(site, c) })
+ page2.data['layout'] = nil
+ site.pages << page2
+ site.data['contributors'].each do |c, _|
+ page4 = PageWithoutAFile.new(site, '', 'api/', "#{type}s/#{c}.json")
+ page4.content = JSON.pretty_generate(mapContributor(site, c))
+ page4.data['layout'] = nil
+ site.pages << page4
+ end
end
page2 = PageWithoutAFile.new(site, '', 'api/', 'contributors.geojson')
@@ -202,7 +190,7 @@ def generate(site)
out = site.data[topic].dup
out['materials'] = TopicFilter.topic_filter(site, topic).map do |x|
q = x.dup
- q['contributors'] = get_contributors(q).dup.map do |c|
+ q['contributors'] = Gtn::Contributors.get_contributors(q).dup.map do |c|
mapContributor(site, c)
end
@@ -286,7 +274,7 @@ def generate(site)
page5 = PageWithoutAFile.new(site, '', 'api/', "#{directory}/slides.json")
p = material.dup
p.delete('ref')
- p['contributors'] = get_contributors(p).dup.map { |c| mapContributor(site, c) }
+ p['contributors'] = Gtn::Contributors.get_contributors(p).dup.map { |c| mapContributor(site, c) }
# Here we un-do the tutorial metadata priority, and overwrite with
# slides metadata when available.
@@ -302,7 +290,7 @@ def generate(site)
page5 = PageWithoutAFile.new(site, '', 'api/', "#{directory}/tutorial.json")
p = material.dup
p.delete('ref')
- p['contributors'] = get_contributors(p).dup.map { |c| mapContributor(site, c) }
+ p['contributors'] = Gtn::Contributors.get_contributors(p).dup.map { |c| mapContributor(site, c) }
page5.content = JSON.pretty_generate(p)
page5.data['layout'] = nil
site.pages << page5
diff --git a/_plugins/author-page.rb b/_plugins/author-page.rb
index f0db6a1f649887..6cdb7a4c0e9234 100644
--- a/_plugins/author-page.rb
+++ b/_plugins/author-page.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require './_plugins/gtn'
+
module Jekyll
##
# This class generates the GTN's author pags
@@ -79,13 +81,13 @@ def generate(site)
pusher(t, news_by_author, true) if t['layout'] == 'news'
end
- site.data['contributors'].reject { |c| c['halloffame'] == 'no' }.each_key do |contributor|
+ Gtn::Contributors.list(site).reject { |c| c['halloffame'] == 'no' }.each_key do |contributor|
# Using PageWithoutAFile instead of a custom class which reads files
# from disk each time, saves some time, but it is unclear how much
# due to how the previous was accounted. But assuming 0.040s per page * 193 should be about 8 seconds.
page2 = PageWithoutAFile.new(site, '', File.join(dir, contributor), 'index.html')
page2.content = nil
- name = site.data['contributors'][contributor].fetch('name', contributor)
+ name = Gtn::Contributors.fetch_contributor(site, contributor).fetch('name', contributor)
# Their tutorials
page2.data['contributor'] = contributor
diff --git a/_plugins/gtn.rb b/_plugins/gtn.rb
index 432060e355d930..f36d1f7a5104d8 100644
--- a/_plugins/gtn.rb
+++ b/_plugins/gtn.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require 'English'
+require './_plugins/gtn/contributors'
require './_plugins/gtn/boxify'
require './_plugins/gtn/mod'
require './_plugins/gtn/images'
@@ -19,37 +20,6 @@
##
# This module contains functions that are used in the GTN, our internal functions that is.
-##
-# This function returns the authors of a material, if it has any. (via contributors or contribution)
-# Params:
-# +material+:: The material to get the authors of
-# Returns:
-# +Array+:: The authors of the material
-def get_authors(material)
- if material.key?('contributors')
- material['contributors']
- elsif material.key?('contributions')
- material['contributions']['authorship']
- else
- []
- end
-end
-
-##
-# This function returns the name of a user, if it is known. Otherwise, it returns the user name.
-# Params:
-# +user+:: The user to get the name of
-# +site+:: The +Jekyll::Site+ object
-# Returns:
-# +String+:: The name of the user
-def lookup_name(user, site)
- if site.data['contributors'].key?(user)
- site.data['contributors'][user].fetch('name', user)
- else
- user
- end
-end
-
module Jekyll
# The main GTN function library
module GtnFunctions
@@ -211,21 +181,80 @@ def fix_box_titles(content, lang, key)
end
##
- # Basically a dupe of 'get_authors'
# Params:
- # +contributors+:: The contributors to the material
- # +contributions+:: The contributions to the material
+ # +data+:: The page data
+ # Returns:
+ # +Array+:: The "authors" of the material (list of strings)
+ #
+ # Example:
+ # {% assign authors = page | filter_authors -%}
+ def filter_authors(data)
+ Gtn::Contributors.get_authors(data)
+ end
+
+ ##
+ # Params:
+ # +data+:: The site data
+ # +string+:: The contributor id
+ # Returns:
+ # +Hash+:: The contributing entity
+ #
+ # Example:
+ # {% assign contrib = site | fetch_contributor: page.contributor -%}
+ def fetch_contributor(site, id)
+ Gtn::Contributors.fetch_contributor(site, id)
+ end
+
+ ##
+ # Params:
+ # +data+:: The contributor's data
# Returns:
- # +Array+:: The "authors" of the material
+ # +String+:: The funding URL
#
- # TODO(hexylena) de-duplicate
+ # Example:
+ # {{ entity | fetch_funding_url }}
+ def fetch_funding_url(entity)
+ Gtn::Contributors.fetch_funding_url(entity)
+ end
+
+ ##
+ # Params:
+ # +data+:: The contributor's data
+ # Returns:
+ # +String+:: The avatar's URL
+ #
+ # Example:
+ # {{ entity | fetch_entity_avatar: 'alice', 120 }}
+ def fetch_entity_avatar_url(entity, id, width)
+ return 'ERROR_NO_ENTITY' if entity.nil?
+
+ width.nil? ? '' : "width=\"#{width}\""
+ if !entity['avatar'].nil?
+ entity['avatar']
+ elsif entity['github'] != false
+ qp = width.nil? ? '' : "?s=#{width}"
+ "https://avatars.githubusercontent.com/#{id}#{qp}"
+ else
+ '/training-material/assets/images/avatar.png'
+ end
+ end
+
+ ##
+ # Params:
+ # +data+:: The contributor's data
+ # Returns:
+ # +String+:: The funding URL
#
# Example:
- # {% assign authors = page.contributors | filter_authors:page.contributions -%}
- def filter_authors(contributors, contributions)
- return contributors if !contributors.nil?
+ # {{ entity | fetch_entity_avatar: 'alice', 120 }}
+ def fetch_entity_avatar(entity, id, width)
+ if entity.nil?
+ return ''
+ end
- contributions['authorship']
+ w = width.nil? ? '' : "width=\"#{width}\""
+ url = fetch_entity_avatar_url(entity, id, width)
+ %()
end
##
@@ -381,10 +410,35 @@ def get_default_link(material)
#
# This exists because the jekyll-feed plugin expects those fields to look like that.
Jekyll::Hooks.register :posts, :pre_render do |post, _out|
- post.data['author'] = get_authors(post.data).map { |c| lookup_name(c, post.site) }.join(', ')
+ post.data['author'] = Gtn::Contributors.get_authors(post.data).map do |c|
+ Gtn::Contributors.fetch_name(post.site, c)
+ end.join(', ')
post.data['image'] = post.data['cover']
end
+# Create back-refs for affiliations
+Jekyll::Hooks.register :site, :post_read do |site|
+ # Users list affiliations on their profile in site.data['contributors']
+ # And we want to create a back-ref to the user from the affiliation
+ site.data['contributors'].each do |name, contributor|
+ if contributor.key?('affiliations')
+ contributor['affiliations'].each do |affiliation|
+ if site.data['organisations'].key?(affiliation)
+ if !site.data['organisations'][affiliation].key?('members')
+ site.data['organisations'][affiliation]['members'] = []
+ end
+
+ site.data['organisations'][affiliation]['members'] << name
+ elsif site.data['funders'].key?(affiliation)
+ site.data['funders'][affiliation]['members'] = [] if !site.data['funders'][affiliation].key?('members')
+
+ site.data['funders'][affiliation]['members'] << name
+ end
+ end
+ end
+ end
+end
+
if $PROGRAM_NAME == __FILE__
result = Gtn::ModificationTimes.obtain_time(ARGV[0].gsub(%r{^/}, ''))
puts "Modification time of #{ARGV[0].gsub(%r{^/}, '')} is #{result}"
diff --git a/_plugins/gtn/contributors.rb b/_plugins/gtn/contributors.rb
new file mode 100644
index 00000000000000..994ae3298dd42d
--- /dev/null
+++ b/_plugins/gtn/contributors.rb
@@ -0,0 +1,148 @@
+# frozen_string_literal: true
+
+require 'jekyll'
+require 'time'
+
+module Gtn
+ # Parse the git repo to get some facts
+ module Contributors
+ ##
+ # Returns contributors, regardless of whether they are 'contributor' or 'contributions' style
+ # Params:
+ # +data+:: +Hash+ of the YAML frontmatter from a material
+ # Returns:
+ # +Array+ of contributor IDs
+ def self.get_contributors(data)
+ if data.key?('contributors')
+ data['contributors']
+ elsif data.key?('contributions')
+ data['contributions'].keys.map { |k| data['contributions'][k] }.flatten
+ else
+ {}
+ end
+ end
+
+ ##
+ # Returns authors, only entities that are primary authors
+ # Params:
+ # +data+:: +Hash+ of the YAML frontmatter from a material
+ # Returns:
+ # +Array+ of contributor IDs
+ def self.get_authors(data)
+ if data.key?('contributors')
+ data['contributors']
+ elsif data.key?('contributions')
+ data['contributions']['authorship']
+ else
+ {}
+ end
+ end
+
+ # Convenience method to allow us to handle nil sites, and load directly
+ # from disk ourselves.
+ def self._load_file(site, category)
+ if site.nil?
+ Jekyll.logger.warning "[GTN/Contributor] Loading #{category} from disk, this access could be improved"
+ File.open("_data/#{category}.yml", 'r') { |f| YAML.safe_load(f) }
+ else
+ site.data[category]
+ end
+ end
+
+ ##
+ # Map a contributor ID to their information and type
+ # Params:
+ # +site+:: +Jekyll::Site+ object
+ # +c+:: +String+ of contributor ID
+ # Returns:
+ # +Hash+ of contributor information
+ # +String+ type of contributor (e.g. 'contributor', 'organisation', 'funder')
+ def self.fetch(site, c)
+ if _load_file(site, 'contributors').key?(c)
+ return ['contributor', site.data['contributors'][c]]
+ elsif _load_file(site, 'organisations').key?(c)
+ return ['organisation', site.data['organisations'][c]]
+ elsif _load_file(site, 'funders').key?(c)
+ return ['funder', site.data['funders'][c]]
+ else
+ Jekyll.logger.error "Contributor #{c} not found"
+ end
+
+ [nil, nil]
+ end
+
+ ##
+ # Map a contributor ID to their information and type
+ # Params:
+ # +site+:: +Jekyll::Site+ object
+ # +c+:: +String+ of contributor ID
+ # Returns:
+ # +Hash+ of contributor information
+ def self.fetch_contributor(site, c)
+ fetch(site, c)[1]
+ end
+
+ ##
+ # Map a contributor ID to their information and type
+ # Params:
+ # +site+:: +Jekyll::Site+ object
+ # +c+:: +String+ of contributor ID
+ # Returns:
+ # +String+ of contributor name
+ def self.fetch_name(site, c)
+ fetch(site, c)[1].fetch('name', c)
+ end
+
+ ##
+ # List ALL contributors
+ # Params:
+ # +site+:: +Jekyll::Site+ object
+ # Returns:
+ # +Hash+ of contributors, funders, organisations merged together
+ def self.list(site)
+ site.data['contributors'].merge(site.data['funders']).merge(site.data['organisations'])
+ end
+
+ ##
+ # Check if a specific contributor is a person or not
+ # Params:
+ # +c+:: +String+ of contributor ID
+ # Returns:
+ # +Boolean+ of whether the contributor is a contributor or not
+ def self.person?(site, c)
+ site.data['contributors'].key?(c)
+ end
+
+ ##
+ # Check if a specific contributor is a funder or not
+ # Params:
+ # +c+:: +String+ of contributor ID
+ # Returns:
+ # +Boolean+ of whether the contributor is a funder or not
+ def self.funder?(site, c)
+ site.data['funders'].key?(c)
+ end
+
+ ##
+ # Obtain the contributor's funding URL
+ # Params:
+ # +c+:: +String+ of contributor ID
+ # Returns:
+ # +Boolean+ of whether the contributor is a funder or not
+ def self.fetch_funding_url(contributor)
+ return contributor['funding_id'] if !contributor.key?('funding_system')
+
+ case contributor['funding_system']
+ when 'cordis'
+ "https://cordis.europa.eu/project/id/#{contributor['funding_id']}"
+ when 'erasmusplus'
+ "https://erasmus-plus.ec.europa.eu/projects/search/details/#{contributor['funding_id']}"
+ when 'ukri'
+ "https://gtr.ukri.org/projects?ref=#{contributor['funding_id']}"
+ else
+ Jekyll.logger.error "Unknown funding system #{contributor['funding_system']}"
+ 'ERROR'
+ end
+ end
+ end
+end
diff --git a/_plugins/gtn/metrics.rb b/_plugins/gtn/metrics.rb
index 6e5cbb4498be68..44dfbdca094b82 100644
--- a/_plugins/gtn/metrics.rb
+++ b/_plugins/gtn/metrics.rb
@@ -95,11 +95,22 @@ def self.collect_metrics(site)
value: segment_page_by_key(site.pages, 'layout'),
help: 'Total number of Pages',
type: 'counter'
- }, 'gtn_contributors_total' => {
- value: segment(site.data['contributors'].values.reject { |x| x['halloffame'] == 'no' }, 'orcid'),
- help: 'Total number of Contributors',
- type: 'counter'
- },
+ },
+ 'gtn_contributors_total' => {
+ value: segment(site.data['contributors'].values.reject { |x| x['halloffame'] == 'no' }, 'orcid'),
+ help: 'Total number of contributors',
+ type: 'counter'
+ },
+ 'gtn_organisations_total' => {
+ value: segment(site.data['organisations'].values.reject { |x| x['halloffame'] == 'no' }, 'orcid'),
+ help: 'Total number of organisations',
+ type: 'counter'
+ },
+ 'gtn_funders_total' => {
+ value: segment(site.data['funders'].values.reject { |x| x['halloffame'] == 'no' }, 'orcid'),
+ help: 'Total number of funders',
+ type: 'counter'
+ },
'gtn_tutorials_total' => {
value: tutorials.length,
help: 'Total number of Hands-on Tutorials',
diff --git a/_plugins/jekyll-jsonld.rb b/_plugins/jekyll-jsonld.rb
index 753672768e2700..ebd27ac43e8cb8 100644
--- a/_plugins/jekyll-jsonld.rb
+++ b/_plugins/jekyll-jsonld.rb
@@ -47,36 +47,13 @@ def generate_dublin_core(material, site)
['DC.date', Gtn::ModificationTimes.obtain_time(material['path'])]
]
- attributes += get_authors(material).map do |user|
- if site['data']['contributors'].key?(user)
- ['DC.creator', site['data']['contributors'][user].fetch('name', user)]
- else
- puts "[GTN/Meta] #{user} not found in CONTRIBUTORS.yaml"
- ['DC.creator', user]
- end
+ attributes += Gtn::Contributors.get_authors(material).map do |user|
+ ['DC.creator', Gtn::Contributors.fetch_name(site, user)]
end
attributes.map { |a, b| "" }.join("\n")
end
- ##
- # Get the authors of a material.
- # Time number 4 i've seen this
- # TODO(hexylena): make this a function in gtn.rb
- # Parmeters:
- # +material+:: The material to get the authors for.
- # Returns:
- # An array of authors.
- def get_authors(material)
- if material.key?('contributors')
- material['contributors']
- elsif material.key?('contributions')
- material['contributions']['authorship']
- else
- []
- end
- end
-
##
# Generate the JSON-LD metadata for a person
# Parameters:
@@ -117,7 +94,7 @@ def generate_person_jsonld(id, contributor, site)
# I guess these are identical?
url: "#{site['url']}#{site['baseurl']}/hall-of-fame/#{id}/",
mainEntityOfPage: "#{site['url']}#{site['baseurl']}/hall-of-fame/#{id}/",
- name: contributor.nil? ? id : contributor.fetch('name', id),
+ name: Gtn::Contributors.fetch_name(site, id),
image: "https://avatars.githubusercontent.com/#{id}",
# No clue what to put here it's a person.
description: if contributor.nil?
@@ -136,7 +113,7 @@ def generate_person_jsonld(id, contributor, site)
person
end
- def generate_org_jsonld(id, contributor, _site)
+ def generate_org_jsonld(id, contributor, site)
organization = {
'@context': 'https://schema.org',
'@type': 'Organization',
@@ -144,7 +121,7 @@ def generate_org_jsonld(id, contributor, _site)
'@id': 'https://bioschemas.org/profiles/Organization/0.3-DRAFT',
'@type': 'CreativeWork'
},
- name: contributor.fetch('name', id),
+ name: Gtn::Contributors.fetch_name(site, id),
description: contributor.fetch('funding_statement', 'An organization supporting the Galaxy Training Network'),
}
@@ -153,19 +130,42 @@ def generate_org_jsonld(id, contributor, _site)
organization
end
+ def generate_funder_jsonld(id, contributor, site)
+ organization = {
+ '@context': 'https://schema.org',
+ '@type': 'Grant',
+ identifier: contributor['funding_id'],
+ url: contributor['url'] || Gtn::Contributors.fetch_funding_url(contributor),
+ funder: {
+ '@type': 'Organization',
+ name: Gtn::Contributors.fetch_name(site, id),
+ description: contributor.fetch('funding_statement',
+ 'An organization supporting the Galaxy Training Network'),
+ url: Gtn::Contributors.fetch_funding_url(contributor),
+ }
+ }
+ organization['startDate'] = contributor['start_date'] if contributor.key?('start_date')
+ organization['endDate'] = contributor['end_date'] if contributor.key?('end_date')
+
+ organization
+ end
+
##
- # Generate the JSON-LD metadata for a person as JSON.
+ # Generate the JSON-LD metadata for a person, funder, or organisation as JSON.
# Parameters:
# +id+:: The id of the person.
# +contributor+:: The contributor object from CONTRIBUTORS.yaml.
# +site+:: The site object.
# Returns:
# +String+:: The JSON-LD metadata.
- def to_person_jsonld(id, contributor, site)
- if contributor.key? 'funder'
- JSON.pretty_generate(generate_org_jsonld(id, contributor, site))
- else
+ def to_pfo_jsonld(id, site)
+ contributor = Gtn::Contributors.fetch_contributor(site, id)
+ if Gtn::Contributors.person?(site, id)
JSON.pretty_generate(generate_person_jsonld(id, contributor, site))
+ elsif Gtn::Contributors.funder?(site, id)
+ JSON.pretty_generate(generate_funder_jsonld(id, contributor, site))
+ else
+ JSON.pretty_generate(generate_org_jsonld(id, contributor, site))
end
end
@@ -177,7 +177,9 @@ def to_person_jsonld(id, contributor, site)
# Returns:
# +Hash+:: The JSON-LD metadata.
def generate_news_jsonld(page, site)
- authors = get_authors(page.to_h).map { |x| generate_person_jsonld(x, site['data']['contributors'][x], site) }
+ authors = Gtn::Contributors.get_authors(page.to_h).map do |x|
+ to_pfo_jsonld(x, site)
+ end
data = {
'@context': 'https://schema.org',
@@ -508,7 +510,9 @@ def to_jsonld(material, topic, site)
# Add contributors/authors
if material.key?('contributors') || material.key?('contributions')
- authors = get_authors(material).map { |x| generate_person_jsonld(x, site['data']['contributors'][x], site) }
+ authors = Gtn::Contributors.get_authors(material).map do |x|
+ generate_person_jsonld(x, Gtn::Contributors.fetch_contributor(site, x), site)
+ end
data['author'] = authors
end
diff --git a/_plugins/jekyll-tool-tag.rb b/_plugins/jekyll-tool-tag.rb
index a83d3e12250c2e..a2cfdef61e56cb 100644
--- a/_plugins/jekyll-tool-tag.rb
+++ b/_plugins/jekyll-tool-tag.rb
@@ -24,11 +24,11 @@ def render(context)
tool = context[m[2].tr('{}', '')] || m[2]
version = tool.split('/').last
- if tool.count('/') == 0
+ if tool.count('/').zero?
"" \
' ' \
"#{m[1]}" \
- ''
+ ''
else
"" \
' ' \
@@ -37,7 +37,7 @@ def render(context)
' ' \
"Galaxy version #{version}" \
')' \
- ''
+ ''
end
else
%(#{@text} )
diff --git a/_plugins/jekyll-topic-filter.rb b/_plugins/jekyll-topic-filter.rb
index de25f52e872bdb..5ca9edb9aacaa6 100644
--- a/_plugins/jekyll-topic-filter.rb
+++ b/_plugins/jekyll-topic-filter.rb
@@ -670,23 +670,6 @@ def self.filter_by_topic_subtopic(site, topic_name, subtopic_id)
resource_pages
end
- ##
- # Get the contributors for a material.
- # This is the third time I've seen this function.
- # I should probably refactor it out
- #
- # Parameters:
- # +material+:: A material object
- # Returns:
- # +Array+:: An array of contributors as strings.
- def self.get_contributors(material)
- if material.key?('contributors')
- material['contributors']
- else
- material['contributions'].map { |_k, v| v }.flatten
- end
- end
-
##
# Get a list of contributors for a list of materials
# Parameters:
@@ -697,8 +680,8 @@ def self.identify_contributors(materials, site)
materials
.map { |_k, v| v['materials'] }.flatten
# Not 100% sure why this flatten is needed? Probably due to the map over hash
- .map { |mat| get_contributors(mat) }.flatten.uniq.shuffle
- .reject { |c| site.data['contributors'][c]['funder'] == true }
+ .map { |mat| Gtn::Contributors.get_contributors(mat) }.flatten.uniq.shuffle
+ .reject { |c| Gtn::Contributors.funder?(site, c) }
end
##
@@ -711,8 +694,8 @@ def self.identify_funders(materials, site)
materials
.map { |_k, v| v['materials'] }.flatten
# Not 100% sure why this flatten is needed? Probably due to the map over hash
- .map { |mat| get_contributors(mat) }.flatten.uniq.shuffle
- .select { |c| site.data['contributors'][c]['funder'] == true }
+ .map { |mat| Gtn::Contributors.get_contributors(mat) }.flatten.uniq.shuffle
+ .select { |c| Gtn::Contributors.funder?(site, c) }
end
##
diff --git a/_plugins/jekyll-webfinger.rb b/_plugins/jekyll-webfinger.rb
index 364c666b2a6482..5e833ce351cab6 100644
--- a/_plugins/jekyll-webfinger.rb
+++ b/_plugins/jekyll-webfinger.rb
@@ -1,13 +1,15 @@
# frozen_string_literal: true
+require './_plugins/gtn'
+
Jekyll::Hooks.register :site, :post_write do |site|
# Make the directory
Jekyll.logger.info 'Generating webfinger files'
FileUtils.mkdir_p "#{site.dest}/api/fedi"
- site.data['contributors']
- .select { |_k, v| v['fediverse'] }
- .each do |k, v|
+ Gtn::Contributors.list(site)
+ .select { |_k, v| v['fediverse'] }
+ .each do |k, v|
# saving the outputs to
# training-material/api/fedi/resource=acct%3Ahexylena%40galaxy.training.json
diff --git a/_plugins/notebook-rmarkdown.rb b/_plugins/notebook-rmarkdown.rb
index 8af426056ef8cd..67815c9266be60 100644
--- a/_plugins/notebook-rmarkdown.rb
+++ b/_plugins/notebook-rmarkdown.rb
@@ -22,7 +22,7 @@ def generate(site)
puts "[GTN/Notebooks/R] Rendering RMarkdown #{fn}"
last_modified = Gtn::ModificationTimes.obtain_time(page.path)
- notebook = GTNNotebooks.render_rmarkdown(page.data, page.content, page.url, last_modified, fn)
+ notebook = GTNNotebooks.render_rmarkdown(site, page.data, page.content, page.url, last_modified, fn)
topic_id = dir.split('/')[-3]
tutorial_id = dir.split('/')[-1]
diff --git a/_plugins/notebook.rb b/_plugins/notebook.rb
index e628fc511cb894..2d3e5f83cae40e 100644
--- a/_plugins/notebook.rb
+++ b/_plugins/notebook.rb
@@ -182,26 +182,16 @@ def self.group_doc_by_first_char(data)
out.flatten(1).join("\n")
end
- def self.construct_byline(metadata)
- folks = if metadata.key?('contributors')
- metadata['contributors']
- else
- metadata['contributions']['authorship']
- end
-
- contributors = nil
- File.open('CONTRIBUTORS.yaml', 'r') do |f2|
- contributors = YAML.safe_load(f2.read)
- end
-
+ def self.construct_byline(site, metadata)
+ folks = Gtn::Contributors.get_authors(metadata)
folks.map do |c|
- name = contributors.fetch(c, { 'name' => c }).fetch('name', c)
+ name = Gtn::Contributors.fetch_name(site, c)
"[#{name}](https://training.galaxyproject.org/hall-of-fame/#{c}/)"
end.join(', ')
end
- def self.add_metadata_cell(notebook, metadata)
- by_line = construct_byline(metadata)
+ def self.add_metadata_cell(site, notebook, metadata)
+ by_line = construct_byline(site, metadata)
meta_header = [
"\n\n",
@@ -323,8 +313,8 @@ def self.notebook_filter(data, language = nil)
and (language.nil? or data['notebook']['language'].downcase == language)
end
- def self.render_rmarkdown(page_data, page_content, page_url, page_last_modified, fn)
- by_line = construct_byline(page_data)
+ def self.render_rmarkdown(site, page_data, page_content, page_url, page_last_modified, fn)
+ by_line = construct_byline(site, page_data)
# Replace top level `>` blocks with fenced `:::`
content = group_doc_by_first_char(page_content)
@@ -411,7 +401,7 @@ def self.render_jupyter_notebook(data, content, url, _last_modified, notebook_la
notebook = convert_notebook_markdown(content, accepted_languages)
# This extracts the metadata yaml header and does manual formatting of
# the header data to make for a nicer notebook.
- notebook = add_metadata_cell(notebook, data)
+ notebook = add_metadata_cell(site, notebook, data)
# Apply language specific conventions
case notebook_language
diff --git a/assets/css/main.scss b/assets/css/main.scss
index 3e5fabdd84e71b..6f9c8b94669b9c 100644
--- a/assets/css/main.scss
+++ b/assets/css/main.scss
@@ -830,6 +830,15 @@ blockquote {
justify-content: space-around;
}
+.contributor-page {
+ img.avatar {
+ background-color: white;
+ border-radius: 20px;
+ // border: 1px solid var(--border-light);
+ // padding: 5px;
+ width: 100%;
+ }
+}
.hall-of-fame-hero {
width: 140px;
margin: 1rem;
@@ -852,9 +861,6 @@ blockquote {
border: 1px solid var(--border-light);
padding: 5px;
width: 100%;
- -webkit-transition: border 0.2s ease-in-out;
- -o-transition: border 0.2s ease-in-out;
- transition: border 0.2s ease-in-out;
}
}
@@ -1002,14 +1008,6 @@ a {
text-decoration: none;
}
- // Unset this for logos on the homepage
- &.logo {
- border: none;
- img {
- max-height: 5em;
- }
- }
-
&.btn-info {
color: black;
}
@@ -1644,3 +1642,30 @@ figure > a[target="_blank"]::after {
align-self: center;
}
+
+.logosoup {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: flex-end;
+ row-gap: 1em;
+
+ figure {
+ max-width: 20em;
+ margin: 0rem 0.5rem;
+
+ img {
+ max-height: 5em;
+ }
+
+ figcaption {
+ text-align: left;
+ }
+ }
+
+ // Unset this for logos on the homepage
+ .logo {
+ border: none;
+ }
+}
diff --git a/assets/images/avatar.png b/assets/images/avatar.png
new file mode 100644
index 00000000000000..0c11f3c454064a
Binary files /dev/null and b/assets/images/avatar.png differ
diff --git a/bin/gtn.rb b/bin/gtn.rb
index 5ef88d07f7c6cb..0f6b6439d9273a 100644
--- a/bin/gtn.rb
+++ b/bin/gtn.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
CONTRIBUTORS = YAML.load_file('CONTRIBUTORS.yaml')
+ORGANISATIONS = YAML.load_file('ORGANISATIONS.yaml')
+FUNDERS = YAML.load_file('FUNDERS.yaml')
def automagic_loading(f)
# Remove our documentation
@@ -12,7 +14,14 @@ def automagic_loading(f)
if v.is_a?(Hash)
automagic_loading(v)
elsif v.is_a?(Array)
- v.replace CONTRIBUTORS.keys if (k == 'enum') && (v[0] == 'CONTRIBUTORS')
+ if k == 'enum'
+ repl = []
+ # If one of the elements in this array is CONTRIBUTORS, replace it with the same named variable
+ repl << CONTRIBUTORS.keys if v.find { |x| x == 'CONTRIBUTORS' }
+ repl << FUNDERS.keys if v.find { |x| x == 'FUNDERS' }
+ repl << ORGANISATIONS.keys if v.find { |x| x == 'ORGANISATIONS' }
+ v.replace repl.flatten if repl.length.positive?
+ end
v.flatten.each { |x| automagic_loading(x) if x.is_a?(Hash) }
end
end
diff --git a/bin/lint.rb b/bin/lint.rb
index fd8806445395f5..8d0530f7b1af78 100755
--- a/bin/lint.rb
+++ b/bin/lint.rb
@@ -693,7 +693,7 @@ def self.zenodo_api(contents)
match_start: selected.begin(1),
match_end: selected.end(1) + 1,
replacement: nil,
- message: 'The Zenodo.org/api URLs are not stable, you must use a URL of the format zenodo.org/record/..., apologies we cannot fix automatically.',
+ message: 'The Zenodo.org/api URLs are not stable, you must use a URL of the format zenodo.org/record/...',
code: 'GTN:032'
)
end
diff --git a/bin/news.rb b/bin/news.rb
index a9f3b31bf0dc97..b4cc1efd80bf27 100755
--- a/bin/news.rb
+++ b/bin/news.rb
@@ -20,6 +20,7 @@
exit 1
end
+# rubocop:disable Style/GlobalVars
$rooms = {
'test' => {
server: 'https://matrix.org',
@@ -34,14 +35,17 @@
room: '!yuLoaCWKpFHkWPmVEO:gitter.im',
}
}
-
+# rubocop:enable Style/GlobalVars
+#
addedfiles = `git diff --cached --name-only --ignore-all-space --diff-filter=A #{options[:previousCommit]}`.split("\n")
-modifiedfiles = `git diff --cached --name-only --ignore-all-space --diff-filter=M #{options[:previousCommit]}`.split("\n")
+mfiles = `git diff --cached --name-only --ignore-all-space --diff-filter=M #{options[:previousCommit]}`.split("\n")
# modifiedfiles = `git diff --cached --name-only --ignore-all-space
# --diff-filter=M #{options[:previousCommit]}`.split("\n")
NOW = Time.now
CONTRIBUTORS = YAML.load_file('CONTRIBUTORS.yaml')
+ORGANISATIONS = YAML.load_file('ORGANISATIONS.yaml')
+FUNDERS = YAML.load_file('FUNDERS.yaml')
# new news
# new slidevideos
@@ -96,17 +100,21 @@ def fixNews(n)
news: addedfiles.grep(%r{news/_posts/.*\.md}).map { |x| printableMaterial(x) }.map { |n| fixNews(n) }
},
modified: {
- slides: modifiedfiles
+ slides: mfiles
.select { |x| filterSlides(x) }
.select { |x| onlyEnabled(x) }
.map { |x| printableMaterial(x) },
- tutorials: modifiedfiles
+ tutorials: mfiles
.select { |x| filterTutorials(x) }
.select { |x| onlyEnabled(x) }
.map { |x| printableMaterial(x) },
},
contributors: `git diff --unified --ignore-all-space #{options[:previousCommit]} CONTRIBUTORS.yaml`
- .split("\n").grep(/^\+[^ ]+:\s*$/).map { |x| x.strip[1..-2] }
+ .split("\n").grep(/^\+[^ ]+:\s*$/).map { |x| x.strip[1..-2] },
+ organisations: `git diff --unified --ignore-all-space #{options[:previousCommit]} ORGANISATIONS.yaml`
+ .split("\n").grep(/^\+[^ ]+:\s*$/).map { |x| x.strip[1..-2] },
+ funders: `git diff --unified --ignore-all-space #{options[:previousCommit]} FUNDERS.yaml`
+ .split("\n").grep(/^\+[^ ]+:\s*$/).map { |x| x.strip[1..-2] },
}
def titleize(t)
@@ -125,9 +133,7 @@ def format_news(news)
def format_tutorials(added, modified, kind: 'tutorials', updates: true)
output = ''
count = added.length
- if updates
- count += modified.length
- end
+ count += modified.length if updates
output += "\n\n## #{count} #{kind}!" if count.positive?
if added.length.positive?
@@ -176,12 +182,26 @@ def build_news(data, filter: nil, updates: true)
output += data[:contributors].map { |c| linkify("@#{c}", "hall-of-fame/#{c}") }.join("\n").gsub(/^/, '- ')
end
+ if filter.nil? && data[:organisations].length.positive?
+ newsworthy = true
+ output += "\n\n## #{data[:organisations].length} new organisations!\n\n"
+ output += data[:organisations].map { |c| linkify("@#{c}", "hall-of-fame/#{c}") }.join("\n").gsub(/^/, '- ')
+ end
+
+ if filter.nil? && data[:funders].length.positive?
+ newsworthy = true
+ output += "\n\n## #{data[:funders].length} new funders!\n\n"
+ output += data[:funders].map { |c| linkify("@#{c}", "hall-of-fame/#{c}") }.join("\n").gsub(/^/, '- ')
+ end
+
[output, newsworthy]
end
def send_news(output, options, channel: 'default')
if options[:postToMatrix]
+ # rubocop:disable Style/GlobalVars
homeserver = $rooms[channel]
+ # rubocop:enable Style/GlobalVars
pp homeserver
data = {
@@ -220,9 +240,9 @@ def send_news(output, options, channel: 'default')
end
end
else
- puts "=============="
+ puts '=============='
puts output
- puts "=============="
+ puts '=============='
end
end
diff --git a/bin/schema-contributors.yaml b/bin/schema-contributors.yaml
index ab2c39ddcebd6f..15d008de4d4adb 100644
--- a/bin/schema-contributors.yaml
+++ b/bin/schema-contributors.yaml
@@ -87,6 +87,15 @@ mapping:
enum:
- "no"
description: Set this to `no` if you would like to be excluded from the hall of fame.
+ affiliations:
+ type: seq
+ description: "A set of organisations or grants your are affiliated with"
+ sequence:
+ - type: str
+ required: true
+ enum:
+ - ORGANISATIONS
+ - FUNDERS
elixir_node:
type: str
enum:
@@ -115,35 +124,6 @@ mapping:
description: The 2 letter code identifying the ELIXIR node to which you are a member or are associated with. If you are from norway, you will need to quote your value, `"no"`, unlike everyone else, due to the [Norway Problem with YAML](https://hitchdev.com/strictyaml/why/implicit-typing-removed/)
avatar:
type: str
- funder:
- type: bool
- description: Set this to true if this entity is a funding agency.
- funder_name:
- type: str
- description: A human-readable name which will be the biggest name on their contributor page.
- funding_id:
- type: str
- description: The short identifier for your grant.
- examples:
- - 2020-1-NL01-KA203-064717
- url:
- type: str
- description: associated webpage (NOTE, funders only!)
- examples:
- - "https://elixir-europe.org"
- funding_system:
- type: str
- description: Automatically link to the grant's information in the appropriate funding system site.
- enum:
- - cordis
- - erasmusplus
- - ukri
- funding_statement:
- type: str
- description: A short statement about the funder, markdown is supported.
- examples:
- - This project ([`2020-1-NL01-KA203-064717`](https://ec.europa.eu/programmes/erasmus-plus/projects/eplus-project-details/#project/2020-1-NL01-KA203-064717)) is funded with the support of the Erasmus+ programme of the European Union. Their funding has supported a large number of tutorials within the GTN across a wide array of topics.
-
in_memoriam:
type: str
description: |
@@ -173,4 +153,3 @@ mapping:
description: Longitude in decimal numbers
examples:
- 55.0
-
diff --git a/bin/schema-faq.yaml b/bin/schema-faq.yaml
index d2cae52cec1246..a2ff99632b028b 100644
--- a/bin/schema-faq.yaml
+++ b/bin/schema-faq.yaml
@@ -61,6 +61,7 @@ mapping:
required: true
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
redirect_from:
type: seq
sequence:
diff --git a/bin/schema-funders.yaml b/bin/schema-funders.yaml
new file mode 100644
index 00000000000000..e8de06f0950315
--- /dev/null
+++ b/bin/schema-funders.yaml
@@ -0,0 +1,128 @@
+---
+type: map
+examples: |
+ erasmusplus:
+ name: Erasmus+
+ bio: We funded some of this work!
+mapping:
+ "=":
+ type: map
+ description: |
+ This ideally is your GitHub handle. If you do not have, or do not wish to provide a GitHub username, you may make up another identifier here, but then you must set `github: false` as described below.
+ mapping:
+ name:
+ type: str
+ required: true
+ description: |
+ The full name for the grant
+ examples:
+ - Gallantries: Bridging Training Communities in Life Science, Environment and Health
+ short_name:
+ type: str
+ description: |
+ A shorter name, as some grants love to stuff a lot of words into the title
+ examples:
+ - Gallantries
+ email:
+ type: str
+ pattern: /@/
+ description: |
+ Your email address, if you wish to provide it.
+ examples:
+ - jane.doe@gmail.com
+ twitter:
+ type: str
+ pattern: /[0-9a-zA-Z]+/
+ description: Your twitter handle, without the `@`
+ examples:
+ - gxytraining
+ fediverse:
+ type: str
+ pattern: /^https:\/\/[0-9a-zA-Z.]+/@?[0-9a-zA-Z.]+$/
+ description: The URL to your fediverse profile
+ examples:
+ - http://genomic.social/@abretaud
+ fediverse_flavor:
+ type: str
+ enum:
+ - mastodon
+ - akkoma
+ description: The flavor of the fediverse server (used in our webfinger endpoint.)
+ bio:
+ type: str
+ description: |
+ A short biography of yourself, if you wish to add additional details or context.
+ examples:
+ - Research at the [South African National Bioinformatics Institute](https://www.sanbi.ac.za/)
+ matrix:
+ type: str
+ pattern: /[0-9a-zA-Z]+:.*/
+ description: Your matrix identifier and home server
+ examples:
+ - "hexylena:matrix.org"
+ linkedin:
+ type: str
+ pattern: /[0-9a-zA-Z]+/
+ github:
+ type: bool
+ description: |
+ If your identifier in this file is **not** a GitHub account (or not your account), then this **must** be set to true, so we do not link to that account.
+ orcid:
+ type: str
+ pattern: /[0-9A-Z]{4}-[0-9A-Z]{4}-[0-9A-Z]{4}-[0-9A-Z]{4}/
+ description: Your identifier at orcid.org
+ examples:
+ - 0000-0001-9760-8992
+ joined:
+ type: str
+ pattern: /[0-9]{4,}-[0-9]{2}/
+ description: The year and month in which you joined
+ examples:
+ - 2020-01
+ start_date:
+ type: str
+ pattern: /[0-9]{4,}-[0-9]{2}-[0-9]{2}/
+ description: The start date of the grant
+ examples:
+ - "2020-01-01"
+ end_date:
+ type: str
+ pattern: /[0-9]{4,}-[0-9]{2}-[0-9]{2}/
+ description: The end date of the grant
+ examples:
+ - "2020-01-01"
+ avatar:
+ type: str
+ funder:
+ type: bool
+ description: Set this to true if this entity is a funding agency.
+ required: true
+ enum:
+ - true
+ funding_id:
+ type: str
+ description: The short identifier for your grant.
+ examples:
+ - 2020-1-NL01-KA203-064717
+ url:
+ type: str
+ description: associated webpage (NOTE, funders only!)
+ examples:
+ - "https://elixir-europe.org"
+ funding_system:
+ type: str
+ description: Automatically link to the grant's information in the appropriate funding system site.
+ enum:
+ - cordis
+ - erasmusplus
+ - ukri
+ funder_name:
+ type: str
+ description: A name for the agency providing the funding.
+ examples:
+ - Erasmus+ Programme
+ funding_statement:
+ type: str
+ description: A short statement about the funder, markdown is supported.
+ examples:
+ - This project ([`2020-1-NL01-KA203-064717`](https://ec.europa.eu/programmes/erasmus-plus/projects/eplus-project-details/#project/2020-1-NL01-KA203-064717)) is funded with the support of the Erasmus+ programme of the European Union. Their funding has supported a large number of tutorials within the GTN across a wide array of topics.
diff --git a/bin/schema-learning-pathway.yaml b/bin/schema-learning-pathway.yaml
index 9793edd7eb6c5c..6c628c6d0628b1 100644
--- a/bin/schema-learning-pathway.yaml
+++ b/bin/schema-learning-pathway.yaml
@@ -19,7 +19,12 @@ mapping:
required: true
description: |
Description of the pathway
-
+ type:
+ type: str
+ enum:
+ - use
+ - admin-dev
+ - instructors
cover-image:
type: str
description: cover image
@@ -39,17 +44,17 @@ mapping:
- type: str
required: true
description: A contributor's ID in the CONTRIBUTORS.yaml file.
- #enum:
- #- CONTRIBUTORS
+ enum:
+ - CONTRIBUTORS
funding:
type: seq
description: These entities provided funding support for the development of this resource
sequence:
- type: str
- #enum:
- #- CONTRIBUTORS
-
+ enum:
+ - ORGANISATIONS
+ - FUNDERS
tags:
type: seq
description: Any relevant tags that would help a user discover this LP
diff --git a/bin/schema-news.yaml b/bin/schema-news.yaml
index 130b7a4dd94c17..7159e3de058af4 100644
--- a/bin/schema-news.yaml
+++ b/bin/schema-news.yaml
@@ -34,6 +34,8 @@ mapping:
required: true
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
+ - FUNDERS
description: |
List of tutorial contributors. Please use `contributions` instead as it provides more detailed accounting of tutorial history.
examples:
@@ -69,6 +71,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
editing:
type: seq
description: These entities edited the text, either for spelling and grammar, flow, GTN-fit, or other similar editing categories
@@ -76,6 +79,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
testing:
type: seq
description: These entities tested the tutorial to ensure it works correctly for students, or reported issues with the tutorial.
@@ -83,6 +87,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
ux:
type: seq
description: These entities contributed UX or Design improvements to this tutorial or the GTN as a whole
@@ -90,6 +95,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
infrastructure:
type: seq
description: These entities managed and provided infrastructure to the GTN or for training purposes
@@ -97,13 +103,16 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
+ - FUNDERS
funding:
type: seq
description: These entities provided funding support for the development of this resource
sequence:
- type: str
enum:
- - CONTRIBUTORS
+ - ORGANISATIONS
+ - FUNDERS
translation:
type: seq
description: These entities did translation and localisation work on this resource
@@ -111,6 +120,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
cover:
type: str
description: |
diff --git a/bin/schema-organisations.yaml b/bin/schema-organisations.yaml
new file mode 100644
index 00000000000000..23526bb5f2d80c
--- /dev/null
+++ b/bin/schema-organisations.yaml
@@ -0,0 +1,86 @@
+---
+type: map
+examples: |
+ elixir:
+ name: ELIXIR
+ bio: We contribute as an organisation!
+mapping:
+ "=":
+ type: map
+ description: |
+ This ideally is your GitHub handle. If you do not have, or do not wish to provide a GitHub username, you may make up another identifier here, but then you must set `github: false` as described below.
+ mapping:
+ name:
+ type: str
+ required: true
+ description: |
+ Your preferred name. If you prefer an alias or another name, this is welcome, it does not need to be your legal name.
+ examples:
+ - 张三
+ - Alice
+ - Jane Doe
+ - Madame Tout-le-Monde
+ - Γιάννης Παπαδόπουλος
+ email:
+ type: str
+ pattern: /@/
+ description: |
+ Your email address, if you wish to provide it.
+ examples:
+ - jane.doe@gmail.com
+ twitter:
+ type: str
+ pattern: /[0-9a-zA-Z]+/
+ description: Your twitter handle, without the `@`
+ examples:
+ - gxytraining
+ fediverse:
+ type: str
+ pattern: /^https:\/\/[0-9a-zA-Z.]+/@?[0-9a-zA-Z.]+$/
+ description: The URL to your fediverse profile
+ examples:
+ - http://genomic.social/@abretaud
+ fediverse_flavor:
+ type: str
+ enum:
+ - mastodon
+ - akkoma
+ description: The flavor of the fediverse server (used in our webfinger endpoint.)
+ bio:
+ type: str
+ description: |
+ A short biography of yourself, if you wish to add additional details or context.
+ examples:
+ - Research at the [South African National Bioinformatics Institute](https://www.sanbi.ac.za/)
+ matrix:
+ type: str
+ pattern: /[0-9a-zA-Z]+:.*/
+ description: Your matrix identifier and home server
+ examples:
+ - "hexylena:matrix.org"
+ linkedin:
+ type: str
+ pattern: /[0-9a-zA-Z]+/
+ github:
+ type: bool
+ description: |
+ If your identifier in this file is **not** a GitHub account (or not your account), then this **must** be set to true, so we do not link to that account.
+ orcid:
+ type: str
+ pattern: /[0-9A-Z]{4}-[0-9A-Z]{4}-[0-9A-Z]{4}-[0-9A-Z]{4}/
+ description: Your identifier at orcid.org
+ examples:
+ - 0000-0001-9760-8992
+ joined:
+ type: str
+ pattern: /[0-9]{4,}-[0-9]{2}/
+ description: The year and month in which you joined
+ examples:
+ - 2020-01
+ avatar:
+ type: str
+ url:
+ type: str
+ description: associated webpage (NOTE, funders only!)
+ examples:
+ - "https://elixir-europe.org"
diff --git a/bin/schema-slides.yaml b/bin/schema-slides.yaml
index 829bcd34097f83..cc1e276da31404 100644
--- a/bin/schema-slides.yaml
+++ b/bin/schema-slides.yaml
@@ -83,6 +83,8 @@ mapping:
required: true
enum:
- CONTRIBUTORS
+ - FUNDERS
+ - ORGANISATIONS
description: |
List of tutorial contributors. Please use `contributions` instead as it provides more detailed accounting of tutorial history.
examples:
@@ -118,6 +120,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
editing:
type: seq
description: These entities edited the text, either for spelling and grammar, flow, GTN-fit, or other similar editing categories
@@ -125,6 +128,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
testing:
type: seq
description: These entities tested the tutorial to ensure it works correctly for students, or reported issues with the tutorial.
@@ -132,6 +136,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
ux:
type: seq
description: These entities contributed UX or Design improvements to this tutorial or the GTN as a whole
@@ -139,6 +144,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
infrastructure:
type: seq
description: These entities managed and provided infrastructure to the GTN or for training purposes
@@ -146,13 +152,16 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
+ - FUNDERS
funding:
type: seq
description: These entities provided funding support for the development of this resource
sequence:
- type: str
enum:
- - CONTRIBUTORS
+ - ORGANISATIONS
+ - FUNDERS
translation:
type: seq
description: These entities did translation and localisation work on this resource
@@ -160,6 +169,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
hands_on:
type: str
enum:
diff --git a/bin/schema-tutorial.yaml b/bin/schema-tutorial.yaml
index 2b77723e1bd6a0..5de98f3657c835 100644
--- a/bin/schema-tutorial.yaml
+++ b/bin/schema-tutorial.yaml
@@ -83,6 +83,8 @@ mapping:
required: true
enum:
- CONTRIBUTORS
+ - FUNDERS
+ - ORGANISATIONS
description: |
List of tutorial contributors. Please use `contributions` instead as it provides more detailed accounting of tutorial history.
examples:
@@ -118,6 +120,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
editing:
type: seq
description: These entities edited the text, either for spelling and grammar, flow, GTN-fit, or other similar editing categories
@@ -125,6 +128,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
testing:
type: seq
description: These entities tested the tutorial to ensure it works correctly for students, or reported issues with the tutorial.
@@ -132,6 +136,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
ux:
type: seq
description: These entities contributed UX or Design improvements to this tutorial or the GTN as a whole
@@ -139,6 +144,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
infrastructure:
type: seq
description: These entities managed and provided infrastructure to the GTN or for training purposes
@@ -146,13 +152,16 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
+ - FUNDERS
funding:
type: seq
description: These entities provided funding support for the development of this resource
sequence:
- type: str
enum:
- - CONTRIBUTORS
+ - ORGANISATIONS
+ - FUNDERS
translation:
type: seq
description: These entities did translation and localisation work on this resource
@@ -160,6 +169,7 @@ mapping:
- type: str
enum:
- CONTRIBUTORS
+ - ORGANISATIONS
subtopic:
type: str
description: |
diff --git a/bin/validate-contributors.rb b/bin/validate-contributors.rb
index 84b9ebe15b8a0e..17d8b0a89065e1 100755
--- a/bin/validate-contributors.rb
+++ b/bin/validate-contributors.rb
@@ -6,14 +6,19 @@
require './bin/gtn'
# Any error messages
-errs = []
CONTRIBUTORS_SCHEMA_UNSAFE = YAML.load_file('bin/schema-contributors.yaml')
CONTRIBUTORS_SCHEMA = automagic_loading(CONTRIBUTORS_SCHEMA_UNSAFE)
-
-# Build validators now that we've filled out the subtopic enum
contribs_validator = Kwalify::Validator.new(CONTRIBUTORS_SCHEMA)
+FUNDERS_SCHEMA_UNSAFE = YAML.load_file('bin/schema-funders.yaml')
+FUNDERS_SCHEMA = automagic_loading(FUNDERS_SCHEMA_UNSAFE)
+funders_validator = Kwalify::Validator.new(FUNDERS_SCHEMA)
+
+ORGANISATIONS_SCHEMA_UNSAFE = YAML.load_file('bin/schema-organisations.yaml')
+ORGANISATIONS_SCHEMA = automagic_loading(ORGANISATIONS_SCHEMA_UNSAFE)
+organisations_validator = Kwalify::Validator.new(ORGANISATIONS_SCHEMA)
+
def validate_document(document, validator)
errors = validator.validate(document)
return errors if errors && !errors.empty?
@@ -21,15 +26,27 @@ def validate_document(document, validator)
[]
end
-errs.push(*validate_document(CONTRIBUTORS, contribs_validator))
-
-# If we had no errors, validated successfully
-if errs.empty?
- puts "\e[38;5;40mCONTRIBUTORS.yaml validated succesfully\e[m"
- exit 0
-else
- # Otherwise, print errors and exit non-zero
- puts "\e[48;5;09mCONTRIBUTORS.yaml has errors\e[m"
- errs.each { |x| puts " #{x}" }
- exit 1
+def show_errors(file, errs)
+ # If we had no errors, validated successfully
+ if errs.empty?
+ puts "\e[38;5;40m#{file} validated succesfully\e[m"
+ 0
+ else
+ # Otherwise, print errors and exit non-zero
+ puts "\e[48;5;09m#{file} has errors\e[m"
+ errs.each { |x| puts " #{x}" }
+ 1
+ end
end
+
+ec = 0
+# This variable from bin/gtn.rb
+errs = validate_document(CONTRIBUTORS, contribs_validator)
+ec |= show_errors('CONTRIBUTORS.yaml', errs)
+errs = validate_document(FUNDERS, funders_validator)
+ec |= show_errors('FUNDERS.yaml', errs)
+errs = validate_document(ORGANISATIONS, organisations_validator)
+ec | show_errors('ORGANISATIONS.yaml', errs)
+
+# Exit
+exit ec
diff --git a/learning-pathways/climate-learning.md b/learning-pathways/climate-learning.md
index af5a5130abeaa4..b38075e27078f5 100644
--- a/learning-pathways/climate-learning.md
+++ b/learning-pathways/climate-learning.md
@@ -3,7 +3,7 @@ layout: learning-pathway
title: Discovering galaxy through climate analysis
description: |
- How to have a complete overview of how Galaxy works going from the user welcome page to use batch tools and finishing by conducting interactive analysis. These set of 3 Climate tutorials allow you to understand and see plenty of the multiple features of Galaxy and learning about the cool subject of climate analysis.
+ How to have a complete overview of how Galaxy works going from the user welcome page to use batch tools and finishing by conducting interactive analysis. These set of 3 Climate tutorials allow you to understand and see plenty of the multiple features of Galaxy and learning about the cool subject of climate analysis.
tags: [Climate, Overview]
editorial_board:
diff --git a/licenses.md b/licenses.md
index 810472d51cc9b1..3abe4c73009c0d 100644
--- a/licenses.md
+++ b/licenses.md
@@ -3,6 +3,12 @@ layout: page
title: Licenses
---
+# Image Credits
+
+Our default avatar is from https://thenounproject.com/icon/users-1926333/ available under CC-BY
+
+# Fonts
+
## Atkinson Hyperlegible
diff --git a/metadata/funders.yaml b/metadata/funders.yaml
new file mode 120000
index 00000000000000..d0859efd5ab683
--- /dev/null
+++ b/metadata/funders.yaml
@@ -0,0 +1 @@
+../FUNDERS.yaml
\ No newline at end of file
diff --git a/metadata/organisations.yaml b/metadata/organisations.yaml
new file mode 120000
index 00000000000000..496308dfa0458d
--- /dev/null
+++ b/metadata/organisations.yaml
@@ -0,0 +1 @@
+../ORGANISATIONS.yaml
\ No newline at end of file
diff --git a/news.md b/news.md
index d8cbafd8293bca..1cc67a73fa4bf2 100644
--- a/news.md
+++ b/news.md
@@ -3,8 +3,6 @@ layout: page
title: The Latest GTN News
---
-{% assign contributors = site.data['contributors'] %}
-
Keep an eye on this page for the latest news around the GTN. New tutorials, GTN features, upcoming training events, and much much more!
Want to add your own news here (e.g. new tutorial, event, publication, anything else training related)? Check out how to do that in [this FAQ]({% link faqs/gtn/gtn_news_create_post.md %})
diff --git a/topics/contributing/tutorials/schemas/tutorial.md b/topics/contributing/tutorials/schemas/tutorial.md
index f61382fda56f8d..ba2fcdcd7480de 100644
--- a/topics/contributing/tutorials/schemas/tutorial.md
+++ b/topics/contributing/tutorials/schemas/tutorial.md
@@ -10,18 +10,18 @@ contributors:
- hexylena
---
+## Training Materials
+
{% assign kid_key = "Tutorial Schema" %}
{% assign kid_val = site.data['schema-tutorial'] %}
{% include _includes/schema-render.html key=kid_key value=kid_val %}
-{% assign kid_key = "Contributor Schema" %}
-{% assign kid_val = site.data['schema-contributors'] %}
-{% include _includes/schema-render.html key=kid_key value=kid_val %}
-
{% assign kid_key = "Slides Schema" %}
{% assign kid_val = site.data['schema-slides'] %}
{% include _includes/schema-render.html key=kid_key value=kid_val %}
+## GTN Resources
+
{% assign kid_key = "FAQ Schema" %}
{% assign kid_val = site.data['schema-faq'] %}
{% include _includes/schema-render.html key=kid_key value=kid_val %}
@@ -41,3 +41,17 @@ contributors:
{% assign kid_key = "News" %}
{% assign kid_val = site.data['schema-news'] %}
{% include _includes/schema-render.html key=kid_key value=kid_val %}
+
+## Contributors
+
+{% assign kid_key = "Contributor Schema" %}
+{% assign kid_val = site.data['schema-contributors'] %}
+{% include _includes/schema-render.html key=kid_key value=kid_val %}
+
+{% assign kid_key = "Organisation Schema" %}
+{% assign kid_val = site.data['schema-organisations'] %}
+{% include _includes/schema-render.html key=kid_key value=kid_val %}
+
+{% assign kid_key = "Funder Schema" %}
+{% assign kid_val = site.data['schema-funders'] %}
+{% include _includes/schema-render.html key=kid_key value=kid_val %}