网络支持快速入门¶
构建文档数据¶
为了在您的应用程序中使用网络支持包,您需要构建它使用的数据。这些数据包括表示文档的 pickle 文件、搜索索引以及用于跟踪评论和其他内容在文档中的位置的节点数据。为此,您需要创建一个 WebSupport
类的实例,并调用其 build()
方法
from sphinxcontrib.websupport import WebSupport
support = WebSupport(srcdir='/path/to/rst/sources/',
builddir='/path/to/build/outdir',
search='xapian')
support.build()
这将从 srcdir
读取 reStructuredText 源文件,并将必要的数据放置到 builddir
中。 builddir
将包含两个子目录:一个名为“data”的目录,其中包含显示文档、搜索文档和向文档添加评论所需的所有数据。另一个目录将名为“static”,其中包含应从“/static”提供服务的静态文件。
注意
如果您希望从“/static”以外的路径提供静态文件,则可以在创建 WebSupport
对象时提供 staticdir 关键字参数。
将 Sphinx 文档集成到您的 Web 应用程序中¶
现在数据已经构建好了,是时候用它做一些有用的事情了。从为您的应用程序创建一个 WebSupport
对象开始
from sphinxcontrib.websupport import WebSupport
support = WebSupport(datadir='/path/to/the/data',
search='xapian')
您只需要为每个要处理的文档集创建一个这样的对象。然后,您可以调用其 get_document()
方法来访问单个文档
contents = support.get_document('contents')
这将返回一个包含以下项目的字典
body: 文档主体的 HTML 代码
sidebar: 文档侧边栏的 HTML 代码
relbar: 包含指向相关文档链接的 div
title: 文档标题
css: Sphinx 使用的 CSS 文件的链接
script: 包含评论选项的 JavaScript 代码
然后,该字典可以用作模板的上下文。目标是易于与您现有的模板系统集成。使用 Jinja2 的示例如下:
{%- extends "layout.html" %}
{%- block title %}
{{ document.title }}
{%- endblock %}
{% block css %}
{{ super() }}
{{ document.css|safe }}
<link rel="stylesheet" href="/static/websupport-custom.css" type="text/css">
{% endblock %}
{%- block script %}
{{ super() }}
{{ document.script|safe }}
{%- endblock %}
{%- block relbar %}
{{ document.relbar|safe }}
{%- endblock %}
{%- block body %}
{{ document.body|safe }}
{%- endblock %}
{%- block sidebar %}
{{ document.sidebar|safe }}
{%- endblock %}
身份验证¶
要使用投票等某些功能,必须能够对用户进行身份验证。身份验证的详细信息留给您的应用程序。用户经过身份验证后,您可以使用 username 和 moderator 关键字参数将用户的详细信息传递给某些 WebSupport
方法。网络支持包将用户名与评论和投票一起存储。唯一的注意事项是,如果您允许用户更改用户名,则必须更新网络支持包的数据
support.update_username(old_username, new_username)
username 应为一个唯一的字符串,用于标识用户,moderator 应为一个布尔值,表示用户是否具有审核权限。moderator 的默认值为 False
。
使用 Flask 检查用户是否已登录,然后检索文档的示例函数如下:
from sphinxcontrib.websupport.errors import *
@app.route('/<path:docname>')
def doc(docname):
username = g.user.name if g.user else ''
moderator = g.user.moderator if g.user else False
try:
document = support.get_document(docname, username, moderator)
except DocumentNotFoundError:
abort(404)
return render_template('doc.html', document=document)
首先要注意的是,docname 只是请求路径。这使得从单个视图轻松访问正确的文档变得容易。如果用户已通过身份验证,则用户名和审核状态将与 docname 一起传递给 get_document()
。网络支持包随后会将此数据添加到用于模板中的 COMMENT_OPTIONS
中。
注意
这仅在您的文档从您的文档根目录提供服务时有效。如果它从另一个目录提供服务,则您需要用该目录作为前缀添加 URL 路由,并在创建网络支持对象时提供 docroot 关键字参数
support = WebSupport(..., docroot='docs')
@app.route('/docs/<path:docname>')
执行搜索¶
要使用 Sphinx 侧边栏中内置的搜索表单,请创建一个函数来处理对相对于文档根目录的 URL“search”的请求。用户的搜索查询将位于 GET 参数中,键为 q
。然后使用 get_search_results()
方法来检索搜索结果。在 Flask 中,这类似于以下代码:
@app.route('/search')
def search():
q = request.args.get('q')
document = support.get_search_results(q)
return render_template('doc.html', document=document)
请注意,我们使用与渲染文档相同的模板来渲染搜索结果。这是因为 get_search_results()
以与 get_document()
相同的格式返回上下文字典。
评论审核¶
默认情况下,通过 add_comment()
添加的所有评论都会自动显示。如果您希望进行某种形式的审核,则可以传递 displayed
关键字参数
comment = support.add_comment(text, node_id='node_id',
parent_id='parent_id',
username=username, proposal=proposal,
displayed=False)
然后,您可以创建一个新视图来处理评论审核。当审核员决定接受并显示评论时,将调用该视图
@app.route('/docs/accept_comment', methods=['POST'])
def accept_comment():
moderator = g.user.moderator if g.user else False
comment_id = request.form.get('id')
support.accept_comment(comment_id, moderator=moderator)
return 'OK'
拒绝评论通过删除评论来完成。
要在新评论被添加但未显示时执行自定义操作(例如向审核员发送电子邮件),您可以在实例化支持对象时将可调用对象传递给 WebSupport
类
def moderation_callback(comment):
"""Do something..."""
support = WebSupport(..., moderation_callback=moderation_callback)
审核回调必须接受一个参数,该参数将与 WebSupport.add_comment()
返回的相同评论字典相同。
评论 & 建议¶
现在这些都已完成,是时候定义处理来自脚本的 AJAX 调用的函数了。您将需要三个函数。第一个函数用于添加新评论,并将调用网络支持方法
add_comment()
您会注意到,请求中同时发送了
parent_id
和node_id
。如果评论直接附加到节点,则parent_id
将为空。如果评论是另一条评论的子评论,则node_id
将为空。然后,下一个函数处理特定节点的评论检索,并被恰如其分地命名为get_data()
最后需要一个函数,该函数将调用
process_vote()
,并处理用户对评论的投票