From 6b1740c1659217522c7a0b5536f1e9ac7864decf Mon Sep 17 00:00:00 2001 From: Jens Peters Date: Tue, 28 Mar 2023 17:07:04 +0200 Subject: [PATCH] Add multi-language support for the search index --- .../generatr/site/model/SearchViewModel.kt | 3 ++ .../site/generatr/site/views/SearchPage.kt | 44 ++++++++++++++++++- .../site/model/SearchViewModelTest.kt | 19 ++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SearchViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SearchViewModel.kt index 6e93ed04..dc5bc00f 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SearchViewModel.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SearchViewModel.kt @@ -17,6 +17,9 @@ class SearchViewModel(generatorContext: GeneratorContext) : PageViewModel(genera override val pageSubTitle = "Search results" override val url = url() + val language: String = generatorContext.workspace.views + .configuration.properties.getOrDefault("structurizr.style.search.language", "") + val documents = buildList { add(home(generatorContext.workspace.documentation, this@SearchViewModel)) addAll(workspaceDecisions(generatorContext.workspace.documentation, this@SearchViewModel)) diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/SearchPage.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/SearchPage.kt index 8ee55220..ac31f534 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/SearchPage.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/SearchPage.kt @@ -7,6 +7,12 @@ import nl.avisi.structurizr.site.generatr.site.asUrlToFile import nl.avisi.structurizr.site.generatr.site.model.SearchViewModel fun HTML.searchPage(viewModel: SearchViewModel) { + val language = if (viewModel.language == "en") "" else viewModel.language + if (!supportedLanguages.contains(language)) + throw IllegalArgumentException( + "Indexing language $language is not supported, available languages are $supportedLanguages" + ) + page(viewModel) { contentDiv { h2 { +viewModel.pageSubTitle } @@ -18,12 +24,19 @@ fun HTML.searchPage(viewModel: SearchViewModel) { type = ScriptType.textJavaScript, src = "https://cdn.jsdelivr.net/npm/lunr-languages@1.10.0/min/lunr.stemmer.support.min.js" ) { } + if (language.isNotBlank()) + script( + type = ScriptType.textJavaScript, + src = "https://cdn.jsdelivr.net/npm/lunr-languages@1.10.0/min/lunr.$language.min.js" + ) { } script(type = ScriptType.textJavaScript) { unsafe { +"const documents = ${Json.encodeToString(viewModel.documents)};" + +"const idx = lunr(function () {" + if (viewModel.language.isNotBlank()) + +"this.use(lunr.${viewModel.language});" +""" - const idx = lunr(function () { this.ref('href') this.field('text') @@ -42,3 +55,32 @@ fun HTML.searchPage(viewModel: SearchViewModel) { } } } + +// From https://github.com/olivernn/lunr-languages +private val supportedLanguages = listOf( + "", + "ar", + "da", + "de", + "du", + "es", + "fi", + "fr", + "hi", + "hu", + "it", + "ja", + "jp", + "ko", + "nl", + "no", + "pt", + "ro", + "ru", + "sv", + "ta", + "th", + "tr", + "vi", + "zh", +) diff --git a/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/SearchViewModelTest.kt b/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/SearchViewModelTest.kt index e58ca0bf..53e43ca3 100644 --- a/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/SearchViewModelTest.kt +++ b/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/SearchViewModelTest.kt @@ -3,12 +3,31 @@ package nl.avisi.structurizr.site.generatr.site.model import assertk.assertThat import assertk.assertions.containsExactly import assertk.assertions.hasSize +import assertk.assertions.isEmpty +import assertk.assertions.isEqualTo import com.structurizr.documentation.Format import com.structurizr.documentation.Section import org.junit.jupiter.api.Test class SearchViewModelTest : ViewModelTest() { + @Test + fun `no index language configured`() { + val viewModel = SearchViewModel(generatorContext()) + + assertThat(viewModel.language).isEmpty() + } + + @Test + fun `index language configured`() { + val generatorContext = generatorContext().apply { + workspace.views.configuration.addProperty("structurizr.style.search.language", "nl") + } + val viewModel = SearchViewModel(generatorContext) + + assertThat(viewModel.language).isEqualTo("nl") + } + @Test fun `nothing to index`() { val viewModel = SearchViewModel(generatorContext())