This commit is contained in:
lwark
2025-09-17 07:52:16 -05:00
commit a2ff72dda8
584 changed files with 52247 additions and 0 deletions

0
docs/__init__.py Normal file
View File

350
docs/conf.py Normal file
View File

@@ -0,0 +1,350 @@
import inspect
import os
import sys
from datetime import datetime
import bleach
import django
try:
from django.utils.encoding import force_text
except ImportError:
from django.utils.encoding import force_str as force_text
#
# django-wiki documentation build configuration file, created by
# sphinx-quickstart on Mon Jul 23 16:13:51 2012.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
# sys.path.insert(0, os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
# needs_sphinx = '1.0'
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath("../src"))
sys.path.insert(0, os.path.abspath("../testproject"))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
# needs_sphinx = '1.0'
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testproject.settings.dev")
django.setup()
# Auto list fields from django models - from https://djangosnippets.org/snippets/2533/#c5977
def process_docstring(app, what, name, obj, options, lines):
# This causes import errors if left outside the function
from django.db import models
# Only look at objects that inherit from Django's base model class
if inspect.isclass(obj) and issubclass(obj, models.Model):
# Grab the field list from the meta class
fields = obj._meta.get_fields()
for field in fields:
# Skip ManyToOneRel and ManyToManyRel fields which have no 'verbose_name' or 'help_text'
if not hasattr(field, "verbose_name"):
continue
# Decode and strip any html out of the field's help text
help_text = bleach.clean(force_text(field.help_text), strip=True)
# Decode and capitalize the verbose name, for use if there isn't
# any help text
verbose_name = force_text(field.verbose_name).capitalize()
if help_text:
# Add the model field to the end of the docstring as a param
# using the help text as the description
lines.append(f":param {field.attname}: {help_text}")
else:
# Add the model field to the end of the docstring as a param
# using the verbose name as the description
lines.append(f":param {field.attname}: {verbose_name}")
# Add the field's type to the docstring
if isinstance(field, models.ForeignKey):
for to in field.to_fields:
lines.append(
":type %s: %s to :class:`~%s`"
% (field.attname, type(field).__name__, to)
)
else:
lines.append(f":type {field.attname}: {type(field).__name__}")
return lines
extlinks = {
"url-issue": (
"https://github.com/django-wiki/django-wiki/issues/%s",
"#%s",
),
}
def setup(app):
# Register the docstring processor with sphinx
app.connect("autodoc-process-docstring", process_docstring)
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.extlinks",
"sphinx.ext.todo",
"sphinx.ext.viewcode",
# Fix: https://github.com/readthedocs/sphinx_rtd_theme/issues/1452
"sphinxcontrib.jquery",
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
# The suffix of source filenames.
source_suffix = ".rst"
# The encoding of source files.
# source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = "index"
# General information about the project.
project = "django-wiki"
copyright = f"{datetime.now().year}, Benjamin Bach" # noqa
path = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
sys.path = [path] + sys.path
sys.path = [os.path.join(path, "wiki")] + sys.path
import wiki # noqa
from wiki import __about__ # noqa
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = ".".join(__about__.__version__.split(".")[0:100])
# The full version, including alpha/beta/rc tags.
release = __about__.__version__
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
# language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
# today = ''
# Else, today_fmt is used as the format for a strftime call.
# today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ["_build"]
# The reST default role (used for this markup: `text`) to use for all documents.
# default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
# add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
# add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
# show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
linkcheck_ignore = [
r"wiki.+",
]
# -- Options for HTML output ---------------------------------------------------
html_theme = "sphinx_rtd_theme"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
# html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
# html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
# html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
# html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
# html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
# html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
# html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
# html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
# html_additional_pages = {}
# If false, no module index is generated.
# html_domain_indices = True
# If false, no index is generated.
# html_use_index = True
# If true, the index is split into individual pages for each letter.
# html_split_index = False
# If true, links to the reST sources are added to the pages.
# html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
# html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
# html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
# html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = "django-wikidoc"
# -- Options for LaTeX output --------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
# 'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
(
"index",
"django-wiki.tex",
"django-wiki Documentation",
"Benjamin Bach",
"manual",
),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
# latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
# latex_use_parts = False
# If true, show page references after internal links.
# latex_show_pagerefs = False
# If true, show URL addresses after external links.
# latex_show_urls = False
# Documents to append as an appendix to all manuals.
# latex_appendices = []
# If false, no module index is generated.
# latex_domain_indices = True
# -- Options for manual page output --------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
("index", "django-wiki", "django-wiki Documentation", ["Benjamin Bach"], 1)
]
# If true, show URL addresses after external links.
# man_show_urls = False
# -- Options for Texinfo output ------------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(
"index",
"django-wiki",
"django-wiki Documentation",
"Benjamin Bach",
"django-wiki",
"Wiki engine for Django - with real data models!",
"Miscellaneous",
),
]
# Documents to append as an appendix to all manuals.
# texinfo_appendices = []
# If false, no module index is generated.
# texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
# texinfo_show_urls = 'footnote'

78
docs/customization.rst Normal file
View File

@@ -0,0 +1,78 @@
Customization
=============
See :doc:`settings` for the settings that can be used to configure
django-wiki. Other ways to customize django-wiki for your use are listed below.
Templates
---------
django-wiki can be customized by providing your own templates.
All templates used by django-wiki inherit from ``wiki/base.html``, which in
turn simply inherits from ``wiki/base_site.html`` (adding
nothing). ``wiki/base_site.html`` provides a complete HTML page, but provides a
number of blocks that you might want to override. The most useful are:
* ``wiki_site_title``
* ``wiki_header_branding``
* ``wiki_header_navlinks``
These can be overridden to provide your own branding and links in the top bar of
the page, as well as in browser window title. The ``wiki/base_site.html``
template uses Bootstrap 3, so the following example shows how to use this in
practice, assuming you want a single link to your home page, and one to the
wiki. Add the following as ``wiki/base.html`` somewhere in your
``TEMPLATE_DIRS``:
.. code-block:: html+django
{% extends "wiki/base_site.html" %}
{% block wiki_site_title %} - Wiki{% endblock %}
{% block wiki_header_branding %}
<a class="navbar-brand" href="/">Your brand</a>
{% endblock %}
{% block wiki_header_navlinks %}
<ul class="nav navbar-nav">
<li class="active"><a href="{% url 'wiki:root' %}">Wiki</a></li>
</ul>
{% endblock %}
Site
----
You can override default django-wiki ``wiki.sites.site`` urls/views site implementation
with your own: override by setting the :attr:`~.WikiConfig.default_site` attribute
of a custom ``AppConfig`` to the dotted import path of either a ``WikiSite`` subclass
or a callable that returns a site instance.
.. code-block:: python
# myproject/sites.py
from wiki.sites import WikiSite
class MyWikiSite(admin.WikiSite):
...
.. code-block:: python
# myproject/apps.py
from wiki.apps import WikiConfig
class MyWikiConfig(WikiConfig):
default_site = 'myproject.sites.MyWikiSite'
.. code-block:: python
# myproject/settings.py
INSTALLED_APPS = [
...
'myproject.apps.MyWikiConfig', # replaces 'wiki.apps.WikiConfig'
...
]

View File

@@ -0,0 +1,14 @@
Setting up a development environment
====================================
* Fork and clone the ``django-wiki`` repo from Github, ``cd`` into it.
* Install `hatch <https://hatch.pypa.io/latest/install/>`_ with your favorite package manager.
* Inside ``django-wiki`` directory, initialize the environment::
$ hatch env create
* Launch a new shell session in order to activate the environment::
$ hatch shell
* And done, you can start developing in ``django-wiki``.

255
docs/development/hatch.rst Normal file
View File

@@ -0,0 +1,255 @@
pyproject.toml and hatch
========================
Initially, django-wiki core devs opted to use the
new ``pyproject.toml`` and drop the old ``setup.py`` (see
:url-issue:`1199`). The Python packaging ecosystem has
standardized on the interface for build backends
(`PEP 517 <https://peps.python.org/pep-0517/>`_/`PEP 660 <https://peps.python.org/pep-0660/>`_)
and the format for metadata declaration (`PEP 621 <https://peps.python.org/pep-0621/>`_/`PEP 631 <https://peps.python.org/pep-0631/>`_).
As a result, the execution of ``setup.py`` files is now `deprecated <https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html>`_.
The discussion for this feature and the steps to mark this as completed are
happening `in this discussion <https://github.com/django-wiki/django-wiki/discussions/1226>`_,
and as well the development process is `here <https://github.com/django-wiki/django-wiki/pull/1227>`_.
As a result of this work, the maintainers opted to use ``hatch`` to manage the
development process of django-wiki, you can read more about it in their
`official docs <https://hatch.pypa.io/latest/>`_.
Assuming you have installed ``hatch`` in your environment, the first thing that
you have to do in a fresh copy of ``django-wiki`` is to initilize the
environments, for that you have to execute ``hatch env create`` in the root of
``django-wiki`` codebase.
This will add a set of available commands, and different environment that are
used in the development process, here's a list generated with ``hatch env show``::
Standalone
+-----------+---------+---------------------------+-------------+
| Name | Type | Dependencies | Scripts |
+===========+=========+===========================+=============+
| default | virtual | black<22.11,>=22.3.0 | assets |
| | | codecov | clean-build |
| | | coverage[toml] | clean-pyc |
| | | ddt | cov |
| | | django-functest<1.6,>=1.2 | lint |
| | | flake8<5.1,>=3.7 | no-cov |
| | | pre-commit | test |
| | | pytest-cov | |
| | | pytest-django | |
| | | pytest-pythonpath | |
| | | pytest<7.3,>=6.2.5 | |
+-----------+---------+---------------------------+-------------+
| transifex | virtual | transifex-client | assets |
| | | | clean-build |
| | | | clean-pyc |
| | | | cov |
| | | | lint |
| | | | no-cov |
| | | | pull |
| | | | push |
| | | | test |
+-----------+---------+---------------------------+-------------+
| docs | virtual | bleach<5.1,>=3.3.0 | assets |
| | | django>=3.1.13 | build |
| | | sphinx-rtd-theme==1.1.1 | changes |
| | | sphinx>=3 | clean |
| | | | clean-build |
| | | | clean-pyc |
| | | | cov |
| | | | devhelp |
| | | | dirhtml |
| | | | doctest |
| | | | epub |
| | | | gettext |
| | | | html |
| | | | htmlhelp |
| | | | info |
| | | | json |
| | | | latex |
| | | | latexpdf |
| | | | link-check |
| | | | link-check2 |
| | | | lint |
| | | | man |
| | | | no-cov |
| | | | pickle |
| | | | qthelp |
| | | | singlehtml |
| | | | test |
| | | | texinfo |
| | | | text |
+-----------+---------+---------------------------+-------------+
Matrices
+------+---------+-------------------+---------------------------+-------------+
| Name | Type | Envs | Dependencies | Scripts |
+======+=========+===================+===========================+=============+
| test | virtual | test.py3.7-dj2.2 | black<22.11,>=22.3.0 | all |
| | | test.py3.7-dj3.0 | codecov | assets |
| | | test.py3.7-dj3.1 | coverage[toml] | clean |
| | | test.py3.7-dj3.2 | ddt | clean-build |
| | | test.py3.8-dj2.2 | django-functest<1.6,>=1.2 | clean-pyc |
| | | test.py3.8-dj3.0 | flake8<5.1,>=3.7 | cov |
| | | test.py3.8-dj3.1 | pre-commit | lint |
| | | test.py3.8-dj3.2 | pytest-cov | no-cov |
| | | test.py3.9-dj2.2 | pytest-django | test |
| | | test.py3.9-dj3.0 | pytest-pythonpath | |
| | | test.py3.9-dj3.1 | pytest<7.3,>=6.2.5 | |
| | | test.py3.9-dj3.2 | | |
| | | test.py3.10-dj3.2 | | |
| | | test.py3.8-dj4.0 | | |
| | | test.py3.9-dj4.0 | | |
| | | test.py3.10-dj4.0 | | |
+------+---------+-------------------+---------------------------+-------------+
We have 4 different environments declared in the configuration file, each one
has his own purpose:
* ``default``: The development environment for django-wiki.
* ``test``: where we ensure that the code works on different Django and Python versions.
* ``docs``: Used for generate the page you're reading at this moment.
* ``transifex``: Used only for the translation side of the project.
We center around the entrypoints provided by ``hatch`` (`read more <https://hatch.pypa.io/latest/environment/#scripts>`_)
that's why we have documented commands that make development easier.
Some commands are only available in certain environments,
so for example at the ``transifex`` environment you see ``pull`` and ``push``
commands that are not present in any other environment declared above. For
executing the command you have to follow this simple formula::
$ hatch run <environment name>:<command name>
Then applied to the ``push`` command on the ``transifex`` environment will be::
$ hatch run transifex:pull
You can use the same logic to execute the available commands in the app, but
heres a detailed list of the commands ordered by environments, so you can
understand the purpose of each one:
* ``cov``: Check coverage status.
* ``no-cov``: Check places pending to add coverage.
* ``lint``: Make sure the code changes follow our guidelines and conventions.
* ``clean-build``: Remove the files generated after the project is built.
* ``clean-pyc``: Remove pyc generated files.
* ``assets``: Generate the static files used by django-wiki frontend.
* ``test``: Test the changes in the current environment.
* ``test:all``: Test the changes across our supported Python and Django versions.
* ``test:lint``: Make sure the code changes follows our guidelines and conventions.
* ``test:clean``: Remove the files generated via the testing process.
* ``transifex:push``: Push the translation files to Transifex.
* ``transifex:pull``: Pull the translation files from Transifex.
* ``docs:clean``: Remove the generated documentation files.
* List of docs commands used to generate the documentation in different formats:
* Please refer to the `Builder documentation of SPHINX <https://www.sphinx-doc.org/en/master/usage/builders/index.html>`_
to understand more about the purpose of each builder and the expected output.
* ``docs:html``
* ``docs:dirhtml``
* ``docs:singlehtml``
* ``docs:pickle``
* ``docs:json``
* ``docs:htmlhelp``
* ``docs:qthelp``
* ``docs:devhelp``
* ``docs:epub``
* ``docs:latex``
* ``docs:latexpdf``
* ``docs:text``
* ``docs:man``
* ``docs:texinfo``
* ``docs:info``
* ``docs:gettext``
* ``docs:changes``
* ``docs:link-check2``
* ``docs:doctest``
* ``docs:build``: Generate the documentation in HTML format.
* ``docs:link-check``: Checks for external links across the documentation.
We hope that this document helps you to understand more about the development
process, if something is not clear please open an issue.
FAQ
---
1. **Whats the difference between test and test:all?**
When you execute ``hatch run test`` this will check your changes in the
active environment, this means it will run over an specific Python version
and an specific Django Version; in the other hand ``test:all`` will run the
test suite in the whole matrix of the supported versions of Python and Django.
2. **hatch is unable to create a test environment with an specific Python Version?**
If after you execute ``hatch env create`` you receive a message like this in
your terminal ``py3.8-4.0 -> cannot locate Python: 3.8`` this means that
``hatch`` was unable to locate that Python version, in the end it depends on
what program do you use for manage your Python version, the most
important part is that the versions must be available in your ``PATH``.
3. **How to manage different Python Versions?**
There's a lot of options outside, the most important piece is that as stated
above, the versions need to able to be located in your system ``PATH``. for
example, if you're a user of `pyenv <https://github.com/pyenv/pyenv>`_ you
can set multiple Python version using ``pyenv local <version> <version>``.
``pyenv local 3.7.12 3.8.12 3.9.13 3.10.2``
4. **There's an error when init an environment?**
If you see and error message like ``Environment default defines a matrix, choose one of the following instead:``
and then a list of all of the available environments, you need to set the
environment name on the shell command like this ``hatch -e <env_name> shell``
``hatch -e test.py3.10-dj3.2 shell``
This way you can switch environments by an specific Python and Django version.
5. **How do I switch default shell versions?**
By default django-wiki runs on the latest supported Python and Django
version, if you want to swich to another environment, say for example
Python 3.9.13 with Django 3.0 then execute the following command:
``hatch -e py3.9-dj3.0 shell``

146
docs/development/index.rst Normal file
View File

@@ -0,0 +1,146 @@
Developer guide
===============
.. toctree::
:maxdepth: 1
hatch
environment
testproject
testing
.. highlight:: shell
Types of Contributions
----------------------
Report Bugs
~~~~~~~~~~~
Report bugs at https://github.com/django-wiki/django-wiki/issues.
If you are reporting a bug, please include:
* Your operating system name and version.
* Any details about your local setup that might be helpful in troubleshooting.
* Detailed steps to reproduce the bug.
Fix Bugs
~~~~~~~~
Look through the GitHub issues for bugs. Anything tagged with "bug"
and "help wanted" is open to whoever wants to implement it.
Implement Features
~~~~~~~~~~~~~~~~~~
Look through the GitHub issues for features. Anything tagged with "enhancement"
and "help wanted" is open to whoever wants to implement it.
Write Documentation
~~~~~~~~~~~~~~~~~~~
Django-wiki could always use more documentation, whether as part of the
official django-wiki docs, in docstrings, or even on the web in blog posts,
articles, and such.
Submit Feedback
~~~~~~~~~~~~~~~
The best way to send feedback is to file an issue at https://github.com/django-wiki/django-wiki/issues.
If you are proposing a feature:
* Explain in detail how it would work.
* Keep the scope as narrow as possible, to make it easier to implement.
* Remember that this is a volunteer-driven project, and that contributions
are welcome :)
Get Started!
------------
Ready to contribute? Here's how to set up `django-wiki` for local development.
#. Fork the `django-wiki` repo on GitHub.
#. Clone your fork locally::
$ git clone git@github.com:your_name_here/django-wiki.git
#. Go to your fork and install ``hatch`` which is the tool we use manage django-wiki
#. Install your local copy into a new environment. Assuming you have ``hatch`` installed, this is how you set up your fork for local development::
$ cd django-wiki/
$ hatch env create
#. Create a branch for local development::
$ git checkout -b name-of-your-bugfix-or-feature
Now you can make your changes locally.
#. As you are making changes you may want to verify that changes are
passing all the relevant functional/unit tests::
$ hatch run test:all
#. If you made changes related to the style sheets (SCSS), you need to install `sassc <https://sass-lang.com/libsass>`__ (``sudo apt install sassc``) and run this to compile css::
$ hatch run assets
#. When you're done making changes, perform one final round of
testing, and also ensure relevant tests pass with all supported
Python versions with our matrix::
$ hatch run test
$ hatch run test:all # Runs all tests that pytest would run, just with various Python/Django combinations
#. Commit your changes and push your branch to GitHub::
$ git add .
$ git commit -m "Your detailed description of your changes."
$ git push origin name-of-your-bugfix-or-feature
#. Submit a pull request through the GitHub website.
Pull Request Guidelines
-----------------------
Before you submit a pull request, check that it meets these guidelines:
1. The pull request should include tests.
2. If the pull request adds functionality, the docs should be updated. Put
your new functionality into a function with a docstring, and add the
feature to the list in README.rst.
3. The pull request should work for Python 3.6, 3.7, 3.8 and for PyPy. Check
the status messages that are automatically generated for your pull request.
Tips
----
To run a subset of tests::
$ hatch run test:all tests/core/test_basic.py # All tests from a single file.
$ hatch run test:all tests/core/test_basic.py::URLPathTests # All tests from a single class.
$ hatch run test:all tests/core/test_basic.py::URLPathTests::test_manager # Just one test.
Roadmap
-------
The best way to contribute is to use our Github issue list to look
at current wishes. The list is found here:
https://github.com/django-wiki/django-wiki/issues/
If you want to add a feature, consider writing a plugin. Please create an
issue to discuss whether your plugin idea is a core plugin
(``wiki.plugins.*``) or external plugin. If there are additions needed
to the plugin API, we can discuss that as well! A discussion is always welcome
in a Github issue.
Generally speaking, we need more **unit tests** to improve coverage, and new
features will not be accepted without tests. To add more stuff to the project
without tests wouldn't be fair to the project or your hard work. We use coverage
metrics to see that each new contribution does not significantly impact test
coverage.

View File

@@ -0,0 +1,62 @@
Tests
=====
Running tests
-------------
To run django-wiki's tests, you need to have installed ``hatch`` (read
more about it `here <https://hatch.pypa.io/latest/install/>`_) once installed
you can execute ``hatch run test:all`` to test your changes across our matrix.
To run **specific tests**, see ``hatch run test:all --help``.
To include Selenium tests, you need to have ``Xvfb`` installed
(usually via system-provided package manager), `chromedriver
<https://sites.google.com/a/chromium.org/chromedriver/>`_ and set the
environment variable ``INCLUDE_SELENIUM_TESTS=1``. For example, run
tests with (depending on whether you want to test directly or via
the test matrix)::
INCLUDE_SELENIUM_TESTS=1 hatch run test
INCLUDE_SELENIUM_TESTS=1 hatch run test:all
If you wish to also show the browser window while running the
functional tests, set the environment variable
``SELENIUM_SHOW_BROWSER=1`` in *addition* to
``INCLUDE_SELENIUM_TESTS=1``, for example::
INCLUDE_SELENIUM_TESTS=1 SELENIUM_SHOW_BROWSER=1 hatch run test:all
Writing tests
-------------
Tests generally fall into a few categories:
* Testing at the model level. These test cases should inherit from
``tests.base.TestBase``.
* Tests for views that return HTML. We normally use `django-functest
<http://django-functest.readthedocs.io/en/latest/>`_ for these, especially if
the page involves forms and handling of POST data. Test cases should inherit
from ``tests.base.WebTestBase`` and ``tests.base.SeleniumBase`` - see
``tests.core.test_views.RootArticleViewTestsBase``,
``RootArticleViewTestsWebTest`` and ``RootArticleViewTestsSelenium`` for an
example.
(In the past the Django test Client was used for these, and currently there
are still a lot of tests written in this style. These should be gradually
phased out where possible, because the test Client does a poor job of
replicating what browsers and people actually do.
* Tests for views that return JSON or other non-HTML. These test cases
should inherit from ``tests.base.DjangoClientTestBase``.
There are also other mixins in ``tests.base`` that provide commonly used
fixtures for tests e.g. a root article.
.. warning::
Views should be written so that as far as possible they work without
Javascript, and can be tested using the fast WebTest method, rather than
relying on the slow and fragile Selenium method. Selenium tests are not run by
default.

View File

@@ -0,0 +1,10 @@
Running the test project
========================
In order to quickly get setup, there is a project in the git repository.
The folder **testproject/** contains a pre-configured django project and
an sqlite database. Login for django admin is ``admin:admin``. This
project should always be maintained, but please do not commit changes to
the SQLite database as we only care about its contents in case data
models are changed.

28
docs/index.rst Normal file
View File

@@ -0,0 +1,28 @@
.. django-wiki documentation master file, created by
sphinx-quickstart on Mon Jul 23 16:13:51 2012.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
django-wiki documentation
=========================
.. toctree::
:name: mastertoc
:maxdepth: 1
installation
release_notes
plugins
customization
settings
development/index
tips/index
.. include:: ../README.rst
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

196
docs/installation.rst Normal file
View File

@@ -0,0 +1,196 @@
Installation
============
django-wiki is an application for Django.
This means that you need to setup a basic Django project in order to use django-wiki.
.. seealso::
Read more about setting up your first Django project in the
`official Django tutorial <https://docs.djangoproject.com/en/stable/intro/tutorial01/>`__.
Pre-requisite: Pillow
---------------------
For image processing, django-wiki uses the `Pillow
library <https://github.com/python-pillow/Pillow>`_ (a fork of PIL).
The preferred method should be to get a system-wide, pre-compiled
version of Pillow, for instance by getting the binaries from your Linux
distribution repos.
Debian/Ubuntu
~~~~~~~~~~~~~
You need to get development libraries which Pip needs for compiling::
sudo apt-get install libjpeg8 libjpeg-dev libpng12-0 libpng12-dev
After that, install with ``sudo pip install Pillow``. You might as well
install Pillow system-wide, because there are little version-specific
dependencies in Django applications when it comes to Pillow, and having
multiple installations of the very same package is a bad practice in
this case.
Mac OS X 10.5+
~~~~~~~~~~~~~~
`Ethan
Tira-Thompson <http://ethan.tira-thompson.com/Mac_OS_X_Ports.html>`_ has
created ports for OS X and made them available as a .dmg installer.
Download and install the universal combo package
`here <http://ethan.tira-thompson.com/Mac_OS_X_Ports_files/libjpeg-libpng%20%28universal%29.dmg>`_.
Once you have the packages installed, you can proceed to the pip
installation. PIL will automatically pick up these libraries and compile
them for django use.
Installing
----------
To install the latest stable release::
pip install wiki
Install the latest pre-release (alpha, beta or rc)::
pip install --pre wiki
Upgrading
---------
Always read the :doc:`release_notes` for instructions on upgrading.
Configuration
-------------
Configure ``settings.INSTALLED_APPS``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The following applications should be listed - NB! it's important to
maintain the order due to database relational constraints:
.. code-block:: python
'django.contrib.sites.apps.SitesConfig',
'django.contrib.humanize.apps.HumanizeConfig',
'django_nyt.apps.DjangoNytConfig',
'mptt',
'sekizai',
'sorl.thumbnail',
'wiki.apps.WikiConfig',
'wiki.plugins.attachments.apps.AttachmentsConfig',
'wiki.plugins.notifications.apps.NotificationsConfig',
'wiki.plugins.images.apps.ImagesConfig',
'wiki.plugins.macros.apps.MacrosConfig',
Configure ``context_processors``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``django-wiki`` uses the `Django Templates` backend.
Add ``'sekizai.context_processors.sekizai'`` and ``'django.template.context_processors.debug'`` to
``context_processors`` section of your template backend settings.
Please refer to the `Django templates docs <https://docs.djangoproject.com/en/stable/topics/templates/#django.template.backends.django.DjangoTemplates/>`_
to see the current default setting for this variable.
.. code-block:: python
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'APP_DIRS': True,
# ...
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.request',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
"sekizai.context_processors.sekizai",
],
},
},
]
Database
~~~~~~~~
To sync and create tables, do:
::
python manage.py migrate
Set ``SITE_ID``
~~~~~~~~~~~~~~~
If you're working with fresh Django installation, you need to set the SITE_ID
.. code-block:: python
SITE_ID = 1
User account handling
~~~~~~~~~~~~~~~~~~~~~
There is a limited account handling included to allow users to sign up. Its
settings are shown below with their default values. To switch off account
handling entirely, set ``WIKI_ACCOUNT_HANDLING = False``.
.. code-block:: python
WIKI_ACCOUNT_HANDLING = True
WIKI_ACCOUNT_SIGNUP_ALLOWED = True
After a user is logged in, they will be redirected to the value of
``LOGIN_REDIRECT_URL``, which you can configure in your project's settings.py to
point to the root article:
.. code-block:: python
from django.urls import reverse_lazy
LOGIN_REDIRECT_URL = reverse_lazy('wiki:get', kwargs={'path': ''})
Include urlpatterns
~~~~~~~~~~~~~~~~~~~
To integrate the wiki in your existing application, you should ensure the
following lines are included in your project's ``urls.py``.
.. code-block:: python
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('notifications/', include('django_nyt.urls')),
path('', include('wiki.urls'))
]
The above line puts the wiki in */* so it's important to put it at the
end of your urlconf. You can also put it in */wiki* by putting
``'^wiki/'`` as the pattern.
.. note::
If you are running ``manage.py runserver``, you need to have static files
and media files from ``STATIC_ROOT`` and ``MEDIA_ROOT`` served by the
development server. ``STATIC_ROOT`` is automatically served, but you have
to add ``MEDIA_ROOT`` manually::
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Please refer to
`the Django docs <https://docs.djangoproject.com/en/stable/howto/static-files/#serving-files-uploaded-by-a-user-during-development>`__.

18
docs/plugins.rst Normal file
View File

@@ -0,0 +1,18 @@
Plugins
=======
Add/remove the following to your ``settings.INSTALLED_APPS`` to
enable/disable the core plugins:
- ``'wiki.plugins.attachments.apps.AttachmentsConfig'``
- ``'wiki.plugins.editsection.apps.EditSectionConfig'``
- ``'wiki.plugins.globalhistory.apps.GlobalHistoryConfig'``
- ``'wiki.plugins.help.apps.HelpConfig'``
- ``'wiki.plugins.images.apps.ImagesConfig'``
- ``'wiki.plugins.links.apps.LinksConfig'``
- ``'wiki.plugins.macros.apps.MacrosConfig'``
- ``'wiki.plugins.notifications.apps.NotificationsConfig'``
The notifications plugin is mandatory for an out-of-the-box installation. You
can safely remove it from ``INSTALLED_APPS`` if you also override the
**wiki/base.html** template.

1084
docs/release_notes.rst Normal file

File diff suppressed because it is too large Load Diff

41
docs/settings.rst Normal file
View File

@@ -0,0 +1,41 @@
Settings
========
The following settings are available for configuration through your project.
All settings are customized by prefixing ``WIKI_``, so for instance
``URL_CASE_SENSITIVE`` should be configured as ``WIKI_URL_CASE_SENSITIVE``.
For plugins the prefix is ``WIKI_PLUGINNAME_``, e.g. ``WIKI_IMAGES`` for the
images plugin.
.. automodule:: wiki.conf.settings
:members:
Plugin attachments
------------------
.. automodule:: wiki.plugins.attachments.settings
:members:
Plugin editsection
------------------
.. automodule:: wiki.plugins.editsection.settings
:members:
Plugin images
-------------
.. automodule:: wiki.plugins.images.settings
:members:
Plugin links
------------
.. automodule:: wiki.plugins.links.settings
:members:
Plugin macros
-------------
.. automodule:: wiki.plugins.macros.settings
:members:

39
docs/tips/disqus.rst Normal file
View File

@@ -0,0 +1,39 @@
Disqus comment embed
====================
This page describes how to embed the Disqus_ comment system on each wiki page.
Put the following as ``wiki/base.html`` somewhere in your
``TEMPLATE_DIRS``:
.. code-block:: html+django
{% extends "wiki/base_site.html" %}
{% load sekizai_tags %}
{% block wiki_body %}
{{ block.super }}
{% block wiki_footer_logo %}
{% endblock wiki_footer_logo %}
{% if selected_tab == 'view' %}
{% addtoblock "js" %}
<script type="text/javascript">
(function(){
$("#wiki-footer p").eq(0).after('<div id="disqus_thread"></div>')
})();
var disqus_shortname = 'your_disqus_shortname';
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
{% endaddtoblock %}
{% endif %}
{% endblock wiki_body %}
Replace ``your_disqus_sortname`` with your disqus sortname.
See also in :doc:`/customization`.
.. _Disqus: https://disqus.com/

32
docs/tips/faq.rst Normal file
View File

@@ -0,0 +1,32 @@
FAQ
===
Q: Why can't I move articles?
-----------------------------
A: Moving articles is not trivial. Here are a couple of reasons:
* Other articles may link to them.
* Permissions may change if you move the articles into a different hierarchy
* We keep revisions of stuff, so the action of moving an article will create a new revision.
* ...but what if the revision is reverted and we had automatically renamed stuff?
Because it isn't trivial to move articles, the work has delayed somewhat.
Resources:
* `Pull Request #461 <https://github.com/django-wiki/django-wiki/pull/461>`__
* `Issue #154 <https://github.com/django-wiki/django-wiki/issues/154>`__
Q: Why do I keep getting *"This slug conflicts with an existing URL."*
----------------------------------------------------------------------
A: When validating a slug, django-wiki will verify through
:doc:`../settings`.``WIKI_CHECK_SLUG_URL_AVAILABLE`` (default: ``True``) that the URL is not
already occupied.
So if you keep getting an error that the "slug" isn't available, it's
probably because you left another URL pattern interfearing with django-wiki's
by letting your pattern (regexp) be too open. Forgetting a closing
``$`` is a common mistake.

38
docs/tips/index.rst Normal file
View File

@@ -0,0 +1,38 @@
Tips & FAQ
==========
.. toctree::
:caption: Tips index
faq
disqus
mediawiki
Quick tips
----------
1. **Account handling:** There are simple views that handle login,
logout and signup. They are on by default. Make sure to set
``settings.LOGIN_URL`` to point to your login page as many wiki views
may redirect to a login page.
2. **Syntax highlighting:** Python-Markdown has a pre-shipped codehilite
extension which works perfectly, so add something like::
WIKI_MARKDOWN_KWARGS = {
'extensions': [
'footnotes',
'attr_list',
'headerid',
'extra',
'codehilite',
]
}
to your settings. Currently, django-wiki ships with a stylesheet
that already has the syntax highlighting CSS rules built-in. Oh, and
you need to ensure ``pip install pygments`` because Pygments is what
the codehilite extension is using!
3. **Project Templates:** Create new django-wiki projects quickly and easily using django-wiki project templates
https://github.com/django-wiki/django-wiki-project-template

150
docs/tips/mediawiki.rst Normal file
View File

@@ -0,0 +1,150 @@
Mediawiki
=========
If you want to import articles from Mediawiki, you can create an XML dump of the pages and then use
a Django management command to import it.
The management command is not provided as part of django-wiki, but we'll show you how to build one for your own Django app.
In the management command, we are going to use the lxml library to parse the MediaWiki XML
and the unidecode to convert non-latin characters to ascii (so as to create their slug). Finally it
uses pandoc to do conversion from MediaWiki markup to GitHub Flavored Markdown (which in this case renders fine in django-wiki).
For the lxml and unidecode you can install them with ``pip install lxml unidecode`` and for pandoc you can
download it from https://pandoc.org/installing.html (make sure the pandoc binary is in your PATH).
The following snippet of code should be placed in ``<your-app>/management/commands/import_mediawiki_dump.py``:
.. code-block:: python
from django.core.management.base import BaseCommand
from wiki.models.article import ArticleRevision, Article
from wiki.models.urlpath import URLPath
from django.contrib.sites.models import Site
from django.template.defaultfilters import slugify
import unidecode
from django.contrib.auth import get_user_model
import datetime
import pytz
from django.db import transaction
import subprocess
from lxml import etree
def slugify2(s):
return slugify(unidecode.unidecode(s))
def convert_to_markdown(text):
proc = subprocess.Popen(
["pandoc", "-f", "mediawiki", "-t", "gfm"],
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
)
proc.stdin.write(text.encode("utf-8"))
proc.stdin.close()
return proc.stdout.read().decode("utf-8")
def create_article(title, text, timestamp, user):
text_ok = (
text.replace("__NOEDITSECTION__", "")
.replace("__NOTOC__", "")
.replace("__TOC__", "")
)
text_ok = convert_to_markdown(text_ok)
article = Article()
article_revision = ArticleRevision()
article_revision.content = text_ok
article_revision.title = title
article_revision.user = user
article_revision.owner = user
article_revision.created = timestamp
article.add_revision(article_revision, save=True)
article_revision.save()
article.save()
return article
def create_article_url(article, slug, current_site, url_root):
upath = URLPath.objects.create(
site=current_site, parent=url_root, slug=slug, article=article
)
article.add_object_relation(upath)
def import_page(current_site, url_root, text, title, timestamp, replace_existing, user):
slug = slugify2(title)
try:
urlp = URLPath.objects.get(slug=slug)
if not replace_existing:
print("\tAlready existing, skipping...")
return
print("\tDestorying old version of the article")
urlp.article.delete()
except URLPath.DoesNotExist:
pass
article = create_article(title, text, timestamp, user)
create_article_url(article, slug, current_site, url_root)
class Command(BaseCommand):
help = "Import everything from a MediaWiki XML dump file. Only the latest version of each page is imported."
args = ""
def add_arguments(self, parser):
parser.add_argument("file", type=str)
@transaction.atomic()
def handle(self, *args, **options):
user = get_user_model().objects.get(username="root")
current_site = Site.objects.get_current()
url_root = URLPath.root()
tree = etree.parse(options["file"])
pages = tree.xpath('// *[local-name()="page"]')
for p in pages:
title = p.xpath('*[local-name()="title"]')[0].text
print(title)
revision = p.xpath('*[local-name()="revision"]')[0]
text = revision.xpath('*[local-name()="text"]')[-1].text
timestamp = revision.xpath('*[local-name()="timestamp"]')[0].text
timestamp = datetime.datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%SZ")
timestamp_with_timezone = pytz.utc.localize(timestamp)
import_page(
current_site,
url_root,
text,
title,
timestamp_with_timezone,
True,
user,
)
Usage
-----
Once the management command is provided by your Django application, you can invoke it from the command-line:
.. code-block:: console
python manage.py import_mediawiki_dump <mediawiki-xml-dump-file>``
Further work and customizing
----------------------------
Please note the following:
- The script defines a ``root`` user to assign the owner of the imported pages (you can leave that as None or add your own user).
- Multiple revisions of each page have not been implemented. Instead, the script tries to pick the text of the latest one (``text = revision.xpath('*[local-name()="text"]')[-1].text``). Because of this, it's recommended to only include the latest revision of each article on your MediaWiki dump.
- You can pass ``True`` or ``False`` to ``import_page()`` in order to replace or skip existing pages.