Vyhledávání na webu

Rudolf Svátek 2016-07-28 14:14

Archiv s dnešní kapitolou včetně malé opravy mapperu PagesMapper.php: kapitola21.zip.

Uživatelé ocení, pokud jim nabídneš na webu políčko s vyhledáváním. Nechce se jim třeba procházet celý web a hledat nějakou informaci. Zadají prostě heslo do vyhledávacího formuláře a z výsledků si už vyberou co chtějí. A co bys čekal? Zase to bude pomocí komponenty.

Komponenta vyhledávacího formuláře

<?php

namespace App\FrontModule\Controls;

use App\Forms\FormFactory;
use Nette\Application\UI;
use Kdyby\BootstrapFormRenderer\BootstrapRenderer;

class SearchControl extends UI\Control
{

	/** @var FormFactory */
	private $factory;

	/**
	 * @param FormFactory $factory
	 */
	public function __construct(FormFactory $factory) {
		parent::__construct();
		$this->factory = $factory;
	}

	public function render() {
		$this->getTemplate()->setFile(__DIR__ . '/SearchControl.latte');
		$this->getTemplate()->render();
	}

	/**
	 * @return UI\Form
	 */
	protected function createComponentSearchForm() {
		$form = $this->factory->create();
		$form->addText('term', 'hledat')
				->setRequired("Zadejte hledaný termín")
				->setAttribute('class', 'form-control input-sm');
		$form->addButton('process', "Hledat")
				->setAttribute('onclick', 'this.form.submit();')
				->setAttribute('class', 'btn btn-primary');

		$form->setRenderer(new BootstrapRenderer);
		$form->getElementPrototype()->class('form-horizontal');
		$form->onSuccess[] = callback($this, 'processForm');

		return $form;
	}

	/**
	 * @param UI\Form $form
	 */
	public function processForm(UI\Form $form) {
		$values = $form->getValues();
		$this->presenter->redirect('Search:default', ['term' => $values->term]);
	}

}

Tohle je jednoduchá komponenta. Jen prostě zobrazí formulář a po odeslání přesměruje na presenter "Search" (který zatím nemáme, ale hned ho uděláme).

Šablona formuláře

Opět nic složitého. Já mám ve zvyku vykreslovat si HTML ručně, takže:

<form n:name="searchForm" class="navbar-form" role="search" style="position: absolute; top:8px; left: 8px;">
	<div class="input-group">
		<input n:name="term" type="text" class="form-control" id="srch-term">
		<div class="input-group-btn">
			<button class="btn btn-default" type="submit" n:name="process"><i class="glyphicon glyphicon-search"></i></button>
		</div>
	</div>
</form>

V hlavní čabloně pak jen zase na vhodné místo stačí formulář umístit:

{control searchControl}

Poslední krok je upravit BasePresenter a přidat mu metodu:

	/**
	 * @return SearchControl
	 */
	public function createComponentSearchControl() {
		$control = new SearchControl($this->formFactory);
		return $control;
	}

Nezapomeň na

use App\FrontModule\Controls\SearchControl;

To by mělo stačit k tomu, abys viděl políčko vyhledávacího formuláře. Teď to ještě rozchodíme. Vytvoříme si presenter pro zobrazení nalezených stránek a taky jeho šablonu.

Presenter pro zobrazení výsledků

Presenter si nazveme třeba Search. No musíme - už s tím počítáme v komponentě, kdy přesměrováváme provoz po odeslání formuláře právě na presenter Search.

<?php

namespace App\FrontModule\Presenters;

class SearchPresenter extends BasePresenter
{

	public function startup() {
		parent::startup();
	}

	/**
	 * @param $term
	 */
	public function actionDefault($term) {
		$pages = $this->pagesRepository->search($term);
		
		$visualPaginator = $this['visualPaginator'];
		$paginator = $visualPaginator->getPaginator();
		$paginator->itemsPerPage = 5;
		$paginator->itemCount = $pages->count();
		$pages->limit($paginator->itemsPerPage);
		$pages->offset($paginator->offset);

		$this->getTemplate()->term = $term;
		$this->getTemplate()->pages = $pages->fetchAll();
		$this->getTemplate()->title = 'Výsledky hledání - ' . $term;
		$this->getTemplate()->description = 'Výsledky hledání - ' . $term;
		$this->getTemplate()->keywords = 'Výsledky hledání - ' . $term;
	}

}

Tady se přiznám k malé nepozornosti: v mapperu je funce search(). Ta fultextově vyhledává stránky, ale nějak jsem tam nedal podmínku, že musí mít status "aktivní". Opravil jsem to a v dnešním archivu ke stažení to bude.

Šablona bude vypisovat nalezené stránky. Těch může být mnoho, tak proto je tam to stránkování.

{block content}
	{snippet search}
		<div class="contentArea">
			<div class="divPanel notop page-content">
				<div class="breadcrumbs"></div>
				<div class="row">
					<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
						<h2>Výsledky hledání <i>"{$term}"</i></h2>
					</div>
					<!--Edit Main Content Area here-->
					<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
						<div class="post-preview" n:foreach="$pages as $page">
							<a n:href="Pages:view $page->id">
								<h2 class="post-title">
									{$page->name|noescape|striptags}
								</h2>
								<p class="post-subtitle">
									{if $page->perex > '' }{$page->perex|striptags|noescape|truncate:500}{else}{$page->text|striptags|noescape|truncate:500}{/if}
								</p>
							</a>
						</div>
						<hr>
					</div>
					<!--End Main Content-->
				</div>
				{control visualPaginator}
				<div id="footerInnerSeparator"></div>
			</div>
		</div>
	{/snippet}
{/block}

Nechci tě k ničemu nutit a klidně si to uprav podle sebe.

Takže teď už by formulář měl umět hledat. Předpokládám, že nějakou textovou stránku už máš. Pokud ne, v administraci ji vytvoř a vlož nějaký text. Klidně i víc stránek, ať si zkusíš to stránkování. No a po zadání hesla pro vyhledávání se ti zobrazí výsledky.

Toť vše. Archiv s dnešní kapitolou včetně toho opraveného mapperu: kapitola21.zip.

Redakční systém RS::RS Předchozí kapitola

Zobrazení novinek

Redakční systém RS::RS Celý seriál

Vývoj redakčního systému v PHP

Redakční systém RS::RS Následující kapitola

Zobrazení fotogalerie

Komentáře (0)

Přidej svůj komentář

O mně

Jmenuji se Rudolf Svátek. Jsem lektor výpočetní techniky a PHP programátor. Stavím firemní stránky a eshopy. Aby se mi to dělalo pohodlně, vytvořil jsem redakční systém RS::RS, který ti tu nabízím k použití.

Rychlý kontakt na mně

  • Rudolf Svátek
  • Telefon:
    +420 777 828 353
  • Email:
  • Adresa:
    Josefa Hory 1097/5
    736 01 Havířov
    ČR



Tyto stránky používají Cookies. Používáním stránek s tím souhlasíte Další informace