Skip to content

Commit 21e8701

Browse files
committed
Landing page v2
1 parent 8c6955b commit 21e8701

File tree

14 files changed

+570
-295
lines changed

14 files changed

+570
-295
lines changed

@l10n/ja/translations.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,16 @@ Stay ahead of the curve with the latest developments in RWA tokenization on the
577577
Join the Developer Discord: 開発者ディスコードに参加
578578
Sign up for the Newsletter: ニュースレターに登録
579579

580+
# docs/tutorials/index.page.tsx
581+
Crypto Wallet and Blockchain Development Tutorials: 暗号資産ウォレットやブロックチェーン開発のチュートリアル
582+
These tutorials walk you through the basics of building a very simple XRP Ledger-connected application using your favorite programming language.: これらのチュートリアルでは、お好きなプログラミング言語を使って、XRP Ledgerに接続するアプリケーションを構築するための基礎について説明します。
583+
Get Started with SDKs: SDKを使って始める
584+
Using the xrpl.js client library.: クライアントライブラリxrpl.jsを使用
585+
Using xrpl.py, a pure Python library.: Pythonライブラリxrpl.pyを使用
586+
Using xrpl4j, a pure Java library.: Javaライブラリを使用
587+
Using the XRPL_PHP client library.: PHPライブラリXRPL_PHPを使用
588+
Access the XRP Ledger directly through the APIs of its core server.: コアサーバのAPIを通じてXRP Ledgerに直接アクセス
589+
580590
# community/index.page.tsx
581591
XRPL Community: XRPLコミュニティ
582592
community.index.h1part1: 開発者とイノベーターによる

@theme/components/TutorialCategory.tsx

Lines changed: 0 additions & 144 deletions
This file was deleted.

@theme/markdoc/components.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { Button } from '@redocly/theme/components/Button/Button'
1010
export { default as XRPLoader } from '../components/XRPLoader'
1111
export { XRPLCard, CardGrid } from '../components/XRPLCard'
1212
export { AmendmentsTable, AmendmentDisclaimer, Badge } from '../components/Amendments'
13-
export { TutorialCategory } from '../components/TutorialCategory'
1413

1514
export function IndexPageItems() {
1615
const { usePageSharedData } = useThemeHooks()

@theme/markdoc/schema.ts

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -243,28 +243,3 @@ export const amendmentDisclaimer: Schema & { tagName: string } = {
243243
render: 'AmendmentDisclaimer',
244244
selfClosing: true
245245
}
246-
247-
export const tutorialCategory: Schema & { tagName: string } = {
248-
tagName: 'tutorial-category',
249-
attributes: {
250-
title: {
251-
type: 'String',
252-
required: true
253-
},
254-
description: {
255-
type: 'String',
256-
required: false
257-
},
258-
tutorials: {
259-
type: 'Array',
260-
required: true
261-
},
262-
maxTutorials: {
263-
type: 'Number',
264-
required: false,
265-
default: 6
266-
}
267-
},
268-
render: 'TutorialCategory',
269-
selfClosing: true
270-
}

@theme/plugin.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { indexPages } from './plugins/index-pages.js';
22
import { codeSamples } from './plugins/code-samples.js';
33
import { blogPosts } from './plugins/blog-posts.js';
4+
import { tutorialLanguages } from './plugins/tutorial-languages.js';
45

56
export default function customPlugin() {
67
const indexPagesInst = indexPages();
78
const codeSamplesInst = codeSamples();
89
const blogPostsInst = blogPosts();
9-
10-
10+
const tutorialLanguagesInst = tutorialLanguages();
1111

1212
/** @type {import("@redocly/realm/dist/server/plugins/types").PluginInstance } */
1313
const pluginInstance = {
@@ -16,6 +16,7 @@ export default function customPlugin() {
1616
await indexPagesInst.processContent?.(content, actions);
1717
await codeSamplesInst.processContent?.(content, actions);
1818
await blogPostsInst.processContent?.(content, actions);
19+
await tutorialLanguagesInst.processContent?.(content, actions);
1920
},
2021
afterRoutesCreated: async (content, actions) => {
2122
await indexPagesInst.afterRoutesCreated?.(content, actions);
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// @ts-check
2+
3+
/**
4+
* Plugin to detect languages supported in tutorial pages by scanning for tab labels.
5+
* This creates shared data that maps tutorial paths to their supported languages.
6+
*/
7+
export function tutorialLanguages() {
8+
/** @type {import("@redocly/realm/dist/server/plugins/types").PluginInstance } */
9+
const instance = {
10+
processContent: async (actions, { fs, cache }) => {
11+
try {
12+
/** @type {Record<string, string[]>} */
13+
const tutorialLanguagesMap = {};
14+
const allFiles = await fs.scan();
15+
16+
// Find all markdown files in tutorials directory
17+
const tutorialFiles = allFiles.filter((file) =>
18+
file.relativePath.match(/^docs[\/\\]tutorials[\/\\].*\.md$/)
19+
);
20+
21+
for (const { relativePath } of tutorialFiles) {
22+
try {
23+
const { data } = await cache.load(relativePath, 'markdown-ast');
24+
const languages = extractLanguagesFromAst(data.ast);
25+
26+
if (languages.length > 0) {
27+
// Convert file path to URL path
28+
const urlPath = '/' + relativePath
29+
.replace(/\.md$/, '/')
30+
.replace(/\\/g, '/');
31+
tutorialLanguagesMap[urlPath] = languages;
32+
}
33+
} catch (err) {
34+
continue; // Skip files that can't be parsed.
35+
}
36+
}
37+
38+
actions.createSharedData('tutorial-languages', tutorialLanguagesMap);
39+
actions.addRouteSharedData('/docs/tutorials/', 'tutorial-languages', 'tutorial-languages');
40+
actions.addRouteSharedData('/ja/docs/tutorials/', 'tutorial-languages', 'tutorial-languages');
41+
actions.addRouteSharedData('/es-es/docs/tutorials/', 'tutorial-languages', 'tutorial-languages');
42+
} catch (e) {
43+
console.log('[tutorial-languages] Error:', e);
44+
}
45+
},
46+
};
47+
return instance;
48+
}
49+
50+
/**
51+
* Extract language names from tab labels in the markdown AST
52+
*/
53+
function extractLanguagesFromAst(ast) {
54+
const languages = new Set();
55+
56+
visit(ast, (node) => {
57+
// Look for tab nodes with a label attribute
58+
if (isNode(node) && node.type === 'tag' && node.tag === 'tab') {
59+
const label = node.attributes?.label;
60+
if (label) {
61+
const normalizedLang = normalizeLanguage(label);
62+
if (normalizedLang) {
63+
languages.add(normalizedLang);
64+
}
65+
}
66+
}
67+
});
68+
69+
return Array.from(languages);
70+
}
71+
72+
/**
73+
* Convert tab labels like "JavaScript", "Python", etc. to lowercase keys
74+
* used for displaying the correct language icons on tutorial cards.
75+
*/
76+
function normalizeLanguage(label) {
77+
const labelLower = label.toLowerCase();
78+
79+
if (labelLower.includes('javascript') || labelLower === 'js') {
80+
return 'javascript';
81+
}
82+
if (labelLower.includes('python') || labelLower === 'py') {
83+
return 'python';
84+
}
85+
if (labelLower.includes('java') && !labelLower.includes('javascript')) {
86+
return 'java';
87+
}
88+
if (labelLower.includes('php')) {
89+
return 'php';
90+
}
91+
if (labelLower.includes('go') || labelLower === 'golang') {
92+
return 'go';
93+
}
94+
if (labelLower.includes('http') || labelLower.includes('websocket')) {
95+
return 'http';
96+
}
97+
98+
return null;
99+
}
100+
101+
function isNode(value) {
102+
return !!(value?.$$mdtype === 'Node');
103+
}
104+
105+
function visit(node, visitor) {
106+
if (!node) return;
107+
108+
visitor(node);
109+
110+
if (node.children) {
111+
for (const child of node.children) {
112+
if (!child || typeof child === 'string') {
113+
continue;
114+
}
115+
visit(child, visitor);
116+
}
117+
}
118+
}

docs/tutorials/index.md

Lines changed: 0 additions & 56 deletions
This file was deleted.

0 commit comments

Comments
 (0)