From 1a795e34d6bf0a827d944af2f05294cc8e561e1c Mon Sep 17 00:00:00 2001 From: Vincent Rubinetti Date: Wed, 7 Aug 2024 02:35:27 -0400 Subject: [PATCH] change list filter behavior and make associated plugin changes --- _includes/button.html | 3 +-- _includes/list.html | 2 +- _plugins/hash.rb | 2 +- _plugins/misc.rb | 56 +++++++++++++++++++++++++++++++++---------- projects/index.md | 4 ++-- team/index.md | 4 ++-- 6 files changed, 50 insertions(+), 21 deletions(-) diff --git a/_includes/button.html b/_includes/button.html index 47ed98bd2e..11739b2db2 100644 --- a/_includes/button.html +++ b/_includes/button.html @@ -1,5 +1,4 @@ -{% assign button = include %} -{% assign button = button | hash_default: site.data.types[include.type] %} +{% assign button = include | hash_default: site.data.types[include.type] %} {% if button.link or button.icon or button.text %}
diff --git a/_includes/list.html b/_includes/list.html index cdb030c956..5dec46ed76 100644 --- a/_includes/list.html +++ b/_includes/list.html @@ -2,7 +2,7 @@ {% assign data = site.data[include.data] | default: site[include.data] | default: emptyarray - | data_filter: include.filters + | data_filter: include.filter %} {% assign years = data diff --git a/_plugins/hash.rb b/_plugins/hash.rb index 23445898ab..7bf6071395 100644 --- a/_plugins/hash.rb +++ b/_plugins/hash.rb @@ -4,7 +4,7 @@ module Jekyll module HashFilters # merge main hash with another hash of defaults def hash_default(hash, defaults) - if not hash.is_a?(Hash) or not defaults.is_a?(Hash) + if not defaults.is_a?(Hash) return hash end defaults.each do |key, value| diff --git a/_plugins/misc.rb b/_plugins/misc.rb index fe19bd8f08..a4186d1a74 100644 --- a/_plugins/misc.rb +++ b/_plugins/misc.rb @@ -19,22 +19,52 @@ def object_items(object) end # filter a list of hashes by comma-sep'd field:value pairs - def data_filter(data, filters) - if not data.is_a?(Array) or not filters.is_a?(String) + def empty_binding + binding + end + + # make arbitrary string into valid ruby variable name + def safe_var_name(name) + return name.to_s.gsub /[^a-z]+/, "_" + end + + # jekyll ruby plugin + def data_filter(data, filter) + if not filter.is_a?(String) return data end - data = data.clone - for filter in array_filter(filters.split(",")) - key, value = array_filter(filter.split(":")) - # find unspecified fields - if value == nil - data.select!{|d| d[key] == nil} - # find fields that match regex - elsif value.is_a?(String) - data.select!{|d| d[key].to_s =~ /#{value}/m} + + # filter data + return data.clone.select{ + |item| + # start with empty context of local variables + b = empty_binding + # add item as local variable + b.local_variable_set("item", item) + # if jekyll doc collection, get hash of doc data + if item.is_a? Jekyll::Document + item = item.data end - end - return data + # also set each item field as local variable when evaluating filter + item.each do |var, val| + b.local_variable_set(safe_var_name(var), val) + end + # whether to keep item + keep = true + while true + begin + # evaluate filter code, coerce to true/false + keep = !!eval(filter, b) + # if no error, done + break + rescue NameError => e + # if var in filter doesn't exist, define it and re-evaluate + b.local_variable_set(safe_var_name(e.name), nil) + end + end + # keep/discard item + keep + } end # from css text, find font family definitions and construct google font url diff --git a/projects/index.md b/projects/index.md index 1d29a19944..0a257b451f 100644 --- a/projects/index.md +++ b/projects/index.md @@ -18,10 +18,10 @@ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliqu ## Featured -{% include list.html component="card" data="projects" filters="group: featured" %} +{% include list.html component="card" data="projects" filter="group == 'featured'" %} {% include section.html %} ## More -{% include list.html component="card" data="projects" filters="group: " style="small" %} +{% include list.html component="card" data="projects" filter="!group" style="small" %} diff --git a/team/index.md b/team/index.md index 08318c9183..c97b0da2cd 100644 --- a/team/index.md +++ b/team/index.md @@ -13,8 +13,8 @@ nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. {% include section.html %} -{% include list.html data="members" component="portrait" filters="role: pi" %} -{% include list.html data="members" component="portrait" filters="role: ^(?!pi$)" %} +{% include list.html data="members" component="portrait" filter="role == 'pi'" %} +{% include list.html data="members" component="portrait" filter="role != 'pi'" %} {% include section.html background="images/background.jpg" dark=true %}