Skip to content

Commit 0553bb0

Browse files
Merge branch 'jsonld-authors' into jsonld-organization
2 parents dc32e51 + 7780bfb commit 0553bb0

84 files changed

Lines changed: 1916 additions & 1211 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.all-contributorsrc

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1501,7 +1501,8 @@
15011501
"avatar_url": "https://avatars1.githubusercontent.com/u/44020788?v=4",
15021502
"profile": "https://twitter.com/AnettRolikova",
15031503
"contributions": [
1504-
"content"
1504+
"content",
1505+
"tool"
15051506
]
15061507
},
15071508
{
@@ -14149,6 +14150,51 @@
1414914150
"contributions": [
1415014151
"maintenance"
1415114152
]
14153+
},
14154+
{
14155+
"login": "Ale-Bv-Dev",
14156+
"name": "Ale-Bv-Dev",
14157+
"avatar_url": "https://avatars.githubusercontent.com/u/214505223?v=4",
14158+
"profile": "https://github.com/Ale-Bv-Dev",
14159+
"contributions": [
14160+
"bug"
14161+
]
14162+
},
14163+
{
14164+
"login": "rayjun",
14165+
"name": "rayoo",
14166+
"avatar_url": "https://avatars.githubusercontent.com/u/7517993?v=4",
14167+
"profile": "https://github.com/rayjun",
14168+
"contributions": [
14169+
"bug"
14170+
]
14171+
},
14172+
{
14173+
"login": "kangbaek324",
14174+
"name": "BaekHo Kang",
14175+
"avatar_url": "https://avatars.githubusercontent.com/u/162931494?v=4",
14176+
"profile": "https://github.com/kangbaek324",
14177+
"contributions": [
14178+
"translation"
14179+
]
14180+
},
14181+
{
14182+
"login": "franrob-projects",
14183+
"name": "Fran Roberts",
14184+
"avatar_url": "https://avatars.githubusercontent.com/u/111994975?v=4",
14185+
"profile": "https://franrob-projects.github.io/portfolio/",
14186+
"contributions": [
14187+
"content"
14188+
]
14189+
},
14190+
{
14191+
"login": "jzhishu",
14192+
"name": "JH",
14193+
"avatar_url": "https://avatars.githubusercontent.com/u/39545185?v=4",
14194+
"profile": "https://github.com/jzhishu",
14195+
"contributions": [
14196+
"bug"
14197+
]
1415214198
}
1415314199
],
1415414200
"contributorsPerLine": 7,

.claude/commands/review-translations.md

Lines changed: 28 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -224,38 +224,39 @@ Read `.claude/translation-review/known-patterns.md` — this contains all issue
224224

225225
### Translation Glossary (AUTHORITATIVE SOURCE)
226226

227-
The EthGlossary API (`https://ethereum.org/api/glossary`) is the **authoritative source** for all Ethereum term translations across the entire pipeline. Community-voted glossary terms are not suggestions — they are the required translations.
227+
**ETHGlossary** is the authoritative source for Ethereum term translations. Deviations are critical issues, not warnings.
228228

229-
**Fetch live from the API first, fall back to cache only if the API is unreachable:**
229+
Resolve the base URL from the pipeline config (env var wins; default lives in `src/scripts/intl-pipeline/config.ts` under `GLOSSARY_API_URL`):
230230

231231
```bash
232-
# Fetch live glossary
233-
GLOSSARY_CACHE="$HOME/.claude/translation-review/fetch-translation-glossary.json"
234-
GLOSSARY_URL="https://ethereum.org/api/glossary"
235-
236-
# Try live fetch first
237-
if curl -sf "$GLOSSARY_URL" -o "$TMPDIR/glossary-live.json" 2>/dev/null; then
238-
# Update cache with fresh data
239-
cp "$TMPDIR/glossary-live.json" "$GLOSSARY_CACHE"
240-
echo "Glossary fetched live from API and cache updated."
241-
else
242-
echo "WARNING: API unreachable, using cached glossary."
243-
fi
232+
GLOSSARY_API_URL="${GLOSSARY_API_URL:-$(grep -oE 'https://[^"]+/api/v[0-9]+' "$WORKTREE_PATH/src/scripts/intl-pipeline/config.ts" | head -1)}"
233+
GLOSSARY_HOST="${GLOSSARY_API_URL%/api/*}"
244234
```
245235

246-
Schema: `Array<{ string_term, translation_text, language_code, total_votes }>`.
236+
Fetch `llms.txt` first as the canonical reference for endpoints and languages; if examples below disagree, llms.txt wins:
247237

248-
For each language being reviewed, extract relevant glossary terms:
238+
```bash
239+
curl -sf "$GLOSSARY_HOST/llms.txt" \
240+
-o "$TMPDIR/ethglossary-llms.txt" \
241+
&& cp "$TMPDIR/ethglossary-llms.txt" "$HOME/.claude/translation-review/ethglossary-llms.txt"
249242
```
250-
Filter entries where language_code matches the target locale.
251-
Sort by total_votes descending.
252-
Include ALL terms for the language (not just top 50) — these are authoritative.
243+
244+
**Preferred — per-file filter** (`POST /filter`): returns only the glossary terms that appear in the English source, with translations sorted by occurrence. Avoids pulling hundreds of irrelevant terms into agent context.
245+
246+
```bash
247+
ENGLISH_SOURCE=$(cat "$WORKTREE_PATH/public/content/{path}.md")
248+
curl -sf -X POST "$GLOSSARY_API_URL/filter" \
249+
-H "Content-Type: application/json" \
250+
-d "$(jq -n --arg text "$ENGLISH_SOURCE" --arg lang "{LANGUAGE_CODE}" '{text: $text, language: $lang}')"
251+
```
252+
253+
**Fallback — full language** when filtering per file is impractical or the endpoint is unreachable:
254+
255+
```bash
256+
curl -sf "$GLOSSARY_API_URL/translations/{LANGUAGE_CODE}"
253257
```
254258

255-
**The glossary is used in every subsequent phase:**
256-
- **Phase 3 (Review):** Agents treat glossary deviations as CRITICAL, not warnings
257-
- **Phase 5 (Auto-Fix):** Glossary deviations are auto-corrected to the top-voted translation
258-
- **Phase 8 (Knowledge Base):** New deviations discovered are logged for future reviews
259+
Used in Phase 3 (review — deviations are CRITICAL), Phase 5 (auto-fix corrects to ETHGlossary translation), Phase 8 (new deviations logged).
259260

260261
### Per-Language Prior Findings
261262
Check if `.claude/translation-review/per-language/{LANGUAGE_CODE}.md` exists. If so, read it and inject relevant prior findings into the agent prompt.
@@ -331,22 +332,11 @@ The community has voted on these translations for key Ethereum terms. Use these
331332
- Review the entire current content of each file
332333
- Compare against English source files from the worktree
333334
334-
## MANDATORY: Fetch Ethereum Glossary FIRST
335-
336-
**Before reviewing ANY translation, you MUST fetch the official Ethereum glossary for the language(s) being reviewed.** This is non-negotiable. The glossary contains community-approved translations for key terms.
337-
338-
```bash
339-
# Fetch full glossary (all languages):
340-
curl -s "https://ethereum.org/api/glossary/"
341-
342-
# Fetch glossary for a specific language (optional lang param, one at a time):
343-
curl -s "https://ethereum.org/api/glossary/?lang=fr"
344-
curl -s "https://ethereum.org/api/glossary/?lang=ja"
345-
```
335+
## MANDATORY: Use ETHGlossary for the target language
346336
347-
The glossary returns approved translations per language. Use these as the authority for how technical terms SHOULD be translated. Flag any deviations as warnings with "Glossary mismatch" in the issue column.
337+
Use the ETHGlossary terms fetched in Phase 2 as the authority for technical term translations. Report deviations as **critical** issues (not warnings), with the current (wrong) translation and the expected (ETHGlossary) translation so Phase 5 can auto-fix them.
348338
349-
**If you skip the glossary, the entire review is invalid.**
339+
**If you skip ETHGlossary, the entire review is invalid.**
350340
351341
## Review Checklist
352342
@@ -733,6 +723,6 @@ ETH, Wei, Gwei, Gas
733723
- Use `--model=sonnet` or `--model=haiku` for faster reviews
734724
- Build verification is opt-in: `--build-local` for local scoped builds, `--netlify-check` for Netlify deploy preview checks
735725
- If an agent exceeds context limits with Opus, fall back to Sonnet with Grep-based file inspection
736-
- **EthGlossary API** (`https://ethereum.org/api/glossary`) is fetched live in Phase 2 and is the authoritative source for term translations across the entire pipeline — review (Phase 3), auto-fix (Phase 5), and knowledge base (Phase 8). The local cache at `~/.claude/translation-review/fetch-translation-glossary.json` is a fallback only.
726+
- **ETHGlossary** is the authoritative source for term translations across review (Phase 3), auto-fix (Phase 5), and knowledge base (Phase 8). See Phase 2 for usage; `llms.txt` is the canonical endpoint reference.
737727
- Knowledge base at `.claude/translation-review/` accumulates findings across reviews (committed to repo)
738728
- `gh` CLI commands require `dangerouslyDisableSandbox: true` due to TLS certificate verification issues in sandbox mode

AGENTS.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,10 @@ pnpm events-import # Import community events
119119

120120
### Internationalization
121121

122-
- **25 languages** supported via Crowdin (canonical list: `i18n.config.json`)
123-
- **RTL support** for Arabic, Urdu
124-
- Translation files (JSON format) in `src/intl/[locale]/`
125-
- Content translations managed through Crowdin platform
122+
- **25 languages** supported (canonical list: `i18n.config.json`); **RTL support** for Arabic, Urdu
123+
- JSON UI strings in `src/intl/[locale]/`; translated markdown content in `public/content/translations/[locale]/`
124+
- Non-English markdown is propagated by the **intl-pipeline** (`src/scripts/intl-pipeline/`, entry `main.ts`). **Do not hand-propagate English changes into non-English files** -- let the pipeline run, or trigger `intl-pipeline.yml` with `stamp_only: true` if manifests must catch up urgently (e.g. unblocking a build). Hand-fixing a translation error is fine when the English side hasn't moved, since the manifest mapping stays valid. Spec: `tests/specs/PIPELINE-SPEC.md`.
125+
- Glossary: base URL from `GLOSSARY_API_URL` env var; default in `src/scripts/intl-pipeline/config.ts`. ETHGlossary is authoritative for Ethereum term translations.
126126

127127
### Markdown Content
128128

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
435435
<td align="center" valign="top" width="14.28%"><a href="https://github.com/evertonfraga"><img src="https://avatars2.githubusercontent.com/u/47108?v=4?s=100" width="100px;" alt="Ev"/><br /><sub><b>Ev</b></sub></a><br /><a href="#ideas-evertonfraga" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/ethereum/ethereum-org-website/issues?q=author%3Aevertonfraga" title="Bug reports">🐛</a> <a href="#content-evertonfraga" title="Content">🖋</a></td>
436436
<td align="center" valign="top" width="14.28%"><a href="https://discord.gg/5W5tVb3"><img src="https://avatars2.githubusercontent.com/u/6251510?v=4?s=100" width="100px;" alt="Ivan Martinez"/><br /><sub><b>Ivan Martinez</b></sub></a><br /><a href="#content-0xKiwi" title="Content">🖋</a></td>
437437
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sebastiantf"><img src="https://avatars3.githubusercontent.com/u/36922376?v=4?s=100" width="100px;" alt="Sebastian T F"/><br /><sub><b>Sebastian T F</b></sub></a><br /><a href="https://github.com/ethereum/ethereum-org-website/commits?author=sebastiantf" title="Code">💻</a></td>
438-
<td align="center" valign="top" width="14.28%"><a href="https://twitter.com/AnettRolikova"><img src="https://avatars1.githubusercontent.com/u/44020788?v=4?s=100" width="100px;" alt="Anett Rolikova "/><br /><sub><b>Anett Rolikova </b></sub></a><br /><a href="#content-anettrolikova" title="Content">🖋</a></td>
438+
<td align="center" valign="top" width="14.28%"><a href="https://twitter.com/AnettRolikova"><img src="https://avatars1.githubusercontent.com/u/44020788?v=4?s=100" width="100px;" alt="Anett Rolikova "/><br /><sub><b>Anett Rolikova </b></sub></a><br /><a href="#content-anettrolikova" title="Content">🖋</a> <a href="#tool-anettrolikova" title="Tools">🔧</a></td>
439439
</tr>
440440
<tr>
441441
<td align="center" valign="top" width="14.28%"><a href="https://etherworld.co"><img src="https://avatars0.githubusercontent.com/u/29681685?v=4?s=100" width="100px;" alt="Pooja Ranjan"/><br /><sub><b>Pooja Ranjan</b></sub></a><br /><a href="#content-poojaranjan" title="Content">🖋</a></td>
@@ -2203,6 +2203,11 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
22032203
</tr>
22042204
<tr>
22052205
<td align="center" valign="top" width="14.28%"><a href="https://linktr.ee/jadijadi"><img src="https://avatars.githubusercontent.com/u/1290639?v=4?s=100" width="100px;" alt="Jadi"/><br /><sub><b>Jadi</b></sub></a><br /><a href="#maintenance-jadijadi" title="Maintenance">🚧</a></td>
2206+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ale-Bv-Dev"><img src="https://avatars.githubusercontent.com/u/214505223?v=4?s=100" width="100px;" alt="Ale-Bv-Dev"/><br /><sub><b>Ale-Bv-Dev</b></sub></a><br /><a href="https://github.com/ethereum/ethereum-org-website/issues?q=author%3AAle-Bv-Dev" title="Bug reports">🐛</a></td>
2207+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rayjun"><img src="https://avatars.githubusercontent.com/u/7517993?v=4?s=100" width="100px;" alt="rayoo"/><br /><sub><b>rayoo</b></sub></a><br /><a href="https://github.com/ethereum/ethereum-org-website/issues?q=author%3Arayjun" title="Bug reports">🐛</a></td>
2208+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kangbaek324"><img src="https://avatars.githubusercontent.com/u/162931494?v=4?s=100" width="100px;" alt="BaekHo Kang"/><br /><sub><b>BaekHo Kang</b></sub></a><br /><a href="#translation-kangbaek324" title="Translation">🌍</a></td>
2209+
<td align="center" valign="top" width="14.28%"><a href="https://franrob-projects.github.io/portfolio/"><img src="https://avatars.githubusercontent.com/u/111994975?v=4?s=100" width="100px;" alt="Fran Roberts"/><br /><sub><b>Fran Roberts</b></sub></a><br /><a href="#content-franrob-projects" title="Content">🖋</a></td>
2210+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jzhishu"><img src="https://avatars.githubusercontent.com/u/39545185?v=4?s=100" width="100px;" alt="JH"/><br /><sub><b>JH</b></sub></a><br /><a href="https://github.com/ethereum/ethereum-org-website/issues?q=author%3Ajzhishu" title="Bug reports">🐛</a></td>
22062211
</tr>
22072212
</tbody>
22082213
</table>

app/[locale]/10years/page-jsonld.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import { FileContributor } from "@/lib/types"
44

55
import PageJsonLD from "@/components/PageJsonLD"
66

7-
import { BASE_GRAPH_NODES, REFERENCE } from "@/lib/jsonld/constants"
87
import { normalizeUrlForJsonLd } from "@/lib/utils/url"
98

9+
import { BASE_GRAPH_NODES, REFERENCE } from "@/lib/jsonld/constants"
10+
1011
export default async function TenYearJsonLD({
1112
locale,
1213
contributors,

app/[locale]/[...slug]/page-jsonld.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { FileContributor, Frontmatter } from "@/lib/types"
33
import PageJsonLD from "@/components/PageJsonLD"
44

55
import { normalizeUrlForJsonLd } from "@/lib/utils/url"
6+
67
import { BASE_GRAPH_NODES, REFERENCE } from "@/lib/jsonld/constants"
78
import { resolveAuthorsFromFrontmatter } from "@/lib/jsonld/utils"
89

app/[locale]/apps/[application]/page-jsonld.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import { AppCategory, AppData, FileContributor } from "@/lib/types"
22

33
import PageJsonLD from "@/components/PageJsonLD"
44

5-
import { BASE_GRAPH_NODES, REFERENCE } from "@/lib/jsonld/constants"
65
import { normalizeUrlForJsonLd, slugify } from "@/lib/utils/url"
76

7+
import { BASE_GRAPH_NODES, REFERENCE } from "@/lib/jsonld/constants"
8+
89
// Map internal app categories to schema.org enumerated applicationCategory values
910
// https://schema.org/applicationCategory
1011
const APPLICATION_CATEGORY_MAP: Record<AppCategory, string> = {

app/[locale]/apps/categories/[catetgoryName]/page-jsonld.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import { AppCategoryData, AppData, FileContributor } from "@/lib/types"
44

55
import PageJsonLD from "@/components/PageJsonLD"
66

7-
import { BASE_GRAPH_NODES, REFERENCE } from "@/lib/jsonld/constants"
87
import { normalizeUrlForJsonLd } from "@/lib/utils/url"
98

9+
import { BASE_GRAPH_NODES, REFERENCE } from "@/lib/jsonld/constants"
10+
1011
export default async function AppsCategoryJsonLD({
1112
locale,
1213
categoryName,

app/[locale]/apps/categories/[catetgoryName]/page.tsx

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -223,35 +223,45 @@ export async function generateMetadata(props: {
223223
}) {
224224
const params = await props.params
225225
const { locale, catetgoryName } = params
226-
const t = await getTranslations("page-apps")
227226

228-
// Normalize slug to lowercase
229-
const normalizedSlug = catetgoryName.toLowerCase()
227+
try {
228+
const t = await getTranslations("page-apps")
230229

231-
// Find category by matching the slug
232-
const categoryEntry = Object.entries(appsCategories).find(
233-
([, categoryData]) => categoryData.slug === normalizedSlug
234-
)
230+
// Normalize slug to lowercase
231+
const normalizedSlug = catetgoryName.toLowerCase()
235232

236-
if (!categoryEntry) {
237-
notFound()
238-
}
233+
// Find category by matching the slug
234+
const categoryEntry = Object.entries(appsCategories).find(
235+
([, categoryData]) => categoryData.slug === normalizedSlug
236+
)
239237

240-
const [categoryEnum, category] = categoryEntry
238+
if (!categoryEntry) {
239+
throw new Error(`App category not found: ${catetgoryName}`)
240+
}
241241

242-
if (!isValidCategory(categoryEnum)) {
243-
notFound()
244-
}
242+
const [categoryEnum, category] = categoryEntry
245243

246-
const title = t(category.metaTitle)
247-
const description = t(category.metaDescription)
244+
if (!isValidCategory(categoryEnum)) {
245+
throw new Error(`Invalid app category enum: ${categoryEnum}`)
246+
}
248247

249-
return await getMetadata({
250-
locale,
251-
slug: ["apps", "categories", normalizedSlug],
252-
title,
253-
description,
254-
})
248+
const title = t(category.metaTitle)
249+
const description = t(category.metaDescription)
250+
251+
return await getMetadata({
252+
locale,
253+
slug: ["apps", "categories", normalizedSlug],
254+
title,
255+
description,
256+
})
257+
} catch {
258+
const t = await getTranslations("common")
259+
260+
return {
261+
title: t("page-not-found"),
262+
description: t("page-not-found-description"),
263+
}
264+
}
255265
}
256266

257267
export default Page

app/[locale]/apps/page-jsonld.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import { FileContributor } from "@/lib/types"
44

55
import PageJsonLD from "@/components/PageJsonLD"
66

7-
import { BASE_GRAPH_NODES, REFERENCE } from "@/lib/jsonld/constants"
87
import { normalizeUrlForJsonLd } from "@/lib/utils/url"
98

109
import { appsCategories } from "@/data/apps/categories"
1110

11+
import { BASE_GRAPH_NODES, REFERENCE } from "@/lib/jsonld/constants"
12+
1213
export default async function AppsJsonLD({
1314
locale,
1415
contributors,

0 commit comments

Comments
 (0)