• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Integrate add-on with search

Onimua

Well-known member
#1
Is there a tutorial, if possible, to how how to integrate your add-on content with search?

If I've got a lot of notes I'd like to be able to search them within XenForo and have them display along with possibly related posts/threads. I imagine it is possible but not sure of how to approach it.
 

Shadab

Well-known member
#2
I didn't try implementing search for an addon, until today. It was much easier than I thought. It's a 4 step process, where you need to implement the following interfaces/handlers:
  • A search handler class
  • Form template (for displaying the search form)
  • Search Results template (for displaying search result snippets)
  • And finally the code that manipulates search index at _postSave and _postDelete
I'll outline the procedure for "Scratchpad" addon...

1. Content-type & Content Field

Insert a record in the xf_content_type table and xf_content_type_field table, adding your content-type name and the search handler's class name. For this addon, I used the following info:
Code:
+-----------------+------------+
| content_type    | addon_id   |
+-----------------+------------+
| scratchpad_note | scratchpad |
+-----------------+------------+
Code:
+-----------------+----------------------+------------------------------------+
| content_type    | field_name           | field_value                        |
+-----------------+----------------------+------------------------------------+
| scratchpad_note | search_handler_class | Scratchpad_Search_DataHandler_Note |
+-----------------+----------------------+------------------------------------+

2. Search Data Handler

Now create the data handler class: Scratchpad_Search_DataHandler_Note. This class should extend the abstract data handler (XenForo_Search_DataHandler_Abstract), and implement about 10 required methods. It would help if your model has methods that return data in the format specified below; although it's not absolutely required.
  • Multiple content records, when supplied an array of IDs.
    For fetching multiple notes I've used: getNotesByIds(array)​

  • List of next X IDs, when supplied a start ID and the limit
    For fetching this list I've used: getNoteIdsInRange(int, int)​

3. Form template:

Created a form template "search_form_note", based on an existing form template "search_form_post". Form fields for displaying the list of nodes and other fields not relevant to the scratchpad, were removed.


4. Results template:

Created a search results template "search_result_note", based on an existing results template "search_result_post". Except for variable names, pretty much everything else was left unchanged.


5. DataWriter hooks for _postSave and _postDelete

The Notes datawriter now includes a _postSave method, which would be used for inserting the note "message" into the search index; and a _postDelete method, which would be used for removing the deleted "note" from the search index.

Screenies:

Search Notes Form page:
1_Search_Notes.png


Notes Search Results page:
2_Notes_Search.png


Search Everything Results page:
(showing forum posts + scratchpad notes as results)

3_Search_Everything.png


Demonstration Addon:

Original thread:
http://xenforo.com/community/threads/scratchpad-demonstration-ajax-add-on.8369/
 

Attachments

Onimua

Well-known member
#3
Happy to hear it wasn't much of a twist to get it in. I'll definitely try this out now to see how I progress.

Thanks for looking into this! :D
 

Shadab

Well-known member
#4
*Attached the addon in my previous post*

To get to the type-specific search form (screenie #1), you'll have to manually visit:
/search/?type=scratchpad_note
 

Jaxel

Well-known member
#6
Sweet... this is awesome... I have one question though... This is what I am using:
Code:
	protected function _insertIntoIndex(XenForo_Search_Indexer $indexer, array $data, array $parentData = null)
	{
		$metaData = array();
		if ($data['media_keywords']) { $metaData['media_keywords'] = $data['media_keywords']; }
		if ($data['media_custom1']) { $metaData['media_custom1'] = $data['media_custom1']; }
		if ($data['media_custom2']) { $metaData['media_custom2'] = $data['media_custom2']; }
		if ($data['media_custom3']) { $metaData['media_custom3'] = $data['media_custom3']; }
		if ($data['media_custom4']) { $metaData['media_custom4'] = $data['media_custom4']; }
		if ($data['media_custom5']) { $metaData['media_custom5'] = $data['media_custom5']; }

		$indexer->insertIntoIndex(
			'media', $data['media_id'], $data['media_title'], $data['media_description'],
			$data['media_date'], $data['user_id'], 0, $metaData
		);
	}
How do I get the search system to also search for text in media_keywords and media_custom#?

As well as sorting by views, comments and likes?