kiwa / page-search
Add a page search functionality to your kiwa project.
Fund package maintenance!
Buymeacoffee
Requires
- php: ^8.2
- ext-dom: *
- bitandblack/helpers: ^2.0
- kiwa/console: ^0
- kiwa/core: ^0
- psr/log: ^2.0 || ^3.0
Requires (Dev)
- phpstan/phpstan: ^1.0
- phpunit/phpunit: ^11.0
- rector/rector: ^1.0
- symfony/var-dumper: ^7.0
- symplify/easy-coding-standard: ^12.0
README
Kiwa Page Search
Add a page search functionality to your Kiwa project.
Installation
This library is made for the use with Composer. Add it to your project by running $ composer require kiwa/page-search
.
Usage
Implementing a page search on your website requires a few steps.
1. Using a traditional form
1.1 Setting up the HTML form
At first, you need a form where website visitors may enter a search term and submit it. This can look like that:
<form action="" method="get">
<input type="search" placeholder="Search ..." name="q" id="search" required autofocus>
<label for="search">
<button type="submit">Search</button>
</label>
</form>
How you implement that, how you want to style your form and anything else is up to you.
1.2 Handling the search term and sending a result
Now you need a page, that handles the request. Following our example above, it will be the same page, but this is not required.
Here comes the part that this library provides.
1.2.1 Receive the search term from the request:
<?php
use Kiwa\DI;
$searchTerm = DI::getRequest()->query->get('q');
Think about making the request safer by using the htmlspecialchars
function.
1.2.2 Initialize the PageSearch
class with your search term:
<?php
use Kiwa\PageSearch\PageSearch;
$pageSearch = new PageSearch($searchTerm);
You can exclude pages from the search by using the excludeFromSearch
method:
<?php
use Kiwa\URL\URLFromFile;
$pageSearch->excludeFromSearch(
new URLFromFile('imprint'),
new URLFromFile('login'),
// and whatever more...
);
To actually start the search, you need to call
<?php
$pageSearch->search();
1.2.3 Get the results and display them
Now you can get the search result by calling the getMatches
method. It will return an array of SearchResult
objects that contain information about the page.
<?php
$matches = $pageSearch->getMatches();
All together it may look like that:
<?php
use Kiwa\DI;
use Kiwa\PageSearch\PageSearch;
use Kiwa\PageSearch\SearchResult;
use Kiwa\URL\URLFromFile;
$searchTerm = DI::getRequest()->query->get('q');
/** @var array<int, SearchResult> $matches */
$matches = [];
if (true === is_string($searchTerm)) {
$searchTerm = htmlspecialchars($searchTerm);
$pageSearch = new PageSearch($searchTerm);
$pageSearch
->setLogger(DI::getLog())
->excludeFromSearch(
new URLFromFile('imprint'),
new URLFromFile('login'),
)
->search()
;
$matches = $pageSearch->getMatches();
}
foreach ($matches as $match) {
$url = $match->getUrl();
$title = $match->getTitle();
$preview = $match->getPreview();
// Create some HTML and display the results here...
}
2. Performing asynchronous searches
If you want to implement an asynchronous search, you need some JavaScript and end endpoint for it.
2.1 Creating an endpoint
Add a page to your /public
folder, that can take the AJAX requests, perform the search, and send some JSON back. It may, for example, be named pagesearch.php
and could look like that:
<?php
use App\PageSearchFactory;
use Kiwa\DI;
require_once '../../vendor/autoload.php';
/**
* Change the content type if the response into JSON.
*/
DI::getResponse()->headers->set('content-type', 'application/json');
$searchTerm = DI::getRequest()->query->get('q');
/**
* Send and empty response in case the search term is missing.
*/
if (false === is_string($searchTerm)) {
echo json_encode([]);
return;
}
/**
* Initialize the PageSearch as described earlier.
* This has been striped here to make the code easier to understand...
*/
//$pageSearch = ...
/**
* Define your response here and finally send it back.
*/
$response = [
'matches' => array_values(
$pageSearch->getMatches()
),
];
echo json_encode($response, JSON_PRETTY_PRINT);
2.2 Sending the search term via AJAX
Now you have to implement some JavaScript to handle the form submit and send a request to your endpoint. This could look like that:
const handleSubmit = (event) => {
const searchTerm = event.target.value;
const results = fetch(`/pagesearch.php?q=${searchTerm}`)
.then((result) => {
return result.json();
})
;
// Do something with the results...
};
const form = document.querySelector("form");
form.addEventListener("submit", handleSubmit);
3. Using a PageSearch Factory
If you are using a traditional search form along with a asynchronous way, we recommend creating a PageSearch Factory using the Factory pattern.
Help
If you have any questions, feel free to contact us under hello@bitandblack.com
.
Further information about Bit&Black can be found under www.bitandblack.com.