diff --git a/_includes/components/pagefind_filters.njk b/_includes/components/pagefind_filters.njk new file mode 100644 index 0000000..a272993 --- /dev/null +++ b/_includes/components/pagefind_filters.njk @@ -0,0 +1,9 @@ +{% if format %} + {% for item in format %}{{ item }}{% endfor %} +{% endif %} +{% if espace %} + {% for item in espace %}{{ item }}{% endfor %} +{% endif %} +{% if profile %} + {% for item in profile %}{{ item }}{% endfor %} +{% endif %} diff --git a/_includes/components/taggroup.njk b/_includes/components/taggroup.njk index f29faad..73871b4 100644 --- a/_includes/components/taggroup.njk +++ b/_includes/components/taggroup.njk @@ -4,7 +4,7 @@ {{ (tagsUrl or "/blog/tags/") | locale_url }}{{ tag | slugify }}/ {% endset %}
  • - {{ tag }} + {{ tag }}
  • {% endfor %} diff --git a/_includes/layouts/page.njk b/_includes/layouts/page.njk index 9a00391..8f83670 100644 --- a/_includes/layouts/page.njk +++ b/_includes/layouts/page.njk @@ -19,6 +19,7 @@ sidemenu: false
    + {% include "components/pagefind_filters.njk" %}
    {% if sidemenu %} {% set sideMenuItems = content | getSideMenuItems %} diff --git a/_includes/layouts/post.njk b/_includes/layouts/post.njk index 15d2553..c18c40d 100644 --- a/_includes/layouts/post.njk +++ b/_includes/layouts/post.njk @@ -7,6 +7,7 @@ layout: layouts/base.njk {% include "components/breadcrumb.njk" %} {% endif %}
    + {% include "components/pagefind_filters.njk" %}
    {% include "components/taggroup.njk" %}
    diff --git a/content/fr/blog/posts/accordeon.md b/content/fr/blog/posts/accordeon.md index d7c69db..397a405 100644 --- a/content/fr/blog/posts/accordeon.md +++ b/content/fr/blog/posts/accordeon.md @@ -5,6 +5,18 @@ date: git Last Modified tags: - DSFR - composant +format: + - Initiation + - Tutoriel + - Référentiel technique + - Article +profile: + - Utilisateur + - Producteur + - Développeur +espace: + - Ecosystème Géoplateforme + - Organismes producteurs --- Chaque composant peut être inclus dans un fichier Nunjucks `.njk` ou Markdown `.md`. diff --git a/content/fr/blog/posts/md-cheatsheet.md b/content/fr/blog/posts/md-cheatsheet.md index 260f78c..2710942 100644 --- a/content/fr/blog/posts/md-cheatsheet.md +++ b/content/fr/blog/posts/md-cheatsheet.md @@ -5,6 +5,10 @@ date: git Last Modified tags: - contenu - Markdown +format: + - Initiation + - Tutoriel + - Référentiel technique --- La syntaxe utilisée dans les fichiers Markdown `.md` du site suit la spécification [CommonMark](https://commonmark.org/). diff --git a/content/fr/search-results.njk b/content/fr/search-results.njk index 1af80fd..358d628 100644 --- a/content/fr/search-results.njk +++ b/content/fr/search-results.njk @@ -13,6 +13,7 @@ layout: layouts/base.njk

    0 {{ "results" | i18n }}

    +
    {% include "components/back_to_top.njk" %} diff --git a/public/js/search-results.js b/public/js/search-results.js index 06f20c0..c0dc2ca 100644 --- a/public/js/search-results.js +++ b/public/js/search-results.js @@ -1,27 +1,122 @@ -(() => { - const RESULTS_PER_PAGE = 10; +const RESULTS_PER_PAGE = 10; - const SEARCH_TERM_SELECTOR = "#search-term"; - const RESULT_COUNT_SELECTOR = "#result-count"; - const SEARCH_RESULTS_SELECTOR = "#search-results"; +const SEARCH_TERM_SELECTOR = "#search-term"; +const RESULT_COUNT_SELECTOR = "#result-count"; +const SEARCH_RESULTS_SELECTOR = "#search-results"; - const FULL_WIDTH_COL_CLASS = "fr-col-12"; +const FULL_WIDTH_COL_CLASS = "fr-col-12"; - const searchTermText = document.querySelector(SEARCH_TERM_SELECTOR); - const resultCounter = document.querySelector(RESULT_COUNT_SELECTOR); - const searchResultList = document.querySelector(SEARCH_RESULTS_SELECTOR); +class PageFinder { + constructor(pagefind) { + this.pagefind = pagefind; - const getSearchResults = async () => { - const pagefind = await import(PAGEFIND_URL); + this.searchTermText = document.querySelector(SEARCH_TERM_SELECTOR); + this.resultCounter = document.querySelector(RESULT_COUNT_SELECTOR); + this.searchResultList = document.querySelector(SEARCH_RESULTS_SELECTOR); + this.filterTagsEl = document.getElementById("search-filter-tags"); + } + + async getSearchResults() { + const queryParams = new URLSearchParams(window.location.search); + console.log(queryParams.get("filters")); + const searchTerm = queryParams.get(SEARCH_PARAM); + this.searchTermText.textContent = searchTerm; + + // https://github.com/CloudCannon/pagefind/blob/production-docs/pagefind_web_js/types/index.d.ts#L72 + const search = await this.pagefind.search(searchTerm); + this.resultCounter.innerText = search.results.length; + + const filters = await this.pagefind.filters(); + console.log(filters); + // , { + // filters: { + // format: "Tutoriel", + // }, + // } + + let start = 0; + let paginatedResults = await Promise.all(search.results.slice(start, start + RESULTS_PER_PAGE).map((r) => r.data())); + + await this.populateSearchResults(paginatedResults); + this.showFilters(filters); + + window.addEventListener("scroll", async () => { + if (this._bottomIsReached()) { + start += RESULTS_PER_PAGE; + paginatedResults = await Promise.all(search.results.slice(start, start + RESULTS_PER_PAGE).map((r) => r.data())); + await populateSearchResults(paginatedResults); + } + }); + } + + async populateSearchResults(paginatedResults) { + this.searchResultList.innerHTML = ""; + + paginatedResults.forEach((result) => { + const cardCol = document.createElement("div"); + cardCol.className = FULL_WIDTH_COL_CLASS; + cardCol.innerHTML = this._getCardHtml(result.meta.title, result.excerpt, result.url); + this.searchResultList.appendChild(cardCol); + }); + } + + showFilters(filters) { const queryParams = new URLSearchParams(window.location.search); + const searchTerm = queryParams.get(SEARCH_PARAM); - searchTermText.textContent = searchTerm; - pagefind.init(); - const search = await pagefind.search(searchTerm); - return search.results; - }; + let queryFilters = queryParams.get("filters") ? JSON.parse(decodeURIComponent(queryParams.get("filters"))) : {}; + + Object.entries(filters).map(([filterType, subFilter]) => { + let div = document.createElement("div"); + div.className = "fr-grid-row fr-grid-row--middle"; + + let divTitle = document.createElement("div"); + divTitle.className = "fr-col-12 fr-col-sm-2"; + divTitle.textContent = `${filterType} : `; - const getCardHtml = (title, excerpt, url) => { + let divTags = document.createElement("div"); + divTags.className = "fr-col-12 fr-col-sm-10"; + + let ul = document.createElement("ul"); + ul.className = "fr-tags-group"; + divTags.appendChild(ul); + + div.appendChild(divTitle); + div.appendChild(divTags); + + Object.entries(subFilter).map(([filter, count]) => { + const li = document.createElement("li"); + li.className = "fr-tag fr-tag--sm"; + + const tmpQueryFilters = { ...queryFilters }; + tmpQueryFilters[filterType] = Array.from(new Set([...(tmpQueryFilters[filterType] ?? []), filter])); + console.log(tmpQueryFilters); + + const aTag = document.createElement("a"); + aTag.href = `${new URL(window.location).pathname}?term=${searchTerm}&filters=${encodeURIComponent(JSON.stringify(tmpQueryFilters))}`; + aTag.text = `${filter} (${count})`; + + li.appendChild(aTag); + ul.appendChild(li); + }); + + this.filterTagsEl.appendChild(div); + }); + + // let ul = document.createElement("ul"); + // ul.className = "fr-tags-group"; + // filters.espace.forEach((espace) => { + // const li = document.createElement("li"); + // li.className = "fr-tag"; + // li.textContent = espace; + // ul.appendChild(li); + // }); + // filterTagsEl.appendChild(ul); + + // console.log(filters); + } + + _getCardHtml(title, excerpt, url) { return `
    `; - }; - - const populateSearchResults = async (paginatedResults) => { - paginatedResults.forEach((result) => { - const cardCol = document.createElement("div"); - cardCol.className = FULL_WIDTH_COL_CLASS; - cardCol.innerHTML = getCardHtml(result.meta.title, result.excerpt, result.url); - searchResultList.appendChild(cardCol); - }); - }; + } - const bottomIsReached = () => { + _bottomIsReached() { return window.scrollY + window.innerHeight >= document.documentElement.scrollHeight; - }; - - getSearchResults().then(async (searchResults) => { - resultCounter.innerText = searchResults.length; - - let start = 0; - let paginatedResults = await Promise.all(searchResults.slice(start, start + RESULTS_PER_PAGE).map((r) => r.data())); + } +} - await populateSearchResults(paginatedResults); +(async () => { + const pagefind = await import(PAGEFIND_URL); - window.addEventListener("scroll", async () => { - if (bottomIsReached()) { - start += RESULTS_PER_PAGE; - paginatedResults = await Promise.all(searchResults.slice(start, start + RESULTS_PER_PAGE).map((r) => r.data())); - await populateSearchResults(paginatedResults); - } - }); - }); + const pageFinder = new PageFinder(pagefind); + await pageFinder.getSearchResults(); })();