summaryrefslogtreecommitdiff
path: root/doc/web
diff options
context:
space:
mode:
authorJacob Mason <jacoblmason@gmail.com>2010-08-09 14:22:31 -0500
committerJacob Mason <jacoblmason@gmail.com>2010-08-09 14:22:31 -0500
commitd9852d47ef41b6aec20b1488c9d6e9718c119c6a (patch)
treef1f0e064ecaf80336652407951f7fc8705af8cf3 /doc/web
parent94f975fd5cf5929bcdb039f4c958da9c1739e1ba (diff)
downloadsphinx-d9852d47ef41b6aec20b1488c9d6e9718c119c6a.tar.gz
updated docs
Diffstat (limited to 'doc/web')
-rw-r--r--doc/web/api.rst43
-rw-r--r--doc/web/frontend.rst6
-rw-r--r--doc/web/quickstart.rst140
-rw-r--r--doc/web/searchadapters.rst2
-rw-r--r--doc/web/storagebackends.rst26
5 files changed, 164 insertions, 53 deletions
diff --git a/doc/web/api.rst b/doc/web/api.rst
index fcd0513e..b2b7ef95 100644
--- a/doc/web/api.rst
+++ b/doc/web/api.rst
@@ -10,10 +10,45 @@ The WebSupport Class
The main API class for the web support package. All interactions
with the web support package should occur through this class.
- :param srcdir: the directory containing the reStructuredText files
- :param outdir: the directory in which to place the built data
- :param search: the search system to use
- :param comments: an instance of a CommentBackend
+ The class takes the following keyword arguments:
+
+ srcdir
+ The directory containing reStructuredText source files.
+
+ builddir
+ The directory that build data and static files should be placed in.
+ This should be used when creating a :class:`WebSupport` object that
+ will be used to build data.
+
+ datadir:
+ The directory that the web support data is in. This should be used
+ when creating a :class:`WebSupport` object that will be used to
+ retrieve data.
+
+ search:
+ This may contain either a string (e.g. 'xapian') referencing a
+ built-in search adapter to use, or an instance of a subclass of
+ :class:`~sphinx.websupport.search.BaseSearch`.
+
+ storage:
+ This may contain either a string representing a database uri, or an
+ instance of a subclass of
+ :class:`~sphinx.websupport.storage.StorageBackend`. If this is not
+ provided a new sqlite database will be created.
+
+ moderation_callback:
+ A callable to be called when a new comment is added that is not
+ displayed. It must accept one argument: a dict representing the
+ comment that was added.
+
+ staticdir:
+ If static files are served from a location besides "/static", this
+ should be a string with the name of that location
+ (e.g. '/static_files').
+
+ docroot:
+ If the documentation is not served from the base path of a URL, this
+ should be a string specifying that path (e.g. 'docs')
Methods
~~~~~~~
diff --git a/doc/web/frontend.rst b/doc/web/frontend.rst
deleted file mode 100644
index 5ffe1667..00000000
--- a/doc/web/frontend.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-.. _websupportfrontend:
-
-Web Support Frontend
-====================
-
-More coming soon. \ No newline at end of file
diff --git a/doc/web/quickstart.rst b/doc/web/quickstart.rst
index b0a60507..302a4db0 100644
--- a/doc/web/quickstart.rst
+++ b/doc/web/quickstart.rst
@@ -7,26 +7,26 @@ Building Documentation Data
~~~~~~~~~~~~~~~~~~~~~~~~~~~
To make use of the web support package in your application you'll
-need to build that data it uses. This data includes pickle files representing
+need to build the data it uses. This data includes pickle files representing
documents, search indices, and node data that is used to track where
comments and other things are in a document. To do this you will need
-to create an instance of the :class:`~sphinx.websupport.api.WebSupport`
+to create an instance of the :class:`~sphinx.websupport.WebSupport`
class and call it's :meth:`~sphinx.websupport.WebSupport.build` method::
from sphinx.websupport import WebSupport
support = WebSupport(srcdir='/path/to/rst/sources/',
- outdir='/path/to/build/outdir',
+ builddir='/path/to/build/outdir',
search='xapian')
support.build()
This will read reStructuredText sources from `srcdir` and place the
-necessary data in `outdir`. This directory contains all the data needed
+necessary data in `builddir`. The `builddir` will contain two
+sub-directories. One named "data" that contains all the data needed
to display documents, search through documents, and add comments to
-documents. It will also contain a subdirectory named "static", which
-contains static files. These files will be linked to by Sphinx documents,
-and should be served from "/static".
+documents. The other directory will be called "static" and contains static
+files that should be served from "/static".
.. note::
@@ -37,7 +37,7 @@ and should be served from "/static".
Integrating Sphinx Documents Into Your Webapp
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Now that you have the data, it's time to do something useful with it.
+Now that the data is built, it's time to do something useful with it.
Start off by creating a :class:`~sphinx.websupport.WebSupport` object
for your application::
@@ -59,8 +59,8 @@ This will return a dictionary containing the following items:
* **sidebar**: The sidebar of the document as HTML
* **relbar**: A div containing links to related documents
* **title**: The title of the document
-* **DOCUMENTATION_OPTIONS**: Javascript containing documentation options
-* **COMMENT_OPTIONS**: Javascript containing comment options
+* **css**: Links to css files used by Sphinx
+* **js**: Javascript containing comment options
This dict can then be used as context for templates. The goal is to be
easy to integrate with your existing templating system. An example using
@@ -74,13 +74,15 @@ easy to integrate with your existing templating system. An example using
{{ document.title }}
{%- endblock %}
+ {% block css %}
+ {{ super() }}
+ {{ document.css|safe }}
+ <link rel="stylesheet" href="/static/websupport-custom.css" type="text/css">
+ {% endblock %}
+
{%- block js %}
- <script type="text/javascript">
- {{ document.DOCUMENTATION_OPTIONS|safe }}
- {{ document.COMMENT_OPTIONS|safe }}
- </script>
{{ super() }}
- <script type="text/javascript" src="/static/websupport.js"></script>
+ {{ document.js|safe }}
{%- endblock %}
{%- block relbar %}
@@ -99,12 +101,12 @@ Authentication
--------------
To use certain features such as voting it must be possible to authenticate
-users. The details of the authentication are left to the your application.
+users. The details of the authentication are left to your application.
Once a user has been authenticated you can pass the user's details to certain
:class:`~sphinx.websupport.WebSupport` methods using the *username* and
*moderator* keyword arguments. The web support package will store the
username with comments and votes. The only caveat is that if you allow users
-to change their username, you must update the websupport package's data::
+to change their username you must update the websupport package's data::
support.update_username(old_username, new_username)
@@ -113,18 +115,22 @@ should be a boolean representing whether the user has moderation
privilieges. The default value for *moderator* is *False*.
An example `Flask <http://flask.pocoo.org/>`_ function that checks whether
-a user is logged in, and the retrieves a document is::
+a user is logged in and then retrieves a document is::
+
+ from sphinx.websupport.errors import *
@app.route('/<path:docname>')
def doc(docname):
- if g.user:
- document = support.get_document(docname, g.user.name,
- g.user.moderator)
- else:
- document = support.get_document(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)
The first thing to notice is that the *docname* is just the request path.
+This makes accessing the correct document easy from a single view.
If the user is authenticated then the username and moderation status are
passed along with the docname to
:meth:`~sphinx.websupport.WebSupport.get_document`. The web support package
@@ -134,8 +140,12 @@ will then add this data to the COMMENT_OPTIONS that are used in the template.
This only works works if your documentation is served from your
document root. If it is served from another directory, you will
- need to prefix the url route with that directory::
-
+ need to prefix the url route with that directory, and give the `docroot`
+ keyword argument when creating the web support object::
+
+ support = WebSupport(...
+ docroot='docs')
+
@app.route('/docs/<path:docname>')
Performing Searches
@@ -160,8 +170,8 @@ did to render our documents. That's because
dict in the same format that
:meth:`~sphinx.websupport.WebSupport.get_document` does.
-Comments
-~~~~~~~~
+Comments & Proposals
+~~~~~~~~~~~~~~~~~~~~
Now that this is done it's time to define the functions that handle
the AJAX calls from the script. You will need three functions. The first
@@ -171,20 +181,29 @@ function is used to add a new comment, and will call the web support method
@app.route('/docs/add_comment', methods=['POST'])
def add_comment():
parent_id = request.form.get('parent', '')
+ node_id = request.form.get('node', '')
text = request.form.get('text', '')
+ proposal = request.form.get('proposal', '')
username = g.user.name if g.user is not None else 'Anonymous'
- comment = support.add_comment(parent_id, text, username=username)
+ comment = support.add_comment(text, node_id='node_id',
+ parent_id='parent_id',
+ username=username, proposal=proposal)
return jsonify(comment=comment)
-Then next function handles the retrieval of comments for a specific node,
-and is aptly named :meth:`~sphinx.websupport.WebSupport.get_data`::
+You'll notice that both a `parent_id` and `node_id` are sent with the
+request. If the comment is being attached directly to a node, `parent_id`
+will be empty. If the comment is a child of another comment, then `node_id`
+will be empty. Then next function handles the retrieval of comments for a
+specific node, and is aptly named
+:meth:`~sphinx.websupport.WebSupport.get_data`::
@app.route('/docs/get_comments')
def get_comments():
- user_id = g.user.id if g.user else None
- parent_id = request.args.get('parent', '')
- comments = support.get_data(parent_id, user_id)
- return jsonify(comments=comments)
+ username = g.user.name if g.user else None
+ moderator = g.user.moderator if g.user else False
+ node_id = request.args.get('node', '')
+ data = support.get_data(parent_id, user_id)
+ return jsonify(**data)
The final function that is needed will call
:meth:`~sphinx.websupport.WebSupport.process_vote`, and will handle user
@@ -201,12 +220,49 @@ votes on comments::
support.process_vote(comment_id, g.user.id, value)
return "success"
-.. note::
+Comment Moderation
+~~~~~~~~~~~~~~~~~~
+
+By default all comments added through
+:meth:`~sphinx.websupport.WebSupport.add_comment` are automatically
+displayed. If you wish to have some form of moderation, you can pass
+the `displayed` keyword argument::
+
+ comment = support.add_comment(text, node_id='node_id',
+ parent_id='parent_id',
+ username=username, proposal=proposal,
+ displayed=False)
+
+You can then create two new views to handle the moderation of comments. The
+first will be called when a moderator decides a comment should be accepted
+and displayed::
+
+ @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'
+
+The next is very similar, but used when rejecting a comment::
+
+ @app.route('/docs/reject_comment', methods=['POST'])
+ def reject_comment():
+ moderator = g.user.moderator if g.user else False
+ comment_id = request.form.get('id')
+ support.reject_comment(comment_id, moderator=moderator)
+ return 'OK'
+
+To perform a custom action (such as emailing a moderator) when a new comment
+is added but not displayed, you can pass callable to the
+:class:`~sphinx.websupport.WebSupport` class when instantiating your support
+object::
+
+ def moderation_callback(comment):
+ Do something...
+
+ support = WebSupport(...
+ moderation_callback=moderation_callback)
- Authentication is left up to your existing web application. If you do
- not have an existing authentication system there are many readily
- available for different frameworks. The web support system stores only
- the user's unique integer `user_id` and uses this both for storing votes
- and retrieving vote information. It is up to you to ensure that the
- user_id passed in is unique, and that the user is authenticated. The
- default backend will only allow one vote per comment per `user_id`.
+The moderation callback must take one argument, which will be the same
+comment dict that is returned by add_comment. \ No newline at end of file
diff --git a/doc/web/searchadapters.rst b/doc/web/searchadapters.rst
index 83e928ba..e03fee81 100644
--- a/doc/web/searchadapters.rst
+++ b/doc/web/searchadapters.rst
@@ -11,7 +11,7 @@ and pass that as the `search` keyword argument when you create the
:class:`~sphinx.websupport.WebSupport` object::
support = Websupport(srcdir=srcdir,
- outdir=outdir,
+ builddir=builddir,
search=MySearch())
For more information about creating a custom search adapter, please see
diff --git a/doc/web/storagebackends.rst b/doc/web/storagebackends.rst
index 4a10e109..6411bf17 100644
--- a/doc/web/storagebackends.rst
+++ b/doc/web/storagebackends.rst
@@ -5,6 +5,22 @@
Storage Backends
================
+To create a custom storage backend you will need to subclass the
+:class:`~StorageBackend` class. Then create an instance of the new class
+and pass that as the `storage` keyword argument when you create the
+:class:`~sphinx.websupport.WebSupport` object::
+
+ support = Websupport(srcdir=srcdir,
+ builddir=builddir,
+ storage=MyStorage())
+
+For more information about creating a custom storage backend, please see
+the documentation of the :class:`StorageBackend` class below.
+
+.. class:: StorageBackend
+
+ Defines an interface for storage backends.
+
StorageBackend Methods
~~~~~~~~~~~~~~~~~~~~~~
@@ -16,4 +32,14 @@ StorageBackend Methods
.. automethod:: sphinx.websupport.storage.StorageBackend.add_comment
+.. automethod:: sphinx.websupport.storage.StorageBackend.delete_comment
+
.. automethod:: sphinx.websupport.storage.StorageBackend.get_data
+
+.. automethod:: sphinx.websupport.storage.StorageBackend.process_vote
+
+.. automethod:: sphinx.websupport.storage.StorageBackend.update_username
+
+.. automethod:: sphinx.websupport.storage.StorageBackend.accept_comment
+
+.. automethod:: sphinx.websupport.storage.StorageBackend.reject_comment \ No newline at end of file