kopia lustrzana https://github.com/wagtail/wagtail
Async search docs done
rodzic
876283debf
commit
206a3e3732
|
@ -84,7 +84,9 @@ Parents
|
|||
```````
|
||||
Parent nodes on the Wagtail tree probably want to organize and display a browsable index of their descendents. A blog, for instance, needs a way to show a list of individual posts.
|
||||
|
||||
A Parent node could provide its own function returning its descendant objects. ::
|
||||
A Parent node could provide its own function returning its descendant objects.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class EventPageIndex(Page):
|
||||
...
|
||||
|
@ -104,7 +106,9 @@ Leaves are the pieces of content itself, a page which is consumable, and might j
|
|||
|
||||
It might be helpful for a leaf to provide a way to back up along the tree to a parent, such as in the case of breadcrumbs navigation. The tree might also be deep enough that a leaf's parent won't be included in general site navigation.
|
||||
|
||||
The model for the leaf could provide a function that traverses the tree in the opposite direction and returns an appropriate ancestor::
|
||||
The model for the leaf could provide a function that traverses the tree in the opposite direction and returns an appropriate ancestor:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class BlogPage(Page):
|
||||
...
|
||||
|
@ -131,7 +135,9 @@ Overriding the Serve() Method
|
|||
|
||||
Wagtail defaults to serving ``Page``-derived models by passing ``self`` to a Django HTML template matching the model's name, but suppose you wanted to serve something other than HTML? You can override the ``serve()`` method provided by the ``Page`` class and handle the Django request and response more directly.
|
||||
|
||||
Consider this example from the Wagtail demo site's ``models.py``, which serves an ``EventPage`` object as an iCal file if the ``format`` variable is set in the request::
|
||||
Consider this example from the Wagtail demo site's ``models.py``, which serves an ``EventPage`` object as an iCal file if the ``format`` variable is set in the request:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class EventPage(Page):
|
||||
...
|
||||
|
@ -161,7 +167,9 @@ Tagging
|
|||
```````
|
||||
Wagtail provides tagging capability through the combination of two django modules, ``taggit`` and ``modelcluster``. ``taggit`` provides a model for tags which is extended by ``modelcluster``, which in turn provides some magical database abstraction which makes drafts and revisions possible in Wagtail. It's a tricky recipe, but the net effect is a many-to-many relationship between your model and a tag class reserved for your model.
|
||||
|
||||
Using an example from the Wagtail demo site, here's what the tag model and the relationship field looks like in ``models.py``::
|
||||
Using an example from the Wagtail demo site, here's what the tag model and the relationship field looks like in ``models.py``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from modelcluster.fields import ParentalKey
|
||||
from modelcluster.tags import ClusterTaggableManager
|
||||
|
@ -181,7 +189,9 @@ Using an example from the Wagtail demo site, here's what the tag model and the r
|
|||
|
||||
Wagtail's admin provides a nice interface for inputting tags into your content, with typeahead tag completion and friendly tag icons.
|
||||
|
||||
Now that we have the many-to-many tag relationship in place, we can fit in a way to render both sides of the relation. Here's more of the Wagtail demo site ``models.py``, where the index model for ``BlogPage`` is extended with logic for filtering the index by tag::
|
||||
Now that we have the many-to-many tag relationship in place, we can fit in a way to render both sides of the relation. Here's more of the Wagtail demo site ``models.py``, where the index model for ``BlogPage`` is extended with logic for filtering the index by tag:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class BlogIndexPage(Page):
|
||||
...
|
||||
|
@ -199,7 +209,9 @@ Now that we have the many-to-many tag relationship in place, we can fit in a way
|
|||
'blogs': blogs,
|
||||
})
|
||||
|
||||
Here, ``blogs.filter(tags__name=tag)`` invokes a reverse Django queryset filter on the ``BlogPageTag`` model to optionally limit the ``BlogPage`` objects sent to the template for rendering. Now, lets render both sides of the relation by showing the tags associated with an object and a way of showing all of the objects associated with each tag. This could be added to the ``blog_page.html`` template::
|
||||
Here, ``blogs.filter(tags__name=tag)`` invokes a reverse Django queryset filter on the ``BlogPageTag`` model to optionally limit the ``BlogPage`` objects sent to the template for rendering. Now, lets render both sides of the relation by showing the tags associated with an object and a way of showing all of the objects associated with each tag. This could be added to the ``blog_page.html`` template:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% for tag in self.tags.all %}
|
||||
<a href="{% pageurl self.blog_index %}?tag={{ tag }}">{{ tag }}</a>
|
||||
|
@ -268,7 +280,9 @@ Template Tags
|
|||
|
||||
**pageurl**
|
||||
|
||||
Takes a ``Page``-derived object and returns its URL as relative (``/foo/bar/``) if it's within the same site as the current page, or absolute (``http://example.com/foo/bar/``) if not. ::
|
||||
Takes a ``Page``-derived object and returns its URL as relative (``/foo/bar/``) if it's within the same site as the current page, or absolute (``http://example.com/foo/bar/``) if not.
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% load pageurl %}
|
||||
...
|
||||
|
@ -276,7 +290,9 @@ Template Tags
|
|||
|
||||
**slugurl**
|
||||
|
||||
Takes a ``slug`` string and returns the URL for the ``Page``-derived object with that slug. Like ``pageurl``, will try to provide a relative link if possible, but will default to an absolute link if on a different site. ::
|
||||
Takes a ``slug`` string and returns the URL for the ``Page``-derived object with that slug. Like ``pageurl``, will try to provide a relative link if possible, but will default to an absolute link if on a different site.
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% load slugurl %}
|
||||
...
|
||||
|
@ -284,7 +300,9 @@ Template Tags
|
|||
|
||||
**wagtailuserbar**
|
||||
|
||||
This tag provides a Wagtail icon and flyout menu on the top-right of a page for a logged-in user with editing capabilities, with the option of editing the current Page-derived object or adding a new sibling object. ::
|
||||
This tag provides a Wagtail icon and flyout menu on the top-right of a page for a logged-in user with editing capabilities, with the option of editing the current Page-derived object or adding a new sibling object.
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% load wagtailuserbar %}
|
||||
...
|
||||
|
@ -292,7 +310,9 @@ Template Tags
|
|||
|
||||
**image**
|
||||
|
||||
This template tag provides a way to process an image with a method and dimensions. ::
|
||||
This template tag provides a way to process an image with a method and dimensions.
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% load image_tags %}
|
||||
...
|
||||
|
@ -312,7 +332,9 @@ Template Filters
|
|||
|
||||
**rich_text**
|
||||
|
||||
This filter is required for use with any ``RichTextField``. It will expand internal shorthand references to embeds and links made in the Wagtail editor into fully-baked HTML ready for display. **Note that the template tag loaded differs from the name of the filter.** ::
|
||||
This filter is required for use with any ``RichTextField``. It will expand internal shorthand references to embeds and links made in the Wagtail editor into fully-baked HTML ready for display. **Note that the template tag loaded differs from the name of the filter.**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% load rich_text %}
|
||||
...
|
||||
|
|
|
@ -93,7 +93,7 @@ exclude_patterns = ['_build']
|
|||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
#pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
|
|
@ -8,7 +8,9 @@ Default Page Search
|
|||
|
||||
Wagtail provides a default frontend search interface which indexes the ``title`` field common to all ``Page``-derived models. Lets take a look at all the components of the search interface.
|
||||
|
||||
The most basic search functionality just needs a search box which submits a request. Since this will be reused throughout the site, lets put it in ``mysite/includes/search_box.html`` and then use ``{% include ... %}`` to weave it into templates::
|
||||
The most basic search functionality just needs a search box which submits a request. Since this will be reused throughout the site, lets put it in ``mysite/includes/search_box.html`` and then use ``{% include ... %}`` to weave it into templates:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
<form action="{% url 'wagtailsearch_search' %}" method="get">
|
||||
<input type="text" name="q"{% if query_string %} value="{{ query_string }}"{% endif %}>
|
||||
|
@ -17,11 +19,15 @@ The most basic search functionality just needs a search box which submits a requ
|
|||
|
||||
The form is submitted to the url of the ``wagtailsearch_search`` view, with the search terms variable ``q``. The view will use its own (very) basic search results template.
|
||||
|
||||
Lets use our own template for the results, though. First, in your project's ``settings.py``, define a path to your template::
|
||||
Lets use our own template for the results, though. First, in your project's ``settings.py``, define a path to your template:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
WAGTAILSEARCH_RESULTS_TEMPLATE = 'mysite/search_results.html'
|
||||
|
||||
Next, lets look at the template itself::
|
||||
Next, lets look at the template itself:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% extends "mysite/base.html" %}
|
||||
{% load pageurl %}
|
||||
|
@ -48,7 +54,7 @@ Next, lets look at the template itself::
|
|||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
The search view returns a context with a few useful variables.
|
||||
The search view provides a context with a few useful variables.
|
||||
|
||||
``query_string``
|
||||
The terms (string) used to make the search.
|
||||
|
@ -62,13 +68,95 @@ The search view returns a context with a few useful variables.
|
|||
``query``
|
||||
A Wagtail Query object matching the terms. The query model provides several class methods for viewing the statistics of all queries, but exposes only one property for single objects, ``query.hits``, which tracks the number of time the search string has been used over the lifetime of the site.
|
||||
|
||||
Asyncronous Search with JSON and AJAX
|
||||
-------------------------------------
|
||||
|
||||
Wagtail's provides JSON search results when queries are made to the ``wagtailsearch_suggest`` view. To take advantage of it, we need a way to make that URL available to a static script. Instead of hard-coding it, lets set a global variable in our ``base.html``:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
Default Page Search with AJAX
|
||||
-----------------------------
|
||||
<script>
|
||||
var wagtailJSONSearchURL = "{% url 'wagtailsearch_suggest' %}";
|
||||
</script>
|
||||
|
||||
Lets also add a simple interface for the search with an ``<input>`` element and ``<div>`` for the results:
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<div>
|
||||
<h3>Search</h3>
|
||||
<input id="json-search" type="text">
|
||||
<div id="json-results"></div>
|
||||
</div>
|
||||
|
||||
Finally, we'll use JQuery to make the aynchronous requests and handle the interactivity:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
$(function() {
|
||||
|
||||
// cache the elements
|
||||
var searchBox = $('#json-search'),
|
||||
resultsBox = $('#json-results');
|
||||
// when there's something in the input box, make the query
|
||||
searchBox.on('input', function() {
|
||||
if( searchBox.val() == ''){
|
||||
resultsBox.html('');
|
||||
return;
|
||||
}
|
||||
// make the request to the Wagtail JSON search view
|
||||
$.ajax({
|
||||
url: wagtailJSONSearchURL + "?q=" + searchBox.val(),
|
||||
dataType: "json"
|
||||
})
|
||||
.done(function(data) {
|
||||
console.log(data);
|
||||
if( data == undefined ){
|
||||
resultsBox.html('');
|
||||
return;
|
||||
}
|
||||
// we're in business! let's format the results
|
||||
var htmlOutput = '';
|
||||
data.forEach(function(element, index, array){
|
||||
htmlOutput += '<p><a href="' + element.url + '">' + element.title + '</a></p>';
|
||||
});
|
||||
// and display them
|
||||
resultsBox.html(htmlOutput);
|
||||
})
|
||||
.error(function(data){
|
||||
console.log(data);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Results are returned as a JSON object with this structure:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
{
|
||||
[
|
||||
{
|
||||
title: "Lumpy Space Princess",
|
||||
url: "/oh-my-glob/"
|
||||
},
|
||||
{
|
||||
title: "Lumpy Space",
|
||||
url: "/no-smooth-posers/"
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
|
||||
What if you wanted access to the rest of the results context or didn't feel like using JSON? Wagtail also provides a generalized AJAX interface where you can use your own template to serve results asyncronously.
|
||||
|
||||
The AJAX interface uses the same view as the normal HTML search, ``wagtailsearch_search``, but will serve different results if Django classifies the request as AJAX (``request.is_ajax()``). Another entry in your project settings will let you override the template used to serve this response:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
WAGTAILSEARCH_RESULTS_TEMPLATE_AJAX = 'mirrorstage/includes/search_listing.html'
|
||||
|
||||
You could provide a template in JSON format with extra properties, such as ``query.hits``, or render an HTML snippet that can go directly into your results ``<div>``. If you need more flexibility, such as multiple formats/templates based on differing requests, you can set up a custom search view.
|
||||
|
||||
Editor's Picks
|
||||
--------------
|
||||
|
|
Ładowanie…
Reference in New Issue