我们最近为 PlanetScale 发布了一个全新且改进的入门引导流程。我们新入门引导的目标是帮助开发者快速连接并查询他们的 PlanetScale 数据库。
连接方式因应用程序使用的语言和框架而异。每个框架都有细微的差异,因此对我们来说,无论你的应用程序使用什么语言/框架,都能为你提供一条单一路径来完成连接,这一点非常重要。

构建这个入门引导的关键是 Markdoc。本文将更详细地介绍我们如何使用 Markdoc 构建产品入门引导。
Markdoc 由 Stripe 创建,是一种基于 Markdown 的语法,用于创建自定义文档站点。
我们在 PlanetScale 能够如此快速交付的原因之一,是我们优先使用易于上手的工具,让公司中的任何人都能做出贡献。因此,使用 Markdown 和 GitHub 来构建我们的产品入门引导对我们来说是一个显而易见的选择。
当我们开始构建时,很快意识到我们希望拥有更具交互性和个性化的内容。静态 Markdown 内容根本无法满足需求。这时我们萌生了探索使用 Markdoc 的想法。
Markdoc 语法是 Markdown 的超集,具体来说是 CommonMark 规范 的超集。这意味着你可以用你所熟悉和喜爱的 Markdown 编写内容,同时还可以扩展它以添加自定义属性、自定义标签,并使用函数和/或变量。
让我们深入了解一些代码。以下片段是用于在入门引导流程中渲染连接教程的部分 Markdown。
```bash
rails credentials:edit --environment production
```
Add the following:
```bash {% file="config/credentials.yml.enc" %}
planetscale:
username: {% $user %}
host: {% $host %}
database: {% $database %}
password: {% $password %}
```
你会注意到,我们在 Markdown 中使用了变量,即 $user、$host、$database 和 $password。目标是让引导流程中的每个路径都针对用户定制,并尽可能易于遵循。提供针对所选框架的、易于复制粘贴的代码是关键。这就是变量变得重要的地方。
变量让你在运行时自定义 Markdoc 文档。我们使用变量将用户凭据直接内联到内容中,而不是使用静态占位符值。
这很像 Laravel 中的 blade 模板和 Ruby on Rails 中的 erb 模板。以下代码片段展示了我们如何设置变量来填充这些 Markdown 字段。
所有凭据在发布前均已失效。为了清晰起见,我们保留了完整、未模糊处理的凭据。
import
React
from
'react'
import
{
parse
,
renderers
,
transform
}
from
'@markdoc/markdoc'
export
default
function
Page
()
{
const
config
=
{
variables
:
{
host
:
'us-east.connect.psdb.cloud'
,
user
:
'mpl0y3jv3a92h4qc4ufn'
,
database
:
'beam'
,
password
:
'pscale_pw_V8db13jnq5mrOWcGFn6GTs6AerDI7A0womsmnJ1qxOc'
,
ssl_ca
:
'/etc/ssl/certs/ca-certificates.crt'
}
}
const
doc
=
`# Configure your application
\n
…`
const
ast
=
parse
(
doc
)
const
content
=
transform
(
ast
,
config
)
const
children
=
renderers
.
react
(
content
,
React
,
{})
return
<
div
>{
children
}
}为了帮助理解引导代码片段所在的文件,我们希望扩展代码块以接受额外的 file 属性。Markdoc 节点使你无需使用任何自定义语法即可自定义文档的渲染方式。
以下示例通过添加一个新的 fence 节点扩展了上一节中的代码片段,该节点在代码片段上方显示文件名。
import
React
from
'react'
import
{
parse
,
renderers
,
transform
}
from
'@markdoc/markdoc'
export
default
function
Page
()
{
const
config
=
{
nodes
:
{
fence
:
Fence
.
scheme
},
variables
:
{
host
:
'us-east.connect.psdb.cloud'
,
user
:
'mpl0y3jv3a92h4qc4ufn'
,
database
:
'beam'
,
password
:
'pscale_pw_V8db13jnq5mrOWcGFn6GTs6AerDI7A0womsmnJ1qxOc'
,
ssl_ca
:
'/etc/ssl/certs/ca-certificates.crt'
}
}
const
doc
=
`# Configure your application
\n
…`
const
ast
=
parse
(
doc
)
const
content
=
transform
(
ast
,
config
)
const
children
=
renderers
.
react
(
content
,
React
,
{
components
:
{
Fence
}
})
return
<
div
>{
children
}
}
function
Fence
({
children
,
file
,
language
})
{
return
(
<
div
><
div
>{
file
}<
pre
><
code
className=
{
`language-
${
language
}
`
}>
children
)
}
Fence
.
scheme
=
{
render
:
Fence
.
name
,
children
:
[
'pre'
,
'code'
],
attributes
:
{
file
:
{
type
:
String
},
language
:
{
type
:
String
}
}
}我们看到用户面临的一个挑战是,在安全连接到 PlanetScale 时决定使用哪个 SSL 证书。为了解决这个问题,我们构建了一个通用组件,它会根据检测到的用户操作系统替换证书。
这也扩展了上一节中的代码片段,添加了检测用户操作系统并为 ssl_ca 变量返回正确字符串的函数。
import
React
from
'react'
import
{
parse
,
renderers
,
transform
}
from
'@markdoc/markdoc'
export
default
function
Page
({
userAgent
})
{
const
platform
=
connectPlatform
(
userAgent
)
const
sslCertificate
=
connectSslCertificate
(
platform
)
const
config
=
{
nodes
:
{
fence
:
Fence
.
scheme
},
variables
:
{
host
:
'us-east.connect.psdb.cloud'
,
user
:
'mpl0y3jv3a92h4qc4ufn'
,
database
:
'beam'
,
password
:
'pscale_pw_V8db13jnq5mrOWcGFn6GTs6AerDI7A0womsmnJ1qxOc'
,
ssl_ca
:
sslCertificate
}
}
const
doc
=
`# Configure your application
\n
…`
const
ast
=
parse
(
doc
)
const
content
=
transform
(
ast
,
config
)
const
children
=
renderers
.
react
(
content
,
React
,
{
components
:
{
Fence
}
})
return
<
div
>{
children
}
}
function
connectPlatform
(
userAgent
)
{
userAgent
=
userAgent
.
toLowerCase
()
switch
(
true
)
{
case
/linux/
.
test
(
userAgent
):
return
'linux'
case
/mac/
.
test
(
userAgent
):
return
'mac'
case
/windows/
.
test
(
userAgent
):
return
'windows'
default
:
return
'ubuntu'
}
}
function
connectSslCertificate
(
platform
)
{
switch
(
platform
)
{
case
'linux'
:
return
'/etc/ssl/certs/ca-certificates.crt'
case
'mac'
:
return
'/etc/ssl/cert.pem'
default
:
return
'/etc/ssl/certs/ca-certificates.crt'
}
}
function
Fence
({
children
,
file
,
language
})
{
return
(
<
pre
><
div
>{
file
}<
code
className=
{
`language-
${
language
}
`
}>
children
)
}
Fence
.
scheme
=
{
// …
}由于用户的开发环境通常与生产环境不同,我们还必须添加一个选择器,允许用户自行选择证书。最终代码如下所示。
import
React
,
{
createContext
,
useState
}
from
'react'
import
{
parse
,
renderers
,
transform
}
from
'@markdoc/markdoc'
const
Platform
=
createContext
({
platform
:
null
,
setPlatform
:
()
=>
{}
})
export
default
function
Page
({
userAgent
})
{
const
initialPlatform
=
connectPlatform
(
userAgent
)
const
[
platform
,
setPlatform
]
=
useState
(
initialPlatform
)
const
sslCertificate
=
connectSslCertificate
(
platform
)
const
config
=
{
nodes
:
{
fence
:
Fence
.
scheme
},
variables
:
{
host
:
'us-east.connect.psdb.cloud'
,
user
:
'mpl0y3jv3a92h4qc4ufn'
,
password
:
'pscale_pw_V8db13jnq5mrOWcGFn6GTs6AerDI7A0womsmnJ1qxOc'
,
ssl_ca
:
sslCertificate
}
}
const
doc
=
`# Configure your application
\n
…`
const
ast
=
parse
(
doc
)
const
content
=
transform
(
ast
,
config
)
const
children
=
renderers
.
react
(
content
,
React
,
{
components
:
{
Fence
}
})
return
(
<
Platform.Provider
value=
{{
platform
,
setPlatform
}}><
div
>{
children
}
)
}
function
connectPlatform
(
userAgent
)
{
// …
}
function
connectSslCertificate
(
platform
)
{
// …
}
function
Fence
({
children
,
file
,
language
})
{
const
{
platform
}
=
useContext
(
Platform
)
const
isDotEnvFile
=
file
===
'.env'
const
isWindowsPlatform
=
platform
===
'windows'
return
(
<
div
><
div
><
div
>{
file
}
{
isDotEnvFile
&&
(
<
select
onChange=
{(
event
)
=>
{
setPlatform
(
event
.
target
.
value
)
}}
value=
{
platform
}
><
option
value=
'linux'
>
Linux
<
option
value=
'mac'
>
macOS
<
option
value=
'windows'
>
Windows
)}
<
pre
><
code
className=
{
`language-
${
language
}
`
}>
children
{
isDotEnvFile
&&
(
<
div
>
{
isWindowsPlatform
&&
(
<>
For Windows you may need to download a root certificate to connect securely.
{
' '
}
<
a
href=
'/docs/vitess/connecting/secure-connections#windows'
>
Learn more
</>
)}
{
!
isWindowsPlatform
&&
(
<>
View the
{
' '
}
<
a
href=
'/docs/vitess/connecting/secure-connections#ca-root-configuration'
>
certificate authority root
{
' '
}
paths for the SSL CA details.
</>
)}
)}
)
}
Fence
.
scheme
=
{
// …
}我们对引导流程的结果非常满意,并且根据一些早期数据,它似乎对新用户来说也是一个巨大的成功。使用 Markdoc 让构建过程变得极其简单直接。我们还发现,维护工作,比如添加新框架,也非常容易管理。
我们很想了解你是否已经有机会接触 Markdoc。如果你想亲身体验我们的引导流程,请务必注册一个 PlanetScale 账户来试试。

转载声明:本文为转载整理,原文版权归原作者及原站点所有。
原文来源:PlanetScale Blog
原创地址:https://planetscale.com/blog/personalizing-your-onboarding-with-markdoc
原文作者:PlanetScale Blog;如有侵权,请联系管理员删除。