大家可以看到,我的这个网站是中英双语的。我想简单介绍一下这里面的考虑,以及我是怎么实现的。
1 为什么做双语
我大概在 2021 年开启了我的博客,维护过一个中文网站,放一些我的科研、学习笔记。到了 2023 年去英国联培之后,我认识了很多当地以英语为母语的朋友和同事,于是又开了一个新的英文网站,也就是现在这个站点的起点。
现在联培已经结束,我回到国内,平时向别人介绍网站的时候,会发现不少人读英文并不方便,所以我开始认真考虑把网站切换回中文可读这件事。我也必须承认,中文是我的母语,我用中文写作更自然,也更有表达力,在除科研外一些不熟悉的领域我也难免会有一些语言障碍,所以使用中文会让我更高效地维护这个网站,写出更好的内容。
但另一方面,我也不想完全放弃英文,原因有几点:
- 一是过去已经积累了不少英文内容,如果全部丢掉很可惜;
- 二是我写的很多内容,尤其是科研和技术相关的,本来就是在英文语境里形成的。很多概念、表达方式,甚至推理路径,本身就更接近英文。对这部分内容来说,英文是更自然的表达方式;
- 三是英文内容更国际化,能让全世界更多人看到。
经过一番思考,我觉得与其在“中文网站”或者“英文网站”之间二选一,不如直接做成一个真正的双语网站。
2 我理解的双语是什么
这里的双语,不是指把一篇文章机械地翻译成另一种语言。
无论是手动翻译还是机器翻译,我都不太想这样做。因为如果只是逐句对应,意义并不大:读者直接用浏览器翻译,其实就已经能达到类似效果了。
我更希望中文和英文是两套各自成立的表达。它们讨论的是同一个主题,但面向不同的读者,也服务于不同的阅读习惯。所以两种语言的内容并不一定完全一致,篇幅、举例、语气,甚至组织方式,都可能会不一样。
换句话说,中文和英文不是互相拷贝的关系,而是同一个主题的两个版本。
当然,受时间限制,并不是每一篇内容都会同时有中英文两个版本。有些文章目前只有中文,有些则只有英文。这也是双语维护中一个很现实的问题。
3 技术上是怎么做的
现在这个网站是基于 Quarto 搭建的,内容都存放在一个个 qmd 文件里,本质上还是 markdown。更准确地说,Quarto 是一个面向内容发布的工具,可以用来生成静态网站、文档和博客。它的好处是,一方面写作和组织内容很方便,另一方面也允许插入原生的 HTML、CSS 和 JavaScript,所以在需要的时候,我仍然可以自由加入各种自定义功能。
大家浏览一下我的网站,可以发现有很多自定义的功能(比如右上角的音乐播放器),这些前端实现都不是我手写的。我本身并不懂前端开发,都是通过 vibe coding 的方式,把想要的效果、需求和逻辑描述清楚,再让 AI 帮我把它实现出来。
我目前用的是 CodeX,要实现我想要的双语功能,只需要把以下逻辑告诉它,它就会写好相应的代码。
每篇内容都要有中英文两个“分身”
既然我希望中文和英文不是简单翻译,而是可以各自独立修改,那么在内容层面,我就需要明确地区分一篇文章的两个语言版本。
我的做法不是为每个内容都创建两个独立的 qmd 文件,因为这样写作时不方便逐段对应参考,而是:
- metadata 层面:每个需要区分语言的字段,都拆成两个版本,例如 _en 和 _zh。
- 正文层面:在每一段分别用类似
:::en和:::zh的块包裹内容,它们本质上就是不同语言对应的 div 标签。
这样一来,同一个 qmd 文件里可以同时放中文和英文内容,两边离得近可以互相参照,便于写作,但渲染时明确分开。
语言切换按钮
网站右上角有一个中英文切换按钮,用来在两种语言之间切换。在URL中,我也会把当前语言作为一个参数(比如 ?lang=en),这样用户在切换语言后,URL 也会跟着变,方便用户分享链接时指定语言。
这个按钮的作用不只是替换几段正文,而是驱动整篇页面进入对应的语言状态,让页面上所有和语言相关的部分都一起变化。
没有对应语言时,给出提示
因为不是所有文章都有完整双语版本,所以还需要处理“缺失另一种语言”的情况。
如果某篇内容目前只有中文,或者只有英文,那么切换到另一种语言时,页面会给出提示,而不是直接显示空白或者报错。这样读者至少能知道:不是页面坏了,而是这篇内容目前还没有对应版本。
如何判断“没有对应语言”?我会在 metadata 里设置一个字段,来标明当前已经写好的语言版本。切换时根据这个字段来决定是显示内容还是显示提示。
默认语言
用一个字段来标明默认语言是什么,这样用户第一次访问网站时(不带 ?lang 参数),就会自动进入默认语言的版本。同时,我在写作时可以忽略这些分身,直接用默认语言按照正常的方式写作(metadata 不加 _en 或 _zh 后缀,不用 :::en 和 :::zh 的块包裹)。
更彻底的语言切换
Quarto 本身有一个 lang 字段,用来标明当前页面的语言环境。这个字段会影响浏览器、搜索引擎,以及页面中一些依赖语言设置的显示逻辑。我让这个字段产生的作用跟随当前切换的语言自动更新,并且不再手动设置该字段。这样浏览器、搜索引擎,以及页面中一些依赖语言设置的显示逻辑,都能更准确地工作,也能让整套双语切换更完整,而不只是“看起来像切换了”。