diff --git a/.gitignore b/.gitignore
index ba996bc..c915ae7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,8 +42,8 @@ docs/build
 lokalize*
 
 .idea
-docs
+docs/_build
 
 *~
 *.db
-*.sqlite
\ No newline at end of file
+*.sqlite
diff --git a/.travis.yml b/.travis.yml
index 74ad3dc..5ee0640 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,7 @@ env:
   matrix:
   - TOXENV='pep8'
   - TOXENV='isort'
+  - TOXENV='docs'
   - DJANGO='django19' CMS='cms33'
   - DJANGO='django19' CMS='cms32'
   - DJANGO='django19' CMS='knocker'
@@ -38,10 +39,14 @@ after_success:
 
 matrix:
   exclude:
+  - python: 2.7
+    env: TOXENV='docs'
   - python: 2.7
     env: TOXENV='pep8'
   - python: 2.7
     env: TOXENV='isort'
+  - python: 3.4
+    env: TOXENV='docs'
   - python: 3.4
     env: TOXENV='pep8'
   - python: 3.4
diff --git a/README.rst b/README.rst
index 47531d6..24cbbca 100644
--- a/README.rst
+++ b/README.rst
@@ -75,427 +75,12 @@ Features
 * Support for django CMS 3.2+ Wizard
 * Haystack index support
 
-Quickstart
-----------
+Documentation
+-------------
 
-Install djangocms-blog::
-
-    pip install djangocms-blog
-
-Add ``djangocms_blog`` and its dependencies to INSTALLED_APPS::
-
-    INSTALLED_APPS = [
-        ...
-        'filer',
-        'easy_thumbnails',
-        'aldryn_apphooks_config',
-        'cmsplugin_filer_image',
-        'parler',
-        'taggit',
-        'taggit_autosuggest',
-        'meta',
-        'djangocms_blog',
-        ...
-    ]
-
-
-Then migrate::
-
-    $ python manage.py migrate
-
-External applications configuration
-+++++++++++++++++++++++++++++++++++
-
-Dependency applications may need configuration to work properly.
-
-Please, refer to each application documentation on details.
-
-* django-filer: http://django-filer.readthedocs.org
-* django-meta: https://github.com/nephila/django-meta#installation
-* django-meta-mixin: https://github.com/nephila/django-meta-mixin#installation
-* django-parler: http://django-parler.readthedocs.org/en/latest/quickstart.html#configuration
-* django-taggit-autosuggest: https://bitbucket.org/fabian/django-taggit-autosuggest
-
-Quick hint
-++++++++++
-
-The following are minimal defaults to get the blog running; they may not be
-suited for your deployment.
-
-* Add the following settings to your project::
-
-    THUMBNAIL_PROCESSORS = (
-        'easy_thumbnails.processors.colorspace',
-        'easy_thumbnails.processors.autocrop',
-        'filer.thumbnail_processors.scale_and_crop_with_subject_location',
-        'easy_thumbnails.processors.filters',
-    )
-    META_SITE_PROTOCOL = 'http'
-    META_USE_SITES = True
-
-* Configure parler according to your languages::
-
-    PARLER_LANGUAGES = {
-        1: (
-            {'code': 'en',},
-            {'code': 'it',},
-            {'code': 'fr',},
-        ),
-        'default': {
-            'fallbacks': ['en', 'it', 'fr'],
-        }
-    }
-
-* Add the following to your ``urls.py``::
-
-    url(r'^taggit_autosuggest/', include('taggit_autosuggest.urls')),
-
-* To start your blog you need to use `AppHooks from django CMS <http://django-cms.readthedocs.org/en/support-3.0.x/how_to/apphooks.html>`_
-  to add the blog to a django CMS page; this step is not required when using
-  `Auto setup <auto_setup>`_:
-
-  * Create a new django CMS page
-  * Go to **Advanced settings** and select Blog from the **Application** selector and
-    create an **Application configuration**;
-  * Eventually customise the Application instance name;
-  * Publish the page
-  * Restart the project instance to properly load blog urls.
-
-.. warning:: After adding the apphook to the page you **cannot** change the **Instance Namspace**
-             field for the defined **AppHokConfig**; if you want to change it, create a new one
-             with the correct namespace, go in the CMS page **Advanced settings** and switch to the
-             new **Application configuration**
-
-* Add and edit blog by creating them in the admin or using the toolbar,
-  and the use the `django CMS frontend editor <http://django-cms.readthedocs.org/en/support-3.0.x/user/reference/page_admin.html#the-interface>`_
-  to edit the blog content:
-
-  * Create a new blog entry in django admin backend or from the toolbar
-  * Click on "view on site" button to view the post detail page
-  * Edit the post via djangocms frontend by adding / editing plugins
-  * Publish the blog post by flagging the "Publish" switch in the blog post
-    admin
-
-Configurable permalinks
-+++++++++++++++++++++++
-
-Blog comes with four different styles of permalinks styles:
-
-* Full date: ``YYYY/MM/DD/SLUG``
-* Year /  Month: ``YYYY/MM/SLUG``
-* Category: ``CATEGORY/SLUG``
-* Just slug: ``SLUG``
-
-As all the styles are loaded in the urlconf, the latter two does not allow
-to have CMS pages beneath the page the blog is attached to. If you want to
-do this, you have to override the default urlconfs by setting something
-like the following in the project settings::
-
-    BLOG_PERMALINK_URLS = {
-        'full_date': r'^(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<slug>\w[-\w]*)/$',
-        'short_date': r'^(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<slug>\w[-\w]*)/$',
-        'category': r'^post/(?P<category>\w[-\w]*)/(?P<slug>\w[-\w]*)/$',
-        'slug': r'^post/(?P<slug>\w[-\w]*)/$',
-    }
-
-And change ``post/`` with the desired prefix.
-
-Attaching blog to the home page
-+++++++++++++++++++++++++++++++
-
-If you want to attach the blog to the home page you have to adapt settings a bit otherwise the
-"Just slug" permalink will swallow any CMS page you create.
-
-To avoit this add the following settings to you project::
-
-    BLOG_PERMALINKS = (
-        ('full_date', _('Full date')),
-        ('short_date', _('Year /  Month')),
-        ('category', _('Category')),
-    )
-    BLOG_PERMALINKS_URLS = {
-        'full_date': r'^(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<slug>\w[-\w]*)/$',
-        'short_date': r'^(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<slug>\w[-\w]*)/$',
-        'category': r'^(?P<category>\w[-\w]*)/(?P<slug>\w[-\w]*)/$',
-    }
-
-Notice that the last permalink type is no longer present.
-
-Then, pick any of the three remaining permalink types in the layout section of the apphooks config
-linked ot the home page (see http://yoursite.com/admin/djangocms_blog/blogconfig/).'
-
-Menu
-++++
-
-``djangocms_blog`` provides support for django CMS menu framework.
-
-By default all the categories and posts are added to the menu, in a hierarchical structure.
-
-It is possibile to configure per Apphook, whether the menu includes post and categories
-(the default), only categories, only posts or no item.
-
-If "post and categories" or "only categories" are set, all the posts not associated with a
-category are not added to the menu.
-
-Templates
-+++++++++
-
-To ease the template customisations a ``djangocms_blog/base.html`` template is
-used by all the blog templates; the templates itself extends a ``base.html``
-template; content is pulled in the ``content`` block.
-If you need to define a different base template, or if your base template does
-not defines a ``content`` block, copy in your template directory
-``djangocms_blog/base.html`` and customise it according to your needs; the
-other application templates will use the newly created base template and
-will ignore the bundled one.
-
-Templates set
-+++++++++++++
-
-By using **Apphook configuration** you can define a different templates set.
-To use this feature provide a directory name in **Template prefix** field in
-the **Apphook configuration** admin (in *Layout* section): it will be the
-root of your custom templates set.
-
-.. _auto_setup:
-
-Auto setup
-++++++++++
-
-``djangocms_blog`` can install and configue itself if it does not find any
-attached instance of itself.
-This feature is enable by default and will create:
-
-* a ``BlogConfig`` with default values
-* a ``Blog`` CMS page and will attach ``djangocms_blog`` instance to it
-* a **home page** if no home is found.
-
-All the items will be created in every language configured for the website
-and the pages will be published. If not using **aldryn-apphook-reload** or
-**django CMS 3.2** auto-reload middleware you are required to reload the
-project instance after this.
-This will only work for the current website as detected by
-``Site.objects.get_current()``.
-
-
-The auto setup is execute once for each server start but it will skip any
-action if a ``BlogConfig`` instance is found.
-
-
-Sitemap
-+++++++
-
-``djangocms_blog`` provides a sitemap for improved SEO indexing.
-Sitemap returns all the published posts in all the languages each post is available.
-
-The changefreq and priority is configurable per-apphook (see ``BLOG_SITEMAP_*`` in
-`Global settings <settings>`_).
-
-To add the blog Sitemap, add the following code to the project ``urls.py``::
-
-
-    from cms.sitemaps import CMSSitemap
-    from djangocms_blog.sitemaps import BlogSitemap
-
-
-    urlpatterns = patterns(
-        '',
-        ...
-        url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap',
-            {'sitemaps': {
-                'cmspages': CMSSitemap, 'blog': BlogSitemap,
-            }
-        }),
-    )
-
-Multisite
-+++++++++
-
-django CMS blog provides full support for multisite setups.
-
-Each blog post can be assigned to none, one or more sites: if no site is selected, then
-it's visible on all sites.
-
-This is matched with and API that allows to restrict users to only be able to edit
-blog posts only for some sites.
-
-To implement this API, you must add a ``get_sites`` method on the user model which
-returns a queryset of sites the user is allowed to add posts to.
-
-Example::
-
-    class CustomUser(AbstractUser):
-        sites = models.ManyToManyField('sites.Site')
-
-        def get_sites(self):
-            return self.sites
-
-
-django CMS 3.2+ Wizard
-++++++++++++++++++++++
-
-django CMS 3.2+ provides a content creation wizard that allows to quickly created supported
-content types, such as blog posts.
-
-For each configured Apphook, a content type is added to the wizard.
-
-Some issues with multiple registrations raising django CMS ``AlreadyRegisteredException``
-hae been reported; to handle these cases gracefully, the exception is swallowed
-when Django ``DEBUG == True`` avoiding breaking production websites. In these cases they
-wizard may not show up, but the rest will work as intended.
-
-django-knocker
-++++++++++++++
-
-``djangocms-blog`` is integrated with `django-knocker <https://github.com/nephila/django-knocker>`_
-to provide real time desktop notifications.
-
-See `django-knocker documentation <https://django-knocker.readthedocs.org/>`_ for how to configure
-knocker.
-
-.. _settings:
-
-Global Settings
----------------
-* BLOG_IMAGE_THUMBNAIL_SIZE: Size of the main image when shown on the post
-  lists; it's a dictionary with ``size``, ``crop`` and ``upscale`` keys;
-  (default: ``{'size': '120x120', 'crop': True,'upscale': False}``)
-* BLOG_IMAGE_FULL_SIZE: Size of the main image when shown on the post
-  detail; it's a dictionary with ``size``, ``crop`` and ``upscale`` keys;
-  (default: ``{'size': '640x120', 'crop': True,'upscale': False}``)
-* BLOG_PAGINATION: Number of post per page; (default: ``10``)
-* BLOG_LATEST_POSTS: Default number of post in the **Latest post** plugin;
-  (default: ``5``)
-* BLOG_POSTS_LIST_TRUNCWORDS_COUNT: Default number of words shown for
-  abstract in the post list; (default: ``100``)
-* BLOG_TYPE: Generic type for the post object; (default: ``Article``)
-* BLOG_TYPES: Choices of available blog types;
-  (default: to ``META_OBJECT_TYPES`` defined in `django-meta-mixin settings`_)
-* BLOG_FB_TYPE: Open Graph type for the post object; (default: ``Article``)
-* BLOG_FB_TYPES: Choices of available blog types;
-  (default: to ``META_FB_TYPES`` defined in `django-meta-mixin settings`_)
-* BLOG_FB_APPID: Facebook Application ID
-* BLOG_FB_PROFILE_ID: Facebook profile ID of the post author
-* BLOG_FB_PUBLISHER: Facebook URL of the blog publisher
-* BLOG_FB_AUTHOR_URL: Facebook profile URL of the post author
-* BLOG_FB_AUTHOR: Facebook profile URL of the post author
-* BLOG_TWITTER_TYPE: Twitter Card type for the post object;
-  (default: ``Summary``)
-* BLOG_TWITTER_TYPES: Choices of available blog types for twitter;
-  (default: to ``META_TWITTER_TYPES`` defined in `django-meta-mixin settings`_)
-* BLOG_TWITTER_SITE: Twitter account of the site
-* BLOG_TWITTER_AUTHOR: Twitter account of the post author
-* BLOG_GPLUS_TYPE: Google+ Snippet type for the post object;
-  (default: ``Blog``)
-* BLOG_GPLUS_TYPES: Choices of available blog types for twitter;
-  (default: to ``META_GPLUS_TYPES`` defined in `django-meta-mixin settings`_)
-* BLOG_GPLUS_AUTHOR: Google+ account of the post author
-* BLOG_ENABLE_COMMENTS: Whether to enable comments by default on posts;
-  while ``djangocms_blog`` does not ship any comment system, this flag
-  can be used to control the chosen comments framework; (default: ``True``)
-* BLOG_USE_ABSTRACT: Use an abstract field for the post; if ``False``
-  no abstract field is available for every post; (default: ``True``)
-* BLOG_USE_PLACEHOLDER: Post content is managed via placeholder;
-  if ``False`` a simple HTMLField is used; (default: ``True``)
-* BLOG_MULTISITE: Add support for multisite setup; (default: ``True``)
-* BLOG_AUTHOR_DEFAULT: Use a default if not specified; if set to ``True`` the
-  current user is set as the default author, if set to ``False`` no default
-  author is set, if set to a string the user with the provided username is
-  used; (default: ``True``)
-* BLOG_DEFAULT_PUBLISHED: If posts are marked as published by default;
-  (default: ``False``)
-* BLOG_ADMIN_POST_FIELDSET_FILTER: Callable function to change(add or filter)
-  fields to fieldsets for admin post edit form; (default: ``False``). Function simple example::
-
-
-    def fieldset_filter_function(fsets, request, obj=None):
-        if request.user.groups.filter(name='Editor').exists():
-            fsets[1][1]['fields'][0].append('author')  # adding 'author' field if user is Editor
-        return fsets
-
-
-* BLOG_AVAILABLE_PERMALINK_STYLES: Choices of permalinks styles;
-* BLOG_PERMALINK_URLS: URLConf corresponding to
-  BLOG_AVAILABLE_PERMALINK_STYLES;
-* BLOG_DEFAULT_OBJECT_NAME: Default name for Blog item (used in django CMS Wizard);
-* BLOG_AUTO_SETUP: Enable the blog **Auto setup** feature; (default: ``True``)
-* BLOG_AUTO_HOME_TITLE: Title of the home page created by **Auto setup**;
-  (default: ``Home``)
-* BLOG_AUTO_BLOG_TITLE: Title of the blog page created by **Auto setup**;
-  (default: ``Blog``)
-* BLOG_AUTO_APP_TITLE: Title of the ``BlogConfig`` instance created by
-  **Auto setup**; (default: ``Blog``)
-* BLOG_SITEMAP_PRIORITY_DEFAULT: Default priority for sitemap items; (default: ``0.5``)
-* BLOG_SITEMAP_CHANGEFREQ: List for available changefreqs for sitemap items; (default: **always**,
-  **hourly**, **daily**, **weekly**, **monthly**, **yearly**, **never**)
-* BLOG_SITEMAP_CHANGEFREQ_DEFAULT: Default changefreq for sitemap items; (default: ``monthly``)
-* BLOG_CURRENT_POST_IDENTIFIER: Current post identifier in request (default ``djangocms_post_current``)
-* BLOG_CURRENT_NAMESPACE: Current post config identifier in request  (default: ``djangocms_post_current_config``)
-* BLOG_ENABLE_THROUGH_TOOLBAR_MENU: Is the toolbar menu throught whole all applications (default: ``False``)
-* BLOG_PLUGIN_MODULE_NAME: Blog plugin module name (default: ``Blog``)
-* BLOG_LATEST_ENTRIES_PLUGIN_NAME: Blog latest entries plugin name (default: ``Latest Blog Articles``)
-* BLOG_AUTHOR_POSTS_PLUGIN_NAME: Blog author posts plugin name (default: ``Author Blog Articles``)
-* BLOG_TAGS_PLUGIN_NAME: Blog tags plugin name (default: ``Tags``)
-* BLOG_CATEGORY_PLUGIN_NAME: Blog categories plugin name (default: ``Categories``)
-* BLOG_ARCHIVE_PLUGIN_NAME: Blog archive plugin name (default: ``Archive``)
-* BLOG_FEED_CACHE_TIMEOUT: Cache timeout for RSS feeds
-* BLOG_FEED_INSTANT_ITEMS: Number of items in Instant Article feed
-* BLOG_FEED_LATEST_ITEMS: Number of items in latest items feed
-* BLOG_FEED_TAGS_ITEMS: Number of items in per tags feed
-
-Read-only settings
-++++++++++++++++++
-
-* BLOG_MENU_TYPES: Available structures of the Blog menu; (default list **Posts and Categories**,
-  **Categories only**, **Posts only**, **None**)
-* BLOG_MENU_TYPE: Structure of the Blog menu;
-  (default: ``Posts and Categories``)
-
-
-Per-Apphook settings
---------------------
-
-* application title: Free text title that can be used as title in templates;
-* object name: Free text label for Blog items in django CMS Wizard;
-* Post published by default: Per-Apphook setting for BLOG_DEFAULT_PUBLISHED;
-* Permalink structure: Per-Apphook setting for
-  BLOG_AVAILABLE_PERMALINK_STYLES;
-* Use placeholder and plugins for article body: Per-Apphook setting for
-  BLOG_USE_PLACEHOLDER;
-* Use abstract field: Per-Apphook setting for BLOG_USE_ABSTRACT;
-* Set author: Per-Apphook setting for BLOG_AUTHOR_DEFAULT;
-* Paginate sizePer-Apphook setting for BLOG_PAGINATION;
-* Template prefix: Alternative directory to load the blog templates from;
-* Menu structure: Per-Apphook setting for BLOG_MENU_TYPE
-* Sitemap changefreq: Per-Apphook setting for BLOG_SITEMAP_CHANGEFREQ_DEFAULT
-* Sitemap priority: Per-Apphook setting for BLOG_SITEMAP_PRIORITY_DEFAULT
-* Object type: Per-Apphook setting for BLOG_TYPE
-* Facebook type: Per-Apphook setting for BLOG_FB_TYPE
-* Facebook application ID: Per-Apphook setting for BLOG_FB_APP_ID
-* Facebook profile ID: Per-Apphook setting for BLOG_FB_PROFILE_ID
-* Facebook page URL: Per-Apphook setting for BLOG_FB_PUBLISHER
-* Facebook author URL: Per-Apphook setting for BLOG_AUTHOR_URL
-* Facebook author: Per-Apphook setting for BLOG_AUTHOR
-* Twitter type: Per-Apphook setting for BLOG_TWITTER_TYPE
-* Twitter site handle: Per-Apphook setting for BLOG_TWITTER_SITE
-* Twitter author handle: Per-Apphook setting for BLOG_TWITTER_AUTHOR
-* Google+ type: Per-Apphook setting for BLOG_GPLUS_TYPE
-* Google+ author name: Per-Apphook setting for BLOG_GPLUS_AUTHOR
-* Send notifications on post publish: Send desktop notifications when a post is published
-* Send notifications on post update: Send desktop notifications when a post is updated
-
-
-Import from Wordpress
-+++++++++++++++++++++
-
-If you want to import content from existing wordpress blog, check
-https://pypi.python.org/pypi/the-real-django-wordpress and
-this gist https://gist.github.com/yakky/11336204 as a base.
+Check documentation at http://djangocms-blog.readthedocs.io/en/latest/
 
 Known djangocms-blog websites
 +++++++++++++++++++++++++++++
 
 See DjangoPackages for an updated list https://www.djangopackages.com/packages/p/djangocms-blog/
-
-
-.. _django-meta-mixin settings: https://github.com/nephila/django-meta-mixin#settings
diff --git a/cms_helper.py b/cms_helper.py
index d332f59..28b737f 100755
--- a/cms_helper.py
+++ b/cms_helper.py
@@ -125,5 +125,11 @@ def run():
     from djangocms_helper import runner
     runner.cms('djangocms_blog')
 
+
+def setup():
+    import sys
+    from djangocms_helper import runner
+    runner.setup('djangocms_blog', sys.modules[__name__], use_cms=True)
+
 if __name__ == '__main__':
     run()
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..ef99d47
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,192 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  applehelp  to make an Apple Help Book"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@echo "  texinfo    to make Texinfo files"
+	@echo "  info       to make Texinfo files and run them through makeinfo"
+	@echo "  gettext    to make PO message catalogs"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  xml        to make Docutils-native XML files"
+	@echo "  pseudoxml  to make pseudoxml-XML files for display purposes"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+	@echo "  coverage   to run coverage check of the documentation (if enabled)"
+
+clean:
+	rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/djangocms-blog.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/djangocms-blog.qhc"
+
+applehelp:
+	$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
+	@echo
+	@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
+	@echo "N.B. You won't be able to view it unless you put it in" \
+	      "~/Library/Documentation/Help or install it in your application" \
+	      "bundle."
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/djangocms-blog"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/djangocms-blog"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	$(MAKE) -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+latexpdfja:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through platex and dvipdfmx..."
+	$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo
+	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+	@echo "Run \`make' in that directory to run these through makeinfo" \
+	      "(use \`make info' here to do that automatically)."
+
+info:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo "Running Texinfo files through makeinfo..."
+	make -C $(BUILDDIR)/texinfo info
+	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+	@echo
+	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
+
+coverage:
+	$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
+	@echo "Testing of coverage in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/coverage/python.txt."
+
+xml:
+	$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+	@echo
+	@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+pseudoxml:
+	$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+	@echo
+	@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
diff --git a/docs/_static/.directory b/docs/_static/.directory
new file mode 100644
index 0000000..e69de29
diff --git a/docs/_templates/.directory b/docs/_templates/.directory
new file mode 100644
index 0000000..e69de29
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..59f9fdc
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,305 @@
+# -*- coding: utf-8 -*-
+#
+# djangocms-blog documentation build configuration file, created by
+# sphinx-quickstart on Sun Jun  5 23:27:04 2016.
+#
+# 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.
+
+import sys
+import os
+import shlex
+
+# 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('.'))
+sys.path.insert(0, os.path.abspath('..'))
+sys.path.insert(0, os.path.abspath('../tests'))
+
+import cms_helper
+import djangocms_blog
+cms_helper.setup()
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# 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.doctest',
+    'sphinx.ext.intersphinx',
+    'sphinx.ext.todo',
+    'sphinx.ext.coverage',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+# source_suffix = ['.rst', '.md']
+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 = u'djangocms-blog'
+copyright = u'2016, Iacopo Spalletti'
+author = u'Iacopo Spalletti'
+
+# 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 = djangocms_blog.__version__
+# The full version, including alpha/beta/rc tags.
+release = djangocms_blog.__version__
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+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 = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = True
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+import sphinx_rtd_theme
+
+html_theme = "sphinx_rtd_theme"
+
+html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+
+
+# 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 = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_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
+
+# Language to be used for generating the HTML full-text search index.
+# Sphinx supports the following languages:
+#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
+#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
+#html_search_language = 'en'
+
+# A dictionary with options for the search language support, empty by default.
+# Now only 'ja' uses this config value
+#html_search_options = {'type': 'default'}
+
+# The name of a javascript file (relative to the configuration directory) that
+# implements a search results scorer. If empty, the default will be used.
+#html_search_scorer = 'scorer.js'
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'djangocms-blogdoc'
+
+# -- 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': '',
+
+# Latex figure (float) alignment
+#'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+#  author, documentclass [howto, manual, or own class]).
+latex_documents = [
+  (master_doc, 'djangocms-blog.tex', u'djangocms-blog Documentation',
+   u'Iacopo Spalletti', '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 = [
+    (master_doc, 'djangocms-blog', u'djangocms-blog Documentation',
+     [author], 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 = [
+  (master_doc, 'djangocms-blog', u'djangocms-blog Documentation',
+   author, 'djangocms-blog', 'One line description of project.',
+   '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'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
+
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {'https://docs.python.org/': None}
diff --git a/docs/contributing.rst b/docs/contributing.rst
new file mode 100644
index 0000000..3bdd7dc
--- /dev/null
+++ b/docs/contributing.rst
@@ -0,0 +1 @@
+.. include:: ../CONTRIBUTING.rst
\ No newline at end of file
diff --git a/docs/development.rst b/docs/development.rst
new file mode 100644
index 0000000..0b42a0d
--- /dev/null
+++ b/docs/development.rst
@@ -0,0 +1,39 @@
+#######################
+Development & community
+#######################
+
+django CMS Blog is an open-source project.
+
+You don't need to be an expert developer to make a valuable contribution - all you need is a little
+knowledge, and a willingness to follow the contribution guidelines.
+
+*******
+Nephila
+*******
+
+django CMS Blog was created by Iacopo Spalletti at `Nephila <https://www.nephila.it/>`_
+and is released under BSD License.
+
+Nephila is an active supporter of django CMS and its community, and it maintains overall
+control of the `django CMS Blog repository <https://github.com/nephila/djangocms-blog>`_.
+
+********************
+Standards & policies
+********************
+
+django CMS Blog is a django CMS application, and shares much of django CMS's standards and
+policies.
+
+These include:
+
+* `guidelines and policies
+  <http://docs.django-cms.org/en/latest/contributing/contributing.html>`_ for contributing
+  to the project, including standards for code and documentation
+* standards for `managing the project's development
+  <http://docs.django-cms.org/en/latest/contributing/management.html>`_
+* a `code of conduct
+  <http://docs.django-cms.org/en/latest/contributing/code_of_conduct.html>`_ for community
+  activity
+
+Please familiarise yourself with this documentation if you'd like to contribute to
+django CMS Blog.
diff --git a/docs/features.rst b/docs/features.rst
new file mode 100644
index 0000000..97c30e4
--- /dev/null
+++ b/docs/features.rst
@@ -0,0 +1,172 @@
+.. _features:
+
+Features
+--------
+
+.. _blog-home-page:
+
+Attaching blog to the home page
++++++++++++++++++++++++++++++++
+
+If you want to attach the blog to the home page you have to adapt settings a bit otherwise the
+"Just slug" permalink will swallow any CMS page you create.
+
+To avoit this add the following settings to you project::
+
+    BLOG_PERMALINKS = (
+        ('full_date', _('Full date')),
+        ('short_date', _('Year /  Month')),
+        ('category', _('Category')),
+    )
+    BLOG_PERMALINKS_URLS = {
+        'full_date': r'^(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<slug>\w[-\w]*)/$',
+        'short_date': r'^(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<slug>\w[-\w]*)/$',
+        'category': r'^(?P<category>\w[-\w]*)/(?P<slug>\w[-\w]*)/$',
+    }
+
+Notice that the last permalink type is no longer present.
+
+Then, pick any of the three remaining permalink types in the layout section of the apphooks config
+linked ot the home page (see http://yoursite.com/admin/djangocms_blog/blogconfig/).'
+
+
+.. _multisite:
+
+Multisite
++++++++++
+
+django CMS blog provides full support for multisite setups.
+
+Each blog post can be assigned to none, one or more sites: if no site is selected, then
+it's visible on all sites.
+
+This is matched with and API that allows to restrict users to only be able to edit
+blog posts only for some sites.
+
+To implement this API, you must add a ``get_sites`` method on the user model which
+returns a queryset of sites the user is allowed to add posts to.
+
+Example::
+
+    class CustomUser(AbstractUser):
+        sites = models.ManyToManyField('sites.Site')
+
+        def get_sites(self):
+            return self.sites
+
+.. _cms-wizard:
+
+django CMS 3.2+ Wizard
+++++++++++++++++++++++
+
+django CMS 3.2+ provides a content creation wizard that allows to quickly created supported
+content types, such as blog posts.
+
+For each configured Apphook, a content type is added to the wizard.
+
+Some issues with multiple registrations raising django CMS ``AlreadyRegisteredException``
+hae been reported; to handle these cases gracefully, the exception is swallowed
+when Django ``DEBUG == True`` avoiding breaking production websites. In these cases they
+wizard may not show up, but the rest will work as intended.
+
+.. _permalinks:
+
+Configurable permalinks
++++++++++++++++++++++++
+
+Blog comes with four different styles of permalinks styles:
+
+* Full date: ``YYYY/MM/DD/SLUG``
+* Year /  Month: ``YYYY/MM/SLUG``
+* Category: ``CATEGORY/SLUG``
+* Just slug: ``SLUG``
+
+As all the styles are loaded in the urlconf, the latter two does not allow
+to have CMS pages beneath the page the blog is attached to. If you want to
+do this, you have to override the default urlconfs by setting something
+like the following in the project settings::
+
+    BLOG_PERMALINK_URLS = {
+        'full_date': r'^(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<slug>\w[-\w]*)/$',
+        'short_date': r'^(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<slug>\w[-\w]*)/$',
+        'category': r'^post/(?P<category>\w[-\w]*)/(?P<slug>\w[-\w]*)/$',
+        'slug': r'^post/(?P<slug>\w[-\w]*)/$',
+    }
+
+And change ``post/`` with the desired prefix.
+
+.. _menu:
+
+Menu
+++++
+
+``djangocms_blog`` provides support for django CMS menu framework.
+
+By default all the categories and posts are added to the menu, in a hierarchical structure.
+
+It is possibile to configure per Apphook, whether the menu includes post and categories
+(the default), only categories, only posts or no item.
+
+If "post and categories" or "only categories" are set, all the posts not associated with a
+category are not added to the menu.
+
+.. _templates:
+
+Templates
++++++++++
+
+To ease the template customisations a ``djangocms_blog/base.html`` template is
+used by all the blog templates; the templates itself extends a ``base.html``
+template; content is pulled in the ``content`` block.
+If you need to define a different base template, or if your base template does
+not defines a ``content`` block, copy in your template directory
+``djangocms_blog/base.html`` and customise it according to your needs; the
+other application templates will use the newly created base template and
+will ignore the bundled one.
+
+Templates set
++++++++++++++
+
+By using **Apphook configuration** you can define a different templates set.
+To use this feature provide a directory name in **Template prefix** field in
+the **Apphook configuration** admin (in *Layout* section): it will be the
+root of your custom templates set.
+
+.. _sitemap:
+
+Sitemap
++++++++
+
+``djangocms_blog`` provides a sitemap for improved SEO indexing.
+Sitemap returns all the published posts in all the languages each post is available.
+
+The changefreq and priority is configurable per-apphook (see ``BLOG_SITEMAP_*`` in
+`Global settings <settings>`_).
+
+To add the blog Sitemap, add the following code to the project ``urls.py``::
+
+
+    from cms.sitemaps import CMSSitemap
+    from djangocms_blog.sitemaps import BlogSitemap
+
+
+    urlpatterns = patterns(
+        '',
+        ...
+        url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap',
+            {'sitemaps': {
+                'cmspages': CMSSitemap, 'blog': BlogSitemap,
+            }
+        }),
+    )
+
+.. _knocker:
+
+django-knocker
+++++++++++++++
+
+``djangocms-blog`` is integrated with `django-knocker <https://github.com/nephila/django-knocker>`_
+to provide real time desktop notifications.
+
+See `django-knocker documentation <https://django-knocker.readthedocs.org/>`_ for how to configure
+knocker.
diff --git a/docs/history.rst b/docs/history.rst
new file mode 100644
index 0000000..2506499
--- /dev/null
+++ b/docs/history.rst
@@ -0,0 +1 @@
+.. include:: ../HISTORY.rst
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000..556496e
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,27 @@
+.. djangocms-blog documentation master file, created by
+   sphinx-quickstart on Sun Jun  5 23:27:04 2016.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to djangocms-blog's documentation!
+==========================================
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   installation
+   settings
+   features
+   development
+   contributing
+   history
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
+
diff --git a/docs/installation.rst b/docs/installation.rst
new file mode 100644
index 0000000..9df6460
--- /dev/null
+++ b/docs/installation.rst
@@ -0,0 +1,129 @@
+.. _installation:
+
+Installation
+------------
+
+Install djangocms-blog::
+
+    pip install djangocms-blog
+
+Add ``djangocms_blog`` and its dependencies to INSTALLED_APPS::
+
+    INSTALLED_APPS = [
+        ...
+        'filer',
+        'easy_thumbnails',
+        'aldryn_apphooks_config',
+        'cmsplugin_filer_image',
+        'parler',
+        'taggit',
+        'taggit_autosuggest',
+        'meta',
+        'djangocms_blog',
+        ...
+    ]
+
+
+Then migrate::
+
+    $ python manage.py migrate
+
+Minimal configuration
++++++++++++++++++++++
+
+The following are minimal defaults to get the blog running; they may not be
+suited for your deployment.
+
+* Add the following settings to your project::
+
+    THUMBNAIL_PROCESSORS = (
+        'easy_thumbnails.processors.colorspace',
+        'easy_thumbnails.processors.autocrop',
+        'filer.thumbnail_processors.scale_and_crop_with_subject_location',
+        'easy_thumbnails.processors.filters',
+    )
+    META_SITE_PROTOCOL = 'http'
+    META_USE_SITES = True
+
+* Configure parler according to your languages::
+
+    PARLER_LANGUAGES = {
+        1: (
+            {'code': 'en',},
+            {'code': 'it',},
+            {'code': 'fr',},
+        ),
+        'default': {
+            'fallbacks': ['en', 'it', 'fr'],
+        }
+    }
+
+* Add the following to your ``urls.py``::
+
+    url(r'^taggit_autosuggest/', include('taggit_autosuggest.urls')),
+
+* To start your blog you need to use `AppHooks from django CMS <http://django-cms.readthedocs.org/en/support-3.0.x/how_to/apphooks.html>`_
+  to add the blog to a django CMS page; this step is not required when using
+  `Auto setup <auto_setup>`_:
+
+  * Create a new django CMS page
+  * Go to **Advanced settings** and select Blog from the **Application** selector and
+    create an **Application configuration**;
+  * Eventually customise the Application instance name;
+  * Publish the page
+  * Restart the project instance to properly load blog urls.
+
+.. warning:: After adding the apphook to the page you **cannot** change the **Instance Namspace**
+             field for the defined **AppHokConfig**; if you want to change it, create a new one
+             with the correct namespace, go in the CMS page **Advanced settings** and switch to the
+             new **Application configuration**
+
+* Add and edit blog by creating them in the admin or using the toolbar,
+  and the use the `django CMS frontend editor <http://django-cms.readthedocs.org/en/support-3.0.x/user/reference/page_admin.html#the-interface>`_
+  to edit the blog content:
+
+  * Create a new blog entry in django admin backend or from the toolbar
+  * Click on "view on site" button to view the post detail page
+  * Edit the post via djangocms frontend by adding / editing plugins
+  * Publish the blog post by flagging the "Publish" switch in the blog post
+    admin
+
+.. _external_applications:
+
+External applications configuration
++++++++++++++++++++++++++++++++++++
+
+Dependency applications may need configuration to work properly.
+
+Please, refer to each application documentation on details.
+
+* django-filer: http://django-filer.readthedocs.org
+* django-meta: https://github.com/nephila/django-meta#installation
+* django-meta-mixin: https://github.com/nephila/django-meta-mixin#installation
+* django-parler: http://django-parler.readthedocs.org/en/latest/quickstart.html#configuration
+* django-taggit-autosuggest: https://bitbucket.org/fabian/django-taggit-autosuggest
+
+
+.. _auto_setup:
+
+Auto setup
+++++++++++
+
+``djangocms_blog`` can install and configue itself if it does not find any
+attached instance of itself.
+This feature is enable by default and will create:
+
+* a ``BlogConfig`` with default values
+* a ``Blog`` CMS page and will attach ``djangocms_blog`` instance to it
+* a **home page** if no home is found.
+
+All the items will be created in every language configured for the website
+and the pages will be published. If not using **aldryn-apphook-reload** or
+**django CMS 3.2** auto-reload middleware you are required to reload the
+project instance after this.
+This will only work for the current website as detected by
+``Site.objects.get_current()``.
+
+
+The auto setup is execute once for each server start but it will skip any
+action if a ``BlogConfig`` instance is found.
diff --git a/docs/settings.rst b/docs/settings.rst
new file mode 100644
index 0000000..b93484f
--- /dev/null
+++ b/docs/settings.rst
@@ -0,0 +1,136 @@
+.. _settings:
+
+Global Settings
+---------------
+* BLOG_IMAGE_THUMBNAIL_SIZE: Size of the main image when shown on the post
+  lists; it's a dictionary with ``size``, ``crop`` and ``upscale`` keys;
+  (default: ``{'size': '120x120', 'crop': True,'upscale': False}``)
+* BLOG_IMAGE_FULL_SIZE: Size of the main image when shown on the post
+  detail; it's a dictionary with ``size``, ``crop`` and ``upscale`` keys;
+  (default: ``{'size': '640x120', 'crop': True,'upscale': False}``)
+* BLOG_PAGINATION: Number of post per page; (default: ``10``)
+* BLOG_LATEST_POSTS: Default number of post in the **Latest post** plugin;
+  (default: ``5``)
+* BLOG_POSTS_LIST_TRUNCWORDS_COUNT: Default number of words shown for
+  abstract in the post list; (default: ``100``)
+* BLOG_TYPE: Generic type for the post object; (default: ``Article``)
+* BLOG_TYPES: Choices of available blog types;
+  (default: to ``META_OBJECT_TYPES`` defined in `django-meta settings`_)
+* BLOG_FB_TYPE: Open Graph type for the post object; (default: ``Article``)
+* BLOG_FB_TYPES: Choices of available blog types;
+  (default: to ``META_FB_TYPES`` defined in `django-meta settings`_)
+* BLOG_FB_APPID: Facebook Application ID
+* BLOG_FB_PROFILE_ID: Facebook profile ID of the post author
+* BLOG_FB_PUBLISHER: Facebook URL of the blog publisher
+* BLOG_FB_AUTHOR_URL: Facebook profile URL of the post author
+* BLOG_FB_AUTHOR: Facebook profile URL of the post author
+* BLOG_TWITTER_TYPE: Twitter Card type for the post object;
+  (default: ``Summary``)
+* BLOG_TWITTER_TYPES: Choices of available blog types for twitter;
+  (default: to ``META_TWITTER_TYPES`` defined in `django-meta settings`_)
+* BLOG_TWITTER_SITE: Twitter account of the site
+* BLOG_TWITTER_AUTHOR: Twitter account of the post author
+* BLOG_GPLUS_TYPE: Google+ Snippet type for the post object;
+  (default: ``Blog``)
+* BLOG_GPLUS_TYPES: Choices of available blog types for twitter;
+  (default: to ``META_GPLUS_TYPES`` defined in `django-meta settings`_)
+* BLOG_GPLUS_AUTHOR: Google+ account of the post author
+* BLOG_ENABLE_COMMENTS: Whether to enable comments by default on posts;
+  while ``djangocms_blog`` does not ship any comment system, this flag
+  can be used to control the chosen comments framework; (default: ``True``)
+* BLOG_USE_ABSTRACT: Use an abstract field for the post; if ``False``
+  no abstract field is available for every post; (default: ``True``)
+* BLOG_USE_PLACEHOLDER: Post content is managed via placeholder;
+  if ``False`` a simple HTMLField is used; (default: ``True``)
+* BLOG_MULTISITE: Add support for multisite setup; (default: ``True``)
+* BLOG_AUTHOR_DEFAULT: Use a default if not specified; if set to ``True`` the
+  current user is set as the default author, if set to ``False`` no default
+  author is set, if set to a string the user with the provided username is
+  used; (default: ``True``)
+* BLOG_DEFAULT_PUBLISHED: If posts are marked as published by default;
+  (default: ``False``)
+* BLOG_ADMIN_POST_FIELDSET_FILTER: Callable function to change(add or filter)
+  fields to fieldsets for admin post edit form; (default: ``False``). Function simple example::
+
+
+    def fieldset_filter_function(fsets, request, obj=None):
+        if request.user.groups.filter(name='Editor').exists():
+            fsets[1][1]['fields'][0].append('author')  # adding 'author' field if user is Editor
+        return fsets
+
+
+* BLOG_AVAILABLE_PERMALINK_STYLES: Choices of permalinks styles;
+* BLOG_PERMALINK_URLS: URLConf corresponding to
+  BLOG_AVAILABLE_PERMALINK_STYLES;
+* BLOG_DEFAULT_OBJECT_NAME: Default name for Blog item (used in django CMS Wizard);
+* BLOG_AUTO_SETUP: Enable the blog **Auto setup** feature; (default: ``True``)
+* BLOG_AUTO_HOME_TITLE: Title of the home page created by **Auto setup**;
+  (default: ``Home``)
+* BLOG_AUTO_BLOG_TITLE: Title of the blog page created by **Auto setup**;
+  (default: ``Blog``)
+* BLOG_AUTO_APP_TITLE: Title of the ``BlogConfig`` instance created by
+  **Auto setup**; (default: ``Blog``)
+* BLOG_SITEMAP_PRIORITY_DEFAULT: Default priority for sitemap items; (default: ``0.5``)
+* BLOG_SITEMAP_CHANGEFREQ: List for available changefreqs for sitemap items; (default: **always**,
+  **hourly**, **daily**, **weekly**, **monthly**, **yearly**, **never**)
+* BLOG_SITEMAP_CHANGEFREQ_DEFAULT: Default changefreq for sitemap items; (default: ``monthly``)
+* BLOG_CURRENT_POST_IDENTIFIER: Current post identifier in request (default ``djangocms_post_current``)
+* BLOG_CURRENT_NAMESPACE: Current post config identifier in request  (default: ``djangocms_post_current_config``)
+* BLOG_ENABLE_THROUGH_TOOLBAR_MENU: Is the toolbar menu throught whole all applications (default: ``False``)
+* BLOG_PLUGIN_MODULE_NAME: Blog plugin module name (default: ``Blog``)
+* BLOG_LATEST_ENTRIES_PLUGIN_NAME: Blog latest entries plugin name (default: ``Latest Blog Articles``)
+* BLOG_AUTHOR_POSTS_PLUGIN_NAME: Blog author posts plugin name (default: ``Author Blog Articles``)
+* BLOG_TAGS_PLUGIN_NAME: Blog tags plugin name (default: ``Tags``)
+* BLOG_CATEGORY_PLUGIN_NAME: Blog categories plugin name (default: ``Categories``)
+* BLOG_ARCHIVE_PLUGIN_NAME: Blog archive plugin name (default: ``Archive``)
+* BLOG_FEED_CACHE_TIMEOUT: Cache timeout for RSS feeds
+* BLOG_FEED_INSTANT_ITEMS: Number of items in Instant Article feed
+* BLOG_FEED_LATEST_ITEMS: Number of items in latest items feed
+* BLOG_FEED_TAGS_ITEMS: Number of items in per tags feed
+
+Read-only settings
+++++++++++++++++++
+
+* BLOG_MENU_TYPES: Available structures of the Blog menu; (default list **Posts and Categories**,
+  **Categories only**, **Posts only**, **None**)
+* BLOG_MENU_TYPE: Structure of the Blog menu;
+  (default: ``Posts and Categories``)
+
+
+Per-Apphook settings
+++++++++++++++++++++
+
+The following settings can be configured for each ``Apphook config``: the settings above will
+be used as defaults.
+
+* application title: Free text title that can be used as title in templates;
+* object name: Free text label for Blog items in django CMS Wizard;
+* Post published by default: Per-Apphook setting for BLOG_DEFAULT_PUBLISHED;
+* Permalink structure: Per-Apphook setting for
+  BLOG_AVAILABLE_PERMALINK_STYLES;
+* Use placeholder and plugins for article body: Per-Apphook setting for
+  BLOG_USE_PLACEHOLDER;
+* Use abstract field: Per-Apphook setting for BLOG_USE_ABSTRACT;
+* Set author: Per-Apphook setting for BLOG_AUTHOR_DEFAULT;
+* Paginate sizePer-Apphook setting for BLOG_PAGINATION;
+* Template prefix: Alternative directory to load the blog templates from;
+* Menu structure: Per-Apphook setting for BLOG_MENU_TYPE
+* Sitemap changefreq: Per-Apphook setting for BLOG_SITEMAP_CHANGEFREQ_DEFAULT
+* Sitemap priority: Per-Apphook setting for BLOG_SITEMAP_PRIORITY_DEFAULT
+* Object type: Per-Apphook setting for BLOG_TYPE
+* Facebook type: Per-Apphook setting for BLOG_FB_TYPE
+* Facebook application ID: Per-Apphook setting for BLOG_FB_APP_ID
+* Facebook profile ID: Per-Apphook setting for BLOG_FB_PROFILE_ID
+* Facebook page URL: Per-Apphook setting for BLOG_FB_PUBLISHER
+* Facebook author URL: Per-Apphook setting for BLOG_AUTHOR_URL
+* Facebook author: Per-Apphook setting for BLOG_AUTHOR
+* Twitter type: Per-Apphook setting for BLOG_TWITTER_TYPE
+* Twitter site handle: Per-Apphook setting for BLOG_TWITTER_SITE
+* Twitter author handle: Per-Apphook setting for BLOG_TWITTER_AUTHOR
+* Google+ type: Per-Apphook setting for BLOG_GPLUS_TYPE
+* Google+ author name: Per-Apphook setting for BLOG_GPLUS_AUTHOR
+* Send notifications on post publish: Send desktop notifications when a post is published
+* Send notifications on post update: Send desktop notifications when a post is updated
+
+
+.. _django-meta settings: https://github.com/nephila/django-meta#settings
diff --git a/setup.py b/setup.py
index d2a5c22..3dbdbcb 100755
--- a/setup.py
+++ b/setup.py
@@ -28,7 +28,7 @@ setup(
     include_package_data=True,
     install_requires=[
         'django-parler>=1.5',
-        'django-cms>3.2',
+        'django-cms>=3.2',
         'django-taggit>=0.12.2',
         'django-filer',
         'pytz',
diff --git a/tox.ini b/tox.ini
index 3c66143..0d88606 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = pep8,isort,py{35,34,27}-django{19}-{cms33,cms32,knocker},py{35,34,33,27}-django{18}-cms{33,32}
+envlist = pep8,isort,docs,py{35,34,27}-django{19}-{cms33,cms32,knocker},py{35,34,33,27}-django{18}-cms{33,32}
 
 [testenv]
 commands = {env:COMMAND:python} cms_helper.py test djangocms_blog
@@ -38,3 +38,13 @@ skip_install = true
 deps = flake8
 commands = flake8
 skip_install = true
+
+[testenv:docs]
+deps =
+    sphinx
+    sphinx-rtd-theme
+    -rrequirements-test.txt
+changedir=docs
+skip_install = true
+commands=
+    sphinx-build -W -b html -d {envtmpdir}/doctrees .  {toxinidir}/docs/_build/html