Web Suporte Início Rápido¶
Building documentation data¶
Para fazer uso, do pacote de suporte a web, em sua aplicação é necessário construir os dados que o pacote utiliza. Esses dados incluem arquivos tipo pickle representando os documentos, índices de busca e dados que serão usados para comentários e outras finalidades dentro do documento. Para isso é necessário criar uma instância da WebSupport
e chamar o método build()
:
from sphinxcontrib.websupport import WebSupport
support = WebSupport(srcdir='/path/to/rst/sources/',
builddir='/path/to/build/outdir',
search='xapian')
support.build()
Isto irá ler as fontes reStructuredText de srcdir
e colocar os dados necessários em builddir
. O builddir
conterá dois subdiretórios: um denominado “data” que contém todos os dados necessários para exibir documentos, pesquisar documentos e adicionar comentários a documentos. O outro diretório será chamado de “estático” e contém arquivos estáticos que devem ser atendidos a partir de “/static”.
Nota
Se desejar servir arquivos estáticos a partir de outro caminho que não “/static”, deverá ser providenciado o argumento staticdir quando criada a WebSupport
do objeto.
Integrating Sphinx documents into your web-app¶
Agora que os dados foram construídos, é hora de fazer algo útil com eles. Inicie criando a WebSupport
do objeto para sua aplicação:
from sphinxcontrib.websupport import WebSupport
support = WebSupport(datadir='/path/to/the/data',
search='xapian')
Só será necessário um desses conjuntos de documentação no qual está trabalhando. Pode ser chamado o método get_document()
para acessar individualmente os documentos:
contents = support.get_document('contents')
Isso irá retornar um dicionário contendo os seguintes itens:
body: O corpo principal do documento como HTML
sidebar: A barra lateral do documento como HTML
relbal: Div contendo links para documentos relacionados
title: O título do documento
css: Links para arquivos CSS usados pelo Sphinx
script: JavaScript contendo opções de comentários
Esse dicionário dict, pode então ser usado como contexto para modelos. O objetivo é facilitar a integração com seu sistema de modelos. Um exemplo usando 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 %}
Autenticação¶
Para cirar certas funcionalidades como enquete, deve ser possível autenticar usuários. Os detalhes da autenticação são deixados para sua aplicação. Quando um usuário for autenticado, podemos passar a usar certos detalhes de classes WebSupport
e métodos usando argumentos username e moderador . O suporte ao pacote web irá armazenar nome do usuário com os comentários e votos. O cuidado é para que quando o nome do usuário for atualizado, sua aplicação deverá atualizar os dados de websuporte.
support.update_username(old_username, new_username)
username deve ser string única que identifica o usuário, e moderator deve ser um booleano representando onde o usuário tem privilégio de moderação. O valor padrão para moderator é False
.
Um exemplo é a função Flask que verifica se o usuário está logado e então recupera documentos:
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)
O primeiro detalhe a notar é que docname é o caminho da requisição. Isso torna fácil acessar o caminho correto do documento em uma simples visão. Se o usuário está autenticado, então o nome do usuário e situação de moderação são passadas junto com o método get_document()
. O pacote suporte a web irá adicionar dados em COMMENT_OPTIONS
os quais serão usados como modelo.
Nota
Isso só funciona se sua documentação é servida a partir do diretório raiz. Se for servida de outro diretório, deve ser informado o prefixo complementar da url até esse diretório no argumento nomeado docroot quando criado o objeto de suporte web:
support = WebSupport(..., docroot='docs')
@app.route('/docs/<path:docname>')
Performing searches¶
Para usar o formulário de pesquisa embutida à barra lateral do Sphinx, crie uma função para manipular solicitações para a URL ‘search’ em relação à raiz da documentação. A consulta de pesquisa do usuário estará nos parâmetros GET, com a chave q
. Em seguida, use o método get_search_results()
para recuperar os resultados da pesquisa. Em Flask seria assim:
@app.route('/search')
def search():
q = request.args.get('q')
document = support.get_search_results(q)
return render_template('doc.html', document=document)
Note que usamos o mesmo modelo para renderizar os resultados da pesquisa, como fizemos com nossos documentos. Isto é porque o método get_search_results()
retorna o mesmo formato que o método get_document()
utiliza.
Comment moderation¶
Por padrão, todos os comentários adicionados através do add_comment()
são exibidos automaticamente. Se você deseja ter alguma forma de moderação, você pode passar o argumento de palavra-chave displayed
:
comment = support.add_comment(text, node_id='node_id',
parent_id='parent_id',
username=username, proposal=proposal,
displayed=False)
Pode ser criada uma nova visão para manusear moderação de comentários. Será ativada quando o moderador decidir que um comentário deva ser aceito e exibido:
@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'
Rejeitar comentários ocorre através de apagar comentário.
Para executar ação configurada (como email para moderador) quando um novo comentário for adicionado, mas ainda não estar exibido, pode ser chamada a classe WebSupport
quando instanciado o suporte do objeto:
def moderation_callback(comment):
"""Do something..."""
support = WebSupport(..., moderation_callback=moderation_callback)
A chamada de retorno da moderação deve ter um argumento que deve ser o mesmo dict comentado que é retornado por WebSupport.add_comment()
.
Comments & proposals¶
Agora que isto está feito, podemos definir as funções para manusear chamadas AJAX a partir do script. Precisaremos de três funções. A primeira função é usada para adicionar novo comentário e irá chamar o método de suporte da web
add_comment()
:Você notará que tanto um
parent_id
quanto umnode_id
são enviados com a solicitação. Se o comentário estiver sendo anexado diretamente a um nó,parent_id
estará vazia. Se o comentário for filho de outro comentário, entãonode_id
estará vazia. Em seguida, a próxima função manipula a recuperação de comentários para um nó específico e é apropriadamente denominadaget_data()
:A função final irá chamar o método
process_vote()
e ira manusear os votos do usuário nos comentários: