Skip to content

Latest commit

ย 

History

65 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

SifterSearch

๐Ÿ” Client-side search for MediaWiki.

SifterSearch adds a fast, fully client-side search box to a MediaWiki site, backed by a Pagefind index. The index is a set of static files and every query runs in the browser, so there is no search server and no database query at request time.

It was built for Wikven, a generator that exports a MediaWiki as a static site where there is no backend to answer searches, so search has to run entirely in the browser. Nothing ties it to Wikven, though: it works on any MediaWiki wiki, whether live or statically exported, and suits smaller sites that want search without running a search server.

How it works

The index is built from page content, not by crawling a deployed site, so the same path serves a live wiki and a static export:

  1. When an indexed page changes, SifterSearch queues a rebuild job. The job de-duplicates, so a burst of edits โ€” or a bulk import during a static build โ€” collapses into a single rebuild.
  2. The job keeps the rendered HTML of indexed pages in a cache directory and re-renders only what changed since the last run, then runs the bundled Pagefind binary over the cache to write the pagefind/ bundle to $wgSifterSearchOutputDir. On a live wiki the queue runs via your normal job runner; on a static build it is drained by the build's runJobs step, so SifterSearch needs no knowledge of the build pipeline.
  3. On every page, the client feeds the skin's own search box from the bundle rather than replacing it: Vector 2022's and Minerva's Codex typeaheads are mounted on Pagefind, and skins using core's mediawiki.searchSuggest keep the classic suggestions widget with Pagefind behind it. On the page named by $wgSifterSearchResultsPage, if one is configured, it also mounts Pagefind's full results UI, and sends both the search form and the "search for pages containing" affordance there.

The Pagefind binary

The indexer is a self-contained binary โ€” no Node.js or other runtime is needed. The extension auto-detects the bundled binary for the running platform (see bin/README.md). The default distribution ships only the most common server platform; on another platform, drop the matching binary in bin/ or set $wgSifterSearchPagefindBinary.

Configuration

Setting Default Description
$wgSifterSearchOutputDir "" The Pagefind bundle directory itself, served at the bundle path (e.g. <docroot>/pagefind). Empty disables indexing.
$wgSifterSearchBundlePath /pagefind/ URL path the client loads the bundle from. Its parent is taken as the site root, which is what anchors a results-page URL a host answers document-relative.
$wgSifterSearchCacheDir "" Rendered-HTML cache for incremental rebuilds. Defaults to a subdirectory of $wgCacheDirectory.
$wgSifterSearchFullText true Whether the wiki answers a full-text search of its own. Set false where it does not, e.g. a static export: with no results page either, the "search for pages containing" affordance is dropped and a plain submit goes to the top result.
$wgSifterSearchResultsPage "" Title of a content page to mount the full results UI on, driven by ?search=. Where it is set, the search form and the "search for pages containing" affordance both lead there.
$wgSifterSearchNamespaces [ NS_MAIN ] Namespace IDs to index.
$wgSifterSearchPagefindBinary "" Override the Pagefind binary path. Empty auto-detects bin/.
$wgSifterSearchBatchSeconds 0 Delay rebuilds so bursts coalesce into one batch.

Hooks

SifterSearchIndexPage

Asked once per page before it is indexed. Every page of the configured namespaces is indexed by default, which is the only thing SifterSearch can decide on its own: it sees titles and content, not what the wiki means by them. A wiki that knows one of its pages is not worth answering with โ€” a duplicate of another under a second title, a page kept for machinery rather than readers โ€” says so here.

public function onSifterSearchIndexPage( Title $title, bool &$index ) {
    if ( $this->isADuplicateOfAnotherPage( $title ) ) {
        $index = false;
    }
}

A page turned away is dropped from the index the way a deleted one is, so a wiki may change its mind: the next run carries it out either way.

License

GPL-3.0-or-later

About

๐Ÿ” Client-side search for statically-exported and small MediaWiki sites

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages