
Pelican 多语言博客实践从another_super_article-fr.rst解析 reST 翻译文章的元数据与语言路由【免费下载链接】pelicanStatic site generator that supports Markdown and reST syntax. Powered by Python.项目地址: https://gitcode.com/gh_mirrors/pe/pelican导读Pelican 是一个基于 Python 的静态站点生成器原生支持 Markdown 与 reStructuredTextreST两种写作格式并内置了多语言翻译内容机制。本文以仓库samples/content/another_super_article-fr.rst这一法语示例文章为切入点完整讲解 reST 文章的文档结构与元数据语法、lang/slug等字段如何驱动翻译匹配以及 Pelican 如何借助DEFAULT_LANG、ARTICLE_LANG_URL、TRANSLATION_FEED_ATOM等配置把同一篇内容路由到不同语言的 URL 与 Feed。读完本文你将掌握在 Pelican 项目中书写多语言文章、配置语言化 URL 与订阅源、并在模板中渲染翻译链接的完整方案。一、示例文件全景一篇法语文章长什么样仓库 samples/content/another_super_article-fr.rst 是一个极简但信息完整的 reST 文章全文如下Trop bien ! ########### :date: 2010-10-20 10:14 :lang: fr :slug: oh-yeah Et voila du contenu en français与其对应的英文版本 samples/content/another_super_article.rst 位于同一目录Oh yeah ! ######### :tags: oh, bar, yeah :date: 2010-10-20 10:14 :category: bar :author: Alexis Métaireau :lang: en :slug: oh-yeah :license: WTFPL Why not ? After all, why not ? Its pretty simple to do it, and it will allow me to write my blogposts in rst ! YEAH !两篇文章有两个关键共性:lang:分别声明为fr与en:slug:均为oh-yeah。正是「相同 slug 不同 lang」的组合让 Pelican 将二者识别为同一篇文章的两种语言版本。在默认配置下pelican/settings.py 中ARTICLE_TRANSLATION_ID slugslug 是翻译内容关联的唯一主键。二、reST 文章结构与元数据语法详解2.1 标题与章节reST 文章以「标题文本 下划线装饰符」开头装饰符字符只要连续且长度不低于标题文本即可。本例使用#Trop bien ! ###########需要注意docutils 要求文档有且仅有一个顶层章节标题。Pelican 的 reST 读取器在 pelican/readers.py 中会检查这一条件if document.first_child_matching_class(docutils.nodes.title) is None: logger.warning( Document title missing in file %s: Ensure exactly one top level section, source_path, )如果缺少标题或出现多个顶层章节构建时会收到警告因此请保证每个 reST 文件只有一个一级标题。2.2 元数据字段Docinfo标题之后、正文之前的:字段名: 值行是 reST 的文档元数据docinfoPelican 会将其解析为文章属性。another_super_article-fr.rst使用了三个核心字段英文版本则演示了更完整的字段集合。常用字段及语义如下表元数据字段示例值作用:date:2010-10-20 10:14文章日期决定归档位置与排序:lang:fr/en文章语言代码多语言匹配的核心:slug:oh-yeahURL 标识符翻译关联主键:tags:oh, bar, yeah逗号分隔的标签列表:category:bar文章分类:author:Alexis Métaireau作者名:license:WTFPL自定义元数据可被模板读取从源码看reST 元数据解析在 pelican/readers.py 的RstReader._parse_metadata中完成docutils 解析 docinfo 节点后字段值经由process_metadata处理支持METADATA_PROCESSORS注册的自定义处理器FORMATTED_FIELDS中的字段则被当作 reST 片段渲染。这意味着元数据字段不仅限于内置项任何自定义字段都会进入文章对象供模板调用。2.3 正文与扩展语法元数据块之后就是正文。reST 支持段落、标题、列表、代码块、图片等丰富语法英文示例中的.. image:: |static|/pictures/Sushi.jpg :height: 450 px :width: 600 px :alt: alternate text展示了 reST 的图片指令directive其中|static|是 Pelican 提供的替换引用指向STATIC_PATHS中配置的静态文件根目录。此类指令由pelican/rstdirectives.py注册因此在正文中可以直接使用。三、语言如何路由lang与DEFAULT_LANG3.1 默认语言Pelican 通过配置项DEFAULT_LANG决定站点的默认语言其默认值为en见 pelican/settings.py。在 pelican/contents.py 中每个内容对象构建时会执行self.in_default_lang True if DEFAULT_LANG in settings: default_lang settings[DEFAULT_LANG].lower() if not hasattr(self, lang): self.lang default_lang self.in_default_lang self.lang default_lang也就是说文章未声明:lang:时语言继承DEFAULT_LANG声明了:lang: fr且默认语言为en时in_default_lang为False该文章被识别为「翻译文章」。3.2 翻译关联process_translations构建阶段文章生成器在 pelican/generators.py 调用工具函数process_translations定义于 pelican/utils.py以ARTICLE_TRANSLATION_ID默认slug为关联键把主语言文章与翻译文章分组origs, translations process_translations( arts, translation_idself.settings[ARTICLE_TRANSLATION_ID] )同 slug 的en与fr文章会被归并为一组默认语言版本进入articles其他语言版本进入translations并通过Content.translations属性互相引用pelican/contents.py。another_super_article-fr.rst正是因此被附加到英文文章的翻译列表中。3.3 语言化的 URL 生成Pelican 为翻译文章准备了独立的 URL 规则pelican/settings.pyARTICLE_URL: {slug}.html, ARTICLE_LANG_URL: {slug}-{lang}.html, ARTICLE_SAVE_AS: {slug}.html, ARTICLE_LANG_SAVE_AS: {slug}-{lang}.html,内容对象在 pelican/contents.py 中按in_default_lang选择键名def get_url_setting(self, key: str) - str: if hasattr(self, override_ key): return getattr(self, override_ key) key key if self.in_default_lang else flang_{key} return self._expand_settings(key)因此英文版oh-yeah生成oh-yeah.html法语版生成oh-yeah-fr.html——这正是仓库测试输出目录中出现 oh-yeah-fr.html 的原因。你可以用ARTICLE_LANG_URL/ARTICLE_LANG_SAVE_AS完全自定义翻译文章的路由例如ARTICLE_LANG_URL posts/{date:%Y}/{date:%B}/{date:%d}/{slug}/{lang}/ ARTICLE_LANG_SAVE_AS ARTICLE_LANG_URL index.html若同时配置了DEFAULT_LANG站点默认语言与ARTICLE_URL可在 pelican/settings.py 看到自动改写逻辑当ARTICLE_URL含{lang}占位符时Pelican 会为默认语言与非默认语言分别生成 URL 规则。四、完整的多语言配置示例仓库 samples/pelican.conf_FR.py 是配套的配置样例展示了法语站点的完整设置其中与多语言直接相关的部分AUTHOR Alexis Métaireau SITENAME Alexis log SITEURL http://blog.notmyidea.org TIMEZONE Europe/Paris RELATIVE_URLS True LOCALE fr_FR.UTF-8 DEFAULT_DATE_FORMAT %d %B %Y ARTICLE_URL posts/{date:%Y}/{date:%B}/{date:%d}/{slug}/ ARTICLE_SAVE_AS ARTICLE_URL index.html FEED_ALL_RSS feeds/all.rss.xml CATEGORY_FEED_RSS feeds/{slug}.rss.xml STATIC_PATHS [pictures, extra/robots.txt] EXTRA_PATH_METADATA {extra/robots.txt: {path: robots.txt}} TEMPLATE_PAGES {pages/jinja2_template.html: jinja2_template.html} DEFAULT_METADATA {yeah: it is}值得注意的几点LOCALE fr_FR.UTF-8用于本地化日期格式与语言环境DEFAULT_DATE_FORMAT %d %B %Y会输出「20 octobre 2010」这类法语日期DEFAULT_METADATA为所有内容注入默认元数据所有配置键必须大写——该文件末尾的注释明确指出foobar barbaz不会被使用因为「All configuration keys have to be in caps」。4.1 日期格式按语言切换如果站点同时发布多语言内容可以在 pelican/contents.py 的逻辑基础上配置按语言区分的日期格式DATE_FORMATS { en: %a, %d %b %Y, fr: %d %B %Y, }内容构建时若文章的lang命中DATE_FORMATS键就使用对应的格式否则回退到DEFAULT_DATE_FORMAT。4.2 翻译文章专属订阅源多语言站点还可以为每种语言生成独立的 Feed由TRANSLATION_FEED_ATOM与TRANSLATION_FEED_RSS控制pelican/settings.pyTRANSLATION_FEED_ATOM feeds/all-{lang}.atom.xml TRANSLATION_FEED_RSS feeds/all-{lang}.rss.xml生成器在 pelican/generators.py 中按article.lang对全部文章含翻译分组再为每个语言写出独立的 Feed 文件translations_feeds defaultdict(list) for article in chain(self.articles, self.translations): translations_feeds[article.lang].append(article)因此配置后会得到feeds/all-en.atom.xml、feeds/all-fr.atom.xml等文件——仓库测试输出目录 pelican/tests/output/custom/feeds 中all-en.atom.xml与all-fr.atom.xml并存正是这一机制的实证。此外 settings 中的configure_settings会把这些 Feed 键里的%s统一替换为{slug}或{lang}占位符并处理新旧键名的兼容告警pelican/settings.py。五、模板中渲染翻译链接多语言内容除了影响 URL 与 Feed也会直接暴露给模板引擎。每个内容对象的translations属性是一个列表因此可以在模板中遍历{% if article.translations %} div classtranslations {% for translation in article.translations %} a href{{ SITEURL }}/{{ translation.url }} hreflang{{ translation.lang }}{{ translation.lang }}/a {% endfor %} /div {% endif %}仓库内置主题 pelican/themes/notmyidea/templates/translations.html 与 pelican/themes/simple/templates/translations.html 都实现了这类「语言切换」区块可直接在base.html或文章页中{% include translations.html %}。这样访问法语文章oh-yeah-fr.html的读者就能看到返回英文版oh-yeah.html的链接。六、验证测试输出中的语言化产物仓库的测试输出目录从构建结果层面验证了多语言机制pelican/tests/output/basic/oh-yeah.html默认语言en文章输出pelican/tests/output/basic/oh-yeah-fr.html法语翻译文章输出pelican/tests/output/custom/feeds/all-en.atom.xml 与 pelican/tests/output/custom/feeds/all-fr.atom.xml按语言分流的订阅源。此外pelican/tests/output/custom_locale/posts/2010/octobre/15/oh-yeah/index.html 展示了在pelican.conf_FR.py式配置下法语文章按「年份/月份法语/日期/slug」嵌套目录输出的实际结构——这正是ARTICLE_URL posts/{date:%Y}/{date:%B}/{date:%d}/{slug}/结合法语 locale 的直接产物。对比 pelican/tests/output/custom_locale/posts/2011/février/17/article-1/index.html 可见同一规则对普通文章同样生效。七、注意事项与最佳实践slug 必须一致翻译文章与主文章必须声明相同的:slug:否则process_translations无法建立关联法语文章会被当作独立内容输出。默认语言唯一DEFAULT_LANG对应的语言版本被视为「主文章」进入常规列表与分类、标签聚合翻译版本默认只生成自己的 URL 与翻译 Feed见 pelican/generators.py 中「only main articles are listed in categories and tags」的注释。reST 标题唯一每个 reST 文件只保留一个顶层标题避免 docutils 解析警告。键名大写Pelican 配置键一律大写否则会被静默忽略。自定义字段可在元数据中自由添加:xxx:字段它会以同名属性进入文章对象供模板使用。结语通过another_super_article-fr.rst与another_super_article.rst这对示例可以看到 Pelican 的多语言支持贯穿了元数据解析lang/slug、内容关联process_translations、URL 路由ARTICLE_LANG_URL与 Feed 生成TRANSLATION_FEED_*全链路。只需要保持 slug 一致、正确声明:lang:并配合pelican.conf_FR.py式的语言化配置即可构建结构清晰、按语言分流的国际化静态博客。相关实现均可直接在 pelican/readers.py、pelican/contents.py、pelican/generators.py 与 pelican/settings.py 中继续深入阅读。【免费下载链接】pelicanStatic site generator that supports Markdown and reST syntax. Powered by Python.项目地址: https://gitcode.com/gh_mirrors/pe/pelican创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考