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

Custom Search Worker setting is ignored #2973

Closed
4 of 5 tasks
xvandish opened this issue Aug 25, 2021 · 3 comments
Closed
4 of 5 tasks

Custom Search Worker setting is ignored #2973

xvandish opened this issue Aug 25, 2021 · 3 comments
Labels
bug Issue reports a bug resolved Issue is resolved, yet unreleased if open

Comments

@xvandish
Copy link

Contribution guidelines

I've found a bug and checked that ...

  • ... the problem doesn't occur with the mkdocs or readthedocs themes
  • ... the problem persists when all overrides are removed, i.e. custom_dir, extra_javascript and extra_css
  • ... the documentation does not mention anything about my problem
  • ... there are no open or closed issues that are related to my problem

Description

As discussed in #2972, at the moment custom search does not work the way it's described in the documentation here.

The worker used to implement search is not configurable in the way thats described by the documentation, which is to override the config block like so:

{% block config %}
  {{ super() }}
  <script>
    var __search = {
      worker: "<url>"
    }
  </script>
{% endblock %}

At the moment, however, this doesn't actually configure the worker thats used, the default/built-in implementation here is always used.

Expected behaviour

I would expect the following block of code set in overrides/main.html

{% block config %}
  {{ super() }}
  <script>
    var __search = {
      worker: "./awesomeWorker.js"
    }
  </script>
{% endblock %}

to load a worker at the path overrides/awesomeWorker.js and have the search html input pass messages to it for consumption and and processing.

Actual behaviour

The worker mentioned in the config block is not called/passed messages by the search input, so effectively nothing happens.

Steps to reproduce

  1. setup a barebones mkdocs repo however you want (mkdocs new)
  2. add the search plugin in mkdocs.yaml. How-to is described here
  3. create a directory overrides
  4. set overrides as the custom_dir by setting custom_dir: overrides in mkdocs.yml under the theme block. How-to described here here
  5. Add a main.html file in the overrides directory. Set it's file contents to:
{% extends "base.html" %}

{% block htmltitle %}
  <title>Lorem ipsum dolor sit amet</title>
{% endblock %}

{% block config %}
  {{ super() }}
  <script>
    var __search = {
      worker: "./worker.js"
    }
  </script>
{% endblock %}
  1. Add a worker.js file in the overrides directory. Set its file contents to:
console.log('whats going on')

export async function handler(message) {
    console.log({ message })
}

addEventListener("message", async ev => {
    postMessage(await handler(ev.data))
})

Now type something in the search. You should see the default search.*.js worker still loaded and working in the background, instead of our custom worker.

Package versions

  • Python: 3.9
  • MkDocs: 1.2.2
  • Material: 7.2.4

Configuration

site_name: My Docs
theme:
  name: material
  custom_dir: overrides
plugins:
  - search

System information

  • Operating system: Mac OS Catalina (10.15.7)
  • Browser: Google Chrome (92.0.4515.131)
@xvandish
Copy link
Author

xvandish commented Aug 25, 2021

I'm happy to contribute and help out, but I may not be able to do any work until this weekend or next.

Also, I understand the documented implementation of custom search may no longer how you'd like to go about this - things change all the time.

@squidfunk squidfunk added the bug Issue reports a bug label Aug 25, 2021
@squidfunk
Copy link
Owner

squidfunk commented Aug 29, 2021

Okay, so I've managed to set aside some time to look into this. Here are some thoughts:

Search plugin dependency

Search index

Although it should be possible to define a custom search worker to completely alter the search behavior, Material for MkDocs will by default always load search_index.json which is generated from the search plugin. The idea behind this is that we will always want to allow to build a client-side search from the MkDocs output, which depends on this very file.

The search_index.json is loaded here if the author did not provide a custom search index through __search.index, which is currently undocumented as it's more or less a silent contract with the localsearch plugin:

const index$ = document.forms.namedItem("search")
? __search?.index || requestJSON<SearchIndex>(
new URL("search/search_index.json", config.base)
)
: NEVER

If the search index should not be loaded, it can just be set to a Promise via __search.index, returning an object which follows the structure in search_index.json, as this is demanded by the setupSearchWorker function, which also adds some options (e.g. whether suggestions should be generated) before sending it to the search worker. From analyzing the control flow, the minimal "fake" search_index.json should look something like (untested):

{
  "config": {
    "lang": []
  },
  "docs": []
}

Search form

Note that the search form is only available if the search plugin is defined:

{% if "search" in config["plugins"] %}
<label class="md-header__button md-icon" for="__search">
{% include ".icons/material/magnify.svg" %}
</label>
<!-- Search interface -->
{% include "partials/search.html" %}
{% endif %}

While the search plugin might not be necessary for external third-party search, it's easier to check from a template perspective. If the search box should be shown regardless of the presence of the search plugin, omitting the need to build the search index at all, the partial can be overridden by using theme extension.

Search worker override

So, now, to allow a custom search worker given all the constraints outlined before, I think that it's okay to add the
worker option back to the global __search override, although naming is slightly inconsistent with the config.search value passed to the JavaScript via the __config JSON in the template:

{%- set app = {
"base": base_url,
"features": features,
"translations": {},
"search": "assets/javascripts/workers/search.js" | url,
"version": config.extra.version or None
} -%}

I've added it back in 441381b.


On a side note, please understand that we cannot provide further support for implementing a custom search worker beyond what's already listed in the documentation. The inline documentation is pretty extensive and you're invited to open further discussions to ask other users for help on a custom implementation. If you, however, run into another behavior which is inconsistent with what is listed in the documentation, feel free to create another issue.

@squidfunk squidfunk added the resolved Issue is resolved, yet unreleased if open label Aug 29, 2021
@squidfunk
Copy link
Owner

Released as part of 7.2.6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue reports a bug resolved Issue is resolved, yet unreleased if open
Projects
None yet
Development

No branches or pull requests

2 participants