Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions TD-21-i18n-PROMPT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Prompt

You are assisting the ArchivesSpace Tech Docs project with translating technical documentation from English into another language, for a human volunteer to review before it is merged.

## Context

- Source: the ArchivesSpace Tech Docs site (this repo, which uses the Starlight/Astro.js framework), documenting ArchivesSpace, the open-source archives management software used by archives, libraries, and museums.
- Audience: a mix of archivists/records managers (administrators, non-developers) and developers/sysadmins who install, configure, extend, and operate ArchivesSpace.
- Output is a DRAFT. Prioritize accuracy and flag uncertainty in "Translator notes" rather than guessing silently.

## Task

Translate the file listed below in the 'Source file' section from English into {TARGET_LANGUAGE} ({LOCALE_CODE}), for use as `src/content/docs/{LOCALE_CODE}/{RELATIVE_FILE_NAME}`.

Before translating:

1. Read the {TARGET_LANGUAGE} section of `TD-21-i18n-glossary.md` in this repo. Reuse existing entries verbatim.
2. If you encounter a recurring ArchivesSpace/archival-science term not yet in the glossary, prefer the term ArchivesSpace's own application already uses in its official {LOCALE_CODE} UI translation (see locale files at github.com/archivesspace/archivesspace under `frontend/config/locales`, `public/config/locales`, `common/locales`; background in `/customization/locales`) so the docs match the software. Otherwise use the most standard professional archival-science translation for {TARGET_LANGUAGE}, not a literal/invented one. Add every such new term to the glossary and note your reasoning in the translator-notes log (see "Output" below).

### Translation rules

- Translate: headings, paragraphs, list items, table text, aside/admonition content, image alt text, and link text.
- Do NOT translate: code blocks/inline code, shell commands, file paths, YAML/JSON keys, config option names, environment variable names, class/method names, and URLs.
- Do NOT translate product/technology proper nouns (ArchivesSpace, MySQL, Solr, Docker, JRuby, GitHub, npm, etc.); follow {TARGET_LANGUAGE}'s normal convention for inflecting/declining them if needed.
- In YAML frontmatter, translate only human-facing values (`title`, `description`, and similar `label`/`tagline` fields). Leave keys and non-text values (booleans, dates, slugs) unchanged.
- Leave internal link paths (e.g. `/architecture/public`) byte-for-byte as-is; translate only the visible link text. The site automatically rewrites these to the correct locale-prefixed path at build time — do not add a locale prefix yourself.
- Preserve all Markdown/MDX syntax exactly: heading levels, code fence language/meta strings, `:::` aside types, `<Steps>`/`<FileTree>` tags and props, table structure, and Mermaid syntax (translate only quoted labels inside `mermaid` blocks, never the diagram syntax).
- Follow {TARGET_LANGUAGE}'s own grammar/capitalization/punctuation conventions rather than mirroring English (see `/about/authoring#writing-conventions` for the English baseline this content follows).
- Use a formal, neutral, precise technical register; avoid regional slang.
- Do not add, remove, reorder, or "fix" content. If you spot an English error, note it instead of silently changing meaning.

### Source file

Read `src/content/docs/{RELATIVE_FILE_NAME}` directly from this repo. `{RELATIVE_FILE_NAME}` must match the English original exactly (same filename and directory segments); do not translate or rename the path.

### Output

Perform these actions directly in this repo; do not just print results in chat:

1. Write the full translated file (frontmatter included) to `src/content/docs/{LOCALE_CODE}/{RELATIVE_FILE_NAME}`.
2. If you proposed any new glossary terms, add them as new rows to the {TARGET_LANGUAGE} table in `TD-21-i18n-glossary.md`.
3. Append a new section to `i18n-notes/{LOCALE_CODE}.md` (create the file with a top-level heading if it doesn't exist yet) titled with today's date and the relative path you just translated, listing: (a) any new glossary terms you added and why, (b) terms/sentences you were unsure about and why, (c) issues noticed in the English source but not changed.
210 changes: 210 additions & 0 deletions TD-21-i18n-glossary.md

Large diffs are not rendered by default.

489 changes: 489 additions & 0 deletions TD-21-i18n_project.md

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions astro.config.mjs
Original file line number Diff line number Diff line change
@@ -1,13 +1,48 @@
import { defineConfig } from 'astro/config'
import starlight from '@astrojs/starlight'
import sidebar from './src/siteNavigation.json'
import { remarkLocalizeLinks } from './src/lib/remark-localize-links.ts'

// https://astro.build/config
export default defineConfig({
site: 'https://docs.archivesspace.org',
markdown: {
remarkPlugins: [remarkLocalizeLinks]
},
integrations: [
starlight({
title: 'Tech Docs',
defaultLocale: 'root',
locales: {
root: {
label: 'English',
lang: 'en'
},
nl: {
label: 'Nederlands',
lang: 'nl'
},
fr: {
label: 'Français',
lang: 'fr'
},
de: {
label: 'Deutsch',
lang: 'de'
},
ja: {
label: '日本語',
lang: 'ja'
},
es: {
label: 'Español',
lang: 'es'
},
uk: {
label: 'Українська',
lang: 'uk'
}
},
routeMiddleware: './src/blogRouteData.js',
logo: {
dark: './src/images/logo-full-dark.svg',
Expand Down
5 changes: 4 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@
"@astrojs/starlight": "^0.41.5",
"astro": "^7.1.6",
"mermaid": "^11.14.0",
"sharp": "^0.35.3"
"sharp": "^0.35.3",
"unist-util-visit": "^5.1.0"
},
"devDependencies": {
"@types/mdast": "^4.0.4",
"@types/unist": "^3.0.3",
"cypress": "^15.13.0",
"postcss-html": "^1.8.0",
"prettier": "^3.8.1",
Expand Down
7 changes: 4 additions & 3 deletions src/content.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineCollection } from 'astro:content'
import { glob } from 'astro/loaders'
import { docsLoader } from '@astrojs/starlight/loaders'
import { docsSchema } from '@astrojs/starlight/schema'
import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders'
import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'
import { z } from 'astro/zod'
import { DEFAULT_ISSUE_TEXT, DEFAULT_ISSUE_URL } from '@lib/constants.ts'

Expand Down Expand Up @@ -30,5 +30,6 @@ export const collections = {
blog: defineCollection({
loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }),
schema: blogSchema
})
}),
i18n: defineCollection({ loader: i18nLoader(), schema: i18nSchema() })
}
78 changes: 78 additions & 0 deletions src/lib/remark-localize-links.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { visit } from 'unist-util-visit'
import type { Root } from 'mdast'
import type { VFile } from 'vfile'

/**
* Locale folders under `src/content/docs/` for translated content, in
* addition to the `en.yml` languages listed in `TD-21-i18n_project.md`.
* Keep in sync with the `locales` configured for Starlight once i18n is
* enabled in `astro.config.mjs`.
*/
const LOCALE_CODES = ['fr', 'de', 'ja', 'es', 'uk', 'nl'] as const

type LocaleCode = (typeof LOCALE_CODES)[number]

const DOCS_COLLECTION_SEGMENT = 'content/docs/'

/**
* Remark plugin that rewrites internal documentation links so they point at
* the current file's own locale instead of always pointing at the English
* (root) path.
*
* Starlight does not localize plain Markdown/MDX link hrefs on its own --
* that only happens for helpers like `getRelativeLocaleUrl()` used inside
* `.astro` components. Without this plugin, a link such as
* `[Public user interface](/architecture/public)` written in a translated
* page would keep sending readers back to the English page.
*
* English is the `root` locale (unprefixed paths, e.g. `/architecture/public`
* stays as-is), so files outside a locale folder are left untouched. Files
* under `src/content/docs/<locale>/` get every internal, non-blog doc link
* prefixed with `/<locale>`. This is safe even before a page has been
* translated: Starlight generates a route for every locale-prefixed path and
* automatically falls back to the English content (with a "not yet
* translated" notice) until a real translation exists -- see "Fallback
* content" in `TD-21-i18n_project.md`.
*/
export function remarkLocalizeLinks() {
return (tree: Root, file: VFile) => {
const locale = getFileLocale(file.path)
if (!locale) return // root (English) content -- links are already correct

visit(tree, 'link', (node) => {
if (shouldLocalize(node.url)) {
node.url = `/${locale}${node.url}`
}
})
}
}

function getFileLocale(filePath: string | undefined): LocaleCode | undefined {
if (!filePath) return undefined

const normalizedPath = filePath.replaceAll('\\', '/')
const collectionIndex = normalizedPath.indexOf(DOCS_COLLECTION_SEGMENT)
if (collectionIndex === -1) return undefined

const relativePath = normalizedPath.slice(
collectionIndex + DOCS_COLLECTION_SEGMENT.length
)
const [firstSegment] = relativePath.split('/')

return (LOCALE_CODES as readonly string[]).includes(firstSegment)
? (firstSegment as LocaleCode)
: undefined
}

function shouldLocalize(url: string): boolean {
if (!url.startsWith('/')) return false // relative, anchor-only, or external
if (url.startsWith('/blog/')) return false // blog is not a localized collection

return !isAlreadyLocalized(url)
}

function isAlreadyLocalized(url: string): boolean {
return LOCALE_CODES.some(
(locale) => url === `/${locale}` || url.startsWith(`/${locale}/`)
)
}
Loading