Skip to content

Internationalization โ€‹

Location
/etc/projectConfigs/
โ””โ”€ 
corpus-1/
   โ”œโ”€ 
search.xml
   โ”œโ”€ 
help.inc
   โ”œโ”€ 
about.inc
   โ”œโ”€ 
article.xsl
   โ”œโ”€ 
meta.xsl
   โ”œโ”€ 
static/
   |  โ”œโ”€ 
locales/
   |  |  โ”œโ”€ 
en-us.json
   |  |  โ””โ”€ 
...
   |  โ””โ”€ 
...
   โ”œโ”€ 
corpus-2/
   โ”œโ”€ 
corpus-3/
   โ”œโ”€ 
...
   โ”œโ”€ 
default/
   |  โ”œโ”€ 
search.xml
   |  โ””โ”€ 
...
   โ””โ”€ 
...
<--- The location set in the corporaInterfaceDataDir setting
<--- Exact name/ID of the corpus as in BlackLab
ย 
ย 
ย 
ย 
ย 
ย 
<--- Language files for the interface, specific to this corpus
ย 
ย 
<--- Anything else you want to make available client-side
ย 
ย 
ย 
<--- Fallbacks / Defaults go here
ย 
ย 
ย 

You can customize field names, labels, and other UI text by creating a locale file. Any keys you provide will override the default locale.
If you fully translate the UI, please consider sharing your translation.

Default en-us locale file github
json
{
	"widgets": {
		"learnMore": "Learn more",
		"clickToRemove": "Click to remove",
		"selectValue": "Select a value...",
		"selectValues": "Select value(s)..."
	},
	"search": {
		"heading": "Search for โ€ฆ",
		"simple": {
			"heading": "Simple"
		},
		"extended": {
			"heading": "Extended",
			"splitBatch": "Split batch queries",
			"within": "Within:"
		},
		"advanced": {
			"heading": "Advanced",
			"copyAdvancedQuery": "Copy to CQL editor",

			"queryBuilder": {
				"$comment": "we use underscores here because mustachejs keys cannot contain dots",

				"createTokenButton_label": "Insert another token",

				"modalEditor_title": "Edit",
				"modalEditor_clear": "Clear",
				"modalEditor_cancel": "Cancel",
				"modalEditor_save": "Save changes",

				"withinSelect_label": "Within:",

				"token_head_handle_title": "Drag here move this token",
				"token_head_deleteButton_title": "Remove token",

				"body_tab_header_search": "Search",
				"body_tab_header_properties": "Context",

				"body_tab_properties_optional": "Optional",
				"body_tab_properties_optional_title": "Token is optional",
				"body_tab_properties_beginOfSentence": "Begin of sentence",
				"body_tab_properties_beginOfSentence_title": "Token must occur at the beginning of a sentence",
				"body_tab_properties_endOfSentence": "End of sentence",
				"body_tab_properties_endOfSentence_title": "Token must occur at the end of a sentence",

				"body_tab_properties_repeats_label": "repeats",
				"body_tab_properties_repeats_to": "to",
				"body_tab_properties_repeats_times": "times",

				"attribute_caseAndDiacriticsSensitive": "Case-\u00a0and\u00a0diacritics-sensitive",
				"attribute_delete_attribute_button_title": "Remove this attribute",

				"attribute_file_upload_button_title": "Upload a list of values",
				"attribute_file_upload_edit_button_title": "Edit your uploaded values",
				"attribute_file_upload_clear_button_title": "Clear uploaded values",

				"attribute_create_button_title": "Add another attribute"
			}
		},
		"concept": {
			"heading": "Concepts",
			"copyConceptQuery": "Copy to CQL editor (expert mode)"
		},
		"glosses": {
			"heading": "User glosses",
			"copyGlossQuery": "Copy to CQL editor (expert mode)"
		},
		"expert": {
			"heading": "Expert",
			"corpusQueryLanguage": "Corpus Query Language",
			"parseQuery": "Copy to query builder",
			"parseQueryTitle": "Edit your query in the querybuilder",
			"importQuery": "Import query",
			"importQueryTitle": "Import a previously downloaded query",
			"gapFilling": "Gap-filling",
			"gapFillingTitle": "Upload a tab-separated list of values to substitute for gap values ('@@' in your query).",
			"clearGapValues": "Clear gap values"
		},
		"parallel": {
			"alignBy": "Align by",
			"inSourceVersion": "Search source version",
			"errorNoSourceVersion": "Please select a source version.",
			"andCompareWithTargetVersions": "And compare with target version(s)",
			"queryForSourceVersion": "Query for source version",
			"queryForTargetVersion": "Query for target version",
			"chooseTargetVersion": "Choose a target version",
			"addTargetVersion": "Add another target version"
		}
	},
	"filter": {
		"heading": "Filter search by โ€ฆ",
		"noFilter": {
			"title": "No filters available",
			"content": "This corpus does not contain metadata, or the author has chosen not to allow filtering on metadata."
		},
		"range": {
			"from": "From",
			"to": "To",
			"permissive": "Permissive",
			"permissiveDescription": "Matches documents that are partially contained within the entered range",
			"strict": "Strict",
			"strictDescription": "Matches documents that are completely contained within the entered range"
		}
	},
	"explore": {
		"heading": "Explore ...",
		"corpora": {
			"heading": "Documents",
			"groupBy": "Group documents by metadata",
			"showAs": {
				"heading": "Show groups as",
				"table": "Table",
				"docs": "Docs",
				"tokens": "Tokens"
			}
		},
		"ngram": {
			"heading": "N-grams",
			"ngramSize": "N-gram size",
			"ngramType": "N-gram type"
		},
		"frequency": {
			"heading": "Statistics",
			"frequencyType": "Frequency list type"
		}
	},
	"setting": {
		"heading": "Global settings",
		"resultsPerPage": "Results per page",
		"resultsPerPageOption": "{n} results per page",
		"sampleSize": "Sample size",
		"sampleSizeCount": "count",
		"sampleSizePercentage": "percentage",
		"sampleSeed": "Seed",
		"context": "Context size",
		"wideView": "Wide View",
		"debug": "Debug info",
		"hideDebugUntilReload": "Hide debug checkbox until next reload",
		"close": "Close"
	},
	"queryForm": {
		"search": "Search",
		"explore": "Explore",
		"reset": "Reset",
		"history": "History"
	},
	"partOfSpeech": {
		"noOptions": "No options",
		"submit": "Ok",
		"reset": "Reset"
	},
	"lexicon": {
		"selectAll": "Select all",
		"deselectAll": "Deselect all",
		"limit": "Limit to Part of Speech"
	},
	"filterOverview": {
		"error": "Error",
		"subCorpus": "Selected subcorpus",
		"totalDocuments": "Total documents",
		"totalTokens": "Total tokens",
		"calculating": "Calculating size of selected subcorpus..."
	},
	"annotation": {
		"caseSensitive": "Case- and diacritics-sensitive"
	},
	"formConcept": {
		"conceptSearch": {
			"searchIn": "Search in:",
			"reset": "Reset",
			"addBox": "Add box",
			"removeBox": "Remove box",
			"viewLexicon": "View lexicon",
			"showQuery": "Show query",
			"settings": "Settings:",
			"query": "Query",
			"cqlRendition": "CQL rendition"
		},
		"conceptSearchBox": {
			"subquery": "Subquery",
			"field": "Field",
			"concept": "Concept",
			"term": "Term",
			"addToLexicon": "Add term to lexicon",
			"clear": "Clear"
		},
		"glossSearch": {
			"reset": "Reset",
			"showQuery": "Show query",
			"settings": "Settings"
		}
	},
	"results": {
		"groupBy": {
			"groupNameWithoutValue": "[none]",

			"groupResults": "Group Results",
			"close": "Close",
			"clear": "Clear",
			"apply": "Group",
			"invalidGrouping": "This grouping is not valid.",

			"parallelCorpusVersion": "Looking at version ",
			"iWantToGroupOnAnnotation": "I want to group on {some_words} {in_this_location_with_text} using annotation {this_annotation}.",
			"in_this_location_with_text": "{in_this_location}",

			"some_words": {
				"theFirstWord": "the first word",
				"allWords": "all words",
				"specificWords": "specific words",
				"captureGroupsLabel": "Labels and relations",
				"spanFiltersLabel": "Span filters"
			},
			"in_this_location": {
				"beforeTheHit": "before the hit",
				"inTheHit": "within the hit",
				"afterTheHit": "after the hit",
				"fromTheEnd": "from the end of the hit"
			},

			"relationPartByClass": {
				"default": {
					"label": "Relation part",
					"source": "source",
					"target": "target"
				},
				"dep": {
					"source": "head",
					"target": "dependent"
				}
			},

			"tipClickOnHighlightedWords": "Tip: click on highlighted words for syntactic grouping.",

			"caseSensitive": "Case sensitive",
			"chooseWordPositions": "Choose the <strong>specific word</strong> positions to group on here, the preview sentence will show you which words you have selected.",
			"selectDocumentMetadata": "Select the metadata to group on.",
			"clickButtonsToStart": "Click on Annotation or Metadata to define grouping criteria.",
			"metadata": "Metadata",
			"annotation": "Annotation",
			"specify": "Specify",

			"summary": {
				"indexedWord": "{field} [{index}] {position}",
				"firstWord": "first {field} {position}",
				"allWords": "{field} {position}",
				"labelledWord": "label {label} on {field}",
				"spanAttribute": "tag {span}, attribute {attribute}",
				"metadata": "Document {field}",

				"position": {
					"before": "before hit",
					"hit": "within hit",
					"after": "after hit",
					"end": "within hit"
				}
			}
		},
		"table": {
			"showFullSentence": "Display sentence analysis",
			"loading": "Loading...",
			"loadMoreConcordances": "Load more concordances",
			"viewDetailedConcordances": "View detailed concordances",
			"document": "Document",
			"hits": "Hits",
			"columnLabelBeforeHit": "Before Hit",
			"columnLabelHit": "Hit",
			"columnLabelAfterHit": "After Hit",
			"sortBy": "Sort by {field}",
			"sortByDescending": "Sort by {field} (reverse)",
			"sort_numberOfHits": "number of hits",
			"sort_groupName": "group name",
			"sort_groupSize": "group size",
			"sort_alignments": "alignments",
			"groupBy": "Group by {field}",
			"sortByDocument": "Sort by document title",
			"moreHiddenHits": "more hidden hits",
			"clickToSort": "click to sort",
			"close": "close",
			"hide": "Hide",
			"show": "Show",
			"titles": "Titles",
			"property": "Property",
			"value": "value",
			"noContext": "No context available.",
			"customColumnHeader": "Version",
			"goToHitInDocument": "Go to hit in document"
		},
		"export": {
			"downloading": "Downloading...",
			"csvTooltip": "Export results as a CSV file",
			"excelTooltip": "Export Results as a CSV file for use with Excel",
			"exportCSV": "Export",
			"exportExcel": "Export for Excel"
		},
		"querySummary": {
			"heading": "Results for: ",
			"allDocuments": "all documents",
			"within": "within",
			"documentsWhere": "documents where"
		},
		"resultsView": {
			"navigation": {
				"backToGroupedResults": "Go back to grouped results",
				"backToUngroupedResults": "Go vack to ungrouped results",
				"hits": "Hits",
				"documents": "Documents",
				"viewingGroup": "Viewing group {group}",
				"groupedBy": "Grouped by {group}",
				"randomSample": "Random sample ({sample})"
			},

			"noResultsFound": "No results found.",
			"inactiveView": "This view is inactive because no search criteria for words were specified.",
			"tryAgainTitle": "Try again with current search settings",
			"tryAgain": "Try again",
			"selectAnnotation": "Select annotation"
		},
		"resultsTotals": {
			"total": "Total",
			"soFar": "so far",
			"totalGroups": "Total groups",
			"searchTime": "Search time",
			"networkError": "Network error",
			"retry": "Retry",
			"queryLimited": "Query limited",
			"heavyQuery": "Heavy query",
			"continue": "Continue",
			"hits": "hits",
			"documents": "documents",
			"tokens": "tokens"
		},
		"sort": {
			"sortBy": "Sort byโ€ฆ"
		}
	},
	"history": {
		"heading": "History",
		"results": "Results",
		"pattern": "Pattern",
		"filters": "Filters",
		"grouping": "Grouping",
		"search": "Search",
		"copyAsLink": "Copy as link",
		"downloadAsFile": "Download as file",
		"delete": "Delete",
		"deleteAll": "Delete all",
		"loadMore": "Load more",
		"importUrl": "Import url",
		"copyUrlHere": "Copy your url here",
		"importFromLink": "Import from a link",
		"close": "Close",
		"clearSearchHistory": "Clear search history",
		"clearSearchHistoryConfirmation": "Are you sure you want to clear your search history?",
		"clear": "Clear",
		"cancel": "Cancel"
	},
	"searchPage": {
		"fullQuery": "Full query"
	},
	"remoteIndex": {
		"loadingCorpora": "Loading your corpora...",
		"pickCorpus": "Please pick a corpus",
		"addFilesToCorpus": "Add files to an existing corpus...",
		"selectCorpus": "Select a corpus",
		"createNewCorpus": "or create a new corpus and add to that...",
		"name": "Name",
		"create": "Create",
		"illegalCorpusName": "Illegal corpus name. Corpus name must be between 3 and 30 characters and may not contain special characters.",
		"retry": "Retry"
	},
	"pageGuide":{
		"simple": "<p>The <code>simple</code></p> search lets you quickly search for words. It supports <code>wildcards</code>.<br><code>Wildcards</code> are special characters that will match any other character. Two kinds of wildcards are supported:<br>The <code>*</code> wildcard will match any string, of any length.<br>The <code>?</code> wildcard will match any single letter or character.<br>As an example: searching for <code>a*b</code> will match <i>all values</i> that start with <code>a</code> and end with <code>b</code>,while searching for <code>a?b</code> will match match <i>only three-letter values</i> starting with <code>a</code> and ending with <code>b</code>.<br>",
		"extended": "<p>The <code>extended</code> search allows you to quickly find all occurrences of <code>tokens</code> with specific <code>attributes</code> in this corpus.<br></p><p><code>Tokens</code> are the smallest unit within a corpus, usually just a single word.<br><code>Attributes</code> are the different values that together make up a <code>token</code>.<br>The most commonly available attributes are <code>Lemma</code>, <code>Part of Speech</code> and <code>Word</code>,however this can differ on a corpus by corpus basis.<br>All supported attributes for this corpus will be shown here.<br></p><p>Enter the value you want to find tokens for in any of the inputs below.<br>Press enter or click the search button below to execute the search and view the results.<br>As an example: to find all <code>nouns</code> within this corpus (assuming this corpus supports <code>part of speech</code> tags),enter <code>NOU</code> (or the equivalent tag for a noun in this corpus) in the <code>part of speech</code> field.<br>To find all occurrences of the word \"ship\", enter <code>ship</code> in the <code>lemma</code> field.<br></p><p>Like the <code>simple</code> search, it supports <code>Wildcards</code>.<br></p><p>It's also possible to search for series of <code>tokens</code>, such as a <code>verb</code> followed by a <code>noun</code>.<br>To do this, enter multiple values in any of the fields, each value separated by a space.<br>As an example: to find all instances of an <code>adjective</code> followed by a <code>noun</code> (assuming this corpus contains <code>part of speech</code> tags),<br>enter <code>ADJ NOU</code> (or the equivalent names for this corpus) in the <code>part of speech</code> field.<br></p><p>Values at the same position in different fields are grouped together as a single <code>token</code>, meaning that all values in the first position of each field are grouped to match a single <code>token</code>,likewise for the second values in every field, and so on.<br>As an example: searching for <code>part of speech</code> <code>NOU</code> together with <code>lemma</code> <code>a*</code>will find all <code>nouns</code> starting with the letter <code>a</code> as you would expect, while searching for <code>pos</code> <code>ADJ NOU</code> together with <code>lemma</code> <code>a* b*</code>will find all <code>adjectives</code> starting with the letter <code>a</code>, <i>followed by</i> a <code>noun</code> starting with the letter <code>b</code>.<br></p>",
		"split": "<p>Split your query into many smaller queries.</p><p>Values for all <code>attributes</code> are split on <code>OR</code> (the <code>|</code> character), and every term is executed as a separate query.<br>Entered <code>Metadata filters</code> will apply to all subqueries.</p><p>After running the query, the result of the last value will be shown.<br>The other subqueries can be inspected and loaded from the <code>history</code> panel.</p>",
		"upload": "Click here to upload a list of values to search for.<br>Every word in the file will be added to the list of values to search for.<br>To remove the wordlist, click the button again, then press <code>cancel</code> when presented with the file selection (only works in chrome),or simply delete all text in the field.",
		"querybuilder": "<p>This is the <code>querybuilder</code>. With it, you can create complex queries without writing CQL.<br></p><p>The querybuilder is structured around configuring the <code>attributes</code> of <code>tokens</code>.<br>Create one or more tokens, and fill in which attributes a token must have to be found.<br>In addition to the simple search, it's also possible to define specific combinations of attributes, or specify lists of possible attributes, and more.</p><p>When multiple tokens are used, they are matched in order from left to right.<br>Any time a query is created in the querybuilder, it's also copied to the <code>CQL editor</code>, where you can further edit the query by hand.</p>",
		"token": "<p>This is a <code>token</code>, the basic building block of a query.<br></p><p>A token in the querybuilder is made up two parts:<br>The set of <code>attributes</code> a token in the corpus must have to be matched by the query.<br>Create attributes by clicking the + button within this token. Then enter a value that the attribute must have for the token to be found.<br>Contextual <code>properties</code>, such as whether the <code>token</code> occurs at the start, or the end of a sentence.</p><p>The CQL query generated to match this token in the corpus is also displayed here, to help understand what is happening internally.<br></p><p>Rearrange a token by clicking and dragging the little arrow handle in the top-left corner.<br>Delete a token by clicking the x in the top-right corner.<br>Create new tokens by clicking the + button over on the right.<br></p>",
		"tokenButton": "Create additional tokens by clicking this button.",
		"attribute": "<p>This is an <code>attribute</code> of this token.<br></p><p>Attributes are much like in the <code>simple</code> search. Select which attributea token should have, and enter the value that the attribute must have for the token to be matched.<br>In addition to this simple behavior the querybuilder also allows several more advanced configurations.<br>Attributes in the querybuilder are interpreted as <code>regular expressions</code>.</p><p>Using the + buttons, new attributes can be added. Two options exist: <code>AND</code> and <code>OR</code>.<br>The <code>AND</code> option creates a new attribute that <i>also</i> must exist on a token for that token to be matched.<br>As an example: the attribute <code>part of speech</code> with value <code>NOU</code> is already defined, so all tokens that are nouns will be matched.<br>Creating a new attribute using <code>AND</code> will change that query so that now a token must be a noun, <i>in addition</i> to being/having whatever new attribute is created.<br>The <code>OR</code> largely performs the same role, with the change that a token will now be matched whenever it has the original attribute <i>or</i> the new attribute.<br>As an example: you have an attribute <code>lemma = \"bee\"</code>, and you select <code>AND</code>.<br>Now you have <code>lemma = \"bee\"</code> AND <code>some other attribute</code>, and both of these must be true for a token to be found.<br>If you had selected <code>OR</code> it would find all tokens with either <code>lemma = \"bee\"</code> or that have your new attribute<br></p><p>It's also possible to upload a list of values, to do so, click the upload button that appears when you hover the mouse over the text input for this attribute and select a text file.Tokens will then be matched for any of the values from the file.<br>Uploaded files must be be plain text files (.txt), with each value on its own line.<br>After uploading a file, the text can be edited by clicking the yellow button that has appeared in place of the text field. Editing the text is temporary and will not modify your original file.<br>To remove an uploaded file and go back to typing a value, click the upload button a second time, then press cancel instead of selecting a file.</p>",
		"CQLeditor": "<p>The <code>CQL editor</code> allows you to type your own CQL query, or edit a query further after creating it in the <code>querybuilder</code>.</p><p>Queries generated by the <code>querybuilder</code> will be pasted here automatically. Note that this will overwrite any queries you type here yourself!<br>In some cases, when the query is relatively simple, it can be also be imported into the querybuilder using the <code>copy to query builder</code> button below.A message will be displayed next to the button if the query couldn't be parsed.</p><p>For more information on how to write <code>CQL</code>, <a style=\"text-decoration:underline;color:#337ab7;\" target=\"_blank\" href=\"https://blacklab.ivdnt.org/guide/corpus-query-language.html\">click here</a>.</p>",
		"TSVbutton": "<p>Use this button to upload a TSV file with terms to complete a query with marked gaps.<br>For instance, given a query:<br><code>[lemma=\"@@\"][pos=\"LID.*\"][lemma=\"@@\"]</code><br>you would supply a list with two tab-separated columns of terms, where the terms in the first column will be entered at the position of the first gap (@@) and the words in the second column at the position of the second gap.This mimics the word list functionality of the Extended and Advanced search interfaces.</p><p>Please note that for this to work, you do need to enter @@ in the field where you want the substitution to take place. An empty field ([]) will match any term.</p>",
		"importQuery": "<p>Import previously saved queries here.</p><p>To <code>export</code> a query: first run a search, then open the history, and select <code>save as file</code> in the dropdown on the right.</p>",
		"metedata": "<p>Listed here are the <code>metadata</code> fields that exist on documents within this corpus.<br>Using these fields a query can be limited to a subset of documents with specific metadata values.<br>It's also possible to view all documents by leaving all <code>attributes</code> in the <code>simple</code> search empty.</p><p>As an example: to search within only documents from the year <code>2003</code> (assuming documents contain metadata for the year of writing),<br>type <code>2003</code> in the <code>year</code> field (or the equivalent name of the year data in this corpus).<br></p><p>Some values like dates and numbers support entering a <code>range</code>.<br>Ranges are <code>inclusive</code>, meaning that for a range of <code>10 to 20</code>, documents for which the value is exactly 10 or 20 will also be included.</p><p>Some of the most common values will for each field be autocompleted as you are entering a value. Clicking on an autocompleted value will paste that value in the field.<br>For fields where the total number of different values is relatively small, a dropdown will be shown instead, allowing you to pick the exact set of documents to search.<br></p><p>To search in documents within a set of different values, enter multiple values, separated by spaces. If one of the values already contains spaces of itself, it must be surrounded by double quotes (<code>\"</code>).<br>As an example: to match the value <code>my metadata value</code>, enter <code>\"my metadata value\"</code> in the field, including the quotes.<br>Entering <code>three different values</code> without quotes will instead search in any document with a value of <code>three</code>, <code>different</code> or <code>values</code> for that metadata field.</p>",
		"results": "Results can be viewed in two ways: as individual <code>hits</code> (groups of one or more <code>tokens</code> that matched the query),or as the <code>documents</code> in which those hits exist.<br>Hits are only available when the query matches at least one attribute.",
		"sortHits": "Click on any of the column headings to sort the <code>hits</code> on values within the column, clicking again inverts the sorting.",
		"showHit": "<p><code>Hit</code> rows are always preceded by a row containing the <code>document</code> in which those hits occurred.<br>Hit rows can be toggled on or off using the <code>Show/hide titles</code> button.<br></p><p>Click the title of this document to open the document in a new window. Hits from the current query will be highlighted in the opened document.<br>This functionality is only available when the corpus has not disabled the viewing of documents.<br></p>",
		"clickHit": "Click a hit to show a part of the document surrounding the hit. Click again to close.",
		"resultsGrouped": "<p>Results can be grouped by properties of the <code>tokens</code> or <code>documents</code> in which those hits occur.<br><code>left context</code>, <code>right context</code> and <code>hit</code> will group the tokens based on the <code>token's</code> attributes.<br>The remaining options group by the <code>metadata</code> of the <code>documents</code>.</p><!-- <p>Grouping by multiple properties simultaneously is possible by selecting more than one option.</p> -->",
		"clickGroup": "Click a <code>group</code> to show or hide the <code>hits</code> within that group.",
		"clickGoBack": "Click here to go back to the normal <code>hits</code> view to see more detailed information for the hits in this group.<br>A small indicator will appear to let you know that you're looking at hits from a specific group only.",
		"documentInfo": "Information about a <code>document</code>.<br>Click the document's title or the <code>view document info</code> button to open this document in a new window.<br>This functionality is only available when the corpus has not disabled the viewing of documents.<br>"
	},

	"index": {
		"annotatedFields": {
			"$exampleAnnotatedField": "Translated display name for annotated field $exampleAnnotatedField",
			"$exampleAnnotatedField_description": "Translated description for annotated field $exampleAnnotatedField"
		},
		"annotations": {
			"$exampleAnnotation": "Translated display name for annotation $exampleAnnotation",
			"$exampleAnnotation_description": "Translated description for annotation $exampleAnnotation"
		},
		"annotationGroups": {
			"$exampleAnnotationGroup": "Translated display name for annotation group $exampleAnnotationGroup"
		},
		"metadata": {
			"$exampleMetadataField": "Translated display name for metadata field $exampleMetadataField"
		},
		"metadataGroups": {
			"$exampleMetadataGroup": "Translated display name for metadata group $exampleMetadataGroup"
		},
		"within": {
			"$exampleWithinValue": "Translated display name for within value $exampleWithinValue"
		},
		"alignBy": {
			"$exampleAlignByValue": "Translated display name for align by relation $exampleAlignByValue"
		}
	}
}

Creating a translation โ€‹

Create a new file in static directory of your corpus' interface data directory (corporaInterfaceDataDir), e.g., static/locales/fr.json. It's best to copy an existing locale file and translate the strings.

Global translations โ€‹

Place your locales in the default directory of the interface data directory (corporaInterfaceDataDir) to make them available for all corpora at once.
This uses the overlay system to apply translations globally.

You can even override these defaults further by placing additional locale files in the static directory of your corpus' dedicated static directory.

Comments โ€‹

Locale files can contain comments using // comment or /* comment */.

Add or remove a language from the selector โ€‹

We don't automatically detect and add locales to the language selector, so you need to register them manually.

The locale string should match the filename of your added locale.

ts
function i18n.registerLocale(locale: string, label: string);
function i18n.removeLocale(locale: string);

Set the default locale โ€‹

Used when no language is selected or the browser's locale isn't available.
The default is en-us.

ts
function i18n.setDefaultLocale(locale: string);

Set the fallback for untranslated keys โ€‹

Defaults to en-us, but you can change it to any other locale you have registered.
โš ๏ธ Make sure to register the locale first, otherwise this won't have any effect.

ts
function i18n.setFallbackLocale(locale: string);

Technical details โ€‹

The app uses vue-i18n. Not all UI text is translatable yet; contributions are welcome.

To help add translation keys, look for usages like {{ $t('search.simple.heading') }} in the code.

To add a new language, copy an existing file in src/frontend/src/locales, rename it for your locale (e.g., fr.json), and translate the strings.

Translating annotations, metadata, etc. โ€‹

In your override file in static/locales, you can set names for annotations, metadata fields, and more. For example, in $corporaInterfaceDataDir/YOUR_CORPUS/static/locales/en-us.json:

json
{
  "index": {
    "annotations": {
      "pos": "Part of speech"
    },
    "annotationGroups": {
      "simple": "Basic annotations",
      "advanced": "Advanced annotations"
    },
    "metadata": {
      "spanFilters": {
        "name": {
          "type": "Named entity type"
        }
      }
    },
    "metadataGroups": {
      "author": "Author-related fields",
      "date": "Date-related fields"
    },
    "within": {
      "name": "Named entity"
    }
  }
}

Apache license 2.0