Async search docs done

pull/256/head
Jeffrey Hearn 2014-05-10 16:49:05 -04:00
rodzic 876283debf
commit 206a3e3732
3 zmienionych plików z 128 dodań i 18 usunięć

Wyświetl plik

@ -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 %}
...

Wyświetl plik

@ -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 = []

Wyświetl plik

@ -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
--------------