mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2026-02-23 23:32:27 +00:00
Compare commits
2 Commits
tutorials-
...
tutorials-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98552291e9 | ||
|
|
8c6955b72c |
@@ -577,6 +577,16 @@ Stay ahead of the curve with the latest developments in RWA tokenization on the
|
||||
Join the Developer Discord: 開発者ディスコードに参加
|
||||
Sign up for the Newsletter: ニュースレターに登録
|
||||
|
||||
# docs/tutorials/index.page.tsx
|
||||
Crypto Wallet and Blockchain Development Tutorials: 暗号資産ウォレットやブロックチェーン開発のチュートリアル
|
||||
These tutorials walk you through the basics of building a very simple XRP Ledger-connected application using your favorite programming language.: これらのチュートリアルでは、お好きなプログラミング言語を使って、XRP Ledgerに接続するアプリケーションを構築するための基礎について説明します。
|
||||
Get Started with SDKs: SDKを使って始める
|
||||
Using the xrpl.js client library.: クライアントライブラリxrpl.jsを使用。
|
||||
Using xrpl.py, a pure Python library.: Pythonライブラリxrpl.pyを使用。
|
||||
Using xrpl4j, a pure Java library.: Javaライブラリを使用。
|
||||
Using the XRPL_PHP client library.: PHPライブラリXRPL_PHPを使用。
|
||||
Access the XRP Ledger directly through the APIs of its core server.: コアサーバのAPIを通じてXRP Ledgerに直接アクセス。
|
||||
|
||||
# community/index.page.tsx
|
||||
XRPL Community: XRPLコミュニティ
|
||||
community.index.h1part1: 開発者とイノベーターによる
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { indexPages } from './plugins/index-pages.js';
|
||||
import { codeSamples } from './plugins/code-samples.js';
|
||||
import { blogPosts } from './plugins/blog-posts.js';
|
||||
import { tutorialLanguages } from './plugins/tutorial-languages.js';
|
||||
|
||||
export default function customPlugin() {
|
||||
const indexPagesInst = indexPages();
|
||||
const codeSamplesInst = codeSamples();
|
||||
const blogPostsInst = blogPosts();
|
||||
|
||||
|
||||
const tutorialLanguagesInst = tutorialLanguages();
|
||||
|
||||
/** @type {import("@redocly/realm/dist/server/plugins/types").PluginInstance } */
|
||||
const pluginInstance = {
|
||||
@@ -16,6 +16,7 @@ export default function customPlugin() {
|
||||
await indexPagesInst.processContent?.(content, actions);
|
||||
await codeSamplesInst.processContent?.(content, actions);
|
||||
await blogPostsInst.processContent?.(content, actions);
|
||||
await tutorialLanguagesInst.processContent?.(content, actions);
|
||||
},
|
||||
afterRoutesCreated: async (content, actions) => {
|
||||
await indexPagesInst.afterRoutesCreated?.(content, actions);
|
||||
|
||||
118
@theme/plugins/tutorial-languages.js
Normal file
118
@theme/plugins/tutorial-languages.js
Normal file
@@ -0,0 +1,118 @@
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* Plugin to detect languages supported in tutorial pages by scanning for tab labels.
|
||||
* This creates shared data that maps tutorial paths to their supported languages.
|
||||
*/
|
||||
export function tutorialLanguages() {
|
||||
/** @type {import("@redocly/realm/dist/server/plugins/types").PluginInstance } */
|
||||
const instance = {
|
||||
processContent: async (actions, { fs, cache }) => {
|
||||
try {
|
||||
/** @type {Record<string, string[]>} */
|
||||
const tutorialLanguagesMap = {};
|
||||
const allFiles = await fs.scan();
|
||||
|
||||
// Find all markdown files in tutorials directory
|
||||
const tutorialFiles = allFiles.filter((file) =>
|
||||
file.relativePath.match(/^docs[\/\\]tutorials[\/\\].*\.md$/)
|
||||
);
|
||||
|
||||
for (const { relativePath } of tutorialFiles) {
|
||||
try {
|
||||
const { data } = await cache.load(relativePath, 'markdown-ast');
|
||||
const languages = extractLanguagesFromAst(data.ast);
|
||||
|
||||
if (languages.length > 0) {
|
||||
// Convert file path to URL path
|
||||
const urlPath = '/' + relativePath
|
||||
.replace(/\.md$/, '/')
|
||||
.replace(/\\/g, '/');
|
||||
tutorialLanguagesMap[urlPath] = languages;
|
||||
}
|
||||
} catch (err) {
|
||||
continue; // Skip files that can't be parsed.
|
||||
}
|
||||
}
|
||||
|
||||
actions.createSharedData('tutorial-languages', tutorialLanguagesMap);
|
||||
actions.addRouteSharedData('/docs/tutorials/', 'tutorial-languages', 'tutorial-languages');
|
||||
actions.addRouteSharedData('/ja/docs/tutorials/', 'tutorial-languages', 'tutorial-languages');
|
||||
actions.addRouteSharedData('/es-es/docs/tutorials/', 'tutorial-languages', 'tutorial-languages');
|
||||
} catch (e) {
|
||||
console.log('[tutorial-languages] Error:', e);
|
||||
}
|
||||
},
|
||||
};
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract language names from tab labels in the markdown AST
|
||||
*/
|
||||
function extractLanguagesFromAst(ast) {
|
||||
const languages = new Set();
|
||||
|
||||
visit(ast, (node) => {
|
||||
// Look for tab nodes with a label attribute
|
||||
if (isNode(node) && node.type === 'tag' && node.tag === 'tab') {
|
||||
const label = node.attributes?.label;
|
||||
if (label) {
|
||||
const normalizedLang = normalizeLanguage(label);
|
||||
if (normalizedLang) {
|
||||
languages.add(normalizedLang);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return Array.from(languages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert tab labels like "JavaScript", "Python", etc. to lowercase keys
|
||||
* used for displaying the correct language icons on tutorial cards.
|
||||
*/
|
||||
function normalizeLanguage(label) {
|
||||
const labelLower = label.toLowerCase();
|
||||
|
||||
if (labelLower.includes('javascript') || labelLower === 'js') {
|
||||
return 'javascript';
|
||||
}
|
||||
if (labelLower.includes('python') || labelLower === 'py') {
|
||||
return 'python';
|
||||
}
|
||||
if (labelLower.includes('java') && !labelLower.includes('javascript')) {
|
||||
return 'java';
|
||||
}
|
||||
if (labelLower.includes('php')) {
|
||||
return 'php';
|
||||
}
|
||||
if (labelLower.includes('go') || labelLower === 'golang') {
|
||||
return 'go';
|
||||
}
|
||||
if (labelLower.includes('http') || labelLower.includes('websocket')) {
|
||||
return 'http';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function isNode(value) {
|
||||
return !!(value?.$$mdtype === 'Node');
|
||||
}
|
||||
|
||||
function visit(node, visitor) {
|
||||
if (!node) return;
|
||||
|
||||
visitor(node);
|
||||
|
||||
if (node.children) {
|
||||
for (const child of node.children) {
|
||||
if (!child || typeof child === 'string') {
|
||||
continue;
|
||||
}
|
||||
visit(child, visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
seo:
|
||||
description: Learn how to get started building on the XRP Ledger with these helpful crypto wallet and blockchain tutorials for developers.
|
||||
---
|
||||
# Crypto Wallet and Blockchain Development Tutorials
|
||||
|
||||
The XRP Ledger tutorials walk you through the steps to learn and get started with the XRP Ledger and to use the ledger for advanced use cases.
|
||||
|
||||
## Get Started with SDKs
|
||||
|
||||
These tutorials walk you through the basics of building a very simple XRP Ledger-connected application using your favorite programming language.
|
||||
|
||||
{% card-grid %}
|
||||
|
||||
{% xrpl-card title="Javascript" body="Using the xrpl.js client library." href="/docs/tutorials/get-started/get-started-javascript/" image="/img/logos/javascript.svg" imageAlt="Javascript logo" /%}
|
||||
|
||||
{% xrpl-card title="Python" body="Using xrpl.py, a pure Python library." href="/docs/tutorials/get-started/get-started-python/" image="/img/logos/python.svg" imageAlt="Python logo" /%}
|
||||
|
||||
{% xrpl-card title="Go" body="Using xrpl-go, a pure Go library." href="/docs/tutorials/get-started/get-started-go/" image="/img/logos/golang.svg" imageAlt="Go logo" /%}
|
||||
|
||||
{% xrpl-card title="Java" body="Using xrpl4j, a pure Java library." href="/docs/tutorials/get-started/get-started-java/" image="/img/logos/java.svg" imageAlt="Java logo" /%}
|
||||
|
||||
{% xrpl-card title="PHP" body="Using the XRPL_PHP client library." href="/docs/tutorials/get-started/get-started-php/" image="/img/logos/php.svg" imageAlt="PHP logo" /%}
|
||||
|
||||
{% xrpl-card title="HTTP & WebSocket APIs" body="Access the XRP Ledger directly through the APIs of its core server." href="/docs/tutorials/get-started/get-started-http-websocket-apis/" image="/img/logos/globe.svg" imageAlt="globe icon" /%}
|
||||
|
||||
{% /card-grid %}
|
||||
|
||||
<!-- TODO: Add new sections for the new tutorial categories -->
|
||||
353
docs/tutorials/index.page.tsx
Normal file
353
docs/tutorials/index.page.tsx
Normal file
@@ -0,0 +1,353 @@
|
||||
import { useThemeHooks } from "@redocly/theme/core/hooks";
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
title: "Tutorials",
|
||||
description:
|
||||
"Learn how to get started building on the XRP Ledger with these helpful crypto wallet and blockchain tutorials for developers.",
|
||||
},
|
||||
};
|
||||
|
||||
const langIcons: Record<string, { src: string; alt: string }> = {
|
||||
javascript: { src: "/img/logos/javascript.svg", alt: "JavaScript" },
|
||||
python: { src: "/img/logos/python.svg", alt: "Python" },
|
||||
java: { src: "/img/logos/java.svg", alt: "Java" },
|
||||
go: { src: "/img/logos/golang.svg", alt: "Go" },
|
||||
php: { src: "/img/logos/php.svg", alt: "PHP" },
|
||||
http: { src: "/img/logos/globe.svg", alt: "HTTP / WebSocket" },
|
||||
xrpl: { src: "/img/logos/xrp-mark.svg", alt: "XRP Ledger" },
|
||||
};
|
||||
|
||||
// Type for the tutorial languages map from the plugin
|
||||
type TutorialLanguagesMap = Record<string, string[]>;
|
||||
|
||||
interface Tutorial {
|
||||
title: string;
|
||||
body?: string;
|
||||
path: string;
|
||||
icon?: string; // Single language icon (for single-language tutorials)
|
||||
}
|
||||
|
||||
interface TutorialSection {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
tutorials: Tutorial[];
|
||||
}
|
||||
|
||||
// Get Started tutorials -----------------
|
||||
const getStartedTutorials: Tutorial[] = [
|
||||
{
|
||||
title: "JavaScript",
|
||||
body: "Using the xrpl.js client library.",
|
||||
path: "/docs/tutorials/get-started/get-started-javascript/",
|
||||
icon: "javascript",
|
||||
},
|
||||
{
|
||||
title: "Python",
|
||||
body: "Using xrpl.py, a pure Python library.",
|
||||
path: "/docs/tutorials/get-started/get-started-python/",
|
||||
icon: "python",
|
||||
},
|
||||
{
|
||||
title: "Go",
|
||||
body: "Using xrpl-go, a pure Go library.",
|
||||
path: "/docs/tutorials/get-started/get-started-go/",
|
||||
icon: "go",
|
||||
},
|
||||
{
|
||||
title: "Java",
|
||||
body: "Using xrpl4j, a pure Java library.",
|
||||
path: "/docs/tutorials/get-started/get-started-java/",
|
||||
icon: "java",
|
||||
},
|
||||
{
|
||||
title: "PHP",
|
||||
body: "Using the XRPL_PHP client library.",
|
||||
path: "/docs/tutorials/get-started/get-started-php/",
|
||||
icon: "php",
|
||||
},
|
||||
{
|
||||
title: "HTTP & WebSocket APIs",
|
||||
body: "Access the XRP Ledger directly through the APIs of its core server.",
|
||||
path: "/docs/tutorials/get-started/get-started-http-websocket-apis/",
|
||||
icon: "http",
|
||||
},
|
||||
];
|
||||
|
||||
// Other tutorial sections -----------------
|
||||
// Languages are auto-detected from the markdown files by the tutorial-languages plugin.
|
||||
// Only specify `icon` for single-language tutorials without tabs.
|
||||
const sections: TutorialSection[] = [
|
||||
{
|
||||
id: "tokens",
|
||||
title: "Tokens",
|
||||
description: "Create and manage tokens on the XRP Ledger.",
|
||||
tutorials: [
|
||||
{
|
||||
title: "Issue a Multi-Purpose Token",
|
||||
body: "Issue new tokens using the v2 fungible token standard.",
|
||||
path: "/docs/tutorials/tokens/mpts/issue-a-multi-purpose-token/",
|
||||
},
|
||||
{
|
||||
title: "Issue a Fungible Token",
|
||||
body: "Issue new tokens using the v1 fungible token standard.",
|
||||
path: "/docs/tutorials/tokens/fungible-tokens/issue-a-fungible-token/",
|
||||
},
|
||||
{
|
||||
title: "Mint and Burn NFTs Using JavaScript",
|
||||
body: "Create new NFTs, retrieve existing tokens, and burn the ones you no longer need.",
|
||||
path: "/docs/tutorials/tokens/nfts/mint-and-burn-nfts-js/",
|
||||
icon: "javascript",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "payments",
|
||||
title: "Payments",
|
||||
description: "Transfer XRP and issued currencies using various payment types.",
|
||||
tutorials: [
|
||||
{
|
||||
title: "Send XRP",
|
||||
body: "Send a direct XRP payment to another account.",
|
||||
path: "/docs/tutorials/payments/send-xrp/",
|
||||
},
|
||||
{
|
||||
title: "Sending MPTs in JavaScript",
|
||||
body: "Send a Multi-Purpose Token (MPT) to another account with the JavaScript SDK.",
|
||||
path: "/docs/tutorials/tokens/mpts/sending-mpts-in-javascript/",
|
||||
icon: "javascript",
|
||||
},
|
||||
{
|
||||
title: "Create Trust Line and Send Currency in JavaScript",
|
||||
body: "Set up trust lines and send issued currencies with the JavaScript SDK.",
|
||||
path: "/docs/tutorials/payments/create-trust-line-send-currency-in-javascript/",
|
||||
icon: "javascript",
|
||||
},
|
||||
{
|
||||
title: "Create Trust Line and Send Currency in Python",
|
||||
body: "Set up trust lines and send issued currencies with the Python SDK.",
|
||||
path: "/docs/tutorials/payments/create-trust-line-send-currency-in-python/",
|
||||
icon: "python",
|
||||
},
|
||||
{
|
||||
title: "Send a Conditional Escrow",
|
||||
body: "Send an escrow that can be released when a specific crypto-condition is fulfilled.",
|
||||
path: "/docs/tutorials/payments/send-a-conditional-escrow/",
|
||||
},
|
||||
{
|
||||
title: "Send a Timed Escrow",
|
||||
body: "Send an escrow whose only condition for release is that a specific time has passed.",
|
||||
path: "/docs/tutorials/payments/send-a-timed-escrow/",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "defi",
|
||||
title: "DeFi",
|
||||
description: "Trade, provide liquidity, and lend using native XRP Ledger DeFi features.",
|
||||
tutorials: [
|
||||
{
|
||||
title: "Create an Automated Market Maker",
|
||||
body: "Set up an AMM for a token pair and provide liquidity.",
|
||||
path: "/docs/tutorials/defi/dex/create-an-automated-market-maker/",
|
||||
},
|
||||
{
|
||||
title: "Trade in the Decentralized Exchange",
|
||||
body: "Buy and sell tokens in the Decentralized Exchange (DEX).",
|
||||
path: "/docs/tutorials/defi/dex/trade-in-the-decentralized-exchange/",
|
||||
},
|
||||
{
|
||||
title: "Create a Loan Broker",
|
||||
body: "Set up a loan broker to create and manage loans.",
|
||||
path: "/docs/tutorials/defi/lending/use-the-lending-protocol/create-a-loan-broker/",
|
||||
},
|
||||
{
|
||||
title: "Create a Loan",
|
||||
body: "Create a loan on the XRP Ledger.",
|
||||
path: "/docs/tutorials/defi/lending/use-the-lending-protocol/create-a-loan/",
|
||||
},
|
||||
{
|
||||
title: "Create a Single Asset Vault",
|
||||
body: "Create a single asset vault on the XRP Ledger.",
|
||||
path: "/docs/tutorials/defi/lending/use-single-asset-vaults/create-a-single-asset-vault/",
|
||||
},
|
||||
{
|
||||
title: "Deposit into a Vault",
|
||||
body: "Deposit assets into a vault and receive shares.",
|
||||
path: "/docs/tutorials/defi/lending/use-single-asset-vaults/deposit-into-a-vault/",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "best-practices",
|
||||
title: "Best Practices",
|
||||
description: "Learn recommended patterns for building reliable, secure applications on the XRP Ledger.",
|
||||
tutorials: [
|
||||
{
|
||||
title: "API Usage",
|
||||
body: "Best practices for using XRP Ledger APIs.",
|
||||
path: "/docs/tutorials/best-practices/api-usage/",
|
||||
},
|
||||
{
|
||||
title: "Use Tickets",
|
||||
body: "Use tickets to send transactions out of the normal order.",
|
||||
path: "/docs/tutorials/best-practices/transaction-sending/use-tickets/",
|
||||
},
|
||||
{
|
||||
title: "Send a Single Account Batch Transaction",
|
||||
body: "Group multiple transactions together and execute them as a single atomic operation.",
|
||||
path: "/docs/tutorials/best-practices/transaction-sending/send-a-single-account-batch-transaction/",
|
||||
},
|
||||
{
|
||||
title: "Assign a Regular Key Pair",
|
||||
body: "Assign a regular key pair for signing transactions.",
|
||||
path: "/docs/tutorials/best-practices/key-management/assign-a-regular-key-pair/",
|
||||
},
|
||||
{
|
||||
title: "Set Up Multi-Signing",
|
||||
body: "Configure multi-signing for enhanced security.",
|
||||
path: "/docs/tutorials/best-practices/key-management/set-up-multi-signing/",
|
||||
},
|
||||
{
|
||||
title: "Send a Multi-Signed Transaction",
|
||||
body: "Send a transaction with multiple signatures.",
|
||||
path: "/docs/tutorials/best-practices/key-management/send-a-multi-signed-transaction/",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "sample-apps",
|
||||
title: "Sample Apps",
|
||||
description: "Build complete, end-to-end applications like wallets and credential services.",
|
||||
tutorials: [
|
||||
{
|
||||
title: "Build a Browser Wallet in JavaScript",
|
||||
body: "Build a browser wallet for the XRP Ledger using JavaScript and various libraries.",
|
||||
path: "/docs/tutorials/sample-apps/build-a-browser-wallet-in-javascript/",
|
||||
icon: "javascript",
|
||||
},
|
||||
{
|
||||
title: "Build a Desktop Wallet in JavaScript",
|
||||
body: "Build a desktop wallet for the XRP Ledger using JavaScript, the Electron Framework, and various libraries.",
|
||||
path: "/docs/tutorials/sample-apps/build-a-desktop-wallet-in-javascript/",
|
||||
icon: "javascript",
|
||||
},
|
||||
{
|
||||
title: "Build a Desktop Wallet in Python",
|
||||
body: "Build a desktop wallet for the XRP Ledger using Python and various libraries.",
|
||||
path: "/docs/tutorials/sample-apps/build-a-desktop-wallet-in-python/",
|
||||
icon: "python",
|
||||
},
|
||||
{
|
||||
title: "Credential Issuing Service in JavaScript",
|
||||
body: "Build a credential issuing service using the JavaScript SDK.",
|
||||
path: "/docs/tutorials/sample-apps/credential-issuing-service-in-javascript/",
|
||||
icon: "javascript",
|
||||
},
|
||||
{
|
||||
title: "Credential Issuing Service in Python",
|
||||
body: "Build a credential issuing service using the Python SDK.",
|
||||
path: "/docs/tutorials/sample-apps/credential-issuing-service-in-python/",
|
||||
icon: "python",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
function TutorialCard({
|
||||
tutorial,
|
||||
detectedLanguages,
|
||||
showFooter = false,
|
||||
translate,
|
||||
}: {
|
||||
tutorial: Tutorial;
|
||||
detectedLanguages?: string[];
|
||||
showFooter?: boolean;
|
||||
translate: (text: string) => string;
|
||||
}) {
|
||||
// Get icons: auto-detected languages take priority, then manual icon, then XRPL fallback
|
||||
const icons = detectedLanguages && detectedLanguages.length > 0
|
||||
? detectedLanguages.map((lang) => langIcons[lang]).filter(Boolean)
|
||||
: tutorial.icon && langIcons[tutorial.icon]
|
||||
? [langIcons[tutorial.icon]]
|
||||
: [langIcons.xrpl];
|
||||
|
||||
return (
|
||||
<a href={tutorial.path} className="card">
|
||||
<div className="card-header d-flex align-items-center flex-wrap">
|
||||
{icons.map((icon, idx) => (
|
||||
<span className="circled-logo" key={idx}>
|
||||
<img src={icon.src} alt={icon.alt} />
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<div className="card-body">
|
||||
<h4 className="card-title h5">{translate(tutorial.title)}</h4>
|
||||
{tutorial.body && <p className="card-text">{translate(tutorial.body)}</p>}
|
||||
</div>
|
||||
{showFooter && <div className="card-footer"></div>}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
export default function TutorialsIndex() {
|
||||
const { useTranslate, usePageSharedData } = useThemeHooks();
|
||||
const { translate } = useTranslate();
|
||||
|
||||
// Get auto-detected languages from the plugin (maps tutorial paths to language arrays).
|
||||
const tutorialLanguages = usePageSharedData<TutorialLanguagesMap>("tutorial-languages") || {};
|
||||
|
||||
return (
|
||||
<main className="landing page-tutorials landing-builtin-bg">
|
||||
<section className="container-new py-26">
|
||||
<div className="col-lg-8 mx-auto text-lg-center">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h1 className="mb-0">
|
||||
{translate("Crypto Wallet and Blockchain Development Tutorials")}
|
||||
</h1>
|
||||
<h6 className="eyebrow mb-3">{translate("Tutorials")}</h6>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Get Started */}
|
||||
<section className="container-new pt-10 pb-20">
|
||||
<div className="col-12 col-xl-8 p-0">
|
||||
<h3 className="h4 mb-3">{translate("Get Started with SDKs")}</h3>
|
||||
<p className="mb-4">
|
||||
{translate("These tutorials walk you through the basics of building a very simple XRP Ledger-connected application using your favorite programming language.")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="row tutorial-cards">
|
||||
{getStartedTutorials.map((tutorial, idx) => (
|
||||
<div key={idx} className="col-lg-4 col-md-6 mb-5">
|
||||
<TutorialCard tutorial={tutorial} showFooter translate={translate} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Other Tutorials */}
|
||||
{sections.map((section) => (
|
||||
<section className="container-new pt-10 pb-10" key={section.id}>
|
||||
<div className="col-12 col-xl-8 p-0">
|
||||
<h3 className="h4 mb-3">{translate(section.title)}</h3>
|
||||
<p className="mb-4">{translate(section.description)}</p>
|
||||
</div>
|
||||
<div className="row tutorial-cards">
|
||||
{section.tutorials.slice(0, 6).map((tutorial, idx) => (
|
||||
<div key={idx} className="col-lg-4 col-md-6 mb-5">
|
||||
<TutorialCard
|
||||
tutorial={tutorial}
|
||||
detectedLanguages={tutorialLanguages[tutorial.path]}
|
||||
translate={translate}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
))}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -127,7 +127,7 @@ footer:
|
||||
- page: docs/concepts/index.md
|
||||
label: Concepts
|
||||
labelTranslationKey: footer.docs.concepts
|
||||
- page: docs/tutorials/index.md
|
||||
- page: docs/tutorials/index.page.tsx
|
||||
label: Tutorials
|
||||
labelTranslationKey: footer.docs.tutorials
|
||||
- page: docs/references/index.md
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
- page: docs/concepts/decentralized-storage/decentralized-identifiers.md
|
||||
- page: docs/concepts/decentralized-storage/price-oracles.md
|
||||
|
||||
- page: docs/tutorials/index.md
|
||||
- page: docs/tutorials/index.page.tsx
|
||||
label: Tutorials
|
||||
labelTranslationKey: sidebar.docs.tutorials
|
||||
expanded: false
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -320,3 +320,84 @@ main article .card-grid {
|
||||
margin-bottom: 0.25rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
/* Tutorial cards */
|
||||
.page-tutorials .tutorial-cards {
|
||||
> div {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
min-height: 280px;
|
||||
transition: all 0.35s ease-out;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-16px);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
border-bottom: none;
|
||||
background: transparent;
|
||||
padding: 1.5rem 1.5rem 0 2rem;
|
||||
}
|
||||
|
||||
.circled-logo {
|
||||
margin-left: -10px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 1rem 1.5rem;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.card-text {
|
||||
font-size: 1rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
background-color: transparent;
|
||||
border-top: none;
|
||||
padding: 0;
|
||||
height: 40px;
|
||||
background-size: cover;
|
||||
background-position: bottom;
|
||||
background-repeat: no-repeat;
|
||||
margin-top: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply colored footers to each card
|
||||
> div:nth-child(1) .card .card-footer {
|
||||
background-image: url("../img/cards/3-col-pink.svg");
|
||||
}
|
||||
> div:nth-child(2) .card .card-footer {
|
||||
background-image: url("../img/cards/3col-blue-light-blue.svg");
|
||||
}
|
||||
> div:nth-child(3) .card .card-footer {
|
||||
background-image: url("../img/cards/3-col-light-blue.svg");
|
||||
}
|
||||
> div:nth-child(4) .card .card-footer {
|
||||
background-image: url("../img/cards/3col-blue-green.svg");
|
||||
}
|
||||
> div:nth-child(5) .card .card-footer {
|
||||
background-image: url("../img/cards/3col-magenta.svg");
|
||||
}
|
||||
> div:nth-child(6) .card .card-footer {
|
||||
background-image: url("../img/cards/3-col-orange.svg");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -424,7 +424,7 @@ aside .card {
|
||||
.circled-logo {
|
||||
background-color: $gray-200;
|
||||
|
||||
img[src="assets/img/logos/globe.svg"] {
|
||||
img[src="/img/logos/globe.svg"] {
|
||||
filter: invert(100%);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
- page: ./docs/concepts/index.md
|
||||
label: Concepts
|
||||
labelTranslationKey: topnav.docs.concepts
|
||||
- page: ./docs/tutorials/index.md
|
||||
- page: ./docs/tutorials/index.page.tsx
|
||||
label: Tutorials
|
||||
labelTranslationKey: topnav.docs.tutorials
|
||||
- page: ./docs/references/index.md
|
||||
|
||||
Reference in New Issue
Block a user