Skip to content

Commit 3ab1d40

Browse files
committed
WIP: search extension
A new extension based on pagefind extension. Which allows full text search on static websites.
1 parent fa85a04 commit 3ab1d40

File tree

9 files changed

+291
-0
lines changed

9 files changed

+291
-0
lines changed

app/Custom.Dockerfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM phpdocumentor-guides
2+
3+
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
4+
5+
WORKDIR /app
6+
7+
RUN composer require phpdocumentor/guides-code phpdocumentor/guides-theme-bootstrap -W --prefer-dist
8+
9+
COPY ./packages/guides-search /tmp/guides-search
10+
11+
RUN composer config repositories.phpdocumentor/guides-search path /tmp/guides-search && \
12+
composer require phpdocumentor/guides-search:dev-main@dev

app/Dockerfile

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
FROM php:8.4-cli AS builder
2+
3+
COPY --from=ghcr.io/php/pie:bin /pie /usr/bin/pie
4+
5+
RUN export DEBIAN_FRONTEND="noninteractive"; \
6+
set -eux; \
7+
apt-get update; \
8+
apt-get install -y --no-install-recommends \
9+
unzip \
10+
curl \
11+
ca-certificates \
12+
build-essential \
13+
pkg-config \
14+
libssl-dev \
15+
libclang-dev \
16+
llvm-dev; \
17+
rm -rf /var/lib/apt/lists/*
18+
19+
ENV RUSTUP_HOME=/usr/local/rustup \
20+
CARGO_HOME=/usr/local/cargo \
21+
PATH=/usr/local/cargo/bin:$PATH \
22+
RUST_VERSION=1.82.0
23+
24+
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
25+
sh -s -- -y --profile minimal --default-toolchain ${RUST_VERSION} && \
26+
chmod -R a+w $RUSTUP_HOME $CARGO_HOME && \
27+
rustc --version && cargo --version
28+
29+
RUN pie install jaapio/pagefind:dev-main@dev
30+
31+
RUN rm -rf /usr/local/cargo/registry /usr/local/cargo/git
32+
33+
FROM php:8.4-cli AS application
34+
35+
COPY --from=builder /usr/local/lib/php /usr/local/lib/php
36+
37+
RUN echo "extension=pagefind" > /usr/local/etc/php/conf.d/pagefind.ini
38+
39+
RUN export DEBIAN_FRONTEND="noninteractive"; \
40+
set -eux; \
41+
apt-get update; \
42+
apt-get install -y --no-install-recommends \
43+
git \
44+
unzip; \
45+
rm -rf /var/lib/apt/lists/*
46+
47+
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
48+
49+
WORKDIR /app
50+
COPY composer.json composer.json
51+
52+
RUN composer install --no-dev --optimize-autoloader
53+
54+
# Production stage
55+
FROM php:8.4-cli AS production
56+
57+
WORKDIR /app
58+
59+
COPY --from=builder /usr/local/lib/php /usr/local/lib/php
60+
COPY --from=application /app /app
61+
62+
RUN export DEBIAN_FRONTEND="noninteractive"; \
63+
set -eux; \
64+
apt-get update; \
65+
apt-get install -y --no-install-recommends \
66+
libclang1 libzip-dev; \
67+
rm -rf /var/lib/apt/lists/*
68+
69+
RUN echo "extension=pagefind" > /usr/local/etc/php/conf.d/pagefind.ini
70+
RUN docker-php-ext-install zip
71+
72+
ENTRYPOINT ["php", "/app/vendor/bin/guides"]

app/composer.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "phpdocumentor/guides-app",
3+
"description": "phpDocumentor Guides CLI Application",
4+
"type": "project",
5+
"require": {
6+
"php": "^8.1",
7+
"ext-pagefind": "*",
8+
"phpdocumentor/guides-cli": "^1.8"
9+
},
10+
"minimum-stability": "dev",
11+
"prefer-stable": true,
12+
"config": {
13+
"sort-packages": true,
14+
"allow-plugins": {
15+
"composer/package-versions-deprecated": true
16+
}
17+
}
18+
}
19+

packages/guides-search/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2025 Jaap van Otterdijk
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

packages/guides-search/README.rst

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
.. image:: https://poser.pugx.org/phpdocumentor/guides-theme-bootstrap/require/php
3+
:alt: PHP Version Require
4+
:target: https://packagist.org/packages/phpdocumentor/guides-theme-bootstrap
5+
6+
.. image:: https://poser.pugx.org/phpdocumentor/guides-theme-bootstrap/v/stable
7+
:alt: Latest Stable Version
8+
:target: https://packagist.org/packages/phpdocumentor/guides-theme-bootstrap
9+
10+
.. image:: https://poser.pugx.org/phpdocumentor/guides-theme-bootstrap/v/unstable
11+
:alt: Latest Unstable Version
12+
:target: https://packagist.org/packages/phpdocumentor/guides-theme-bootstrap
13+
14+
.. image:: https://poser.pugx.org/phpdocumentor/guides-theme-bootstrap/d/total
15+
:alt: Total Downloads
16+
:target: https://packagist.org/packages/phpdocumentor/guides-theme-bootstrap
17+
18+
.. image:: https://poser.pugx.org/phpdocumentor/guides-theme-bootstrap/d/monthly
19+
:alt: Monthly Downloads
20+
:target: https://packagist.org/packages/phpdocumentor/guides-theme-bootstrap
21+
22+
====================================
23+
phpDocumentor Guides Bootstrap Theme
24+
====================================
25+
26+
This repository is part of `phpDocumentor's Guides library <https://github.com/phpDocumentor/guides>`__, a framework
27+
designed to take hand-written documentation in code repositories and create an AST (abstract syntax tree) from it.
28+
This AST is then fed to a renderer, which produces the desired output, such as HTML.
29+
30+
The package `phpdocumentor/guides-theme-bootstrap <https://packagist.org/packages/phpdocumentor/guides-theme-bootstrap>`__ adds
31+
`bootstrap theme <https://getbootstrap.com/>`__ to the
32+
phpDocumentor's Guides library.
33+
34+
:Mono-Repository: https://github.com/phpDocumentor/guides
35+
:Documentation: https://docs.phpdoc.org/components/guides/guides/index.html
36+
:Packagist: https://packagist.org/packages/phpdocumentor/guides-theme-bootstrap
37+
:Contribution: https://github.com/phpDocumentor/guides/tree/main/CONTRIBUTING.rst

packages/guides-search/composer.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "phpdocumentor/guides-search",
3+
"description": "Search extension for phpDocumentor Guides",
4+
"type": "library",
5+
"license": "MIT",
6+
"homepage": "https://www.phpdoc.org",
7+
"config": {
8+
"sort-packages": true
9+
},
10+
"autoload": {
11+
"psr-4": {
12+
"phpDocumentor\\Guides\\": "src/"
13+
}
14+
},
15+
"require": {
16+
"php": "^8.1",
17+
"phpdocumentor/guides": "^1.0 || ^2.0"
18+
},
19+
"extra": {
20+
"branch-alias": {
21+
"dev-main": "1.x-dev"
22+
}
23+
}
24+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use phpDocumentor\Guides\Event\PostRenderProcess;
6+
use phpDocumentor\Guides\Search\Indexer;
7+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
8+
9+
return static function (ContainerConfigurator $container): void {
10+
$container->services()
11+
->set(Indexer::class)
12+
->tag(
13+
'event_listener',
14+
['event' => PostRenderProcess::class, 'method' => 'index'],
15+
);
16+
};
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of phpDocumentor.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*
11+
* @link https://phpdoc.org
12+
*/
13+
14+
namespace phpDocumentor\Guides\Search\DependencyInjection;
15+
16+
use Symfony\Component\Config\FileLocator;
17+
use Symfony\Component\DependencyInjection\ContainerBuilder;
18+
use Symfony\Component\DependencyInjection\Extension\Extension;
19+
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
20+
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
21+
22+
use Symfony\Component\EventDispatcher\EventDispatcher;
23+
use function dirname;
24+
25+
final class SearchExtension extends Extension implements PrependExtensionInterface
26+
{
27+
/** @param mixed[] $configs */
28+
public function load(array $configs, ContainerBuilder $container): void
29+
{
30+
$loader = new PhpFileLoader(
31+
$container,
32+
new FileLocator(dirname(__DIR__, 3) . '/resources/config'),
33+
);
34+
$loader->load('guides-search.php');
35+
}
36+
37+
public function prepend(ContainerBuilder $container): void
38+
{
39+
}
40+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace phpDocumentor\Guides\Search;
6+
7+
use phpDocumentor\Guides\Event\PostRenderProcess;
8+
9+
final class Indexer
10+
{
11+
public function index(PostRenderProcess $postRenderProcess): void
12+
{
13+
$command = $postRenderProcess->getCommand();
14+
// Create a configuration
15+
$config = new \Pagefind\ServiceConfig(
16+
true, // keep URL
17+
true, // verbose mode
18+
'en' // fallback language (optional, defaults to 'en')
19+
);
20+
21+
$indexer = new \Pagefind\Indexer($config);
22+
$fileSystem = $command->getDestination();
23+
24+
foreach ($fileSystem->listContents($command->getDestinationPath(), true) as $file)
25+
{
26+
if ($file['type'] !== 'file') {
27+
continue;
28+
}
29+
30+
if (!str_ends_with($file['path'], '.html')) {
31+
continue;
32+
}
33+
34+
$content = $fileSystem->read($file['path']);
35+
if ($content === false) {
36+
continue;
37+
}
38+
39+
$indexer->addHtmlFile(
40+
$file['path'],
41+
$file['path'],
42+
$content
43+
);
44+
}
45+
46+
foreach ($indexer->getFiles() as $file) {
47+
$fileSystem->put('pagefind/' . $file->getFileName(), $file->getContents());
48+
}
49+
}
50+
}

0 commit comments

Comments
 (0)