diff --git a/docs/document.rst b/docs/document.rst
index 7207e357c..990bbe8a7 100644
--- a/docs/document.rst
+++ b/docs/document.rst
@@ -4,42 +4,26 @@ Document
=========
This project uses Sphinx_ documentation generator.
-After you have set up to `develop locally`_, run the following commands to generate the HTML documentation: ::
- $ sphinx-build docs/ docs/_build/html/
+After you have set up to `develop locally`_, run the following command from the project directory to build and serve HTML documentation: ::
+
+ $ make -C docs livehtml
If you set up your project to `develop locally with docker`_, run the following command: ::
- $ docker-compose -f local.yml run --rm django sphinx-build docs/ docs/_build/html/
+ $ docker-compose -f local.yml up docs
+
+Navigate to port 7000 on your host to see the documentation. This will be opened automatically at `localhost`_ for local, non-docker development.
Generate API documentation
----------------------------
-Sphinx can automatically generate documentation from docstrings, to enable this feature, follow these steps:
+Edit the docs/_source files and project application docstrings to create your documentation.
-1. Add Sphinx extension in ``docs/conf.py`` file, like below: ::
-
- extensions = [
- 'sphinx.ext.autodoc',
- ]
-
-2. Uncomment the following lines in the ``docs/conf.py`` file: ::
-
- # import django
- # sys.path.insert(0, os.path.abspath('..'))
- # os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
- # django.setup()
-
-3. Run the following command: ::
-
- $ sphinx-apidoc -f -o ./docs/modules/ ./tpub/ migrations/*
-
- If you set up your project to `develop locally with docker`_, run the following command: ::
-
- $ docker-compose -f local.yml run --rm django sphinx-apidoc -f -o ./docs/modules ./tpub/ migrations/*
-
-4. Regenerate HTML documentation as written above.
+Sphinx can automatically include class and function signatures and docstrings in generated documentation.
+See the generated project documentation for more examples.
+.. _localhost: http://localhost:7000/
.. _Sphinx: https://www.sphinx-doc.org/en/master/index.html
.. _develop locally: ./developing-locally.html
.. _develop locally with docker: ./developing-locally-docker.html
diff --git a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile
new file mode 100644
index 000000000..7736777b3
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile
@@ -0,0 +1,29 @@
+FROM python:3.8-slim-buster
+
+ENV PYTHONUNBUFFERED 1
+ENV PYTHONDONTWRITEBYTECODE 1
+
+RUN apt-get update \
+ # dependencies for building Python packages
+ && apt-get install -y build-essential \
+ # psycopg2 dependencies
+ && apt-get install -y libpq-dev \
+ # Translations dependencies
+ && apt-get install -y gettext \
+ # Uncomment below lines to enable Sphinx output to latex and pdf
+ # && apt-get install -y texlive-latex-recommended \
+ # && apt-get install -y texlive-fonts-recommended \
+ # && apt-get install -y texlive-latex-extra \
+ # && apt-get install -y latexmk \
+ # cleaning up unused files
+ && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
+ && rm -rf /var/lib/apt/lists/*
+
+# Requirements are installed here to ensure they will be cached.
+COPY ./requirements /requirements
+# All imports needed for autodoc.
+RUN pip install -r /requirements/local.txt -r /requirements/production.txt
+
+WORKDIR /docs
+
+CMD make livehtml
diff --git a/{{cookiecutter.project_slug}}/docs/Makefile b/{{cookiecutter.project_slug}}/docs/Makefile
index d4bb2cbb9..90f61de32 100644
--- a/{{cookiecutter.project_slug}}/docs/Makefile
+++ b/{{cookiecutter.project_slug}}/docs/Makefile
@@ -3,18 +3,38 @@
# You can set these variables from the command line, and also
# from the environment for the first two.
-SPHINXOPTS ?=
-SPHINXBUILD ?= sphinx-build
-SOURCEDIR = .
-BUILDDIR = _build
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build -c .
+SOURCEDIR = ./_source
+BUILDDIR = ./_build
+{%- if cookiecutter.use_docker == 'y' %}
+APP = /app
+{%- else %}
+APP = ../{{cookiecutter.project_slug}}
+{% endif %}
+
+.PHONY: help livehtml apidocs Makefile
# Put it first so that "make" without argument is like "make help".
help:
- @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+ @$(SPHINXBUILD) help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-.PHONY: help Makefile
+# Build, watch and serve docs with live reload
+livehtml:
+ sphinx-autobuild -b html
+ {%- if cookiecutter.use_docker == 'y' %} -H 0.0.0.0
+ {%- else %} --open-browser
+ {%- endif %} -p 7000 --watch $(APP) -c . $(SOURCEDIR) $(BUILDDIR)/html
+
+# Outputs rst files from django application code
+apidocs:
+ {%- if cookiecutter.use_docker == 'y' %}
+ sphinx-apidoc -o $(SOURCEDIR)/api /app
+ {%- else %}
+ sphinx-apidoc -o $(SOURCEDIR)/api ../{{cookiecutter.project_slug}}
+ {%- endif %}
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
- @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+ @$(SPHINXBUILD) -b $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/{{cookiecutter.project_slug}}/docs/_source/howto.rst b/{{cookiecutter.project_slug}}/docs/_source/howto.rst
new file mode 100644
index 000000000..25f442c37
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/docs/_source/howto.rst
@@ -0,0 +1,46 @@
+How To - Project Documentation
+======================================================================
+
+Get Started
+----------------------------------------------------------------------
+
+Documentation can be written as rst files in the `{{cookiecutter.project_slug}}/docs/_source`.
+
+{% if cookiecutter.use_docker == 'n' %}
+To build and serve docs, use the command:
+ ::
+
+ make livehtml
+
+from inside the `{{cookiecutter.project_slug}}/docs` directory.
+{% else %}
+To build and serve docs, use the commands:
+ ::
+
+ docker-compose -f local.yml up docs
+{% endif %}
+
+Changes to files in `docs/_source` will be picked up and reloaded automatically.
+
+`Sphinx `_ is the tool used to build documentation.
+
+Docstrings to Documentation
+----------------------------------------------------------------------
+
+The sphinx extension `apidoc `_ is used to automatically document code using signatures and docstrings.
+
+Numpy or Google style docstrings will be picked up from project files and availble for documentation. See the `Napoleon `_ extension for details.
+
+For an in-use example, see the `page source <_sources/users.rst.txt>`_ for :ref:`users`.
+
+To compile all docstrings automatically into documentation source files, use the command:
+ ::
+
+ make apidocs
+
+{% if cookiecutter.use_docker == 'y' %}
+This can be done in the docker container:
+ ::
+
+ docker run --rm docs make apidocs
+{% endif -%}
diff --git a/{{cookiecutter.project_slug}}/docs/index.rst b/{{cookiecutter.project_slug}}/docs/_source/index.rst
similarity index 96%
rename from {{cookiecutter.project_slug}}/docs/index.rst
rename to {{cookiecutter.project_slug}}/docs/_source/index.rst
index b107a9e5c..5fafc6966 100644
--- a/{{cookiecutter.project_slug}}/docs/index.rst
+++ b/{{cookiecutter.project_slug}}/docs/_source/index.rst
@@ -10,7 +10,9 @@ Welcome to {{ cookiecutter.project_name }}'s documentation!
:maxdepth: 2
:caption: Contents:
+ howto
pycharm/configuration
+ users
diff --git a/{{cookiecutter.project_slug}}/docs/pycharm/configuration.rst b/{{cookiecutter.project_slug}}/docs/_source/pycharm/configuration.rst
similarity index 100%
rename from {{cookiecutter.project_slug}}/docs/pycharm/configuration.rst
rename to {{cookiecutter.project_slug}}/docs/_source/pycharm/configuration.rst
diff --git a/{{cookiecutter.project_slug}}/docs/pycharm/images/1.png b/{{cookiecutter.project_slug}}/docs/_source/pycharm/images/1.png
similarity index 100%
rename from {{cookiecutter.project_slug}}/docs/pycharm/images/1.png
rename to {{cookiecutter.project_slug}}/docs/_source/pycharm/images/1.png
diff --git a/{{cookiecutter.project_slug}}/docs/pycharm/images/2.png b/{{cookiecutter.project_slug}}/docs/_source/pycharm/images/2.png
similarity index 100%
rename from {{cookiecutter.project_slug}}/docs/pycharm/images/2.png
rename to {{cookiecutter.project_slug}}/docs/_source/pycharm/images/2.png
diff --git a/{{cookiecutter.project_slug}}/docs/pycharm/images/3.png b/{{cookiecutter.project_slug}}/docs/_source/pycharm/images/3.png
similarity index 100%
rename from {{cookiecutter.project_slug}}/docs/pycharm/images/3.png
rename to {{cookiecutter.project_slug}}/docs/_source/pycharm/images/3.png
diff --git a/{{cookiecutter.project_slug}}/docs/pycharm/images/4.png b/{{cookiecutter.project_slug}}/docs/_source/pycharm/images/4.png
similarity index 100%
rename from {{cookiecutter.project_slug}}/docs/pycharm/images/4.png
rename to {{cookiecutter.project_slug}}/docs/_source/pycharm/images/4.png
diff --git a/{{cookiecutter.project_slug}}/docs/pycharm/images/7.png b/{{cookiecutter.project_slug}}/docs/_source/pycharm/images/7.png
similarity index 100%
rename from {{cookiecutter.project_slug}}/docs/pycharm/images/7.png
rename to {{cookiecutter.project_slug}}/docs/_source/pycharm/images/7.png
diff --git a/{{cookiecutter.project_slug}}/docs/pycharm/images/8.png b/{{cookiecutter.project_slug}}/docs/_source/pycharm/images/8.png
similarity index 100%
rename from {{cookiecutter.project_slug}}/docs/pycharm/images/8.png
rename to {{cookiecutter.project_slug}}/docs/_source/pycharm/images/8.png
diff --git a/{{cookiecutter.project_slug}}/docs/pycharm/images/f1.png b/{{cookiecutter.project_slug}}/docs/_source/pycharm/images/f1.png
similarity index 100%
rename from {{cookiecutter.project_slug}}/docs/pycharm/images/f1.png
rename to {{cookiecutter.project_slug}}/docs/_source/pycharm/images/f1.png
diff --git a/{{cookiecutter.project_slug}}/docs/pycharm/images/f2.png b/{{cookiecutter.project_slug}}/docs/_source/pycharm/images/f2.png
similarity index 100%
rename from {{cookiecutter.project_slug}}/docs/pycharm/images/f2.png
rename to {{cookiecutter.project_slug}}/docs/_source/pycharm/images/f2.png
diff --git a/{{cookiecutter.project_slug}}/docs/pycharm/images/f3.png b/{{cookiecutter.project_slug}}/docs/_source/pycharm/images/f3.png
similarity index 100%
rename from {{cookiecutter.project_slug}}/docs/pycharm/images/f3.png
rename to {{cookiecutter.project_slug}}/docs/_source/pycharm/images/f3.png
diff --git a/{{cookiecutter.project_slug}}/docs/pycharm/images/f4.png b/{{cookiecutter.project_slug}}/docs/_source/pycharm/images/f4.png
similarity index 100%
rename from {{cookiecutter.project_slug}}/docs/pycharm/images/f4.png
rename to {{cookiecutter.project_slug}}/docs/_source/pycharm/images/f4.png
diff --git a/{{cookiecutter.project_slug}}/docs/pycharm/images/issue1.png b/{{cookiecutter.project_slug}}/docs/_source/pycharm/images/issue1.png
similarity index 100%
rename from {{cookiecutter.project_slug}}/docs/pycharm/images/issue1.png
rename to {{cookiecutter.project_slug}}/docs/_source/pycharm/images/issue1.png
diff --git a/{{cookiecutter.project_slug}}/docs/pycharm/images/issue2.png b/{{cookiecutter.project_slug}}/docs/_source/pycharm/images/issue2.png
similarity index 100%
rename from {{cookiecutter.project_slug}}/docs/pycharm/images/issue2.png
rename to {{cookiecutter.project_slug}}/docs/_source/pycharm/images/issue2.png
diff --git a/{{cookiecutter.project_slug}}/docs/_source/users.rst b/{{cookiecutter.project_slug}}/docs/_source/users.rst
new file mode 100644
index 000000000..6cf645562
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/docs/_source/users.rst
@@ -0,0 +1,15 @@
+ .. _users:
+
+Users
+======================================================================
+
+Starting a new project, it’s highly recommended to set up a custom user model,
+even if the default User model is sufficient for you.
+
+This model behaves identically to the default user model,
+but you’ll be able to customize it in the future if the need arises.
+
+.. automodule:: {{cookiecutter.project_slug}}.users.models
+ :members:
+ :noindex:
+
diff --git a/{{cookiecutter.project_slug}}/docs/conf.py b/{{cookiecutter.project_slug}}/docs/conf.py
index bfde1e3a6..691f351e5 100644
--- a/{{cookiecutter.project_slug}}/docs/conf.py
+++ b/{{cookiecutter.project_slug}}/docs/conf.py
@@ -9,15 +9,19 @@
# 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.
-#
+
import os
import sys
+import django
-# import django
-# sys.path.insert(0, os.path.abspath('..'))
-# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
-# django.setup()
-
+{% if cookiecutter.use_docker == 'y' %}
+sys.path.insert(0, os.path.abspath("/app"))
+os.environ.setdefault("DATABASE_URL", "")
+{% else %}
+sys.path.insert(0, os.path.abspath(".."))
+{%- endif %}
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
+django.setup()
# -- Project information -----------------------------------------------------
@@ -31,17 +35,19 @@ author = "{{ cookiecutter.author_name }}"
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
-extensions = []
+extensions = [
+ "sphinx.ext.autodoc",
+ "sphinx.ext.napoleon",
+]
# Add any paths that contain templates here, relative to this directory.
-templates_path = ["_templates"]
+# templates_path = ["_templates"]
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
-
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
@@ -52,4 +58,4 @@ html_theme = "alabaster"
# 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 = ["_static"]
+# html_static_path = ["_static"]
diff --git a/{{cookiecutter.project_slug}}/docs/make.bat b/{{cookiecutter.project_slug}}/docs/make.bat
index 922152e96..b19f42c6a 100644
--- a/{{cookiecutter.project_slug}}/docs/make.bat
+++ b/{{cookiecutter.project_slug}}/docs/make.bat
@@ -4,11 +4,13 @@ pushd %~dp0
REM Command file for Sphinx documentation
+
if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=sphinx-build
+ set SPHINXBUILD=sphinx-build -c .
)
-set SOURCEDIR=.
+set SOURCEDIR=_source
set BUILDDIR=_build
+set APP=..\{{cookiecutter.project_slug}}
if "%1" == "" goto help
@@ -20,16 +22,25 @@ if errorlevel 9009 (
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
+ echo.Install sphinx-autobuild for live serving.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
-%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+%SPHINXBUILD% -b %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
+:livehtml
+sphinx-autobuild -b html --open-browser -p 7000 --watch %APP% -c . %SOURCEDIR% %BUILDDIR%/html
+GOTO :EOF
+
+:apidocs
+sphinx-apidoc -o %SOURCEDIR%/api %APP%
+GOTO :EOF
+
:help
-%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+%SPHINXBUILD% -b help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
diff --git a/{{cookiecutter.project_slug}}/local.yml b/{{cookiecutter.project_slug}}/local.yml
index b603f1778..528e59b2c 100644
--- a/{{cookiecutter.project_slug}}/local.yml
+++ b/{{cookiecutter.project_slug}}/local.yml
@@ -36,6 +36,22 @@ services:
- local_postgres_data_backups:/backups
env_file:
- ./.envs/.local/.postgres
+
+ docs:
+ image: {{ cookiecutter.project_slug }}_local_docs
+ container_name: docs
+ build:
+ context: .
+ dockerfile: ./compose/local/docs/Dockerfile
+ env_file:
+ - ./.envs/.local/.django
+ volumes:
+ - ./docs:/docs
+ - ./config:/app/config
+ - ./{{ cookiecutter.project_slug }}:/app/{{ cookiecutter.project_slug }}
+ ports:
+ - "7000:7000"
+
{%- if cookiecutter.use_mailhog == 'y' %}
mailhog:
diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt
index 6db3546e8..9c41385ad 100644
--- a/{{cookiecutter.project_slug}}/requirements/local.txt
+++ b/{{cookiecutter.project_slug}}/requirements/local.txt
@@ -2,7 +2,6 @@
Werkzeug==1.0.1 # https://github.com/pallets/werkzeug
ipdb==0.13.3 # https://github.com/gotcha/ipdb
-Sphinx==3.1.1 # https://github.com/sphinx-doc/sphinx
{%- if cookiecutter.use_docker == 'y' %}
psycopg2==2.8.5 --no-binary psycopg2 # https://github.com/psycopg/psycopg2
{%- else %}
@@ -19,6 +18,11 @@ django-stubs==1.5.0 # https://github.com/typeddjango/django-stubs
pytest==5.4.3 # https://github.com/pytest-dev/pytest
pytest-sugar==0.9.3 # https://github.com/Frozenball/pytest-sugar
+# Documentation
+# ------------------------------------------------------------------------------
+sphinx==3.1.1 # https://github.com/sphinx-doc/sphinx
+sphinx-autobuild # https://github.com/GaretJax/sphinx-autobuild
+
# Code quality
# ------------------------------------------------------------------------------
flake8==3.8.3 # https://github.com/PyCQA/flake8
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py
index 57b201cc2..70efdfdec 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py
@@ -5,10 +5,17 @@ from django.utils.translation import gettext_lazy as _
class User(AbstractUser):
+ """Default user for {{cookiecutter.project_name}}.
+ """
- # First Name and Last Name do not cover name patterns
- # around the globe.
+ #: First and last name do not cover name patterns around the globe
name = CharField(_("Name of User"), blank=True, max_length=255)
def get_absolute_url(self):
+ """Get url for user's detail view.
+
+ Returns:
+ str: URL for user detail.
+
+ """
return reverse("users:detail", kwargs={"username": self.username})