mirror of
https://github.com/Hopiu/wagtail.git
synced 2026-05-21 21:41:55 +00:00
Merge branch 'master' into multiple-page-types-in-page-chooser
Conflicts: wagtail/wagtailadmin/views/chooser.py
This commit is contained in:
commit
b67426c86b
200 changed files with 2754 additions and 1993 deletions
2
.jscsrc
2
.jscsrc
|
|
@ -12,7 +12,7 @@
|
|||
"**/*.min.js",
|
||||
"**/vendor/**/*.js",
|
||||
"./wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/inline_panel.js",
|
||||
"./wagtail/wagtailsearch/templates/wagtailsearch/editorspicks/includes/editorspicks_formset.js",
|
||||
"./wagtail/contrib/wagtailsearchpromotions/templates/wagtailsearchpromotions/includes/searchpromotions_formset.js",
|
||||
"./wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_formset.js",
|
||||
"./wagtail/wagtailsnippets/templates/wagtailsnippets/chooser/chosen.js",
|
||||
"./wagtail/wagtailimages/templates/wagtailimages/chooser/image_chosen.js",
|
||||
|
|
|
|||
|
|
@ -5,13 +5,23 @@ Changelog
|
|||
~~~~~~~~~~~~~~~~
|
||||
|
||||
* Implemented the `specific()` method on PageQuerySet, to return pages as their most specific type
|
||||
* "Promoted search results" has moved into its own module
|
||||
* Elasticsearch backend now supports an experimental `ATOMIC_REBUILD` flag to keep the existing index available while the `update_index` task is running
|
||||
* The wagtailapi module has been refactored to use Django REST Framework
|
||||
* Implemented pagination in the page chooser modal
|
||||
* Changed INSTALLED_APPS in project template to list apps in precedence order (Piet Delport)
|
||||
* The `{% image %}` tag now supports filters on the image variable, e.g. `{% image primary_img|default:secondary_img width-500 %}`
|
||||
* Moved the style guide menu item into the Settings sub-menu
|
||||
* Search backends can now be specified by module (e.g. `wagtail.wagtailsearch.backends.elasticsearch`), rather than a specific class (`wagtail.wagtailsearch.backends.elasticsearch.ElasticSearch`)
|
||||
* Added ``descendant_of`` filter to the API (Michael Fillier)
|
||||
* Added optional directory argument to "wagtail start" command (Mitchel Cabuloy)
|
||||
* Non-superusers can now view/edit/delete sites if they have the correct permissions
|
||||
* Image file size is now stored in the database, to avoid unnecessary filesystem lookups
|
||||
* Updated URLs within the admin backend to use namespaces
|
||||
* The `update_index` task now indexes objects in batches of 1000, to indicate progress and avoid excessive memory use
|
||||
* Fix: Text areas in the non-default tab of the page editor now resize to the correct height
|
||||
* Fix: Tabs in "insert link" modal in the rich text editor no longer disappear (Tim Heap)
|
||||
* Fix: H2 elements in rich text fields were accidentally given a click() binding when put insite a collapsible multi field panel
|
||||
|
||||
|
||||
1.0 (16.07.2015)
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ Contributors
|
|||
* Nar Chhantyal
|
||||
* Michael Fillier
|
||||
* Mitchel Cabuloy
|
||||
* Piet Delport
|
||||
* Tom Christie
|
||||
|
||||
Translators
|
||||
===========
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ Create a template at ``blog/templates/blog/blog_page.html``:
|
|||
|
||||
{% load wagtailcore_tags %}
|
||||
|
||||
{% block body_class %}templage-blogpage{% endblock %}
|
||||
{% block body_class %}template-blogpage{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ self.title }}</h1>
|
||||
|
|
@ -217,7 +217,7 @@ Adjust your blog page template to include the image:
|
|||
|
||||
{% load wagtailcore_tags wagtailimages_tags %}
|
||||
|
||||
{% block body_class %}templage-blogpage{% endblock %}
|
||||
{% block body_class %}template-blogpage{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ self.title }}</h1>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ Wagtail ships with a variety of extra optional modules.
|
|||
frontendcache
|
||||
routablepage
|
||||
api/index
|
||||
searchpromotions
|
||||
|
||||
|
||||
:doc:`forms`
|
||||
|
|
@ -49,3 +50,9 @@ Provides a way of embedding Django URLconfs into pages.
|
|||
----------------
|
||||
|
||||
A module for adding a read only, JSON based web API to your Wagtail site
|
||||
|
||||
|
||||
:doc:`searchpromotions`
|
||||
-----------------------
|
||||
|
||||
A module for managing "Promoted Search Results"
|
||||
|
|
|
|||
63
docs/reference/contrib/searchpromotions.rst
Normal file
63
docs/reference/contrib/searchpromotions.rst
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
.. _editors-picks:
|
||||
|
||||
=======================
|
||||
Promoted search results
|
||||
=======================
|
||||
|
||||
.. module:: wagtail.contrib.wagtailsearchpromotions
|
||||
|
||||
.. versionchanged:: 1.1
|
||||
|
||||
Before Wagtail 1.1, promoted search results were implemented in the :mod:`wagtail.wagtailsearch` core module and called "editors picks".
|
||||
|
||||
The ``searchpromotions`` module provides the models and user interface for managing "Promoted search results" and displaying them in a search results page.
|
||||
|
||||
"Promoted search results" allow editors to explicitly link relevant content to search terms, so results pages can contain curated content in addition to results from the search engine.
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
The ``searchpromotions`` module is not enabled by default. To install it, add ``wagtail.contrib.wagtailsearchpromotions`` to ``INSTALLED_APPS`` in your project's Django settings file.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
INSTALLED_APPS = [
|
||||
...
|
||||
|
||||
'wagtail.contrib.wagtailsearchpromotions',
|
||||
]
|
||||
|
||||
This app contains migrations so make sure you run the ``migrate`` django-admin command after installing.
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Once installed, a new menu item called "Promoted search results" should appear in the "Settings" menu. This is where you can assign pages to popular search terms.
|
||||
|
||||
|
||||
Displaying on a search results page
|
||||
-----------------------------------
|
||||
|
||||
To retrieve a list of promoted search results for a particular search query, you can use the ``{% get_search_promotions %}`` template tag from the ``wagtailsearchpromotions_tags`` templatetag library:
|
||||
|
||||
.. code-block:: HTML+Django
|
||||
|
||||
{% load wagtailcore_tags wagtailsearchpromotions_tags %}
|
||||
|
||||
...
|
||||
|
||||
{% get_search_promotions search_query as search_promotions %}
|
||||
|
||||
<ul>
|
||||
{% for search_promotion in search_promotions %}
|
||||
<li>
|
||||
<a href="{% pageurl search_promotion.page %}">
|
||||
<h2>{{ search_promotion.page.title }}</h2>
|
||||
<p>{{ search_promotion.description }}</p>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
|
@ -15,17 +15,56 @@ What's new
|
|||
|
||||
Usually, an operation that retrieves a queryset of pages (such as ``homepage.get_children()``) will return them as basic Page instances, which only include the core page data such as title. The ``specific()`` method (e.g. ``homepage.get_children().specific()``) now allows them to be retrieved as their most specific type, using the minimum number of queries.
|
||||
|
||||
"Promoted search results" has moved into its own module
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Previously, this was implemented in :mod:`~wagtail.wagtailsearch` but now has
|
||||
been moved into a separate module: :mod:`wagtail.contrib.wagtailsearchpromotions`
|
||||
|
||||
Atomic rebuilding of Elasticsearch indexes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Elasticsearch search backend now accepts an experimental ``ATOMIC_REBUILD`` flag which ensures that the existing search index continues to be available while the ``update_index`` task is running. See :ref:`wagtailsearch_backends_atomic_rebuild`.
|
||||
|
||||
Minor features
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
* The :mod:`~wagtail.contrib.wagtailapi` module has been refactored to use Django REST Framework
|
||||
* Implemented pagination in the page chooser modal
|
||||
* Changed INSTALLED_APPS in project template to list apps in precedence order
|
||||
* The ``{% image %}`` tag now supports filters on the image variable, e.g. ``{% image primary_img|default:secondary_img width-500 %}``
|
||||
* Moved the style guide menu item into the Settings sub-menu
|
||||
* Search backends can now be specified by module (e.g. ``wagtail.wagtailsearch.backends.elasticsearch``), rather than a specific class (``wagtail.wagtailsearch.backends.elasticsearch.ElasticSearch``)
|
||||
* Added ``descendant_of`` filter to the API
|
||||
* Added optional directory argument to "wagtail start" command
|
||||
* Non-superusers can now view/edit/delete sites if they have the correct permissions
|
||||
* Image file size is now stored in the database, to avoid unnecessary filesystem lookups
|
||||
* Updated URLs within the admin backend to use namespaces
|
||||
* The ``update_index`` task now indexes objects in batches of 1000, to indicate progress and avoid excessive memory use
|
||||
|
||||
Bug fixes
|
||||
~~~~~~~~~
|
||||
|
||||
* Text areas in the non-default tab of the page editor now resize to the correct height
|
||||
* Tabs in "insert link" modal in the rich text editor no longer disappear (Tim Heap)
|
||||
* H2 elements in rich text fields were accidentally given a click() binding when put insite a collapsible multi field panel
|
||||
|
||||
|
||||
Upgrade considerations
|
||||
======================
|
||||
|
||||
"Promoted search results" no longer in :mod:`~wagtail.wagtailsearch`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This feature has moved into a contrib module so is no longer enabled by default.
|
||||
|
||||
To re-enable it, add :mod:`wagtail.contrib.wagtailsearchpromotions` to your ``INSTALLED_APPS``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
INSTALLED_APPS = [
|
||||
...
|
||||
|
||||
'wagtail.contrib.wagtailsearchpromotions',
|
||||
|
||||
...
|
||||
|
|
|
|||
|
|
@ -41,6 +41,22 @@ The ``AUTO_UPDATE`` setting allows you to disable this on a per-index basis:
|
|||
If you have disabled auto update, you must run the :ref:`update_index` command on a regular basis to keep the index in sync with the database.
|
||||
|
||||
|
||||
.. _wagtailsearch_backends_atomic_rebuild:
|
||||
|
||||
``ATOMIC_REBUILD``
|
||||
==================
|
||||
|
||||
.. versionadded:: 1.1
|
||||
|
||||
By default (when using the Elasticsearch backend), when the ``update_index`` command is run, Wagtail deletes the index and rebuilds it from scratch. This causes the search engine to not return results until the rebuild is complete and is also risky as you can't rollback if an error occurs.
|
||||
|
||||
Setting the ``ATOMIC_REBUILD`` setting to ``True`` makes Wagtail rebuild into a separate index while keep the old index active until the new one is fully built. When the rebuild is finished, the indexes are swapped atomically and the old index is deleted.
|
||||
|
||||
.. warning:: Experimental feature
|
||||
|
||||
This feature is currently experimental. Please use it with caution.
|
||||
|
||||
|
||||
``BACKEND``
|
||||
===========
|
||||
|
||||
|
|
|
|||
|
|
@ -100,28 +100,12 @@ And here's a template to go with it:
|
|||
{% endblock %}
|
||||
|
||||
|
||||
.. _editors-picks:
|
||||
Promoted search results
|
||||
=======================
|
||||
|
||||
"Promoted search results" allow editors to explicitly link relevant content to search terms, so results pages can contain curated content in addition to results from the search engine.
|
||||
|
||||
Editor's picks
|
||||
==============
|
||||
|
||||
Editor's picks are a way of explicitly linking relevant content to search terms, so results pages can contain curated content in addition to results from the search algorithm.
|
||||
|
||||
You can get a list of editors picks for a particular query using the ``Query`` class:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
editors_picks = Query.get(search_query).editors_picks.all()
|
||||
|
||||
|
||||
Each editors pick contains the following fields:
|
||||
|
||||
``page``
|
||||
The page object associated with the pick. Use ``{% pageurl editors_pick.page %}`` to generate a URL or provide other properties of the page object.
|
||||
|
||||
``description``
|
||||
The description entered when choosing the pick, perhaps explaining why the page is relevant to the search terms.
|
||||
This functionality is provided by the :mod:`~wagtail.contrib.wagtailsearchpromotions` contrib module.
|
||||
|
||||
|
||||
Searching Images, Documents and custom models
|
||||
|
|
|
|||
1
setup.py
1
setup.py
|
|
@ -28,6 +28,7 @@ install_requires = [
|
|||
"django-modelcluster>=0.6",
|
||||
"django-taggit>=0.13.0",
|
||||
"django-treebeard==3.0",
|
||||
"djangorestframework==3.1.3",
|
||||
"Pillow>=2.6.1",
|
||||
"beautifulsoup4>=4.3.2",
|
||||
"html5lib==0.999",
|
||||
|
|
|
|||
1
tox.ini
1
tox.ini
|
|
@ -22,6 +22,7 @@ deps =
|
|||
django-taggit==0.13.0
|
||||
django-treebeard==3.0
|
||||
django-sendfile==0.3.6
|
||||
djangorestframework==3.1.3
|
||||
Pillow>=2.3.0
|
||||
beautifulsoup4>=4.3.2
|
||||
html5lib==0.999
|
||||
|
|
|
|||
|
|
@ -1,95 +0,0 @@
|
|||
import json
|
||||
from functools import wraps
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseNotFound, Http404
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from taggit.managers import _TaggableManager
|
||||
from taggit.models import Tag
|
||||
|
||||
from wagtail.utils.urlpatterns import decorate_urlpatterns
|
||||
from wagtail.wagtailcore.blocks import StreamValue
|
||||
|
||||
from .endpoints import URLPath, ObjectDetailURL, PagesAPIEndpoint, ImagesAPIEndpoint, DocumentsAPIEndpoint
|
||||
from .utils import BadRequestError, get_base_url
|
||||
|
||||
|
||||
def get_full_url(request, path):
|
||||
base_url = get_base_url(request) or ''
|
||||
return base_url + path
|
||||
|
||||
|
||||
class API(object):
|
||||
def __init__(self, endpoints):
|
||||
self.endpoints = endpoints
|
||||
|
||||
def find_model_detail_view(self, model):
|
||||
for endpoint_name, endpoint in self.endpoints.items():
|
||||
if endpoint.has_model(model):
|
||||
return 'wagtailapi_v1:%s:detail' % endpoint_name
|
||||
|
||||
def make_response(self, request, data, response_cls=HttpResponse):
|
||||
api = self
|
||||
|
||||
class WagtailAPIJSONEncoder(DjangoJSONEncoder):
|
||||
def default(self, o):
|
||||
if isinstance(o, _TaggableManager):
|
||||
return list(o.all())
|
||||
elif isinstance(o, Tag):
|
||||
return o.name
|
||||
elif isinstance(o, URLPath):
|
||||
return get_full_url(request, o.path)
|
||||
elif isinstance(o, ObjectDetailURL):
|
||||
view = api.find_model_detail_view(o.model)
|
||||
|
||||
if view:
|
||||
return get_full_url(request, reverse(view, args=(o.pk, )))
|
||||
else:
|
||||
return None
|
||||
elif isinstance(o, StreamValue):
|
||||
return o.stream_block.get_prep_value(o)
|
||||
else:
|
||||
return super(WagtailAPIJSONEncoder, self).default(o)
|
||||
|
||||
return response_cls(
|
||||
json.dumps(data, indent=4, cls=WagtailAPIJSONEncoder),
|
||||
content_type='application/json'
|
||||
)
|
||||
|
||||
def api_view(self, view):
|
||||
"""
|
||||
This is a decorator that is applied to all API views.
|
||||
|
||||
It is responsible for serialising the responses from the endpoints
|
||||
and handling errors.
|
||||
"""
|
||||
@wraps(view)
|
||||
def wrapper(request, *args, **kwargs):
|
||||
# Catch exceptions and format them as JSON documents
|
||||
try:
|
||||
return self.make_response(request, view(request, *args, **kwargs))
|
||||
except Http404 as e:
|
||||
return self.make_response(request, {
|
||||
'message': str(e)
|
||||
}, response_cls=HttpResponseNotFound)
|
||||
except BadRequestError as e:
|
||||
return self.make_response(request, {
|
||||
'message': str(e)
|
||||
}, response_cls=HttpResponseBadRequest)
|
||||
|
||||
return wrapper
|
||||
|
||||
def get_urlpatterns(self):
|
||||
return decorate_urlpatterns([
|
||||
url(r'^%s/' % name, include(endpoint.get_urlpatterns(), namespace=name))
|
||||
for name, endpoint in self.endpoints.items()
|
||||
], self.api_view)
|
||||
|
||||
|
||||
v1 = API({
|
||||
'pages': PagesAPIEndpoint(),
|
||||
'images': ImagesAPIEndpoint(),
|
||||
'documents': DocumentsAPIEndpoint(),
|
||||
})
|
||||
|
|
@ -1,100 +1,34 @@
|
|||
from __future__ import absolute_import
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
from modelcluster.models import get_all_child_relations
|
||||
from taggit.managers import _TaggableManager
|
||||
|
||||
from django.db import models
|
||||
from django.utils.encoding import force_text
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.conf.urls import url
|
||||
from django.conf import settings
|
||||
from django.http import Http404
|
||||
|
||||
from rest_framework import status
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.viewsets import GenericViewSet
|
||||
|
||||
from wagtail.wagtailcore.models import Page
|
||||
from wagtail.wagtailimages.models import get_image_model
|
||||
from wagtail.wagtaildocs.models import Document
|
||||
from wagtail.wagtailcore.utils import resolve_model_string
|
||||
from wagtail.wagtailsearch.backends import get_search_backend
|
||||
from wagtail.utils.compat import get_related_model
|
||||
|
||||
from .filters import (
|
||||
FieldsFilter, OrderingFilter, SearchFilter,
|
||||
ChildOfFilter, DescendantOfFilter
|
||||
)
|
||||
from .renderers import WagtailJSONRenderer
|
||||
from .pagination import WagtailPagination
|
||||
from .serializers import WagtailSerializer, PageSerializer, DocumentSerializer
|
||||
from .utils import BadRequestError
|
||||
|
||||
|
||||
class URLPath(object):
|
||||
"""
|
||||
This class represents a URL path that should be converted to a full URL.
|
||||
class BaseAPIEndpoint(GenericViewSet):
|
||||
renderer_classes = [WagtailJSONRenderer]
|
||||
pagination_class = WagtailPagination
|
||||
serializer_class = WagtailSerializer
|
||||
filter_classes = []
|
||||
queryset = None # Set on subclasses or implement `get_queryset()`.
|
||||
|
||||
It is used when the domain that should be used is not known at the time
|
||||
the URL was generated. It will get resolved to a full URL during
|
||||
serialisation in api.py.
|
||||
|
||||
One example use case is the documents endpoint adding download URLs into
|
||||
the JSON. The endpoint does not know the domain name to use at the time so
|
||||
returns one of these instead.
|
||||
"""
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
|
||||
|
||||
class ObjectDetailURL(object):
|
||||
def __init__(self, model, pk):
|
||||
self.model = model
|
||||
self.pk = pk
|
||||
|
||||
|
||||
def get_api_data(obj, fields):
|
||||
# Find any child relations (pages only)
|
||||
child_relations = {}
|
||||
if isinstance(obj, Page):
|
||||
child_relations = {
|
||||
child_relation.field.rel.related_name: get_related_model(child_relation)
|
||||
for child_relation in get_all_child_relations(type(obj))
|
||||
}
|
||||
|
||||
# Loop through fields
|
||||
for field_name in fields:
|
||||
# Check child relations
|
||||
if field_name in child_relations and hasattr(child_relations[field_name], 'api_fields'):
|
||||
yield field_name, [
|
||||
dict(get_api_data(child_object, child_relations[field_name].api_fields))
|
||||
for child_object in getattr(obj, field_name).all()
|
||||
]
|
||||
continue
|
||||
|
||||
# Check django fields
|
||||
try:
|
||||
field = obj._meta.get_field(field_name)
|
||||
|
||||
if field.rel and isinstance(field.rel, models.ManyToOneRel):
|
||||
# Foreign key
|
||||
val = field._get_val_from_obj(obj)
|
||||
|
||||
if val:
|
||||
yield field_name, OrderedDict([
|
||||
('id', field._get_val_from_obj(obj)),
|
||||
('meta', OrderedDict([
|
||||
('type', field.rel.to._meta.app_label + '.' + field.rel.to.__name__),
|
||||
('detail_url', ObjectDetailURL(field.rel.to, val)),
|
||||
])),
|
||||
])
|
||||
else:
|
||||
yield field_name, None
|
||||
else:
|
||||
yield field_name, field._get_val_from_obj(obj)
|
||||
|
||||
continue
|
||||
except models.fields.FieldDoesNotExist:
|
||||
pass
|
||||
|
||||
# Check attributes
|
||||
if hasattr(obj, field_name):
|
||||
value = getattr(obj, field_name)
|
||||
yield field_name, force_text(value, strings_only=True)
|
||||
continue
|
||||
|
||||
|
||||
class BaseAPIEndpoint(object):
|
||||
known_query_parameters = frozenset([
|
||||
'limit',
|
||||
'offset',
|
||||
|
|
@ -102,76 +36,48 @@ class BaseAPIEndpoint(object):
|
|||
'order',
|
||||
'search',
|
||||
])
|
||||
extra_api_fields = []
|
||||
name = None # Set on subclass.
|
||||
|
||||
def listing_view(self, request):
|
||||
return NotImplemented
|
||||
queryset = self.get_queryset()
|
||||
self.check_query_parameters(queryset)
|
||||
queryset = self.filter_queryset(queryset)
|
||||
queryset = self.paginate_queryset(queryset)
|
||||
serializer = self.get_serializer(queryset, many=True)
|
||||
return self.get_paginated_response(serializer.data)
|
||||
|
||||
def detail_view(self, request, pk):
|
||||
return NotImplemented
|
||||
instance = self.get_object()
|
||||
serializer = self.get_serializer(instance)
|
||||
return Response(serializer.data)
|
||||
|
||||
def handle_exception(self, exc):
|
||||
if isinstance(exc, Http404):
|
||||
data = {'message': str(exc)}
|
||||
return Response(data, status=status.HTTP_404_NOT_FOUND)
|
||||
elif isinstance(exc, BadRequestError):
|
||||
data = {'message': str(exc)}
|
||||
return Response(data, status=status.HTTP_400_BAD_REQUEST)
|
||||
return super(BaseAPIEndpoint, self).handle_exception(exc)
|
||||
|
||||
def get_api_fields(self, model):
|
||||
"""
|
||||
This returns a list of field names that are allowed to
|
||||
be used in the API (excluding the id field).
|
||||
"""
|
||||
api_fields = []
|
||||
api_fields = self.extra_api_fields[:]
|
||||
|
||||
if hasattr(model, 'api_fields'):
|
||||
api_fields.extend(model.api_fields)
|
||||
|
||||
return api_fields
|
||||
|
||||
def serialize_object_metadata(self, request, obj, show_details=False):
|
||||
def check_query_parameters(self, queryset):
|
||||
"""
|
||||
This returns a JSON-serialisable dict to use for the "meta"
|
||||
section of a particlular object.
|
||||
Ensure that only valid query paramters are included in the URL.
|
||||
"""
|
||||
data = OrderedDict()
|
||||
|
||||
# Add type
|
||||
data['type'] = type(obj)._meta.app_label + '.' + type(obj).__name__
|
||||
data['detail_url'] = ObjectDetailURL(type(obj), obj.pk)
|
||||
|
||||
return data
|
||||
|
||||
def serialize_object(self, request, obj, fields=frozenset(), extra_data=(), all_fields=False, show_details=False):
|
||||
"""
|
||||
This converts an object into JSON-serialisable dict so it can
|
||||
be used in the API.
|
||||
"""
|
||||
data = [
|
||||
('id', obj.id),
|
||||
]
|
||||
|
||||
# Add meta
|
||||
metadata = self.serialize_object_metadata(request, obj, show_details=show_details)
|
||||
if metadata:
|
||||
data.append(('meta', metadata))
|
||||
|
||||
# Add extra data
|
||||
data.extend(extra_data)
|
||||
|
||||
# Add other fields
|
||||
api_fields = self.get_api_fields(type(obj))
|
||||
api_fields = list(OrderedDict.fromkeys(api_fields)) # Removes any duplicates in case the user put "title" in api_fields
|
||||
|
||||
if all_fields:
|
||||
fields = api_fields
|
||||
else:
|
||||
unknown_fields = fields - set(api_fields)
|
||||
|
||||
if unknown_fields:
|
||||
raise BadRequestError("unknown fields: %s" % ', '.join(sorted(unknown_fields)))
|
||||
|
||||
# Reorder fields so it matches the order of api_fields
|
||||
fields = [field for field in api_fields if field in fields]
|
||||
|
||||
data.extend(get_api_data(obj, fields))
|
||||
|
||||
return OrderedDict(data)
|
||||
|
||||
def check_query_parameters(self, request, queryset):
|
||||
query_parameters = set(request.GET.keys())
|
||||
query_parameters = set(self.request.GET.keys())
|
||||
|
||||
# All query paramters must be either a field or an operation
|
||||
allowed_query_parameters = set(self.get_api_fields(queryset.model)).union(self.known_query_parameters).union({'id'})
|
||||
|
|
@ -179,147 +85,87 @@ class BaseAPIEndpoint(object):
|
|||
if unknown_parameters:
|
||||
raise BadRequestError("query parameter is not an operation or a recognised field: %s" % ', '.join(sorted(unknown_parameters)))
|
||||
|
||||
def do_field_filtering(self, request, queryset):
|
||||
def get_serializer_context(self):
|
||||
"""
|
||||
This performs field level filtering on the result set
|
||||
Eg: ?title=James Joyce
|
||||
The serialization context differs between listing and detail views.
|
||||
"""
|
||||
fields = set(self.get_api_fields(queryset.model)).union({'id'})
|
||||
request = self.request
|
||||
if self.action == 'listing_view':
|
||||
|
||||
for field_name, value in request.GET.items():
|
||||
if field_name in fields:
|
||||
field = getattr(queryset.model, field_name, None)
|
||||
|
||||
if isinstance(field, _TaggableManager):
|
||||
for tag in value.split(','):
|
||||
queryset = queryset.filter(**{field_name + '__name': tag})
|
||||
|
||||
# Stick a message on the queryset to indicate that tag filtering has been performed
|
||||
# This will let the do_search method know that it must raise an error as searching
|
||||
# and tag filtering at the same time is not supported
|
||||
queryset._filtered_by_tag = True
|
||||
else:
|
||||
queryset = queryset.filter(**{field_name: value})
|
||||
|
||||
return queryset
|
||||
|
||||
def do_ordering(self, request, queryset):
|
||||
"""
|
||||
This applies ordering to the result set
|
||||
Eg: ?order=title
|
||||
|
||||
It also supports reverse ordering
|
||||
Eg: ?order=-title
|
||||
|
||||
And random ordering
|
||||
Eg: ?order=random
|
||||
"""
|
||||
if 'order' in request.GET:
|
||||
# Prevent ordering while searching
|
||||
if 'search' in request.GET:
|
||||
raise BadRequestError("ordering with a search query is not supported")
|
||||
|
||||
order_by = request.GET['order']
|
||||
|
||||
# Random ordering
|
||||
if order_by == 'random':
|
||||
# Prevent ordering by random with offset
|
||||
if 'offset' in request.GET:
|
||||
raise BadRequestError("random ordering with offset is not supported")
|
||||
|
||||
return queryset.order_by('?')
|
||||
|
||||
# Check if reverse ordering is set
|
||||
if order_by.startswith('-'):
|
||||
reverse_order = True
|
||||
order_by = order_by[1:]
|
||||
if 'fields' in request.GET:
|
||||
fields = set(request.GET['fields'].split(','))
|
||||
else:
|
||||
reverse_order = False
|
||||
fields = {'title'}
|
||||
|
||||
# Add ordering
|
||||
if order_by == 'id' or order_by in self.get_api_fields(queryset.model):
|
||||
queryset = queryset.order_by(order_by)
|
||||
else:
|
||||
# Unknown field
|
||||
raise BadRequestError("cannot order by '%s' (unknown field)" % order_by)
|
||||
return {
|
||||
'request': request,
|
||||
'view': self,
|
||||
'fields': fields
|
||||
}
|
||||
|
||||
# Reverse order
|
||||
if reverse_order:
|
||||
queryset = queryset.reverse()
|
||||
return {
|
||||
'request': request,
|
||||
'view': self,
|
||||
'all_fields': True,
|
||||
'show_details': True
|
||||
}
|
||||
|
||||
return queryset
|
||||
def get_renderer_context(self):
|
||||
context = super(BaseAPIEndpoint, self).get_renderer_context()
|
||||
context['endpoints'] = [
|
||||
PagesAPIEndpoint,
|
||||
ImagesAPIEndpoint,
|
||||
DocumentsAPIEndpoint
|
||||
]
|
||||
return context
|
||||
|
||||
def do_search(self, request, queryset):
|
||||
"""
|
||||
This performs a full-text search on the result set
|
||||
Eg: ?search=James Joyce
|
||||
"""
|
||||
search_enabled = getattr(settings, 'WAGTAILAPI_SEARCH_ENABLED', True)
|
||||
|
||||
if 'search' in request.GET:
|
||||
if not search_enabled:
|
||||
raise BadRequestError("search is disabled")
|
||||
|
||||
# Searching and filtering by tag at the same time is not supported
|
||||
if getattr(queryset, '_filtered_by_tag', False):
|
||||
raise BadRequestError("filtering by tag with a search query is not supported")
|
||||
|
||||
search_query = request.GET['search']
|
||||
|
||||
sb = get_search_backend()
|
||||
queryset = sb.search(search_query, queryset)
|
||||
|
||||
return queryset
|
||||
|
||||
def do_pagination(self, request, queryset):
|
||||
"""
|
||||
This performs limit/offset based pagination on the result set
|
||||
Eg: ?limit=10&offset=20 -- Returns 10 items starting at item 20
|
||||
"""
|
||||
limit_max = getattr(settings, 'WAGTAILAPI_LIMIT_MAX', 20)
|
||||
|
||||
try:
|
||||
offset = int(request.GET.get('offset', 0))
|
||||
assert offset >= 0
|
||||
except (ValueError, AssertionError):
|
||||
raise BadRequestError("offset must be a positive integer")
|
||||
|
||||
try:
|
||||
limit = int(request.GET.get('limit', min(20, limit_max)))
|
||||
|
||||
if limit > limit_max:
|
||||
raise BadRequestError("limit cannot be higher than %d" % limit_max)
|
||||
|
||||
assert limit >= 0
|
||||
except (ValueError, AssertionError):
|
||||
raise BadRequestError("limit must be a positive integer")
|
||||
|
||||
start = offset
|
||||
stop = offset + limit
|
||||
|
||||
return queryset[start:stop]
|
||||
|
||||
def get_urlpatterns(self):
|
||||
@classmethod
|
||||
def get_urlpatterns(cls):
|
||||
"""
|
||||
This returns a list of URL patterns for the endpoint
|
||||
"""
|
||||
return [
|
||||
url(r'^$', self.listing_view, name='listing'),
|
||||
url(r'^(\d+)/$', self.detail_view, name='detail'),
|
||||
url(r'^$', cls.as_view({'get': 'listing_view'}), name='listing'),
|
||||
url(r'^(?P<pk>\d+)/$', cls.as_view({'get': 'detail_view'}), name='detail'),
|
||||
]
|
||||
|
||||
def has_model(self, model):
|
||||
return False
|
||||
@classmethod
|
||||
def has_model(cls, model):
|
||||
return NotImplemented
|
||||
|
||||
|
||||
class PagesAPIEndpoint(BaseAPIEndpoint):
|
||||
serializer_class = PageSerializer
|
||||
filter_backends = [
|
||||
FieldsFilter,
|
||||
ChildOfFilter,
|
||||
DescendantOfFilter,
|
||||
OrderingFilter,
|
||||
SearchFilter
|
||||
]
|
||||
known_query_parameters = BaseAPIEndpoint.known_query_parameters.union([
|
||||
'type',
|
||||
'child_of',
|
||||
'descendant_of',
|
||||
])
|
||||
extra_api_fields = ['title']
|
||||
name = 'pages'
|
||||
|
||||
def get_queryset(self):
|
||||
request = self.request
|
||||
|
||||
# Allow pages to be filtered to a specific type
|
||||
if 'type' not in request.GET:
|
||||
model = Page
|
||||
else:
|
||||
model_name = request.GET['type']
|
||||
try:
|
||||
model = resolve_model_string(model_name)
|
||||
except LookupError:
|
||||
raise BadRequestError("type doesn't exist")
|
||||
if not issubclass(model, Page):
|
||||
raise BadRequestError("type doesn't exist")
|
||||
|
||||
def get_queryset(self, request, model=Page):
|
||||
# Get live pages that are not in a private section
|
||||
queryset = model.objects.public().live()
|
||||
|
||||
|
|
@ -328,245 +174,33 @@ class PagesAPIEndpoint(BaseAPIEndpoint):
|
|||
|
||||
return queryset
|
||||
|
||||
def get_api_fields(self, model):
|
||||
api_fields = ['title']
|
||||
api_fields.extend(super(PagesAPIEndpoint, self).get_api_fields(model))
|
||||
return api_fields
|
||||
def get_object(self):
|
||||
base = super(PagesAPIEndpoint, self).get_object()
|
||||
return base.specific
|
||||
|
||||
def serialize_object_metadata(self, request, page, show_details=False):
|
||||
data = super(PagesAPIEndpoint, self).serialize_object_metadata(request, page, show_details=show_details)
|
||||
|
||||
# Add type
|
||||
data['type'] = page.specific_class._meta.app_label + '.' + page.specific_class.__name__
|
||||
|
||||
return data
|
||||
|
||||
def serialize_object(self, request, page, fields=frozenset(), extra_data=(), all_fields=False, show_details=False):
|
||||
# Add parent
|
||||
if show_details:
|
||||
parent = page.get_parent()
|
||||
|
||||
# Make sure the parent is visible in the API
|
||||
if self.get_queryset(request).filter(id=parent.id).exists():
|
||||
parent_class = parent.specific_class
|
||||
|
||||
extra_data += (
|
||||
('parent', OrderedDict([
|
||||
('id', parent.id),
|
||||
('meta', OrderedDict([
|
||||
('type', parent_class._meta.app_label + '.' + parent_class.__name__),
|
||||
('detail_url', ObjectDetailURL(parent_class, parent.id)),
|
||||
])),
|
||||
])),
|
||||
)
|
||||
|
||||
return super(PagesAPIEndpoint, self).serialize_object(request, page, fields=fields, extra_data=extra_data, all_fields=all_fields, show_details=show_details)
|
||||
|
||||
def get_model(self, request):
|
||||
if 'type' not in request.GET:
|
||||
return Page
|
||||
|
||||
model_name = request.GET['type']
|
||||
try:
|
||||
model = resolve_model_string(model_name)
|
||||
|
||||
if not issubclass(model, Page):
|
||||
raise BadRequestError("type doesn't exist")
|
||||
|
||||
return model
|
||||
except LookupError:
|
||||
raise BadRequestError("type doesn't exist")
|
||||
|
||||
def do_child_of_filter(self, request, queryset):
|
||||
if 'child_of' in request.GET:
|
||||
try:
|
||||
parent_page_id = int(request.GET['child_of'])
|
||||
assert parent_page_id >= 0
|
||||
except (ValueError, AssertionError):
|
||||
raise BadRequestError("child_of must be a positive integer")
|
||||
|
||||
try:
|
||||
parent_page = self.get_queryset(request).get(id=parent_page_id)
|
||||
queryset = queryset.child_of(parent_page)
|
||||
queryset._filtered_by_child_of = True
|
||||
return queryset
|
||||
except Page.DoesNotExist:
|
||||
raise BadRequestError("parent page doesn't exist")
|
||||
|
||||
return queryset
|
||||
|
||||
def do_descendant_of_filter(self, request, queryset):
|
||||
if 'descendant_of' in request.GET:
|
||||
if getattr(queryset, '_filtered_by_child_of', False):
|
||||
raise BadRequestError("filtering by descendant_of with child_of is not supported")
|
||||
try:
|
||||
ancestor_page_id = int(request.GET['descendant_of'])
|
||||
assert ancestor_page_id >= 0
|
||||
except (ValueError, AssertionError):
|
||||
raise BadRequestError("descendant_of must be a positive integer")
|
||||
|
||||
try:
|
||||
ancestor_page = self.get_queryset(request).get(id=ancestor_page_id)
|
||||
return queryset.descendant_of(ancestor_page)
|
||||
except Page.DoesNotExist:
|
||||
raise BadRequestError("ancestor page doesn't exist")
|
||||
|
||||
return queryset
|
||||
|
||||
def listing_view(self, request):
|
||||
# Get model and queryset
|
||||
model = self.get_model(request)
|
||||
queryset = self.get_queryset(request, model=model)
|
||||
|
||||
# Check query paramters
|
||||
self.check_query_parameters(request, queryset)
|
||||
|
||||
# Filtering
|
||||
queryset = self.do_field_filtering(request, queryset)
|
||||
queryset = self.do_child_of_filter(request, queryset)
|
||||
queryset = self.do_descendant_of_filter(request, queryset)
|
||||
|
||||
# Ordering
|
||||
queryset = self.do_ordering(request, queryset)
|
||||
|
||||
# Search
|
||||
queryset = self.do_search(request, queryset)
|
||||
|
||||
# Pagination
|
||||
total_count = queryset.count()
|
||||
queryset = self.do_pagination(request, queryset)
|
||||
|
||||
# Get list of fields to show in results
|
||||
if 'fields' in request.GET:
|
||||
fields = set(request.GET['fields'].split(','))
|
||||
else:
|
||||
fields = {'title'}
|
||||
|
||||
return OrderedDict([
|
||||
('meta', OrderedDict([
|
||||
('total_count', total_count),
|
||||
])),
|
||||
('pages', [
|
||||
self.serialize_object(request, page, fields=fields)
|
||||
for page in queryset
|
||||
]),
|
||||
])
|
||||
|
||||
def detail_view(self, request, pk):
|
||||
page = get_object_or_404(self.get_queryset(request), pk=pk).specific
|
||||
return self.serialize_object(request, page, all_fields=True, show_details=True)
|
||||
|
||||
def has_model(self, model):
|
||||
@classmethod
|
||||
def has_model(cls, model):
|
||||
return issubclass(model, Page)
|
||||
|
||||
|
||||
class ImagesAPIEndpoint(BaseAPIEndpoint):
|
||||
model = get_image_model()
|
||||
queryset = get_image_model().objects.all().order_by('id')
|
||||
filter_backends = [FieldsFilter, OrderingFilter, SearchFilter]
|
||||
extra_api_fields = ['title', 'tags', 'width', 'height']
|
||||
name = 'images'
|
||||
|
||||
def get_queryset(self, request):
|
||||
return self.model.objects.all().order_by('id')
|
||||
|
||||
def get_api_fields(self, model):
|
||||
api_fields = ['title', 'tags', 'width', 'height']
|
||||
api_fields.extend(super(ImagesAPIEndpoint, self).get_api_fields(model))
|
||||
return api_fields
|
||||
|
||||
def listing_view(self, request):
|
||||
queryset = self.get_queryset(request)
|
||||
|
||||
# Check query paramters
|
||||
self.check_query_parameters(request, queryset)
|
||||
|
||||
# Filtering
|
||||
queryset = self.do_field_filtering(request, queryset)
|
||||
|
||||
# Ordering
|
||||
queryset = self.do_ordering(request, queryset)
|
||||
|
||||
# Search
|
||||
queryset = self.do_search(request, queryset)
|
||||
|
||||
# Pagination
|
||||
total_count = queryset.count()
|
||||
queryset = self.do_pagination(request, queryset)
|
||||
|
||||
# Get list of fields to show in results
|
||||
if 'fields' in request.GET:
|
||||
fields = set(request.GET['fields'].split(','))
|
||||
else:
|
||||
fields = {'title'}
|
||||
|
||||
return OrderedDict([
|
||||
('meta', OrderedDict([
|
||||
('total_count', total_count),
|
||||
])),
|
||||
('images', [
|
||||
self.serialize_object(request, image, fields=fields)
|
||||
for image in queryset
|
||||
]),
|
||||
])
|
||||
|
||||
def detail_view(self, request, pk):
|
||||
image = get_object_or_404(self.get_queryset(request), pk=pk)
|
||||
return self.serialize_object(request, image, all_fields=True)
|
||||
|
||||
def has_model(self, model):
|
||||
return model == self.model
|
||||
@classmethod
|
||||
def has_model(cls, model):
|
||||
return model == get_image_model()
|
||||
|
||||
|
||||
class DocumentsAPIEndpoint(BaseAPIEndpoint):
|
||||
def get_api_fields(self, model):
|
||||
api_fields = ['title', 'tags']
|
||||
api_fields.extend(super(DocumentsAPIEndpoint, self).get_api_fields(model))
|
||||
return api_fields
|
||||
queryset = Document.objects.all().order_by('id')
|
||||
serializer_class = DocumentSerializer
|
||||
filter_backends = [FieldsFilter, OrderingFilter, SearchFilter]
|
||||
extra_api_fields = ['title', 'tags']
|
||||
name = 'documents'
|
||||
|
||||
def serialize_object_metadata(self, request, document, show_details=False):
|
||||
data = super(DocumentsAPIEndpoint, self).serialize_object_metadata(request, document, show_details=show_details)
|
||||
|
||||
# Download URL
|
||||
if show_details:
|
||||
data['download_url'] = URLPath(document.url)
|
||||
|
||||
return data
|
||||
|
||||
def listing_view(self, request):
|
||||
queryset = Document.objects.all().order_by('id')
|
||||
|
||||
# Check query paramters
|
||||
self.check_query_parameters(request, queryset)
|
||||
|
||||
# Filtering
|
||||
queryset = self.do_field_filtering(request, queryset)
|
||||
|
||||
# Ordering
|
||||
queryset = self.do_ordering(request, queryset)
|
||||
|
||||
# Search
|
||||
queryset = self.do_search(request, queryset)
|
||||
|
||||
# Pagination
|
||||
total_count = queryset.count()
|
||||
queryset = self.do_pagination(request, queryset)
|
||||
|
||||
# Get list of fields to show in results
|
||||
if 'fields' in request.GET:
|
||||
fields = set(request.GET['fields'].split(','))
|
||||
else:
|
||||
fields = {'title'}
|
||||
|
||||
return OrderedDict([
|
||||
('meta', OrderedDict([
|
||||
('total_count', total_count),
|
||||
])),
|
||||
('documents', [
|
||||
self.serialize_object(request, document, fields=fields)
|
||||
for document in queryset
|
||||
]),
|
||||
])
|
||||
|
||||
def detail_view(self, request, pk):
|
||||
document = get_object_or_404(Document, pk=pk)
|
||||
return self.serialize_object(request, document, all_fields=True, show_details=True)
|
||||
|
||||
def has_model(self, model):
|
||||
@classmethod
|
||||
def has_model(cls, model):
|
||||
return model == Document
|
||||
|
|
|
|||
150
wagtail/contrib/wagtailapi/filters.py
Normal file
150
wagtail/contrib/wagtailapi/filters.py
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
from django.conf import settings
|
||||
|
||||
from rest_framework.filters import BaseFilterBackend
|
||||
|
||||
from taggit.managers import _TaggableManager
|
||||
|
||||
from wagtail.wagtailcore.models import Page
|
||||
from wagtail.wagtailsearch.backends import get_search_backend
|
||||
|
||||
from .utils import BadRequestError, pages_for_site
|
||||
|
||||
|
||||
class FieldsFilter(BaseFilterBackend):
|
||||
def filter_queryset(self, request, queryset, view):
|
||||
"""
|
||||
This performs field level filtering on the result set
|
||||
Eg: ?title=James Joyce
|
||||
"""
|
||||
fields = set(view.get_api_fields(queryset.model)).union({'id'})
|
||||
|
||||
for field_name, value in request.GET.items():
|
||||
if field_name in fields:
|
||||
field = getattr(queryset.model, field_name, None)
|
||||
|
||||
if isinstance(field, _TaggableManager):
|
||||
for tag in value.split(','):
|
||||
queryset = queryset.filter(**{field_name + '__name': tag})
|
||||
|
||||
# Stick a message on the queryset to indicate that tag filtering has been performed
|
||||
# This will let the do_search method know that it must raise an error as searching
|
||||
# and tag filtering at the same time is not supported
|
||||
queryset._filtered_by_tag = True
|
||||
else:
|
||||
queryset = queryset.filter(**{field_name: value})
|
||||
|
||||
return queryset
|
||||
|
||||
|
||||
class OrderingFilter(BaseFilterBackend):
|
||||
def filter_queryset(self, request, queryset, view):
|
||||
"""
|
||||
This applies ordering to the result set
|
||||
Eg: ?order=title
|
||||
|
||||
It also supports reverse ordering
|
||||
Eg: ?order=-title
|
||||
|
||||
And random ordering
|
||||
Eg: ?order=random
|
||||
"""
|
||||
if 'order' in request.GET:
|
||||
# Prevent ordering while searching
|
||||
if 'search' in request.GET:
|
||||
raise BadRequestError("ordering with a search query is not supported")
|
||||
|
||||
order_by = request.GET['order']
|
||||
|
||||
# Random ordering
|
||||
if order_by == 'random':
|
||||
# Prevent ordering by random with offset
|
||||
if 'offset' in request.GET:
|
||||
raise BadRequestError("random ordering with offset is not supported")
|
||||
|
||||
return queryset.order_by('?')
|
||||
|
||||
# Check if reverse ordering is set
|
||||
if order_by.startswith('-'):
|
||||
reverse_order = True
|
||||
order_by = order_by[1:]
|
||||
else:
|
||||
reverse_order = False
|
||||
|
||||
# Add ordering
|
||||
if order_by == 'id' or order_by in view.get_api_fields(queryset.model):
|
||||
queryset = queryset.order_by(order_by)
|
||||
else:
|
||||
# Unknown field
|
||||
raise BadRequestError("cannot order by '%s' (unknown field)" % order_by)
|
||||
|
||||
# Reverse order
|
||||
if reverse_order:
|
||||
queryset = queryset.reverse()
|
||||
|
||||
return queryset
|
||||
|
||||
|
||||
class SearchFilter(BaseFilterBackend):
|
||||
def filter_queryset(self, request, queryset, view):
|
||||
"""
|
||||
This performs a full-text search on the result set
|
||||
Eg: ?search=James Joyce
|
||||
"""
|
||||
search_enabled = getattr(settings, 'WAGTAILAPI_SEARCH_ENABLED', True)
|
||||
|
||||
if 'search' in request.GET:
|
||||
if not search_enabled:
|
||||
raise BadRequestError("search is disabled")
|
||||
|
||||
# Searching and filtering by tag at the same time is not supported
|
||||
if getattr(queryset, '_filtered_by_tag', False):
|
||||
raise BadRequestError("filtering by tag with a search query is not supported")
|
||||
|
||||
search_query = request.GET['search']
|
||||
|
||||
sb = get_search_backend()
|
||||
queryset = sb.search(search_query, queryset)
|
||||
|
||||
return queryset
|
||||
|
||||
|
||||
class ChildOfFilter(BaseFilterBackend):
|
||||
def filter_queryset(self, request, queryset, view):
|
||||
if 'child_of' in request.GET:
|
||||
try:
|
||||
parent_page_id = int(request.GET['child_of'])
|
||||
assert parent_page_id >= 0
|
||||
except (ValueError, AssertionError):
|
||||
raise BadRequestError("child_of must be a positive integer")
|
||||
|
||||
site_pages = pages_for_site(request.site)
|
||||
try:
|
||||
parent_page = site_pages.get(id=parent_page_id)
|
||||
queryset = queryset.child_of(parent_page)
|
||||
queryset._filtered_by_child_of = True
|
||||
return queryset
|
||||
except Page.DoesNotExist:
|
||||
raise BadRequestError("parent page doesn't exist")
|
||||
|
||||
return queryset
|
||||
|
||||
|
||||
class DescendantOfFilter(BaseFilterBackend):
|
||||
def filter_queryset(self, request, queryset, view):
|
||||
if 'descendant_of' in request.GET:
|
||||
if getattr(queryset, '_filtered_by_child_of', False):
|
||||
raise BadRequestError("filtering by descendant_of with child_of is not supported")
|
||||
try:
|
||||
ancestor_page_id = int(request.GET['descendant_of'])
|
||||
assert ancestor_page_id >= 0
|
||||
except (ValueError, AssertionError):
|
||||
raise BadRequestError("descendant_of must be a positive integer")
|
||||
|
||||
site_pages = pages_for_site(request.site)
|
||||
try:
|
||||
ancestor_page = site_pages.get(id=ancestor_page_id)
|
||||
return queryset.descendant_of(ancestor_page)
|
||||
except Page.DoesNotExist:
|
||||
raise BadRequestError("ancestor page doesn't exist")
|
||||
|
||||
return queryset
|
||||
45
wagtail/contrib/wagtailapi/pagination.py
Normal file
45
wagtail/contrib/wagtailapi/pagination.py
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
from collections import OrderedDict
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from rest_framework.pagination import BasePagination
|
||||
from rest_framework.response import Response
|
||||
|
||||
from .utils import BadRequestError
|
||||
|
||||
|
||||
class WagtailPagination(BasePagination):
|
||||
def paginate_queryset(self, queryset, request, view=None):
|
||||
limit_max = getattr(settings, 'WAGTAILAPI_LIMIT_MAX', 20)
|
||||
|
||||
try:
|
||||
offset = int(request.GET.get('offset', 0))
|
||||
assert offset >= 0
|
||||
except (ValueError, AssertionError):
|
||||
raise BadRequestError("offset must be a positive integer")
|
||||
|
||||
try:
|
||||
limit = int(request.GET.get('limit', min(20, limit_max)))
|
||||
|
||||
if limit > limit_max:
|
||||
raise BadRequestError("limit cannot be higher than %d" % limit_max)
|
||||
|
||||
assert limit >= 0
|
||||
except (ValueError, AssertionError):
|
||||
raise BadRequestError("limit must be a positive integer")
|
||||
|
||||
start = offset
|
||||
stop = offset + limit
|
||||
|
||||
self.view = view
|
||||
self.total_count = queryset.count()
|
||||
return queryset[start:stop]
|
||||
|
||||
def get_paginated_response(self, data):
|
||||
data = OrderedDict([
|
||||
('meta', OrderedDict([
|
||||
('total_count', self.total_count),
|
||||
])),
|
||||
(self.view.name, data),
|
||||
])
|
||||
return Response(data)
|
||||
61
wagtail/contrib/wagtailapi/renderers.py
Normal file
61
wagtail/contrib/wagtailapi/renderers.py
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import json
|
||||
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.six import text_type
|
||||
|
||||
from rest_framework import renderers
|
||||
|
||||
from taggit.managers import _TaggableManager
|
||||
from taggit.models import Tag
|
||||
|
||||
from wagtail.wagtailcore.blocks import StreamValue
|
||||
|
||||
from .utils import URLPath, ObjectDetailURL, get_base_url
|
||||
|
||||
|
||||
def get_full_url(request, path):
|
||||
base_url = get_base_url(request) or ''
|
||||
return base_url + path
|
||||
|
||||
|
||||
def find_model_detail_view(model, endpoints):
|
||||
for endpoint in endpoints:
|
||||
if endpoint.has_model(model):
|
||||
return 'wagtailapi_v1:%s:detail' % endpoint.name
|
||||
|
||||
|
||||
class WagtailJSONRenderer(renderers.BaseRenderer):
|
||||
media_type = 'application/json'
|
||||
charset = None
|
||||
|
||||
def render(self, data, media_type=None, renderer_context=None):
|
||||
request = renderer_context['request']
|
||||
endpoints = renderer_context['endpoints']
|
||||
|
||||
class WagtailAPIJSONEncoder(DjangoJSONEncoder):
|
||||
def default(self, o):
|
||||
if isinstance(o, _TaggableManager):
|
||||
return list(o.all())
|
||||
elif isinstance(o, Tag):
|
||||
return o.name
|
||||
elif isinstance(o, URLPath):
|
||||
return get_full_url(request, o.path)
|
||||
elif isinstance(o, ObjectDetailURL):
|
||||
detail_view = find_model_detail_view(o.model, endpoints)
|
||||
|
||||
if detail_view:
|
||||
return get_full_url(request, reverse(detail_view, args=(o.pk, )))
|
||||
else:
|
||||
return None
|
||||
elif isinstance(o, StreamValue):
|
||||
return o.stream_block.get_prep_value(o)
|
||||
else:
|
||||
return super(WagtailAPIJSONEncoder, self).default(o)
|
||||
|
||||
ret = json.dumps(data, indent=4, cls=WagtailAPIJSONEncoder)
|
||||
|
||||
# Deal with inconsistent py2/py3 behavior, and always return bytes.
|
||||
if isinstance(ret, text_type):
|
||||
return bytes(ret.encode('utf-8'))
|
||||
return ret
|
||||
172
wagtail/contrib/wagtailapi/serializers.py
Normal file
172
wagtail/contrib/wagtailapi/serializers.py
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
from __future__ import absolute_import
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
from django.db import models
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
from modelcluster.models import get_all_child_relations
|
||||
|
||||
from rest_framework.serializers import BaseSerializer
|
||||
|
||||
from wagtail.utils.compat import get_related_model
|
||||
from wagtail.wagtailcore.models import Page
|
||||
|
||||
from .utils import ObjectDetailURL, URLPath, BadRequestError, pages_for_site
|
||||
|
||||
|
||||
def get_api_data(obj, fields):
|
||||
# Find any child relations (pages only)
|
||||
child_relations = {}
|
||||
if isinstance(obj, Page):
|
||||
child_relations = {
|
||||
child_relation.field.rel.related_name: get_related_model(child_relation)
|
||||
for child_relation in get_all_child_relations(type(obj))
|
||||
}
|
||||
|
||||
# Loop through fields
|
||||
for field_name in fields:
|
||||
# Check child relations
|
||||
if field_name in child_relations and hasattr(child_relations[field_name], 'api_fields'):
|
||||
yield field_name, [
|
||||
dict(get_api_data(child_object, child_relations[field_name].api_fields))
|
||||
for child_object in getattr(obj, field_name).all()
|
||||
]
|
||||
continue
|
||||
|
||||
# Check django fields
|
||||
try:
|
||||
field = obj._meta.get_field(field_name)
|
||||
|
||||
if field.rel and isinstance(field.rel, models.ManyToOneRel):
|
||||
# Foreign key
|
||||
val = field._get_val_from_obj(obj)
|
||||
|
||||
if val:
|
||||
yield field_name, OrderedDict([
|
||||
('id', field._get_val_from_obj(obj)),
|
||||
('meta', OrderedDict([
|
||||
('type', field.rel.to._meta.app_label + '.' + field.rel.to.__name__),
|
||||
('detail_url', ObjectDetailURL(field.rel.to, val)),
|
||||
])),
|
||||
])
|
||||
else:
|
||||
yield field_name, None
|
||||
else:
|
||||
yield field_name, field._get_val_from_obj(obj)
|
||||
|
||||
continue
|
||||
except models.fields.FieldDoesNotExist:
|
||||
pass
|
||||
|
||||
# Check attributes
|
||||
if hasattr(obj, field_name):
|
||||
value = getattr(obj, field_name)
|
||||
yield field_name, force_text(value, strings_only=True)
|
||||
continue
|
||||
|
||||
|
||||
class WagtailSerializer(BaseSerializer):
|
||||
def to_representation(self, instance):
|
||||
request = self.context['request']
|
||||
fields = self.context.get('fields', frozenset())
|
||||
all_fields = self.context.get('all_fields', False)
|
||||
show_details = self.context.get('show_details', False)
|
||||
return self.serialize_object(
|
||||
request,
|
||||
instance,
|
||||
fields=fields,
|
||||
all_fields=all_fields,
|
||||
show_details=show_details
|
||||
)
|
||||
|
||||
def serialize_object_metadata(self, request, obj, show_details=False):
|
||||
"""
|
||||
This returns a JSON-serialisable dict to use for the "meta"
|
||||
section of a particlular object.
|
||||
"""
|
||||
data = OrderedDict()
|
||||
|
||||
# Add type
|
||||
data['type'] = type(obj)._meta.app_label + '.' + type(obj).__name__
|
||||
data['detail_url'] = ObjectDetailURL(type(obj), obj.pk)
|
||||
|
||||
return data
|
||||
|
||||
def serialize_object(self, request, obj, fields=frozenset(), extra_data=(), all_fields=False, show_details=False):
|
||||
"""
|
||||
This converts an object into JSON-serialisable dict so it can
|
||||
be used in the API.
|
||||
"""
|
||||
data = [
|
||||
('id', obj.id),
|
||||
]
|
||||
|
||||
# Add meta
|
||||
metadata = self.serialize_object_metadata(request, obj, show_details=show_details)
|
||||
if metadata:
|
||||
data.append(('meta', metadata))
|
||||
|
||||
# Add extra data
|
||||
data.extend(extra_data)
|
||||
|
||||
# Add other fields
|
||||
api_fields = self.context['view'].get_api_fields(type(obj))
|
||||
api_fields = list(OrderedDict.fromkeys(api_fields)) # Removes any duplicates in case the user put "title" in api_fields
|
||||
|
||||
if all_fields:
|
||||
fields = api_fields
|
||||
else:
|
||||
unknown_fields = fields - set(api_fields)
|
||||
|
||||
if unknown_fields:
|
||||
raise BadRequestError("unknown fields: %s" % ', '.join(sorted(unknown_fields)))
|
||||
|
||||
# Reorder fields so it matches the order of api_fields
|
||||
fields = [field for field in api_fields if field in fields]
|
||||
|
||||
data.extend(get_api_data(obj, fields))
|
||||
|
||||
return OrderedDict(data)
|
||||
|
||||
|
||||
class PageSerializer(WagtailSerializer):
|
||||
def serialize_object_metadata(self, request, page, show_details=False):
|
||||
data = super(PageSerializer, self).serialize_object_metadata(request, page, show_details=show_details)
|
||||
|
||||
# Add type
|
||||
data['type'] = page.specific_class._meta.app_label + '.' + page.specific_class.__name__
|
||||
|
||||
return data
|
||||
|
||||
def serialize_object(self, request, page, fields=frozenset(), extra_data=(), all_fields=False, show_details=False):
|
||||
# Add parent
|
||||
if show_details:
|
||||
parent = page.get_parent()
|
||||
|
||||
site_pages = pages_for_site(request.site)
|
||||
if site_pages.filter(id=parent.id).exists():
|
||||
parent_class = parent.specific_class
|
||||
|
||||
extra_data += (
|
||||
('parent', OrderedDict([
|
||||
('id', parent.id),
|
||||
('meta', OrderedDict([
|
||||
('type', parent_class._meta.app_label + '.' + parent_class.__name__),
|
||||
('detail_url', ObjectDetailURL(parent_class, parent.id)),
|
||||
])),
|
||||
])),
|
||||
)
|
||||
|
||||
return super(PageSerializer, self).serialize_object(request, page, fields=fields, extra_data=extra_data, all_fields=all_fields, show_details=show_details)
|
||||
|
||||
|
||||
class DocumentSerializer(WagtailSerializer):
|
||||
def serialize_object_metadata(self, request, document, show_details=False):
|
||||
data = super(DocumentSerializer, self).serialize_object_metadata(request, document, show_details=show_details)
|
||||
|
||||
# Download URL
|
||||
if show_details:
|
||||
data['download_url'] = URLPath(document.url)
|
||||
|
||||
return data
|
||||
|
|
@ -2,9 +2,16 @@ from __future__ import absolute_import
|
|||
|
||||
from django.conf.urls import url, include
|
||||
|
||||
from . import api
|
||||
from .endpoints import PagesAPIEndpoint, ImagesAPIEndpoint, DocumentsAPIEndpoint
|
||||
|
||||
|
||||
v1 = [
|
||||
url(r'^pages/', include(PagesAPIEndpoint.get_urlpatterns(), namespace='pages')),
|
||||
url(r'^images/', include(ImagesAPIEndpoint.get_urlpatterns(), namespace='images')),
|
||||
url(r'^documents/', include(DocumentsAPIEndpoint.get_urlpatterns(), namespace='documents'))
|
||||
]
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^v1/', include(api.v1.get_urlpatterns(), namespace='wagtailapi_v1')),
|
||||
url(r'^v1/', include(v1, namespace='wagtailapi_v1')),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,11 +1,35 @@
|
|||
from django.conf import settings
|
||||
from django.utils.six.moves.urllib.parse import urlparse
|
||||
|
||||
from wagtail.wagtailcore.models import Page
|
||||
|
||||
|
||||
class BadRequestError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class URLPath(object):
|
||||
"""
|
||||
This class represents a URL path that should be converted to a full URL.
|
||||
|
||||
It is used when the domain that should be used is not known at the time
|
||||
the URL was generated. It will get resolved to a full URL during
|
||||
serialisation in api.py.
|
||||
|
||||
One example use case is the documents endpoint adding download URLs into
|
||||
the JSON. The endpoint does not know the domain name to use at the time so
|
||||
returns one of these instead.
|
||||
"""
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
|
||||
|
||||
class ObjectDetailURL(object):
|
||||
def __init__(self, model, pk):
|
||||
self.model = model
|
||||
self.pk = pk
|
||||
|
||||
|
||||
def get_base_url(request=None):
|
||||
base_url = getattr(settings, 'WAGTAILAPI_BASE_URL', request.site.root_url if request else None)
|
||||
|
||||
|
|
@ -14,3 +38,9 @@ def get_base_url(request=None):
|
|||
base_url_parsed = urlparse(base_url)
|
||||
|
||||
return base_url_parsed.scheme + '://' + base_url_parsed.netloc
|
||||
|
||||
|
||||
def pages_for_site(site):
|
||||
pages = Page.objects.public().live()
|
||||
pages = pages.descendant_of(site.root_page, inclusive=True)
|
||||
return pages
|
||||
|
|
|
|||
1
wagtail/contrib/wagtailsearchpromotions/__init__.py
Normal file
1
wagtail/contrib/wagtailsearchpromotions/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
default_app_config = 'wagtail.contrib.wagtailsearchpromotions.apps.WagtailSearchPromotionsAppConfig'
|
||||
10
wagtail/contrib/wagtailsearchpromotions/admin_urls.py
Normal file
10
wagtail/contrib/wagtailsearchpromotions/admin_urls.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
from django.conf.urls import url
|
||||
from wagtail.contrib.wagtailsearchpromotions import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.index, name='index'),
|
||||
url(r'^add/$', views.add, name='add'),
|
||||
url(r'^(\d+)/$', views.edit, name='edit'),
|
||||
url(r'^(\d+)/delete/$', views.delete, name='delete'),
|
||||
]
|
||||
7
wagtail/contrib/wagtailsearchpromotions/apps.py
Normal file
7
wagtail/contrib/wagtailsearchpromotions/apps.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class WagtailSearchPromotionsAppConfig(AppConfig):
|
||||
name = 'wagtail.contrib.wagtailsearchpromotions'
|
||||
label = 'wagtailsearchpromotions'
|
||||
verbose_name = "Wagtail search promotions"
|
||||
58
wagtail/contrib/wagtailsearchpromotions/forms.py
Normal file
58
wagtail/contrib/wagtailsearchpromotions/forms.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
from django import forms
|
||||
from django.forms.models import inlineformset_factory
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from wagtail.wagtailadmin.widgets import AdminPageChooser
|
||||
from wagtail.wagtailsearch.models import Query
|
||||
from wagtail.contrib.wagtailsearchpromotions.models import SearchPromotion
|
||||
|
||||
|
||||
class SearchPromotionForm(forms.ModelForm):
|
||||
sort_order = forms.IntegerField(required=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SearchPromotionForm, self).__init__(*args, **kwargs)
|
||||
self.fields['page'].widget = AdminPageChooser()
|
||||
|
||||
class Meta:
|
||||
model = SearchPromotion
|
||||
fields = ('query', 'page', 'description')
|
||||
|
||||
widgets = {
|
||||
'description': forms.Textarea(attrs=dict(rows=3)),
|
||||
}
|
||||
|
||||
|
||||
SearchPromotionsFormSetBase = inlineformset_factory(Query, SearchPromotion, form=SearchPromotionForm, can_order=True, can_delete=True, extra=0)
|
||||
|
||||
|
||||
class SearchPromotionsFormSet(SearchPromotionsFormSetBase):
|
||||
minimum_forms = 1
|
||||
minimum_forms_message = _("Please specify at least one recommendation for this search term.")
|
||||
|
||||
def add_fields(self, form, *args, **kwargs):
|
||||
super(SearchPromotionsFormSet, self).add_fields(form, *args, **kwargs)
|
||||
|
||||
# Hide delete and order fields
|
||||
form.fields['DELETE'].widget = forms.HiddenInput()
|
||||
form.fields['ORDER'].widget = forms.HiddenInput()
|
||||
|
||||
# Remove query field
|
||||
del form.fields['query']
|
||||
|
||||
def clean(self):
|
||||
# Search pick must have at least one recommended page to be valid
|
||||
# Check there is at least one non-deleted form.
|
||||
non_deleted_forms = self.total_form_count()
|
||||
non_empty_forms = 0
|
||||
for i in range(0, self.total_form_count()):
|
||||
form = self.forms[i]
|
||||
if self.can_delete and self._should_delete_form(form):
|
||||
non_deleted_forms -= 1
|
||||
if not (form.instance.id is None and not form.has_changed()):
|
||||
non_empty_forms += 1
|
||||
if (
|
||||
non_deleted_forms < self.minimum_forms
|
||||
or non_empty_forms < self.minimum_forms
|
||||
):
|
||||
raise forms.ValidationError(self.minimum_forms_message)
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wagtailcore', '0015_add_more_verbose_names'),
|
||||
('wagtailsearch', '0003_remove_editors_pick'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.SeparateDatabaseAndState(
|
||||
state_operations=[
|
||||
migrations.CreateModel(
|
||||
name='EditorsPick',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='ID', auto_created=True)),
|
||||
('sort_order', models.IntegerField(editable=False, null=True, blank=True)),
|
||||
('description', models.TextField(verbose_name='Description', blank=True)),
|
||||
('page', models.ForeignKey(verbose_name='Page', to='wagtailcore.Page')),
|
||||
('query', models.ForeignKey(to='wagtailsearch.Query', related_name='editors_picks')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'wagtailsearch_editorspick',
|
||||
'verbose_name': "Editor's Pick",
|
||||
'ordering': ('sort_order',),
|
||||
},
|
||||
),
|
||||
],
|
||||
database_operations=[]
|
||||
),
|
||||
migrations.AlterModelTable(
|
||||
name='editorspick',
|
||||
table=None,
|
||||
),
|
||||
migrations.RenameModel(
|
||||
old_name='EditorsPick',
|
||||
new_name='SearchPromotion'
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='searchpromotion',
|
||||
options={'ordering': ('sort_order',), 'verbose_name': 'Search promotion'},
|
||||
),
|
||||
]
|
||||
18
wagtail/contrib/wagtailsearchpromotions/models.py
Normal file
18
wagtail/contrib/wagtailsearchpromotions/models.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from wagtail.wagtailsearch.models import Query
|
||||
|
||||
|
||||
class SearchPromotion(models.Model):
|
||||
query = models.ForeignKey(Query, db_index=True, related_name='editors_picks')
|
||||
page = models.ForeignKey('wagtailcore.Page', verbose_name=_('Page'))
|
||||
sort_order = models.IntegerField(null=True, blank=True, editable=False)
|
||||
description = models.TextField(verbose_name=_('Description'), blank=True)
|
||||
|
||||
def __repr__(self):
|
||||
return 'SearchPromotion(query="' + self.query.query_string + '", page="' + self.page.title + '")'
|
||||
|
||||
class Meta:
|
||||
ordering = ('sort_order', )
|
||||
verbose_name = _("Search promotion")
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
{% extends "wagtailadmin/base.html" %}
|
||||
{% load i18n %}
|
||||
{% block titletag %}{% trans "Add editor's pick" %}{% endblock %}
|
||||
{% block titletag %}{% trans "Add search pick" %}{% endblock %}
|
||||
{% block content %}
|
||||
{% trans "Add editor's pick" as add_str %}
|
||||
{% trans "Add search pick" as add_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=add_str icon="pick" %}
|
||||
|
||||
<div class="nice-padding">
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
<p>The "Search term(s)/phrase" field below must contain the full and exact search for which you wish to provide recommended results, <em>including</em> any misspellings/user error. To help, you can choose from search terms that have been popular with users of your site.</p>
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
<form action="{% url 'wagtailsearch_editorspicks_add' %}" method="POST">
|
||||
<form action="{% url 'wagtailsearchpromotions:add' %}" method="POST">
|
||||
{% csrf_token %}
|
||||
|
||||
<ul class="fields">
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
{% include "wagtailsearch/queries/chooser_field.html" with field=query_form.query_string only %}
|
||||
</li>
|
||||
<li>
|
||||
{% include "wagtailsearch/editorspicks/includes/editorspicks_formset.html" with formset=editors_pick_formset only %}
|
||||
{% include "wagtailsearchpromotions/includes/searchpromotions_formset.html" with formset=searchpicks_formset only %}
|
||||
</li>
|
||||
<li><input type="submit" value="{% trans 'Save' %}" /></li>
|
||||
</ul>
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
{% include "wagtailadmin/pages/_editor_js.html" %}
|
||||
|
||||
<script type="text/javascript">
|
||||
{% include "wagtailsearch/editorspicks/includes/editorspicks_formset.js" with formset=editors_pick_formset only %}
|
||||
{% include "wagtailsearchpromotions/includes/searchpromotions_formset.js" with formset=searchpicks_formset only %}
|
||||
{% include "wagtailsearch/queries/chooser_field.js" only %}
|
||||
|
||||
$(function() {
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
<div class="nice-padding">
|
||||
<p>{% trans "Are you sure you want to delete all promoted results for this search term?" %}</p>
|
||||
<form action="{% url 'wagtailsearch_editorspicks_delete' query.id %}" method="POST">
|
||||
<form action="{% url 'wagtailsearchpromotions:delete' query.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="submit" value="{% trans 'Yes, delete' %}" class="serious" />
|
||||
</form>
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
{% trans "Editing" as editing_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=editing_str subtitle=query.query_string icon="pick" %}
|
||||
|
||||
<form action="{% url 'wagtailsearch_editorspicks_edit' query.id %}" method="POST" class="nice-padding">
|
||||
<form action="{% url 'wagtailsearchpromotions:edit' query.id %}" method="POST" class="nice-padding">
|
||||
{% csrf_token %}
|
||||
|
||||
<ul class="fields">
|
||||
|
|
@ -13,11 +13,11 @@
|
|||
{% include "wagtailsearch/queries/chooser_field.html" with field=query_form.query_string only %}
|
||||
</li>
|
||||
<li>
|
||||
{% include "wagtailsearch/editorspicks/includes/editorspicks_formset.html" with formset=editors_pick_formset only %}
|
||||
{% include "wagtailsearchpromotions/includes/searchpromotions_formset.html" with formset=searchpicks_formset only %}
|
||||
</li>
|
||||
<li>
|
||||
<input type="submit" value="{% trans 'Save' %}" />
|
||||
<a href="{% url 'wagtailsearch_editorspicks_delete' query.id %}" class="button button-secondary no">{% trans "Delete" %}</a>
|
||||
<a href="{% url 'wagtailsearchpromotions:delete' query.id %}" class="button button-secondary no">{% trans "Delete" %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</form>
|
||||
|
|
@ -30,11 +30,11 @@
|
|||
{% include "wagtailadmin/pages/_editor_js.html" %}
|
||||
|
||||
<script type="text/javascript">
|
||||
{% include "wagtailsearch/editorspicks/includes/editorspicks_formset.js" with formset=editors_pick_formset only %}
|
||||
{% include "wagtailsearchpromotions/includes/searchpromotions_formset.js" with formset=searchpicks_formset only %}
|
||||
{% include "wagtailsearch/queries/chooser_field.js" only %}
|
||||
|
||||
$(function() {
|
||||
createQueryChooser('{{ query_form.query_string.auto_id }}');
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
@ -2,13 +2,13 @@
|
|||
{{ formset.management_form }}
|
||||
<ul class="multiple" id="id_{{ formset.prefix }}-FORMS">
|
||||
{% for form in formset.forms %}
|
||||
{% include "wagtailsearch/editorspicks/includes/editorspicks_form.html" with form=form only %}
|
||||
{% include "wagtailsearchpromotions/includes/searchpromotion_form.html" with form=form only %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<script type="text/django-form-template" id="id_{{ formset.prefix }}-EMPTY_FORM_TEMPLATE">
|
||||
{% escapescript %}
|
||||
{% include "wagtailsearch/editorspicks/includes/editorspicks_form.html" with form=formset.empty_form only %}
|
||||
{% include "wagtailsearchpromotions/includes/searchpromotion_form.html" with form=formset.empty_form only %}
|
||||
{% endescapescript %}
|
||||
</script>
|
||||
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
{% block extra_js %}
|
||||
<script>
|
||||
window.headerSearch = {
|
||||
url: "{% url 'wagtailsearch_editorspicks_index' %}",
|
||||
url: "{% url 'wagtailsearchpromotions:index' %}",
|
||||
termInput: "#id_q",
|
||||
targetOutput: "#editorspicks-results"
|
||||
}
|
||||
|
|
@ -16,11 +16,11 @@
|
|||
{% block content %}
|
||||
{% trans "Promoted search results" as sp_title_str %}
|
||||
{% trans "Add new promoted result" as sp_text_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=sp_title_str add_link="wagtailsearch_editorspicks_add" icon="pick" add_text=sp_text_str search_url="wagtailsearch_editorspicks_index" %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=sp_title_str add_link="wagtailsearchpromotions:add" icon="pick" add_text=sp_text_str search_url="wagtailsearchpromotions:index" %}
|
||||
|
||||
<div class="nice-padding">
|
||||
<div id="editorspicks-results" class="redirects">
|
||||
{% include "wagtailsearch/editorspicks/results.html" %}
|
||||
{% include "wagtailsearchpromotions/results.html" %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
@ -14,11 +14,11 @@
|
|||
{% for query in queries %}
|
||||
<tr>
|
||||
<td class="title">
|
||||
<h2><a href="{% url 'wagtailsearch_editorspicks_edit' query.id %}" title="{% trans 'Edit this pick' %}">{{ query.query_string }}</a></h2>
|
||||
<h2><a href="{% url 'wagtailsearchpromotions:edit' query.id %}" title="{% trans 'Edit this pick' %}">{{ query.query_string }}</a></h2>
|
||||
</td>
|
||||
<td>
|
||||
{% for editors_pick in query.editors_picks.all %}
|
||||
<a href="{% url 'wagtailadmin_pages_edit' editors_pick.page.id %}" class="nolink">{{ editors_pick.page.title }}</a>{% if not forloop.last %}, {% endif %}
|
||||
{% for searchpick in query.editors_picks.all %}
|
||||
<a href="{% url 'wagtailadmin_pages:edit' searchpick.page.id %}" class="nolink">{{ searchpick.page.title }}</a>{% if not forloop.last %}, {% endif %}
|
||||
{% empty %}
|
||||
{% trans "None" %}
|
||||
{% endfor %}
|
||||
|
|
@ -27,4 +27,4 @@
|
|||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
|
|
@ -10,14 +10,14 @@
|
|||
</h2>
|
||||
{% endif %}
|
||||
|
||||
{% include "wagtailsearch/editorspicks/list.html" %}
|
||||
{% include "wagtailsearchpromotions/list.html" %}
|
||||
|
||||
{% include "wagtailadmin/shared/pagination_nav.html" with items=queries is_searching=is_searching linkurl="wagtailsearch_editorspicks_index" %}
|
||||
{% include "wagtailadmin/shared/pagination_nav.html" with items=queries is_searching=is_searching linkurl="wagtailsearchpromotions:index" %}
|
||||
{% else %}
|
||||
{% if is_searching %}
|
||||
<p>{% blocktrans %}Sorry, no promoted results match "<em>{{ query_string }}</em>"{% endblocktrans %}</p>
|
||||
{% else %}
|
||||
{% url 'wagtailsearch_editorspicks_add' as wagtailsearch_editorspicks_add_url %}
|
||||
<p>{% blocktrans %}No promoted results have been created. Why not <a href="{{ wagtailsearch_editorspicks_add_url }}">add one</a>?{% endblocktrans %}</p>
|
||||
{% url 'wagtailsearchpromotions:add' as wagtailsearchpromotions_add_url %}
|
||||
<p>{% blocktrans %}No promoted results have been created. Why not <a href="{{ wagtailsearchpromotions_add_url }}">add one</a>?{% endblocktrans %}</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
from django import template
|
||||
|
||||
from wagtail.wagtailsearch.models import Query
|
||||
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.assignment_tag()
|
||||
def get_search_promotions(search_query):
|
||||
return Query.get(search_query).editors_picks.all()
|
||||
336
wagtail/contrib/wagtailsearchpromotions/tests.py
Normal file
336
wagtail/contrib/wagtailsearchpromotions/tests.py
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
from django.test import TestCase
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from wagtail.tests.utils import WagtailTestUtils
|
||||
from wagtail.wagtailsearch.models import Query
|
||||
from wagtail.contrib.wagtailsearchpromotions.models import SearchPromotion
|
||||
from wagtail.contrib.wagtailsearchpromotions.templatetags.wagtailsearchpromotions_tags import get_search_promotions
|
||||
|
||||
|
||||
class TestSearchPromotions(TestCase):
|
||||
def test_search_pick_create(self):
|
||||
# Create a search pick to the root page
|
||||
SearchPromotion.objects.create(
|
||||
query=Query.get("root page"),
|
||||
page_id=1,
|
||||
sort_order=0,
|
||||
description="First search pick",
|
||||
)
|
||||
|
||||
# Check
|
||||
self.assertEqual(Query.get("root page").editors_picks.count(), 1)
|
||||
self.assertEqual(Query.get("root page").editors_picks.first().page_id, 1)
|
||||
|
||||
def test_search_pick_ordering(self):
|
||||
# Add 3 search picks in a different order to their sort_order values
|
||||
# They should be ordered by their sort order values and not their insertion order
|
||||
SearchPromotion.objects.create(
|
||||
query=Query.get("root page"),
|
||||
page_id=1,
|
||||
sort_order=0,
|
||||
description="First search pick",
|
||||
)
|
||||
SearchPromotion.objects.create(
|
||||
query=Query.get("root page"),
|
||||
page_id=1,
|
||||
sort_order=2,
|
||||
description="Last search pick",
|
||||
)
|
||||
SearchPromotion.objects.create(
|
||||
query=Query.get("root page"),
|
||||
page_id=1,
|
||||
sort_order=1,
|
||||
description="Middle search pick",
|
||||
)
|
||||
|
||||
# Check
|
||||
self.assertEqual(Query.get("root page").editors_picks.count(), 3)
|
||||
self.assertEqual(Query.get("root page").editors_picks.first().description, "First search pick")
|
||||
self.assertEqual(Query.get("root page").editors_picks.last().description, "Last search pick")
|
||||
|
||||
|
||||
class TestGetSearchPromotionsTemplateTag(TestCase):
|
||||
def test_get_search_promotions_template_tag(self):
|
||||
# Create a search pick to the root page
|
||||
pick = SearchPromotion.objects.create(
|
||||
query=Query.get("root page"),
|
||||
page_id=1,
|
||||
sort_order=0,
|
||||
description="First search pick",
|
||||
)
|
||||
|
||||
# Create another search pick against a different query
|
||||
SearchPromotion.objects.create(
|
||||
query=Query.get("root page again"),
|
||||
page_id=1,
|
||||
sort_order=0,
|
||||
description="Second search pick",
|
||||
)
|
||||
|
||||
# Check
|
||||
search_picks = list(get_search_promotions("root page"))
|
||||
self.assertEqual(search_picks, [pick])
|
||||
|
||||
|
||||
class TestSearchPromotionsIndexView(TestCase, WagtailTestUtils):
|
||||
def setUp(self):
|
||||
self.login()
|
||||
|
||||
def test_simple(self):
|
||||
response = self.client.get(reverse('wagtailsearchpromotions:index'))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, 'wagtailsearchpromotions/index.html')
|
||||
|
||||
def test_search(self):
|
||||
response = self.client.get(reverse('wagtailsearchpromotions:index'), {'q': "Hello"})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.context['query_string'], "Hello")
|
||||
|
||||
def make_search_picks(self):
|
||||
for i in range(50):
|
||||
SearchPromotion.objects.create(
|
||||
query=Query.get("query " + str(i)),
|
||||
page_id=1,
|
||||
sort_order=0,
|
||||
description="First search pick",
|
||||
)
|
||||
|
||||
def test_pagination(self):
|
||||
self.make_search_picks()
|
||||
|
||||
response = self.client.get(reverse('wagtailsearchpromotions:index'), {'p': 2})
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, 'wagtailsearchpromotions/index.html')
|
||||
|
||||
# Check that we got the correct page
|
||||
self.assertEqual(response.context['queries'].number, 2)
|
||||
|
||||
def test_pagination_invalid(self):
|
||||
self.make_search_picks()
|
||||
|
||||
response = self.client.get(reverse('wagtailsearchpromotions:index'), {'p': 'Hello World!'})
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, 'wagtailsearchpromotions/index.html')
|
||||
|
||||
# Check that we got page one
|
||||
self.assertEqual(response.context['queries'].number, 1)
|
||||
|
||||
def test_pagination_out_of_range(self):
|
||||
self.make_search_picks()
|
||||
|
||||
response = self.client.get(reverse('wagtailsearchpromotions:index'), {'p': 99999})
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, 'wagtailsearchpromotions/index.html')
|
||||
|
||||
# Check that we got the last page
|
||||
self.assertEqual(response.context['queries'].number, response.context['queries'].paginator.num_pages)
|
||||
|
||||
|
||||
class TestSearchPromotionsAddView(TestCase, WagtailTestUtils):
|
||||
def setUp(self):
|
||||
self.login()
|
||||
|
||||
def test_simple(self):
|
||||
response = self.client.get(reverse('wagtailsearchpromotions:add'))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, 'wagtailsearchpromotions/add.html')
|
||||
|
||||
def test_post(self):
|
||||
# Submit
|
||||
post_data = {
|
||||
'query_string': "test",
|
||||
'editors_picks-TOTAL_FORMS': 1,
|
||||
'editors_picks-INITIAL_FORMS': 0,
|
||||
'editors_picks-MAX_NUM_FORMS': 1000,
|
||||
'editors_picks-0-DELETE': '',
|
||||
'editors_picks-0-ORDER': 0,
|
||||
'editors_picks-0-page': 1,
|
||||
'editors_picks-0-description': "Hello",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailsearchpromotions:add'), post_data)
|
||||
|
||||
# User should be redirected back to the index
|
||||
self.assertRedirects(response, reverse('wagtailsearchpromotions:index'))
|
||||
|
||||
# Check that the search pick was created
|
||||
self.assertTrue(Query.get('test').editors_picks.filter(page_id=1).exists())
|
||||
|
||||
def test_post_without_recommendations(self):
|
||||
# Submit
|
||||
post_data = {
|
||||
'query_string': "test",
|
||||
'editors_picks-TOTAL_FORMS': 0,
|
||||
'editors_picks-INITIAL_FORMS': 0,
|
||||
'editors_picks-MAX_NUM_FORMS': 1000,
|
||||
}
|
||||
response = self.client.post(reverse('wagtailsearchpromotions:add'), post_data)
|
||||
|
||||
# User should be given an error
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertFormsetError(response, 'searchpicks_formset', None, None, "Please specify at least one recommendation for this search term.")
|
||||
|
||||
|
||||
class TestSearchPromotionsEditView(TestCase, WagtailTestUtils):
|
||||
def setUp(self):
|
||||
self.login()
|
||||
|
||||
# Create an search pick to edit
|
||||
self.query = Query.get("Hello")
|
||||
self.search_pick = self.query.editors_picks.create(page_id=1, description="Root page")
|
||||
self.search_pick_2 = self.query.editors_picks.create(page_id=2, description="Homepage")
|
||||
|
||||
def test_simple(self):
|
||||
response = self.client.get(reverse('wagtailsearchpromotions:edit', args=(self.query.id, )))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, 'wagtailsearchpromotions/edit.html')
|
||||
|
||||
def test_post(self):
|
||||
# Submit
|
||||
post_data = {
|
||||
'query_string': "Hello",
|
||||
'editors_picks-TOTAL_FORMS': 2,
|
||||
'editors_picks-INITIAL_FORMS': 2,
|
||||
'editors_picks-MAX_NUM_FORMS': 1000,
|
||||
'editors_picks-0-id': self.search_pick.id,
|
||||
'editors_picks-0-DELETE': '',
|
||||
'editors_picks-0-ORDER': 0,
|
||||
'editors_picks-0-page': 1,
|
||||
'editors_picks-0-description': "Description has changed", # Change
|
||||
'editors_picks-1-id': self.search_pick_2.id,
|
||||
'editors_picks-1-DELETE': '',
|
||||
'editors_picks-1-ORDER': 1,
|
||||
'editors_picks-1-page': 2,
|
||||
'editors_picks-1-description': "Homepage",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailsearchpromotions:edit', args=(self.query.id, )), post_data)
|
||||
|
||||
# User should be redirected back to the index
|
||||
self.assertRedirects(response, reverse('wagtailsearchpromotions:index'))
|
||||
|
||||
# Check that the search pick description was edited
|
||||
self.assertEqual(SearchPromotion.objects.get(id=self.search_pick.id).description, "Description has changed")
|
||||
|
||||
def test_post_reorder(self):
|
||||
# Check order before reordering
|
||||
self.assertEqual(Query.get("Hello").editors_picks.all()[0], self.search_pick)
|
||||
self.assertEqual(Query.get("Hello").editors_picks.all()[1], self.search_pick_2)
|
||||
|
||||
# Submit
|
||||
post_data = {
|
||||
'query_string': "Hello",
|
||||
'editors_picks-TOTAL_FORMS': 2,
|
||||
'editors_picks-INITIAL_FORMS': 2,
|
||||
'editors_picks-MAX_NUM_FORMS': 1000,
|
||||
'editors_picks-0-id': self.search_pick.id,
|
||||
'editors_picks-0-DELETE': '',
|
||||
'editors_picks-0-ORDER': 1, # Change
|
||||
'editors_picks-0-page': 1,
|
||||
'editors_picks-0-description': "Root page",
|
||||
'editors_picks-1-id': self.search_pick_2.id,
|
||||
'editors_picks-1-DELETE': '',
|
||||
'editors_picks-1-ORDER': 0, # Change
|
||||
'editors_picks-1-page': 2,
|
||||
'editors_picks-1-description': "Homepage",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailsearchpromotions:edit', args=(self.query.id, )), post_data)
|
||||
|
||||
# User should be redirected back to the index
|
||||
self.assertRedirects(response, reverse('wagtailsearchpromotions:index'))
|
||||
|
||||
# Check that the ordering has been saved correctly
|
||||
self.assertEqual(SearchPromotion.objects.get(id=self.search_pick.id).sort_order, 1)
|
||||
self.assertEqual(SearchPromotion.objects.get(id=self.search_pick_2.id).sort_order, 0)
|
||||
|
||||
# Check that the recommendations were reordered
|
||||
self.assertEqual(Query.get("Hello").editors_picks.all()[0], self.search_pick_2)
|
||||
self.assertEqual(Query.get("Hello").editors_picks.all()[1], self.search_pick)
|
||||
|
||||
def test_post_delete_recommendation(self):
|
||||
# Submit
|
||||
post_data = {
|
||||
'query_string': "Hello",
|
||||
'editors_picks-TOTAL_FORMS': 2,
|
||||
'editors_picks-INITIAL_FORMS': 2,
|
||||
'editors_picks-MAX_NUM_FORMS': 1000,
|
||||
'editors_picks-0-id': self.search_pick.id,
|
||||
'editors_picks-0-DELETE': '',
|
||||
'editors_picks-0-ORDER': 0,
|
||||
'editors_picks-0-page': 1,
|
||||
'editors_picks-0-description': "Root page",
|
||||
'editors_picks-1-id': self.search_pick_2.id,
|
||||
'editors_picks-1-DELETE': 1,
|
||||
'editors_picks-1-ORDER': 1,
|
||||
'editors_picks-1-page': 2,
|
||||
'editors_picks-1-description': "Homepage",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailsearchpromotions:edit', args=(self.query.id, )), post_data)
|
||||
|
||||
# User should be redirected back to the index
|
||||
self.assertRedirects(response, reverse('wagtailsearchpromotions:index'))
|
||||
|
||||
# Check that the recommendation was deleted
|
||||
self.assertFalse(SearchPromotion.objects.filter(id=self.search_pick_2.id).exists())
|
||||
|
||||
# The other recommendation should still exist
|
||||
self.assertTrue(SearchPromotion.objects.filter(id=self.search_pick.id).exists())
|
||||
|
||||
def test_post_without_recommendations(self):
|
||||
# Submit
|
||||
post_data = {
|
||||
'query_string': "Hello",
|
||||
'editors_picks-TOTAL_FORMS': 2,
|
||||
'editors_picks-INITIAL_FORMS': 2,
|
||||
'editors_picks-MAX_NUM_FORMS': 1000,
|
||||
'editors_picks-0-id': self.search_pick.id,
|
||||
'editors_picks-0-DELETE': 1,
|
||||
'editors_picks-0-ORDER': 0,
|
||||
'editors_picks-0-page': 1,
|
||||
'editors_picks-0-description': "Description has changed", # Change
|
||||
'editors_picks-1-id': self.search_pick_2.id,
|
||||
'editors_picks-1-DELETE': 1,
|
||||
'editors_picks-1-ORDER': 1,
|
||||
'editors_picks-1-page': 2,
|
||||
'editors_picks-1-description': "Homepage",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailsearchpromotions:edit', args=(self.query.id, )), post_data)
|
||||
|
||||
# User should be given an error
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertFormsetError(response, 'searchpicks_formset', None, None, "Please specify at least one recommendation for this search term.")
|
||||
|
||||
|
||||
class TestSearchPromotionsDeleteView(TestCase, WagtailTestUtils):
|
||||
def setUp(self):
|
||||
self.login()
|
||||
|
||||
# Create an search pick to delete
|
||||
self.query = Query.get("Hello")
|
||||
self.search_pick = self.query.editors_picks.create(page_id=1, description="Root page")
|
||||
self.search_pick_2 = self.query.editors_picks.create(page_id=2, description="Homepage")
|
||||
|
||||
def test_simple(self):
|
||||
response = self.client.get(reverse('wagtailsearchpromotions:delete', args=(self.query.id, )))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, 'wagtailsearchpromotions/confirm_delete.html')
|
||||
|
||||
def test_post(self):
|
||||
# Submit
|
||||
post_data = {
|
||||
'foo': 'bar',
|
||||
}
|
||||
response = self.client.post(reverse('wagtailsearchpromotions:delete', args=(self.query.id, )), post_data)
|
||||
|
||||
# User should be redirected back to the index
|
||||
self.assertRedirects(response, reverse('wagtailsearchpromotions:index'))
|
||||
|
||||
# Check that both recommendations were deleted
|
||||
self.assertFalse(SearchPromotion.objects.filter(id=self.search_pick_2.id).exists())
|
||||
|
||||
# The other recommendation should still exist
|
||||
self.assertFalse(SearchPromotion.objects.filter(id=self.search_pick.id).exists())
|
||||
|
|
@ -5,10 +5,13 @@ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
|||
from django.utils.translation import ugettext as _
|
||||
from django.views.decorators.vary import vary_on_headers
|
||||
|
||||
from wagtail.wagtailsearch import models, forms
|
||||
from wagtail.wagtailsearch import forms as search_forms
|
||||
from wagtail.wagtailsearch.models import Query
|
||||
from wagtail.wagtailadmin.forms import SearchForm
|
||||
from wagtail.wagtailadmin import messages
|
||||
|
||||
from wagtail.contrib.wagtailsearchpromotions import forms
|
||||
|
||||
|
||||
@vary_on_headers('X-Requested-With')
|
||||
def index(request):
|
||||
|
|
@ -16,7 +19,7 @@ def index(request):
|
|||
page = request.GET.get('p', 1)
|
||||
query_string = request.GET.get('q', "")
|
||||
|
||||
queries = models.Query.objects.filter(editors_picks__isnull=False).distinct()
|
||||
queries = Query.objects.filter(editors_picks__isnull=False).distinct()
|
||||
|
||||
# Search
|
||||
if query_string:
|
||||
|
|
@ -33,13 +36,13 @@ def index(request):
|
|||
queries = paginator.page(paginator.num_pages)
|
||||
|
||||
if request.is_ajax():
|
||||
return render(request, "wagtailsearch/editorspicks/results.html", {
|
||||
return render(request, "wagtailsearchpromotions/results.html", {
|
||||
'is_searching': is_searching,
|
||||
'queries': queries,
|
||||
'query_string': query_string,
|
||||
})
|
||||
else:
|
||||
return render(request, 'wagtailsearch/editorspicks/index.html', {
|
||||
return render(request, 'wagtailsearchpromotions/index.html', {
|
||||
'is_searching': is_searching,
|
||||
'queries': queries,
|
||||
'query_string': query_string,
|
||||
|
|
@ -47,21 +50,21 @@ def index(request):
|
|||
})
|
||||
|
||||
|
||||
def save_editorspicks(query, new_query, editors_pick_formset):
|
||||
def save_searchpicks(query, new_query, searchpicks_formset):
|
||||
# Save
|
||||
if editors_pick_formset.is_valid():
|
||||
if searchpicks_formset.is_valid():
|
||||
# Set sort_order
|
||||
for i, form in enumerate(editors_pick_formset.ordered_forms):
|
||||
for i, form in enumerate(searchpicks_formset.ordered_forms):
|
||||
form.instance.sort_order = i
|
||||
|
||||
# Make sure the form is marked as changed so it gets saved with the new order
|
||||
form.has_changed = lambda: True
|
||||
|
||||
editors_pick_formset.save()
|
||||
searchpicks_formset.save()
|
||||
|
||||
# If query was changed, move all editors picks to the new query
|
||||
# If query was changed, move all search picks to the new query
|
||||
if query != new_query:
|
||||
editors_pick_formset.get_queryset().update(query=new_query)
|
||||
searchpicks_formset.get_queryset().update(query=new_query)
|
||||
|
||||
return True
|
||||
else:
|
||||
|
|
@ -71,77 +74,77 @@ def save_editorspicks(query, new_query, editors_pick_formset):
|
|||
def add(request):
|
||||
if request.POST:
|
||||
# Get query
|
||||
query_form = forms.QueryForm(request.POST)
|
||||
query_form = search_forms.QueryForm(request.POST)
|
||||
if query_form.is_valid():
|
||||
query = models.Query.get(query_form['query_string'].value())
|
||||
query = Query.get(query_form['query_string'].value())
|
||||
|
||||
# Save editors picks
|
||||
editors_pick_formset = forms.EditorsPickFormSet(request.POST, instance=query)
|
||||
if save_editorspicks(query, query, editors_pick_formset):
|
||||
# Save search picks
|
||||
searchpicks_formset = forms.SearchPromotionsFormSet(request.POST, instance=query)
|
||||
if save_searchpicks(query, query, searchpicks_formset):
|
||||
messages.success(request, _("Editor's picks for '{0}' created.").format(query), buttons=[
|
||||
messages.button(reverse('wagtailsearch_editorspicks_edit', args=(query.id,)), _('Edit'))
|
||||
messages.button(reverse('wagtailsearchpromotions:edit', args=(query.id,)), _('Edit'))
|
||||
])
|
||||
return redirect('wagtailsearch_editorspicks_index')
|
||||
return redirect('wagtailsearchpromotions:index')
|
||||
else:
|
||||
if len(editors_pick_formset.non_form_errors()):
|
||||
messages.error(request, " ".join(error for error in editors_pick_formset.non_form_errors())) # formset level error (e.g. no forms submitted)
|
||||
if len(searchpicks_formset.non_form_errors()):
|
||||
messages.error(request, " ".join(error for error in searchpicks_formset.non_form_errors())) # formset level error (e.g. no forms submitted)
|
||||
else:
|
||||
messages.error(request, _("Recommendations have not been created due to errors")) # specific errors will be displayed within form fields
|
||||
else:
|
||||
editors_pick_formset = forms.EditorsPickFormSet()
|
||||
searchpicks_formset = forms.SearchPromotionsFormSet()
|
||||
else:
|
||||
query_form = forms.QueryForm()
|
||||
editors_pick_formset = forms.EditorsPickFormSet()
|
||||
query_form = search_forms.QueryForm()
|
||||
searchpicks_formset = forms.SearchPromotionsFormSet()
|
||||
|
||||
return render(request, 'wagtailsearch/editorspicks/add.html', {
|
||||
return render(request, 'wagtailsearchpromotions/add.html', {
|
||||
'query_form': query_form,
|
||||
'editors_pick_formset': editors_pick_formset,
|
||||
'searchpicks_formset': searchpicks_formset,
|
||||
})
|
||||
|
||||
|
||||
def edit(request, query_id):
|
||||
query = get_object_or_404(models.Query, id=query_id)
|
||||
query = get_object_or_404(Query, id=query_id)
|
||||
|
||||
if request.POST:
|
||||
# Get query
|
||||
query_form = forms.QueryForm(request.POST)
|
||||
query_form = search_forms.QueryForm(request.POST)
|
||||
# and the recommendations
|
||||
editors_pick_formset = forms.EditorsPickFormSet(request.POST, instance=query)
|
||||
searchpicks_formset = forms.SearchPromotionsFormSet(request.POST, instance=query)
|
||||
|
||||
if query_form.is_valid():
|
||||
new_query = models.Query.get(query_form['query_string'].value())
|
||||
new_query = Query.get(query_form['query_string'].value())
|
||||
|
||||
# Save editors picks
|
||||
if save_editorspicks(query, new_query, editors_pick_formset):
|
||||
# Save search picks
|
||||
if save_searchpicks(query, new_query, searchpicks_formset):
|
||||
messages.success(request, _("Editor's picks for '{0}' updated.").format(new_query), buttons=[
|
||||
messages.button(reverse('wagtailsearch_editorspicks_edit', args=(query.id,)), _('Edit'))
|
||||
messages.button(reverse('wagtailsearchpromotions:edit', args=(query.id,)), _('Edit'))
|
||||
])
|
||||
return redirect('wagtailsearch_editorspicks_index')
|
||||
return redirect('wagtailsearchpromotions:index')
|
||||
else:
|
||||
if len(editors_pick_formset.non_form_errors()):
|
||||
messages.error(request, " ".join(error for error in editors_pick_formset.non_form_errors())) # formset level error (e.g. no forms submitted)
|
||||
if len(searchpicks_formset.non_form_errors()):
|
||||
messages.error(request, " ".join(error for error in searchpicks_formset.non_form_errors())) # formset level error (e.g. no forms submitted)
|
||||
else:
|
||||
messages.error(request, _("Recommendations have not been saved due to errors")) # specific errors will be displayed within form fields
|
||||
|
||||
else:
|
||||
query_form = forms.QueryForm(initial=dict(query_string=query.query_string))
|
||||
editors_pick_formset = forms.EditorsPickFormSet(instance=query)
|
||||
query_form = search_forms.QueryForm(initial=dict(query_string=query.query_string))
|
||||
searchpicks_formset = forms.SearchPromotionsFormSet(instance=query)
|
||||
|
||||
return render(request, 'wagtailsearch/editorspicks/edit.html', {
|
||||
return render(request, 'wagtailsearchpromotions/edit.html', {
|
||||
'query_form': query_form,
|
||||
'editors_pick_formset': editors_pick_formset,
|
||||
'searchpicks_formset': searchpicks_formset,
|
||||
'query': query,
|
||||
})
|
||||
|
||||
|
||||
def delete(request, query_id):
|
||||
query = get_object_or_404(models.Query, id=query_id)
|
||||
query = get_object_or_404(Query, id=query_id)
|
||||
|
||||
if request.POST:
|
||||
query.editors_picks.all().delete()
|
||||
messages.success(request, _("Editor's picks deleted."))
|
||||
return redirect('wagtailsearch_editorspicks_index')
|
||||
return redirect('wagtailsearchpromotions:index')
|
||||
|
||||
return render(request, 'wagtailsearch/editorspicks/confirm_delete.html', {
|
||||
return render(request, 'wagtailsearchpromotions/confirm_delete.html', {
|
||||
'query': query,
|
||||
})
|
||||
26
wagtail/contrib/wagtailsearchpromotions/wagtail_hooks.py
Normal file
26
wagtail/contrib/wagtailsearchpromotions/wagtail_hooks.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
from django.core import urlresolvers
|
||||
from django.conf.urls import include, url
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from wagtail.wagtailcore import hooks
|
||||
from wagtail.contrib.wagtailsearchpromotions import admin_urls
|
||||
|
||||
from wagtail.wagtailadmin.menu import MenuItem
|
||||
|
||||
|
||||
@hooks.register('register_admin_urls')
|
||||
def register_admin_urls():
|
||||
return [
|
||||
url(r'^searchpicks/', include(admin_urls, namespace='wagtailsearchpromotions')),
|
||||
]
|
||||
|
||||
|
||||
class SearchPicksMenuItem(MenuItem):
|
||||
def is_shown(self, request):
|
||||
# TEMPORARY: Only show if the user is a superuser
|
||||
return request.user.is_superuser
|
||||
|
||||
|
||||
@hooks.register('register_settings_menu_item')
|
||||
def register_search_picks_menu_item():
|
||||
return SearchPicksMenuItem(_('Promoted search results'), urlresolvers.reverse('wagtailsearchpromotions:index'), classnames='icon icon-pick', order=900)
|
||||
|
|
@ -374,7 +374,7 @@
|
|||
|
||||
{% include "wagtailadmin/shared/header.html" with title=title_trans %}
|
||||
|
||||
{% include "wagtailadmin/shared/header.html" with title=title_trans add_link="wagtailimages_add_image" icon="image" add_text="button" search_url="wagtailimages_index" %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=title_trans add_link="wagtailimages_add_image" icon="image" add_text="button" search_url="wagtailimages:index" %}
|
||||
</section>
|
||||
|
||||
<section id="forms">
|
||||
|
|
|
|||
|
|
@ -23,33 +23,33 @@ BASE_DIR = os.path.dirname(PROJECT_DIR)
|
|||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = (
|
||||
INSTALLED_APPS = [
|
||||
'home',
|
||||
'search',
|
||||
|
||||
'wagtail.wagtailforms',
|
||||
'wagtail.wagtailredirects',
|
||||
'wagtail.wagtailembeds',
|
||||
'wagtail.wagtailsites',
|
||||
'wagtail.wagtailusers',
|
||||
'wagtail.wagtailsnippets',
|
||||
'wagtail.wagtaildocs',
|
||||
'wagtail.wagtailimages',
|
||||
'wagtail.wagtailsearch',
|
||||
'wagtail.wagtailadmin',
|
||||
'wagtail.wagtailcore',
|
||||
|
||||
'modelcluster',
|
||||
'compressor',
|
||||
'taggit',
|
||||
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
|
||||
'taggit',
|
||||
'compressor',
|
||||
'modelcluster',
|
||||
|
||||
'wagtail.wagtailcore',
|
||||
'wagtail.wagtailadmin',
|
||||
'wagtail.wagtailsearch',
|
||||
'wagtail.wagtailimages',
|
||||
'wagtail.wagtaildocs',
|
||||
'wagtail.wagtailsnippets',
|
||||
'wagtail.wagtailusers',
|
||||
'wagtail.wagtailsites',
|
||||
'wagtail.wagtailembeds',
|
||||
'wagtail.wagtailredirects',
|
||||
'wagtail.wagtailforms',
|
||||
|
||||
'search',
|
||||
'home',
|
||||
)
|
||||
]
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
Django>=1.8,<1.9
|
||||
wagtail==1.0rc1
|
||||
wagtail==1.0
|
||||
|
|
|
|||
|
|
@ -78,42 +78,43 @@ MIDDLEWARE_CLASSES = (
|
|||
)
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.admin',
|
||||
# Install wagtailredirects with its appconfig
|
||||
# Theres nothing special about wagtailredirects, we just need to have one
|
||||
# app which uses AppConfigs to test that hooks load properly
|
||||
'wagtail.wagtailredirects.apps.WagtailRedirectsAppConfig',
|
||||
|
||||
'taggit',
|
||||
'compressor',
|
||||
|
||||
'wagtail.wagtailcore',
|
||||
'wagtail.wagtailadmin',
|
||||
'wagtail.wagtaildocs',
|
||||
'wagtail.wagtailsnippets',
|
||||
'wagtail.wagtailusers',
|
||||
'wagtail.wagtailsites',
|
||||
'wagtail.wagtailimages',
|
||||
'wagtail.wagtailembeds',
|
||||
'wagtail.wagtailsearch',
|
||||
'wagtail.wagtailforms',
|
||||
'wagtail.contrib.wagtailstyleguide',
|
||||
'wagtail.contrib.wagtailsitemaps',
|
||||
'wagtail.contrib.wagtailroutablepage',
|
||||
'wagtail.contrib.wagtailfrontendcache',
|
||||
'wagtail.contrib.wagtailapi',
|
||||
'wagtail.tests.testapp',
|
||||
'wagtail.tests.demosite',
|
||||
'wagtail.tests.customuser',
|
||||
'wagtail.tests.snippets',
|
||||
'wagtail.tests.routablepage',
|
||||
'wagtail.tests.search',
|
||||
'wagtail.contrib.wagtailstyleguide',
|
||||
'wagtail.contrib.wagtailsitemaps',
|
||||
'wagtail.contrib.wagtailroutablepage',
|
||||
'wagtail.contrib.wagtailfrontendcache',
|
||||
'wagtail.contrib.wagtailapi',
|
||||
'wagtail.contrib.wagtailsearchpromotions',
|
||||
'wagtail.wagtailforms',
|
||||
'wagtail.wagtailsearch',
|
||||
'wagtail.wagtailembeds',
|
||||
'wagtail.wagtailimages',
|
||||
'wagtail.wagtailsites',
|
||||
'wagtail.wagtailusers',
|
||||
'wagtail.wagtailsnippets',
|
||||
'wagtail.wagtaildocs',
|
||||
'wagtail.wagtailadmin',
|
||||
'wagtail.wagtailcore',
|
||||
|
||||
# Install wagtailredirects with its appconfig
|
||||
# Theres nothing special about wagtailredirects, we just need to have one
|
||||
# app which uses AppConfigs to test that hooks load properly
|
||||
'wagtail.wagtailredirects.apps.WagtailRedirectsAppConfig',
|
||||
'taggit',
|
||||
'compressor',
|
||||
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
24
wagtail/tests/testapp/migrations/0006_image_file_size.py
Normal file
24
wagtail/tests/testapp/migrations/0006_image_file_size.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tests', '0005_streampage'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='customimagewithadminformfields',
|
||||
name='file_size',
|
||||
field=models.PositiveIntegerField(null=True, editable=False),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='customimagewithoutadminformfields',
|
||||
name='file_size',
|
||||
field=models.PositiveIntegerField(null=True, editable=False),
|
||||
),
|
||||
]
|
||||
|
|
@ -335,7 +335,7 @@ function initCollapsibleBlocks() {
|
|||
$fieldset.hide();
|
||||
}
|
||||
|
||||
$li.find('h2').click(function() {
|
||||
$li.find('> h2').click(function() {
|
||||
if (!$li.hasClass('collapsed')) {
|
||||
$li.addClass('collapsed');
|
||||
$fieldset.hide('slow');
|
||||
|
|
|
|||
|
|
@ -293,33 +293,18 @@
|
|||
min-height: 41px;
|
||||
|
||||
h2{
|
||||
cursor: pointer;
|
||||
}
|
||||
h2:before{
|
||||
content: '6';
|
||||
text-shadow:none;
|
||||
line-height: 40px;
|
||||
padding-right: 1px;
|
||||
opacity: 1;
|
||||
color: #666;
|
||||
background-color: transparent;
|
||||
@include transition(background-color 0.2s ease, color 0.2s ease);
|
||||
}
|
||||
h2:hover:before{
|
||||
&:before, label:before{
|
||||
content: '6';
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&.collapsed{
|
||||
background: #fff;
|
||||
h2{
|
||||
@include box-shadow(none);
|
||||
}
|
||||
h2:before{
|
||||
content: '5';
|
||||
color: #fff;
|
||||
background-color:$color-teal;
|
||||
}
|
||||
h2:hover:before{
|
||||
background-color:$color-teal-darker;
|
||||
&:before, label:before{
|
||||
content: '5';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<span>{% trans "Dashboard" %}</span>
|
||||
</a>
|
||||
|
||||
<form class="nav-search" action="{% url 'wagtailadmin_pages_search' %}" method="get">
|
||||
<form class="nav-search" action="{% url 'wagtailadmin_pages:search' %}" method="get">
|
||||
<div>
|
||||
<label for="menu-search-q">{% trans "Search" %}</label>
|
||||
<input type="text" id="menu-search-q" name="q" placeholder="{% trans 'Search' %}" />
|
||||
|
|
|
|||
|
|
@ -21,26 +21,26 @@
|
|||
<tr>
|
||||
<td class="title" valign="top">
|
||||
<h2>
|
||||
<a href="{% url 'wagtailadmin_pages_edit' revision.page.id %}" title="{% trans 'Edit this page' %}">{{ revision.page.title }}</a>
|
||||
<a href="{% url 'wagtailadmin_pages:edit' revision.page.id %}" title="{% trans 'Edit this page' %}">{{ revision.page.title }}</a>
|
||||
|
||||
{% include "wagtailadmin/pages/listing/_privacy_indicator.html" with page=revision.page %}
|
||||
{% include "wagtailadmin/pages/listing/_locked_indicator.html" with page=revision.page %}
|
||||
</h2>
|
||||
<ul class="actions">
|
||||
<li>
|
||||
<form action="{% url 'wagtailadmin_pages_approve_moderation' revision.id %}" method="POST">
|
||||
<form action="{% url 'wagtailadmin_pages:approve_moderation' revision.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="button button-small button-secondary" value="{% trans 'Approve' %}">
|
||||
</form>
|
||||
</li>
|
||||
<li class="no-border">
|
||||
<form action="{% url 'wagtailadmin_pages_reject_moderation' revision.id %}" method="POST">
|
||||
<form action="{% url 'wagtailadmin_pages:reject_moderation' revision.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="button button-small button-secondary no" value="{% trans 'Reject' %}">
|
||||
</form>
|
||||
</li>
|
||||
<li><a href="{% url 'wagtailadmin_pages_edit' revision.page.id %}" class="button button-small button-secondary">{% trans 'Edit' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages_preview_for_moderation' revision.id %}" class="button button-small button-secondary">{% trans 'Preview' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:edit' revision.page.id %}" class="button button-small button-secondary">{% trans 'Edit' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:preview_for_moderation' revision.id %}" class="button button-small button-secondary">{% trans 'Preview' %}</a></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td valign="top">
|
||||
|
|
|
|||
|
|
@ -19,15 +19,15 @@
|
|||
<tr>
|
||||
<td class="title" valign="top">
|
||||
<h2>
|
||||
<a href="{% url 'wagtailadmin_pages_edit' revision.page.id %}" title="{% trans 'Edit this page' %}">{{ revision.page.title }}</a>
|
||||
<a href="{% url 'wagtailadmin_pages:edit' revision.page.id %}" title="{% trans 'Edit this page' %}">{{ revision.page.title }}</a>
|
||||
|
||||
{% include "wagtailadmin/pages/listing/_privacy_indicator.html" with page=revision.page %}
|
||||
{% include "wagtailadmin/pages/listing/_locked_indicator.html" with page=revision.page %}
|
||||
</h2>
|
||||
<ul class="actions">
|
||||
<li><a href="{% url 'wagtailadmin_pages_edit' revision.page.id %}" class="button button-small button-secondary">{% trans "Edit" %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:edit' revision.page.id %}" class="button button-small button-secondary">{% trans "Edit" %}</a></li>
|
||||
{% if revision.page.has_unpublished_changes %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_view_draft' revision.page.id %}" class="button button-small button-secondary">{% trans 'Draft' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:view_draft' revision.page.id %}" class="button button-small button-secondary">{% trans 'Draft' %}</a></li>
|
||||
{% endif %}
|
||||
{% if revision.page.live %}
|
||||
<li><a href="{{ revision.page.url }}" class="button button-small button-secondary">{% trans 'Live' %}</a></li>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'wagtailadmin/notifications/base_notification.html' %}{% block notification %}{% load i18n %}{% blocktrans with title=revision.page.title|safe %}The page "{{ title }}" has been rejected{% endblocktrans %}
|
||||
{% blocktrans with title=revision.page.title|safe %}The page "{{ title }}" has been rejected.{% endblocktrans %}
|
||||
|
||||
{% trans "You can edit the page here:"%} {{ settings.BASE_URL }}{% url 'wagtailadmin_pages_edit' revision.page.id %}{% endblock %}
|
||||
{% trans "You can edit the page here:"%} {{ settings.BASE_URL }}{% url 'wagtailadmin_pages:edit' revision.page.id %}{% endblock %}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{% extends 'wagtailadmin/notifications/base_notification.html' %}{% block notification %}{% load i18n %}{% blocktrans with page=revision.page|safe %}The page "{{ page }}" has been submitted for moderation{% endblocktrans %}
|
||||
{% blocktrans with page=revision.page|safe %}The page "{{ page }}" has been submitted for moderation.{% endblocktrans %}
|
||||
|
||||
{% trans "You can preview the page here:" %} {{ settings.BASE_URL }}{% url 'wagtailadmin_pages_preview_for_moderation' revision.id %}
|
||||
{% trans "You can edit the page here:" %} {{ settings.BASE_URL }}{% url 'wagtailadmin_pages_edit' revision.page.id %}{% endblock %}
|
||||
{% trans "You can preview the page here:" %} {{ settings.BASE_URL }}{% url 'wagtailadmin_pages:preview_for_moderation' revision.id %}
|
||||
{% trans "You can edit the page here:" %} {{ settings.BASE_URL }}{% url 'wagtailadmin_pages:edit' revision.page.id %}{% endblock %}
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@
|
|||
|
||||
<div class="nice-padding">
|
||||
<p>{% trans "This page has been made private by a parent page." %}</p>
|
||||
<p>{% trans "You can edit the privacy settings on:" %} <a href="{% url 'wagtailadmin_pages_edit' page_with_restriction.id %}">{{ page_with_restriction.title }}</a>
|
||||
<p>{% trans "You can edit the privacy settings on:" %} <a href="{% url 'wagtailadmin_pages:edit' page_with_restriction.id %}">{{ page_with_restriction.title }}</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<div class="nice-padding">
|
||||
<p class="help-block help-warning">{% trans "Privacy changes apply to all children of this page too." %}</p>
|
||||
<form action="{% url 'wagtailadmin_pages_set_privacy' page.id %}" method="POST">
|
||||
<form action="{% url 'wagtailadmin_pages:set_privacy' page.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<ul class="fields">
|
||||
{% include "wagtailadmin/shared/field_as_li.html" with field=form.restriction_type %}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@
|
|||
|
||||
{% if page.locked %}
|
||||
{% if page_perms.can_lock %}
|
||||
<form action="{% url 'wagtailadmin_pages_unlock' page.id %}" method="POST" class="status-tag primary">
|
||||
<form action="{% url 'wagtailadmin_pages:unlock' page.id %}" method="POST" class="status-tag primary">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{% url 'wagtailadmin_pages_edit' page.id %}">
|
||||
<input type="hidden" name="next" value="{% url 'wagtailadmin_pages:edit' page.id %}">
|
||||
<input type="submit" class="unbutton" value="{% trans "Locked" %}">
|
||||
</form>
|
||||
{% else %}
|
||||
|
|
@ -19,9 +19,9 @@
|
|||
{% endif %}
|
||||
{% else %}
|
||||
{% if page_perms.can_lock %}
|
||||
<form action="{% url 'wagtailadmin_pages_lock' page.id %}" method="POST" class="status-tag secondary">
|
||||
<form action="{% url 'wagtailadmin_pages:lock' page.id %}" method="POST" class="status-tag secondary">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{% url 'wagtailadmin_pages_edit' page.id %}">
|
||||
<input type="hidden" name="next" value="{% url 'wagtailadmin_pages:edit' page.id %}">
|
||||
<input type="submit" class="unbutton" value="{% trans "Unlocked" %}">
|
||||
</form>
|
||||
{% else %}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<button class="action-preview {% if icon %}icon icon-view{% endif %}"
|
||||
data-action="{% url 'wagtailadmin_pages_preview_on_create' content_type.app_label content_type.model parent_page.id %}{% if mode %}?mode={{ mode|urlencode }}{% endif %}"
|
||||
data-placeholder="{% url 'wagtailadmin_pages_preview' %}"
|
||||
data-action="{% url 'wagtailadmin_pages:preview_on_add' content_type.app_label content_type.model parent_page.id %}{% if mode %}?mode={{ mode|urlencode }}{% endif %}"
|
||||
data-placeholder="{% url 'wagtailadmin_pages:preview' %}"
|
||||
data-windowname="wagtail_preview_{{ parent_page.id }}_child">{{ label }}</button>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<button class="action-preview {% if icon %}icon icon-view{% endif %}"
|
||||
data-action="{% url 'wagtailadmin_pages_preview_on_edit' page.id %}{% if mode %}?mode={{ mode|urlencode }}{% endif %}"
|
||||
data-placeholder="{% url 'wagtailadmin_pages_preview' %}"
|
||||
data-action="{% url 'wagtailadmin_pages:preview_on_edit' page.id %}{% if mode %}?mode={{ mode|urlencode }}{% endif %}"
|
||||
data-placeholder="{% url 'wagtailadmin_pages:preview' %}"
|
||||
data-windowname="wagtail_preview_{{ page.id }}">{{ label }}</button>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<div class="privacy-indicator {% if is_public %}public{% else %}private{% endif %}">
|
||||
{% trans "Privacy" %}
|
||||
{% if page_perms.can_set_view_restrictions %}
|
||||
<a href="{% url 'wagtailadmin_pages_set_privacy' page.id %}" class="status-tag primary action-set-privacy">
|
||||
<a href="{% url 'wagtailadmin_pages:set_privacy' page.id %}" class="status-tag primary action-set-privacy">
|
||||
{# labels are shown/hidden in CSS according to the 'private' / 'public' class on view-permission-indicator #}
|
||||
<span class="label-public icon icon-view">{% trans 'Public' %}</span>
|
||||
<span class="label-private icon icon-no-view">{% trans 'Private' %}</span>
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@
|
|||
<li>
|
||||
<div class="row row-flush">
|
||||
<div class="col6">
|
||||
<a href="{% url 'wagtailadmin_pages_create' content_type.app_label content_type.model parent_page.id %}" class="icon icon-plus-inverse icon-larger">{{ content_type.model_class.get_verbose_name }}</a>
|
||||
<a href="{% url 'wagtailadmin_pages:add' content_type.app_label content_type.model parent_page.id %}" class="icon icon-plus-inverse icon-larger">{{ content_type.model_class.get_verbose_name }}</a>
|
||||
</div>
|
||||
|
||||
<small class="col6" style="text-align:right">
|
||||
{{ content_type|meta_description }}
|
||||
<a href="{% url 'wagtailadmin_pages_type_use' content_type.app_label content_type.model %}" class="nolink">{% blocktrans with page_type=content_type.model_class.get_verbose_name %}Pages using {{ page_type }}{% endblocktrans %}</a>
|
||||
<a href="{% url 'wagtailadmin_pages:type_use' content_type.app_label content_type.model %}" class="nolink">{% blocktrans with page_type=content_type.model_class.get_verbose_name %}Pages using {{ page_type }}{% endblocktrans %}</a>
|
||||
</small>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
{% if page.live %}
|
||||
<p>{% trans "Alternatively you can unpublish the page. This removes the page from public view and you can edit or publish it again later." %}</p>
|
||||
{% endif %}
|
||||
<form action="{% url 'wagtailadmin_pages_delete' page.id %}" method="POST">
|
||||
<form action="{% url 'wagtailadmin_pages:delete' page.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="submit" value="{% trans 'Delete it' %}" class="serious {% if page.live %}button-secondary{% endif %}"> {% if page.live %}<a href="{% url 'wagtailadmin_pages_unpublish' page.id %}" class="button">{% trans 'Unpublish it' %}</a>{% endif %}
|
||||
<input type="submit" value="{% trans 'Delete it' %}" class="serious {% if page.live %}button-secondary{% endif %}"> {% if page.live %}<a href="{% url 'wagtailadmin_pages:unpublish' page.id %}" class="button">{% trans 'Unpublish it' %}</a>{% endif %}
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
<p>{% blocktrans with title=destination.title %}Are you sure you want to move this page and all of its children into '{{ title }}'?{% endblocktrans %}</p>
|
||||
{% endif %}
|
||||
|
||||
<form action="{% url 'wagtailadmin_pages_move_confirm' page_to_move.id destination.id %}" method="POST">
|
||||
<form action="{% url 'wagtailadmin_pages:move_confirm' page_to_move.id destination.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="submit" value="{% trans 'Yes, move this page' %}">
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<div class="nice-padding">
|
||||
<p>{% trans "Are you sure you want to unpublish this page?" %}</p>
|
||||
<form action="{% url 'wagtailadmin_pages_unpublish' page.id %}" method="POST">
|
||||
<form action="{% url 'wagtailadmin_pages:unpublish' page.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="submit" value="{% trans 'Yes, unpublish it' %}">
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
{% include "wagtailadmin/shared/header.html" with title=copy_str subtitle=page.title icon="doc-empty-inverse" %}
|
||||
|
||||
<div class="nice-padding">
|
||||
<form action="{% url 'wagtailadmin_pages_copy' page.id %}" method="POST">
|
||||
<form action="{% url 'wagtailadmin_pages:copy' page.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
|
||||
<ul class="fields">
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
</div>
|
||||
</header>
|
||||
|
||||
<form id="page-edit-form" action="{% url 'wagtailadmin_pages_create' content_type.app_label content_type.model parent_page.id %}" method="POST">
|
||||
<form id="page-edit-form" action="{% url 'wagtailadmin_pages:add' content_type.app_label content_type.model parent_page.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
{{ edit_handler.render_form_content }}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
</div>
|
||||
</header>
|
||||
|
||||
<form id="page-edit-form" action="{% url 'wagtailadmin_pages_edit' page.id %}" method="POST">
|
||||
<form id="page-edit-form" action="{% url 'wagtailadmin_pages:edit' page.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
{{ edit_handler.render_form_content }}
|
||||
|
||||
|
|
@ -38,10 +38,10 @@
|
|||
<div class="dropdown-toggle icon icon-arrow-up"></div>
|
||||
<ul role="menu">
|
||||
{% if page_perms.can_unpublish %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_unpublish' page.id %}">{% trans 'Unpublish' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:unpublish' page.id %}">{% trans 'Unpublish' %}</a></li>
|
||||
{% endif %}
|
||||
{% if page_perms.can_delete %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_delete' page.id %}" class="shortcut">{% trans 'Delete' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:delete' page.id %}" class="shortcut">{% trans 'Delete' %}</a></li>
|
||||
{% endif %}
|
||||
{% if page_perms.can_publish %}
|
||||
<li><input type="submit" name="action-publish" value="{% trans 'Publish' %}" class="button" /></li>
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
// Build url
|
||||
// TODO: Find better way to inject movedPageId
|
||||
var url = "{% url 'wagtailadmin_pages_set_page_position' '999999' %}".replace('999999', movedPageId);
|
||||
var url = "{% url 'wagtailadmin_pages:set_page_position' '999999' %}".replace('999999', movedPageId);
|
||||
if (newPosition != null) {
|
||||
url += '?position=' + newPosition;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,6 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block no_results %}
|
||||
{% url 'wagtailadmin_pages_add_subpage' parent_page.id as add_page_url%}
|
||||
{% url 'wagtailadmin_pages:add_subpage' parent_page.id as add_page_url%}
|
||||
<tr><td colspan="3" class="no-results-message"><p>{% trans "No pages have been created at this location." %}{% if parent_page and parent_page_perms.can_add_subpage %} {% blocktrans %}Why not <a href="{{ add_page_url }}">create one</a>?{% endblocktrans %}{% endif %}</td></tr>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ Navigation controls for the page listing in 'explore' mode
|
|||
{% if page.is_navigable %}
|
||||
<a href="{% url 'wagtailadmin_explore' page.id %}" class="icon text-replace icon-arrow-right" title="{% blocktrans with title=page.title %}Explore child pages of '{{ title }}'{% endblocktrans %}">{% trans "Explore" %}</a>
|
||||
{% elif page_perms.can_add_subpage %}
|
||||
<a href="{% url 'wagtailadmin_pages_add_subpage' page.id %}" class="icon text-replace icon-plus-inverse" title="{% blocktrans with title=page.title %}Add a child page to '{{ title }}'{% endblocktrans %}">{% trans 'Add subpage' %}</a>
|
||||
<a href="{% url 'wagtailadmin_pages:add_subpage' page.id %}" class="icon text-replace icon-plus-inverse" title="{% blocktrans with title=page.title %}Add a child page to '{{ title }}'{% endblocktrans %}">{% trans 'Add subpage' %}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,6 @@ Navigation controls for the page listing in 'move' mode
|
|||
|
||||
<td class="{% if page.can_descend %}children{% endif %}">
|
||||
{% if page.can_descend %}
|
||||
<a href="{% url 'wagtailadmin_pages_move_choose_destination' page_to_move.id page.id %}" class="icon text-replace icon-arrow-right navigate-pages" title="{% blocktrans with title=page.title %}Explore subpages of '{{ title }}'{% endblocktrans %}">{% trans 'Explore' %}</a>
|
||||
<a href="{% url 'wagtailadmin_pages:move_choose_destination' page_to_move.id page.id %}" class="icon text-replace icon-arrow-right navigate-pages" title="{% blocktrans with title=page.title %}Explore subpages of '{{ title }}'{% endblocktrans %}">{% trans 'Explore' %}</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ Expects a variable 'page', the page instance.
|
|||
|
||||
<h2>
|
||||
{% if page.can_choose %}
|
||||
<a class="choose-page" href="#{{ page.id }}" data-id="{{ page.id }}" data-title="{{ page.title }}" data-url="{{ page.url }}" data-edit-url="{% url 'wagtailadmin_pages_edit' page.id %}">{{ page.title }}</a>
|
||||
<a class="choose-page" href="#{{ page.id }}" data-id="{{ page.id }}" data-title="{{ page.title }}" data-url="{{ page.url }}" data-edit-url="{% url 'wagtailadmin_pages:edit' page.id %}">{{ page.title }}</a>
|
||||
{% else %}
|
||||
{{ page.title }}
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<h2>
|
||||
{% if page_perms.can_edit and 'edit' not in hide_actions|default:'' %}
|
||||
<a href="{% url 'wagtailadmin_pages_edit' page.id %}" title="{% trans 'Edit this page' %}">{{ page.title }}</a>
|
||||
<a href="{% url 'wagtailadmin_pages:edit' page.id %}" title="{% trans 'Edit this page' %}">{{ page.title }}</a>
|
||||
{% else %}
|
||||
{{ page.title }}
|
||||
{% endif %}
|
||||
|
|
@ -15,27 +15,27 @@
|
|||
|
||||
<ul class="actions">
|
||||
{% if page_perms.can_edit and 'edit' not in hide_actions|default:'' %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_edit' page.id %}" class="button button-small button-secondary" title="{% trans 'Edit this page' %}">{% trans 'Edit' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:edit' page.id %}" class="button button-small button-secondary" title="{% trans 'Edit this page' %}">{% trans 'Edit' %}</a></li>
|
||||
{% endif %}
|
||||
{% if page.has_unpublished_changes and 'view_draft' not in hide_actions|default:'' %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_view_draft' page.id %}" class="button button-small button-secondary" target="_blank">{% trans 'Draft' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:view_draft' page.id %}" class="button button-small button-secondary" target="_blank">{% trans 'Draft' %}</a></li>
|
||||
{% endif %}
|
||||
{% if page.live and 'view_live' not in hide_actions|default:'' %}
|
||||
<li><a {% if page.url %}href="{{ page.url }}"{% endif %} class="button button-small button-secondary {% if not page.url %}disabled{% endif %}" target="_blank" {% if not page.url %}title="{% trans 'This page is published but does not exist within a configured Site, so cannot be viewed.' %}"{% endif %}>{% trans 'Live' %}</a></li>
|
||||
{% endif %}
|
||||
{% if page_perms.can_move and 'move' not in hide_actions|default:'' %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_move' page.id %}" class="button button-small button-secondary">{% trans 'Move' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:move' page.id %}" class="button button-small button-secondary">{% trans 'Move' %}</a></li>
|
||||
{% endif %}
|
||||
{% if parent_page_perms.can_add_subpage and 'copy' not in hide_actions|default:'' %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_copy' page.id %}" class="button button-small button-secondary">{% trans 'Copy' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:copy' page.id %}" class="button button-small button-secondary">{% trans 'Copy' %}</a></li>
|
||||
{% endif %}
|
||||
{% if page_perms.can_delete and 'delete' not in hide_actions|default:'' %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_delete' page.id %}" class="button button-small button-secondary">{% trans 'Delete' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:delete' page.id %}" class="button button-small button-secondary">{% trans 'Delete' %}</a></li>
|
||||
{% endif %}
|
||||
{% if page_perms.can_unpublish and 'unpublish' not in hide_actions|default:'' %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_unpublish' page.id %}" class="button button-small button-secondary">{% trans 'Unpublish' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:unpublish' page.id %}" class="button button-small button-secondary">{% trans 'Unpublish' %}</a></li>
|
||||
{% endif %}
|
||||
{% if page_perms.can_add_subpage and 'add_subpage' not in hide_actions|default:'' %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_add_subpage' page.id %}" class="button button-small button-secondary">{% trans 'Add child page' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:add_subpage' page.id %}" class="button button-small button-secondary">{% trans 'Add child page' %}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
|
@ -6,7 +6,7 @@ Expects a variable 'page', the page instance.
|
|||
|
||||
<h2>
|
||||
{% if page.can_choose %}
|
||||
<a href="{% url 'wagtailadmin_pages_move_confirm' page_to_move.id page.id %}">{{ page.title }}</a>
|
||||
<a href="{% url 'wagtailadmin_pages:move_confirm' page_to_move.id page.id %}">{{ page.title }}</a>
|
||||
{% else %}
|
||||
{{ page.title }}
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
<h2>
|
||||
{% if parent_page_perms.can_edit and 'edit' not in hide_actions|default:'' %}
|
||||
<a href="{% url 'wagtailadmin_pages_edit' parent_page.id %}">{{ parent_page.title }}</a>
|
||||
<a href="{% url 'wagtailadmin_pages:edit' parent_page.id %}">{{ parent_page.title }}</a>
|
||||
{% else %}
|
||||
{{ parent_page.title }}
|
||||
{% endif %}
|
||||
|
|
@ -17,25 +17,25 @@
|
|||
|
||||
<ul class="actions">
|
||||
{% if parent_page_perms.can_edit and 'edit' not in hide_actions|default:'' %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_edit' parent_page.id %}" class="button button-small button-secondary">{% trans 'Edit' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:edit' parent_page.id %}" class="button button-small button-secondary">{% trans 'Edit' %}</a></li>
|
||||
{% endif %}
|
||||
{% if parent_page.has_unpublished_changes and 'view_draft' not in hide_actions|default:'' %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_view_draft' parent_page.id %}" class="button button-small button-secondary" target="_blank">{% trans 'Draft' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:view_draft' parent_page.id %}" class="button button-small button-secondary" target="_blank">{% trans 'Draft' %}</a></li>
|
||||
{% endif %}
|
||||
|
||||
{% if parent_page.live and not parent_page.is_root and 'view_live' not in hide_actions|default:'' %}
|
||||
<li><a {% if parent_page.url %}href="{{ parent_page.url }}"{% endif %} class="button button-small button-secondary {% if not parent_page.url %}disabled{% endif %}" target="_blank" {% if not parent_page.url %}title="{% trans 'This page is published but does not exist within a configured Site, so cannot be viewed.' %}"{% endif %}>{% trans 'Live' %}</a></li>
|
||||
{% endif %}
|
||||
{% if parent_page_perms.can_move and 'move' not in hide_actions|default:'' %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_move' parent_page.id %}" class="button button-small button-secondary">{% trans 'Move' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:move' parent_page.id %}" class="button button-small button-secondary">{% trans 'Move' %}</a></li>
|
||||
{% endif %}
|
||||
{% if parent_page_perms.can_delete and 'delete' not in hide_actions|default:'' %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_delete' parent_page.id %}" class="button button-small button-secondary">{% trans 'Delete' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:delete' parent_page.id %}" class="button button-small button-secondary">{% trans 'Delete' %}</a></li>
|
||||
{% endif %}
|
||||
{% if parent_page_perms.can_unpublish and 'unpublish' not in hide_actions|default:'' %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_unpublish' parent_page.id %}" class="button button-small button-secondary">{% trans 'Unpublish' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:unpublish' parent_page.id %}" class="button button-small button-secondary">{% trans 'Unpublish' %}</a></li>
|
||||
{% endif %}
|
||||
{% if parent_page_perms.can_add_subpage and 'add_subpage' not in hide_actions|default:'' %}
|
||||
<li><a href="{% url 'wagtailadmin_pages_add_subpage' parent_page.id %}" class="button button-small bicolor icon white icon-plus">{% trans 'Add child page' %}</a></li>
|
||||
<li><a href="{% url 'wagtailadmin_pages:add_subpage' parent_page.id %}" class="button button-small bicolor icon white icon-plus">{% trans 'Add child page' %}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
|
@ -11,6 +11,6 @@
|
|||
<div id="loading-spinner-wrapper">
|
||||
<div id="loading-spinner"></div>
|
||||
</div>
|
||||
<iframe id="preview-frame" src="{% url 'wagtailadmin_pages_preview_loading' %}"></iframe>
|
||||
<iframe id="preview-frame" src="{% url 'wagtailadmin_pages:preview_loading' %}"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
{% block extra_js %}
|
||||
<script>
|
||||
window.headerSearch = {
|
||||
url: "{% url 'wagtailadmin_pages_search' %}",
|
||||
url: "{% url 'wagtailadmin_pages:search' %}",
|
||||
termInput: "#id_q",
|
||||
targetOutput: "#page-results"
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
{% block content %}
|
||||
{% trans "Search" as search_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=search_str search_url="wagtailadmin_pages_search" icon="search" %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=search_str search_url="wagtailadmin_pages:search" icon="search" %}
|
||||
|
||||
<div id="page-results">
|
||||
{% include "wagtailadmin/pages/search_results.html" %}
|
||||
|
|
|
|||
|
|
@ -12,15 +12,15 @@
|
|||
<nav class="listing-filter">
|
||||
<h3 class="filter-title">{% trans "Other searches" %}</h3>
|
||||
<ul class="filter-options">
|
||||
<li><a href="{% url 'wagtailimages_index' %}?q={{ query_string|urlencode }}" class="icon icon-image">{% trans "Images" %}</a></li>
|
||||
<li><a href="{% url 'wagtaildocs_index' %}?q={{ query_string|urlencode }}" class="icon icon-doc-full-inverse">{% trans "Documents" %}</a></li>
|
||||
<li><a href="{% url 'wagtailusers_users_index' %}?q={{ query_string|urlencode }}" class="icon icon-user">{% trans "Users" %}</a></li>
|
||||
<li><a href="{% url 'wagtailimages:index' %}?q={{ query_string|urlencode }}" class="icon icon-image">{% trans "Images" %}</a></li>
|
||||
<li><a href="{% url 'wagtaildocs:index' %}?q={{ query_string|urlencode }}" class="icon icon-doc-full-inverse">{% trans "Documents" %}</a></li>
|
||||
<li><a href="{% url 'wagtailusers_users:index' %}?q={{ query_string|urlencode }}" class="icon icon-user">{% trans "Users" %}</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
{% include "wagtailadmin/pages/listing/_list_explore.html" with show_parent=1 allow_navigation=0 %}
|
||||
|
||||
{% url 'wagtailadmin_pages_search' as pagination_base_url %}
|
||||
{% url 'wagtailadmin_pages:search' as pagination_base_url %}
|
||||
{% include "wagtailadmin/pages/listing/_pagination.html" with page=pages base_url=pagination_base_url query_params=pagination_query_params only %}
|
||||
{% else %}
|
||||
{% if query_string %}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
{% if pages %}
|
||||
{% include "wagtailadmin/pages/listing/_list_explore.html" with show_parent=1 allow_navigation=0 %}
|
||||
|
||||
{% url 'wagtailadmin_pages_type_use' app_name content_type.model as pagination_base_url %}
|
||||
{% url 'wagtailadmin_pages:type_use' app_name content_type.model as pagination_base_url %}
|
||||
{% include "wagtailadmin/pages/listing/_pagination.html" with page=pages base_url=pagination_base_url only %}
|
||||
{% else %}
|
||||
<p>{% trans 'No pages use' %}<em>"{{ page_class.get_verbose_name }}"</em>.</p>
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block item_content %}
|
||||
<a href="{% url 'wagtailadmin_pages_add_subpage' self.page.id %}" target="_parent" class="action icon icon-plus" title="{% trans 'Add a child page' %}">{% trans 'Add' %}</a>
|
||||
<a href="{% url 'wagtailadmin_pages:add_subpage' self.page.id %}" target="_parent" class="action icon icon-plus" title="{% trans 'Add a child page' %}">{% trans 'Add' %}</a>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block item_content %}
|
||||
<form action="{% url 'wagtailadmin_pages_approve_moderation' self.revision.id %}" target="_parent" method="post">
|
||||
<form action="{% url 'wagtailadmin_pages:approve_moderation' self.revision.id %}" target="_parent" method="post">
|
||||
{% csrf_token %}
|
||||
<div class="action icon icon-tick">
|
||||
<input type="submit" value="{% trans 'Approve' %}" />
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block item_content %}
|
||||
<a href="{% url 'wagtailadmin_pages_edit' self.page.id %}" target="_parent" class="action icon icon-edit">{% trans 'Edit' %}</a>
|
||||
<a href="{% url 'wagtailadmin_pages:edit' self.page.id %}" target="_parent" class="action icon icon-edit">{% trans 'Edit' %}</a>
|
||||
{% endblock %}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block item_content %}
|
||||
<form action="{% url 'wagtailadmin_pages_reject_moderation' self.revision.id %}" target="_parent" method="post">
|
||||
<form action="{% url 'wagtailadmin_pages:reject_moderation' self.revision.id %}" target="_parent" method="post">
|
||||
{% csrf_token %}
|
||||
<div class="action icon icon-cross">
|
||||
<input type="submit" value="{% trans 'Reject' %}" />
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@
|
|||
<span class="title">{{ page.title }}</span>
|
||||
{% endblock %}
|
||||
|
||||
{% block edit_chosen_item_url %}{% if page %}{% url 'wagtailadmin_pages_edit' page.id %}{% endif %}{% endblock %}
|
||||
{% block edit_chosen_item_url %}{% if page %}{% url 'wagtailadmin_pages:edit' page.id %}{% endif %}{% endblock %}
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
self.user = self.login()
|
||||
|
||||
def test_add_subpage(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_add_subpage', args=(self.root_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add_subpage', args=(self.root_page.id, )))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_add_subpage_bad_permissions(self):
|
||||
|
|
@ -147,17 +147,17 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
self.user.save()
|
||||
|
||||
# Get add subpage page
|
||||
response = self.client.get(reverse('wagtailadmin_pages_add_subpage', args=(self.root_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add_subpage', args=(self.root_page.id, )))
|
||||
|
||||
# Check that the user recieved a 403 response
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_add_subpage_nonexistantparent(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_add_subpage', args=(100000, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add_subpage', args=(100000, )))
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_create_simplepage(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.root_page.id)))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.root_page.id)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, '<a href="#content" class="active">Content</a>')
|
||||
self.assertContains(response, '<a href="#promote" class="">Promote</a>')
|
||||
|
|
@ -166,7 +166,7 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
"""
|
||||
Test that the Promote tab is not rendered for page classes that define it as empty
|
||||
"""
|
||||
response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'standardindex', self.root_page.id)))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add', args=('tests', 'standardindex', self.root_page.id)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, '<a href="#content" class="active">Content</a>')
|
||||
self.assertNotContains(response, '<a href="#promote" class="">Promote</a>')
|
||||
|
|
@ -175,7 +175,7 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
"""
|
||||
Test that custom edit handlers are rendered
|
||||
"""
|
||||
response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'standardchild', self.root_page.id)))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add', args=('tests', 'standardchild', self.root_page.id)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, '<a href="#content" class="active">Content</a>')
|
||||
self.assertContains(response, '<a href="#promote" class="">Promote</a>')
|
||||
|
|
@ -190,7 +190,7 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
self.user.save()
|
||||
|
||||
# Get page
|
||||
response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.root_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.root_page.id, )))
|
||||
|
||||
# Check that the user recieved a 403 response
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
|
@ -201,13 +201,13 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
'content': "Some content",
|
||||
'slug': 'hello-world',
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
|
||||
# Find the page and check it
|
||||
page = Page.objects.get(path__startswith=self.root_page.path, slug='hello-world').specific
|
||||
|
||||
# Should be redirected to edit page
|
||||
self.assertRedirects(response, reverse('wagtailadmin_pages_edit', args=(page.id, )))
|
||||
self.assertRedirects(response, reverse('wagtailadmin_pages:edit', args=(page.id, )))
|
||||
|
||||
self.assertEqual(page.title, post_data['title'])
|
||||
self.assertIsInstance(page, SimplePage)
|
||||
|
|
@ -227,7 +227,7 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
'go_live_at': submittable_timestamp(go_live_at),
|
||||
'expire_at': submittable_timestamp(expire_at),
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
|
||||
# Should be redirected to explorer page
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
|
@ -250,7 +250,7 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
'go_live_at': submittable_timestamp(timezone.now() + timedelta(days=2)),
|
||||
'expire_at': submittable_timestamp(timezone.now() + timedelta(days=1)),
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
|
@ -265,7 +265,7 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
'slug': 'hello-world',
|
||||
'expire_at': submittable_timestamp(timezone.now() + timedelta(days=-1)),
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
|
@ -284,7 +284,7 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
'slug': 'hello-world',
|
||||
'action-publish': "Publish",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
|
||||
# Find the page and check it
|
||||
page = Page.objects.get(path__startswith=self.root_page.path, slug='hello-world').specific
|
||||
|
|
@ -319,7 +319,7 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
'go_live_at': submittable_timestamp(go_live_at),
|
||||
'expire_at': submittable_timestamp(expire_at),
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
|
||||
# Should be redirected to explorer page
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
|
@ -348,7 +348,7 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
'slug': 'hello-world',
|
||||
'action-submit': "Submit",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
|
||||
# Find the page and check it
|
||||
page = Page.objects.get(path__startswith=self.root_page.path, slug='hello-world').specific
|
||||
|
|
@ -385,7 +385,7 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
'slug': 'hello-world',
|
||||
'action-publish': "Publish",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
|
||||
# Should not be redirected (as the save should fail)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -394,11 +394,11 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
self.assertFormError(response, 'form', 'slug', "This slug is already in use")
|
||||
|
||||
def test_create_nonexistantparent(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', 100000)))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', 100000)))
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_create_nonpagetype(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_create', args=('wagtailimages', 'image', self.root_page.id)))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add', args=('wagtailimages', 'image', self.root_page.id)))
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_preview_on_create(self):
|
||||
|
|
@ -408,7 +408,7 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
'slug': 'hello-world',
|
||||
'action-submit': "Submit",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_preview_on_create', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:preview_on_add', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
|
||||
# Check the response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -428,7 +428,7 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
'action-submit': "Submit",
|
||||
'seo_title': '\t',
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
|
||||
# Check that a form error was raised
|
||||
self.assertFormError(response, 'form', 'title', "Value cannot be entirely whitespace characters")
|
||||
|
|
@ -444,7 +444,7 @@ class TestPageCreation(TestCase, WagtailTestUtils):
|
|||
'hello-world-hello-world-hello-world-hello-world-hello-world-hello-world',
|
||||
'action-submit': "Submit",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.root_page.id)), post_data)
|
||||
|
||||
# Check that a form error was raised
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -476,7 +476,7 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
|
||||
def test_page_edit(self):
|
||||
# Tests that the edit page loads
|
||||
response = self.client.get(reverse('wagtailadmin_pages_edit', args=(self.event_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.event_page.id, )))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_page_edit_bad_permissions(self):
|
||||
|
|
@ -488,7 +488,7 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
self.user.save()
|
||||
|
||||
# Get edit page
|
||||
response = self.client.get(reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )))
|
||||
|
||||
# Check that the user recieved a 403 response
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
|
@ -500,10 +500,10 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
'content': "Some content",
|
||||
'slug': 'hello-world',
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data)
|
||||
|
||||
# Should be redirected to edit page
|
||||
self.assertRedirects(response, reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )))
|
||||
self.assertRedirects(response, reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )))
|
||||
|
||||
# The page should have "has_unpublished_changes" flag set
|
||||
child_page_new = SimplePage.objects.get(id=self.child_page.id)
|
||||
|
|
@ -522,7 +522,7 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
'content': "Some content",
|
||||
'slug': 'hello-world',
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data)
|
||||
|
||||
# Shouldn't be redirected
|
||||
self.assertContains(response, "The page could not be saved as it is locked")
|
||||
|
|
@ -543,7 +543,7 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
'go_live_at': submittable_timestamp(go_live_at),
|
||||
'expire_at': submittable_timestamp(expire_at),
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data)
|
||||
|
||||
# Should be redirected to explorer page
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
|
@ -568,7 +568,7 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
'go_live_at': submittable_timestamp(timezone.now() + timedelta(days=2)),
|
||||
'expire_at': submittable_timestamp(timezone.now() + timedelta(days=1)),
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
|
@ -583,7 +583,7 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
'slug': 'hello-world',
|
||||
'expire_at': submittable_timestamp(timezone.now() + timedelta(days=-1)),
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
|
@ -610,7 +610,7 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
'slug': 'hello-world',
|
||||
'action-publish': "Publish",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data)
|
||||
|
||||
# Should be redirected to explorer
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -644,7 +644,7 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
'go_live_at': submittable_timestamp(go_live_at),
|
||||
'expire_at': submittable_timestamp(expire_at),
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data)
|
||||
|
||||
# Should be redirected to explorer page
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
|
@ -672,7 +672,7 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
'go_live_at': submittable_timestamp(go_live_at),
|
||||
'expire_at': submittable_timestamp(expire_at),
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data)
|
||||
|
||||
# Should be redirected to edit page
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
|
@ -694,7 +694,7 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
'action-publish': "Publish",
|
||||
'go_live_at': "",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data)
|
||||
|
||||
# Should be redirected to edit page
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
|
@ -718,7 +718,7 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
'slug': 'hello-world',
|
||||
'action-submit': "Submit",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data)
|
||||
|
||||
# Should be redirected to explorer
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -750,7 +750,7 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
'slug': 'hello-world',
|
||||
'action-submit': "Submit",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data)
|
||||
|
||||
# Should not be redirected (as the save should fail)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -765,7 +765,7 @@ class TestPageEdit(TestCase, WagtailTestUtils):
|
|||
'slug': 'hello-world',
|
||||
'action-submit': "Submit",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_preview_on_edit', args=(self.child_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:preview_on_edit', args=(self.child_page.id, )), post_data)
|
||||
|
||||
# Check the response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -798,7 +798,7 @@ class TestPageEditReordering(TestCase, WagtailTestUtils):
|
|||
self.assertEqual(order, expected_order)
|
||||
|
||||
def test_order(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_edit', args=(self.event_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.event_page.id, )))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.check_order(response, ['1234567', '7654321', 'abcdefg'])
|
||||
|
|
@ -834,13 +834,13 @@ class TestPageEditReordering(TestCase, WagtailTestUtils):
|
|||
'carousel_items-2-caption': self.event_page.carousel_items.all()[2].caption,
|
||||
'carousel_items-2-ORDER': 1,
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.event_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.event_page.id, )), post_data)
|
||||
|
||||
# Should be redirected back to same page
|
||||
self.assertRedirects(response, reverse('wagtailadmin_pages_edit', args=(self.event_page.id, )))
|
||||
self.assertRedirects(response, reverse('wagtailadmin_pages:edit', args=(self.event_page.id, )))
|
||||
|
||||
# Check order
|
||||
response = self.client.get(reverse('wagtailadmin_pages_edit', args=(self.event_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.event_page.id, )))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.check_order(response, ['abcdefg', '1234567', '7654321'])
|
||||
|
|
@ -876,7 +876,7 @@ class TestPageEditReordering(TestCase, WagtailTestUtils):
|
|||
'carousel_items-2-caption': self.event_page.carousel_items.all()[2].caption,
|
||||
'carousel_items-2-ORDER': 1,
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.event_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.event_page.id, )), post_data)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.check_order(response, ['abcdefg', '1234567', '7654321'])
|
||||
|
|
@ -903,7 +903,7 @@ class TestPageDelete(TestCase, WagtailTestUtils):
|
|||
self.user = self.login()
|
||||
|
||||
def test_page_delete(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_delete', args=(self.child_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:delete', args=(self.child_page.id, )))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# deletion should not actually happen on GET
|
||||
self.assertTrue(SimplePage.objects.filter(id=self.child_page.id).exists())
|
||||
|
|
@ -917,7 +917,7 @@ class TestPageDelete(TestCase, WagtailTestUtils):
|
|||
self.user.save()
|
||||
|
||||
# Get delete page
|
||||
response = self.client.get(reverse('wagtailadmin_pages_delete', args=(self.child_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:delete', args=(self.child_page.id, )))
|
||||
|
||||
# Check that the user recieved a 403 response
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
|
@ -931,7 +931,7 @@ class TestPageDelete(TestCase, WagtailTestUtils):
|
|||
page_unpublished.connect(mock_handler)
|
||||
|
||||
# Post
|
||||
response = self.client.post(reverse('wagtailadmin_pages_delete', args=(self.child_page.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:delete', args=(self.child_page.id, )))
|
||||
|
||||
# Should be redirected to explorer page
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -963,7 +963,7 @@ class TestPageDelete(TestCase, WagtailTestUtils):
|
|||
page_unpublished.connect(mock_handler)
|
||||
|
||||
# Post
|
||||
response = self.client.post(reverse('wagtailadmin_pages_delete', args=(self.child_page.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:delete', args=(self.child_page.id, )))
|
||||
|
||||
# Should be redirected to explorer page
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -997,7 +997,7 @@ class TestPageDelete(TestCase, WagtailTestUtils):
|
|||
post_delete.connect(post_delete_handler)
|
||||
|
||||
# Post
|
||||
response = self.client.post(reverse('wagtailadmin_pages_delete', args=(self.child_index.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:delete', args=(self.child_index.id, )))
|
||||
|
||||
# Should be redirected to explorer page
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -1030,7 +1030,7 @@ class TestPageSearch(TestCase, WagtailTestUtils):
|
|||
self.login()
|
||||
|
||||
def get(self, params=None, **extra):
|
||||
return self.client.get(reverse('wagtailadmin_pages_search'), params or {}, **extra)
|
||||
return self.client.get(reverse('wagtailadmin_pages:search'), params or {}, **extra)
|
||||
|
||||
def test_view(self):
|
||||
response = self.get()
|
||||
|
|
@ -1091,7 +1091,7 @@ class TestPageMove(TestCase, WagtailTestUtils):
|
|||
self.user = self.login()
|
||||
|
||||
def test_page_move(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_move', args=(self.test_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:move', args=(self.test_page.id, )))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_page_move_bad_permissions(self):
|
||||
|
|
@ -1103,17 +1103,17 @@ class TestPageMove(TestCase, WagtailTestUtils):
|
|||
self.user.save()
|
||||
|
||||
# Get move page
|
||||
response = self.client.get(reverse('wagtailadmin_pages_move', args=(self.test_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:move', args=(self.test_page.id, )))
|
||||
|
||||
# Check that the user recieved a 403 response
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_page_move_confirm(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_move_confirm', args=(self.test_page.id, self.section_b.id)))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:move_confirm', args=(self.test_page.id, self.section_b.id)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_page_set_page_position(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_set_page_position', args=(self.test_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:set_page_position', args=(self.test_page.id, )))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
|
|
@ -1149,7 +1149,7 @@ class TestPageCopy(TestCase, WagtailTestUtils):
|
|||
self.user = self.login()
|
||||
|
||||
def test_page_copy(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_copy', args=(self.test_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:copy', args=(self.test_page.id, )))
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -1177,7 +1177,7 @@ class TestPageCopy(TestCase, WagtailTestUtils):
|
|||
'new_parent_page': str(self.test_page.id),
|
||||
'copy_subpages': False,
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_copy', args=(self.test_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:copy', args=(self.test_page.id, )), post_data)
|
||||
|
||||
# Check that the user received a 403 response
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
|
@ -1190,7 +1190,7 @@ class TestPageCopy(TestCase, WagtailTestUtils):
|
|||
'copy_subpages': False,
|
||||
'publish_copies': False,
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_copy', args=(self.test_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:copy', args=(self.test_page.id, )), post_data)
|
||||
|
||||
# Check that the user was redirected to the parents explore page
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -1222,7 +1222,7 @@ class TestPageCopy(TestCase, WagtailTestUtils):
|
|||
'copy_subpages': True,
|
||||
'publish_copies': False,
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_copy', args=(self.test_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:copy', args=(self.test_page.id, )), post_data)
|
||||
|
||||
# Check that the user was redirected to the parents explore page
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -1266,7 +1266,7 @@ class TestPageCopy(TestCase, WagtailTestUtils):
|
|||
'copy_subpages': True,
|
||||
'publish_copies': True,
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_copy', args=(self.test_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:copy', args=(self.test_page.id, )), post_data)
|
||||
|
||||
# Check that the user was redirected to the parents explore page
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -1310,7 +1310,7 @@ class TestPageCopy(TestCase, WagtailTestUtils):
|
|||
'copy_subpages': False,
|
||||
'publish_copies': False,
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_copy', args=(self.test_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:copy', args=(self.test_page.id, )), post_data)
|
||||
|
||||
# Check that the user was redirected to the new parents explore page
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.test_child_page.id, )))
|
||||
|
|
@ -1331,7 +1331,7 @@ class TestPageCopy(TestCase, WagtailTestUtils):
|
|||
'new_parent_page': str(self.root_page.id),
|
||||
'copy_subpages': False,
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_copy', args=(self.test_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:copy', args=(self.test_page.id, )), post_data)
|
||||
|
||||
# Should not be redirected (as the save should fail)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -1349,7 +1349,7 @@ class TestPageCopy(TestCase, WagtailTestUtils):
|
|||
'new_parent_page': str(self.test_child_page.id),
|
||||
'copy_subpages': False,
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_copy', args=(self.test_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:copy', args=(self.test_page.id, )), post_data)
|
||||
|
||||
# Check that the user was redirected to the parents explore page
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.test_child_page.id, )))
|
||||
|
|
@ -1362,7 +1362,7 @@ class TestPageCopy(TestCase, WagtailTestUtils):
|
|||
'new_parent_page': str(self.root_page.id),
|
||||
'copy_subpages': False,
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_copy', args=(self.test_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:copy', args=(self.test_page.id, )), post_data)
|
||||
|
||||
# Should not be redirected (as the save should fail)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -1379,7 +1379,7 @@ class TestPageCopy(TestCase, WagtailTestUtils):
|
|||
self.user.save()
|
||||
|
||||
# Get copy page
|
||||
response = self.client.get(reverse('wagtailadmin_pages_copy', args=(self.test_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:copy', args=(self.test_page.id, )))
|
||||
|
||||
# The user should have access to the copy page
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -1406,7 +1406,7 @@ class TestPageCopy(TestCase, WagtailTestUtils):
|
|||
'copy_subpages': True,
|
||||
'publish_copies': True,
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_copy', args=(self.test_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:copy', args=(self.test_page.id, )), post_data)
|
||||
|
||||
# Check that the user was redirected to the parents explore page
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -1458,7 +1458,7 @@ class TestPageUnpublish(TestCase, WagtailTestUtils):
|
|||
This tests that the unpublish view responds with an unpublish confirm page
|
||||
"""
|
||||
# Get unpublish page
|
||||
response = self.client.get(reverse('wagtailadmin_pages_unpublish', args=(self.page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:unpublish', args=(self.page.id, )))
|
||||
|
||||
# Check that the user recieved an unpublish confirm page
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -1469,7 +1469,7 @@ class TestPageUnpublish(TestCase, WagtailTestUtils):
|
|||
This tests that the unpublish view returns an error if the page id is invalid
|
||||
"""
|
||||
# Get unpublish page
|
||||
response = self.client.get(reverse('wagtailadmin_pages_unpublish', args=(12345, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:unpublish', args=(12345, )))
|
||||
|
||||
# Check that the user recieved a 404 response
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
|
@ -1486,7 +1486,7 @@ class TestPageUnpublish(TestCase, WagtailTestUtils):
|
|||
self.user.save()
|
||||
|
||||
# Get unpublish page
|
||||
response = self.client.get(reverse('wagtailadmin_pages_unpublish', args=(self.page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:unpublish', args=(self.page.id, )))
|
||||
|
||||
# Check that the user recieved a 403 response
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
|
@ -1500,7 +1500,7 @@ class TestPageUnpublish(TestCase, WagtailTestUtils):
|
|||
page_unpublished.connect(mock_handler)
|
||||
|
||||
# Post to the unpublish page
|
||||
response = self.client.post(reverse('wagtailadmin_pages_unpublish', args=(self.page.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:unpublish', args=(self.page.id, )))
|
||||
|
||||
# Should be redirected to explorer page
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -1549,7 +1549,7 @@ class TestApproveRejectModeration(TestCase, WagtailTestUtils):
|
|||
page_published.connect(mock_handler)
|
||||
|
||||
# Post
|
||||
response = self.client.post(reverse('wagtailadmin_pages_approve_moderation', args=(self.revision.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:approve_moderation', args=(self.revision.id, )))
|
||||
|
||||
# Check that the user was redirected to the dashboard
|
||||
self.assertRedirects(response, reverse('wagtailadmin_home'))
|
||||
|
|
@ -1572,7 +1572,7 @@ class TestApproveRejectModeration(TestCase, WagtailTestUtils):
|
|||
self.page.title = "Goodbye world!"
|
||||
self.page.save_revision(user=self.submitter, submitted_for_moderation=False)
|
||||
|
||||
response = self.client.post(reverse('wagtailadmin_pages_approve_moderation', args=(self.revision.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:approve_moderation', args=(self.revision.id, )))
|
||||
|
||||
# Check that the user was redirected to the dashboard
|
||||
self.assertRedirects(response, reverse('wagtailadmin_home'))
|
||||
|
|
@ -1590,7 +1590,7 @@ class TestApproveRejectModeration(TestCase, WagtailTestUtils):
|
|||
This tests that the approve moderation view handles invalid revision ids correctly
|
||||
"""
|
||||
# Post
|
||||
response = self.client.post(reverse('wagtailadmin_pages_approve_moderation', args=(12345, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:approve_moderation', args=(12345, )))
|
||||
|
||||
# Check that the user recieved a 404 response
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
|
@ -1607,7 +1607,7 @@ class TestApproveRejectModeration(TestCase, WagtailTestUtils):
|
|||
self.user.save()
|
||||
|
||||
# Post
|
||||
response = self.client.post(reverse('wagtailadmin_pages_approve_moderation', args=(self.revision.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:approve_moderation', args=(self.revision.id, )))
|
||||
|
||||
# Check that the user recieved a 403 response
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
|
@ -1617,7 +1617,7 @@ class TestApproveRejectModeration(TestCase, WagtailTestUtils):
|
|||
This posts to the reject moderation view and checks that the page was rejected
|
||||
"""
|
||||
# Post
|
||||
response = self.client.post(reverse('wagtailadmin_pages_reject_moderation', args=(self.revision.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:reject_moderation', args=(self.revision.id, )))
|
||||
|
||||
# Check that the user was redirected to the dashboard
|
||||
self.assertRedirects(response, reverse('wagtailadmin_home'))
|
||||
|
|
@ -1633,7 +1633,7 @@ class TestApproveRejectModeration(TestCase, WagtailTestUtils):
|
|||
This tests that the reject moderation view handles invalid revision ids correctly
|
||||
"""
|
||||
# Post
|
||||
response = self.client.post(reverse('wagtailadmin_pages_reject_moderation', args=(12345, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:reject_moderation', args=(12345, )))
|
||||
|
||||
# Check that the user recieved a 404 response
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
|
@ -1650,13 +1650,13 @@ class TestApproveRejectModeration(TestCase, WagtailTestUtils):
|
|||
self.user.save()
|
||||
|
||||
# Post
|
||||
response = self.client.post(reverse('wagtailadmin_pages_reject_moderation', args=(self.revision.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:reject_moderation', args=(self.revision.id, )))
|
||||
|
||||
# Check that the user recieved a 403 response
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_preview_for_moderation(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_preview_for_moderation', args=(self.revision.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:preview_for_moderation', args=(self.revision.id, )))
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -1672,7 +1672,7 @@ class TestContentTypeUse(TestCase, WagtailTestUtils):
|
|||
|
||||
def test_content_type_use(self):
|
||||
# Get use of event page
|
||||
response = self.client.get(reverse('wagtailadmin_pages_type_use', args=('tests', 'eventpage')))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:type_use', args=('tests', 'eventpage')))
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -1713,7 +1713,7 @@ class TestSubpageBusinessRules(TestCase, WagtailTestUtils):
|
|||
self.login()
|
||||
|
||||
def test_standard_subpage(self):
|
||||
add_subpage_url = reverse('wagtailadmin_pages_add_subpage', args=(self.standard_index.id, ))
|
||||
add_subpage_url = reverse('wagtailadmin_pages:add_subpage', args=(self.standard_index.id, ))
|
||||
|
||||
# explorer should contain a link to 'add child page'
|
||||
response = self.client.get(reverse('wagtailadmin_explore', args=(self.standard_index.id, )))
|
||||
|
|
@ -1730,7 +1730,7 @@ class TestSubpageBusinessRules(TestCase, WagtailTestUtils):
|
|||
self.assertNotContains(response, BusinessChild.get_verbose_name())
|
||||
|
||||
def test_business_subpage(self):
|
||||
add_subpage_url = reverse('wagtailadmin_pages_add_subpage', args=(self.business_index.id, ))
|
||||
add_subpage_url = reverse('wagtailadmin_pages:add_subpage', args=(self.business_index.id, ))
|
||||
|
||||
# explorer should contain a link to 'add child page'
|
||||
response = self.client.get(reverse('wagtailadmin_explore', args=(self.business_index.id, )))
|
||||
|
|
@ -1746,7 +1746,7 @@ class TestSubpageBusinessRules(TestCase, WagtailTestUtils):
|
|||
self.assertContains(response, BusinessChild.get_verbose_name())
|
||||
|
||||
def test_business_child_subpage(self):
|
||||
add_subpage_url = reverse('wagtailadmin_pages_add_subpage', args=(self.business_child.id, ))
|
||||
add_subpage_url = reverse('wagtailadmin_pages:add_subpage', args=(self.business_child.id, ))
|
||||
|
||||
# explorer should not contain a link to 'add child page', as this page doesn't accept subpages
|
||||
response = self.client.get(reverse('wagtailadmin_explore', args=(self.business_child.id, )))
|
||||
|
|
@ -1754,30 +1754,30 @@ class TestSubpageBusinessRules(TestCase, WagtailTestUtils):
|
|||
self.assertNotContains(response, add_subpage_url)
|
||||
|
||||
# this also means that fetching add_subpage is blocked at the permission-check level
|
||||
response = self.client.get(reverse('wagtailadmin_pages_add_subpage', args=(self.business_child.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add_subpage', args=(self.business_child.id, )))
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_cannot_add_invalid_subpage_type(self):
|
||||
# cannot add StandardChild as a child of BusinessIndex, as StandardChild is not present in subpage_types
|
||||
response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'standardchild', self.business_index.id)))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add', args=('tests', 'standardchild', self.business_index.id)))
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
# likewise for BusinessChild which has an empty subpage_types list
|
||||
response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'standardchild', self.business_child.id)))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add', args=('tests', 'standardchild', self.business_child.id)))
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
# cannot add BusinessChild to StandardIndex, as BusinessChild restricts is parent page types
|
||||
response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'businesschild', self.standard_index.id)))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add', args=('tests', 'businesschild', self.standard_index.id)))
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
# but we can add a BusinessChild to BusinessIndex
|
||||
response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'businesschild', self.business_index.id)))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add', args=('tests', 'businesschild', self.business_index.id)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_not_prompted_for_page_type_when_only_one_choice(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_add_subpage', args=(self.business_subindex.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add_subpage', args=(self.business_subindex.id, )))
|
||||
# BusinessChild is the only valid subpage type of BusinessSubIndex, so redirect straight there
|
||||
self.assertRedirects(response, reverse('wagtailadmin_pages_create', args=('tests', 'businesschild', self.business_subindex.id)))
|
||||
self.assertRedirects(response, reverse('wagtailadmin_pages:add', args=('tests', 'businesschild', self.business_subindex.id)))
|
||||
|
||||
|
||||
class TestNotificationPreferences(TestCase, WagtailTestUtils):
|
||||
|
|
@ -1817,7 +1817,7 @@ class TestNotificationPreferences(TestCase, WagtailTestUtils):
|
|||
}
|
||||
|
||||
def submit(self):
|
||||
return self.client.post(reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )), self.post_data)
|
||||
return self.client.post(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), self.post_data)
|
||||
|
||||
def silent_submit(self):
|
||||
"""
|
||||
|
|
@ -1827,10 +1827,10 @@ class TestNotificationPreferences(TestCase, WagtailTestUtils):
|
|||
self.revision = self.child_page.get_latest_revision()
|
||||
|
||||
def approve(self):
|
||||
return self.client.post(reverse('wagtailadmin_pages_approve_moderation', args=(self.revision.id, )))
|
||||
return self.client.post(reverse('wagtailadmin_pages:approve_moderation', args=(self.revision.id, )))
|
||||
|
||||
def reject(self):
|
||||
return self.client.post(reverse('wagtailadmin_pages_reject_moderation', args=(self.revision.id, )))
|
||||
return self.client.post(reverse('wagtailadmin_pages:reject_moderation', args=(self.revision.id, )))
|
||||
|
||||
def test_vanilla_profile(self):
|
||||
# Check that the vanilla profile has rejected notifications on
|
||||
|
|
@ -1927,7 +1927,7 @@ class TestLocking(TestCase, WagtailTestUtils):
|
|||
self.root_page.add_child(instance=self.child_page)
|
||||
|
||||
def test_lock_post(self):
|
||||
response = self.client.post(reverse('wagtailadmin_pages_lock', args=(self.child_page.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:lock', args=(self.child_page.id, )))
|
||||
|
||||
# Check response
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -1936,7 +1936,7 @@ class TestLocking(TestCase, WagtailTestUtils):
|
|||
self.assertTrue(Page.objects.get(id=self.child_page.id).locked)
|
||||
|
||||
def test_lock_get(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_lock', args=(self.child_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:lock', args=(self.child_page.id, )))
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 405)
|
||||
|
|
@ -1949,7 +1949,7 @@ class TestLocking(TestCase, WagtailTestUtils):
|
|||
self.child_page.locked = True
|
||||
self.child_page.save()
|
||||
|
||||
response = self.client.post(reverse('wagtailadmin_pages_lock', args=(self.child_page.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:lock', args=(self.child_page.id, )))
|
||||
|
||||
# Check response
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -1958,18 +1958,18 @@ class TestLocking(TestCase, WagtailTestUtils):
|
|||
self.assertTrue(Page.objects.get(id=self.child_page.id).locked)
|
||||
|
||||
def test_lock_post_with_good_redirect(self):
|
||||
response = self.client.post(reverse('wagtailadmin_pages_lock', args=(self.child_page.id, )), {
|
||||
'next': reverse('wagtailadmin_pages_edit', args=(self.child_page.id, ))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:lock', args=(self.child_page.id, )), {
|
||||
'next': reverse('wagtailadmin_pages:edit', args=(self.child_page.id, ))
|
||||
})
|
||||
|
||||
# Check response
|
||||
self.assertRedirects(response, reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )))
|
||||
self.assertRedirects(response, reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )))
|
||||
|
||||
# Check that the page is locked
|
||||
self.assertTrue(Page.objects.get(id=self.child_page.id).locked)
|
||||
|
||||
def test_lock_post_with_bad_redirect(self):
|
||||
response = self.client.post(reverse('wagtailadmin_pages_lock', args=(self.child_page.id, )), {
|
||||
response = self.client.post(reverse('wagtailadmin_pages:lock', args=(self.child_page.id, )), {
|
||||
'next': 'http://www.google.co.uk'
|
||||
})
|
||||
|
||||
|
|
@ -1980,7 +1980,7 @@ class TestLocking(TestCase, WagtailTestUtils):
|
|||
self.assertTrue(Page.objects.get(id=self.child_page.id).locked)
|
||||
|
||||
def test_lock_post_bad_page(self):
|
||||
response = self.client.post(reverse('wagtailadmin_pages_lock', args=(9999, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:lock', args=(9999, )))
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
|
@ -1996,7 +1996,7 @@ class TestLocking(TestCase, WagtailTestUtils):
|
|||
)
|
||||
self.user.save()
|
||||
|
||||
response = self.client.post(reverse('wagtailadmin_pages_lock', args=(self.child_page.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:lock', args=(self.child_page.id, )))
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
|
@ -2009,7 +2009,7 @@ class TestLocking(TestCase, WagtailTestUtils):
|
|||
self.child_page.locked = True
|
||||
self.child_page.save()
|
||||
|
||||
response = self.client.post(reverse('wagtailadmin_pages_unlock', args=(self.child_page.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:unlock', args=(self.child_page.id, )))
|
||||
|
||||
# Check response
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -2022,7 +2022,7 @@ class TestLocking(TestCase, WagtailTestUtils):
|
|||
self.child_page.locked = True
|
||||
self.child_page.save()
|
||||
|
||||
response = self.client.get(reverse('wagtailadmin_pages_unlock', args=(self.child_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:unlock', args=(self.child_page.id, )))
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 405)
|
||||
|
|
@ -2031,7 +2031,7 @@ class TestLocking(TestCase, WagtailTestUtils):
|
|||
self.assertTrue(Page.objects.get(id=self.child_page.id).locked)
|
||||
|
||||
def test_unlock_post_already_unlocked(self):
|
||||
response = self.client.post(reverse('wagtailadmin_pages_unlock', args=(self.child_page.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:unlock', args=(self.child_page.id, )))
|
||||
|
||||
# Check response
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -2044,12 +2044,12 @@ class TestLocking(TestCase, WagtailTestUtils):
|
|||
self.child_page.locked = True
|
||||
self.child_page.save()
|
||||
|
||||
response = self.client.post(reverse('wagtailadmin_pages_unlock', args=(self.child_page.id, )), {
|
||||
'next': reverse('wagtailadmin_pages_edit', args=(self.child_page.id, ))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:unlock', args=(self.child_page.id, )), {
|
||||
'next': reverse('wagtailadmin_pages:edit', args=(self.child_page.id, ))
|
||||
})
|
||||
|
||||
# Check response
|
||||
self.assertRedirects(response, reverse('wagtailadmin_pages_edit', args=(self.child_page.id, )))
|
||||
self.assertRedirects(response, reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )))
|
||||
|
||||
# Check that the page is unlocked
|
||||
self.assertFalse(Page.objects.get(id=self.child_page.id).locked)
|
||||
|
|
@ -2059,7 +2059,7 @@ class TestLocking(TestCase, WagtailTestUtils):
|
|||
self.child_page.locked = True
|
||||
self.child_page.save()
|
||||
|
||||
response = self.client.post(reverse('wagtailadmin_pages_unlock', args=(self.child_page.id, )), {
|
||||
response = self.client.post(reverse('wagtailadmin_pages:unlock', args=(self.child_page.id, )), {
|
||||
'next': 'http://www.google.co.uk'
|
||||
})
|
||||
|
||||
|
|
@ -2074,7 +2074,7 @@ class TestLocking(TestCase, WagtailTestUtils):
|
|||
self.child_page.locked = True
|
||||
self.child_page.save()
|
||||
|
||||
response = self.client.post(reverse('wagtailadmin_pages_unlock', args=(9999, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:unlock', args=(9999, )))
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
|
@ -2094,7 +2094,7 @@ class TestLocking(TestCase, WagtailTestUtils):
|
|||
self.child_page.locked = True
|
||||
self.child_page.save()
|
||||
|
||||
response = self.client.post(reverse('wagtailadmin_pages_unlock', args=(self.child_page.id, )))
|
||||
response = self.client.post(reverse('wagtailadmin_pages:unlock', args=(self.child_page.id, )))
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
|
@ -2125,7 +2125,7 @@ class TestIssue197(TestCase, WagtailTestUtils):
|
|||
'tags': "hello, world",
|
||||
'action-publish': "Publish",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.tagged_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.tagged_page.id, )), post_data)
|
||||
|
||||
# Should be redirected to explorer
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
@ -2159,7 +2159,7 @@ class TestChildRelationsOnSuperclass(TestCase, WagtailTestUtils):
|
|||
self.login()
|
||||
|
||||
def test_get_create_form(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'standardindex', self.root_page.id)))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add', args=('tests', 'standardindex', self.root_page.id)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# Response should include an advert_placements formset labelled Adverts
|
||||
self.assertContains(response, "Adverts")
|
||||
|
|
@ -2176,19 +2176,19 @@ class TestChildRelationsOnSuperclass(TestCase, WagtailTestUtils):
|
|||
'advert_placements-0-colour': 'yellow',
|
||||
'advert_placements-0-id': '',
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_create', args=('tests', 'standardindex', self.root_page.id)), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:add', args=('tests', 'standardindex', self.root_page.id)), post_data)
|
||||
|
||||
# Find the page and check it
|
||||
page = Page.objects.get(path__startswith=self.root_page.path, slug='new-index').specific
|
||||
|
||||
# Should be redirected to edit page
|
||||
self.assertRedirects(response, reverse('wagtailadmin_pages_edit', args=(page.id, )))
|
||||
self.assertRedirects(response, reverse('wagtailadmin_pages:edit', args=(page.id, )))
|
||||
|
||||
self.assertEqual(page.advert_placements.count(), 1)
|
||||
self.assertEqual(page.advert_placements.first().advert.text, 'test_advert')
|
||||
|
||||
def test_get_edit_form(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_edit', args=(self.index_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.index_page.id, )))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Response should include an advert_placements formset labelled Adverts
|
||||
|
|
@ -2213,7 +2213,7 @@ class TestChildRelationsOnSuperclass(TestCase, WagtailTestUtils):
|
|||
'advert_placements-1-id': '',
|
||||
'action-publish': "Publish",
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_edit', args=(self.index_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.index_page.id, )), post_data)
|
||||
|
||||
# Should be redirected to explorer
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class TestSetPrivacyView(TestCase, WagtailTestUtils):
|
|||
"""
|
||||
This tests that a blank form is returned when a user opens the set_privacy view on a public page
|
||||
"""
|
||||
response = self.client.get(reverse('wagtailadmin_pages_set_privacy', args=(self.public_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:set_privacy', args=(self.public_page.id, )))
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -50,7 +50,7 @@ class TestSetPrivacyView(TestCase, WagtailTestUtils):
|
|||
"""
|
||||
This tests that the restriction type and password fields as set correctly when a user opens the set_privacy view on a public page
|
||||
"""
|
||||
response = self.client.get(reverse('wagtailadmin_pages_set_privacy', args=(self.private_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:set_privacy', args=(self.private_page.id, )))
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -65,7 +65,7 @@ class TestSetPrivacyView(TestCase, WagtailTestUtils):
|
|||
"""
|
||||
This tests that the set_privacy view tells the user that the password restriction has been applied to an ancestor
|
||||
"""
|
||||
response = self.client.get(reverse('wagtailadmin_pages_set_privacy', args=(self.private_child_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:set_privacy', args=(self.private_child_page.id, )))
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -80,7 +80,7 @@ class TestSetPrivacyView(TestCase, WagtailTestUtils):
|
|||
'restriction_type': 'password',
|
||||
'password': 'helloworld',
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_set_privacy', args=(self.public_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:set_privacy', args=(self.public_page.id, )), post_data)
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -100,7 +100,7 @@ class TestSetPrivacyView(TestCase, WagtailTestUtils):
|
|||
'restriction_type': 'password',
|
||||
'password': '',
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_set_privacy', args=(self.public_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:set_privacy', args=(self.public_page.id, )), post_data)
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -116,7 +116,7 @@ class TestSetPrivacyView(TestCase, WagtailTestUtils):
|
|||
'restriction_type': 'none',
|
||||
'password': '',
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_pages_set_privacy', args=(self.private_page.id, )), post_data)
|
||||
response = self.client.post(reverse('wagtailadmin_pages:set_privacy', args=(self.private_page.id, )), post_data)
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -222,7 +222,7 @@ class TestPrivacyIndicators(TestCase, WagtailTestUtils):
|
|||
"""
|
||||
This tests that the privacy indicator on the public pages edit view is set to "PUBLIC"
|
||||
"""
|
||||
response = self.client.get(reverse('wagtailadmin_pages_edit', args=(self.public_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.public_page.id, )))
|
||||
|
||||
# Check the response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -236,7 +236,7 @@ class TestPrivacyIndicators(TestCase, WagtailTestUtils):
|
|||
"""
|
||||
This tests that the privacy indicator on the private pages edit view is set to "PRIVATE"
|
||||
"""
|
||||
response = self.client.get(reverse('wagtailadmin_pages_edit', args=(self.private_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.private_page.id, )))
|
||||
|
||||
# Check the response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
@ -250,7 +250,7 @@ class TestPrivacyIndicators(TestCase, WagtailTestUtils):
|
|||
"""
|
||||
This tests that the privacy indicator on the private child pages edit view is set to "PRIVATE"
|
||||
"""
|
||||
response = self.client.get(reverse('wagtailadmin_pages_edit', args=(self.private_child_page.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.private_child_page.id, )))
|
||||
|
||||
# Check the response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ class TestUserbarAddLink(TestCase, WagtailTestUtils):
|
|||
response = self.client.get(reverse('wagtailadmin_userbar_frontend', args=(self.event_index.id, )))
|
||||
|
||||
# page allows subpages, so the 'add page' button should show
|
||||
expected_url = reverse('wagtailadmin_pages_add_subpage', args=(self.event_index.id, ))
|
||||
expected_url = reverse('wagtailadmin_pages:add_subpage', args=(self.event_index.id, ))
|
||||
expected_link = '<a href="%s" target="_parent" class="action icon icon-plus" title="Add a child page">Add</a>' % expected_url
|
||||
self.assertContains(response, expected_link)
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ class TestUserbarAddLink(TestCase, WagtailTestUtils):
|
|||
response = self.client.get(reverse('wagtailadmin_userbar_frontend', args=(self.business_child.id, )))
|
||||
|
||||
# page disallows subpages, so the 'add page' button shouldn't show
|
||||
expected_url = reverse('wagtailadmin_pages_add_subpage', args=(self.business_index.id, ))
|
||||
expected_url = reverse('wagtailadmin_pages:add_subpage', args=(self.business_index.id, ))
|
||||
expected_link = '<a href="%s" target="_parent" class="action icon icon-plus" title="Add a child page">Add</a>' % expected_url
|
||||
self.assertNotContains(response, expected_link)
|
||||
|
||||
|
|
|
|||
|
|
@ -44,13 +44,13 @@ class TestEditorHooks(TestCase, WagtailTestUtils):
|
|||
self.login()
|
||||
|
||||
def test_editor_css_and_js_hooks_on_add(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.homepage.id)))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:add', args=('tests', 'simplepage', self.homepage.id)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, '<link rel="stylesheet" href="/path/to/my/custom.css">')
|
||||
self.assertContains(response, '<script src="/path/to/my/custom.js"></script>')
|
||||
|
||||
def test_editor_css_and_js_hooks_on_edit(self):
|
||||
response = self.client.get(reverse('wagtailadmin_pages_edit', args=(self.homepage.id, )))
|
||||
response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.homepage.id, )))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, '<link rel="stylesheet" href="/path/to/my/custom.css">')
|
||||
self.assertContains(response, '<script src="/path/to/my/custom.js"></script>')
|
||||
|
|
|
|||
|
|
@ -1,127 +0,0 @@
|
|||
from django.conf.urls import url
|
||||
from django.contrib.auth.decorators import permission_required
|
||||
from django.contrib.auth import views as django_auth_views
|
||||
from django.views.decorators.cache import cache_control
|
||||
|
||||
from wagtail.wagtailadmin.forms import PasswordResetForm
|
||||
from wagtail.wagtailadmin.views import account, chooser, home, pages, tags, userbar, page_privacy
|
||||
from wagtail.wagtailcore import hooks
|
||||
from wagtail.utils.urlpatterns import decorate_urlpatterns
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', home.home, name='wagtailadmin_home'),
|
||||
|
||||
url(r'^failwhale/$', home.error_test, name='wagtailadmin_error_test'),
|
||||
|
||||
url(r'^explorer-nav/$', pages.explorer_nav, name='wagtailadmin_explorer_nav'),
|
||||
|
||||
url(r'^pages/$', pages.index, name='wagtailadmin_explore_root'),
|
||||
url(r'^pages/(\d+)/$', pages.index, name='wagtailadmin_explore'),
|
||||
|
||||
url(r'^pages/new/(\w+)/(\w+)/(\d+)/$', pages.create, name='wagtailadmin_pages_create'),
|
||||
url(r'^pages/new/(\w+)/(\w+)/(\d+)/preview/$', pages.preview_on_create, name='wagtailadmin_pages_preview_on_create'),
|
||||
url(r'^pages/usage/(\w+)/(\w+)/$', pages.content_type_use, name='wagtailadmin_pages_type_use'),
|
||||
|
||||
url(r'^pages/(\d+)/edit/$', pages.edit, name='wagtailadmin_pages_edit'),
|
||||
url(r'^pages/(\d+)/edit/preview/$', pages.preview_on_edit, name='wagtailadmin_pages_preview_on_edit'),
|
||||
|
||||
url(r'^pages/preview/$', pages.preview, name='wagtailadmin_pages_preview'),
|
||||
url(r'^pages/preview_loading/$', pages.preview_loading, name='wagtailadmin_pages_preview_loading'),
|
||||
|
||||
url(r'^pages/(\d+)/view_draft/$', pages.view_draft, name='wagtailadmin_pages_view_draft'),
|
||||
url(r'^pages/(\d+)/add_subpage/$', pages.add_subpage, name='wagtailadmin_pages_add_subpage'),
|
||||
url(r'^pages/(\d+)/delete/$', pages.delete, name='wagtailadmin_pages_delete'),
|
||||
url(r'^pages/(\d+)/unpublish/$', pages.unpublish, name='wagtailadmin_pages_unpublish'),
|
||||
|
||||
url(r'^pages/search/$', pages.search, name='wagtailadmin_pages_search'),
|
||||
|
||||
url(r'^pages/(\d+)/move/$', pages.move_choose_destination, name='wagtailadmin_pages_move'),
|
||||
url(r'^pages/(\d+)/move/(\d+)/$', pages.move_choose_destination, name='wagtailadmin_pages_move_choose_destination'),
|
||||
url(r'^pages/(\d+)/move/(\d+)/confirm/$', pages.move_confirm, name='wagtailadmin_pages_move_confirm'),
|
||||
url(r'^pages/(\d+)/set_position/$', pages.set_page_position, name='wagtailadmin_pages_set_page_position'),
|
||||
|
||||
url(r'^pages/(\d+)/copy/$', pages.copy, name='wagtailadmin_pages_copy'),
|
||||
|
||||
url(r'^pages/moderation/(\d+)/approve/$', pages.approve_moderation, name='wagtailadmin_pages_approve_moderation'),
|
||||
url(r'^pages/moderation/(\d+)/reject/$', pages.reject_moderation, name='wagtailadmin_pages_reject_moderation'),
|
||||
url(r'^pages/moderation/(\d+)/preview/$', pages.preview_for_moderation, name='wagtailadmin_pages_preview_for_moderation'),
|
||||
|
||||
url(r'^pages/(\d+)/privacy/$', page_privacy.set_privacy, name='wagtailadmin_pages_set_privacy'),
|
||||
|
||||
url(r'^pages/(\d+)/lock/$', pages.lock, name='wagtailadmin_pages_lock'),
|
||||
url(r'^pages/(\d+)/unlock/$', pages.unlock, name='wagtailadmin_pages_unlock'),
|
||||
|
||||
url(r'^choose-page/$', chooser.browse, name='wagtailadmin_choose_page'),
|
||||
url(r'^choose-page/(\d+)/$', chooser.browse, name='wagtailadmin_choose_page_child'),
|
||||
url(r'^choose-page/search/$', chooser.search, name='wagtailadmin_choose_page_search'),
|
||||
url(r'^choose-external-link/$', chooser.external_link, name='wagtailadmin_choose_page_external_link'),
|
||||
url(r'^choose-email-link/$', chooser.email_link, name='wagtailadmin_choose_page_email_link'),
|
||||
|
||||
url(r'^tag-autocomplete/$', tags.autocomplete, name='wagtailadmin_tag_autocomplete'),
|
||||
|
||||
url(r'^account/$', account.account, name='wagtailadmin_account'),
|
||||
url(r'^account/change_password/$', account.change_password, name='wagtailadmin_account_change_password'),
|
||||
url(r'^account/notification_preferences/$', account.notification_preferences, name='wagtailadmin_account_notification_preferences'),
|
||||
url(r'^logout/$', account.logout, name='wagtailadmin_logout'),
|
||||
]
|
||||
|
||||
|
||||
# Import additional urlpatterns from any apps that define a register_admin_urls hook
|
||||
for fn in hooks.get_hooks('register_admin_urls'):
|
||||
urls = fn()
|
||||
if urls:
|
||||
urlpatterns += urls
|
||||
|
||||
|
||||
# Add "wagtailadmin.access_admin" permission check
|
||||
urlpatterns = decorate_urlpatterns(urlpatterns,
|
||||
permission_required(
|
||||
'wagtailadmin.access_admin',
|
||||
login_url='wagtailadmin_login'
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# These url patterns do not require an authenticated admin user
|
||||
urlpatterns += [
|
||||
url(r'^login/$', account.login, name='wagtailadmin_login'),
|
||||
|
||||
# These two URLs have the "permission_required" decorator applied directly
|
||||
# as they need to fail with a 403 error rather than redirect to the login page
|
||||
url(r'^userbar/(\d+)/$', userbar.for_frontend, name='wagtailadmin_userbar_frontend'),
|
||||
url(r'^userbar/moderation/(\d+)/$', userbar.for_moderation, name='wagtailadmin_userbar_moderation'),
|
||||
|
||||
# Password reset
|
||||
url(
|
||||
r'^password_reset/$', django_auth_views.password_reset, {
|
||||
'template_name': 'wagtailadmin/account/password_reset/form.html',
|
||||
'email_template_name': 'wagtailadmin/account/password_reset/email.txt',
|
||||
'subject_template_name': 'wagtailadmin/account/password_reset/email_subject.txt',
|
||||
'password_reset_form': PasswordResetForm,
|
||||
'post_reset_redirect': 'wagtailadmin_password_reset_done',
|
||||
}, name='wagtailadmin_password_reset'
|
||||
),
|
||||
url(
|
||||
r'^password_reset/done/$', django_auth_views.password_reset_done, {
|
||||
'template_name': 'wagtailadmin/account/password_reset/done.html'
|
||||
}, name='wagtailadmin_password_reset_done'
|
||||
),
|
||||
url(
|
||||
r'^password_reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
|
||||
django_auth_views.password_reset_confirm, {
|
||||
'template_name': 'wagtailadmin/account/password_reset/confirm.html',
|
||||
'post_reset_redirect': 'wagtailadmin_password_reset_complete',
|
||||
}, name='wagtailadmin_password_reset_confirm',
|
||||
),
|
||||
url(
|
||||
r'^password_reset/complete/$', django_auth_views.password_reset_complete, {
|
||||
'template_name': 'wagtailadmin/account/password_reset/complete.html'
|
||||
}, name='wagtailadmin_password_reset_complete'
|
||||
),
|
||||
]
|
||||
|
||||
# Decorate all views with cache settings to prevent caching
|
||||
urlpatterns = decorate_urlpatterns(urlpatterns,
|
||||
cache_control(private=True, no_cache=True, no_store=True, max_age=0)
|
||||
)
|
||||
73
wagtail/wagtailadmin/urls/__init__.py
Normal file
73
wagtail/wagtailadmin/urls/__init__.py
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
from django.conf.urls import url, include
|
||||
from django.contrib.auth.decorators import permission_required
|
||||
from django.views.decorators.cache import cache_control
|
||||
|
||||
from wagtail.wagtailadmin.urls import pages as wagtailadmin_pages_urls
|
||||
from wagtail.wagtailadmin.urls import password_reset as wagtailadmin_password_reset_urls
|
||||
from wagtail.wagtailadmin.views import account, chooser, home, pages, tags, userbar
|
||||
from wagtail.wagtailcore import hooks
|
||||
from wagtail.utils.urlpatterns import decorate_urlpatterns
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', home.home, name='wagtailadmin_home'),
|
||||
|
||||
url(r'^failwhale/$', home.error_test, name='wagtailadmin_error_test'),
|
||||
|
||||
url(r'^explorer-nav/$', pages.explorer_nav, name='wagtailadmin_explorer_nav'),
|
||||
|
||||
# TODO: Move into wagtailadmin_pages namespace
|
||||
url(r'^pages/$', pages.index, name='wagtailadmin_explore_root'),
|
||||
url(r'^pages/(\d+)/$', pages.index, name='wagtailadmin_explore'),
|
||||
|
||||
url(r'^pages/', include(wagtailadmin_pages_urls, namespace='wagtailadmin_pages')),
|
||||
|
||||
# TODO: Move into wagtailadmin_pages namespace
|
||||
url(r'^choose-page/$', chooser.browse, name='wagtailadmin_choose_page'),
|
||||
url(r'^choose-page/(\d+)/$', chooser.browse, name='wagtailadmin_choose_page_child'),
|
||||
url(r'^choose-page/search/$', chooser.search, name='wagtailadmin_choose_page_search'),
|
||||
url(r'^choose-external-link/$', chooser.external_link, name='wagtailadmin_choose_page_external_link'),
|
||||
url(r'^choose-email-link/$', chooser.email_link, name='wagtailadmin_choose_page_email_link'),
|
||||
|
||||
url(r'^tag-autocomplete/$', tags.autocomplete, name='wagtailadmin_tag_autocomplete'),
|
||||
|
||||
url(r'^account/$', account.account, name='wagtailadmin_account'),
|
||||
url(r'^account/change_password/$', account.change_password, name='wagtailadmin_account_change_password'),
|
||||
url(r'^account/notification_preferences/$', account.notification_preferences, name='wagtailadmin_account_notification_preferences'),
|
||||
url(r'^logout/$', account.logout, name='wagtailadmin_logout'),
|
||||
]
|
||||
|
||||
|
||||
# Import additional urlpatterns from any apps that define a register_admin_urls hook
|
||||
for fn in hooks.get_hooks('register_admin_urls'):
|
||||
urls = fn()
|
||||
if urls:
|
||||
urlpatterns += urls
|
||||
|
||||
|
||||
# Add "wagtailadmin.access_admin" permission check
|
||||
urlpatterns = decorate_urlpatterns(urlpatterns,
|
||||
permission_required(
|
||||
'wagtailadmin.access_admin',
|
||||
login_url='wagtailadmin_login'
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# These url patterns do not require an authenticated admin user
|
||||
urlpatterns += [
|
||||
url(r'^login/$', account.login, name='wagtailadmin_login'),
|
||||
|
||||
# These two URLs have the "permission_required" decorator applied directly
|
||||
# as they need to fail with a 403 error rather than redirect to the login page
|
||||
url(r'^userbar/(\d+)/$', userbar.for_frontend, name='wagtailadmin_userbar_frontend'),
|
||||
url(r'^userbar/moderation/(\d+)/$', userbar.for_moderation, name='wagtailadmin_userbar_moderation'),
|
||||
|
||||
# Password reset
|
||||
url(r'^password_reset/', include(wagtailadmin_password_reset_urls)),
|
||||
]
|
||||
|
||||
# Decorate all views with cache settings to prevent caching
|
||||
urlpatterns = decorate_urlpatterns(urlpatterns,
|
||||
cache_control(private=True, no_cache=True, no_store=True, max_age=0)
|
||||
)
|
||||
39
wagtail/wagtailadmin/urls/pages.py
Normal file
39
wagtail/wagtailadmin/urls/pages.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
from django.conf.urls import url
|
||||
|
||||
from wagtail.wagtailadmin.views import pages, page_privacy
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^add/(\w+)/(\w+)/(\d+)/$', pages.create, name='add'),
|
||||
url(r'^add/(\w+)/(\w+)/(\d+)/preview/$', pages.preview_on_create, name='preview_on_add'),
|
||||
url(r'^usage/(\w+)/(\w+)/$', pages.content_type_use, name='type_use'),
|
||||
|
||||
url(r'^(\d+)/edit/$', pages.edit, name='edit'),
|
||||
url(r'^(\d+)/edit/preview/$', pages.preview_on_edit, name='preview_on_edit'),
|
||||
|
||||
url(r'^preview/$', pages.preview, name='preview'),
|
||||
url(r'^preview_loading/$', pages.preview_loading, name='preview_loading'),
|
||||
|
||||
url(r'^(\d+)/view_draft/$', pages.view_draft, name='view_draft'),
|
||||
url(r'^(\d+)/add_subpage/$', pages.add_subpage, name='add_subpage'),
|
||||
url(r'^(\d+)/delete/$', pages.delete, name='delete'),
|
||||
url(r'^(\d+)/unpublish/$', pages.unpublish, name='unpublish'),
|
||||
|
||||
url(r'^search/$', pages.search, name='search'),
|
||||
|
||||
url(r'^(\d+)/move/$', pages.move_choose_destination, name='move'),
|
||||
url(r'^(\d+)/move/(\d+)/$', pages.move_choose_destination, name='move_choose_destination'),
|
||||
url(r'^(\d+)/move/(\d+)/confirm/$', pages.move_confirm, name='move_confirm'),
|
||||
url(r'^(\d+)/set_position/$', pages.set_page_position, name='set_page_position'),
|
||||
|
||||
url(r'^(\d+)/copy/$', pages.copy, name='copy'),
|
||||
|
||||
url(r'^moderation/(\d+)/approve/$', pages.approve_moderation, name='approve_moderation'),
|
||||
url(r'^moderation/(\d+)/reject/$', pages.reject_moderation, name='reject_moderation'),
|
||||
url(r'^moderation/(\d+)/preview/$', pages.preview_for_moderation, name='preview_for_moderation'),
|
||||
|
||||
url(r'^(\d+)/privacy/$', page_privacy.set_privacy, name='set_privacy'),
|
||||
|
||||
url(r'^(\d+)/lock/$', pages.lock, name='lock'),
|
||||
url(r'^(\d+)/unlock/$', pages.unlock, name='unlock'),
|
||||
]
|
||||
34
wagtail/wagtailadmin/urls/password_reset.py
Normal file
34
wagtail/wagtailadmin/urls/password_reset.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
from django.conf.urls import url
|
||||
from django.contrib.auth import views as django_auth_views
|
||||
|
||||
from wagtail.wagtailadmin.forms import PasswordResetForm
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(
|
||||
r'^$', django_auth_views.password_reset, {
|
||||
'template_name': 'wagtailadmin/account/password_reset/form.html',
|
||||
'email_template_name': 'wagtailadmin/account/password_reset/email.txt',
|
||||
'subject_template_name': 'wagtailadmin/account/password_reset/email_subject.txt',
|
||||
'password_reset_form': PasswordResetForm,
|
||||
'post_reset_redirect': 'wagtailadmin_password_reset_done',
|
||||
}, name='wagtailadmin_password_reset'
|
||||
),
|
||||
url(
|
||||
r'^done/$', django_auth_views.password_reset_done, {
|
||||
'template_name': 'wagtailadmin/account/password_reset/done.html'
|
||||
}, name='wagtailadmin_password_reset_done'
|
||||
),
|
||||
url(
|
||||
r'^confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
|
||||
django_auth_views.password_reset_confirm, {
|
||||
'template_name': 'wagtailadmin/account/password_reset/confirm.html',
|
||||
'post_reset_redirect': 'wagtailadmin_password_reset_complete',
|
||||
}, name='wagtailadmin_password_reset_confirm',
|
||||
),
|
||||
url(
|
||||
r'^complete/$', django_auth_views.password_reset_complete, {
|
||||
'template_name': 'wagtailadmin/account/password_reset/complete.html'
|
||||
}, name='wagtailadmin_password_reset_complete'
|
||||
),
|
||||
]
|
||||
|
|
@ -20,6 +20,16 @@ def get_querystring(request):
|
|||
})
|
||||
|
||||
|
||||
def shared_context(request, extra_context={}):
|
||||
context = {
|
||||
'allow_external_link': request.GET.get('allow_external_link'),
|
||||
'allow_email_link': request.GET.get('allow_email_link'),
|
||||
'querystring': get_querystring(request),
|
||||
}
|
||||
context.update(extra_context)
|
||||
return context
|
||||
|
||||
|
||||
def browse(request, parent_page_id=None):
|
||||
ITEMS_PER_PAGE = 25
|
||||
|
||||
|
|
@ -82,17 +92,18 @@ def browse(request, parent_page_id=None):
|
|||
except EmptyPage:
|
||||
pages = paginator.page(paginator.num_pages)
|
||||
|
||||
return render_modal_workflow(request, 'wagtailadmin/chooser/browse.html', 'wagtailadmin/chooser/browse.js', {
|
||||
'allow_external_link': request.GET.get('allow_external_link'),
|
||||
'allow_email_link': request.GET.get('allow_email_link'),
|
||||
'querystring': get_querystring(request),
|
||||
'parent_page': parent_page,
|
||||
'pages': pages,
|
||||
'search_form': search_form,
|
||||
'page_type_string': ','.join(page_types),
|
||||
'page_type_names': [desired_class.get_verbose_name() for desired_class in desired_classes],
|
||||
'page_types_restricted': (page_type != 'wagtailcore.page')
|
||||
})
|
||||
return render_modal_workflow(
|
||||
request,
|
||||
'wagtailadmin/chooser/browse.html', 'wagtailadmin/chooser/browse.js',
|
||||
shared_context(request, {
|
||||
'parent_page': parent_page,
|
||||
'pages': pages,
|
||||
'search_form': search_form,
|
||||
'page_type_string': ','.join(page_types),
|
||||
'page_type_names': [desired_class.get_verbose_name() for desired_class in desired_classes],
|
||||
'page_types_restricted': (page_type != 'wagtailcore.page')
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
def search(request, parent_page_id=None):
|
||||
|
|
@ -130,11 +141,13 @@ def search(request, parent_page_id=None):
|
|||
page.can_choose = True
|
||||
shown_pages.append(page)
|
||||
|
||||
return render(request, 'wagtailadmin/chooser/_search_results.html', {
|
||||
'querystring': get_querystring(request),
|
||||
'searchform': search_form,
|
||||
'pages': shown_pages,
|
||||
})
|
||||
return render(
|
||||
request, 'wagtailadmin/chooser/_search_results.html',
|
||||
shared_context(request, {
|
||||
'searchform': search_form,
|
||||
'pages': shown_pages,
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
def external_link(request):
|
||||
|
|
@ -162,11 +175,9 @@ def external_link(request):
|
|||
return render_modal_workflow(
|
||||
request,
|
||||
'wagtailadmin/chooser/external_link.html', 'wagtailadmin/chooser/external_link.js',
|
||||
{
|
||||
'querystring': get_querystring(request),
|
||||
'allow_email_link': request.GET.get('allow_email_link'),
|
||||
shared_context(request, {
|
||||
'form': form,
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -195,9 +206,7 @@ def email_link(request):
|
|||
return render_modal_workflow(
|
||||
request,
|
||||
'wagtailadmin/chooser/email_link.html', 'wagtailadmin/chooser/email_link.js',
|
||||
{
|
||||
'querystring': get_querystring(request),
|
||||
'allow_external_link': request.GET.get('allow_external_link'),
|
||||
shared_context(request, {
|
||||
'form': form,
|
||||
}
|
||||
})
|
||||
)
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ def add_subpage(request, parent_page_id):
|
|||
# Only one page type is available - redirect straight to the create form rather than
|
||||
# making the user choose
|
||||
content_type = page_types[0]
|
||||
return redirect('wagtailadmin_pages_create', content_type.app_label, content_type.model, parent_page.id)
|
||||
return redirect('wagtailadmin_pages:add', content_type.app_label, content_type.model, parent_page.id)
|
||||
|
||||
return render(request, 'wagtailadmin/pages/add_subpage.html', {
|
||||
'parent_page': parent_page,
|
||||
|
|
@ -176,12 +176,12 @@ def create(request, content_type_app_name, content_type_model_name, parent_page_
|
|||
if is_publishing:
|
||||
messages.success(request, _("Page '{0}' created and published.").format(page.title), buttons=[
|
||||
messages.button(page.url, _('View live')),
|
||||
messages.button(reverse('wagtailadmin_pages_edit', args=(page.id,)), _('Edit'))
|
||||
messages.button(reverse('wagtailadmin_pages:edit', args=(page.id,)), _('Edit'))
|
||||
])
|
||||
elif is_submitting:
|
||||
messages.success(request, _("Page '{0}' created and submitted for moderation.").format(page.title), buttons=[
|
||||
messages.button(reverse('wagtailadmin_pages_view_draft', args=(page.id,)), _('View draft')),
|
||||
messages.button(reverse('wagtailadmin_pages_edit', args=(page.id,)), _('Edit'))
|
||||
messages.button(reverse('wagtailadmin_pages:view_draft', args=(page.id,)), _('View draft')),
|
||||
messages.button(reverse('wagtailadmin_pages:edit', args=(page.id,)), _('Edit'))
|
||||
])
|
||||
send_notification(page.get_latest_revision().id, 'submitted', request.user.id)
|
||||
else:
|
||||
|
|
@ -197,7 +197,7 @@ def create(request, content_type_app_name, content_type_model_name, parent_page_
|
|||
return redirect('wagtailadmin_explore', page.get_parent().id)
|
||||
else:
|
||||
# Just saving - remain on edit page for further edits
|
||||
return redirect('wagtailadmin_pages_edit', page.id)
|
||||
return redirect('wagtailadmin_pages:edit', page.id)
|
||||
else:
|
||||
messages.error(request, _("The page could not be created due to validation errors"))
|
||||
edit_handler = edit_handler_class(instance=page, form=form)
|
||||
|
|
@ -256,12 +256,12 @@ def edit(request, page_id):
|
|||
if is_publishing:
|
||||
messages.success(request, _("Page '{0}' published.").format(page.title), buttons=[
|
||||
messages.button(page.url, _('View live')),
|
||||
messages.button(reverse('wagtailadmin_pages_edit', args=(page_id,)), _('Edit'))
|
||||
messages.button(reverse('wagtailadmin_pages:edit', args=(page_id,)), _('Edit'))
|
||||
])
|
||||
elif is_submitting:
|
||||
messages.success(request, _("Page '{0}' submitted for moderation.").format(page.title), buttons=[
|
||||
messages.button(reverse('wagtailadmin_pages_view_draft', args=(page_id,)), _('View draft')),
|
||||
messages.button(reverse('wagtailadmin_pages_edit', args=(page_id,)), _('Edit'))
|
||||
messages.button(reverse('wagtailadmin_pages:view_draft', args=(page_id,)), _('View draft')),
|
||||
messages.button(reverse('wagtailadmin_pages:edit', args=(page_id,)), _('Edit'))
|
||||
])
|
||||
send_notification(page.get_latest_revision().id, 'submitted', request.user.id)
|
||||
else:
|
||||
|
|
@ -277,7 +277,7 @@ def edit(request, page_id):
|
|||
return redirect('wagtailadmin_explore', page.get_parent().id)
|
||||
else:
|
||||
# Just saving - remain on edit page for further edits
|
||||
return redirect('wagtailadmin_pages_edit', page.id)
|
||||
return redirect('wagtailadmin_pages:edit', page.id)
|
||||
else:
|
||||
if page.locked:
|
||||
messages.error(request, _("The page could not be saved as it is locked"))
|
||||
|
|
@ -494,7 +494,7 @@ def unpublish(request, page_id):
|
|||
page.unpublish()
|
||||
|
||||
messages.success(request, _("Page '{0}' unpublished.").format(page.title), buttons=[
|
||||
messages.button(reverse('wagtailadmin_pages_edit', args=(page.id,)), _('Edit'))
|
||||
messages.button(reverse('wagtailadmin_pages:edit', args=(page.id,)), _('Edit'))
|
||||
])
|
||||
|
||||
return redirect('wagtailadmin_explore', page.get_parent().id)
|
||||
|
|
@ -546,7 +546,7 @@ def move_confirm(request, page_to_move_id, destination_id):
|
|||
page_to_move.move(destination, pos='last-child')
|
||||
|
||||
messages.success(request, _("Page '{0}' moved.").format(page_to_move.title), buttons=[
|
||||
messages.button(reverse('wagtailadmin_pages_edit', args=(page_to_move.id,)), _('Edit'))
|
||||
messages.button(reverse('wagtailadmin_pages:edit', args=(page_to_move.id,)), _('Edit'))
|
||||
])
|
||||
|
||||
return redirect('wagtailadmin_explore', destination.id)
|
||||
|
|
@ -733,7 +733,7 @@ def approve_moderation(request, revision_id):
|
|||
revision.approve_moderation()
|
||||
messages.success(request, _("Page '{0}' published.").format(revision.page.title), buttons=[
|
||||
messages.button(revision.page.url, _('View live')),
|
||||
messages.button(reverse('wagtailadmin_pages_edit', args=(revision.page.id,)), _('Edit'))
|
||||
messages.button(reverse('wagtailadmin_pages:edit', args=(revision.page.id,)), _('Edit'))
|
||||
])
|
||||
send_notification(revision.id, 'approved', request.user.id)
|
||||
|
||||
|
|
@ -752,7 +752,7 @@ def reject_moderation(request, revision_id):
|
|||
if request.method == 'POST':
|
||||
revision.reject_moderation()
|
||||
messages.success(request, _("Page '{0}' rejected for publication.").format(revision.page.title), buttons=[
|
||||
messages.button(reverse('wagtailadmin_pages_edit', args=(revision.page.id,)), _('Edit'))
|
||||
messages.button(reverse('wagtailadmin_pages:edit', args=(revision.page.id,)), _('Edit'))
|
||||
])
|
||||
send_notification(revision.id, 'rejected', request.user.id)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@ from wagtail.wagtaildocs.views import documents, chooser
|
|||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', documents.index, name='wagtaildocs_index'),
|
||||
url(r'^add/$', documents.add, name='wagtaildocs_add_document'),
|
||||
url(r'^edit/(\d+)/$', documents.edit, name='wagtaildocs_edit_document'),
|
||||
url(r'^delete/(\d+)/$', documents.delete, name='wagtaildocs_delete_document'),
|
||||
url(r'^$', documents.index, name='index'),
|
||||
url(r'^add/$', documents.add, name='add'),
|
||||
url(r'^edit/(\d+)/$', documents.edit, name='edit'),
|
||||
url(r'^delete/(\d+)/$', documents.delete, name='delete'),
|
||||
|
||||
url(r'^chooser/$', chooser.chooser, name='wagtaildocs_chooser'),
|
||||
url(r'^chooser/(\d+)/$', chooser.document_chosen, name='wagtaildocs_document_chosen'),
|
||||
url(r'^chooser/upload/$', chooser.chooser_upload, name='wagtaildocs_chooser_upload'),
|
||||
url(r'^usage/(\d+)/$', documents.usage, name='wagtaildocs_document_usage'),
|
||||
url(r'^chooser/$', chooser.chooser, name='chooser'),
|
||||
url(r'^chooser/(\d+)/$', chooser.document_chosen, name='document_chosen'),
|
||||
url(r'^chooser/upload/$', chooser.chooser_upload, name='chooser_upload'),
|
||||
url(r'^usage/(\d+)/$', documents.usage, name='document_usage'),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class Document(models.Model, TagSearchable):
|
|||
|
||||
@property
|
||||
def usage_url(self):
|
||||
return reverse('wagtaildocs_document_usage',
|
||||
return reverse('wagtaildocs:document_usage',
|
||||
args=(self.id,))
|
||||
|
||||
def is_editable_by_user(self, user):
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
<div class="tab-content">
|
||||
<section id="search" class="{% if not uploadform.errors %}active {% endif %}nice-padding">
|
||||
<form class="document-search search-bar" action="{% url 'wagtaildocs_chooser' %}" method="GET">
|
||||
<form class="document-search search-bar" action="{% url 'wagtaildocs:chooser' %}" method="GET">
|
||||
<ul class="fields">
|
||||
{% for field in searchform %}
|
||||
{% include "wagtailadmin/shared/field_as_li.html" with field=field %}
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
</section>
|
||||
{% if uploadform %}
|
||||
<section id="upload" class="{% if uploadform.errors %}active {% endif %}nice-padding">
|
||||
<form class="document-upload" action="{% url 'wagtaildocs_chooser_upload' %}" method="POST" enctype="multipart/form-data">
|
||||
<form class="document-upload" action="{% url 'wagtaildocs:chooser_upload' %}" method="POST" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<ul class="fields">
|
||||
{% for field in uploadform %}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
{% include "wagtailadmin/shared/header.html" with title=add_str icon="doc-full-inverse" %}
|
||||
|
||||
<div class="nice-padding">
|
||||
<form action="{% url 'wagtaildocs_add_document' %}" method="POST" enctype="multipart/form-data">
|
||||
<form action="{% url 'wagtaildocs:add' %}" method="POST" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<ul class="fields">
|
||||
{% for field in form %}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<div class="nice-padding">
|
||||
<p>{% trans "Are you sure you want to delete this document?" %}</p>
|
||||
<form action="{% url 'wagtaildocs_delete_document' document.id %}" method="POST">
|
||||
<form action="{% url 'wagtaildocs:delete' document.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="submit" value='{% trans "Yes, delete" %}' class="serious" />
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<div class="row row-flush nice-padding">
|
||||
|
||||
<div class="col10 divider-after">
|
||||
<form action="{% url 'wagtaildocs_edit_document' document.id %}" method="POST" enctype="multipart/form-data">
|
||||
<form action="{% url 'wagtaildocs:edit' document.id %}" method="POST" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<ul class="fields">
|
||||
{% for field in form %}
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
{% include "wagtailadmin/shared/field_as_li.html" %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<li><input type="submit" value="{% trans 'Save' %}" /> <a href="{% url 'wagtaildocs_delete_document' document.id %}" class="button button-secondary no">{% trans "Delete document" %}</a></li>
|
||||
<li><input type="submit" value="{% trans 'Save' %}" /> <a href="{% url 'wagtaildocs:delete' document.id %}" class="button button-secondary no">{% trans "Delete document" %}</a></li>
|
||||
</ul>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
{% block extra_js %}
|
||||
<script>
|
||||
window.headerSearch = {
|
||||
url: "{% url 'wagtaildocs_index' %}",
|
||||
url: "{% url 'wagtaildocs:index' %}",
|
||||
termInput: "#id_q",
|
||||
targetOutput: "#document-results"
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
{% block content %}
|
||||
{% trans "Documents" as doc_str %}
|
||||
{% trans "Add a document" as add_doc_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=doc_str add_link="wagtaildocs_add_document" icon="doc-full-inverse" add_text=add_doc_str search_url="wagtaildocs_index" %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=doc_str add_link="wagtaildocs:add" icon="doc-full-inverse" add_text=add_doc_str search_url="wagtaildocs:index" %}
|
||||
|
||||
<div class="nice-padding">
|
||||
<div id="document-results" class="documents">
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<tr class="table-headers">
|
||||
<th>
|
||||
{% if not is_searching %}
|
||||
<a href="{% url 'wagtaildocs_index' %}{% if not ordering == "title" %}?ordering=title{% endif %}" class="icon icon-arrow-down-after {% if ordering == "title" %}teal{% endif %}">
|
||||
<a href="{% url 'wagtaildocs:index' %}{% if not ordering == "title" %}?ordering=title{% endif %}" class="icon icon-arrow-down-after {% if ordering == "title" %}teal{% endif %}">
|
||||
{% trans "Title" %}
|
||||
</a>
|
||||
{% else %}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<th>{% trans "File" %}</th>
|
||||
<th>
|
||||
{% if not is_searching %}
|
||||
<a href="{% url 'wagtaildocs_index' %}{% if not ordering == "-created_at" %}?ordering=-created_at{% endif %}" class="icon icon-arrow-down-after {% if ordering == "-created_at" %}teal{% endif %}">
|
||||
<a href="{% url 'wagtaildocs:index' %}{% if not ordering == "-created_at" %}?ordering=-created_at{% endif %}" class="icon icon-arrow-down-after {% if ordering == "-created_at" %}teal{% endif %}">
|
||||
{% trans "Uploaded" %}
|
||||
</a>
|
||||
{% else %}
|
||||
|
|
@ -31,9 +31,9 @@
|
|||
<tr>
|
||||
<td class="title">
|
||||
{% if choosing %}
|
||||
<h2><a href="{% url 'wagtaildocs_document_chosen' doc.id %}" class="document-choice">{{ doc.title }}</a></h2>
|
||||
<h2><a href="{% url 'wagtaildocs:document_chosen' doc.id %}" class="document-choice">{{ doc.title }}</a></h2>
|
||||
{% else %}
|
||||
<h2><a href="{% url 'wagtaildocs_edit_document' doc.id %}">{{ doc.title }}</a></h2>
|
||||
<h2><a href="{% url 'wagtaildocs:edit' doc.id %}">{{ doc.title }}</a></h2>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td><a href="{{ doc.url }}" class="nolink">{{ doc.filename }}</a></td>
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue