mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Clean up search documentation
This commit is contained in:
parent
c1c0ad3dac
commit
a7971d0540
@ -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 … 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 %>
|
|
||||||
…
|
|
||||||
<% 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)
|
|
||||||
|
44
docs/en/02_Developer_Guides/12_Search/02_FulltextSearch.md
Normal file
44
docs/en/02_Developer_Guides/12_Search/02_FulltextSearch.md
Normal 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]
|
@ -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)
|
|
Loading…
Reference in New Issue
Block a user