mirror of https://github.com/onweru/compose.git

weru
27.05.2023 9594c1812fed415b65c0256556f32ddce1e84436
enable algolia search #98

Signed-off-by: weru <fromweru@gmail.com>
3 files modified
223 ■■■■ changed files
assets/js/index.js 4 ●●● patch | view | raw | blame | history
assets/js/search/index.js 185 ●●●● patch | view | raw | blame | history
assets/js/search/variables.js 34 ●●●●● patch | view | raw | blame | history
assets/js/index.js
@@ -174,10 +174,12 @@
  let heading_nodes = [];
  [...Array(6).keys()].forEach(function(i){
    if(i) {
    Array.prototype.push.apply(heading_nodes, document.getElementsByTagName(`h${i+1}`));
    }
  });
  heading_nodes.forEach(function(node){
  heading_nodes.forEach(node => {
    let link = createEl('a');
    let icon = createEl('img');
    icon.src = '{{ absURL "icons/link.svg" }}';
assets/js/search/index.js
@@ -1,20 +1,3 @@
function initializeSearch(index) {
  let search_keys = ['title', 'id', 'link', 'body', 'section'];
  search_keys = search_keys.concat(other_searchable_fields);
  const search_page_element = elem('#searchpage');
  const search_options = {
    ignoreLocation: true,
    findAllMatches: true,
    includeScore: true,
    shouldSort: true,
    keys: search_keys,
    threshold: 0.5
  };
  index = new Fuse(index, search_options);
  function minQueryLen(query) {
    query = query.trim();
    const query_is_float = parseFloat(query);
@@ -22,6 +5,53 @@
    return min_query_length;
  }
function findQuery(query = 'query') {
  const url_params = new URLSearchParams(window.location.search);
  return url_params.has(query) ? url_params.get(query) : empty_string;
}
function search(index, scope = null, passive = false) {
  if(search_term.length) {
    let raw_results = index;
    if(!algolia_config.on) {
      raw_results = index.search(search_term);
      raw_results = raw_results.map(function(result){
        const score = result.score;
        const result_item = result.item;
        result_item.score = (parseFloat(score) * 50).toFixed(0);
        return result_item;
      })
    }
    if(scope) {
      raw_results = raw_results.filter(result_item => {
        return result_item.section == scope;
      });
    }
    passive ? searchResults(raw_results, search_term, true) : searchResults(raw_results, search_term);
  } else {
    passive ? searchResults([], empty_string, true) : searchResults();
  }
}
function liveSearch(index) {
  if (search_field) {
    const search_scope = search_field.dataset.scope;
    search(index, search_scope);
    if(!search_page_element) {
      search_field.addEventListener('search', function(){
        search_term = search_field.value.trim().toLowerCase();
        if(search_term.length)  {
          const scope_parameter = search_scope ? `&scope=${search_scope}` : empty_string;
          window.location.href = new URL(`search/?query=${search_term}${ scope_parameter }`, root_url).href;
        }
      });
    }
  }
}
  function searchResults(results=[], query=empty_string, passive = false) {
    let results_fragment = new DocumentFragment();
    let show_results = elem('.search_results');
@@ -47,7 +77,7 @@
      if(!search_page_element) {
        results = results.slice(0,8);
      } else {
        results_fragment.appendChild(go_back_button);
      // results_fragment.appendChild(go_back_button);
        results = results.slice(0,12);
      }
      results_fragment.appendChild(results_title);
@@ -90,72 +120,11 @@
    }
  }
  function search(search_term, scope = null, passive = false) {
    if(search_term.length) {
      let raw_results = index.search(search_term);
      raw_results = raw_results.map(function(result){
        const score = result.score;
        const result_item = result.item;
        result_item.score = (parseFloat(score) * 50).toFixed(0);
        return result_item;
      })
      if(scope) {
        raw_results = raw_results.filter(result_item => {
          return result_item.section == scope;
        });
      }
      passive ? searchResults(raw_results, search_term, true) : searchResults(raw_results, search_term);
    } else {
      passive ? searchResults([], empty_string, true) : searchResults();
    }
  }
  function liveSearch() {
    const search_field = elem(search_field_class);
    if (search_field) {
      const search_scope = search_field.dataset.scope;
      search_field.addEventListener('input', function() {
        const search_term = search_field.value.trim().toLowerCase();
        search(search_term, search_scope);
      });
      if(!search_page_element) {
        search_field.addEventListener('search', function(){
          const search_term = search_field.value.trim().toLowerCase();
          if(search_term.length)  {
            const scope_parameter = search_scope ? `&scope=${search_scope}` : empty_string;
            window.location.href = new URL(`search/?query=${search_term}${ scope_parameter }`, root_url).href;
          }
        });
      }
    }
  }
  function findQuery(query = 'query') {
    const url_params = new URLSearchParams(window.location.search);
    return url_params.has(query) ? url_params.get(query) : empty_string;
  }
  function passiveSearch() {
function passiveSearch(index) {
    if(search_page_element) {
      const search_term = findQuery();
    search_term = findQuery();
      const search_scope = findQuery('scope');
      // search actively after search page has loaded
      const search_field = elem(search_field_class);
      search(search_term, search_scope, true);
      if(search_field) {
        search_field.addEventListener('input', function() {
          const search_term = search_field.value.trim().toLowerCase();
          search(search_term, true);
          wrapText(search_term, main);
        });
      }
    search(index, search_scope, true);
    }
  }
@@ -177,11 +146,42 @@
    window.addEventListener('keydown', event => event.code === "Escape" ? fn() : false);
  }
function initFuseSearch(manual = true) {
  const page_language = document.documentElement.lang;
  const search_index = `${ page_language === 'en' ? empty_string : page_language}/index.json`;
  fetch(new URL(search_index, root_url).href)
  .then(response => response.json())
  .then(function(search_data) {
    search_data = search_data.length ? search_data : [];
    const fuse_index = new Fuse(search_data, search_options);
    manual ? liveSearch(fuse_index) : passiveSearch(fuse_index);
  })
  .catch((error) => console.error(error));
}
function initAlgoliaSearch(manual = true) {
  const algolia_client = algoliasearch(algolia_config.id, algolia_config.key);
  const algolia_index = algolia_client.initIndex(algolia_config.index);
  algolia_index.search(search_term, {
    attributesToRetrieve: search_keys.slice(0,5),
    hitsPerPage: 12,
  }).then(({ hits }) => {
    manual ? liveSearch(hits) : passiveSearch(hits);
  });
}
function initializeSearch() {
  let main = elem('main');
  main = main ? main : elem('.main');
  search_page_element ? false : liveSearch();
  passiveSearch();
  search_field.addEventListener('input', function() {
    search_term = search_field.value.trim().toLowerCase();
    algolia_config.on ? initAlgoliaSearch() : initFuseSearch();
  });
  if (search_page_element) {
    algolia_config.on ? initAlgoliaSearch(false) : initFuseSearch(false);
  }
  wrapText(findQuery(), main);
@@ -194,19 +194,4 @@
  });
}
window.addEventListener('load', function() {
  console.log(algolia_config, 'enabled', algolia_config.id);
  if(algolia_config.on) {
    initAlgoliaSearch();
  } else {
    const page_language = document.documentElement.lang;
    const search_index = `${ page_language === 'en' ? empty_string : page_language}/index.json`;
    fetch(new URL(search_index, root_url).href)
    .then(response => response.json())
    .then(function(search_data) {
      search_data = search_data.length ? search_data : [];
      initializeSearch(search_data);
    })
    .catch((error) => console.error(error));
  }
});
window.addEventListener('load', () => initializeSearch());
assets/js/search/variables.js
@@ -2,6 +2,8 @@
const empty_string = '';
const search_field_class = '.search_field';
const search_class = '.search';
let search_term = empty_string;
const search_field = elem(search_field_class);
// defined in i18n / translation files
const quick_links = '{{ T "quick_links" }}';
@@ -21,26 +23,20 @@
  other_searchable_fields = [];
}
// Algolia specific
const algolia_config = JSON.parse(`{{ partialCached "functions/getAlgoliaConfig" . }}`);
function initAlgoliaSearch() {
  const algolia_client = algoliasearch(algolia_config.id, algolia_config.key);
  const algolia_index = algolia_client.initIndex(algolia_config.index);
const search_page_element = elem('#searchpage');
  // Fuse specific
let search_keys = ['body', 'title', 'link', 'section', 'id',];
search_keys = search_keys.concat(other_searchable_fields);
  // Search for "query string" in the index "contacts"
  algolia_index.search('custom css').then(({ hits }) => {
    console.log(hits);
  });
const search_options = {
  ignoreLocation: true,
  findAllMatches: true,
  includeScore: true,
  shouldSort: true,
  keys: search_keys,
  threshold: 0.1
};
  // Perform the same search, but only retrieve 50 results
  // Return only the attributes "firstname" and "lastname"
  algolia_index.search('query string', {
    attributesToRetrieve: ['firstname', 'lastname'],
    hitsPerPage: 50,
  }).then(({ hits }) => {
    console.log(hits);
  });
}
// Algolia specific
const algolia_config = JSON.parse(`{{ partialCached "functions/getAlgoliaConfig" . }}`);