diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 11:31:33 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 11:31:33 +0000 |
commit | e863fd965dd6253243c3342bd6f0adc4fc8aec4d (patch) | |
tree | a4c1b6491a82593950043c3f8b2530e80664d768 /doc/usage/advanced | |
parent | Initial commit. (diff) | |
download | sphinx-e863fd965dd6253243c3342bd6f0adc4fc8aec4d.tar.xz sphinx-e863fd965dd6253243c3342bd6f0adc4fc8aec4d.zip |
Adding upstream version 5.3.0.upstream/5.3.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc/usage/advanced')
-rw-r--r-- | doc/usage/advanced/intl.rst | 348 | ||||
-rw-r--r-- | doc/usage/advanced/setuptools.rst | 200 | ||||
-rw-r--r-- | doc/usage/advanced/websupport/api.rst | 80 | ||||
-rw-r--r-- | doc/usage/advanced/websupport/index.rst | 16 | ||||
-rw-r--r-- | doc/usage/advanced/websupport/quickstart.rst | 255 | ||||
-rw-r--r-- | doc/usage/advanced/websupport/searchadapters.rst | 49 | ||||
-rw-r--r-- | doc/usage/advanced/websupport/storagebackends.rst | 49 |
7 files changed, 997 insertions, 0 deletions
diff --git a/doc/usage/advanced/intl.rst b/doc/usage/advanced/intl.rst new file mode 100644 index 0000000..ccdb6e9 --- /dev/null +++ b/doc/usage/advanced/intl.rst @@ -0,0 +1,348 @@ +.. _intl: + +Internationalization +==================== + +.. versionadded:: 1.1 + +Complementary to translations provided for Sphinx-generated messages such as +navigation bars, Sphinx provides mechanisms facilitating the translation of +*documents*. See the :ref:`intl-options` for details on configuration. + +.. figure:: /_static/translation.* + :width: 100% + + Workflow visualization of translations in Sphinx. (The figure is created by + `plantuml <https://plantuml.com>`_.) + +.. contents:: + :local: + +Sphinx internationalization details +----------------------------------- + +**gettext** [1]_ is an established standard for internationalization and +localization. It naively maps messages in a program to a translated string. +Sphinx uses these facilities to translate whole documents. + +Initially project maintainers have to collect all translatable strings (also +referred to as *messages*) to make them known to translators. Sphinx extracts +these through invocation of ``sphinx-build -b gettext``. + +Every single element in the doctree will end up in a single message which +results in lists being equally split into different chunks while large +paragraphs will remain as coarsely-grained as they were in the original +document. This grants seamless document updates while still providing a little +bit of context for translators in free-text passages. It is the maintainer's +task to split up paragraphs which are too large as there is no sane automated +way to do that. + +After Sphinx successfully ran the +:class:`~sphinx.builders.gettext.MessageCatalogBuilder` you will find a +collection of ``.pot`` files in your output directory. These are **catalog +templates** and contain messages in your original language *only*. + +They can be delivered to translators which will transform them to ``.po`` files +--- so called **message catalogs** --- containing a mapping from the original +messages to foreign-language strings. + +*gettext* compiles them into a binary format known as **binary catalogs** +through :program:`msgfmt` for efficiency reasons. If you make these files +discoverable with :confval:`locale_dirs` for your :confval:`language`, Sphinx +will pick them up automatically. + +An example: you have a document ``usage.rst`` in your Sphinx project. The +*gettext* builder will put its messages into ``usage.pot``. Imagine you have +Spanish translations [2]_ stored in ``usage.po`` --- for your builds to +be translated you need to follow these instructions: + +* Compile your message catalog to a locale directory, say ``locale``, so it + ends up in ``./locale/es/LC_MESSAGES/usage.mo`` in your source directory + (where ``es`` is the language code for Spanish.) :: + + msgfmt "usage.po" -o "locale/es/LC_MESSAGES/usage.mo" + +* Set :confval:`locale_dirs` to ``["locale/"]``. +* Set :confval:`language` to ``es`` (also possible via + :option:`-D <sphinx-build -D>`). +* Run your desired build. + + +In order to protect against mistakes, a warning is emitted if +cross-references in the translated paragraph do not match those from the +original. This can be turned off globally using the +:confval:`suppress_warnings` configuration variable. Alternatively, to +turn it off for one message only, end the message with ``#noqa`` like +this:: + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse + risus tortor, luctus id ultrices at. #noqa + +(Write ``\#noqa`` in case you want to have "#noqa" literally in the +text. This does not apply to code blocks, where ``#noqa`` is ignored +because code blocks do not contain references anyway.) + +.. versionadded:: 4.5 + The ``#noqa`` mechanism. + + +Translating with sphinx-intl +---------------------------- + +Quick guide +~~~~~~~~~~~ + +`sphinx-intl`_ is a useful tool to work with Sphinx translation flow. This +section describe an easy way to translate with *sphinx-intl*. + +#. Install `sphinx-intl`_. + + .. code-block:: console + + $ pip install sphinx-intl + +#. Add configurations to ``conf.py``. + + :: + + locale_dirs = ['locale/'] # path is example but recommended. + gettext_compact = False # optional. + + This case-study assumes that BUILDDIR is set to ``_build``, + :confval:`locale_dirs` is set to ``locale/`` and :confval:`gettext_compact` + is set to ``False`` (the Sphinx document is already configured as such). + +#. Extract translatable messages into pot files. + + .. code-block:: console + + $ make gettext + + The generated pot files will be placed in the ``_build/gettext`` directory. + +#. Generate po files. + + We'll use the pot files generated in the above step. + + .. code-block:: console + + $ sphinx-intl update -p _build/gettext -l de -l ja + + Once completed, the generated po files will be placed in the below + directories: + + * ``./locale/de/LC_MESSAGES/`` + * ``./locale/ja/LC_MESSAGES/`` + +#. Translate po files. + + As noted above, these are located in the ``./locale/<lang>/LC_MESSAGES`` + directory. An example of one such file, from Sphinx, ``builders.po``, is + given below. + + .. code-block:: po + + # a5600c3d2e3d48fc8c261ea0284db79b + #: ../../builders.rst:4 + msgid "Available builders" + msgstr "<FILL HERE BY TARGET LANGUAGE>" + + Another case, msgid is multi-line text and contains reStructuredText syntax: + + .. code-block:: po + + # 302558364e1d41c69b3277277e34b184 + #: ../../builders.rst:9 + msgid "" + "These are the built-in Sphinx builders. More builders can be added by " + ":ref:`extensions <extensions>`." + msgstr "" + "FILL HERE BY TARGET LANGUAGE FILL HERE BY TARGET LANGUAGE FILL HERE " + "BY TARGET LANGUAGE :ref:`EXTENSIONS <extensions>` FILL HERE." + + Please be careful not to break reST notation. Most po-editors will help you + with that. + +#. Build translated document. + + You need a :confval:`language` parameter in ``conf.py`` or you may also + specify the parameter on the command line. + + For for BSD/GNU make, run: + + .. code-block:: console + + $ make -e SPHINXOPTS="-D language='de'" html + + For Windows :command:`cmd.exe`, run: + + .. code-block:: console + + > set SPHINXOPTS=-D language=de + > .\make.bat html + + For PowerShell, run: + + .. code-block:: console + + > Set-Item env:SPHINXOPTS "-D language=de" + > .\make.bat html + +Congratulations! You got the translated documentation in the ``_build/html`` +directory. + +.. versionadded:: 1.3 + + :program:`sphinx-build` that is invoked by make command will build po files + into mo files. + + If you are using 1.2.x or earlier, please invoke :command:`sphinx-intl build` + command before :command:`make` command. + +Translating +~~~~~~~~~~~ + +Update your po files by new pot files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If a document is updated, it is necessary to generate updated pot files and to +apply differences to translated po files. In order to apply the updates from a +pot file to the po file, use the :command:`sphinx-intl update` command. + +.. code-block:: console + + $ sphinx-intl update -p _build/gettext + + +Using Transifex service for team translation +-------------------------------------------- + +Transifex_ is one of several services that allow collaborative translation via a +web interface. It has a nifty Python-based command line client that makes it +easy to fetch and push translations. + +.. TODO: why use transifex? + + +#. Install `transifex-client`_. + + You need :command:`tx` command to upload resources (pot files). + + .. code-block:: console + + $ pip install transifex-client + + .. seealso:: `Transifex Client documentation`_ + +#. Create your transifex_ account and create new project for your document. + + Currently, transifex does not allow for a translation project to have more + than one version of the document, so you'd better include a version number in + your project name. + + For example: + + :Project ID: ``sphinx-document-test_1_0`` + :Project URL: ``https://www.transifex.com/projects/p/sphinx-document-test_1_0/`` + +#. Create config files for :command:`tx` command. + + This process will create ``.tx/config`` in the current directory, as well as + a ``~/.transifexrc`` file that includes auth information. + + .. code-block:: console + + $ tx init + Creating .tx folder... + Transifex instance [https://www.transifex.com]: + ... + Please enter your transifex username: <transifex-username> + Password: <transifex-password> + ... + Done. + +#. Upload pot files to transifex service. + + Register pot files to ``.tx/config`` file: + + .. code-block:: console + + $ cd /your/document/root + $ sphinx-intl update-txconfig-resources --pot-dir _build/locale \ + --transifex-project-name sphinx-document-test_1_0 + + and upload pot files: + + .. code-block:: console + + $ tx push -s + Pushing translations for resource sphinx-document-test_1_0.builders: + Pushing source file (locale/pot/builders.pot) + Resource does not exist. Creating... + ... + Done. + +#. Forward the translation on transifex. + + .. TODO: write this section + +#. Pull translated po files and make translated HTML. + + Get translated catalogs and build mo files. For example, to build mo files + for German (de): + + .. code-block:: console + + $ cd /your/document/root + $ tx pull -l de + Pulling translations for resource sphinx-document-test_1_0.builders (...) + -> de: locale/de/LC_MESSAGES/builders.po + ... + Done. + + Invoke :command:`make html` (for BSD/GNU make): + + .. code-block:: console + + $ make -e SPHINXOPTS="-D language='de'" html + +That's all! + +.. tip:: Translating locally and on Transifex + + If you want to push all language's po files, you can be done by using + :command:`tx push -t` command. Watch out! This operation overwrites + translations in transifex. + + In other words, if you have updated each in the service and local po files, + it would take much time and effort to integrate them. + + +Contributing to Sphinx reference translation +-------------------------------------------- + +The recommended way for new contributors to translate Sphinx reference is to +join the translation team on Transifex. + +There is a `sphinx translation page`_ for Sphinx (master) documentation. + +1. Login to transifex_ service. +2. Go to `sphinx translation page`_. +3. Click ``Request language`` and fill form. +4. Wait acceptance by transifex sphinx translation maintainers. +5. (After acceptance) Translate on transifex. + +Detail is here: https://docs.transifex.com/getting-started-1/translators + +.. rubric:: Footnotes + +.. [1] See the `GNU gettext utilities + <https://www.gnu.org/software/gettext/manual/gettext.html#Introduction>`_ + for details on that software suite. +.. [2] Because nobody expects the Spanish Inquisition! + +.. _`transifex-client`: https://pypi.org/project/transifex-client/ +.. _`sphinx-intl`: https://pypi.org/project/sphinx-intl/ +.. _Transifex: https://www.transifex.com/ +.. _`sphinx translation page`: https://www.transifex.com/sphinx-doc/sphinx-doc/ +.. _`Transifex Client documentation`: https://docs.transifex.com/client/introduction/ diff --git a/doc/usage/advanced/setuptools.rst b/doc/usage/advanced/setuptools.rst new file mode 100644 index 0000000..672d658 --- /dev/null +++ b/doc/usage/advanced/setuptools.rst @@ -0,0 +1,200 @@ +.. _setuptools: + +Setuptools integration +====================== + +Sphinx supports integration with setuptools and distutils through a custom +command - :class:`~sphinx.setup_command.BuildDoc`. + +.. deprecated:: 5.0 + + This feature will be removed in v7.0. + +Using setuptools integration +---------------------------- + +The Sphinx build can then be triggered from distutils, and some Sphinx +options can be set in ``setup.py`` or ``setup.cfg`` instead of Sphinx's own +configuration file. + +For instance, from ``setup.py``:: + + # this is only necessary when not using setuptools/distribute + from sphinx.setup_command import BuildDoc + cmdclass = {'build_sphinx': BuildDoc} + + name = 'My project' + version = '1.2' + release = '1.2.0' + setup( + name=name, + author='Bernard Montgomery', + version=release, + cmdclass=cmdclass, + # these are optional and override conf.py settings + command_options={ + 'build_sphinx': { + 'project': ('setup.py', name), + 'version': ('setup.py', version), + 'release': ('setup.py', release), + 'source_dir': ('setup.py', 'doc')}}, + ) + +.. note:: + + If you set Sphinx options directly in the ``setup()`` command, replace + hyphens in variable names with underscores. In the example above, + ``source-dir`` becomes ``source_dir``. + +Or add this section in ``setup.cfg``:: + + [build_sphinx] + project = 'My project' + version = 1.2 + release = 1.2.0 + source-dir = 'doc' + +Once configured, call this by calling the relevant command on ``setup.py``:: + + $ python setup.py build_sphinx + +Options for setuptools integration +---------------------------------- + +.. setuptools-confval:: fresh-env + + A boolean that determines whether the saved environment should be discarded + on build. Default is false. + + This can also be set by passing the `-E` flag to ``setup.py``: + + .. code-block:: console + + $ python setup.py build_sphinx -E + +.. setuptools-confval:: all-files + + A boolean that determines whether all files should be built from scratch. + Default is false. + + This can also be set by passing the `-a` flag to ``setup.py``: + + .. code-block:: console + + $ python setup.py build_sphinx -a + +.. setuptools-confval:: source-dir + + The target source directory. This can be relative to the ``setup.py`` or + ``setup.cfg`` file, or it can be absolute. It defaults to ``./doc`` or + ``./docs`` if either contains a file named ``conf.py`` (checking ``./doc`` + first); otherwise it defaults to the current directory. + + This can also be set by passing the `-s` flag to ``setup.py``: + + .. code-block:: console + + $ python setup.py build_sphinx -s $SOURCE_DIR + +.. setuptools-confval:: build-dir + + The target build directory. This can be relative to the ``setup.py`` or + ``setup.cfg`` file, or it can be absolute. Default is ``./build/sphinx``. + +.. setuptools-confval:: config-dir + + Location of the configuration directory. This can be relative to the + ``setup.py`` or ``setup.cfg`` file, or it can be absolute. Default is to use + `source-dir`. + + This can also be set by passing the `-c` flag to ``setup.py``: + + .. code-block:: console + + $ python setup.py build_sphinx -c $CONFIG_DIR + + .. versionadded:: 1.0 + +.. setuptools-confval:: builder + + The builder or list of builders to use. Default is ``html``. + + This can also be set by passing the `-b` flag to ``setup.py``: + + .. code-block:: console + + $ python setup.py build_sphinx -b $BUILDER + + .. versionchanged:: 1.6 + This can now be a comma- or space-separated list of builders + +.. setuptools-confval:: warning-is-error + + A boolean that ensures Sphinx warnings will result in a failed build. + Default is false. + + This can also be set by passing the `-W` flag to ``setup.py``: + + .. code-block:: console + + $ python setup.py build_sphinx -W + + .. versionadded:: 1.5 + +.. setuptools-confval:: project + + The documented project's name. Default is ``''``. + + .. versionadded:: 1.0 + +.. setuptools-confval:: version + + The short X.Y version. Default is ``''``. + + .. versionadded:: 1.0 + +.. setuptools-confval:: release + + The full version, including alpha/beta/rc tags. Default is ``''``. + + .. versionadded:: 1.0 + +.. setuptools-confval:: today + + How to format the current date, used as the replacement for ``|today|``. + Default is ``''``. + + .. versionadded:: 1.0 + +.. setuptools-confval:: link-index + + A boolean that ensures index.html will be linked to the root doc. Default + is false. + + This can also be set by passing the `-i` flag to ``setup.py``: + + .. code-block:: console + + $ python setup.py build_sphinx -i + + .. versionadded:: 1.0 + +.. setuptools-confval:: copyright + + The copyright string. Default is ``''``. + + .. versionadded:: 1.3 + +.. setuptools-confval:: nitpicky + + Run in nit-picky mode. Currently, this generates warnings for all missing + references. See the config value :confval:`nitpick_ignore` for a way to + exclude some references as "known missing". + + .. versionadded:: 1.8 + +.. setuptools-confval:: pdb + + A boolean to configure ``pdb`` on exception. Default is false. + + .. versionadded:: 1.5 diff --git a/doc/usage/advanced/websupport/api.rst b/doc/usage/advanced/websupport/api.rst new file mode 100644 index 0000000..79b51ee --- /dev/null +++ b/doc/usage/advanced/websupport/api.rst @@ -0,0 +1,80 @@ +.. _websupportapi: + +.. currentmodule:: sphinxcontrib.websupport + +The WebSupport Class +==================== + +.. class:: WebSupport + + The main API class for the web support package. All interactions with the + web support package should occur through this class. + + 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:`~.search.BaseSearch`. + + storage + This may contain either a string representing a database uri, or an + instance of a subclass of :class:`~.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 dictionary representing the + comment that was added. + + staticdir + If the static files should be created in a different location + **and not in** ``'/static'``, this should be a string with the name of + that location (e.g. ``builddir + '/static_files'``). + + .. note:: + If you specify ``staticdir``, you will typically want to adjust + ``staticroot`` accordingly. + + staticroot + If the static files are not served from ``'/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'``). + + +.. versionchanged:: 1.6 + + WebSupport class is moved to sphinxcontrib.websupport from sphinx.websupport. + Please add ``sphinxcontrib-websupport`` package in your dependency and use + moved class instead. + + +Methods +------- + +.. automethod:: sphinxcontrib.websupport.WebSupport.build + +.. automethod:: sphinxcontrib.websupport.WebSupport.get_document + +.. automethod:: sphinxcontrib.websupport.WebSupport.get_data + +.. automethod:: sphinxcontrib.websupport.WebSupport.add_comment + +.. automethod:: sphinxcontrib.websupport.WebSupport.process_vote + +.. automethod:: sphinxcontrib.websupport.WebSupport.get_search_results diff --git a/doc/usage/advanced/websupport/index.rst b/doc/usage/advanced/websupport/index.rst new file mode 100644 index 0000000..0816640 --- /dev/null +++ b/doc/usage/advanced/websupport/index.rst @@ -0,0 +1,16 @@ +.. _websupport: + +Sphinx Web Support +================== + +.. versionadded:: 1.1 + +Sphinx provides a Python API to easily integrate Sphinx documentation into your +web application. To learn more read the :ref:`websupportquickstart`. + +.. toctree:: + + quickstart + api + searchadapters + storagebackends diff --git a/doc/usage/advanced/websupport/quickstart.rst b/doc/usage/advanced/websupport/quickstart.rst new file mode 100644 index 0000000..5fa5b00 --- /dev/null +++ b/doc/usage/advanced/websupport/quickstart.rst @@ -0,0 +1,255 @@ +.. _websupportquickstart: + +Web Support Quick Start +======================= + +Building Documentation Data +---------------------------- + +To make use of the web support package in your application you'll 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:`~.WebSupport` class and call its :meth:`~.WebSupport.build` method:: + + from sphinxcontrib.websupport import WebSupport + + support = WebSupport(srcdir='/path/to/rst/sources/', + builddir='/path/to/build/outdir', + search='xapian') + + support.build() + +This will read reStructuredText sources from ``srcdir`` and place the 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. The other directory will be +called "static" and contains static files that should be served from "/static". + +.. note:: + + If you wish to serve static files from a path other than "/static", you can + do so by providing the *staticdir* keyword argument when creating the + :class:`~.WebSupport` object. + + +Integrating Sphinx Documents Into Your Webapp +---------------------------------------------- + +Now that the data is built, it's time to do something useful with it. Start off +by creating a :class:`~.WebSupport` object for your application:: + + from sphinxcontrib.websupport import WebSupport + + support = WebSupport(datadir='/path/to/the/data', + search='xapian') + +You'll only need one of these for each set of documentation you will be working +with. You can then call its :meth:`~.WebSupport.get_document` method to access +individual documents:: + + contents = support.get_document('contents') + +This will return a dictionary containing the following items: + +* **body**: The main body of the document as HTML +* **sidebar**: The sidebar of the document as HTML +* **relbar**: A div containing links to related documents +* **title**: The title of the document +* **css**: Links to CSS files used by Sphinx +* **script**: 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 `Jinja2 +<https://jinja.palletsprojects.com/>`_ is: + +.. code-block:: html+jinja + + {%- 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 %} + + +Authentication +~~~~~~~~~~~~~~ + +To use certain features such as voting, it must be possible to authenticate +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:`~.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:: + + support.update_username(old_username, new_username) + +*username* should be a unique string which identifies a user, and *moderator* +should be a boolean representing whether the user has moderation privileges. +The default value for *moderator* is ``False``. + +An example `Flask <https://flask.palletsprojects.com/>`_ function that checks +whether a user is logged in and then retrieves a document is:: + + 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) + +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:`~.WebSupport.get_document`. The web support package will then +add this data to the ``COMMENT_OPTIONS`` that are used in the template. + +.. note:: + + This only 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, and give the `docroot` + keyword argument when creating the web support object:: + + support = WebSupport(..., docroot='docs') + + @app.route('/docs/<path:docname>') + + +Performing Searches +------------------- + +To use the search form built-in to the Sphinx sidebar, create a function to +handle requests to the URL 'search' relative to the documentation root. The +user's search query will be in the GET parameters, with the key `q`. Then use +the :meth:`~sphinxcontrib.websupport.WebSupport.get_search_results` method to +retrieve search results. In `Flask <https://flask.palletsprojects.com/>`_ that +would be like this:: + + @app.route('/search') + def search(): + q = request.args.get('q') + document = support.get_search_results(q) + return render_template('doc.html', document=document) + +Note that we used the same template to render our search results as we did to +render our documents. That's because :meth:`~.WebSupport.get_search_results` +returns a context dict in the same format that :meth:`~.WebSupport.get_document` +does. + + +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 function is +used to add a new comment, and will call the web support method +:meth:`~.WebSupport.add_comment`:: + + @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(text, node_id='node_id', + parent_id='parent_id', + username=username, proposal=proposal) + return jsonify(comment=comment) + +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:`~sphinxcontrib.websupport.WebSupport.get_data`:: + + @app.route('/docs/get_comments') + def get_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(node_id, username, moderator) + return jsonify(**data) + +The final function that is needed will call :meth:`~.WebSupport.process_vote`, +and will handle user votes on comments:: + + @app.route('/docs/process_vote', methods=['POST']) + def process_vote(): + if g.user is None: + abort(401) + comment_id = request.form.get('comment_id') + value = request.form.get('value') + if value is None or comment_id is None: + abort(400) + support.process_vote(comment_id, g.user.id, value) + return "success" + + +Comment Moderation +------------------ + +By default, all comments added through :meth:`~.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 a new view to handle the moderation of comments. It +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' + +Rejecting comments happens via comment deletion. + +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:`~.WebSupport` +class when instantiating your support object:: + + def moderation_callback(comment): + """Do something...""" + + support = WebSupport(..., moderation_callback=moderation_callback) + +The moderation callback must take one argument, which will be the same comment +dict that is returned by :meth:`add_comment`. diff --git a/doc/usage/advanced/websupport/searchadapters.rst b/doc/usage/advanced/websupport/searchadapters.rst new file mode 100644 index 0000000..262d666 --- /dev/null +++ b/doc/usage/advanced/websupport/searchadapters.rst @@ -0,0 +1,49 @@ +.. _searchadapters: + +.. currentmodule:: sphinxcontrib.websupport.search + +Search Adapters +=============== + +To create a custom search adapter you will need to subclass the +:class:`BaseSearch` class. Then create an instance of the new class and pass +that as the `search` keyword argument when you create the :class:`~.WebSupport` +object:: + + support = WebSupport(srcdir=srcdir, + builddir=builddir, + search=MySearch()) + +For more information about creating a custom search adapter, please see the +documentation of the :class:`BaseSearch` class below. + +.. class:: BaseSearch + + Defines an interface for search adapters. + +.. versionchanged:: 1.6 + + BaseSearch class is moved to sphinxcontrib.websupport.search from + sphinx.websupport.search. + +Methods +------- + +The following methods are defined in the BaseSearch class. Some methods do not +need to be overridden, but some (:meth:`~BaseSearch.add_document` and +:meth:`~BaseSearch.handle_query`) must be overridden in your subclass. For a +working example, look at the built-in adapter for whoosh. + +.. automethod:: BaseSearch.init_indexing + +.. automethod:: BaseSearch.finish_indexing + +.. automethod:: BaseSearch.feed + +.. automethod:: BaseSearch.add_document + +.. automethod:: BaseSearch.query + +.. automethod:: BaseSearch.handle_query + +.. automethod:: BaseSearch.extract_context diff --git a/doc/usage/advanced/websupport/storagebackends.rst b/doc/usage/advanced/websupport/storagebackends.rst new file mode 100644 index 0000000..ccb00b6 --- /dev/null +++ b/doc/usage/advanced/websupport/storagebackends.rst @@ -0,0 +1,49 @@ +.. _storagebackends: + +.. currentmodule:: sphinxcontrib.websupport.storage + +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:`~.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. + +.. versionchanged:: 1.6 + + StorageBackend class is moved to sphinxcontrib.websupport.storage from + sphinx.websupport.storage. + + +Methods +------- + +.. automethod:: StorageBackend.pre_build + +.. automethod:: StorageBackend.add_node + +.. automethod:: StorageBackend.post_build + +.. automethod:: StorageBackend.add_comment + +.. automethod:: StorageBackend.delete_comment + +.. automethod:: StorageBackend.get_data + +.. automethod:: StorageBackend.process_vote + +.. automethod:: StorageBackend.update_username + +.. automethod:: StorageBackend.accept_comment |