Class: Jekyll::Ett::ToolTag
- Inherits:
-
Liquid::Tag
- Object
- Liquid::Tag
- Jekyll::Ett::ToolTag
- Defined in:
- lib/elixir-toolkit-theme-plugins/tool_tag.rb
Constant Summary collapse
- TOOLS_PATH =
File.join(Dir.pwd, "_data", "tool_and_resource_list.yml")
- @@instances_by_tool =
nil
Class Method Summary collapse
- .build_instances_index ⇒ Object
-
.extract_front_matter(file_string) ⇒ Object
shared front-matter parser (class-level).
-
.instances_index ⇒ Object
--- class-level accessor used by both tag and filters ---.
Instance Method Summary collapse
- #create_tag(url, icon, label) ⇒ Object
- #create_tags(tool, site) ⇒ Object
- #find_tool(tool_id) ⇒ Object
- #html_attr(s) ⇒ Object
-
#html_escape(s) ⇒ Object
--- escaping helpers ---.
-
#initialize(tagName, content, tokens) ⇒ ToolTag
constructor
A new instance of ToolTag.
- #instances_dropdown(instances, site, tool_id) ⇒ Object
-
#load_instances ⇒ Object
instance-level wrapper uses the shared index.
- #load_tools ⇒ Object
- #render(context) ⇒ Object
-
#resolve_page_url(abs_path, site) ⇒ Object
Resolve a site-relative URL from an absolute file path stored in page_path.
Constructor Details
#initialize(tagName, content, tokens) ⇒ ToolTag
Returns a new instance of ToolTag.
10 11 12 13 14 15 |
# File 'lib/elixir-toolkit-theme-plugins/tool_tag.rb', line 10 def initialize(tagName, content, tokens) super @content = content load_tools load_instances end |
Class Method Details
.build_instances_index ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/elixir-toolkit-theme-plugins/tool_tag.rb', line 26 def self.build_instances_index instances_by_tool = Hash.new { |h, k| h[k] = [] } tools = YAML.load(File.read(TOOLS_PATH)) # 1) instances from national_resources in page front matter pages_path = File.join(Dir.pwd, "**", "*.md") files = Dir.glob(pages_path) files.each do |f| raw = File.read(f) fm = extract_front_matter(raw) next unless fm.is_a?(Hash) country_code = (fm["country_code"] || "").to_s country_name = (fm["title"] || "").to_s resources = fm["national_resources"] || [] next unless resources.is_a?(Array) resources.each do |res| next unless res.is_a?(Hash) inst_of = res["instance_of"] next if inst_of.nil? || inst_of == "NA" instances_by_tool[inst_of] << { "name" => (res["name"] || res["id"] || "Instance"), "url" => res["url"], "id" => res["id"], "country_code" => country_code, "country_name" => country_name, "page_path" => f } end end # 2) instances from tool_and_resource_list.yml itself (tools || []).each do |tool| parent_id = tool["instance_of"] next if parent_id.nil? || parent_id == "NA" instances_by_tool[parent_id] << { "name" => (tool["name"] || tool["id"] || "Instance"), "url" => tool["url"], "id" => tool["id"], "country_code" => "", "country_name" => "", "page_path" => nil } end instances_by_tool end |
.extract_front_matter(file_string) ⇒ Object
shared front-matter parser (class-level)
80 81 82 83 84 85 86 87 88 89 |
# File 'lib/elixir-toolkit-theme-plugins/tool_tag.rb', line 80 def self.extract_front_matter(file_string) if file_string =~ /\A---\s*\n(.*?)\n---\s*\n/m yaml = Regexp.last_match(1) YAML.safe_load(yaml, permitted_classes: [Date, Time], aliases: true) else nil end rescue nil end |
.instances_index ⇒ Object
--- class-level accessor used by both tag and filters ---
22 23 24 |
# File 'lib/elixir-toolkit-theme-plugins/tool_tag.rb', line 22 def self.instances_index @@instances_by_tool ||= build_instances_index end |
Instance Method Details
#create_tag(url, icon, label) ⇒ Object
136 137 138 |
# File 'lib/elixir-toolkit-theme-plugins/tool_tag.rb', line 136 def create_tag(url, icon, label) "<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>" end |
#create_tags(tool, site) ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/elixir-toolkit-theme-plugins/tool_tag.rb', line 120 def (tool, site) = "" << create_tag("#{tool["url"]}", "fa-link", "Website") if tool["registry"] registry = tool["registry"] << create_tag("https://bio.tools/#{registry["biotools"]}", "fa-info", "Tool info") if registry["biotools"] && registry["biotools"] != "NA" << create_tag("https://fairsharing.org/FAIRsharing.#{registry["fairsharing"]}", "fa-database", "Standards/Databases") if registry["fairsharing"] && registry["fairsharing"] != "NA" << create_tag("https://tess.elixir-europe.org/search?q=#{registry["tess"]}", "fa-graduation-cap", "Training") if registry["tess"] && registry["tess"] != "NA" << create_tag("https://europepmc.org/article/MED/#{registry["europmc"]}", "fa-book", "Publication") if registry["europmc"] && registry["europmc"] != "NA" end instances = @instances_by_tool[tool["id"]] << instances_dropdown(instances, site, tool["id"]) if instances && !instances.empty? end |
#find_tool(tool_id) ⇒ Object
114 115 116 117 118 |
# File 'lib/elixir-toolkit-theme-plugins/tool_tag.rb', line 114 def find_tool(tool_id) tool = @tools.find { |t| t["id"] == tool_id.strip } return tool if tool raise Exception.new "Undefined tool ID: #{tool_id}" end |
#html_attr(s) ⇒ Object
183 184 185 |
# File 'lib/elixir-toolkit-theme-plugins/tool_tag.rb', line 183 def html_attr(s) html_escape(s).gsub("'","'") end |
#html_escape(s) ⇒ Object
--- escaping helpers ---
179 180 181 |
# File 'lib/elixir-toolkit-theme-plugins/tool_tag.rb', line 179 def html_escape(s) (s || "").to_s.gsub("&","&").gsub("<","<").gsub(">",">").gsub('"',""") end |
#instances_dropdown(instances, site, tool_id) ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/elixir-toolkit-theme-plugins/tool_tag.rb', line 140 def instances_dropdown(instances, site, tool_id) dd_id = "instances-dd-#{tool_id}-#{object_id}" items = instances.map do |inst| href = inst["url"] || resolve_page_url(inst["page_path"], site) || "#" flag = inst["country_code"].to_s.strip.empty? ? "" : "<span class='flag-icon ms-2 shadow-sm flag-icon-#{inst["country_code"].downcase}'></span>" name = html_escape(inst["name"]) url = html_attr(href) "<li><a class='dropdown-item' href='#{url}' target='_blank' rel='noopener'>#{name} #{flag}</a></li>" end.join %Q{ <div class='dropdown d-inline-block'> <button class='btn btn-badge btn-outline-primary dropdown-toggle' type='button' id='#{dd_id}' data-bs-toggle='dropdown' aria-expanded='false'> <i class='fa-solid fa-globe me-2'></i>Instances </button> <ul class='dropdown-menu' aria-labelledby='#{dd_id}'> #{items} </ul> </div> } end |
#load_instances ⇒ Object
instance-level wrapper uses the shared index
92 93 94 |
# File 'lib/elixir-toolkit-theme-plugins/tool_tag.rb', line 92 def load_instances @instances_by_tool = self.class.instances_index end |
#load_tools ⇒ Object
17 18 19 |
# File 'lib/elixir-toolkit-theme-plugins/tool_tag.rb', line 17 def load_tools @tools = YAML.load(File.read(TOOLS_PATH)) end |
#render(context) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/elixir-toolkit-theme-plugins/tool_tag.rb', line 96 def render(context) site = context.registers[:site] tool_id_from_liquid = context[@content.strip] tool = find_tool(tool_id_from_liquid) = (tool, site) %Q{<a tabindex="0" class="tool" aria-description="#{html_escape(tool["description"])}" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-trigger="focus" 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'>#{}</div>" 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>" data-bs-html="true" ><i class="fa-solid fa-wrench fa-sm me-2"></i>#{ html_escape(tool["name"]) }</a>} end |
#resolve_page_url(abs_path, site) ⇒ Object
Resolve a site-relative URL from an absolute file path stored in page_path
168 169 170 171 172 173 174 175 |
# File 'lib/elixir-toolkit-theme-plugins/tool_tag.rb', line 168 def resolve_page_url(abs_path, site) return nil unless abs_path && site rel = abs_path.sub(%r{\A#{Regexp.escape(Dir.pwd)}/?}, "") doc = (site.pages + site.collections.values.flat_map(&:docs)).find { |p| p.path == rel } doc&.url rescue nil end |