├── faq
├── views
│ ├── __init__.py
│ ├── deep.py
│ ├── normal.py
│ └── shallow.py
├── templates
│ ├── search
│ │ └── indexes
│ │ │ └── faq
│ │ │ ├── question_text.txt
│ │ │ └── topic_text.txt
│ └── faq
│ │ ├── base.html
│ │ ├── question_detail.html
│ │ ├── topic_detail.html
│ │ └── topic_list.html
├── locale
│ ├── en
│ │ └── LC_MESSAGES
│ │ │ ├── django.mo
│ │ │ └── django.po
│ └── es
│ │ └── LC_MESSAGES
│ │ ├── django.mo
│ │ └── django.po
├── urls
│ ├── __init__.py
│ ├── shallow.py
│ ├── normal.py
│ └── deep.py
├── __init__.py
├── search_indexes.py
├── settings.py
├── forms.py
├── admin.py
├── tests.py
├── models.py
└── fixtures
│ └── test_data.json
├── pip
├── requirements.txt
├── optional-haystack.txt
└── optional-whoosh.txt
├── .gitignore
├── docs
├── getting_started.rst
├── index.rst
├── Makefile
├── make.bat
└── conf.py
├── MANIFEST.in
├── INSTALL
├── setup.py
├── LICENSE
└── README.rst
/faq/views/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pip/requirements.txt:
--------------------------------------------------------------------------------
1 | Django>=1.2
2 |
--------------------------------------------------------------------------------
/pip/optional-haystack.txt:
--------------------------------------------------------------------------------
1 | django-haystack<2
2 | django-haystack>=1
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | .DS_Store
3 | build/
4 | dist/
5 | docs/_build
6 | MANIFEST
7 |
--------------------------------------------------------------------------------
/pip/optional-whoosh.txt:
--------------------------------------------------------------------------------
1 | # If you want to get Haystack running fast, use Whoosh.
2 | Whoosh<=1.2
3 |
--------------------------------------------------------------------------------
/faq/templates/search/indexes/faq/question_text.txt:
--------------------------------------------------------------------------------
1 | {{ object.question }}
2 |
3 | {{ object.answer }}
4 |
--------------------------------------------------------------------------------
/faq/templates/search/indexes/faq/topic_text.txt:
--------------------------------------------------------------------------------
1 | {{ object.title }}
2 |
3 | {{ object.description }}
4 |
--------------------------------------------------------------------------------
/docs/getting_started.rst:
--------------------------------------------------------------------------------
1 | .. _getting_started:
2 |
3 | Getting Started
4 | ===============
5 |
6 | Overview
7 | --------
8 |
--------------------------------------------------------------------------------
/faq/locale/en/LC_MESSAGES/django.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkh44/django-faq/master/faq/locale/en/LC_MESSAGES/django.mo
--------------------------------------------------------------------------------
/faq/locale/es/LC_MESSAGES/django.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkh44/django-faq/master/faq/locale/es/LC_MESSAGES/django.mo
--------------------------------------------------------------------------------
/faq/urls/__init__.py:
--------------------------------------------------------------------------------
1 | from faq.urls.normal import *
2 | # This serves as both backwords-compatability and a shortcut to the default.
3 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include LICENSE
2 | include README.rst
3 | include MANIFEST.in
4 | recursive-include docs *
5 | recursive-include faq/locale *
6 | recursive-include faq/templates *
--------------------------------------------------------------------------------
/faq/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | A Frequently Asked Question (FAQ) management application for Django apps.
3 |
4 | """
5 |
6 | from django.utils.translation import ugettext_lazy as _
7 |
8 |
9 | VERSION = '0.8.2'
10 |
11 | # Mark the app_label for translation.
12 | _(u'faq')
13 |
--------------------------------------------------------------------------------
/faq/templates/faq/base.html:
--------------------------------------------------------------------------------
1 |
2 | {% load i18n %}
3 | {% get_current_language as language %}
4 |
5 |
6 |
7 |
{% block title %}{% endblock %}
8 |
9 | {% block header %}{% endblock %}
10 |
11 | {% block content %}
12 | {% endblock %}
13 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. _index:
2 | .. module:: faq
3 |
4 | Django FAQ
5 | ==========
6 |
7 | Overview
8 | --------
9 |
10 | ``django-faq`` is
11 |
12 |
13 |
14 | Contents
15 | --------
16 |
17 | .. toctree::
18 | :maxdepth: 2
19 |
20 | getting_started
21 |
22 |
23 | Indices and tables
24 | ------------------
25 |
26 | * :ref:`genindex`
27 | * :ref:`modindex`
28 | * :ref:`search`
29 |
30 |
--------------------------------------------------------------------------------
/faq/urls/shallow.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls.defaults import *
2 |
3 | from faq.views.shallow import topic_list, topic_detail, question_detail
4 |
5 |
6 | # Include these patterns if you want URLs like:
7 | #
8 | # /faq/
9 | # /faq/#topic
10 | # /faq/#question
11 | #
12 |
13 | urlpatterns = patterns('',
14 | url(r'^$', topic_list, name='faq-topic-list'),
15 | url(r'^(?P[-\w]+)/$', topic_detail, name='faq-topic-detail'),
16 | url(r'^(?P[-\w]+)/(?P[-\w]+)/$', question_detail,
17 | name='faq-question-detail'),
18 | )
19 |
--------------------------------------------------------------------------------
/faq/urls/normal.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls.defaults import *
2 |
3 | from faq.views.shallow import topic_list
4 | from faq.views.normal import topic_detail, question_detail
5 |
6 |
7 | # Include these patterns if you want URLs like:
8 | #
9 | # /faq/
10 | # /faq/topic/
11 | # /faq/topic/#question
12 | #
13 |
14 | urlpatterns = patterns('',
15 | url(r'^$', topic_list, name='faq-topic-list'),
16 | url(r'^(?P[-\w]+)/$', topic_detail, name='faq-topic-detail'),
17 | url(r'^(?P[-\w]+)/(?P[-\w]+)/$', question_detail,
18 | name='faq-question-detail'),
19 | )
20 |
--------------------------------------------------------------------------------
/faq/templates/faq/question_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "faq/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 |
6 | {# This template will only be used if the ``faq.urls.deep`` patterns are used. #}
7 |
8 | {% block title %}{% blocktrans with question.question as question %}FAQ: {{ question }}{% endblocktrans %}{% endblock %}
9 |
10 |
11 | {% block header %}
12 | {% trans "FAQ" %} ›
13 | {{ topic }} ›
14 | {{ question }}
15 | {% endblock %}
16 |
17 |
18 | {% block content %}
19 | {{ question.answer|linebreaks|urlize }}
20 | {% endblock %}
21 |
--------------------------------------------------------------------------------
/faq/urls/deep.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls.defaults import *
2 |
3 | from faq.views.shallow import topic_list
4 | from faq.views.normal import topic_detail
5 | from faq.views.deep import question_detail
6 |
7 |
8 | # Include these patterns if you want URLs like:
9 | #
10 | # /faq/
11 | # /faq/topic/
12 | # /faq/topic/question/
13 | #
14 |
15 | urlpatterns = patterns('',
16 | url(r'^$', topic_list, name='faq-topic-list'),
17 | url(r'^(?P[-\w]+)/$', topic_detail, name='faq-topic-detail'),
18 | url(r'^(?P[-\w]+)/(?P[-\w]+)/$', question_detail,
19 | name='faq-question-detail'),
20 | )
21 |
--------------------------------------------------------------------------------
/faq/search_indexes.py:
--------------------------------------------------------------------------------
1 | from haystack import indexes
2 | from haystack.sites import site
3 |
4 | from faq.settings import SEARCH_INDEX
5 | from faq.models import Topic, Question
6 |
7 |
8 | class FAQIndexBase(SEARCH_INDEX):
9 |
10 | text = indexes.CharField(document=True, use_template=True)
11 | url = indexes.CharField(model_attr='get_absolute_url', indexed=False)
12 |
13 |
14 | class TopicIndex(FAQIndexBase):
15 |
16 | def get_queryset(self):
17 | return Topic.objects.published()
18 |
19 |
20 | class QuestionIndex(FAQIndexBase):
21 |
22 | def get_queryset(self):
23 | return Question.objects.published()
24 |
25 |
26 | site.register(Topic, TopicIndex)
27 | site.register(Question, QuestionIndex)
28 |
--------------------------------------------------------------------------------
/faq/views/deep.py:
--------------------------------------------------------------------------------
1 | from django.views.generic.list_detail import object_detail
2 |
3 | from faq.models import Topic, Question
4 |
5 |
6 | def question_detail(request, topic_slug, slug):
7 | """
8 | A detail view of a Question.
9 |
10 | Templates:
11 | :template:`faq/question_detail.html`
12 | Context:
13 | question
14 | A :model:`faq.Question`.
15 | topic
16 | The :model:`faq.Topic` object related to ``question``.
17 |
18 | """
19 | extra_context = {
20 | 'topic': Topic.objects.published().get(slug=topic_slug),
21 | }
22 |
23 | return object_detail(request, queryset=Question.objects.published(),
24 | extra_context=extra_context, template_object_name='question',
25 | slug=slug)
26 |
--------------------------------------------------------------------------------
/INSTALL:
--------------------------------------------------------------------------------
1 | Thanks for downloading django-faq.
2 |
3 | To install it, run the following command inside this directory::
4 |
5 | python setup.py install
6 |
7 | If you have the Python ``pip`` utility available, you can
8 | also type the following to download and install in one step::
9 |
10 | pip install django-faq
11 |
12 | Or if you're still using ``easy_install``::
13 |
14 | easy_install django-faq
15 |
16 | Or if you’d prefer you can simply place the included ``faq``
17 | directory somewhere on your Python path, or symlink to it from
18 | somewhere on your Python path; this is useful if you’re working from a
19 | Git checkout.
20 |
21 | Note that this application requires Python 2.4 or newer, and a
22 | functional installation of Django 1.2 or newer. You can obtain Python
23 | from http://www.python.org/ and Django from
24 | https://www.djangoproject.com/.
25 |
--------------------------------------------------------------------------------
/faq/settings.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 | from django.utils.translation import ugettext_lazy as _
3 |
4 |
5 | # Status settings.
6 | # It's unlikely that you should need to change these. But if
7 | # you do, here you go.
8 |
9 | DRAFTED = getattr(settings, 'FAQ_DRAFTED', 1)
10 | PUBLISHED = getattr(settings, 'FAQ_PUBLISHED', 2)
11 | REMOVED = getattr(settings, 'FAQ_REMOVED', 3)
12 |
13 | STATUS_CHOICES = (
14 | (DRAFTED, _(u'drafted')),
15 | (PUBLISHED, _(u'published')),
16 | (REMOVED, _(u'removed')),
17 | )
18 | STATUS_CHOICES = getattr(settings, 'FAQ_STATUS_CHOICES', STATUS_CHOICES)
19 |
20 |
21 | # Haystack settings.
22 | # The default search index used for the app is the default haystack index.
23 | # But possibly you want to use haystack.indexes.RealTimeSearchIndex, or another
24 | # of your own making. Go ahead.
25 | try:
26 | from haystack.indexes import SearchIndex
27 | SEARCH_INDEX = getattr(settings, 'FAQ_SEARCH_INDEX', SearchIndex)
28 | except ImportError:
29 | SEARCH_INDEX = None
30 |
--------------------------------------------------------------------------------
/faq/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | from faq.models import Question
4 |
5 |
6 | class QuestionForm(forms.ModelForm):
7 | """A form whose only purpose is to manage fields for the QuestionInline."""
8 |
9 | class Meta:
10 | # InlineModelAdmin does not support ``fields``, so if we want to order
11 | # the fields in an InlineModelAdmin, we must do so with a custom
12 | # ModelForm. This is not ideal, but at least it gets the job done.
13 | #
14 | # Note that ``slug`` is left out of the fields list. This is because
15 | # we don't show the slug when adding an Question as an inline to a
16 | # topic because InlineModelAdmin does not support
17 | # ``prepopulated_fields`` either, and it's evil to expect the user
18 | # supply a slug by hand.
19 | #
20 | # If the user really wants to edit the slug, they can do so on the
21 | # Question change page.
22 | fields = ('question', 'answer', 'ordering', 'status')
23 | model = Question
24 |
--------------------------------------------------------------------------------
/faq/templates/faq/topic_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "faq/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 |
6 | {% comment %}
7 | This template will be used when either ``faq.urls.normal`` (default) or
8 | ``faq.urls.deep`` patterns are used. Note that you will want to code this
9 | differently depending on the patterns. This template is coded for ``normal``.
10 | {% endcomment %}
11 |
12 | {% block title %}{% blocktrans with topic.title as topic %}FAQ: {{ topic }}{% endblocktrans %}{% endblock %}
13 |
14 |
15 | {% block header %}
16 | {% trans "FAQ" %} › {{ topic }}
17 | {% endblock %}
18 |
19 |
20 | {% block content %}
21 | {{ topic.description }}
22 |
23 |
24 | {% for question in question_list %}
25 | -
26 |
{{ question.question }}
27 | ∞
28 | {{ question.answer|linebreaks|urlize }}
29 |
30 | {% comment %} For ``deep`` you may do something like the following.
31 | - {{ question.question }}
32 | {% endcomment %}
33 | {% endfor %}
34 |
35 | {% endblock %}
36 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | import os
2 | from distutils.core import setup
3 | from faq import VERSION
4 |
5 | def read(fname):
6 | return open(os.path.join(os.path.dirname(__file__), fname)).read()
7 |
8 | setup(
9 | name='django-faq',
10 | version=VERSION,
11 | description='Frequently Asked Question (FAQ) management for Django apps.',
12 | url='https://github.com/benspaulding/django-faq/',
13 | author='Ben Spaulding',
14 | author_email='ben@benspaulding.us',
15 | license='BSD',
16 | download_url='http://github.com/benspaulding/django-faq/tarball/v%s' % VERSION,
17 | long_description = read('README.rst'),
18 | packages = ['faq', 'faq.urls', 'faq.views'],
19 | package_data = {'faq': ['locale/*/LC_MESSAGES/*',
20 | 'templates/faq/*',
21 | 'templates/search/indexes/faq/*']},
22 | classifiers=['Development Status :: 4 - Beta',
23 | 'Environment :: Web Environment',
24 | 'Framework :: Django',
25 | 'Intended Audience :: Developers',
26 | 'License :: OSI Approved :: BSD License',
27 | 'Operating System :: OS Independent',
28 | 'Programming Language :: Python',
29 | 'Topic :: Internet :: WWW/HTTP :: Site Management'],
30 | )
31 |
--------------------------------------------------------------------------------
/faq/templates/faq/topic_list.html:
--------------------------------------------------------------------------------
1 | {% extends "faq/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 |
6 | {% comment %}
7 | This template will be used regardless of what ``faq.urls`` patterns are used.
8 | But note that you will want to code this differently depending on the
9 | patterns used. This template is coded for either ``normal`` or ``deep``.
10 | {% endcomment %}
11 |
12 | {% block title %}{% trans "Frequently Asked Questions" %}{% endblock %}
13 | {% block header %}{% trans "Frequently Asked Questions" %}{% endblock %}
14 |
15 |
16 | {% block content %}
17 |
18 | {% for topic in topic_list %}
19 | - {{ topic.title }}
20 | {% comment %} For ``faq.urls.shallow`` you may do something like the following.
21 | -
22 |
{{ topic.title }} ∞
23 |
24 | {% for question in topic.questions.published %}
25 | -
26 |
{{ question.question }}
27 | ∞
28 | {{ question.answer|linebreaks|urlize }}
29 |
30 | {% endfor %}
31 |
32 |
33 | {% endcomment %}
34 | {% endfor %}
35 |
36 | {% endblock %}
37 |
--------------------------------------------------------------------------------
/faq/views/normal.py:
--------------------------------------------------------------------------------
1 | from django.core.urlresolvers import reverse
2 | from django.shortcuts import get_object_or_404, redirect
3 | from django.views.generic.list_detail import object_detail
4 |
5 | from faq.models import Topic, Question
6 | from faq.views.shallow import _fragmentify
7 |
8 |
9 | def topic_detail(request, slug):
10 | """
11 | A detail view of a Topic
12 |
13 | Templates:
14 | :template:`faq/topic_detail.html`
15 | Context:
16 | topic
17 | An :model:`faq.Topic` object.
18 | question_list
19 | A list of all published :model:`faq.Question` objects that relate
20 | to the given :model:`faq.Topic`.
21 |
22 | """
23 | extra_context = {
24 | 'question_list': Question.objects.published().filter(topic__slug=slug),
25 | }
26 |
27 | return object_detail(request, queryset=Topic.objects.published(),
28 | extra_context=extra_context, template_object_name='topic', slug=slug)
29 |
30 |
31 | def question_detail(request, topic_slug, slug):
32 | """
33 | A detail view of a Question.
34 |
35 | Simply redirects to a detail page for the related :model:`faq.Topic`
36 | (:view:`faq.views.topic_detail`) with the addition of a fragment
37 | identifier that links to the given :model:`faq.Question`.
38 | E.g. ``/faq/topic-slug/#question-slug``.
39 |
40 | """
41 | url = reverse('faq-topic-detail', kwargs={'slug': topic_slug})
42 | return _fragmentify(Question, slug, url)
43 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011, Ben Spaulding
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are
6 | met:
7 |
8 | * Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 | * Redistributions in binary form must reproduce the above
11 | copyright notice, this list of conditions and the following
12 | disclaimer in the documentation and/or other materials provided
13 | with the distribution.
14 | * Neither the name of the author nor the names of other
15 | contributors may be used to endorse or promote products derived
16 | from this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 |
--------------------------------------------------------------------------------
/faq/views/shallow.py:
--------------------------------------------------------------------------------
1 | from django.core.urlresolvers import reverse
2 | from django.shortcuts import get_object_or_404, redirect
3 | from django.views.generic.list_detail import object_list
4 |
5 | from faq.models import Topic, Question
6 |
7 |
8 | def _fragmentify(model, slug, url=None):
9 | get_object_or_404(model.objects.published().filter(slug=slug))
10 | url = url or reverse('faq-topic-list')
11 | fragment = '#%s' % slug
12 |
13 | return redirect(url + fragment, permanent=True)
14 |
15 |
16 | def topic_list(request):
17 | """
18 | A list view of all published Topics
19 |
20 | Templates:
21 | :template:`faq/topic_list.html`
22 | Context:
23 | topic_list
24 | A list of all published :model:`faq.Topic` objects that
25 | relate to the current :model:`sites.Site`.
26 |
27 | """
28 | return object_list(request, queryset=Topic.objects.published(),
29 | template_object_name='topic')
30 |
31 |
32 | def topic_detail(request, slug):
33 | """
34 | A detail view of a Topic
35 |
36 | Simply redirects to :view:`faq.views.topic_list` with the addition of
37 | a fragment identifier that links to the given :model:`faq.Topic`.
38 | E.g., ``/faq/#topic-slug``.
39 |
40 | """
41 | return _fragmentify(Topic, slug)
42 |
43 |
44 | def question_detail(request, topic_slug, slug):
45 | """
46 | A detail view of a Question.
47 |
48 | Simply redirects to :view:`faq.views.topic_list` with the addition of
49 | a fragment identifier that links to the given :model:`faq.Question`.
50 | E.g. ``/faq/#question-slug``.
51 |
52 | """
53 | return _fragmentify(Question, slug)
54 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | ============================================================
2 | Frequently Asked Question (FAQ) management for Django apps
3 | ============================================================
4 |
5 | This Django_ application provides the ability to create and manage lists of
6 | Frequently Asked Questions (FAQ), organized by topic.
7 |
8 | This project is still under development, though several medium-to-large
9 | websites are currently using it in production. The plan is to get a stable
10 | version with a full test suite and documentation out the door in the coming
11 | months.
12 |
13 | .. _Django: http://www.djangoproject.com/
14 |
15 | TODO’s
16 | ------
17 |
18 | Below are tasks that need done, features under consideration, and some
19 | reminders for the future.
20 |
21 | * Finish writing tests.
22 | * Write general documentation, and specifically,
23 |
24 | * The change of modified date field behavior. (Dropped null=True, now
25 | has a date upon creation.) Write migration if necessary.
26 | * Document removal of custom template name field on Topic. (The feature made
27 | little sense given the various URL/view setups.) Write migration if
28 | necessary.
29 |
30 | * Finalize Django, Haystack, and Whoosh versions in pip requirements/optionals files.
31 | * Bump the version number.
32 | * Roll a release
33 |
34 | * Create git tag
35 | * Get on Read the Docs
36 | * Upload to PyPi
37 |
38 |
39 | Features
40 | ~~~~~~~~
41 |
42 | * Create a better interface for ordering questions within a topic.
43 | * Consider if/how to add ordering to Topics. (This is complicated because of
44 | site relations.)
45 |
46 |
47 | In the future, when dropping Django 1.2 support
48 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49 |
50 | * Update to class-based generic views
51 | * Move from Question.save() to model validation?
52 |
--------------------------------------------------------------------------------
/faq/locale/es/LC_MESSAGES/django.po:
--------------------------------------------------------------------------------
1 | # English translation for the django-faq project.
2 | # Copyright (C) 2011, Ben Spaulding.
3 | # This file is distributed under the same license as the django-faq package.
4 | # Ben Spaulding , 2011.
5 | #
6 | msgid ""
7 | msgstr ""
8 | "Project-Id-Version: django-faq\n"
9 | "Report-Msgid-Bugs-To: \n"
10 | "POT-Creation-Date: 2010-02-01 22:37-0600\n"
11 | "PO-Revision-Date: 2010-01-31 04:35-0600\n"
12 | "Last-Translator: FULL NAME \n"
13 | "MIME-Version: 1.0\n"
14 | "Content-Type: text/plain; charset=UTF-8\n"
15 | "Content-Transfer-Encoding: 8bit\n"
16 |
17 | #: __init__.py:10
18 | msgid "faq"
19 | msgstr ""
20 |
21 | #: admin.py:27
22 | #, python-format
23 | msgid "Changed status to '%s'."
24 | msgstr ""
25 |
26 | #: admin.py:40
27 | #, python-format
28 | msgid "%(count)s %(object)s was successfully %(verb)s."
29 | msgid_plural "%(count)s %(object)s were successfully %(verb)s."
30 | msgstr[0] ""
31 | msgstr[1] ""
32 |
33 | #: admin.py:54
34 | #, python-format
35 | msgid "Draft selected %(verbose_name_plural)s"
36 | msgstr ""
37 |
38 | #: admin.py:60
39 | #, python-format
40 | msgid "Publish selected %(verbose_name_plural)s"
41 | msgstr ""
42 |
43 | #: admin.py:66
44 | #, python-format
45 | msgid "Remove selected %(verbose_name_plural)s"
46 | msgstr ""
47 |
48 | #: admin.py:101
49 | msgid "No. of Questions"
50 | msgstr ""
51 |
52 | #: models.py:76
53 | msgid "date created"
54 | msgstr ""
55 |
56 | #: models.py:77
57 | msgid "date modified"
58 | msgstr ""
59 |
60 | #: models.py:79
61 | msgid "status"
62 | msgstr ""
63 |
64 | #: models.py:81
65 | msgid ""
66 | "Only objects with \"published\" status will be displayed "
67 | "publicly."
68 | msgstr ""
69 |
70 | #: models.py:101
71 | msgid "title"
72 | msgstr ""
73 |
74 | #: models.py:102 models.py:130
75 | msgid "slug"
76 | msgstr ""
77 |
78 | #: models.py:102
79 | msgid "Used in the URL for the topic. Must be unique."
80 | msgstr ""
81 |
82 | #: models.py:104
83 | msgid "description"
84 | msgstr ""
85 |
86 | #: models.py:105
87 | msgid "A short description of this topic."
88 | msgstr ""
89 |
90 | #: models.py:106
91 | msgid "sites"
92 | msgstr ""
93 |
94 | #: models.py:108
95 | msgid "template name"
96 | msgstr ""
97 |
98 | #: models.py:109
99 | msgid ""
100 | "Optional template to use for this topic's detail page, e.g., "
101 | "\"faq/topics/special.html\". If not given the standard template "
102 | "will be used."
103 | msgstr ""
104 |
105 | #: models.py:115 models.py:133
106 | msgid "topic"
107 | msgstr ""
108 |
109 | #: models.py:116
110 | msgid "topics"
111 | msgstr ""
112 |
113 | #: models.py:129 models.py:142
114 | msgid "question"
115 | msgstr ""
116 |
117 | #: models.py:130
118 | msgid "Used in the URL for the Question. Must be unique."
119 | msgstr ""
120 |
121 | #: models.py:132
122 | msgid "answer"
123 | msgstr ""
124 |
125 | #: models.py:135
126 | msgid "ordering"
127 | msgstr ""
128 |
129 | #: models.py:136
130 | msgid ""
131 | "An integer used to order the question amongst others related to "
132 | "the same topic. If not given this question will be last in the "
133 | "list."
134 | msgstr ""
135 |
136 | #: models.py:143
137 | msgid "questions"
138 | msgstr ""
139 |
140 | #: settings.py:14
141 | msgid "drafted"
142 | msgstr ""
143 |
144 | #: settings.py:15
145 | msgid "published"
146 | msgstr ""
147 |
148 | #: settings.py:16
149 | msgid "removed"
150 | msgstr ""
151 |
152 | #: templates/faq/question_detail.html:8
153 | #, python-format
154 | msgid "FAQ: %(question)s"
155 | msgstr ""
156 |
157 | #: templates/faq/question_detail.html:12 templates/faq/topic_detail.html:16
158 | msgid "FAQ"
159 | msgstr ""
160 |
161 | #: templates/faq/topic_detail.html:12
162 | #, python-format
163 | msgid "FAQ: %(topic)s"
164 | msgstr ""
165 |
166 | #: templates/faq/topic_list.html:12 templates/faq/topic_list.html.py:13
167 | msgid "Frequently Asked Questions"
168 | msgstr ""
169 |
--------------------------------------------------------------------------------
/faq/locale/en/LC_MESSAGES/django.po:
--------------------------------------------------------------------------------
1 | # English "translation" for the django-faq project.
2 | # Copyright (C) 2011, Ben Spaulding.
3 | # This file is distributed under the same license as the django-faq package.
4 | # Ben Spaulding , 2011.
5 | #
6 | msgid ""
7 | msgstr ""
8 | "Project-Id-Version: django-faq\n"
9 | "Report-Msgid-Bugs-To: \n"
10 | "POT-Creation-Date: 2010-02-01 22:37-0600\n"
11 | "PO-Revision-Date: 2010-01-31 04:35-0600\n"
12 | "Last-Translator: Ben Spaulding \n"
13 | "MIME-Version: 1.0\n"
14 | "Content-Type: text/plain; charset=UTF-8\n"
15 | "Content-Transfer-Encoding: 8bit\n"
16 |
17 | #: __init__.py:10
18 | msgid "faq"
19 | msgstr "FAQ"
20 |
21 | #: admin.py:27
22 | #, python-format
23 | msgid "Changed status to '%s'."
24 | msgstr ""
25 |
26 | #: admin.py:40
27 | #, python-format
28 | msgid "%(count)s %(object)s was successfully %(verb)s."
29 | msgid_plural "%(count)s %(object)s were successfully %(verb)s."
30 | msgstr[0] ""
31 | msgstr[1] ""
32 |
33 | #: admin.py:54
34 | #, python-format
35 | msgid "Draft selected %(verbose_name_plural)s"
36 | msgstr ""
37 |
38 | #: admin.py:60
39 | #, python-format
40 | msgid "Publish selected %(verbose_name_plural)s"
41 | msgstr ""
42 |
43 | #: admin.py:66
44 | #, python-format
45 | msgid "Remove selected %(verbose_name_plural)s"
46 | msgstr ""
47 |
48 | #: admin.py:101
49 | msgid "No. of Questions"
50 | msgstr ""
51 |
52 | #: models.py:76
53 | msgid "date created"
54 | msgstr ""
55 |
56 | #: models.py:77
57 | msgid "date modified"
58 | msgstr ""
59 |
60 | #: models.py:79
61 | msgid "status"
62 | msgstr ""
63 |
64 | #: models.py:81
65 | msgid ""
66 | "Only objects with \"published\" status will be displayed "
67 | "publicly."
68 | msgstr ""
69 |
70 | #: models.py:101
71 | msgid "title"
72 | msgstr ""
73 |
74 | #: models.py:102 models.py:130
75 | msgid "slug"
76 | msgstr ""
77 |
78 | #: models.py:102
79 | msgid "Used in the URL for the topic. Must be unique."
80 | msgstr ""
81 |
82 | #: models.py:104
83 | msgid "description"
84 | msgstr ""
85 |
86 | #: models.py:105
87 | msgid "A short description of this topic."
88 | msgstr ""
89 |
90 | #: models.py:106
91 | msgid "sites"
92 | msgstr ""
93 |
94 | #: models.py:108
95 | msgid "template name"
96 | msgstr ""
97 |
98 | #: models.py:109
99 | msgid ""
100 | "Optional template to use for this topic's detail page, e.g., "
101 | "\"faq/topics/special.html\". If not given the standard template "
102 | "will be used."
103 | msgstr ""
104 |
105 | #: models.py:115 models.py:133
106 | msgid "topic"
107 | msgstr ""
108 |
109 | #: models.py:116
110 | msgid "topics"
111 | msgstr ""
112 |
113 | #: models.py:129 models.py:142
114 | msgid "question"
115 | msgstr ""
116 |
117 | #: models.py:130
118 | msgid "Used in the URL for the Question. Must be unique."
119 | msgstr ""
120 |
121 | #: models.py:132
122 | msgid "answer"
123 | msgstr ""
124 |
125 | #: models.py:135
126 | msgid "ordering"
127 | msgstr ""
128 |
129 | #: models.py:136
130 | msgid ""
131 | "An integer used to order the question amongst others related to "
132 | "the same topic. If not given this question will be last in the "
133 | "list."
134 | msgstr ""
135 |
136 | #: models.py:143
137 | msgid "questions"
138 | msgstr ""
139 |
140 | #: settings.py:14
141 | msgid "drafted"
142 | msgstr ""
143 |
144 | #: settings.py:15
145 | msgid "published"
146 | msgstr ""
147 |
148 | #: settings.py:16
149 | msgid "removed"
150 | msgstr ""
151 |
152 | #: templates/faq/question_detail.html:8
153 | #, python-format
154 | msgid "FAQ: %(question)s"
155 | msgstr ""
156 |
157 | #: templates/faq/question_detail.html:12 templates/faq/topic_detail.html:16
158 | msgid "FAQ"
159 | msgstr ""
160 |
161 | #: templates/faq/topic_detail.html:12
162 | #, python-format
163 | msgid "FAQ: %(topic)s"
164 | msgstr ""
165 |
166 | #: templates/faq/topic_list.html:12 templates/faq/topic_list.html.py:13
167 | msgid "Frequently Asked Questions"
168 | msgstr ""
169 |
--------------------------------------------------------------------------------
/faq/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from django.contrib.sites.models import Site
3 | from django.utils.translation import ugettext_lazy as _
4 | from django.utils.translation import ugettext_noop, ungettext
5 |
6 | from faq.settings import DRAFTED, PUBLISHED, REMOVED, STATUS_CHOICES
7 | from faq.models import Topic, Question
8 | from faq.forms import QuestionForm
9 |
10 |
11 | # Actions.
12 |
13 | def update_status(modeladmin, request, queryset, status):
14 | """The workhorse function for the admin action functions that follow."""
15 | # We loop over the objects here rather than use queryset.update() for
16 | # two reasons:
17 | #
18 | # 1. No one should ever be updating zillions of Topics or Questions, so
19 | # performance is not an issue.
20 | # 2. To be tidy, we want to log what the user has done.
21 | #
22 | for obj in queryset:
23 | obj.status = status
24 | obj.save()
25 | # Now log what happened.
26 | # Use ugettext_noop() 'cause this is going straight into the db.
27 | log_message = ugettext_noop(u'Changed status to \'%s\'.' %
28 | obj.get_status_display())
29 | modeladmin.log_change(request, obj, log_message)
30 |
31 | # Send a message to the user telling them what has happened.
32 | message_dict = {
33 | 'count': queryset.count(),
34 | 'object': modeladmin.model._meta.verbose_name,
35 | 'verb': dict(STATUS_CHOICES)[status],
36 | }
37 | if not message_dict['count'] == 1:
38 | message_dict['object'] = modeladmin.model._meta.verbose_name_plural
39 | user_message = ungettext(
40 | u'%(count)s %(object)s was successfully %(verb)s.',
41 | u'%(count)s %(object)s were successfully %(verb)s.',
42 | message_dict['count']) % message_dict
43 | modeladmin.message_user(request, user_message)
44 |
45 | # Return None to display the change list page again and allow the user
46 | # to reload the page without getting that nasty "Send the form again ..."
47 | # warning from their browser.
48 | return None
49 |
50 |
51 | def draft(modeladmin, request, queryset):
52 | """Admin action for setting status of selected items to 'drafted'."""
53 | return update_status(modeladmin, request, queryset, DRAFTED)
54 | draft.short_description = _(u'Draft selected %(verbose_name_plural)s')
55 |
56 |
57 | def publish(modeladmin, request, queryset):
58 | """Admin action for setting status of selected items to 'published'."""
59 | return update_status(modeladmin, request, queryset, PUBLISHED)
60 | publish.short_description = _(u'Publish selected %(verbose_name_plural)s')
61 |
62 |
63 | def remove(modeladmin, request, queryset):
64 | """Admin action for setting status of selected items to 'removed'."""
65 | return update_status(modeladmin, request, queryset, REMOVED)
66 | remove.short_description = _(u'Remove selected %(verbose_name_plural)s')
67 |
68 |
69 | # Inlines.
70 |
71 | class QuestionInline(admin.TabularInline):
72 | extra = 1
73 | form = QuestionForm
74 | model = Question
75 |
76 |
77 | # Admins.
78 |
79 | class FAQAdminBase(admin.ModelAdmin):
80 | actions = (draft, publish, remove)
81 | actions_on_top = True
82 | actions_on_bottom = True
83 | list_per_page = 50
84 |
85 |
86 | class TopicAdmin(FAQAdminBase):
87 | fieldsets = (
88 | (None, {
89 | 'fields': ('title', 'slug', 'description', 'status', 'sites')}),
90 | )
91 | inlines = (QuestionInline, )
92 | list_display = ('title', 'description', 'status', 'question_count')
93 | list_filter = ('status', 'sites', 'modified', 'created')
94 | prepopulated_fields = {'slug': ('title', )}
95 | search_fields = ('title', 'description')
96 |
97 | def question_count(self, obj):
98 | """Returns the total number of Questions for this topic."""
99 | return obj.questions.count()
100 | question_count.short_description = _(u'No. of Questions')
101 |
102 |
103 | class QuestionAdmin(FAQAdminBase):
104 | fieldsets = (
105 | (None, {
106 | 'fields': ('topic', 'question', 'slug', 'answer', 'status',
107 | 'ordering')}),
108 | )
109 | list_display = ('question', 'topic', 'status', 'ordering')
110 | list_filter = ('status', 'topic', 'modified', 'created')
111 | prepopulated_fields = {'slug': ('question', )}
112 | search_fields = ('question', 'answer')
113 |
114 |
115 | admin.site.register(Topic, TopicAdmin)
116 | admin.site.register(Question, QuestionAdmin)
117 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 | BUILDDIR = _build
9 |
10 | # Internal variables.
11 | PAPEROPT_a4 = -D latex_paper_size=a4
12 | PAPEROPT_letter = -D latex_paper_size=letter
13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
14 |
15 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
16 |
17 | help:
18 | @echo "Please use \`make ' where is one of"
19 | @echo " html to make standalone HTML files"
20 | @echo " dirhtml to make HTML files named index.html in directories"
21 | @echo " singlehtml to make a single large HTML file"
22 | @echo " pickle to make pickle files"
23 | @echo " json to make JSON files"
24 | @echo " htmlhelp to make HTML files and a HTML help project"
25 | @echo " qthelp to make HTML files and a qthelp project"
26 | @echo " devhelp to make HTML files and a Devhelp project"
27 | @echo " epub to make an epub"
28 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
29 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
30 | @echo " text to make text files"
31 | @echo " man to make manual pages"
32 | @echo " changes to make an overview of all changed/added/deprecated items"
33 | @echo " linkcheck to check all external links for integrity"
34 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
35 |
36 | clean:
37 | -rm -rf $(BUILDDIR)/*
38 |
39 | html:
40 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
41 | @echo
42 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
43 |
44 | dirhtml:
45 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
46 | @echo
47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
48 |
49 | singlehtml:
50 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
51 | @echo
52 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
53 |
54 | pickle:
55 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
56 | @echo
57 | @echo "Build finished; now you can process the pickle files."
58 |
59 | json:
60 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
61 | @echo
62 | @echo "Build finished; now you can process the JSON files."
63 |
64 | htmlhelp:
65 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
66 | @echo
67 | @echo "Build finished; now you can run HTML Help Workshop with the" \
68 | ".hhp project file in $(BUILDDIR)/htmlhelp."
69 |
70 | qthelp:
71 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
72 | @echo
73 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
74 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
75 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-faq.qhcp"
76 | @echo "To view the help file:"
77 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-faq.qhc"
78 |
79 | devhelp:
80 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
81 | @echo
82 | @echo "Build finished."
83 | @echo "To view the help file:"
84 | @echo "# mkdir -p $$HOME/.local/share/devhelp/django-faq"
85 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-faq"
86 | @echo "# devhelp"
87 |
88 | epub:
89 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
90 | @echo
91 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
92 |
93 | latex:
94 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
95 | @echo
96 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
97 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
98 | "(use \`make latexpdf' here to do that automatically)."
99 |
100 | latexpdf:
101 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
102 | @echo "Running LaTeX files through pdflatex..."
103 | make -C $(BUILDDIR)/latex all-pdf
104 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
105 |
106 | text:
107 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
108 | @echo
109 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
110 |
111 | man:
112 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
113 | @echo
114 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
115 |
116 | changes:
117 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
118 | @echo
119 | @echo "The overview file is in $(BUILDDIR)/changes."
120 |
121 | linkcheck:
122 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
123 | @echo
124 | @echo "Link check complete; look for any errors in the above output " \
125 | "or in $(BUILDDIR)/linkcheck/output.txt."
126 |
127 | doctest:
128 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
129 | @echo "Testing of doctests in the sources finished, look at the " \
130 | "results in $(BUILDDIR)/doctest/output.txt."
131 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | REM Command file for Sphinx documentation
4 |
5 | if "%SPHINXBUILD%" == "" (
6 | set SPHINXBUILD=sphinx-build
7 | )
8 | set BUILDDIR=_build
9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
10 | if NOT "%PAPER%" == "" (
11 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
12 | )
13 |
14 | if "%1" == "" goto help
15 |
16 | if "%1" == "help" (
17 | :help
18 | echo.Please use `make ^` where ^ is one of
19 | echo. html to make standalone HTML files
20 | echo. dirhtml to make HTML files named index.html in directories
21 | echo. singlehtml to make a single large HTML file
22 | echo. pickle to make pickle files
23 | echo. json to make JSON files
24 | echo. htmlhelp to make HTML files and a HTML help project
25 | echo. qthelp to make HTML files and a qthelp project
26 | echo. devhelp to make HTML files and a Devhelp project
27 | echo. epub to make an epub
28 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
29 | echo. text to make text files
30 | echo. man to make manual pages
31 | echo. changes to make an overview over all changed/added/deprecated items
32 | echo. linkcheck to check all external links for integrity
33 | echo. doctest to run all doctests embedded in the documentation if enabled
34 | goto end
35 | )
36 |
37 | if "%1" == "clean" (
38 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
39 | del /q /s %BUILDDIR%\*
40 | goto end
41 | )
42 |
43 | if "%1" == "html" (
44 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
45 | if errorlevel 1 exit /b 1
46 | echo.
47 | echo.Build finished. The HTML pages are in %BUILDDIR%/html.
48 | goto end
49 | )
50 |
51 | if "%1" == "dirhtml" (
52 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
53 | if errorlevel 1 exit /b 1
54 | echo.
55 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
56 | goto end
57 | )
58 |
59 | if "%1" == "singlehtml" (
60 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
61 | if errorlevel 1 exit /b 1
62 | echo.
63 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
64 | goto end
65 | )
66 |
67 | if "%1" == "pickle" (
68 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
69 | if errorlevel 1 exit /b 1
70 | echo.
71 | echo.Build finished; now you can process the pickle files.
72 | goto end
73 | )
74 |
75 | if "%1" == "json" (
76 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
77 | if errorlevel 1 exit /b 1
78 | echo.
79 | echo.Build finished; now you can process the JSON files.
80 | goto end
81 | )
82 |
83 | if "%1" == "htmlhelp" (
84 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
85 | if errorlevel 1 exit /b 1
86 | echo.
87 | echo.Build finished; now you can run HTML Help Workshop with the ^
88 | .hhp project file in %BUILDDIR%/htmlhelp.
89 | goto end
90 | )
91 |
92 | if "%1" == "qthelp" (
93 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
94 | if errorlevel 1 exit /b 1
95 | echo.
96 | echo.Build finished; now you can run "qcollectiongenerator" with the ^
97 | .qhcp project file in %BUILDDIR%/qthelp, like this:
98 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\django-faq.qhcp
99 | echo.To view the help file:
100 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\django-faq.ghc
101 | goto end
102 | )
103 |
104 | if "%1" == "devhelp" (
105 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
106 | if errorlevel 1 exit /b 1
107 | echo.
108 | echo.Build finished.
109 | goto end
110 | )
111 |
112 | if "%1" == "epub" (
113 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
114 | if errorlevel 1 exit /b 1
115 | echo.
116 | echo.Build finished. The epub file is in %BUILDDIR%/epub.
117 | goto end
118 | )
119 |
120 | if "%1" == "latex" (
121 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
122 | if errorlevel 1 exit /b 1
123 | echo.
124 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
125 | goto end
126 | )
127 |
128 | if "%1" == "text" (
129 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
130 | if errorlevel 1 exit /b 1
131 | echo.
132 | echo.Build finished. The text files are in %BUILDDIR%/text.
133 | goto end
134 | )
135 |
136 | if "%1" == "man" (
137 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
138 | if errorlevel 1 exit /b 1
139 | echo.
140 | echo.Build finished. The manual pages are in %BUILDDIR%/man.
141 | goto end
142 | )
143 |
144 | if "%1" == "changes" (
145 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
146 | if errorlevel 1 exit /b 1
147 | echo.
148 | echo.The overview file is in %BUILDDIR%/changes.
149 | goto end
150 | )
151 |
152 | if "%1" == "linkcheck" (
153 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
154 | if errorlevel 1 exit /b 1
155 | echo.
156 | echo.Link check complete; look for any errors in the above output ^
157 | or in %BUILDDIR%/linkcheck/output.txt.
158 | goto end
159 | )
160 |
161 | if "%1" == "doctest" (
162 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
163 | if errorlevel 1 exit /b 1
164 | echo.
165 | echo.Testing of doctests in the sources finished, look at the ^
166 | results in %BUILDDIR%/doctest/output.txt.
167 | goto end
168 | )
169 |
170 | :end
171 |
--------------------------------------------------------------------------------
/faq/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 | from django.contrib.sites.models import Site
3 |
4 | from faq.settings import DRAFTED
5 | from faq.models import Topic, Question, OnSiteManager
6 |
7 | ##
8 | # Test fragmentify, or just view redirects?
9 | # Test _field_lookups, or just Manager?
10 | # Test admin actions?
11 | ##
12 |
13 | class BaseTestCase(TestCase):
14 | """"""
15 |
16 | fixtures = ['test_data']
17 |
18 | def setUp(self):
19 | # Setup some new objects. We want these instead of ones from the test
20 | # data because we will be testing for the state of something newly
21 | # created, which the test data does not contain, obviously.
22 | self.topics = {
23 | 'new': Site.objects.get_current().faq_topics.create(title=u'Test Topic',
24 | slug=u'test-topic'),
25 | 'drafted': Topic.objects.get(slug='website'),
26 | 'published': Topic.objects.get(slug='shipping'),
27 | 'removed': Topic.objects.get(slug='black-market-items'),
28 | 'off_site': Topic.objects.get(slug='about-us'),
29 | }
30 |
31 | self. questions = {
32 | 'new1': self.topics['new'].questions.create(question=u'Where am I?',
33 | answer=u'That is classified.'),
34 | 'new2': self.topics['new'].questions.create(question=u'Who are you?',
35 | answer=u'I cannot say.'),
36 | 'drafted': Question.objects.get(slug='in-what-color-box-do-you-ship'),
37 | 'published': Question.objects.get(slug='how-much-does-shipping-cost'),
38 | 'removed': Question.objects.get(slug='what-carrier-do-you-use'),
39 | 'off_site': Question.objects.get(slug='are-you-hiring'),
40 | 'pub_topic_draft': Question.objects.get(slug='do-you-have-an-sla'),
41 | 'pub_topic_removed': Question.objects.get(slug='how-do-you-acquire-black-market-items'),
42 | }
43 |
44 |
45 | # Model and Manager test cases.
46 |
47 | class ManagerTestCase(BaseTestCase):
48 | """"""
49 |
50 | pass
51 |
52 |
53 | class ModelsTestCase(BaseTestCase):
54 | """"""
55 |
56 | def testManager(self):
57 | # Because of our sublcassing with the models, be certain that the
58 | # manager is wired up correctly.
59 | self.assertTrue(isinstance(Topic.objects, OnSiteManager))
60 | self.assertTrue(isinstance(Question.objects, OnSiteManager))
61 |
62 | def testUnicode(self):
63 | # Ensure that we don't absent-mindedly change what the `__unicode__()`
64 | # method returns.
65 | self.assertEqual(self.topics['new'].__unicode__(),
66 | self.topics['new'].title)
67 | self.assertEqual(self.questions['new1'].__unicode__(),
68 | self.questions['new1'].question)
69 |
70 | def testDefaultStatus(self):
71 | # Items created without choosing a status should be drafted by default.
72 | self.assertEqual(self.topics['new'].status, DRAFTED)
73 | self.assertEqual(self.questions['new1'].status, DRAFTED)
74 |
75 | def testSlugOnSave(self):
76 | # Be sure we are properly creating slugs for questions that are created
77 | # without them (those created as an inline to a topic).
78 | self.assertEqual(self.questions['new1'].slug, u'where-am-i')
79 | self.assertEqual(self.questions['new2'].slug, u'who-are-you')
80 |
81 | def testOrderingOnSave(self):
82 | # Be sure we are properly calculating and filling the ordering field
83 | # when a user leaves it blank.
84 | self.assertEqual(self.questions['new1'].ordering, 1)
85 | self.assertEqual(self.questions['new2'].ordering, 2)
86 |
87 |
88 | # View test case.
89 |
90 | class ViewsBaseTestCase(BaseTestCase):
91 | """"""
92 |
93 | def setUp(self):
94 | # Call `super` first because we used some of the stuff that it set up.
95 | super(ViewsBaseTestCase, self).setUp()
96 |
97 | # Set up some responses. We do this here because we are going to be
98 | # testing on these responses with various methods here and in subclasses.
99 | self.responses = {
100 | 'topic_list': self.client.get('/'),
101 | 'topic_detail': self.client.get(
102 | self.topics['published'].get_absolute_url(), follow=True),
103 | 'question_detail': self.client.get(
104 | self.questions['published'].get_absolute_url(), follow=True),
105 | }
106 |
107 |
108 | class ViewsShallowTestCase(ViewsBaseTestCase):
109 |
110 | urls = 'faq.urls.shallow'
111 |
112 | def testTopicDetail(self):
113 | # Redirects to a fragment identifier on the topic list.
114 | self.assertRedirects(self.responses['topic_detail'],
115 | '/#shipping', status_code=301)
116 |
117 | def testQuestionDetail(self):
118 | # Redirects to a fragment identifier on the topic list.
119 | self.assertRedirects(self.responses['question_detail'],
120 | '/#how-much-does-shipping-cost', status_code=301)
121 |
122 |
123 | class ViewsNormalTestCase(ViewsShallowTestCase):
124 | """"""
125 |
126 | urls = 'faq.urls.normal'
127 |
128 | def testTopicDetail(self):
129 | # Does not redirect.
130 | self.assertEqual(self.responses['topic_detail'].status_code, 200)
131 | # Check for our extra_context.
132 | # Must `list()` the QuerySets because querysets are unique.
133 | self.assertEqual(list(self.responses['topic_detail'].context['question_list']),
134 | list(self.topics['published'].questions.published()))
135 |
136 | def testQuestionDetail(self):
137 | # Redirects to a fragment identifier on the topic detail.
138 | self.assertRedirects(self.responses['question_detail'],
139 | '/shipping/#how-much-does-shipping-cost', status_code=301)
140 |
141 |
142 | class ViewsDeepTestCase(ViewsNormalTestCase):
143 | """"""
144 |
145 | urls = 'faq.urls.deep'
146 |
147 | def testQuestionDetail(self):
148 | # Does not redirect.
149 | self.assertEqual(self.responses['question_detail'].status_code, 200)
150 | # Check for our extra_context.
151 | self.assertEqual(self.responses['question_detail'].context['topic'],
152 | self.questions['published'].topic)
153 |
--------------------------------------------------------------------------------
/faq/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.conf import settings
3 | from django.contrib.sites.models import Site
4 | from django.template.defaultfilters import slugify
5 | from django.utils.translation import ugettext_lazy as _
6 |
7 | from faq.settings import DRAFTED, PUBLISHED, REMOVED, STATUS_CHOICES
8 |
9 |
10 | # Managers.
11 |
12 | def _field_lookups(model, status=None):
13 | """
14 | Abstraction of field lookups for managers.
15 |
16 | Returns a dictionary of field lookups for a queryset. The lookups
17 | will always filter by site. Optionally, if ``status`` is passed to
18 | the function the objects will also be filtered by the given status.
19 |
20 | This function saves from having to make two different on-site and
21 | published Managers each for `Topic` and `Question`, and having to move
22 | Managers out of the `FAQBase` model and into each of the `Topic`
23 | and `Question` models.
24 |
25 | """
26 | # Import models here to avoid circular import fail.
27 | from faq.models import Topic, Question
28 |
29 | field_lookups = {}
30 |
31 | if model == Topic:
32 | field_lookups['sites__pk'] = settings.SITE_ID
33 |
34 | if model == Question:
35 | field_lookups['topic__sites__pk'] = settings.SITE_ID
36 | if status:
37 | field_lookups['topic__status'] = status
38 |
39 | # Both Topic & Question have a status field.
40 | if status:
41 | field_lookups['status'] = status
42 |
43 | return field_lookups
44 |
45 |
46 | class OnSiteManager(models.Manager):
47 | """Custom manager providing shortcuts for filtering by status."""
48 |
49 | def on_site(self):
50 | """Returns only items related to the current site."""
51 | return self.get_query_set().filter(**_field_lookups(self.model))
52 |
53 | def drafted(self):
54 | """Returns only on-site items with a status of 'drafted'."""
55 | return self.get_query_set().filter(
56 | **_field_lookups(self.model, DRAFTED))
57 |
58 | def published(self):
59 | """Returns only on-site items with a status of 'published'."""
60 | return self.get_query_set().filter(
61 | **_field_lookups(self.model, PUBLISHED))
62 |
63 | def removed(self):
64 | """Returns only on-site items with a status of 'removed'."""
65 | return self.get_query_set().filter(
66 | **_field_lookups(self.model, REMOVED))
67 |
68 |
69 | # Models.
70 |
71 | class FAQBase(models.Model):
72 | """A model holding information common to Topics and Questions."""
73 |
74 | created = models.DateTimeField(_(u'date created'), auto_now_add=True)
75 | modified = models.DateTimeField(_(u'date modified'), auto_now=True)
76 | status = models.IntegerField(_(u'status'), choices=STATUS_CHOICES,
77 | # TODO: Genericize/fix the help_text.
78 | db_index=True, default=DRAFTED, help_text=_(u'Only objects with \
79 | "published" status will be displayed publicly.'))
80 |
81 | objects = OnSiteManager()
82 |
83 | class Meta:
84 | abstract = True
85 | get_latest_by = 'modified'
86 |
87 |
88 | class Topic(FAQBase):
89 | """A topic that a Question can belong to."""
90 |
91 | title = models.CharField(_(u'title'), max_length=255)
92 | slug = models.SlugField(_(u'slug'), unique=True, help_text=_(u'Used in \
93 | the URL for the topic. Must be unique.'))
94 | description = models.TextField(_(u'description'), blank=True,
95 | help_text=_(u'A short description of this topic.'))
96 | sites = models.ManyToManyField(Site, verbose_name=_(u'sites'),
97 | related_name='faq_topics')
98 |
99 | class Meta(FAQBase.Meta):
100 | ordering = ('title', 'slug')
101 | verbose_name = _(u'topic')
102 | verbose_name_plural = _(u'topics')
103 |
104 | def __unicode__(self):
105 | return self.title
106 |
107 | @models.permalink
108 | def get_absolute_url(self):
109 | return ('faq-topic-detail', (), {'slug': self.slug})
110 |
111 |
112 | class Question(FAQBase):
113 | """A frequently asked question."""
114 |
115 | question = models.CharField(_(u'question'), max_length=255)
116 | slug = models.SlugField(_(u'slug'), unique=True, help_text=_(u'Used in \
117 | the URL for the Question. Must be unique.'))
118 | answer = models.TextField(_(u'answer'))
119 | topic = models.ForeignKey(Topic, verbose_name=_(u'topic'),
120 | related_name='questions')
121 | ordering = models.PositiveSmallIntegerField(_(u'ordering'), blank=True,
122 | db_index=True, help_text=_(u'An integer used to order the question \
123 | amongst others related to the same topic. If not given this \
124 | question will be last in the list.'))
125 |
126 | class Meta(FAQBase.Meta):
127 | ordering = ('ordering', 'question', 'slug')
128 | verbose_name = _(u'question')
129 | verbose_name_plural = _(u'questions')
130 |
131 | def __unicode__(self):
132 | return self.question
133 |
134 | def save(self, *args, **kwargs):
135 | if not self.slug:
136 | # We populate the slug here because the common case for adding an
137 | # Question is as an inline to a Topic and InlineModelAdmin does not
138 | # currently support ``prepopulated_fields`` and it's mean to make
139 | # the user supply a slug by hand.
140 | self.slug = slugify(self.question)[:50]
141 | if not self.ordering:
142 | # When adding an Question to a Topic, it's easy to overlook the
143 | # ordering. We don't want to throw an error if it's left blank,
144 | # so to be nice we'll just put it at the end of the list.
145 | try:
146 | # Find the highest ordering value for all other Questions
147 | # related to the same topic and add 1.
148 | ordering = self.topic.questions.exclude(pk=self.pk).aggregate(
149 | models.Max('ordering'))['ordering__max'] + 1
150 | except TypeError:
151 | # There are no other related Questions, so let's set this
152 | # as no. 1.
153 | ordering = 1
154 | self.ordering = ordering
155 | super(Question, self).save(*args, **kwargs)
156 |
157 | @models.permalink
158 | def get_absolute_url(self):
159 | return ('faq-question-detail', (), {'topic_slug': self.topic.slug,
160 | 'slug': self.slug})
161 |
--------------------------------------------------------------------------------
/faq/fixtures/test_data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "pk": 3,
4 | "model": "faq.topic",
5 | "fields": {
6 | "status": 3,
7 | "description": "All about \u2026 US!",
8 | "title": "About us",
9 | "created": "2011-06-07 15:21:44",
10 | "modified": "2011-06-07 15:30:31",
11 | "sites": [
12 | 2
13 | ],
14 | "slug": "about-us"
15 | }
16 | },
17 | {
18 | "pk": 5,
19 | "model": "faq.topic",
20 | "fields": {
21 | "status": 3,
22 | "description": "Sshhh!",
23 | "title": "Black market items",
24 | "created": "2011-06-07 15:26:07",
25 | "modified": "2011-06-07 15:26:07",
26 | "sites": [
27 | 1
28 | ],
29 | "slug": "black-market-items"
30 | }
31 | },
32 | {
33 | "pk": 2,
34 | "model": "faq.topic",
35 | "fields": {
36 | "status": 2,
37 | "description": "All about returning an unwanted item.",
38 | "title": "Returns",
39 | "created": "2011-06-07 11:33:25",
40 | "modified": "2011-06-07 15:29:41",
41 | "sites": [
42 | 1,
43 | 2
44 | ],
45 | "slug": "returns"
46 | }
47 | },
48 | {
49 | "pk": 1,
50 | "model": "faq.topic",
51 | "fields": {
52 | "status": 2,
53 | "description": "All about how we ship your purchase to you.",
54 | "title": "Shipping",
55 | "created": "2011-06-07 11:31:15",
56 | "modified": "2011-06-07 15:28:46",
57 | "sites": [
58 | 1
59 | ],
60 | "slug": "shipping"
61 | }
62 | },
63 | {
64 | "pk": 4,
65 | "model": "faq.topic",
66 | "fields": {
67 | "status": 1,
68 | "description": "About our website.",
69 | "title": "Website",
70 | "created": "2011-06-07 15:23:59",
71 | "modified": "2011-06-07 15:23:59",
72 | "sites": [
73 | 1,
74 | 2
75 | ],
76 | "slug": "website"
77 | }
78 | },
79 | {
80 | "pk": 4,
81 | "model": "faq.question",
82 | "fields": {
83 | "status": 2,
84 | "created": "2011-06-07 15:21:44",
85 | "ordering": 1,
86 | "question": "Are you hiring?",
87 | "modified": "2011-06-07 15:21:44",
88 | "topic": 3,
89 | "answer": "Yes and no. If you are awesome, yes. If you are less than awesome, then not so much.",
90 | "slug": "are-you-hiring"
91 | }
92 | },
93 | {
94 | "pk": 5,
95 | "model": "faq.question",
96 | "fields": {
97 | "status": 2,
98 | "created": "2011-06-07 15:23:59",
99 | "ordering": 1,
100 | "question": "Do you have an SLA?",
101 | "modified": "2011-06-07 15:23:59",
102 | "topic": 4,
103 | "answer": "No, because people with those get hosed.",
104 | "slug": "do-you-have-an-sla"
105 | }
106 | },
107 | {
108 | "pk": 6,
109 | "model": "faq.question",
110 | "fields": {
111 | "status": 2,
112 | "created": "2011-06-07 15:26:07",
113 | "ordering": 1,
114 | "question": "How do you acquire black market items?",
115 | "modified": "2011-06-07 15:26:07",
116 | "topic": 5,
117 | "answer": "Very, very carefully",
118 | "slug": "how-do-you-acquire-black-market-items"
119 | }
120 | },
121 | {
122 | "pk": 3,
123 | "model": "faq.question",
124 | "fields": {
125 | "status": 2,
126 | "created": "2011-06-07 11:33:25",
127 | "ordering": 1,
128 | "question": "How long do I have to return my item?",
129 | "modified": "2011-06-07 11:33:25",
130 | "topic": 2,
131 | "answer": "We are very liberal with this, but it is generally 20-30 minutes.",
132 | "slug": "how-long-do-i-have-to-return-my-item"
133 | }
134 | },
135 | {
136 | "pk": 1,
137 | "model": "faq.question",
138 | "fields": {
139 | "status": 2,
140 | "created": "2011-06-07 11:31:15",
141 | "ordering": 1,
142 | "question": "How much does shipping cost?",
143 | "modified": "2011-06-07 11:31:15",
144 | "topic": 1,
145 | "answer": "Not much. At last check it was just shy of one frillion dollars.",
146 | "slug": "how-much-does-shipping-cost"
147 | }
148 | },
149 | {
150 | "pk": 2,
151 | "model": "faq.question",
152 | "fields": {
153 | "status": 2,
154 | "created": "2011-06-07 11:32:14",
155 | "ordering": 2,
156 | "question": "How fast will my item arrive?",
157 | "modified": "2011-06-07 11:32:14",
158 | "topic": 1,
159 | "answer": "Sometime next week. We think.",
160 | "slug": "how-fast-will-my-item-arrive"
161 | }
162 | },
163 | {
164 | "pk": 7,
165 | "model": "faq.question",
166 | "fields": {
167 | "status": 1,
168 | "created": "2011-06-07 15:28:46",
169 | "ordering": 3,
170 | "question": "In what color box do you ship?",
171 | "modified": "2011-06-07 15:28:46",
172 | "topic": 1,
173 | "answer": "Green, because it is good for the environment. Go us!",
174 | "slug": "in-what-color-box-do-you-ship"
175 | }
176 | },
177 | {
178 | "pk": 8,
179 | "model": "faq.question",
180 | "fields": {
181 | "status": 3,
182 | "created": "2011-06-07 15:28:46",
183 | "ordering": 4,
184 | "question": "What carrier do you use?",
185 | "modified": "2011-06-07 15:28:46",
186 | "topic": 1,
187 | "answer": "Whomever saves us the most money.",
188 | "slug": "what-carrier-do-you-use"
189 | }
190 | },
191 | {
192 | "pk": 1,
193 | "model": "sites.site",
194 | "fields": {
195 | "domain": "example.com",
196 | "name": "example.com"
197 | }
198 | },
199 | {
200 | "pk": 2,
201 | "model": "sites.site",
202 | "fields": {
203 | "domain": "example.us",
204 | "name": "example.us"
205 | }
206 | }
207 | ]
208 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # django-faq documentation build configuration file, created by
4 | # sphinx-quickstart on Sat Sep 17 13:09:21 2011.
5 | #
6 | # This file is execfile()d with the current directory set to its containing dir.
7 | #
8 | # Note that not all possible configuration values are present in this
9 | # autogenerated file.
10 | #
11 | # All configuration values have a default; values that are commented out
12 | # serve to show the default.
13 |
14 | import sys, os
15 |
16 | # If extensions (or modules to document with autodoc) are in another directory,
17 | # add these directories to sys.path here. If the directory is relative to the
18 | # documentation root, use os.path.abspath to make it absolute, like shown here.
19 | #sys.path.insert(0, os.path.abspath('.'))
20 |
21 | # -- General configuration -----------------------------------------------------
22 |
23 | # If your documentation needs a minimal Sphinx version, state it here.
24 | #needs_sphinx = '1.0'
25 |
26 | # Add any Sphinx extension module names here, as strings. They can be extensions
27 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
28 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx']
29 |
30 | intersphinx_mapping = {
31 | 'python': ('http://python.readthedocs.org/en/latest/', None),
32 | 'django': ('http://django.readthedocs.org/en/latest/', None),
33 | 'sphinx': ('http://sphinx.readthedocs.org/en/latest/', None),
34 | }
35 |
36 | # Add any paths that contain templates here, relative to this directory.
37 | # templates_path = ['_templates']
38 |
39 | # The suffix of source filenames.
40 | source_suffix = '.rst'
41 |
42 | # The encoding of source files.
43 | #source_encoding = 'utf-8-sig'
44 |
45 | # The master toctree document.
46 | master_doc = 'index'
47 |
48 | # General information about the project.
49 | project = u'django-faq'
50 | copyright = u'2011, Ben Spaulding'
51 |
52 | # The version info for the project you're documenting, acts as replacement for
53 | # |version| and |release|, also used in various other places throughout the
54 | # built documents.
55 | #
56 | # The short X.Y version.
57 | version = '0.8'
58 | # The full version, including alpha/beta/rc tags.
59 | release = '0.8.2'
60 |
61 | # The language for content autogenerated by Sphinx. Refer to documentation
62 | # for a list of supported languages.
63 | #language = None
64 |
65 | # There are two options for replacing |today|: either, you set today to some
66 | # non-false value, then it is used:
67 | #today = ''
68 | # Else, today_fmt is used as the format for a strftime call.
69 | #today_fmt = '%B %d, %Y'
70 |
71 | # List of patterns, relative to source directory, that match files and
72 | # directories to ignore when looking for source files.
73 | exclude_patterns = ['_build']
74 |
75 | # The reST default role (used for this markup: `text`) to use for all documents.
76 | #default_role = None
77 |
78 | # If true, '()' will be appended to :func: etc. cross-reference text.
79 | #add_function_parentheses = True
80 |
81 | # If true, the current module name will be prepended to all description
82 | # unit titles (such as .. function::).
83 | #add_module_names = True
84 |
85 | # If true, sectionauthor and moduleauthor directives will be shown in the
86 | # output. They are ignored by default.
87 | #show_authors = False
88 |
89 | # The name of the Pygments (syntax highlighting) style to use.
90 | pygments_style = 'sphinx'
91 |
92 | # A list of ignored prefixes for module index sorting.
93 | #modindex_common_prefix = []
94 |
95 |
96 | # -- Options for HTML output ---------------------------------------------------
97 |
98 | # The theme to use for HTML and HTML Help pages. See the documentation for
99 | # a list of builtin themes.
100 | html_theme = 'default'
101 |
102 | # Theme options are theme-specific and customize the look and feel of a theme
103 | # further. For a list of options available for each theme, see the
104 | # documentation.
105 | #html_theme_options = {}
106 |
107 | # Add any paths that contain custom themes here, relative to this directory.
108 | #html_theme_path = []
109 |
110 | # The name for this set of Sphinx documents. If None, it defaults to
111 | # " v documentation".
112 | #html_title = None
113 |
114 | # A shorter title for the navigation bar. Default is the same as html_title.
115 | #html_short_title = None
116 |
117 | # The name of an image file (relative to this directory) to place at the top
118 | # of the sidebar.
119 | #html_logo = None
120 |
121 | # The name of an image file (within the static path) to use as favicon of the
122 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
123 | # pixels large.
124 | #html_favicon = None
125 |
126 | # Add any paths that contain custom static files (such as style sheets) here,
127 | # relative to this directory. They are copied after the builtin static files,
128 | # so a file named "default.css" will overwrite the builtin "default.css".
129 | # html_static_path = ['_static']
130 |
131 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
132 | # using the given strftime format.
133 | #html_last_updated_fmt = '%b %d, %Y'
134 |
135 | # If true, SmartyPants will be used to convert quotes and dashes to
136 | # typographically correct entities.
137 | #html_use_smartypants = True
138 |
139 | # Custom sidebar templates, maps document names to template names.
140 | #html_sidebars = {}
141 |
142 | # Additional templates that should be rendered to pages, maps page names to
143 | # template names.
144 | #html_additional_pages = {}
145 |
146 | # If false, no module index is generated.
147 | #html_domain_indices = True
148 |
149 | # If false, no index is generated.
150 | #html_use_index = True
151 |
152 | # If true, the index is split into individual pages for each letter.
153 | #html_split_index = False
154 |
155 | # If true, links to the reST sources are added to the pages.
156 | #html_show_sourcelink = True
157 |
158 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
159 | #html_show_sphinx = True
160 |
161 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
162 | #html_show_copyright = True
163 |
164 | # If true, an OpenSearch description file will be output, and all pages will
165 | # contain a tag referring to it. The value of this option must be the
166 | # base URL from which the finished HTML is served.
167 | #html_use_opensearch = ''
168 |
169 | # This is the file name suffix for HTML files (e.g. ".xhtml").
170 | #html_file_suffix = None
171 |
172 | # Output file base name for HTML help builder.
173 | htmlhelp_basename = 'django-faqdoc'
174 |
175 |
176 | # -- Options for LaTeX output --------------------------------------------------
177 |
178 | # The paper size ('letter' or 'a4').
179 | #latex_paper_size = 'letter'
180 |
181 | # The font size ('10pt', '11pt' or '12pt').
182 | #latex_font_size = '10pt'
183 |
184 | # Grouping the document tree into LaTeX files. List of tuples
185 | # (source start file, target name, title, author, documentclass [howto/manual]).
186 | latex_documents = [
187 | ('index', 'django-faq.tex', u'django-faq Documentation',
188 | u'Ben Spaulding', 'manual'),
189 | ]
190 |
191 | # The name of an image file (relative to this directory) to place at the top of
192 | # the title page.
193 | #latex_logo = None
194 |
195 | # For "manual" documents, if this is true, then toplevel headings are parts,
196 | # not chapters.
197 | #latex_use_parts = False
198 |
199 | # If true, show page references after internal links.
200 | #latex_show_pagerefs = False
201 |
202 | # If true, show URL addresses after external links.
203 | #latex_show_urls = False
204 |
205 | # Additional stuff for the LaTeX preamble.
206 | #latex_preamble = ''
207 |
208 | # Documents to append as an appendix to all manuals.
209 | #latex_appendices = []
210 |
211 | # If false, no module index is generated.
212 | #latex_domain_indices = True
213 |
214 |
215 | # -- Options for manual page output --------------------------------------------
216 |
217 | # One entry per manual page. List of tuples
218 | # (source start file, name, description, authors, manual section).
219 | man_pages = [
220 | ('index', 'django-faq', u'django-faq Documentation',
221 | [u'Ben Spaulding'], 1)
222 | ]
223 |
224 |
225 | # Example configuration for intersphinx: refer to the Python standard library.
226 | intersphinx_mapping = {'http://docs.python.org/': None}
227 |
--------------------------------------------------------------------------------