Open pmfx opened 6 years ago
Good question
I found that AjaxSearch can perform search in custom tables this way:
function pagebuilder_ajaxsearch(&$main, &$joined, $bsf, $fields) {
global $modx;
$joined = [
'tb_name' => $modx->getFullTablename('pagebuilder'),
'tb_alias' => 'pb',
'id' => 'id',
'main' => 'id',
'join' => 'document_id',
'searchable' => ['values'],
'displayed' => ['config', 'values'],
'concat_separator' => ', ',
'filters' => [
['field' => 'visible', 'oper' => '=', 'value' => '1'],
],
];
}
[!AjaxSearch? &whereSearch=`content|pagebuilder_ajaxsearch` &ajaxSearch=`0`!]
But results filtered by built in jscropper (because data stored in json format)
Thanks. That was a good clue and I got it working! At least it looks like it is working ;)
Here is what I did:
I've copied AjaxSearch default config file:
assets/snippets/ajaxSearch/configs/default.config.php
as a
assets/snippets/ajaxSearch/configs/pagebuilder.config.php
At the end of this new config file I've added your code and a copy of AjaxSearch strip code (without JS strip):
function pagebuilder_ajaxsearch(&$main, &$joined, $bsf, $fields) {
global $modx;
$joined = [
'tb_name' => $modx->getFullTablename('pagebuilder'),
'tb_alias' => 'pb',
'id' => 'id',
'main' => 'id',
'join' => 'document_id',
'searchable' => ['values'],
'displayed' => ['config', 'values'],
'concat_separator' => ', ',
'filters' => [
['field' => 'visible', 'oper' => '=', 'value' => '1']
],
];
}
function pagebuilderStripOutput($text) {
global $modx;
if ($text !== '') {
// stripLineBreaking : replace line breaking tags with whitespace
$text = preg_replace("'<(br[^/>]*?/|hr[^/>]*?/|/(div|h[1-6]|li|p|td))>'si", ' ', $text);
// stripTags : Remove MODX sensitive tags
$modRegExArray[] = '~\[\[(.*?)\]\]~s';
$modRegExArray[] = '~\[\!(.*?)\!\]~s';
$modRegExArray[] = '#\[\~(.*?)\~\]#s';
$modRegExArray[] = '~\[\((.*?)\)\]~s';
$modRegExArray[] = '~{{(.*?)}}~s';
$modRegExArray[] = '~\[\*(.*?)\*\]~s';
$modRegExArray[] = '~\[\+(.*?)\+\]~s';
foreach ($modRegExArray as $mReg) $text = preg_replace($mReg, '', $text);
// stripHtml : Remove HTML sensitive tags
$text = strip_tags($text);
}
return $text;
}
The last thing was a snippet call:
[!AjaxSearch?
&config=`pagebuilder`
&ajaxSearch=`0`
&whereSearch=`content|tv|pagebuilder_ajaxsearch`
&stripOutput=`pagebuilderStripOutput`
!]
To show extract from PB in AS results you can use this in snippet parameter:
&extract=`1:content,pb_values`
But this may result in showing code like {"richtext":"Lorem ipsum....."}
As a temporary workaround I added this at the end of a "pagebuilderStripOutput" function:
// strip pagebuilder wrappers
$text = str_replace('{"richtext":"', '', $text);
$text = str_replace('"}', '', $text);
But it is not perfect in case other field names are used. Probably can be solved with preg_replace/regex but I'm not that familiar with it.
While the configuring AjaxSearch is pretty difficult, maybe easiest solution would be to make a copy of PageBuilder values (without JS code) inside "content" field of "site_content" table on every document save event?
With this, there would be no issues with searching or configuring AjaxSearch.
... and it could be added as a new plugin setting (turned off by default).
I don't like this solution, we can just end AjaxSearch config to crop all mustaches with regex
Cool, have it working. My mistake was that I didn't add it to the result (landing) page snippet.
I was wondering what is the best way to make site search when website content heavily depends on PageBuilder?
How to configure AjaxSearch or other snippet to search in PageBuilder and show the search results?