elixir-toolkit-theme-plugins 0.1.9 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5bb1cdc151230795119279aefda1cc3585465ec27f09d4d6f0f0b6dbcab68ba2
4
- data.tar.gz: cce47064f65e42a8fce979c6187d6922d8e62d6d1e54d1e93344a4e0c25745be
3
+ metadata.gz: 34f25d1dcf2409c807016000b18943617c1c16311b69e93ca1270cdf7ea64ef4
4
+ data.tar.gz: 60bc0906be8a455f57c82ed82b18ff5173c506c10ff6cf6e774a492d11b37e92
5
5
  SHA512:
6
- metadata.gz: dec119a2285b73ddf1ff833f29b67f39283579edcff14a400d4a51be1a53b00e4a1a1e3f3a07e3af6b727041751ba440c20d30d2c16fa57123fbf40f1fb1a1f9
7
- data.tar.gz: f513d5e4f734bc845b7f55ee5b1fc7bf1262f782bdce7108f0e944268c22ad637a81007e75bf369c78302e9ceaa11c806edd23dff96e3152304dd8641f441b34
6
+ metadata.gz: 0a4c3978c495d6c9d8c4236c086d0d8edc101ccf206ace362d129aadeaafe15756285a07cbfc8df7ca19afbb8cbafe43805c1e9316563acb1f19f3047da3f09a
7
+ data.tar.gz: 88a77667e160b4049b564c63f95f24393b5332aa531395dd5fbefffb0808a7dbe3ec082e9206c6d7c2646f1fa90be4aa3104ff15f97858553ea3846b824d90a4
@@ -11,11 +11,13 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
 
13
13
  steps:
14
- - uses: actions/checkout@v3
15
- - name: Set up Ruby 3.1
16
- uses: actions/setup-ruby@v1
14
+ - uses: actions/checkout@v5
15
+ - name: Set up Ruby 3.3
16
+ uses: ruby/setup-ruby@v1.204.0
17
17
  with:
18
- ruby-version: 3.1
18
+ ruby-version: '3.3'
19
+ bundler-cache: true
20
+ cache-version: 0
19
21
 
20
22
  - name: Publish to GPR
21
23
  run: |
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.name = "elixir-toolkit-theme-plugins"
10
10
  spec.version = Jekyll::Ett::VERSION.dup
11
11
  spec.authors = ["bedroesb", "janslifka", "MarekSuchanek"]
12
- spec.email = ["bedro@psb.vib-ugent.be\n"]
12
+ spec.email = ["bert.droesbeke@vib.be\n"]
13
13
 
14
14
  spec.summary = "Plugins to work together with ELIXIR Toolkit theme"
15
15
  spec.homepage = "https://elixir-belgium.github.io/elixir-toolkit-theme-plugins/"
@@ -1,15 +1,20 @@
1
1
  require "jekyll"
2
-
2
+ require "set"
3
3
 
4
4
  module Jekyll
5
5
  class Ett
6
6
  module ToolTableFilter
7
7
  def add_related_pages(data)
8
+ return [] if data.nil?
9
+ return data unless data.is_a?(Array)
10
+
8
11
  load_page_data
9
12
 
10
- for tool in data
11
- if tool['id'] && @related_pages[tool['id']]
12
- tool['related_pages'] = @related_pages[tool['id']].to_a
13
+ data.each do |tool|
14
+ next unless tool.is_a?(Hash)
15
+
16
+ if tool["id"] && @related_pages[tool["id"]]
17
+ tool["related_pages"] = @related_pages[tool["id"]].to_a
13
18
  end
14
19
  end
15
20
 
@@ -21,20 +26,23 @@ module Jekyll
21
26
  def load_page_data
22
27
  @related_pages = {}
23
28
  pages_path = File.join(Dir.pwd, "**", "*.md")
29
+
24
30
  Dir.glob(pages_path).each do |f|
25
31
  file = File.read(f)
26
32
  page_id_matches = file.match(/page_id:\s*(\w+)/)
27
-
28
- if page_id_matches
29
- page_id = page_id_matches[1]
30
- file.scan(/\{%\s*tool\s*"([^"]+)"\s*%}/).flatten.each do |m|
31
- @related_pages[m] = Set[] unless @related_pages[m]
32
- @related_pages[m].add(page_id)
33
- end
33
+
34
+ next unless page_id_matches
35
+
36
+ page_id = page_id_matches[1]
37
+
38
+ file.scan(/\{%\s*tool\s*"([^"]+)"\s*%}/).flatten.each do |m|
39
+ @related_pages[m] ||= Set.new
40
+ @related_pages[m].add(page_id)
34
41
  end
35
42
  end
36
43
  end
37
44
  end
38
45
  end
46
+
39
47
  Liquid::Template.register_filter(Jekyll::Ett::ToolTableFilter)
40
48
  end
@@ -1,76 +1,178 @@
1
1
  require "jekyll"
2
-
2
+ require "yaml"
3
3
 
4
4
  module Jekyll
5
5
  class Ett
6
6
  class ToolTag < Liquid::Tag
7
- def initialize(tagName, content, tokens)
8
- super
9
- @content = content
10
- load_tools
7
+ def initialize(tagName, content, tokens)
8
+ super
9
+ @content = content
10
+ load_tools
11
+ load_instances
12
+ end
13
+
14
+ def load_tools
15
+ tools_path = File.join(Dir.pwd, "_data", "tool_and_resource_list.yml")
16
+ @tools = YAML.load(File.read(tools_path))
17
+ end
18
+
19
+ # Scan Markdown pages for front matter declaring national_resources
20
+ # and index instances by their "instance_of" tool id
21
+ def load_instances
22
+ # Single combined index for *all* instances
23
+ @instances_by_tool = Hash.new { |h, k| h[k] = [] }
24
+
25
+ # --- 1) instances from national_resources in page front matter ---
26
+ pages_path = File.join(Dir.pwd, "**", "*.md")
27
+ files = Dir.glob(pages_path)
28
+
29
+ files.each do |f|
30
+ raw = File.read(f)
31
+ fm = extract_front_matter(raw)
32
+ next unless fm.is_a?(Hash)
33
+
34
+ country_code = (fm["country_code"] || "").to_s
35
+ country_name = (fm["title"] || "").to_s
36
+ resources = fm["national_resources"] || []
37
+ next unless resources.is_a?(Array)
38
+
39
+ resources.each do |res|
40
+ next unless res.is_a?(Hash)
41
+ inst_of = res["instance_of"]
42
+ next if inst_of.nil? || inst_of == "NA"
43
+
44
+ @instances_by_tool[inst_of] << {
45
+ "name" => (res["name"] || res["id"] || "Instance"),
46
+ "url" => res["url"],
47
+ "id" => res["id"],
48
+ "country_code" => country_code,
49
+ "country_name" => country_name,
50
+ "page_path" => f
51
+ }
11
52
  end
53
+ end
54
+
55
+ # --- 2) instances from tool_and_resource_list.yml itself ---
56
+ (@tools || []).each do |tool|
57
+ parent_id = tool["instance_of"]
58
+ next if parent_id.nil? || parent_id == "NA"
12
59
 
13
- def load_tools
14
- tools_path = File.join(Dir.pwd, "_data", "tool_and_resource_list.yml")
15
- @tools = YAML.load(File.read(tools_path))
60
+ @instances_by_tool[parent_id] << {
61
+ "name" => (tool["name"] || tool["id"] || "Instance"),
62
+ "url" => tool["url"], # normally defined for tools
63
+ "id" => tool["id"],
64
+ # YAML entries often don’t have country information; leave blank so no flag
65
+ "country_code" => "",
66
+ "country_name" => "",
67
+ "page_path" => nil # no page file to resolve
68
+ }
16
69
  end
70
+ end
71
+
17
72
 
18
- def render(context)
19
- tool = find_tool(context[@content.strip])
20
- tags = create_tags(tool)
21
- %Q{<a
22
- tabindex="0"
23
- class="tool"
24
- aria-description="#{tool["description"]}"
25
- data-bs-toggle="popover"
26
- data-bs-placement="bottom"
27
- data-bs-trigger="focus"
28
- data-bs-content="<h5>#{tool["name"]}</h5><div class='mb-2'>#{tool["description"]}</div>#{tags}"
29
- data-bs-template="<div class='popover popover-tool' role='tooltip'><div class='popover-arrow'></div><h3 class='popover-header'></h3><div class='popover-body'></div></div>"
30
- data-bs-html="true"
31
- ><i class="fa-solid fa-wrench fa-sm me-2"></i>#{ tool["name"] }</a>}
73
+ # Accepts a file string, returns parsed YAML front matter hash or nil
74
+ def extract_front_matter(file_string)
75
+ if file_string =~ /\A---\s*\n(.*?)\n---\s*\n/m
76
+ yaml = Regexp.last_match(1)
77
+ YAML.safe_load(yaml, permitted_classes: [Date, Time], aliases: true)
78
+ else
79
+ nil
32
80
  end
81
+ rescue
82
+ nil
83
+ end
33
84
 
34
- def find_tool(tool_id)
35
- tool = @tools.find { |t| t["id"] == tool_id.strip }
36
- return tool if tool
37
-
38
- raise Exception.new "Undefined tool ID: #{tool_id}"
85
+ def render(context)
86
+ site = context.registers[:site]
87
+ tool_id_from_liquid = context[@content.strip]
88
+ tool = find_tool(tool_id_from_liquid)
89
+ tags = create_tags(tool, site)
90
+ %Q{<a
91
+ tabindex="0"
92
+ class="tool"
93
+ aria-description="#{html_escape(tool["description"])}"
94
+ data-bs-toggle="popover"
95
+ data-bs-placement="bottom"
96
+ data-bs-trigger="focus"
97
+ data-bs-content="<h5>#{html_escape(tool["name"])}</h5><div class='mb-2'>#{html_escape(tool["description"])}</div><div class='d-flex flex-wrap gap-1'>#{tags}</div>"
98
+ data-bs-template="<div class='popover popover-tool' role='tooltip'><div class='popover-arrow'></div><h3 class='popover-header'></h3><div class='popover-body'></div></div>"
99
+ data-bs-html="true"
100
+ ><i class="fa-solid fa-wrench fa-sm me-2"></i>#{ html_escape(tool["name"]) }</a>}
101
+ end
102
+
103
+ def find_tool(tool_id)
104
+ tool = @tools.find { |t| t["id"] == tool_id.strip }
105
+ return tool if tool
106
+ raise Exception.new "Undefined tool ID: #{tool_id}"
107
+ end
108
+
109
+ def create_tags(tool, site)
110
+ tags = ""
111
+ tags << create_tag("#{tool["url"]}", "fa-link", "Website")
112
+ if tool["registry"]
113
+ registry = tool["registry"]
114
+ tags << create_tag("https://bio.tools/#{registry["biotools"]}", "fa-info", "Tool info") if registry["biotools"] && registry["biotools"] != "NA"
115
+ tags << create_tag("https://fairsharing.org/FAIRsharing.#{registry["fairsharing"]}", "fa-database", "Standards/Databases") if registry["fairsharing"] && registry["fairsharing"] != "NA"
116
+ tags << create_tag("https://fairsharing.org/#{registry["fairsharing-coll"]}", "fa-database", "Standards/Databases") if registry["fairsharing-coll"] && registry["fairsharing-coll"] != "NA"
117
+ tags << create_tag("https://tess.elixir-europe.org/search?q=#{registry["tess"]}", "fa-graduation-cap", "Training") if registry["tess"] && registry["tess"] != "NA"
118
+ tags << create_tag("https://europepmc.org/article/MED/#{registry["europmc"]}", "fa-book", "Publication") if registry["europmc"] && registry["europmc"] != "NA"
39
119
  end
40
120
 
41
- def create_tags(tool)
42
- tags = ""
43
- tags << create_tag("#{tool["url"]}", "fa-link", "Website")
44
- if tool["registry"]
45
- registry = tool["registry"]
121
+ instances = @instances_by_tool[tool["id"]]
122
+ tags << instances_dropdown(instances, site, tool["id"]) if instances && !instances.empty?
123
+ tags
124
+ end
46
125
 
47
- if registry["biotools"]
48
- tags << create_tag("https://bio.tools/#{registry["biotools"]}", "fa-info", "Tool info")
49
- end
126
+ def create_tag(url, icon, label)
127
+ "<a href='#{html_attr(url)}' target='_blank' rel='noopener'><span class='badge bg-dark text-white hover-primary'><i class='fa-solid #{icon} me-2'></i>#{html_escape(label)}</span></a>"
128
+ end
50
129
 
51
- if registry["fairsharing"]
52
- tags << create_tag("https://fairsharing.org/FAIRsharing.#{registry["fairsharing"]}", "fa-database", "Standards/Databases")
53
- end
130
+ def instances_dropdown(instances, site, tool_id)
131
+ dd_id = "instances-dd-#{tool_id}-#{object_id}"
54
132
 
55
- if registry["fairsharing-coll"]
56
- tags << create_tag("https://fairsharing.org/#{registry["fairsharing-coll"]}", "fa-database", "Standards/Databases")
57
- end
133
+ items = instances.map do |inst|
134
+ href = inst["url"] || resolve_page_url(inst["page_path"], site) || "#"
135
+ flag = inst["country_code"].to_s.strip.empty? ? "" : "<span class='flag-icon ms-2 shadow-sm flag-icon-#{inst["country_code"].downcase}'></span>"
136
+ name = html_escape(inst["name"])
137
+ url = html_attr(href)
138
+ "<li><a class='dropdown-item' href='#{url}' target='_blank' rel='noopener'>#{name} #{flag}</a></li>"
139
+ end.join
58
140
 
59
- if registry["tess"]
60
- tags << create_tag("https://tess.elixir-europe.org/search?q=#{registry["tess"]}", "fa-graduation-cap", "Training")
61
- end
141
+ %Q{
142
+ <div class='dropdown d-inline-block'>
143
+ <button class='btn btn-badge btn-outline-primary dropdown-toggle'
144
+ type='button'
145
+ id='#{dd_id}'
146
+ data-bs-toggle='dropdown'
147
+ aria-expanded='false'>
148
+ <i class='fa-solid fa-globe me-2'></i>Instances
149
+ </button>
150
+ <ul class='dropdown-menu' aria-labelledby='#{dd_id}'>
151
+ #{items}
152
+ </ul>
153
+ </div>
154
+ }
155
+ end
62
156
 
63
- if registry["europmc"]
64
- tags << create_tag("https://europepmc.org/article/MED/#{registry["europmc"]}", "fa-book", "Publication")
65
- end
157
+ # Resolve a site-relative URL from an absolute file path stored in page_path
158
+ def resolve_page_url(abs_path, site)
159
+ return nil unless abs_path && site
160
+ rel = abs_path.sub(%r{\A#{Regexp.escape(Dir.pwd)}/?}, "")
161
+ doc = (site.pages + site.collections.values.flat_map(&:docs)).find { |p| p.path == rel }
162
+ doc&.url
163
+ rescue
164
+ nil
165
+ end
66
166
 
67
- end
68
- tags
69
- end
167
+ # --- escaping helpers ---
70
168
 
71
- def create_tag(url, icon, label)
72
- "<a href='#{url}' target='_blank' rel='noopener' class='mt-2 me-2'><span class='badge bg-dark text-white hover-primary'><i class='fa-solid #{icon} me-2'></i>#{label}</span></a>"
73
- end
169
+ def html_escape(s)
170
+ (s || "").to_s.gsub("&","&amp;").gsub("<","&lt;").gsub(">","&gt;").gsub('"',"&quot;")
171
+ end
172
+
173
+ def html_attr(s)
174
+ html_escape(s).gsub("'","&#39;")
175
+ end
74
176
  end
75
177
  end
76
178
  Liquid::Template.register_tag("tool", Jekyll::Ett::ToolTag)
@@ -1,5 +1,5 @@
1
1
  module Jekyll
2
2
  class Ett
3
- VERSION = '0.1.9'
3
+ VERSION = '1.0.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elixir-toolkit-theme-plugins
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - bedroesb
8
8
  - janslifka
9
9
  - MarekSuchanek
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-07-26 00:00:00.000000000 Z
13
+ date: 2025-12-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: jekyll
@@ -46,9 +46,9 @@ dependencies:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
48
  version: '12.0'
49
- description:
49
+ description:
50
50
  email:
51
- - 'bedro@psb.vib-ugent.be
51
+ - 'bert.droesbeke@vib.be
52
52
 
53
53
  '
54
54
  executables: []
@@ -69,7 +69,7 @@ homepage: https://elixir-belgium.github.io/elixir-toolkit-theme-plugins/
69
69
  licenses:
70
70
  - MIT
71
71
  metadata: {}
72
- post_install_message:
72
+ post_install_message:
73
73
  rdoc_options: []
74
74
  require_paths:
75
75
  - lib
@@ -84,8 +84,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
84
  - !ruby/object:Gem::Version
85
85
  version: '0'
86
86
  requirements: []
87
- rubygems_version: 3.3.26
88
- signing_key:
87
+ rubygems_version: 3.5.22
88
+ signing_key:
89
89
  specification_version: 4
90
90
  summary: Plugins to work together with ELIXIR Toolkit theme
91
91
  test_files: []