Merge branch 'master' into feature/streamfield

This commit is contained in:
Matt Westcott 2015-02-18 10:50:32 +00:00
commit 2f37e188f5
43 changed files with 561 additions and 296 deletions

8
.drone.yml Normal file
View file

@ -0,0 +1,8 @@
image: kaedroho/django-base
script:
- pip3.4 install mock python-dateutil pytz elasticsearch
- python3.4 setup.py install
- python3.4 runtests.py
services:
- postgres
- dockerfile/elasticsearch

View file

@ -22,9 +22,12 @@ Changelog
* Added validation to prevent pages being crated with only whitespace characters in their title fields (Frank Wiles)
* Page model fields without a FieldPanel are no longer displayed in the form
* No longer need to specify the base model on InlinePanel definitions
* The project template Vagrantfile now listens on port 8000
* The external link chooser in rich text areas now accepts URLs of the form '/some/local/path', to allow linking to non-Wagtail-controlled URLs within the local site (Eric Drechsel)
* SCSS files in wagtailadmin now use absolute imports, to permit overriding by user stylesheets (Martin Sanders)
* Bare text entered in rich text areas is now automatically wrapped in a paragraph element
0.8.5 (xx.xx.20xx)
0.8.5 (17.02.2015)
~~~~~~~~~~~~~~~~~~
* Fix: On adding a new page, the available page types are ordered by the displayed verbose name
@ -35,6 +38,10 @@ Changelog
* Fix: Punctuation characters are no longer stripped when performing search queries
* Fix: When adding tags where there were none before, it is now possible to save a single tag with multiple words in it
* Fix: richtext template tag no longer raises TypeError if None is passed into it (Alejandro Varas)
* Fix: Serving documents now uses a streaming HTTP response and will no longer break Django's cache middleware
* Fix: User admin area no longer fails in the presence of negative user IDs (as used by django-guardian's default settings)
* Fix: Password reset emails now use the ``BASE_URL`` setting for the reset URL
* Fix: BASE_URL is now included in the project template's default settings file
0.8.4 (04.12.2014)
~~~~~~~~~~~~~~~~~~

View file

@ -43,6 +43,7 @@ Contributors
* Frank Wiles
* Sebastian Spiegel
* Alejandro Varas
* Martin Sanders
Translators
===========

View file

@ -3,6 +3,9 @@ Generating a static site
This document describes how to render your Wagtail site into static HTML files on your local filesystem, Amazon S3 or Google App Engine, using `django medusa`_ and the ``wagtail.contrib.wagtailmedusa`` module.
.. note::
An alternative module based on the `django-bakery`_ package is available as a third-party contribution: https://github.com/mhnbcu/wagtailbakery
Installing django-medusa
~~~~~~~~~~~~~~~~~~~~~~~~
@ -86,3 +89,4 @@ For example, the BlogIndex above would need to yield one URL for each page of re
.. _django medusa: https://github.com/mtigas/django-medusa
.. _django-bakery: https://github.com/datadesk/django-bakery

View file

@ -23,7 +23,11 @@ Within the models.py of one of your apps, create a model that extends wagtailfor
.. code:: python
from modelcluster.fields import ParentalKey
from wagtail.wagtailadmin.edit_handlers import (FieldPanel, InlinePanel,
MultiFieldPanel)
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailforms.models import AbstractEmailForm, AbstractFormField
class FormField(AbstractFormField):

View file

@ -1,148 +1,81 @@
=====================
Creating your project
=====================
===========================
Starting your first project
===========================
.. contents:: Contents
:local:
Once you've installed Wagtail, you are ready start your first project. Wagtail projects are ordinary Django projects with a few extra apps installed.
The ``wagtail start`` command
=============================
The easiest way to start a new project with wagtail is to use the ``wagtail start`` command. This command is installed into your environment when you install Wagtail (see: :doc:`installation`).
The command works the same way as ``django-admin.py startproject`` except that the produced project is pre-configured for Wagtail. It also contains some useful extras which we will look at in the next section.
To create a project, cd into a directory where you would like to create your project and run the following command:
Wagtail provides a command to get you started called ``wagtail start``. Open up a command line shell in your project folder and type:
.. code-block:: bash
wagtail start mysite
The project
===========
Lets look at what ``wagtail start`` created::
mysite/
core/
static/
templates/
base.html
404.html
500.html
mysite/
settings/
base.py
dev.py
production.py
manage.py
vagrant/
provision.sh
Vagrantfile
readme.rst
requirements.txt
The "core" app
----------------
Location: ``/mysite/core/``
This app is here to help get you started quicker by providing a ``HomePage`` model with migrations to create one when you first setup your app.
This should create a new folder called ``mysite``. Its contents are similar to what ``django-admin.py startproject`` creates but ``wagtail start`` comes with some useful extras that are documented :doc:`here <../reference/project_template>`.
Default templates and static files
----------------------------------
Running it
==========
Location: ``/mysite/core/templates/`` and ``/mysite/core/static/``
The templates directory contains ``base.html``, ``404.html`` and ``500.html``. These files are very commonly needed on Wagtail sites to they have been added into the template.
The static directory contains an empty javascript and sass file. Wagtail uses ``django-compressor`` for compiling and compressing static files. For more information, see: `Django Compressor Documentation <http://django-compressor.readthedocs.org/en/latest/>`_
Firstly, open up a command line shell in your new projects directory.
Vagrant configuration
---------------------
* **1. Create a virtual environment**
Location: ``/Vagrantfile`` and ``/vagrant/``
This is only required when you first run your project. This creates a folder to install extra Python modules into.
If you have Vagrant installed, these files let you easily setup a development environment with PostgreSQL and Elasticsearch inside a virtual machine.
**Linux/Mac OSX:** :code:`pyvenv venv`
See below section `With Vagrant`_ for info on how to use Vagrant in development
If you do not want to use Vagrant, you can just delete these files.
**Windows:** :code:`c:\Python34\python -m venv myenv`
Django settings
---------------
Location: ``/mysite/mysite/settings/``
The Django settings files are split up into ``base.py``, ``dev.py``, ``production.py`` and ``local.py``.
.. glossary::
``base.py``
This file is for global settings that will be used in both development and production. Aim to keep most of your configuration in this file.
``dev.py``
This file is for settings that will only be used by developers. For example: ``DEBUG = True``
``production.py``
This file is for settings that will only run on a production server. For example: ``DEBUG = False``
``local.py``
This file is used for settings local to a particular machine. This file should never be tracked by a version control system.
.. tip::
On production servers, we recommend that you only store secrets in local.py (such as API keys and passwords). This can save you headaches in the future if you are ever trying to debug why a server is behaving badly. If you are using multiple servers which need different settings then we recommend that you create a different ``production.py`` file for each one.
https://docs.python.org/3/library/venv.html
Getting it running
==================
**Python 2.7**
``pyvenv`` is only included with Python 3.3 onwards. To get virtual environments on Python 2, use the ``virtualenv`` package:
.. code-block:: bash
pip install virtualenv
virtualenv venv
With Vagrant
------------
* **2. Activate the virtual environment**
This is the easiest way to get the project running. Vagrant runs your project locally in a virtual machine so you can use PostgreSQL and Elasticsearch in development without having to install them on your host machine. If you haven't yet installed Vagrant, see: `Installing Vagrant <https://docs.vagrantup.com/v2/installation/>`_.
**Linux/Mac OSX:** :code:`source venv/bin/activate`
**Windows:** :code:`venv/Scripts/activate.bat`
https://docs.python.org/3/library/venv.html
To setup the Vagrant box, run the following commands
* **3. Install PIP requirements**
.. code-block:: bash
vagrant up # This may take some time on first run
vagrant ssh
# within the ssh session
dj createsuperuser
djrun
:code:`pip install -r requirements.txt`
If you now visit http://localhost:8111 you should see a very basic "Welcome to your new Wagtail site!" page.
* **4. Create the database**
You can browse the Wagtail admin interface at: http://localhost:8111/admin
By default, this would create an SQLite database file within the project directory.
You can read more about how Vagrant works at: https://docs.vagrantup.com/v2/
:code:`python manage.py migrate`
.. topic:: The ``dj`` and ``djrun`` aliases
* **5. Create an admin user**
When using Vagrant, the Wagtail template provides two aliases: ``dj`` and ``djrun`` which can be used in the ``vagrant ssh`` session.
:code:`python manage.py createsuperuser`
.. glossary::
``dj``
This is short for ``python manage.py`` so you can use it to reduce typing. For example: ``python manage.py syncdb`` becomes ``dj syncdb``.
* **6. Run the development server**
``djrun``
This is short for ``python manage.py runserver 0.0.0.0:8000``. This is used to run the testing server which is accessible from ``http://localhost:8111`` (note that the port number gets changed by Vagrant)
:code:`python manage.py runserver`
Your site is now accessible at ``http://localhost:8000``, with the admin backend available at ``http://localhost:8000/admin/``.
Using Vagrant
-------------
:doc:`using_vagrant`

View file

@ -5,5 +5,7 @@ Getting started
.. toctree::
:maxdepth: 2
trying_wagtail
installation
creating_your_project
using_vagrant

View file

@ -2,6 +2,7 @@
Installation
============
Before you start
================
@ -10,75 +11,46 @@ A basic Wagtail setup can be installed on your machine with only a few prerequis
Whether you just want to try out the demo site, or you're ready to dive in and create a Wagtail site with all bells and whistles enabled, we strongly recommend the Vagrant approach. Nevertheless, if you're the sort of person who balks at the idea of downloading a whole operating system just to run a web app, we've got you covered too. Start from `A basic Wagtail installation`_ below.
The demo site (a.k.a. the no-installation route)
================================================
Install Python
==============
We provide a demo site containing a set of standard templates and page types - if you're new to Wagtail, this is the best way to try it out and familiarise yourself with how Wagtail works from the point of view of an editor.
If you're happy to use Vagrant, and you just want to set up the Wagtail demo site, or any other pre-existing Wagtail site that ships with Vagrant support, you don't need to install Wagtail at all. Install `Vagrant <http://www.vagrantup.com/>`__ and `VirtualBox <https://www.virtualbox.org/>`__, and run::
git clone https://github.com/torchbox/wagtaildemo.git
cd wagtaildemo
vagrant up
vagrant ssh
If you haven't got Python installed yet, we recommend installing Python 3.4. You can find the download for it here: https://www.python.org/downloads/
Then, within the SSH session::
pip
---
./manage.py createsuperuser
./manage.py runserver 0.0.0.0:8000
Python 3.4 has this built in. If you are using Python 2.7 or 3.3, you will have to install PIP separately
See: https://pip.pypa.io/en/latest/installing.html
This will make the demo site available on your host machine at the URL http://localhost:8111/ - you can access the Wagtail admin interface at http://localhost:8111/admin/ . Further instructions can be found at :ref:`editor_manual`.
Virtual environments
--------------------
Once youve experimented with the demo site and are ready to build your own site, it's time to install Wagtail on your host machine. Even if you intend to do all further Wagtail work within Vagrant, installing the Wagtail package on your host machine will provide the ``wagtail start`` command that sets up the initial file structure for your project.
Python 3.3 and 3.4 has this built in. If you are using Python 2.7 you will have to install the ``virtualenv`` package from pip:
.. code-block:: bash
pip install virtualenv
A basic Wagtail installation
============================
Install Wagtail
===============
This provides everything you need to create a new Wagtail project from scratch, containing no page definitions or templates other than a basic homepage as a starting point for building your site. (For a gentler introduction to Wagtail, you may wish to try out the demo site first!)
Wagtail is available as a pip-installable package. To get the latest stable version:
You will need Python's `pip <http://pip.readthedocs.org/en/latest/installing.html>`__ package manager. We also recommend `virtualenvwrapper <http://virtualenvwrapper.readthedocs.org/en/latest/>`_ so that you can manage multiple independent Python environments for different projects - although this is not strictly necessary if you intend to do all your development under Vagrant.
Wagtail is based on the Django web framework and various other Python libraries. Most of these are pure Python and will install automatically using ``pip``, but there are a few native-code components that require further attention:
* libsass-python (for compiling SASS stylesheets) - requires a C++ compiler and the Python development headers.
* Pillow (for image processing) - additionally requires libjpeg and zlib.
On Debian or Ubuntu, these can be installed with the command::
sudo apt-get install python-dev python-pip g++ libjpeg62-dev zlib1g-dev
With these dependencies installed, Wagtail can then be installed with the command::
.. code-block:: bash
pip install wagtail
(or if you're not using virtualenvwrapper: ``sudo pip install wagtail``.)
You will now be able to run the following command to set up an initial file structure for your Wagtail project (replace ``myprojectname`` with a name of your choice)::
To check that Wagtail can be seen by Python. Type ``python`` in your shell then try to import ``wagtail`` from the prompt:
wagtail start myprojectname
.. code-block:: python
**Without Vagrant:** Run the following steps to complete setup of your project (the ``createsuperuser`` step will prompt you to set up a superuser account)::
>>> import wagtail
cd myprojectname
pip install -r requirements.txt
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver
Your site is now accessible at http://localhost:8000, with the admin backend available at http://localhost:8000/admin/ .
**With Vagrant:** Run the following steps to bring up the virtual machine and complete setup of your project (the ``createsuperuser`` step will prompt you to set up a superuser account)::
cd myprojectname
vagrant up
vagrant ssh
./manage.py createsuperuser
./manage.py runserver 0.0.0.0:8000
Your site is now accessible at http://localhost:8111, with the admin backend available at http://localhost:8111/admin/ .
Optional extras
===============
@ -104,6 +76,7 @@ This assumes that your PostgreSQL instance is configured to allow you to connect
ElasticSearch
-------------
Wagtail integrates with ElasticSearch to provide full-text searching of your content, both within the Wagtail interface and on your site's front-end. If ElasticSearch is not available, Wagtail will fall back to much more basic search functionality using database queries. ElasticSearch is pre-installed as part of the Vagrant virtual machine image; non-Vagrant users can use the `debian.sh <https://github.com/torchbox/wagtail/blob/master/scripts/install/debian.sh>`__ or `ubuntu.sh <https://github.com/torchbox/wagtail/blob/master/scripts/install/ubuntu.sh>`__ installation scripts as a guide.
To enable ElasticSearch for your project, uncomment the ``elasticsearch`` line from your project's requirements.txt, and in ``myprojectname/settings/base.py``, uncomment the WAGTAILSEARCH_BACKENDS section. Then run::
@ -115,52 +88,3 @@ To enable ElasticSearch for your project, uncomment the ``elasticsearch`` line f
Image feature detection
-----------------------
Wagtail can use the OpenCV computer vision library to detect faces and other features in images, and use this information to select the most appropriate centre point when cropping the image. OpenCV is pre-installed as part of the Vagrant virtual machine image, and Vagrant users can enable this by setting ``WAGTAILIMAGES_FEATURE_DETECTION_ENABLED`` to True in ``myprojectname/settings/base.py``. For installation outside of Vagrant, see :ref:`image_feature_detection`.
Alternative installation methods
================================
Ubuntu
------
If you have a fresh instance of Ubuntu 13.04 or later, you can install Wagtail,
along with a demonstration site containing a set of standard templates and page
types, in one step. As the root user::
curl -O https://raw.githubusercontent.com/torchbox/wagtail/master/scripts/install/ubuntu.sh; bash ubuntu.sh
This script installs all the dependencies for a production-ready Wagtail site,
including PostgreSQL, Redis, Elasticsearch, Nginx and uwsgi. We
recommend you check through the script before running it, and adapt it according
to your deployment preferences. The canonical version is at
`github.com/torchbox/wagtail/blob/master/scripts/install/ubuntu.sh
<https://github.com/torchbox/wagtail/blob/master/scripts/install/ubuntu.sh>`_.
Debian
------
If you have a fresh instance of Debian 7, you can install Wagtail, along with a
demonstration site containing a set of standard templates and page types, in one
step. As the root user::
curl -O https://raw.githubusercontent.com/torchbox/wagtail/master/scripts/install/debian.sh; bash debian.sh
This script installs all the dependencies for a production-ready Wagtail site,
including PostgreSQL, Redis, Elasticsearch, Nginx and uwsgi. We
recommend you check through the script before running it, and adapt it according
to your deployment preferences. The canonical version is at
`github.com/torchbox/wagtail/blob/master/scripts/install/debian.sh
<https://github.com/torchbox/wagtail/blob/master/scripts/install/debian.sh>`_.
Docker
------
`@oyvindsk <https://github.com/oyvindsk>`_ has built a Dockerfile for the Wagtail demo. Simply run::
docker run -p 8000:8000 -d oyvindsk/wagtail-demo
then access the site at http://your-ip:8000 and the admin
interface at http://your-ip:8000/admin using admin / test.
See https://index.docker.io/u/oyvindsk/wagtail-demo/ for more details.

View file

@ -0,0 +1,78 @@
==============
Trying Wagtail
==============
Wagtail demo
============
We provide a demo site containing a set of standard templates and page types - if you're new to Wagtail, this is the best way to try it out and familiarise yourself with how Wagtail works from the point of view of an editor.
If you're happy to use Vagrant, and you just want to set up the Wagtail demo site, or any other pre-existing Wagtail site that ships with Vagrant support, you don't need to install Wagtail at all. Install `Vagrant <http://www.vagrantup.com/>`__ and `VirtualBox <https://www.virtualbox.org/>`__, and run::
git clone https://github.com/torchbox/wagtaildemo.git
cd wagtaildemo
vagrant up
vagrant ssh
Then, within the SSH session::
./manage.py createsuperuser
./manage.py runserver 0.0.0.0:8000
This will make the demo site available on your host machine at the URL http://localhost:8000/ - you can access the Wagtail admin interface at http://localhost:8000/admin/ . Further instructions can be found at :ref:`editor_manual`.
Once youve experimented with the demo site and are ready to build your own site, it's time to install Wagtail on your host machine. Even if you intend to do all further Wagtail work within Vagrant, installing the Wagtail package on your host machine will provide the ``wagtail start`` command that sets up the initial file structure for your project.
One line install
================
Ubuntu
------
If you have a fresh instance of Ubuntu 13.04 or later, you can install Wagtail,
along with a demonstration site containing a set of standard templates and page
types, in one step. As the root user::
curl -O https://raw.githubusercontent.com/torchbox/wagtail/master/scripts/install/ubuntu.sh; bash ubuntu.sh
This script installs all the dependencies for a production-ready Wagtail site,
including PostgreSQL, Redis, Elasticsearch, Nginx and uwsgi. We
recommend you check through the script before running it, and adapt it according
to your deployment preferences. The canonical version is at
`github.com/torchbox/wagtail/blob/master/scripts/install/ubuntu.sh
<https://github.com/torchbox/wagtail/blob/master/scripts/install/ubuntu.sh>`_.
Debian
------
If you have a fresh instance of Debian 7, you can install Wagtail, along with a
demonstration site containing a set of standard templates and page types, in one
step. As the root user::
curl -O https://raw.githubusercontent.com/torchbox/wagtail/master/scripts/install/debian.sh; bash debian.sh
This script installs all the dependencies for a production-ready Wagtail site,
including PostgreSQL, Redis, Elasticsearch, Nginx and uwsgi. We
recommend you check through the script before running it, and adapt it according
to your deployment preferences. The canonical version is at
`github.com/torchbox/wagtail/blob/master/scripts/install/debian.sh
<https://github.com/torchbox/wagtail/blob/master/scripts/install/debian.sh>`_.
Docker
======
`@oyvindsk <https://github.com/oyvindsk>`_ has built a Dockerfile for the Wagtail demo. Simply run::
docker run -p 8000:8000 -d oyvindsk/wagtail-demo
then access the site at http://your-ip:8000 and the admin
interface at http://your-ip:8000/admin using admin / test.
See https://index.docker.io/u/oyvindsk/wagtail-demo/ for more details.

View file

@ -0,0 +1,37 @@
Using Vagrant
=============
This is the easiest way to get the project running. Vagrant runs your project locally in a virtual machine so you can use PostgreSQL and Elasticsearch in development without having to install them on your host machine. If you haven't yet installed Vagrant, see: `Installing Vagrant <https://docs.vagrantup.com/v2/installation/>`_.
To setup the Vagrant box, run the following commands
.. code-block:: bash
vagrant up # This may take some time on first run
vagrant ssh
# within the ssh session
dj createsuperuser
djrun
If you now visit http://localhost:8000 you should see a very basic "Welcome to your new Wagtail site!" page.
You can browse the Wagtail admin interface at: http://localhost:8000/admin
You can read more about how Vagrant works at: https://docs.vagrantup.com/v2/
.. topic:: The ``dj`` and ``djrun`` aliases
When using Vagrant, the Wagtail template provides two aliases: ``dj`` and ``djrun`` which can be used in the ``vagrant ssh`` session.
.. glossary::
``dj``
This is short for ``python manage.py`` so you can use it to reduce typing. For example: ``python manage.py syncdb`` becomes ``dj syncdb``.
``djrun``
This is short for ``python manage.py runserver 0.0.0.0:8000``. This is used to run the testing server which is accessible from ``http://localhost:8000`` (note that the port number gets changed by Vagrant)

View file

@ -10,7 +10,7 @@ Third-party tutorials
* `Upgrading Wagtail to use Django 1.7 locally using vagrant <https://jossingram.wordpress.com/2014/12/10/upgrading-wagtail-to-use-django-1-7-locally-using-vagrant/>`_ (10 December 2014)
* `Wagtail redirect page. Can link to page, URL and document <https://gist.github.com/alej0varas/e7e334643ceab6e65744>`_ (24 September 2014)
* `Outputing JSON for a model with properties and db fields in Wagtail/Django <https://jossingram.wordpress.com/2014/09/24/outputing-json-for-a-model-with-properties-and-db-fields-in-wagtaildjango/>`_ (24 September 2014)
* `Bi-lingual website using Wagtail CMS <https://jossingram.wordpress.com/2014/09/17/bi-lingual-website-using-wagtail-cms/>`_ (17 September 2015)
* `Bi-lingual website using Wagtail CMS <https://jossingram.wordpress.com/2014/09/17/bi-lingual-website-using-wagtail-cms/>`_ (17 September 2014)
* `Wagtail CMS Lesser known features <https://jossingram.wordpress.com/2014/09/12/wagtail-cms-lesser-known-features/>`_ (12 September 2014)
* `Wagtail notes: stateful on/off hallo.js plugins <http://www.coactivate.org/projects/ejucovy/blog/2014/08/09/wagtail-notes-stateful-onoff-hallojs-plugins/>`_ (9 August 2014)
* `Add some blockquote buttons to Wagtail CMS WYSIWYG Editor <https://jossingram.wordpress.com/2014/07/24/add-some-blockquote-buttons-to-wagtail-cms-wysiwyg-editor/>`_ (24 July 2014)

View file

@ -1,12 +1,44 @@
Welcome to Wagtail's documentation
==================================
Wagtail is a modern, flexible CMS, built on Django.
Wagtail is an open source CMS written in `Python <https://www.python.org/>`_ and built on the `Django web framework <https://www.djangoproject.com/>`_.
Below are some useful links to help you get started with Wagtail.
* **First steps**
:doc:`getting_started/trying_wagtail`
:doc:`getting_started/installation`
:doc:`getting_started/creating_your_project`
* **Creating your Wagtail site**
:doc:`core_components/pages/creating_pages`
:doc:`Writing templates <core_components/pages/writing_templates>`
:doc:`core_components/images/index`
:doc:`core_components/search/index`
:doc:`howto/third_party_tutorials`
* **Using Wagtail**
:doc:`Editors guide <editor_manual/index>`
Index
-----
It supports Django 1.7.0+ on Python 2.7, 3.3 and 3.4.
.. toctree::
:maxdepth: 3
:maxdepth: 2
:titlesonly:
getting_started/index

View file

@ -6,3 +6,4 @@ Reference
:maxdepth: 2
management_commands
project_template

View file

@ -0,0 +1,83 @@
The project template
====================
.. code-block:: text
mysite/
core/
static/
templates/
base.html
404.html
500.html
mysite/
settings/
base.py
dev.py
production.py
manage.py
vagrant/
provision.sh
Vagrantfile
readme.rst
requirements.txt
The "core" app
----------------
Location: ``/mysite/core/``
This app is here to help get you started quicker by providing a ``HomePage`` model with migrations to create one when you first setup your app.
Default templates and static files
----------------------------------
Location: ``/mysite/core/templates/`` and ``/mysite/core/static/``
The templates directory contains ``base.html``, ``404.html`` and ``500.html``. These files are very commonly needed on Wagtail sites to they have been added into the template.
The static directory contains an empty javascript and sass file. Wagtail uses ``django-compressor`` for compiling and compressing static files. For more information, see: `Django Compressor Documentation <http://django-compressor.readthedocs.org/en/latest/>`_
Vagrant configuration
---------------------
Location: ``/Vagrantfile`` and ``/vagrant/``
If you have Vagrant installed, these files let you easily setup a development environment with PostgreSQL and Elasticsearch inside a virtual machine.
See :doc:`../getting_started/using_vagrant` for info on how to use Vagrant in development
If you do not want to use Vagrant, you can just delete these files.
Django settings
---------------
Location: ``/mysite/mysite/settings/``
The Django settings files are split up into ``base.py``, ``dev.py``, ``production.py`` and ``local.py``.
.. glossary::
``base.py``
This file is for global settings that will be used in both development and production. Aim to keep most of your configuration in this file.
``dev.py``
This file is for settings that will only be used by developers. For example: ``DEBUG = True``
``production.py``
This file is for settings that will only run on a production server. For example: ``DEBUG = False``
``local.py``
This file is used for settings local to a particular machine. This file should never be tracked by a version control system.
.. tip::
On production servers, we recommend that you only store secrets in local.py (such as API keys and passwords). This can save you headaches in the future if you are ever trying to debug why a server is behaving badly. If you are using multiple servers which need different settings then we recommend that you create a different ``production.py`` file for each one.

View file

@ -1,6 +1,6 @@
============================================
Wagtail 0.8.5 release notes - IN DEVELOPMENT
============================================
===========================
Wagtail 0.8.5 release notes
===========================
.. contents::
:local:
@ -21,3 +21,7 @@ Bug fixes
* Punctuation characters are no longer stripped when performing search queries
* When adding tags where there were none before, it is now possible to save a single tag with multiple words in it
* ``richtext`` template tag no longer raises ``TypeError`` if ``None`` is passed into it
* Serving documents now uses a streaming HTTP response and will no longer break Django's cache middleware
* User admin area no longer fails in the presence of negative user IDs (as used by django-guardian's default settings)
* Password reset emails now use the ``BASE_URL`` setting for the reset URL
* ``BASE_URL`` is now included in the project template's default settings file

View file

@ -23,14 +23,18 @@ Minor features
* Dropped Python 2.6 and 3.2 support
* Dropped Elasticsearch 0.90.x support
* Search view accepts "page" GET parameter in line with pagination
* Removed the dependency on `LOGIN_URL` and `LOGIN_REDIRECT_URL` settings
* Removed the dependency on ``LOGIN_URL`` and ``LOGIN_REDIRECT_URL`` settings
* Password reset view names namespaced to wagtailadmin
* Removed the need to add permission check on admin views (now automated)
* Reversing `django.contrib.auth.admin.login` will no longer lead to Wagtails login view (making it easier to have front end views)
* Reversing ``django.contrib.auth.admin.login`` will no longer lead to Wagtails login view (making it easier to have front end views)
* Added cache-control headers to all admin views. This allows Varnish/Squid/CDN to run on vanilla settings in front of a Wagtail site
* Added validation to prevent pages being created with only whitespace characters in their title fields
* Page model fields without a FieldPanel are no longer displayed in the form
* No longer need to specify the base model on InlinePanel definitions
* The project template Vagrantfile now listens on port 8000
* The external link chooser in rich text areas now accepts URLs of the form '/some/local/path', to allow linking to non-Wagtail-controlled URLs within the local site
* SCSS files in wagtailadmin now use absolute imports, to permit overriding by user stylesheets
* Bare text entered in rich text areas is now automatically wrapped in a paragraph element
Bug fixes

View file

@ -8,7 +8,7 @@ Vagrant::Config.run do |config|
# Forward a port from the guest to the host, which allows for outside
# computers to access the VM, whereas host only networking does not.
config.vm.forward_port 8000, 8111
config.vm.forward_port 8000, 8000
# Share an additional folder to the guest VM. The first argument is
# an identifier, the second is the path on the guest to mount the

View file

@ -28,6 +28,11 @@ TEMPLATE_DEBUG = True
ALLOWED_HOSTS = []
# Base URL to use when referring to full URLs within the Wagtail admin backend -
# e.g. in notification emails. Don't include '/admin' or a trailing slash
BASE_URL = 'http://example.com'
# Application definition
INSTALLED_APPS = (

View file

@ -1,6 +1,6 @@
# Minimal requirements
Django>=1.7,<1.8
wagtail==0.8.4
wagtail==0.8.5
# Recommended components (require additional setup):
# psycopg2==2.5.2

View file

@ -16,6 +16,8 @@ DATABASES = {
'TEST_NAME': os.environ.get('DATABASE_NAME', 'test_wagtaildemo'),
'USER': os.environ.get('DATABASE_USER', 'postgres'),
'PASSWORD': os.environ.get('DATABASE_PASS', None),
'HOST': os.environ.get('POSTGRES_PORT_5432_TCP_ADDR', None),
'PORT': os.environ.get('POSTGRES_PORT_5432_TCP_PORT', None),
}
}
@ -121,6 +123,13 @@ try:
'TIMEOUT': 10,
'max_retries': 1,
}
# Check if we're running in Drone
if 'ELASTICSEARCH_PORT_9200_TCP_PORT' in os.environ:
ip = os.environ.get('ELASTICSEARCH_PORT_9200_TCP_ADDR')
port = os.environ.get('ELASTICSEARCH_PORT_9200_TCP_PORT')
WAGTAILSEARCH_BACKENDS['elasticsearch']['URLS'] = ['http://%s:%s/' % (ip, port)]
except ImportError:
pass

View file

@ -1,4 +1,6 @@
from django import forms
from django.core import validators
from django.forms.widgets import TextInput
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import AuthenticationForm, PasswordResetForm
from django.utils.translation import ugettext as _
@ -6,6 +8,25 @@ from django.utils.translation import ungettext, ugettext_lazy
from wagtail.wagtailadmin.widgets import AdminPageChooser
from wagtail.wagtailcore.models import Page
class URLOrAbsolutePathValidator(validators.URLValidator):
@staticmethod
def is_absolute_path(value):
return value.startswith('/')
def __call__(self, value):
if URLOrAbsolutePathValidator.is_absolute_path(value):
return None
else:
return super(URLOrAbsolutePathValidator, self).__call__(value)
class URLOrAbsolutePathField(forms.URLField):
widget = TextInput
default_validators = [URLOrAbsolutePathValidator()]
def to_python(self, value):
if not URLOrAbsolutePathValidator.is_absolute_path(value):
value = super(URLOrAbsolutePathField, self).to_python(value)
return value
class SearchForm(forms.Form):
def __init__(self, *args, **kwargs):
@ -22,11 +43,11 @@ class SearchForm(forms.Form):
class ExternalLinkChooserForm(forms.Form):
url = forms.URLField(required=True)
url = URLOrAbsolutePathField(required=True)
class ExternalLinkChooserWithLinkTextForm(forms.Form):
url = forms.URLField(required=True)
url = URLOrAbsolutePathField(required=True)
link_text = forms.CharField(required=True)

View file

@ -0,0 +1,17 @@
(function() {
(function(jQuery) {
return jQuery.widget("IKS.hallorequireparagraphs", {
options: {
editable: null,
uuid: '',
blockElements: ["dd", "div", "dl", "figure", "form", "ul", "ol", "table", "p", "h1", "h2", "h3", "h4", "h5", "h6"]
},
cleanupContentClone: function(el) {
// if the editable element contains no block-level elements wrap the contents in a <P>
if(el.html().length && !jQuery(this.options.blockElements.toString(), el).length){
this.options.editable.execute('formatBlock', 'p');
}
}
});
})(jQuery);
}).call(this);

View file

@ -6,7 +6,8 @@ var halloPlugins = {
'hallolists': {},
'hallohr': {},
'halloreundo': {},
'hallowagtaillink': {}
'hallowagtaillink': {},
'hallorequireparagraphs': {}
};
function registerHalloPlugin(name, opts) {

View file

@ -72,7 +72,9 @@ $submenu-color:darken($color-grey-1, 5%);
font-size:0.95em;
font-weight:300;
&:hover{
&:hover,
&:focus{
outline:none;
background-color:rgba(100,100,100,0.15);
color:white;
text-shadow:-1px -1px 0px rgba(0,0,0,0.3);

View file

@ -1,21 +1,21 @@
@import "variables.scss";
@import "mixins.scss";
@import "grid.scss";
@import "wagtailadmin/scss/variables.scss";
@import "wagtailadmin/scss/mixins.scss";
@import "wagtailadmin/scss/grid.scss";
@import "components/explorer.scss";
@import "components/icons.scss";
@import "components/typography.scss";
@import "components/tabs.scss";
@import "components/dropdowns.scss";
@import "components/modals.scss";
@import "components/forms.scss";
@import "components/listing.scss";
@import "components/messages.scss";
@import "components/formatters.scss";
@import "components/header.scss";
@import "components/progressbar.scss";
@import "components/datetimepicker.scss";
@import "components/main-nav.scss";
@import "wagtailadmin/scss/components/explorer.scss";
@import "wagtailadmin/scss/components/icons.scss";
@import "wagtailadmin/scss/components/typography.scss";
@import "wagtailadmin/scss/components/tabs.scss";
@import "wagtailadmin/scss/components/dropdowns.scss";
@import "wagtailadmin/scss/components/modals.scss";
@import "wagtailadmin/scss/components/forms.scss";
@import "wagtailadmin/scss/components/listing.scss";
@import "wagtailadmin/scss/components/messages.scss";
@import "wagtailadmin/scss/components/formatters.scss";
@import "wagtailadmin/scss/components/header.scss";
@import "wagtailadmin/scss/components/progressbar.scss";
@import "wagtailadmin/scss/components/datetimepicker.scss";
@import "wagtailadmin/scss/components/main-nav.scss";
@import "fonts.scss";

View file

@ -1,6 +1,6 @@
@import "../variables.scss";
@import "../mixins.scss";
@import "../grid.scss";
@import "wagtailadmin/scss/variables.scss";
@import "wagtailadmin/scss/mixins.scss";
@import "wagtailadmin/scss/grid.scss";
h1{
font-weight:300;

View file

@ -1,6 +1,6 @@
@import "../variables.scss";
@import "../mixins.scss";
@import "../grid.scss";
@import "wagtailadmin/scss/variables.scss";
@import "wagtailadmin/scss/mixins.scss";
@import "wagtailadmin/scss/grid.scss";
// overrides default nice padding defined in variables.scss
$desktop-nice-padding: 100px;

View file

@ -1,6 +1,6 @@
@import "../variables.scss";
@import "../mixins.scss";
@import "../grid.scss";
@import "wagtailadmin/scss/variables.scss";
@import "wagtailadmin/scss/mixins.scss";
@import "wagtailadmin/scss/grid.scss";
.page-editor {
.content-wrapper{

View file

@ -1,5 +1,5 @@
@import "../variables.scss";
@import "../mixins.scss";
@import "wagtailadmin/scss/variables.scss";
@import "wagtailadmin/scss/mixins.scss";
/* This font is just a single spinner glyph */
@font-face {

View file

@ -1,5 +1,5 @@
@import "../variables.scss";
@import "../mixins.scss";
@import "wagtailadmin/scss/variables.scss";
@import "wagtailadmin/scss/mixins.scss";
.hallotoolbar{
position:absolute;

View file

@ -1,9 +1,9 @@
@import "variables.scss";
@import "mixins.scss";
@import "wagtailadmin/scss/variables.scss";
@import "wagtailadmin/scss/mixins.scss";
@import "components/icons.scss";
@import "wagtailadmin/scss/components/icons.scss";
@import "fonts.scss";
@import "wagtailadmin/scss/fonts.scss";
html, body{
background-color:transparent;

View file

@ -1,3 +1,3 @@
{% load i18n %}
{% load i18n wagtailadmin_tags %}{% base_url_setting as base_url %}
{% trans "Please follow the link below to reset your password" %}
{{ protocol }}://{{ domain }}{% url 'wagtailadmin_password_reset_confirm' uidb64=uid token=token %}
{% if base_url %}{{ base_url }}{% else %}{{ protocol }}://{{ domain }}{% endif %}{% url 'wagtailadmin_password_reset_confirm' uidb64=uid token=token %}

View file

@ -18,6 +18,7 @@
<script src="{{ STATIC_URL }}wagtailadmin/js/modal-workflow.js"></script>
<script src="{{ STATIC_URL }}wagtailadmin/js/hallo-plugins/hallo-wagtaillink.js"></script>
<script src="{{ STATIC_URL }}wagtailadmin/js/hallo-plugins/hallo-hr.js"></script>
<script src="{{ STATIC_URL }}wagtailadmin/js/hallo-plugins/hallo-requireparagraphs.js"></script>
<script src="{{ STATIC_URL }}wagtailadmin/js/page-editor.js"></script>
<script src="{{ STATIC_URL }}wagtailadmin/js/page-chooser.js"></script>
<script src="{{ STATIC_URL }}admin/js/urlify.js"></script>

View file

@ -136,6 +136,11 @@ def usage_count_enabled():
return getattr(settings, 'WAGTAIL_USAGE_COUNT_ENABLED', False)
@register.assignment_tag
def base_url_setting():
return getattr(settings, 'BASE_URL', None)
class EscapeScriptNode(template.Node):
TAG_NAME = 'escapescript'

View file

@ -101,9 +101,24 @@ class TestChooserExternalLink(TestCase, WagtailTestUtils):
self.assertEqual(self.get({'prompt_for_link_text': 'foo'}).status_code, 200)
def test_create_link(self):
request = self.post({'url': 'http://www.example.com'})
self.assertContains(request, "'url': 'http://www.example.com/',")
self.assertContains(request, "'title': 'http://www.example.com/'")
response = self.post({'url': 'http://www.example.com'})
self.assertEqual(response.status_code, 200)
self.assertContains(response, "'onload'") # indicates success / post back to calling page
self.assertContains(response, "'url': 'http://www.example.com/',")
self.assertContains(response, "'title': 'http://www.example.com/'")
def test_invalid_url(self):
response = self.post({'url': 'ntp://www.example.com'})
self.assertEqual(response.status_code, 200)
self.assertContains(response, "'html'") # indicates failure / show error message
self.assertContains(response, "Enter a valid URL.")
def test_allow_local_url(self):
response = self.post({'url': '/admin/'})
self.assertEqual(response.status_code, 200)
self.assertContains(response, "'onload'") # indicates success / post back to calling page
self.assertContains(response, "'url': '/admin/',")
self.assertContains(response, "'title': '/admin/'")
class TestChooserEmailLink(TestCase, WagtailTestUtils):

View file

@ -0,0 +1,33 @@
from django.test import TestCase, override_settings
from django.core import mail
from wagtail.tests.utils import WagtailTestUtils
from wagtail.wagtailcore.models import Site
class TestUserPasswordReset(TestCase, WagtailTestUtils):
fixtures = ['test.json']
# need to clear urlresolver caches before/after tests, because we override ROOT_URLCONF
# in some tests here
def setUp(self):
from django.core.urlresolvers import clear_url_caches
clear_url_caches()
def tearDown(self):
from django.core.urlresolvers import clear_url_caches
clear_url_caches()
@override_settings(ROOT_URLCONF="wagtail.wagtailadmin.urls")
def test_email_found_default_url(self):
response = self.client.post('/password_reset/', {'email': 'siteeditor@example.com'})
self.assertEqual(response.status_code, 302)
self.assertEqual(len(mail.outbox), 1)
self.assertIn("testserver", mail.outbox[0].body)
@override_settings(ROOT_URLCONF="wagtail.wagtailadmin.urls", BASE_URL='http://mysite.com')
def test_email_found_base_url(self):
response = self.client.post('/password_reset/', {'email': 'siteeditor@example.com'})
self.assertEqual(response.status_code, 302)
self.assertEqual(len(mail.outbox), 1)
self.assertIn("mysite.com", mail.outbox[0].body)

View file

@ -26,11 +26,7 @@ from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ValidationError, ImproperlyConfigured, ObjectDoesNotExist
from django.utils.functional import cached_property
from django.utils.encoding import python_2_unicode_compatible
try:
from django.core import checks
except ImportError:
pass
from django.core import checks
from treebeard.mp_tree import MP_Node

View file

@ -1,5 +1,6 @@
from six import b
import unittest
import mock
from django.test import TestCase
from django.contrib.auth import get_user_model
@ -17,9 +18,6 @@ from wagtail.wagtaildocs.models import Document
from wagtail.wagtaildocs import models
# TODO: Test serve view
class TestDocumentPermissions(TestCase):
def setUp(self):
# Create some user accounts for testing permissions
@ -519,3 +517,46 @@ class TestIssue613(TestCase, WagtailTestUtils):
# Check
self.assertEqual(len(results), 1)
self.assertEqual(results[0].id, document.id)
class TestServeView(TestCase):
def setUp(self):
self.document = models.Document(title="Test document")
self.document.file.save('example.doc', ContentFile("A boring example document"))
def get(self):
return self.client.get(reverse('wagtaildocs_serve', args=(self.document.id, 'example.doc')))
def test_response_code(self):
self.assertEqual(self.get().status_code, 200)
@unittest.expectedFailure # Filename has a random string appended to it
def test_content_disposition_header(self):
self.assertEqual(self.get()['Content-Disposition'], 'attachment; filename=example.doc')
def test_content_length_header(self):
self.assertEqual(self.get()['Content-Length'], '25')
def test_is_streaming_response(self):
self.assertTrue(self.get().streaming)
def test_content(self):
self.assertEqual(b"".join(self.get().streaming_content), b"A boring example document")
def test_document_served_fired(self):
mock_handler = mock.MagicMock()
models.document_served.connect(mock_handler)
self.get()
self.assertEqual(mock_handler.call_count, 1)
self.assertEqual(mock_handler.mock_calls[0][2]['sender'], self.document)
def test_with_nonexistent_document(self):
response = self.client.get(reverse('wagtaildocs_serve', args=(1000, 'blahblahblah', )))
self.assertEqual(response.status_code, 404)
@unittest.expectedFailure
def test_with_incorrect_filename(self):
response = self.client.get(reverse('wagtaildocs_serve', args=(self.document.id, 'incorrectfilename')))
self.assertEqual(response.status_code, 404)

View file

@ -1,6 +1,6 @@
from django.shortcuts import get_object_or_404
from django.core.servers.basehttp import FileWrapper
from django.http import HttpResponse
from wsgiref.util import FileWrapper
from django.http import StreamingHttpResponse
from wagtail.wagtaildocs.models import Document, document_served
@ -8,7 +8,7 @@ from wagtail.wagtaildocs.models import Document, document_served
def serve(request, document_id, document_filename):
doc = get_object_or_404(Document, id=document_id)
wrapper = FileWrapper(doc.file)
response = HttpResponse(wrapper, content_type='application/octet-stream')
response = StreamingHttpResponse(wrapper, content_type='application/octet-stream')
# TODO: strip out weird characters like semicolons from the filename
# (there doesn't seem to be an official way of escaping them)

View file

@ -57,13 +57,3 @@ class Rect(object):
x + width / 2,
y + height / 2,
)
# DELETEME
def get_key(self):
return "%(x)d-%(y)d-%(width)dx%(height)d" % {
'x': int(self.centroid_x),
'y': int(self.centroid_y),
'width': int(self.width),
'height': int(self.height),
}

View file

@ -237,7 +237,3 @@ class TestRect(TestCase):
def test_from_point(self):
rect = Rect.from_point(100, 200, 50, 20)
self.assertEqual(rect, Rect(75, 190, 125, 210))
def test_get_key(self):
rect = Rect(100, 150, 200, 250)
self.assertEqual(rect.get_key(), '150-200-100x100')

View file

@ -16,6 +16,8 @@ from wagtail.wagtailcore.models import Page, GroupPagePermission
class TestUserIndexView(TestCase, WagtailTestUtils):
def setUp(self):
# create a user that should be visible in the listing
self.test_user = get_user_model().objects.create_user(username='testuser', email='testuser@email.com', password='password')
self.login()
def get(self, params={}):
@ -25,6 +27,15 @@ class TestUserIndexView(TestCase, WagtailTestUtils):
response = self.get()
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'wagtailusers/users/index.html')
self.assertContains(response, 'testuser')
def test_allows_negative_ids(self):
# see https://github.com/torchbox/wagtail/issues/565
get_user_model().objects.create_user('guardian', 'guardian@example.com', 'gu@rd14n', id=-1)
response = self.get()
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'testuser')
self.assertContains(response, 'guardian')
def test_search(self):
response = self.get({'q': "Hello"})
@ -215,7 +226,7 @@ class TestGroupCreateView(TestCase, WagtailTestUtils):
new_group = Group.objects.get(name='test group')
self.assertEqual(new_group.page_permissions.all().count(), 2)
@unittest.skip("currently failing on Django 1.7")
@unittest.expectedFailure
def test_duplicate_page_permissions_error(self):
# Try to submit duplicate page permission entries
response = self.post({

View file

@ -4,5 +4,5 @@ from wagtail.wagtailusers.views import users
urlpatterns = [
url(r'^$', users.index, name='wagtailusers_users_index'),
url(r'^new/$', users.create, name='wagtailusers_users_create'),
url(r'^(\d+)/$', users.edit, name='wagtailusers_users_edit'),
url(r'^([^\/]+)/$', users.edit, name='wagtailusers_users_edit'),
]