Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.x] Rewrite documentation search page internals to be based on dynamic pages instead of a build task #1498

Merged
merged 70 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
4e3a0c2
Deprecate GenerateSearch.php
caendesilva Dec 13, 2023
d9eec28
Add new internal `GeneratesDocumentationSearchIndex::generate` method
caendesilva Dec 13, 2023
feb99e9
Deprecate internal `GeneratesDocumentationSearchIndex::handle` method
caendesilva Dec 13, 2023
697e016
Add experimental `InMemoryPage::getOutputPath` overload support
caendesilva Dec 13, 2023
002f716
Merge branch '2.x-dev' into v2/refactor-search-index-handling
caendesilva Dec 13, 2023
9bee9cd
Update build task service to not call deprecated search generator
caendesilva Dec 13, 2023
c8937ad
Update core extension to add search index as an in memory page
caendesilva Dec 13, 2023
30f3ce6
Update core extension to inject search page during discovery
caendesilva Dec 13, 2023
733b95f
Hide dynamic search pages from navigation
caendesilva Dec 13, 2023
8bfe35e
Run tests without documentation search feature
caendesilva Dec 13, 2023
f55ad51
Hide the search page from sidebar generation
caendesilva Dec 13, 2023
ba44d87
Test documentation search sitemap integration
caendesilva Dec 13, 2023
c45a64e
Remove blanket assertion
caendesilva Dec 13, 2023
49de93d
Update RELEASE_NOTES.md
caendesilva Dec 13, 2023
d438c43
Merge branch '2.x-dev' into v2/refactor-search-index-handling
caendesilva Dec 13, 2023
5728f7a
Extract helper method
caendesilva Dec 14, 2023
3cb7f40
Make search index page exclusion dependent on config setting
caendesilva Dec 14, 2023
86063e0
Merge branch '2.x-dev' into v2/refactor-search-index-handling
caendesilva Dec 14, 2023
bd14049
Extract experimental helper method
caendesilva Dec 14, 2023
cdc37f3
Merge branch '2.x-dev' into v2/refactor-search-index-handling
caendesilva Dec 14, 2023
e6e0093
Merge branch '2.x-dev' into v2/refactor-search-index-handling
caendesilva Dec 14, 2023
158c6f2
Update build search command to use new search page system
caendesilva Dec 14, 2023
873b928
Support getting the search page from the kernel
caendesilva Dec 14, 2023
4f91f82
Simplify logic to use nullable helper
caendesilva Dec 14, 2023
e80cbb2
Inline simplified helper method
caendesilva Dec 14, 2023
03f7fd8
Get the search page from the kernel as well
caendesilva Dec 14, 2023
b021766
Clean up test method
caendesilva Dec 14, 2023
799d51f
Extract a model class for the documentation search index
caendesilva Dec 14, 2023
76c1c3e
Remove unused method
caendesilva Dec 14, 2023
44e97cd
Merge in source directory prefix for search index identifier
caendesilva Dec 14, 2023
01cba90
Trim leading slashes from assembled paths
caendesilva Dec 14, 2023
57bdecb
Inline added simplified experimental method
caendesilva Dec 14, 2023
cca3610
Change constructor style
caendesilva Dec 14, 2023
37f7046
Refractor internal search page to extend in memory page
caendesilva Dec 14, 2023
34ba855
Update documentation article component to support existing variables
caendesilva Dec 15, 2023
e6f6a98
Update search page to mock document
caendesilva Dec 15, 2023
b6eca70
Fix added search index page should include docs prefix
caendesilva Dec 15, 2023
6c932a1
Deprecate internal logic to be removed within refactor
caendesilva Dec 15, 2023
4556eed
Fix wrong method used to emulate route key
caendesilva Dec 15, 2023
790689e
Create DocumentationSearchIndexTest.php
caendesilva Dec 15, 2023
37c2dde
Add coverage annotation
caendesilva Dec 15, 2023
38608b8
Remove hacky route injection in favour of new search page implementation
caendesilva Dec 15, 2023
9c10059
Update test to use new search page implementation
caendesilva Dec 15, 2023
0838ab4
Remove internal `DocumentationSearchPage::routeKey()` method
caendesilva Dec 15, 2023
82dc71f
Add improved conditional to fix override priority
caendesilva Dec 15, 2023
53d41b8
Update RELEASE_NOTES.md
caendesilva Dec 16, 2023
3bad913
Breaking: Remove the GenerateSearch build task
caendesilva Dec 17, 2023
aeeed9f
Cleanup and improve release notes
caendesilva Dec 17, 2023
e43d6e8
Improve code comment
caendesilva Dec 18, 2023
32a1ee5
Use helper method with same code
caendesilva Dec 18, 2023
eb07152
Revert "Remove internal `DocumentationSearchPage::routeKey()` method"
caendesilva Dec 18, 2023
ef0fa70
Revert internal deprecation
caendesilva Dec 18, 2023
883c09d
Move up public method
caendesilva Dec 18, 2023
89c6352
Import used function
caendesilva Dec 18, 2023
0f8fe02
Fix missing trim argument
caendesilva Dec 18, 2023
b7a2537
Extract internal route key helper
caendesilva Dec 18, 2023
2d46f6b
Revert "Add experimental `InMemoryPage::getOutputPath` overload support"
caendesilva Dec 18, 2023
d86f543
Replace instance override with static
caendesilva Dec 18, 2023
a33a3f5
Refactor to use RouteKey helper
caendesilva Dec 18, 2023
076c398
Add default value to make parameter optional
caendesilva Dec 18, 2023
be553d7
Shift logic to different internal helper
caendesilva Dec 18, 2023
83cfa5a
Inline simplified helper
caendesilva Dec 18, 2023
d81a2ab
Use the RouteKey helper
caendesilva Dec 18, 2023
aa62516
Revert "Deprecate internal `GeneratesDocumentationSearchIndex::handle…
caendesilva Dec 18, 2023
02ed17d
Revert "Add new internal `GeneratesDocumentationSearchIndex::generate…
caendesilva Dec 18, 2023
1c37851
Change internal search generator method to return JSON directly
caendesilva Dec 18, 2023
b868613
Format long line
caendesilva Dec 19, 2023
f72e503
Remove legacy assertions
caendesilva Dec 19, 2023
4942992
Merge branch 'master' into v2/refactor-search-index-handling
caendesilva Dec 23, 2023
99a235f
Merge branch '2.x-dev' into v2/refactor-search-index-handling
caendesilva Jan 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 31 additions & 3 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ This serves two purposes:
2. At release time, you can move the Unreleased section changes into a new release version section.

### Added
- for new features.
- Add experimental `InMemoryPage::getOutputPath` overload support
caendesilva marked this conversation as resolved.
Show resolved Hide resolved

### Changed
- for changes in existing functionality.
- Changed how the documentation search is generated, to be an `InMemoryPage` instead of a post-build task.
- Updated the documentation article component to support existing `$document` instance.
caendesilva marked this conversation as resolved.
Show resolved Hide resolved

### Deprecated
- for soon-to-be removed features.

### Removed
- for now removed features.
- Breaking: Removed the build task `\Hyde\Framework\Actions\PostBuildTasks\GenerateSearch` (see upgrade guide below)

### Fixed
- for any bug fixes.
Expand All @@ -30,3 +31,30 @@ This serves two purposes:
### Upgrade Guide

If there are any breaking changes, include an upgrade guide here.

#### Documentation search page changes

The documentation search page and search index have been changed to be generated as `InMemoryPages` instead of a post-build task.

The main impact noticeable to most users by this is the implicit changes, like the pages showing up in the dashboard and route list command.

In case you have customized the `GenerateSearch` post-build task you may, depending on what you were trying to do,
want to adapt your code to interact with the new `InMemoryPage`, which is generated in the `HydeCoreExtension` class.

For more information, see https://github.com/hydephp/develop/pull/1498.

### Breaking changes

#### Low impact

- The `GenerateSearch` post-build task has been removed. If you have previously extended or customized this class,
you will need to adapt your code, as the search index files are now handled implicitly during the standard build process,
as the search pages are now added to the kernel page and route collection. (https://github.com/hydephp/develop/pull/1498)

- If your site has a custom documentation search page, for example `_docs/search.md` or `_pages/docs/search.blade.php`,
that page will no longer be built when using the specific `build:search` command. It will, of course,
be built using the standard `build` command. https://github.com/hydephp/develop/commit/82dc71f4a0e7b6be7a9f8d822fbebe39d2289ced
-
- In the highly unlikely event your site customizes any of the search pages by replacing them in the kernel route collection,
you would now need to do that in the kernel page collection due to the search pages being generated earlier in the lifecycle.
https://github.com/hydephp/develop/commit/82dc71f4a0e7b6be7a9f8d822fbebe39d2289ced
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@php
$document = \Hyde\Framework\Features\Documentation\SemanticDocumentationArticle::make($page);
$document ??= \Hyde\Framework\Features\Documentation\SemanticDocumentationArticle::make($page);
caendesilva marked this conversation as resolved.
Show resolved Hide resolved
@endphp

<article id="document" itemscope itemtype="https://schema.org/Article" @class([
Expand Down
13 changes: 11 additions & 2 deletions packages/framework/src/Console/Commands/BuildSearchCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

namespace Hyde\Console\Commands;

use Hyde\Framework\Actions\PostBuildTasks\GenerateSearch;
use Hyde\Foundation\Facades\Pages;
use Hyde\Framework\Actions\StaticPageBuilder;
use LaravelZero\Framework\Commands\Command;
use Hyde\Framework\Features\Documentation\DocumentationSearchPage;
use Hyde\Framework\Features\Documentation\DocumentationSearchIndex;

/**
* Run the build process for the documentation search index.
Expand All @@ -20,6 +23,12 @@ class BuildSearchCommand extends Command

public function handle(): int
{
return (new GenerateSearch())->run($this->output);
StaticPageBuilder::handle(Pages::get('docs/search.json') ?? new DocumentationSearchIndex());

if (DocumentationSearchPage::enabled()) {
StaticPageBuilder::handle(Pages::get('docs/search') ?? new DocumentationSearchPage());
}

return Command::SUCCESS;
}
}
14 changes: 14 additions & 0 deletions packages/framework/src/Foundation/HydeCoreExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
use Hyde\Pages\MarkdownPage;
use Hyde\Pages\MarkdownPost;
use Hyde\Pages\DocumentationPage;
use Hyde\Foundation\Kernel\PageCollection;
use Hyde\Foundation\Concerns\HydeExtension;
use Hyde\Facades\Features;
use Hyde\Framework\Features\Documentation\DocumentationSearchPage;
use Hyde\Framework\Features\Documentation\DocumentationSearchIndex;

use function array_filter;
use function array_keys;
Expand All @@ -28,4 +31,15 @@ public static function getPageClasses(): array
DocumentationPage::class => Features::hasDocumentationPages(),
], fn (bool $value): bool => $value));
}

public function discoverPages(PageCollection $collection): void
{
if (Features::hasDocumentationSearch()) {
$collection->addPage(new DocumentationSearchIndex());

if (DocumentationSearchPage::enabled()) {
$collection->addPage(new DocumentationSearchPage());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class GeneratesDocumentationSearchIndex
protected string $path;

/**
* Generate the search index and save it to disk.
* @deprecated Generate the search index and save it to disk.
*
* @return string The path to the generated file.
*/
Expand All @@ -39,6 +39,17 @@ public static function handle(): string
return $service->path;
}

/**
* Generate the search index return it as a string.
*/
public static function generate(): string
{
$service = new static();
$service->run();

return $service->index->toJson();
}

protected function __construct()
{
$this->index = new Collection();
Expand All @@ -48,7 +59,7 @@ protected function __construct()
protected function run(): void
{
DocumentationPage::all()->each(function (DocumentationPage $page): void {
if (! in_array($page->identifier, Config::getArray('docs.exclude_from_search', []))) {
if (! in_array($page->identifier, $this->getPagesToExcludeFromSearch())) {
$this->index->push($this->generatePageEntry($page));
}
});
Expand Down Expand Up @@ -92,4 +103,9 @@ protected function getPath(): string
{
return Hyde::sitePath(DocumentationPage::outputDirectory().'/search.json');
}

protected function getPagesToExcludeFromSearch(): array
{
return array_merge(Config::getArray('docs.exclude_from_search', []), Config::getBool('docs.create_search_page', true) ? ['search'] : []);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace Hyde\Framework\Features\Documentation;

use Hyde\Pages\InMemoryPage;
use Hyde\Pages\DocumentationPage;
use Hyde\Framework\Actions\GeneratesDocumentationSearchIndex;

/**
* @internal This page is used to render the search index for the documentation.
*/
class DocumentationSearchIndex extends InMemoryPage
{
/**
* Create a new DocumentationSearchPage instance.
*/
public function __construct()
{
parent::__construct(ltrim(DocumentationPage::outputDirectory().'/search.json', '/'), [
'navigation' => ['hidden' => true],
]);
}

public function compile(): string
{
return GeneratesDocumentationSearchIndex::generate();
}

public function getOutputPath(): string
{
return ltrim(DocumentationPage::outputDirectory().'/search.json', '/');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
namespace Hyde\Framework\Features\Documentation;

use Hyde\Hyde;
use Hyde\Pages\InMemoryPage;
use Hyde\Pages\DocumentationPage;
use Hyde\Pages\Concerns\HydePage;
use Hyde\Framework\Actions\StaticPageBuilder;
use Hyde\Facades\Config;
use Illuminate\Support\Facades\View;

/**
* @internal This page is used to render the search page for the documentation.
Expand All @@ -17,7 +18,7 @@
* If you want to override this page, you can create a page with the route key "docs/search",
* then this class will not be applied. For example, `_pages/docs/search.blade.php`.
*/
class DocumentationSearchPage extends DocumentationPage
class DocumentationSearchPage extends InMemoryPage
{
/**
* Generate the search page and save it to disk.
Expand All @@ -34,23 +35,32 @@ public static function generate(): string
*/
public function __construct()
{
parent::__construct('search', [
parent::__construct(ltrim(DocumentationPage::outputDirectory().'/search', '/'), [
'title' => 'Search',
]);
'navigation' => ['hidden' => true],
'document' => $this->makeDocument(),
], view: 'hyde::pages.documentation-search');
}

public function compile(): string
public static function enabled(): bool
{
return View::make('hyde::pages.documentation-search')->render();
return Config::getBool('docs.create_search_page', true) && ! static::anotherSearchPageExists();
}

public static function enabled(): bool
protected static function anotherSearchPageExists(): bool
{
// Since routes aren't discovered yet, we need to check the pages directly
return Hyde::pages()->first(fn (HydePage $file): bool => $file->getRouteKey() === static::routeKey()) !== null;
}

protected static function routeKey(): string
{
return Config::getBool('docs.create_search_page', true) && ! Hyde::routes()->has(self::routeKey());
return ltrim(DocumentationPage::outputDirectory().'/search');
}

public static function routeKey(): string
/** @experimental Fixes type issue {@see https://github.com/hydephp/develop/commit/37f7046251b8c0514b8d8ef821de4ef3d35bbac8#commitcomment-135026537} */
protected function makeDocument(): SemanticDocumentationArticle
{
return parent::outputDirectory().'/search';
return SemanticDocumentationArticle::make(new DocumentationPage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use Hyde\Framework\Features\BuildTasks\PreBuildTask;
use Hyde\Framework\Features\BuildTasks\PostBuildTask;
use Hyde\Framework\Actions\PreBuildTasks\CleanSiteDirectory;
use Hyde\Framework\Actions\PostBuildTasks\GenerateSearch;
use Hyde\Framework\Actions\PostBuildTasks\GenerateRssFeed;
use Hyde\Framework\Actions\PostBuildTasks\GenerateSitemap;
use Hyde\Framework\Actions\PostBuildTasks\GenerateBuildManifest;
Expand Down Expand Up @@ -136,7 +135,6 @@ private function registerFrameworkTasks(): void
$this->registerIf(GenerateBuildManifest::class, $this->canGenerateManifest());
$this->registerIf(GenerateSitemap::class, $this->canGenerateSitemap());
$this->registerIf(GenerateRssFeed::class, $this->canGenerateFeed());
$this->registerIf(GenerateSearch::class, $this->canGenerateSearch());
}

private function canCleanSiteDirectory(): bool
Expand All @@ -158,9 +156,4 @@ private function canGenerateFeed(): bool
{
return Features::rss();
}

private function canGenerateSearch(): bool
{
return Features::hasDocumentationSearch();
}
}
10 changes: 10 additions & 0 deletions packages/framework/src/Pages/InMemoryPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ public function getBladeView(): string
return $this->view;
}

/** @experimental Get the path to the output file for the page. */
public function getOutputPath(): string
{
if ($this->hasMacro('getOutputPath')) {
return $this->__call('getOutputPath', []);
}

return parent::getOutputPath();
}

/**
* Get the contents that will be saved to disk for this page.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@

use Hyde\Facades\Filesystem;
use Hyde\Hyde;
use Hyde\Pages\InMemoryPage;
use Hyde\Pages\DocumentationPage;
use Hyde\Testing\TestCase;

/**
* @covers \Hyde\Console\Commands\BuildSearchCommand
* @covers \Hyde\Framework\Actions\PostBuildTasks\GenerateSearch
* @covers \Hyde\Framework\Features\Documentation\DocumentationSearchPage
* @covers \Hyde\Framework\Features\Documentation\DocumentationSearchIndex
*/
class BuildSearchCommandTest extends TestCase
{
Expand Down Expand Up @@ -103,4 +104,27 @@ public function test_search_files_can_be_generated_for_custom_site_and_nested_do

Filesystem::deleteDirectory('foo');
}

public function test_command_uses_search_pages_from_kernel_when_present()
{
Hyde::pages()->addPage(tap(new InMemoryPage('docs/search.json'), function (InMemoryPage $page): void {
$page->macro('compile', fn () => '{"foo":"bar"}');
$page->macro('getOutputPath', fn () => 'docs/search.json');
}));

Hyde::pages()->addPage(tap(new InMemoryPage('docs/search'), function (InMemoryPage $page): void {
$page->macro('compile', fn () => 'Foo');
}));

$this->artisan('build:search')->assertExitCode(0);

$this->assertFileExists(Hyde::path('_site/docs/search.json'));
// $this->assertFileExists(Hyde::path('_site/docs/search.html'));

$this->assertSame('{"foo":"bar"}', Filesystem::getContents('_site/docs/search.json'));
// $this->assertSame('Foo', Filesystem::getContents('_site/docs/search.html'));

Filesystem::unlink('_site/docs/search.json');
// Filesystem::unlink('_site/docs/search.html');
}
}
Loading