Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(site): fix site sorters, make them generalized #2501

Merged
merged 1 commit into from
Jul 11, 2024
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
60 changes: 38 additions & 22 deletions site/11ty/sort.filter.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,47 @@
module.exports = (config) => {
/** Generic sort njk filter */
const createSortFilter = (comparer) => (values) => {
if (!Array.isArray(values)) {
console.error(`Unexpected values for sort filter: ${values}`);
return values;
}
return [...values].sort(comparer);
};

// Utils
/** Resolve date from item */
const resolveDate = (item) => new Date(item.date).getTime();
/** Resolve date from item without fileUpdateDate fallback */
const resolveMetaDate = (item) => item.data.date ? new Date(item.date).getTime() : Number.POSITIVE_INFINITY;

/** Comparer composer */
const compose = (...cmps) => (a, b) => cmps.reduce((res, cmp) => res || cmp(a, b), 0);

/** Name metadata comparer */
const nameComparer = (a, b) => a.data.name.localeCompare(b.data.name);
/** Order metadata comparer */
const orderComparer = (a, b) => (a.data.order || 0) - (b.data.order || 0);
/** Date metadata comparer */
const dateComparer = (a, b) => resolveDate(a) - resolveDate(b);
/** Date metadata comparer (will not use file creation date) */
const dateComparerStrict = (a, b) => resolveMetaDate(a) - resolveMetaDate(b);
const metaDateComparer = (a, b) => resolveMetaDate(a) - resolveMetaDate(b);

/** Order metadata comparer */
const orderComparer = (a, b) => (a.data.order ?? 0) - (b.data.order ?? 0);

config.addFilter('sortByName', createSortFilter(nameComparer));
config.addFilter('sortByNameAndOrder', createSortFilter(compose(orderComparer, nameComparer)));
config.addFilter('sortByDate', createSortFilter(dateComparer));
config.addFilter('sortByDateStrict', createSortFilter(dateComparerStrict));
/** Abstract string comparer */
const stringComparer = (field) => (a, b) => {
const aField = a.data[field] || '';
const bField = b.data[field] || '';
return aField.localeCompare(bField, 'en');
};

/** Build comparer for field */
const buildComparer = (field) => {
switch (field) {
case 'date':
return dateComparer;
case 'meta-date':
return metaDateComparer;
case 'order':
return orderComparer;
default:
return stringComparer(field);
}
};

/** Comparer composer */
const compose = (...comparers) => (a, b) => comparers.reduce((res, cmp) => res || cmp(a, b), 0);

config.addFilter('sortBy', (values, ...fields) => {
if (!Array.isArray(values)) {
console.error(`Unexpected values for sort filter: ${values}`);
return values;
}
const comparers = fields.map(buildComparer);
return [...values].sort(compose(...comparers));
});
};
2 changes: 1 addition & 1 deletion site/views/_includes/landing/newsline.njk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% from 'landing/newsline-item.njk' import newsitem with context %}
{% set releasedNews = collections.news | released | sortByDateStrict | reverse %}
{% set releasedNews = collections.news | released | sortBy('meta-date') | reverse %}
{% if releasedNews.length %}
<div class="newsline container">
<h2>{{ landing.news.title }}</h2>
Expand Down
2 changes: 1 addition & 1 deletion site/views/_includes/navigation/footer-menu.njk
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
close-on-esc>
<ul class="footer-list">
{% if collections[collection] %}
{% for item in collections[collection] | exclude('data.hidden') | releasedStrict | sortByNameAndOrder %}
{% for item in collections[collection] | exclude('data.hidden') | releasedStrict | sortBy('order', 'name') %}
<li class="footer-item">
<a class="footer-link" href="{{ item.url | url }}">{{ item.data.name }}</a>
</li>
Expand Down
2 changes: 1 addition & 1 deletion site/views/_includes/navigation/sidebar-item.njk
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
fallback-duration="400">
<ul class="sidebar-nav-secondary-list">
<esl-a11y-group targets="::child(li)::find(.sidebar-nav-secondary-link)"></esl-a11y-group>
{% for item in items | sortByNameAndOrder %}
{% for item in items | sortBy('order', 'name') %}
{% set isActive = page.url === item.url %}
{% set isDraft = [].concat(item.data.tags).includes('draft') %}
{% set isNew = [].concat(item.data.tags).includes('new') %}
Expand Down
2 changes: 1 addition & 1 deletion site/views/_layouts/collection-grid.njk
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ banner:
<link href="https://fonts.googleapis.com/css2?family=Ubuntu:wght@500&display=swap" rel="stylesheet">

<ul class="collection-grid unstyled-list {{ 'collection-grid-column' if list }}">
{% for item in collections[collection] | released | exclude('data.hidden') | sortByNameAndOrder %}
{% for item in collections[collection] | released | exclude('data.hidden') | sortBy('order', 'name') %}
{% set isDraft = [].concat(item.data.tags).includes('draft') %}
{% set isBeta = [].concat(item.data.tags).includes('beta') %}
{% set isNew = [].concat(item.data.tags).includes('new') %}
Expand Down
2 changes: 1 addition & 1 deletion site/views/examples/carousel.njk
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ eleventyImport:
<section class="row">
<div class="col-12">
<uip-root>
{% for sample in collections['carousel-sample'] | sortByNameAndOrder %}
{% for sample in collections['carousel-sample'] | sortBy('order', 'title') %}
<script type="text/html"
label=" {{ sample.data.title }}"
uip-snippet
Expand Down
Loading