Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions _includes/components/atoms/real-resources.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,25 @@
placeholders (example.com) and keeping one entry per resource name.
Usage: {% assign topic_data = site.data[page.lang][page.data_folder] %}{% include components/atoms/real-resources.html node=topic_data %}
Sets: real_resources (array of {name, url, description, …}), real_resource_total (number)
Accepts a node whose values are resource lists (category files) or folders of lists (subcategories).
Accepts a subcategory (type → list), a category (files and subcategory folders) or a whole language.
{%- endcomment -%}
{%- comment -%} Up to three levels: lists of resources, files (type → list), and folders (subcategory → files). {%- endcomment -%}
{%- assign real_collected = '' | split: '' -%}
{%- for entry in include.node -%}
{%- assign entry_value = entry[1] -%}
{%- if entry_value.first.url or entry_value.first.name -%}
{%- for r in entry_value -%}{%- if r.url -%}{%- unless r.url contains 'example.com' -%}{%- assign real_collected = real_collected | push: r -%}{%- endunless -%}{%- endif -%}{%- endfor -%}
{%- assign level1 = entry[1] -%}
{%- if level1.first.url or level1.first.name -%}
{%- for r in level1 -%}{%- if r.url -%}{%- unless r.url contains 'example.com' -%}{%- assign real_collected = real_collected | push: r -%}{%- endunless -%}{%- endif -%}{%- endfor -%}
{%- else -%}
{%- for file in entry_value -%}
{%- if file[1].first.url -%}{%- for r in file[1] -%}{%- if r.url -%}{%- unless r.url contains 'example.com' -%}{%- assign real_collected = real_collected | push: r -%}{%- endunless -%}{%- endif -%}{%- endfor -%}{%- endif -%}
{%- for child in level1 -%}
{%- assign level2 = child[1] -%}
{%- if level2.first.url or level2.first.name -%}
{%- for r in level2 -%}{%- if r.url -%}{%- unless r.url contains 'example.com' -%}{%- assign real_collected = real_collected | push: r -%}{%- endunless -%}{%- endif -%}{%- endfor -%}
{%- else -%}
{%- for file in level2 -%}
{%- assign level3 = file[1] -%}
{%- if level3.first.url -%}{%- for r in level3 -%}{%- if r.url -%}{%- unless r.url contains 'example.com' -%}{%- assign real_collected = real_collected | push: r -%}{%- endunless -%}{%- endif -%}{%- endfor -%}{%- endif -%}
{%- endfor -%}
{%- endif -%}
{%- endfor -%}
{%- endif -%}
{%- endfor -%}
Expand Down
4 changes: 2 additions & 2 deletions _includes/components/organisms/footer.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
{%- assign footer_menu = site.data[footer_lang].menu -%}
{%- assign footer_subcategories = 0 -%}{%- assign footer_sections = 0 -%}
{%- for category in footer_menu -%}{%- assign footer_subcategories = footer_subcategories | plus: category.children.size -%}{%- for subcategory in category.children -%}{%- assign footer_sections = footer_sections | plus: subcategory.children.size -%}{%- endfor -%}{%- endfor -%}
{%- assign footer_data = site.data[footer_lang] -%}{%- include components/atoms/real-resources.html node=footer_data -%}
{%- assign footer_resources = real_resource_total -%}
{%- comment -%} Computed once per build by _plugins/resource_stats.rb. {%- endcomment -%}
{%- assign footer_resources = site.data.resource_stats[footer_lang].resources | default: 0 -%}

<footer class="bg-white border-t border-gray-200 pt-10 pb-8 mt-10 text-sm">
<div class="container mx-auto px-4">
Expand Down
4 changes: 1 addition & 3 deletions _layouts/categories.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
{%- assign subcategory_total = subcategory_total | plus: category.children.size -%}
{%- for subcategory in category.children -%}{%- assign section_total = section_total | plus: subcategory.children.size -%}{%- endfor -%}
{%- endfor -%}
{%- assign library_data = site.data[lang] -%}
{%- include components/atoms/real-resources.html node=library_data -%}
{%- assign library_resources = real_resource_total -%}
{%- assign library_resources = site.data.resource_stats[lang].resources | default: 0 -%}
{%- assign issue_body = page.url | absolute_url | url_encode -%}
{%- capture suggest_title -%}{% if pt %}Sugestão de categoria ou recurso{% else %}Category or resource suggestion{% endif %}{%- endcapture -%}
{%- assign suggest_title_enc = suggest_title | url_encode -%}
Expand Down
15 changes: 7 additions & 8 deletions _layouts/topic.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,10 @@
{%- if parent -%}{%- assign level = 'subcategory' -%}{%- endif -%}
{%- assign children = node.children | default: page.children -%}
{%- assign url_parts = page.url | split: '/' -%}
{%- if level == 'subcategory' -%}
{%- assign topic_data = site.data[lang][url_parts[2]][url_parts[3]] -%}
{%- else -%}
{%- assign topic_data = site.data[lang][url_parts[2]] -%}
{%- endif -%}
{%- comment -%} Liquid 4 cannot parse nested brackets (data[a[2]]), so the path parts are assigned first. {%- endcomment -%}
{%- assign category_key = url_parts[2] -%}{%- assign subcategory_key = url_parts[3] -%}
{%- assign topic_data = site.data[lang][category_key] -%}
{%- if level == 'subcategory' -%}{%- assign topic_data = topic_data[subcategory_key] -%}{%- endif -%}
{%- include components/atoms/real-resources.html node=topic_data -%}
{%- assign section_total = 0 -%}
{%- if level == 'category' -%}{%- for child in children -%}{%- assign section_total = section_total | plus: child.children.size -%}{%- endfor -%}{%- endif -%}
Expand Down Expand Up @@ -151,10 +150,10 @@ <h2 id="resources" class="text-xl font-semibold border-b border-gray-200 pb-2 mb
{%- endif -%}
{%- assign shown = '' | split: '' -%}
{%- for resource_type in resource_types -%}
{%- assign rt = resource_type | split: '|' -%}
{%- assign rt = resource_type | split: '|' -%}{%- assign rt_key = rt[0] -%}
{%- assign listed = '' | split: '' -%}
{%- for r in real_resources -%}{%- if r.ipl_group == rt[0] -%}{%- assign listed = listed | push: r -%}{%- endif -%}{%- endfor -%}
{%- if level == 'subcategory' -%}{%- assign listed = '' | split: '' -%}{%- for r in topic_data[rt[0]] -%}{%- if r.url -%}{%- unless r.url contains 'example.com' -%}{%- assign listed = listed | push: r -%}{%- endunless -%}{%- endif -%}{%- endfor -%}{%- endif -%}
{%- for r in real_resources -%}{%- if r.ipl_group == rt_key -%}{%- assign listed = listed | push: r -%}{%- endif -%}{%- endfor -%}
{%- if level == 'subcategory' -%}{%- assign listed = '' | split: '' -%}{%- for r in topic_data[rt_key] -%}{%- if r.url -%}{%- unless r.url contains 'example.com' -%}{%- assign listed = listed | push: r -%}{%- endunless -%}{%- endif -%}{%- endfor -%}{%- endif -%}
{%- if listed.size > 0 %}
<h3 class="flex items-center gap-2 font-semibold text-gray-800 mt-4 mb-1"><i class="fas {{ rt[1] }} text-blue-600" aria-hidden="true"></i>{{ rt[2] }} <span class="text-xs font-normal text-gray-600">({{ listed.size }})</span></h3>
<ul class="divide-y divide-gray-100" role="list">
Expand Down
31 changes: 31 additions & 0 deletions _plugins/resource_stats.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Library totals (spec 002): unique curated resources per language, computed once per build instead of walking
# every data file from the footer of each page. Placeholders (example.com hosts) are not counted, and a resource
# listed in several subcategories counts once (by name, as components/atoms/real-resources.html does).
module IPL
class ResourceStats < Jekyll::Generator
priority :high
PLACEHOLDER = %r{\Ahttps?://(?:[^/]+\.)?example\.(?:com|org|net)(?:[/:?#]|\z)}i

def generate(site)
site.data['resource_stats'] = site.config.fetch('languages', []).to_h do |language|
code = language['code']
[code, { 'resources' => names(site.data[code]).uniq.size }]
end
end

private

# Resource names anywhere under a language's data: lists of entries, files and subcategory folders.
def names(node)
case node
when Array then node.flat_map { |item| resource?(item) ? [item['name']] : names(item) }
when Hash then resource?(node) ? [node['name']] : node.except('menu', 'translations').values.flat_map { |value| names(value) }
else []
end
end

def resource?(item)
item.is_a?(Hash) && item['url'].is_a?(String) && item['name'] && !item['url'].match?(PLACEHOLDER)
end
end
end
18 changes: 18 additions & 0 deletions test/build_output_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@ def test_pages_use_the_ipl_brand_favicons
assert File.file?(File.join(SiteBuild.site.dest, 'favicon.ico'))
end

# Curated resources reach the pages (Liquid 4 cannot read data[a[2]], which hid them all) and library totals
# count resources inside subcategory folders.
def test_subcategory_pages_list_their_curated_resources
html = SiteBuild.output('pt-BR/marketing/seo/index.html')

refute_includes html, 'Ainda não há recursos selecionados'
assert_operator html.scan(/rel="noopener" class="font-semibold text-blue-700/).size, :>=, 10
end

def test_library_totals_count_every_curated_resource
stats = SiteBuild.site.data['resource_stats']
html = SiteBuild.output('en-US/categories/index.html')

assert_operator stats['en-US']['resources'], :>, 1000
assert_operator stats['pt-BR']['resources'], :>, 1000
assert_includes html, "<dd>#{stats['en-US']['resources']}</dd>"
end

# Spec 001 AC3: an encyclopedia must not show invented numbers, placeholder
# knowledge, dead actions or the build time presented as an edit date.
FABRICATED = [
Expand Down
Loading