Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Possible solution to allow the built-in search to include fields without hacking the search engine?


Reply


4 Posts   2210 Views

Avatar
Codetapper

Community Member, 8 Posts

30 July 2009 at 10:34am

I have read the forums regarding the limitations of searches in Silverstripe (whereby the engine will only search the title and content fields) and like others, found the search rather disappointing.

Is it possible to create a page type with all the relevant fields you need, and the content editor the CMS user sees is actually a different field (let's call it rawcontent for example), and when it is saved, it copies all the fields plus the rawcontent into the $Content section and saves? Will that work?

That way a search will still index all the data for that record, and the template would just be changed to display $rawcontent when the page is viewed.

If this is possible, what is the "beforesave" type method? I find the API very difficult to follow compared to other languages and prefer code snippets!

Avatar
schellmax

Community Member, 126 Posts

30 July 2009 at 9:06pm

i like your approach, didn't think of that.
what you're looking for is the 'onBeforeWrite' hook (http://doc.silverstripe.org/doku.php?id=datamodel#onbeforewrite)

Avatar
brokemeister

Community Member, 30 Posts

5 August 2009 at 7:48pm

Edited: 05/08/2009 7:48pm

Hi!

Just use following snippet in MainDataObject (e.g. Page):

static $db = array (
      "ContentToSearch" => "Text",
   );

static $indexes = array(
      "SearchFields" => "fulltext (Title, ContentToSearch)",
      "TitleSearchFields" => "fulltext (Title)",
   );

protected $searchable_content_fields = array(); //Here you can enter your fields

protected function onBeforeWrite() {
      // CAUTION: You are required to call the parent-function, otherwise sapphire will not execute the request.
      parent::onBeforeWrite();
      
      if (is_array($this->searchable_content_fields)
         && count($this->searchable_content_fields) > 0) {
            $SearchContent = array();
            foreach ($this->searchable_content_fields AS $field) {
               if (!empty($this->$field)) {
                  $SearchContent[] = $this->$field;
               }
            }
            $this->ContentToSearch = implode(chr(10), $SearchContent);
      }
   }

You also can use Content-field...

Cheers,

Malte

Avatar
Codetapper

Community Member, 8 Posts

10 August 2009 at 3:19pm

Thanks for the reply. When I put that code into top part of Page.php and rebuild the database I get the following error:

(User Error) Couldn't run query: CREATE TABLE `Page` ( `ID` int(11) not null auto_increment, `ContentToSearch` mediumtext character set utf8 collate utf8_general_ci, fulltext `SearchFields` (Title,ContentToSearch), fulltext `TitleSearchFields` (Title), primary key (ID) ) TYPE=MyISAM Key column 'Title' doesn't exist in table
GET /ss/db/build?flush=1

Line 400 in C:\wamp\www\ss\sapphire\core\model\MySQLDatabase.php

Also if you look at the indexes in phpMyAdmin, it has all of the following:

Title, MenuTitle, Content, MetaTitle, MetaDescription, MetaKeywords

Does the code above mean it's not going to index the meta tags anymore unless I re-add them to the $indexes array? (Is this because of indexing changes in the version you used to write the code or something? I am using the latest version 2.3.1).