Skip to content

Commit

Permalink
Merge pull request #1710 from hydephp/support-automatic-navigation-pr…
Browse files Browse the repository at this point in the history
…iorities-by-prefixing-a-number-in-filenames

[2.x] Improve the numerical filename priority prefix feature
  • Loading branch information
caendesilva authored Jun 4, 2024
2 parents 5b1446d + 0bcb133 commit 58774f7
Show file tree
Hide file tree
Showing 9 changed files with 539 additions and 211 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use Hyde\Framework\Factories\Concerns\CoreDataObject;
use Hyde\Framework\Features\Navigation\NavigationMenu;
use Hyde\Markdown\Contracts\FrontMatter\SubSchemas\NavigationSchema;
use Hyde\Framework\Features\Navigation\FilenamePrefixNavigationHelper;
use Hyde\Framework\Features\Navigation\NumericalPageOrderingHelper;

use function basename;
use function array_flip;
Expand Down Expand Up @@ -80,7 +80,9 @@ protected function makeLabel(): ?string
protected function makeGroup(): ?string
{
if ($this->pageIsInSubdirectory() && $this->canUseSubdirectoryForGroups()) {
return $this->getSubdirectoryName();
return NumericalPageOrderingHelper::hasNumericalPrefix($this->getSubdirectoryName())
? NumericalPageOrderingHelper::splitNumericPrefix($this->getSubdirectoryName())[1]
: $this->getSubdirectoryName();
}

return $this->searchForGroupInFrontMatter();
Expand Down Expand Up @@ -243,15 +245,15 @@ private function parseNavigationPriorityConfig(array $config, string $pageKeyNam

private function checkFilePrefixForOrder(): ?int
{
if (! FilenamePrefixNavigationHelper::enabled()) {
if (! NumericalPageOrderingHelper::enabled()) {
return null;
}

if (! FilenamePrefixNavigationHelper::isIdentifierNumbered($this->identifier)) {
if (! NumericalPageOrderingHelper::hasNumericalPrefix($this->identifier)) {
return null;
}

return FilenamePrefixNavigationHelper::splitNumberAndIdentifier($this->identifier)[0];
return NumericalPageOrderingHelper::splitNumericPrefix($this->identifier)[0];
}

private function canUseSubdirectoryForGroups(): bool
Expand Down

This file was deleted.

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

declare(strict_types=1);

namespace Hyde\Framework\Features\Navigation;

use Hyde\Facades\Config;
use Illuminate\Support\Str;

use function ltrim;
use function substr;
use function explode;
use function implode;
use function sprintf;
use function array_map;
use function preg_match;

/**
* @internal This class contains shared helper code for the framework to provide numerical page ordering.
* It is not intended to be used outside the framework code internals.
*/
class NumericalPageOrderingHelper
{
/** @var array<string> The delimiters that are used to separate the numerical prefix from the rest of the identifier. */
protected const DELIMITERS = ['-', '_'];

/** Check if the feature is enabled. */
public static function enabled(): bool
{
return Config::getBool('hyde.numerical_page_ordering', true);
}

/** Determines if a given identifier has a numerical prefix. */
public static function hasNumericalPrefix(string $identifier): bool
{
if (static::isIdentifierNested($identifier)) {
$identifier = static::getCoreIdentifierPart($identifier);
}

return preg_match(sprintf('/^\d+[%s]/', implode(static::DELIMITERS)), $identifier) === 1;
}

/**
* Splits a numbered identifier into its numerical prefix and the rest of the identifier.
*
* @return array{integer, string}
*/
public static function splitNumericPrefix(string $identifier): array
{
if (static::isIdentifierNested($identifier)) {
$parentPath = static::getNestedIdentifierPrefix($identifier);
$identifier = static::getCoreIdentifierPart($identifier);
}

$separator = static::getFirstCharacterFromIdentifier($identifier);
$parts = explode($separator, $identifier, 2);

$parts[0] = (int) $parts[0];

if (isset($parentPath)) {
$parentPaths = explode('/', $parentPath);
$parentPaths = array_map(function (string $part): string {
return static::hasNumericalPrefix($part) ? static::splitNumericPrefix($part)[1] : $part;
}, $parentPaths);
$parentPath = implode('/', $parentPaths);

$parts[1] = "$parentPath/$parts[1]";
}

return $parts;
}

protected static function isIdentifierNested(string $identifier): bool
{
return str_contains($identifier, '/');
}

protected static function getNestedIdentifierPrefix(string $identifier): string
{
return Str::beforeLast($identifier, '/');
}

protected static function getCoreIdentifierPart(string $identifier): string
{
return Str::afterLast($identifier, '/');
}

protected static function getFirstCharacterFromIdentifier(string $identifier): string
{
return substr(ltrim($identifier, '0123456789'), 0, 1);
}
}
6 changes: 3 additions & 3 deletions packages/framework/src/Support/Models/RouteKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Hyde\Support\Models;

use Stringable;
use Hyde\Framework\Features\Navigation\FilenamePrefixNavigationHelper;
use Hyde\Framework\Features\Navigation\NumericalPageOrderingHelper;

use function unslash;

Expand Down Expand Up @@ -56,8 +56,8 @@ public static function fromPage(string $pageClass, string $identifier): self
/** @experimental */
protected static function splitNumberedIdentifiersIfNeeded(string $identifier): string
{
if (FilenamePrefixNavigationHelper::enabled() && FilenamePrefixNavigationHelper::isIdentifierNumbered($identifier)) {
$identifier = FilenamePrefixNavigationHelper::splitNumberAndIdentifier($identifier)[1];
if (NumericalPageOrderingHelper::enabled() && NumericalPageOrderingHelper::hasNumericalPrefix($identifier)) {
return NumericalPageOrderingHelper::splitNumericPrefix($identifier)[1];
}

return $identifier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,15 @@
* The feature can be disabled in the config. It also works within sidebar groups,
* so that multiple groups can have the same prefix independent of other groups.
*
* @covers \Hyde\Framework\Features\Navigation\FilenamePrefixNavigationHelper
* @covers \Hyde\Framework\Features\Navigation\NumericalPageOrderingHelper
* @covers \Hyde\Framework\Features\Navigation\MainNavigationMenu
* @covers \Hyde\Framework\Features\Navigation\DocumentationSidebar
* @covers \Hyde\Framework\Factories\NavigationDataFactory // Todo: Update the unit test for this class.
* @covers \Hyde\Support\Models\RouteKey // Todo: Update the unit test for this class.
* @covers \Hyde\Framework\Factories\NavigationDataFactory
* @covers \Hyde\Support\Models\RouteKey
*
* @see \Hyde\Framework\Testing\Unit\FilenamePrefixNavigationPriorityUnitTest
*
* Todo: Add test to ensure explicitly set priority overrides filename prefix.
* @see \Hyde\Framework\Testing\Unit\NumericalPageOrderingHelperUnitTest
*/
class FilenamePrefixNavigationPriorityTest extends TestCase
class NumericalPageOrderingHelperTest extends TestCase
{
protected function setUp(): void
{
Expand Down Expand Up @@ -251,6 +249,34 @@ public function testOrderingWithDifferentFileExtensions()
$this->assertOrder(['foo', 'bar', 'baz']);
}

public function testSidebarGroupPrioritiesCanBeSetWithNumericalPrefix()
{
$this->directory('_docs/03-getting-started');
$this->file('_docs/03-getting-started/05-advanced.md');

$page = DocumentationPage::parse('03-getting-started/05-advanced');
$this->assertInstanceOf(DocumentationPage::class, $page);

$this->assertSame('docs/advanced', $page->getRouteKey());
$this->assertSame('docs/advanced.html', $page->getOutputPath());
$this->assertSame('getting-started', $page->navigationMenuGroup());
}

public function testSidebarGroupPrioritiesCanBeSetWithNumericalPrefixWithoutFlattenedOutputPaths()
{
config(['docs.flattened_output_paths' => false]);

$this->directory('_docs/03-getting-started');
$this->file('_docs/03-getting-started/05-advanced.md');

$page = DocumentationPage::parse('03-getting-started/05-advanced');
$this->assertInstanceOf(DocumentationPage::class, $page);

$this->assertSame('docs/getting-started/advanced', $page->getRouteKey());
$this->assertSame('docs/getting-started/advanced.html', $page->getOutputPath());
$this->assertSame('getting-started', $page->navigationMenuGroup());
}

protected function setUpSidebarFixture(array $files): self
{
return $this->setupFixture($files, sidebar: true);
Expand Down Expand Up @@ -291,9 +317,9 @@ protected function arrayReverseRecursive(array $array): array

class FilenamePrefixNavigationPriorityTestingHelper
{
protected FilenamePrefixNavigationPriorityTest $test;
protected NumericalPageOrderingHelperTest $test;

public function __construct(FilenamePrefixNavigationPriorityTest $test)
public function __construct(NumericalPageOrderingHelperTest $test)
{
$this->test = $test;
}
Expand Down
Loading

0 comments on commit 58774f7

Please sign in to comment.