Jump to content

[SOLVED] Best way to search a site including hidden child pages


Juergen
 Share

Recommended Posts

Hello ,

I want to know how others deal with site search and hidden child pages.

Some of my pages have children which status is set to hidden. The parent page is the main page and the only visible page. The child pages provide some content wich will be displayed on the parent (main) page.

fe my main page is a page about privacy policies of several social networks

- Privacy policy (main page, visible)

-- Privacy policy for Facebook (child page, status hidden)

-- Privacy policy for Twitter (child page, status hidden)

-- Privacy policy for Linkedin (child page, status hidden)

 

So on my main page all the texts of the child pages will be visible.

 

Problem: 

If I use my search form on the frontend and search for a word (term) that is included in a hidden child page, it will not be found, but this word (term) is visible on the main page. I want to achive that the word (term) will be found, but the URL should point to the main page (in this case the privacy policy page).

I guess that others are struggeling with this problem too. How do you deal with this problem? What would be a good approach?

Thanks in advance

Link to comment
Share on other sites

Maybe a bit dirty but very effective: add a hidden (or none manually editable) textarea field to your main page and on save of the main page or one of the children, collect all text there in.
Then you need to search in this field instead of the (main)-body field.

  • Like 1
Link to comment
Share on other sites

Thanks @horst,

I have also thought about this to add the values via a page save hook to a field, but I have hoped that there will be a more elegant solution (fe. via a page reference field or something like that). Storing the same data twice is a little bit of overhead.

  • Like 1
Link to comment
Share on other sites

I might not be getting the full picture here but...

1 hour ago, Juergen said:

If I use my search form on the frontend and search for a word (term) that is included in a hidden child page, it will not be found,

It should be found if you use 'include=hidden' in your selector.

1 hour ago, Juergen said:

I want to achive that the word (term) will be found, but the URL should point to the main page (in this case the privacy policy page).

Assuming the hidden pages will always refer to their parents...

$search = $pages->find('body%=something, include=hidden');
$out = '<ol>';
foreach ($search as $s) {
	// if page hidden, grab url of parent
	if($s->isHidden()) $url = $s->parent->url;
      // if at the top of the tree, just return the found page URL
	elseif($s->rootParent == $s) $url = $s->url;
  // normal find
    else $url = $s->url;
	$out .= '<li>' . $url . ' (original path: '. $s->url.')</li>';// just for testing
}

$out .= '</ol>';

echo $out;

You might want to change the logic a bit

  • Like 2
Link to comment
Share on other sites

2 minutes ago, kongondo said:

It should be found if you use 'include=hidden' in your selector.

This was not clearly written by me. Sorry! I have used "include=hidden" and the page will be found, but the URL did not point to the parent.

5 minutes ago, kongondo said:

You might want to change the logic a bit

Thats the way to go! :)

Link to comment
Share on other sites

27 minutes ago, Juergen said:

I have hoped that there will be a more elegant solution (fe. via a page reference field or something like that)

For any field that references a page, the syntax to access and search content in the referenced page is the same. You use dot syntax in the form page_reference_field_name.field_name. This applies equally to Page Reference, PageTable and Repeater / Repeater Matrix field types.

So if you use a Page Reference field called "social_networks" that contains pages for Facebook, Twitter and LinkedIn, and those pages contain a "body" field that you want to search, your selector would be:

social_networks.body%=foo

This will match the page that contains the social_network field rather than the referenced pages. So exactly what you are wanting to do.

  • Like 3
Link to comment
Share on other sites

1 hour ago, Juergen said:

Thanks @horst,

I have also thought about this to add the values via a page save hook to a field, but I have hoped that there will be a more elegant solution (fe. via a page reference field or something like that). Storing the same data twice is a little bit of overhead.

Yep, that's with the overhead is right, but only on the first view.

If you have many fields and reference fields on one page (template), your searches may become time costy in the DB. At that point you want to use concatenated fields (also available as core module!). :)

So it depends on the amount of your involved fields (=DB-tables) which way to go.

 

EDIT:

The core module is called Cache, it is a fieldtype:

Quote
Title Cache
Class FieldtypeCache
File /wire /modules /Fieldtype /FieldtypeCache.module
Namespace \ (default namespace)
   
Version 1.0.2
   
Summary Caches the values of other fields for fewer runtime queries. Can also be used to combine multiple text fields and have them all be searchable under the cached field name.

 

  • Like 2
Link to comment
Share on other sites

Thanks to all for their contributions!

Finally I ended up with the solution from @Robin S  and a hook in the ready.php.

In my case I only need to search the title and body fields in the hidden children. The reference field is located in the parent template. Instead of adding the pages manually to the reference field i use a hook to add a child page after save to the reference field.

The reason behind this is if there will be added a new child page, by default you have to add the new page manually to the page reference field. This makes it a little bit complicated.

So I decided to add the following hook inside the ready.php to add the newly created page automatically after save to the page reference field.

$pages->addHookAfter('saveReady', function($event)
{
$page = $event->arguments(0);
$page->of(false);
if($page->template->name == 'privacy-policy-item'){
$page->parent->of(false);
 if($page->parent->hasField('privacyref')) {
   $page->parent->privacyref->add($page->id);
   $page->parent->save('privacyref');
   $this->message('Page reference was added to parent template');
 }
}
});

The child template in my case is called "privacy-policy-item". The page reference field in the parent template is called "privacyref". So if a new child page was created and the save button was clicked the new page will be added automatically to the reference field. Therefore the new page is fully searchable without doing something manually.

Best regards

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...