diff --git a/docs/building_your_site.rst b/docs/building_your_site.rst index b52d797a1..4c62d8cab 100644 --- a/docs/building_your_site.rst +++ b/docs/building_your_site.rst @@ -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 %} {{ tag }} @@ -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 %} ... diff --git a/docs/conf.py b/docs/conf.py index 11517ada2..4112e3753 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -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 = [] diff --git a/docs/wagtail_search.rst b/docs/wagtail_search.rst index c43a53737..c3ebd236c 100644 --- a/docs/wagtail_search.rst +++ b/docs/wagtail_search.rst @@ -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
@@ -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:: {% 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 ------------------------------ + +Lets also add a simple interface for the search with an ```` element and ``
`` for the results: +.. code-block:: html + +
+

Search

+ +
+
+ +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 += '

' + element.title + '

'; + }); + // 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 ``
``. 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 --------------