django-powerpages
=================
.. image:: https://api.travis-ci.org/Open-E-WEB/django-powerpages.svg?branch=master
:target: https://travis-ci.org/Open-E-WEB/django-powerpages
.. image:: https://img.shields.io/pypi/v/django-powerpages.svg
:target: https://pypi.python.org/pypi/django-powerpages
.. image:: https://coveralls.io/repos/github/Open-E-WEB/django-powerpages/badge.svg?branch=master
:target: https://coveralls.io/github/Open-E-WEB/django-powerpages?branch=master
Developer-friendly, simple CMS for Django, "flatpages on steroids".
Features
--------
- edit pages in Admin using syntax highlighting - HTML, CSS, JavaScript, Django template language
- edit pages as files using your favourite text editor or IDE
- on demand synchronization of pages between database and file system using Django commands
- integration with Django's template system
- attach custom server-side logic to a page through configurable *Page Processors*
- sitemap.xml
Installation
------------
Install package using pip:
.. code-block:: python
pip install django-powerpages
Add ``'powerpages'`` to ``INSTALLED_APPS`` in your settings module:
.. code-block:: python
INSTALLED_APPS = (
...
'powerpages',
)
Define ``POWER_PAGES`` setting:
.. code-block:: python
POWER_PAGES = {
# absolute path to directory, where page files are located:
'SYNC_DIRECTORY': '/path/to/directory/'
}
Include app's URLs at the end of your urlconf:
.. code-block:: python
urlpatterns = [
...
url(r'', include('powerpages.urls', namespace='powerpages')),
]
Add ``powerpages.loader.WebsiteLoader`` at end of your ``loaders`` in
``TEMPLATES -> OPTIONS`` setting:
.. code-block:: python
TEMPLATES = [
{
...
'OPTIONS': {
...
'loaders': [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# Database template loader for powerpages app
'powerpages.loader.WebsiteLoader',
],
...
}
...
}
]
Run migrations:
.. code-block:: python
python manage.py migrate
Usage
-----
Admin screenshots:
~~~~~~~~~~~~~~~~~~
.. image:: powerpages-scr-01.png
.. image:: powerpages-scr-02.png
Edit pages using Admin
~~~~~~~~~~~~~~~~~~~~~~
Admin interface allows to edit pages using the following fields:
- *URL* - unique address of every page
- *Alias* - optional code name for page to be used to resolve it's URL address
- *Title*, *Description*, *Keywords* - convenience fields to work with meta-tags
- *Template* - page's content as a Django template source
- *Page Processor* and *Page Processor Config* - options to assign and customize server-side logic
URL addresses of pages can be reversed in templates by using ``{% page_url alias %}``.
This template tag can also reverse URLs of regular Django views.
Page templates work as regular Django's templates with few modifications:
1. ``{% extends ... %}`` tag should not be used:
- by default each template inherits from template of parent page
- parent template can be overwritten by providing ``base template`` option to the page processor config
2. ``{% load ... %}`` tag is not necessary:
- template tag libraries from ``settings.POWER_PAGES['TAG_LIBRARIES']`` are loaded automatically
- additional libraries may be provided using ``tag libraries`` in page processor config
*Page Processor* field allows to select a Python class responsible for processing requests for current page.
Page processor can be configured using YAML config in *Page Processor Config* field.
Default value, ``powerpages.DefaultPageProcessor`` just renders page content and returns the output as ``200 OK`` response.
Other predefined options are:
- ``powerpages.RedirectProcessor`` - creates ``301 Moved Permanently`` or ``302 Found`` response depending on boolean ``permanent`` parameter. Redirect location is provided by URL (parameter ``to url``), view name (``to name``) or Page alias (``to alias``).
- ``powerpages.NotFoundProcessor`` - generates ``404 Not Found`` response.
Example configuration of default page processor:
.. code-block:: python
base template: myapp/base.html
context processors:
- myapp.context_processors.context
tag libraries:
- myapp_tags
headers: {x-magic-id: '42'}
cache: 300
cache for user: true
sitemap: false
To define a custom page processor you may create a subclass of ``DefaultPageProcessor``
inside ``page_processors.py`` file in your app:
.. code-block:: python
# myapp/page_processors.py
from powerpages.page_processors import DefaultPageProcessor
from powerpages.page_processor_registry import register
class MyPageProcessor(DefaultPageProcessor):
def process_request(self, request, extra_context=None):
"""Process a request and create HTTP Response."""
# Put your custom view logic here
register(MyPageProcessor)
Browse website in "edit mode"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Button "Edit mode" in Admin allows to show information about current page while browsing the website.
User enables "Edit mode" for current session in Admin using *Edit mode* button.
This mode works only if template tag ``{% current_page_info %}`` has been added to the template source.
File-Database Synchronization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Export pages from database to file system is done by ``website_dump`` command.
All pages are saved as structure of files and directories inside ``settings.POWER_PAGES['SYNC_DIRECTORY']``.
Exported pages can be modified using text editor and later loaded again into the database.
.. code-block:: python
python manage.py website_dump
Example structure of output directory:
.. code-block:: python
_index_.page
about-us/_index_.page
about-us/contact.page
download.page
robots.txt
Each of dumped files has the following structure:
.. code-block:: python
{
... page fields as JSON
}
## TEMPLATE SOURCE: ##
... template content (plain text)
Import pages from directory into database is done using ``website_load`` command.
.. code-block:: python
python manage.py website_load
Both website commands accept a variety of options to tweak their behaviour.
For the full list of options, use ``--help``.
XML Sitemaps
~~~~~~~~~~~~
``django-powerpages`` comes with a system for defining XML Sitemaps (alternative to ``django.contrib.sitemaps``).
By default, all accessible pages are listed as URLs in ``sitemap.xml``.
To remove a page from the sitemap user may add the following option to page processor config:
.. code-block:: python
sitemap: false
``sitemap`` option may be used to modify page's sitemap params:
.. code-block:: python
sitemap: {changefreq: 'daily', priority: 0.9}
Default values for ``changefreq`` and ``priority`` for all URLs can be set using ``settings.POWER_PAGES``:
.. code-block:: python
POWER_PAGES = {
# (...)
'SITEMAP_DEFAULT_CHANGEFREQ': 'weekly',
'SITEMAP_DEFAULT_PRIORITY': 0.7,
}
To add custom URLs from your app to the sitemap you may define and register
a subclass of ``Sitemap`` or ``ModelSitemap`` class inside ``sitemap.py`` file in your app:
.. code-block:: python
# myapp/sitemap.py
from powerpages import sitemap_config
from myapp.models import MyModel
class MyModelSitemap(sitemap_config.ModelSitemap):
"""Sitemap config for Storage Powered by Open-E document files"""
queryset = MyModel.objects.all()
class MyStaticSitemap(sitemap_config.Sitemap):
items = (
{'location': sitemap_config.NamedURL('myview')},
{'location': sitemap_config.NamedURL('myview2', param='value')}
)
sitemap_config.sitemaps.add(MyModelSitemap)
sitemap_config.sitemaps.add(MyStaticSitemap)
Requirements
------------
Python: 2.7, 3.4, 3.5
Django: 1.9, 1.10