Different search functions on two templates based website

I use two templates on my website. The site based on baseblog theme and there is a search function to search in blog articles. As the second template knowledge base is used. There is a basic search functionality, that I want to use only therefore.

[...]
04-support
05-blog
[some hidden folders...]

Both templates are using different styles and I want to show two different result pages. Is this possible?

I have different header, content and footer for both of them.

<?php snippet('header') ?>
<?php snippet('menu') ?>

  <main role="main">

    <?php $countItems = $pagination->countItems();

          if($results) {

            echo '<h1 class="result">';

            if($countItems == 0) {
              echo 'No results';
            }
            elseif($countItems == 1) {
              echo $countItems , ' top result';
            }
            else {
              echo $countItems , ' results';
            }

            echo ' for “<mark>' , $query , '</mark>”</h1>';
    } ?>

    <?php if($results->count() != 0): ?>
    <ul class="results">
      <?php foreach($results as $result): ?>
      <li>
        <h2><a href="<?= $result->url() ?>"><?= $result->title()->html() ?></a></h2>
        <div class="meta">
          <time datetime="<?= $result->date('c') ?>"><?= $result->date('%A, %e. %B %Y'); ?></time>
          <?php if ($result->tags() != ''): ?> |
          <ul class="tags">
            <?php foreach(str::split($result->tags()) as $tag): ?>
            <li><a href="<?= url('tag:' . urlencode($tag)) ?>">#<?= $tag ?></a></li>
            <?php endforeach ?>
          </ul>
          <?php endif ?>
        </div>
      </li>
      <?php endforeach ?>
    </ul>
    <?php endif ?>

    
    <?php if($pagination->hasPages()): // pagination ?>
    <nav class="pagination cf">
      <?php if($pagination->hasPrevPage()): ?>
      <a class="button prev" href="<?= $pagination->prevPageURL() ?>">&lsaquo;&lsaquo; newer results</a>
      <?php endif ?>
      <?php if($pagination->hasNextPage()): ?>
      <a class="button next" href="<?= $pagination->nextPageURL() ?>">older results &rsaquo;&rsaquo;</a>
      <?php endif ?>
    </nav>
    <?php endif ?>

  </main>

<?php snippet('footer') ?>

How can I detect the calling search function to choose the right header, footer… in the template search.php?

How do I have to modify the controller file.

<?php

return function($site, $pages, $page) {

  $query   = get('q');
  
  // baseblog
  if (page('blog')) {
    $results = page('blog')->search($query, array('words' => true))
                           ->visible()
                           ->sortBy('date', 'desc')
                           ->paginate(10);

    return array(
      'query'   => $query,
      'results' => $results,
      'pagination' => $results->pagination()
    );
  
  // knowledge base
  } elseif (page('support')) {
    $results = page('support')->visible()
                              ->search($query, 'title|text')
                              ->paginate(10);
    /*
    $results = $site->index()
                    ->visible()
                    ->search($query, 'title|text');
    */
    return array(
      'query'   => $query,
      'results' => $results,
      'pagination' => $results->pagination()
    );

  }

};

So that it works. At the moment it works for blog entries, but not for the support page. Always showing “no results”.

Thanks for your advice and help.

I’d create two different templates with their own controllers (and two different search result pages in content). The the action attribute in your search form decides which page to call.

Hello again.

Sorry for asking again. I miss the right solution and don’t know what to do.

site/templates/search_blog.php
site/templates/search_knowledge.php

site/controllers/search_blog.php
site/controllers/search_knowledge.php
content/search/search_blog.de.txt
content/search/search_blog.en.txt
content/search/search_knowledge.de.txt
content/search/search_knowledge.en.txt

I filled in a “marker” in the search_knowledge.php to identify the used search page. And the result shows, that only one search is used, and not both of them.

I use this menu for the entire site, except the knowledge base.

<nav class="menu cf" role="navigation">
  <ul class="cf">
    <?php foreach($pages->visible() as $item): ?>
    <li><a<?php e($item->isOpen(), ' class="active"') ?> href="<?= $item->url() ?>"><?= $item->title()->html() ?></a></li>
    <?php endforeach ?>
  </ul>
  <form class="search" role="search" action="<?= url('search') ?>">
    <label class="vh" for="search"><?php echo l::get('search') ?></label>
    <input type="search" class="searchword" name="q" id="search" placeholder="<?php echo l::get('search') ?>..."/>
  </form>
</nav>

The other search form is in the header_knowledge.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width,initial-scale=1.0">

	<title><?= $site->title()->html() ?> | <?= $page->title()->html() ?></title>
	<meta name="description" content="<?= $site->description()->html() ?>">
	<?= css('https://fonts.googleapis.com/css?family=Roboto:300,400,500,700') ?>
	<?= css('assets/css/style.css') ?>
	<?= css('assets/css/prism.css') ?>
	<link rel="icon" href="<?php echo url('assets/images/kb.favicon.png?v=3') ?>" />
</head>
<body>
	<div class="wrap">
		<nav class="menu">
			<a class="logo" href="<?php echo url() ?>"><img src="<?= url() ?>/assets/images/kb.logo.png" alt="" /></a>
			<form action="<?= url() ?>/search"><input type="search" class="search" name="q" placeholder="<?php echo l::get('search') ?>..."/></form>
			<?php snippet('treemenu_knowledge') ?>			
		</nav>

Can you please give me an advice, why only on one result page ist used.

You can’t have two pages with the same folder name, you would have to rename at least one of them, e.g search-blogand search-knowledge and then the action:

action="<?= url('search-knowledge') ?>"

and

action="<?= url('search-blog') ?>"

Too tired to have a closer look if there is anything else… :sleeping::sleeping:

Thanks again - it works. I have to do some other things.

That’s ok. :wink:

The search results are shown with this code:

<?php if($results): ?>

		<ul>
		  <?php foreach($results as $result): ?>
		  <li>
		    <a href="<?php echo $result->url() ?>">
		      <?php echo $result->title()->html() ?>
		    </a>
		  </li>
		  <?php endforeach ?>
		</ul>

		<?php else: ?>
		<div class="no-results">No really knowledge results for <strong><?= html($search->query()) ?></strong></div>
		<?php endif ?>

With a controller like this:

<?php

return function($site, $pages, $page) {

  $query   = get('q');
  $results = $site->index()->visible()->search($query, 'title|text');

  return array(
    'query'   => $query,
    'results' => $results,
  );

};

And now, the <?php else: ?>is never reached, even the search string was not found. Where is the missing logic?

Returns the $results always a value? And why?

$results is a collection object, even if there are no elements in it, it is still an object, so will always return true. Instead of checking if it is true or not, you have to check if counting elements returns true/false

if($results->count()) {
  // do stuff
}

Thank you. This works, now I can make the next steps.

This “check” was in the original code. It is used in both templates on which my code based on…

Not quite, If you look closely, there are two different checks in the original Baseblog template. see lines #8 and #25 of the search.php template…

You are right. I will make a couple of changes the next time. Maybe I need help again.