Clean up search documentation

This commit is contained in:
Will Rossiter 2014-10-28 18:42:27 +13:00 committed by Cam Findlay
parent c1c0ad3dac
commit a7971d0540
3 changed files with 99 additions and 163 deletions

View File

@ -1,41 +1,45 @@
title: Scaffolding with SearchContext
summary: Configure the search form within ModelAdmin using the SearchContext class.
# SearchContext # SearchContext
## Introduction [api:SearchContext] manages searching of properties on one or more [api:DataObject] types, based on a given set of
input parameters. [api:SearchContext] is intentionally decoupled from any controller-logic, it just receives a set of
search parameters and an object class it acts on.
Manages searching of properties on one or more `[api:DataObject]` types, based on a given set of input parameters. The default output of a [api:SearchContext] is either a [api:SQLQuery] object for further refinement, or a
`[api:SearchContext]` is intentionally decoupled from any controller-logic, [api:DataObject] instance.
it just receives a set of search parameters and an object class it acts on.
The default output of a `[api:SearchContext]` is either a `[api:SQLQuery]` object for further refinement, or a <div class="notice" markdown="1">
`[api:DataObject]` instance. [api:SearchContext] is mainly used by [ModelAdmin](../customising_the_cms/modeladmin).
</div>
In case you need multiple contexts, consider namespacing your request parameters by using `FieldList->namespace()` on
the $fields constructor parameter.
`[api:SearchContext]` is mainly used by `[ModelAdmin](/reference/modeladmin)`, our generic data administration interface. Another
implementation can be found in generic frontend search forms through the [genericviews](http://silverstripe.org/generic-views-module) module.
## Usage ## Usage
Getting results Defining search-able fields on your DataObject.
:::php :::php
singleton('MyDataObject')->getDefaultSearchContext(); <?php
class MyDataObject extends DataObject {
### Defining fields on your DataObject private static $searchable_fields = array(
'Name',
'ProductCode'
);
}
See `[api:DataObject::$searchable_fields]`. ## Customizing fields and filters
### Customizing fields and filters
In this example we're defining three attributes on our MyDataObject subclass: `PublicProperty`, `HiddenProperty` In this example we're defining three attributes on our MyDataObject subclass: `PublicProperty`, `HiddenProperty`
and `MyDate`. The attribute `HiddenProperty` should not be searchable, and `MyDate` should only search for dates and `MyDate`. The attribute `HiddenProperty` should not be searchable, and `MyDate` should only search for dates
*after* the search entry (with a `GreaterThanFilter`). Similiar to the built-in `DataObject->getDefaultSearchContext()` *after* the search entry (with a `GreaterThanFilter`).
method, we're building our own `getCustomSearchContext()` variant.
:::php :::php
<?php
class MyDataObject extends DataObject { class MyDataObject extends DataObject {
private static $db = array( private static $db = array(
'PublicProperty' => 'Text' 'PublicProperty' => 'Text'
'HiddenProperty' => 'Text', 'HiddenProperty' => 'Text',
@ -46,10 +50,12 @@ method, we're building our own `getCustomSearchContext()` variant.
$fields = $this->scaffoldSearchFields(array( $fields = $this->scaffoldSearchFields(array(
'restrictFields' => array('PublicProperty','MyDate') 'restrictFields' => array('PublicProperty','MyDate')
)); ));
$filters = array( $filters = array(
'PublicProperty' => new PartialMatchFilter('PublicProperty'), 'PublicProperty' => new PartialMatchFilter('PublicProperty'),
'MyDate' => new GreaterThanFilter('MyDate') 'MyDate' => new GreaterThanFilter('MyDate')
); );
return new SearchContext( return new SearchContext(
$this->class, $this->class,
$fields, $fields,
@ -58,24 +64,43 @@ method, we're building our own `getCustomSearchContext()` variant.
} }
} }
<div class="notice" markdown="1">
See the [SearchFilter](../model/searchfilters) documentation for more information about filters to use such as the
`GreaterThanFilter`.
</div>
<div class="notice" markdown="1">
In case you need multiple contexts, consider name-spacing your request parameters by using `FieldList->namespace()` on
the `$fields` constructor parameter.
</div>
### Generating a search form from the context ### Generating a search form from the context
:::php :::php
<?php
..
class Page_Controller extends ContentController { class Page_Controller extends ContentController {
public function SearchForm() { public function SearchForm() {
$context = singleton('MyDataObject')->getCustomSearchContext(); $context = singleton('MyDataObject')->getCustomSearchContext();
$fields = $context->getSearchFields(); $fields = $context->getSearchFields();
$form = new Form($this, "SearchForm", $form = new Form($this, "SearchForm",
$fields, $fields,
new FieldList( new FieldList(
new FormAction('doSearch') new FormAction('doSearch')
) )
); );
return $form; return $form;
} }
public function doSearch($data, $form) { public function doSearch($data, $form) {
$context = singleton('MyDataObject')->getCustomSearchContext(); $context = singleton('MyDataObject')->getCustomSearchContext();
$results = $context->getResults($data); $results = $context->getResults($data);
return $this->customise(array( return $this->customise(array(
'Results' => $results 'Results' => $results
))->renderWith('Page_results'); ))->renderWith('Page_results');
@ -83,110 +108,13 @@ method, we're building our own `getCustomSearchContext()` variant.
} }
### Pagination ## Related Documentation
For pagination records on multiple pages, you need to wrap the results in a * [ModelAdmin](../customising_the_cms/modeladmin)
`PaginatedList` object. This object is also passed the generated `SQLQuery` * [Tutorial: Site Search](/tutorials/site_search)
in order to read page limit information. It is also passed the current
`SS_HTTPRequest` object so it can read the current page from a GET var.
:::php
public function getResults($searchCriteria = array()) {
$start = ($this->request->getVar('start')) ? (int)$this->request->getVar('start') : 0;
$limit = 10;
$context = singleton('MyDataObject')->getCustomSearchContext();
$query = $context->getQuery($searchCriteria, null, array('start'=>$start,'limit'=>$limit));
$records = $context->getResults($searchCriteria, null, array('start'=>$start,'limit'=>$limit));
if($records) {
$records = new PaginatedList($records, $this->request);
$records->setPageStart($start);
$records->setPageLength($limit);
$records->setTotalItems($query->unlimitedRowCount());
}
return $records;
}
notice that if you want to use this getResults function, you need to change the function doSearch for this one:
:::php
public function doSearch($data, $form) {
$context = singleton('MyDataObject')->getCustomSearchContext();
$results = $this->getResults($data);
return $this->customise(array(
'Results' => $results
))->renderWith(array('Catalogo_results', 'Page'));
}
The change is in **$results = $this->getResults($data);**, because you are using a custom getResults function.
Another thing you cant forget is to check the name of the singleton you are using in your project. the example uses
**MyDataObject**, you need to change it for the one you are using
For more information on how to paginate your results within the template, see [Tutorial: Site Search](/tutorials/4-site-search).
### The Pagination Template
to show the results of your custom search you need at least this content in your template, notice that
Results.PaginationSummary(4) defines how many pages the search will show in the search results. something like:
**Next 1 2 *3* 4 5 &hellip; 558**
:::ss
<% if $Results %>
<ul>
<% loop $Results %>
<li>$Title, $Autor</li>
<% end_loop %>
</ul>
<% else %>
<p>Sorry, your search query did not return any results.</p>
<% end_if %>
<% if $Results.MoreThanOnePage %>
<div id="PageNumbers">
<p>
<% if $Results.NotFirstPage %>
<a class="prev" href="$Results.PrevLink" title="View the previous page">Prev</a>
<% end_if %>
<span>
<% loop $Results.PaginationSummary(4) %>
<% if $CurrentBool %>
$PageNum
<% else %>
<% if $Link %>
<a href="$Link" title="View page number $PageNum">$PageNum</a>
<% else %>
&hellip;
<% end_if %>
<% end_if %>
<% end_loop %>
</span>
<% if $Results.NotLastPage %>
<a class="next" href="$Results.NextLink" title="View the next page">Next</a>
<% end_if %>
</p>
</div>
<% end_if %>
## Available SearchFilters
See `[api:SearchFilter]` API Documentation
## API Documentation ## API Documentation
`[api:SearchContext]`
## Related * [api:SearchContext]
* [api:DataObject]
* [ModelAdmin](/reference/modeladmin)
* [RestfulServer module](https://github.com/silverstripe/silverstripe-restfulserver)
* [Tutorial: Site Search](/tutorials/4-site-search)

View File

@ -0,0 +1,44 @@
title: Fulltext Search
summary: Fulltext search allows sophisticated searching on text content.
# FulltextSearchable
Fulltext search allows advanced search criteria for searching words within a text based data column. While basic
Fulltext search can be achieved using the built-in [api:MySQLDatabase] class a more powerful wrapper for Fulltext
search is provided through a module.
<div class="notice" markdown="1">
See the [FulltextSearch Module](https://github.com/silverstripe-labs/silverstripe-fulltextsearch/). This module provides
a high level wrapper for running advanced search services such as Solr, Lucene or Sphinx in the backend rather than
`MySQL` search.
</div>
## Adding Fulltext Support to MySQLDatabase
The [api:MySQLDatabase] class defaults to creating tables using the InnoDB storage engine. As Fulltext search in MySQL
requires the MyISAM storage engine, any DataObject you wish to use with Fulltext search must be changed to use MyISAM
storage engine.
You can do so by adding this static variable to your class definition:
:::php
<?php
class MyDataObject extends DataObject {
private static $create_table_options = array(
'MySQLDatabase' => 'ENGINE=MyISAM'
);
}
The [api:FulltextSearchable] extension will add the correct `Fulltext` indexes to the data model.
<div class="alert" markdown="1">
The [api:SearchForm] and [api:FulltextSearchable] API's are currently hard coded to be specific to `Page` and `File`
records and cannot easily be adapted to include custom `DataObject` instances. To include your custom objects in the
default site search, have a look at those extensions and modify as required.
</div>
## API Documentation
* [api:FulltextSearchable]

View File

@ -1,44 +1,8 @@
title: Search
summary: Provide your users with advanced search functionality. summary: Provide your users with advanced search functionality.
introduction: Give users the ability to search your applications. Fulltext search for Page Content (and other attributes like "Title") can be easily added to SilverStripe.
# Search See the [Site Search Tutorial](/tutorials/site_search) for a detailed walk through of adding basic Search to your
website.
## Searching for Pages (and Files) [CHILDREN]
Fulltext search for page content (and other attributes like "Title" or "MetaTags") can be easily added to SilverStripe.
See [Tutorial: Site Search](/tutorials/site_search) for details.
## Searching for DataObjects
The `[api:SearchContext]` class provides a good base implementation that you can hook into your own controllers.
A working implementation of searchable DataObjects can be seen in the [ModelAdmin](../customising_the_cms/modeladmin) class.
[SearchContext](/searchcontext) goes into more detail about setting up a default search form for `[api:DataObject]`s.
## Fulltext search on DataObjects
The `[api:MySQLDatabase]` class now defaults to creating tables using the InnoDB storage engine. As Fulltext search in
MySQL requires the MyISAM storage engine, any DataObject you wish to use with Fulltext search must be changed to use
MyISAM storage engine.
You can do so by adding this static variable to your class definition:
:::php
private static $create_table_options = array(
'MySQLDatabase' => 'ENGINE=MyISAM'
);
## Searching for Documents
SilverStripe does not have a built-in method to search through file content (e.g. in PDF or DOC format). You can either
extract any textual file content into the `[File](api:File)->Content` property, or use a dedicated search service like
the [Full module](http://silverstripe.org/sphinx-module).
## Related
* [ModelAdmin](/reference/modeladmin)
* [RestfulServer module](https://github.com/silverstripe/silverstripe-restfulserver)
* [Tutorial: Site Search](/tutorials/4-site-search)
* [SearchContext](/reference/searchcontext)
* [genericviews module](http://silverstripe.org/generic-views-module)
* [sphinx module](http://silverstripe.org/sphinx-module)
* [lucene module](http://silverstripe.org/lucene-module)