diff --git a/composer.lock b/composer.lock index 72a28cb35..8c5d44f29 100644 --- a/composer.lock +++ b/composer.lock @@ -1597,16 +1597,16 @@ }, { "name": "symfony/cache", - "version": "v6.4.24", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "d038cd3054aeaf1c674022a77048b2ef6376a175" + "reference": "66c853ddcbf85c1984169869be498c3e7597b367" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/d038cd3054aeaf1c674022a77048b2ef6376a175", - "reference": "d038cd3054aeaf1c674022a77048b2ef6376a175", + "url": "https://api.github.com/repos/symfony/cache/zipball/66c853ddcbf85c1984169869be498c3e7597b367", + "reference": "66c853ddcbf85c1984169869be498c3e7597b367", "shasum": "" }, "require": { @@ -1673,7 +1673,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v6.4.24" + "source": "https://github.com/symfony/cache/tree/v6.4.26" }, "funding": [ { @@ -1693,7 +1693,7 @@ "type": "tidelift" } ], - "time": "2025-07-30T09:32:03+00:00" + "time": "2025-09-11T09:57:09+00:00" }, { "name": "symfony/cache-contracts", @@ -1773,16 +1773,16 @@ }, { "name": "symfony/config", - "version": "v6.4.24", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "80e2cf005cf17138c97193be0434cdcfd1b2212e" + "reference": "f18dc5926cb203e125956987def795d052ee774e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/80e2cf005cf17138c97193be0434cdcfd1b2212e", - "reference": "80e2cf005cf17138c97193be0434cdcfd1b2212e", + "url": "https://api.github.com/repos/symfony/config/zipball/f18dc5926cb203e125956987def795d052ee774e", + "reference": "f18dc5926cb203e125956987def795d052ee774e", "shasum": "" }, "require": { @@ -1828,7 +1828,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v6.4.24" + "source": "https://github.com/symfony/config/tree/v6.4.26" }, "funding": [ { @@ -1848,20 +1848,20 @@ "type": "tidelift" } ], - "time": "2025-07-26T13:50:30+00:00" + "time": "2025-09-11T09:57:09+00:00" }, { "name": "symfony/console", - "version": "v6.4.25", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "273fd29ff30ba0a88ca5fb83f7cf1ab69306adae" + "reference": "492de6dfd93910d7d7a729c5a04ddcd2b9e99c4f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/273fd29ff30ba0a88ca5fb83f7cf1ab69306adae", - "reference": "273fd29ff30ba0a88ca5fb83f7cf1ab69306adae", + "url": "https://api.github.com/repos/symfony/console/zipball/492de6dfd93910d7d7a729c5a04ddcd2b9e99c4f", + "reference": "492de6dfd93910d7d7a729c5a04ddcd2b9e99c4f", "shasum": "" }, "require": { @@ -1926,7 +1926,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.25" + "source": "https://github.com/symfony/console/tree/v6.4.26" }, "funding": [ { @@ -1946,7 +1946,7 @@ "type": "tidelift" } ], - "time": "2025-08-22T10:21:53+00:00" + "time": "2025-09-26T12:13:46+00:00" }, { "name": "symfony/css-selector", @@ -2224,16 +2224,16 @@ }, { "name": "symfony/intl", - "version": "v6.4.25", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "84dc64e179360927eed8f3403b4927aa70702c4f" + "reference": "0cd11e99e8c505f7ee7c6f0ccc8bccb8e14e652f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/84dc64e179360927eed8f3403b4927aa70702c4f", - "reference": "84dc64e179360927eed8f3403b4927aa70702c4f", + "url": "https://api.github.com/repos/symfony/intl/zipball/0cd11e99e8c505f7ee7c6f0ccc8bccb8e14e652f", + "reference": "0cd11e99e8c505f7ee7c6f0ccc8bccb8e14e652f", "shasum": "" }, "require": { @@ -2287,7 +2287,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v6.4.25" + "source": "https://github.com/symfony/intl/tree/v6.4.26" }, "funding": [ { @@ -2307,20 +2307,20 @@ "type": "tidelift" } ], - "time": "2025-08-19T13:57:48+00:00" + "time": "2025-09-07T21:26:26+00:00" }, { "name": "symfony/mime", - "version": "v6.4.24", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "664d5e844a2de5e11c8255d0aef6bc15a9660ac7" + "reference": "61ab9681cdfe315071eb4fa79b6ad6ab030a9235" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/664d5e844a2de5e11c8255d0aef6bc15a9660ac7", - "reference": "664d5e844a2de5e11c8255d0aef6bc15a9660ac7", + "url": "https://api.github.com/repos/symfony/mime/zipball/61ab9681cdfe315071eb4fa79b6ad6ab030a9235", + "reference": "61ab9681cdfe315071eb4fa79b6ad6ab030a9235", "shasum": "" }, "require": { @@ -2376,7 +2376,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.4.24" + "source": "https://github.com/symfony/mime/tree/v6.4.26" }, "funding": [ { @@ -2396,7 +2396,7 @@ "type": "tidelift" } ], - "time": "2025-07-15T12:02:45+00:00" + "time": "2025-09-16T08:22:30+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2990,16 +2990,16 @@ }, { "name": "symfony/process", - "version": "v6.4.25", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "6be2f0c9ab3428587c07bed03aa9e3d1b823c6c8" + "reference": "48bad913268c8cafabbf7034b39c8bb24fbc5ab8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/6be2f0c9ab3428587c07bed03aa9e3d1b823c6c8", - "reference": "6be2f0c9ab3428587c07bed03aa9e3d1b823c6c8", + "url": "https://api.github.com/repos/symfony/process/zipball/48bad913268c8cafabbf7034b39c8bb24fbc5ab8", + "reference": "48bad913268c8cafabbf7034b39c8bb24fbc5ab8", "shasum": "" }, "require": { @@ -3031,7 +3031,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.25" + "source": "https://github.com/symfony/process/tree/v6.4.26" }, "funding": [ { @@ -3051,7 +3051,7 @@ "type": "tidelift" } ], - "time": "2025-08-14T06:23:17+00:00" + "time": "2025-09-11T09:57:09+00:00" }, { "name": "symfony/property-access", @@ -3226,16 +3226,16 @@ }, { "name": "symfony/serializer", - "version": "v6.4.25", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "26f877808e20da1c0f8bc366d54c726003b0088b" + "reference": "48d0477483614d615aa1d5e5d90a45e4c7bfa2c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/26f877808e20da1c0f8bc366d54c726003b0088b", - "reference": "26f877808e20da1c0f8bc366d54c726003b0088b", + "url": "https://api.github.com/repos/symfony/serializer/zipball/48d0477483614d615aa1d5e5d90a45e4c7bfa2c9", + "reference": "48d0477483614d615aa1d5e5d90a45e4c7bfa2c9", "shasum": "" }, "require": { @@ -3304,7 +3304,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.4.25" + "source": "https://github.com/symfony/serializer/tree/v6.4.26" }, "funding": [ { @@ -3324,7 +3324,7 @@ "type": "tidelift" } ], - "time": "2025-08-27T11:31:57+00:00" + "time": "2025-09-15T13:37:27+00:00" }, { "name": "symfony/service-contracts", @@ -3411,16 +3411,16 @@ }, { "name": "symfony/string", - "version": "v6.4.25", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "7cdec7edfaf2cdd9c18901e35bcf9653d6209ff1" + "reference": "5621f039a71a11c87c106c1c598bdcd04a19aeea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/7cdec7edfaf2cdd9c18901e35bcf9653d6209ff1", - "reference": "7cdec7edfaf2cdd9c18901e35bcf9653d6209ff1", + "url": "https://api.github.com/repos/symfony/string/zipball/5621f039a71a11c87c106c1c598bdcd04a19aeea", + "reference": "5621f039a71a11c87c106c1c598bdcd04a19aeea", "shasum": "" }, "require": { @@ -3434,7 +3434,6 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0|^7.0", "symfony/http-client": "^5.4|^6.0|^7.0", "symfony/intl": "^6.2|^7.0", "symfony/translation-contracts": "^2.5|^3.0", @@ -3477,7 +3476,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.25" + "source": "https://github.com/symfony/string/tree/v6.4.26" }, "funding": [ { @@ -3497,20 +3496,20 @@ "type": "tidelift" } ], - "time": "2025-08-22T12:33:20+00:00" + "time": "2025-09-11T14:32:46+00:00" }, { "name": "symfony/translation", - "version": "v6.4.24", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "300b72643e89de0734d99a9e3f8494a3ef6936e1" + "reference": "c8559fe25c7ee7aa9d28f228903a46db008156a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/300b72643e89de0734d99a9e3f8494a3ef6936e1", - "reference": "300b72643e89de0734d99a9e3f8494a3ef6936e1", + "url": "https://api.github.com/repos/symfony/translation/zipball/c8559fe25c7ee7aa9d28f228903a46db008156a4", + "reference": "c8559fe25c7ee7aa9d28f228903a46db008156a4", "shasum": "" }, "require": { @@ -3576,7 +3575,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.4.24" + "source": "https://github.com/symfony/translation/tree/v6.4.26" }, "funding": [ { @@ -3596,7 +3595,7 @@ "type": "tidelift" } ], - "time": "2025-07-30T17:30:48+00:00" + "time": "2025-09-05T18:17:25+00:00" }, { "name": "symfony/translation-contracts", @@ -3791,16 +3790,16 @@ }, { "name": "symfony/validator", - "version": "v6.4.25", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "9352177c0e937793423053846f80bee805552324" + "reference": "3ed456b3cd04e61fc7ed2601805fee3c1130663a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/9352177c0e937793423053846f80bee805552324", - "reference": "9352177c0e937793423053846f80bee805552324", + "url": "https://api.github.com/repos/symfony/validator/zipball/3ed456b3cd04e61fc7ed2601805fee3c1130663a", + "reference": "3ed456b3cd04e61fc7ed2601805fee3c1130663a", "shasum": "" }, "require": { @@ -3868,7 +3867,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v6.4.25" + "source": "https://github.com/symfony/validator/tree/v6.4.26" }, "funding": [ { @@ -3888,20 +3887,20 @@ "type": "tidelift" } ], - "time": "2025-08-27T11:31:57+00:00" + "time": "2025-09-25T15:37:27+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.4.25", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "c6cd92486e9fc32506370822c57bc02353a5a92c" + "reference": "cfae1497a2f1eaad78dbc0590311c599c7178d4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c6cd92486e9fc32506370822c57bc02353a5a92c", - "reference": "c6cd92486e9fc32506370822c57bc02353a5a92c", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/cfae1497a2f1eaad78dbc0590311c599c7178d4a", + "reference": "cfae1497a2f1eaad78dbc0590311c599c7178d4a", "shasum": "" }, "require": { @@ -3956,7 +3955,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.25" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.26" }, "funding": [ { @@ -3976,20 +3975,20 @@ "type": "tidelift" } ], - "time": "2025-08-13T09:41:44+00:00" + "time": "2025-09-25T15:37:27+00:00" }, { "name": "symfony/var-exporter", - "version": "v6.4.25", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "4ff50a1b7c75d1d596aca50899d0c8c7e3de8358" + "reference": "466fcac5fa2e871f83d31173f80e9c2684743bfc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/4ff50a1b7c75d1d596aca50899d0c8c7e3de8358", - "reference": "4ff50a1b7c75d1d596aca50899d0c8c7e3de8358", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/466fcac5fa2e871f83d31173f80e9c2684743bfc", + "reference": "466fcac5fa2e871f83d31173f80e9c2684743bfc", "shasum": "" }, "require": { @@ -4037,7 +4036,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.4.25" + "source": "https://github.com/symfony/var-exporter/tree/v6.4.26" }, "funding": [ { @@ -4057,20 +4056,20 @@ "type": "tidelift" } ], - "time": "2025-08-18T13:06:32+00:00" + "time": "2025-09-11T09:57:09+00:00" }, { "name": "symfony/yaml", - "version": "v6.4.25", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "e54b060bc9c3dc3d4258bf0d165d0064e755f565" + "reference": "0fc8b966fd0dcaab544ae59bfc3a433f048c17b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e54b060bc9c3dc3d4258bf0d165d0064e755f565", - "reference": "e54b060bc9c3dc3d4258bf0d165d0064e755f565", + "url": "https://api.github.com/repos/symfony/yaml/zipball/0fc8b966fd0dcaab544ae59bfc3a433f048c17b0", + "reference": "0fc8b966fd0dcaab544ae59bfc3a433f048c17b0", "shasum": "" }, "require": { @@ -4113,7 +4112,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.25" + "source": "https://github.com/symfony/yaml/tree/v6.4.26" }, "funding": [ { @@ -4133,7 +4132,7 @@ "type": "tidelift" } ], - "time": "2025-08-26T16:59:00+00:00" + "time": "2025-09-26T15:07:38+00:00" }, { "name": "twig/cache-extra", @@ -5646,16 +5645,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.88.0", + "version": "v3.88.2", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "f23469674ae50d40e398bfff8018911a2a2b0dbe" + "reference": "a8d15584bafb0f0d9d938827840060fd4a3ebc99" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/f23469674ae50d40e398bfff8018911a2a2b0dbe", - "reference": "f23469674ae50d40e398bfff8018911a2a2b0dbe", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a8d15584bafb0f0d9d938827840060fd4a3ebc99", + "reference": "a8d15584bafb0f0d9d938827840060fd4a3ebc99", "shasum": "" }, "require": { @@ -5738,7 +5737,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.88.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.88.2" }, "funding": [ { @@ -5746,7 +5745,7 @@ "type": "github" } ], - "time": "2025-09-24T21:31:42+00:00" + "time": "2025-09-27T00:24:15+00:00" }, { "name": "justinrainbow/json-schema", @@ -8494,16 +8493,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v6.4.25", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "900da8a42eceeb4a13a0ec34caa7db49328daff3" + "reference": "5f311eaf0b321f8ec640f6bae12da43a14026898" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/900da8a42eceeb4a13a0ec34caa7db49328daff3", - "reference": "900da8a42eceeb4a13a0ec34caa7db49328daff3", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/5f311eaf0b321f8ec640f6bae12da43a14026898", + "reference": "5f311eaf0b321f8ec640f6bae12da43a14026898", "shasum": "" }, "require": { @@ -8555,7 +8554,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.4.25" + "source": "https://github.com/symfony/dependency-injection/tree/v6.4.26" }, "funding": [ { @@ -8575,7 +8574,7 @@ "type": "tidelift" } ], - "time": "2025-08-13T09:41:44+00:00" + "time": "2025-09-11T09:57:09+00:00" }, { "name": "symfony/event-dispatcher", diff --git a/src/Collection/Page/Page.php b/src/Collection/Page/Page.php index 7692020b7..e7f3a039f 100644 --- a/src/Collection/Page/Page.php +++ b/src/Collection/Page/Page.php @@ -83,7 +83,7 @@ public function __construct(mixed $id) throw new RuntimeException('Create a page with a string ID or a SplFileInfo.'); } - // default properties + // set default properties and variables $this->setVirtual(true); $this->setType(Type::PAGE->value); $this->setVariables([ @@ -96,6 +96,7 @@ public function __construct(mixed $id) 'content_template' => 'page.content.twig', ]); + // if file, create ID from its pathname if ($id instanceof SplFileInfo) { $file = $id; $this->setFile($file); @@ -154,40 +155,38 @@ public function getIdWithoutLang(): string public function setFile(SplFileInfo $file): self { $this->file = $file; - $this->setVirtual(false); - /* - * File path components - */ - $fileRelativePath = str_replace(DIRECTORY_SEPARATOR, '/', $this->file->getRelativePath()); - $fileExtension = $this->file->getExtension(); - $fileName = $this->file->getBasename('.' . $fileExtension); + $relativePath = str_replace(DIRECTORY_SEPARATOR, '/', $this->file->getRelativePath()); + $filename = $this->file->getFilenameWithoutExtension(); // renames "README" to "index" - $fileName = strtolower($fileName) == 'readme' ? 'index' : $fileName; - // case of "index" = home page - if (empty($this->file->getRelativePath()) && PrefixSuffix::sub($fileName) == 'index') { - $this->setType(Type::HOMEPAGE->value); - } - /* - * Set page properties and variables - */ - $this->setFolder($fileRelativePath); - $this->setSlug($fileName); + $filename = strtolower(PrefixSuffix::sub($filename)) == 'readme' ? 'index' : $filename; + + // set properties + $this->setVirtual(false); + $this->setFolder($relativePath); + $this->setSlug($filename); $this->setPath($this->getFolder() . '/' . $this->getSlug()); + // if "index" : type = section or homepage + if (PrefixSuffix::sub($filename) == 'index') { + // section by default + $this->setType(Type::SECTION->value); + // homepage + if (empty($this->file->getRelativePath())) { + $this->setType(Type::HOMEPAGE->value); + } + } + // set variables $this->setVariables([ - 'title' => PrefixSuffix::sub($fileName), + 'title' => PrefixSuffix::sub($filename), 'date' => (new \DateTime())->setTimestamp($this->file->getMTime()), 'updated' => (new \DateTime())->setTimestamp($this->file->getMTime()), 'filepath' => $this->file->getRelativePathname(), ]); - /* - * Set specific variables - */ - // is file has a prefix? - if (PrefixSuffix::hasPrefix($fileName)) { - $prefix = PrefixSuffix::getPrefix($fileName); + // if prefix : set weight or date + if (PrefixSuffix::hasPrefix($filename)) { + $prefix = PrefixSuffix::getPrefix($filename); if ($prefix !== null) { - // prefix is an integer: used for sorting + // prefix is an integer: weight (used for sorting) if (is_numeric($prefix)) { $this->setVariable('weight', (int) $prefix); } @@ -197,11 +196,11 @@ public function setFile(SplFileInfo $file): self } } } - // is file has a language suffix? - if (PrefixSuffix::hasSuffix($fileName)) { - $this->setVariable('language', PrefixSuffix::getSuffix($fileName)); + // if suffix : set language + if (PrefixSuffix::hasSuffix($filename)) { + $this->setVariable('language', PrefixSuffix::getSuffix($filename)); } - // set reference between page's translations, even if it exist in only one language + // set reference between page's translations (even if it exist in only one language) $this->setVariable('langref', $this->getPath()); return $this; @@ -346,14 +345,14 @@ public function setPath(string $path): self { $path = trim($path, '/'); - // case of homepage + // homepage : path is empty if ($path == 'index') { $this->path = ''; return $this; } - // case of custom sections' index (ie: section/index.md -> section) + // section/index : path = section if (substr($path, -6) == '/index') { $path = substr($path, 0, \strlen($path) - 6); } @@ -361,14 +360,14 @@ public function setPath(string $path): self $lastslash = strrpos($this->path, '/'); - // case of root/top-level pages + // top-level pages : slug = path if ($lastslash === false) { $this->slug = $this->path; return $this; } - // case of sections' pages: set section + // set section if (!$this->virtual && $this->getSection() === null) { $this->section = explode('/', $this->path)[0]; } @@ -680,24 +679,24 @@ public function getFmVariables(): array private static function createIdFromFile(SplFileInfo $file): string { $relativePath = self::slugify(str_replace(DIRECTORY_SEPARATOR, '/', $file->getRelativePath())); - $basename = self::slugify(PrefixSuffix::subPrefix($file->getBasename('.' . $file->getExtension()))); + $filename = self::slugify(PrefixSuffix::subPrefix($file->getFilenameWithoutExtension())); // if file is "README.md", ID is "index" - $basename = strtolower($basename) == 'readme' ? 'index' : $basename; - // if file is section's index: "section/index.md", ID is "section" - if (!empty($relativePath) && PrefixSuffix::sub($basename) == 'index') { - // case of a localized section's index: "section/index.fr.md", ID is "fr/section" - if (PrefixSuffix::hasSuffix($basename)) { - return PrefixSuffix::getSuffix($basename) . '/' . $relativePath; + $filename = strtolower($filename) == 'readme' ? 'index' : $filename; + // if file is section's index (ie: if file is "section/index.md", ID is "section") + if (!empty($relativePath) && PrefixSuffix::sub($filename) == 'index') { + // localized section (ie: if file is "section/index.fr.md", ID is "fr/section") + if (PrefixSuffix::hasSuffix($filename)) { + return PrefixSuffix::getSuffix($filename) . '/' . $relativePath; } return $relativePath; } - // localized page - if (PrefixSuffix::hasSuffix($basename)) { - return trim(Util::joinPath(PrefixSuffix::getSuffix($basename), $relativePath, PrefixSuffix::sub($basename)), '/'); + // localized page (ie: if file is "page.fr.md", ID is "fr/page") + if (PrefixSuffix::hasSuffix($filename)) { + return trim(Util::joinPath(PrefixSuffix::getSuffix($filename), $relativePath, PrefixSuffix::sub($filename)), '/'); } - return trim(Util::joinPath($relativePath, $basename), '/'); + return trim(Util::joinPath($relativePath, $filename), '/'); } /** diff --git a/src/Generator/Section.php b/src/Generator/Section.php index c3ec3b2e2..4833b3923 100644 --- a/src/Generator/Section.php +++ b/src/Generator/Section.php @@ -24,7 +24,7 @@ * This class is responsible for generating sections from the pages in the builder. * It identifies sections based on the 'section' variable in each page, and * creates a new page for each section. The generated pages are added to the - * collection of generated pages. It also handles sorting of subpages and + * collection of generated pages. It also handles sorting of sub-pages and * adding navigation links (next and previous) to the section pages. */ class Section extends AbstractGenerator implements GeneratorInterface diff --git a/src/Step/Pages/Load.php b/src/Step/Pages/Load.php index b2417aed0..85c6719bb 100644 --- a/src/Step/Pages/Load.php +++ b/src/Step/Pages/Load.php @@ -66,15 +66,22 @@ public function process(): void ->files() ->in($this->config->getPagesPath()) ->sort(function (SplFileInfo $a, SplFileInfo $b): int { + // root pages first + if (empty($a->getRelativePath()) && !empty($b->getRelativePath())) { + return -1; + } + if (empty($b->getRelativePath()) && !empty($a->getRelativePath())) { + return 1; + } // section's index first - if ($a->getRelativePath() == $b->getRelativePath() && $a->getBasename('.' . $a->getExtension()) == 'index') { + if ($a->getRelativePath() == $b->getRelativePath() && \in_array(strtolower($a->getFilenameWithoutExtension()), ['index', 'readme'])) { return -1; } - if ($b->getRelativePath() == $a->getRelativePath() && $b->getBasename('.' . $b->getExtension()) == 'index') { + if ($b->getRelativePath() == $a->getRelativePath() && \in_array(strtolower($b->getFilenameWithoutExtension()), ['index', 'readme'])) { return 1; } // sort by name - return strnatcasecmp($a->getRealPath(), $b->getRealPath()); + return strnatcasecmp($a->getRelativePath(), $b->getRelativePath()); }); // load only one page? if ($this->page) { diff --git a/tests/fixtures/website/layouts/page.html.twig b/tests/fixtures/website/layouts/page.html.twig index c563d851e..5471ac5e8 100644 --- a/tests/fixtures/website/layouts/page.html.twig +++ b/tests/fixtures/website/layouts/page.html.twig @@ -1 +1,24 @@ {% extends '_default/page.html.twig' %} + +{% block content %} + +{{ parent() }} + +{#- prev/next page ~#} +{%- if page.prev is defined or page.next is defined ~%} +

Navigation between pages of a section: + {%- if page.prev is defined ~%} + + ← {{ page.prev.title }} + + {%- endif -%} +  |  + {%- if page.next is defined ~%} + + {{ page.next.title }} → + + {%- endif ~%} +

+{%- endif ~%} + +{% endblock %} \ No newline at end of file diff --git a/tests/fixtures/website/pages/Section/folder/Sub section/index.md b/tests/fixtures/website/pages/Section/folder/Sub section/index.md new file mode 100644 index 000000000..1beba3635 --- /dev/null +++ b/tests/fixtures/website/pages/Section/folder/Sub section/index.md @@ -0,0 +1,5 @@ +--- +title: Sub section +--- + +Home > Section > (folder) > Sub section diff --git a/tests/fixtures/website/pages/Section/folder/Sub section/page-in-subsection.md b/tests/fixtures/website/pages/Section/folder/Sub section/page-in-subsection.md new file mode 100644 index 000000000..a944ef3a9 --- /dev/null +++ b/tests/fixtures/website/pages/Section/folder/Sub section/page-in-subsection.md @@ -0,0 +1,3 @@ +--- +title: Page in a sub section +--- diff --git a/tests/fixtures/website/themes/a-theme/layouts/project/page.html.twig b/tests/fixtures/website/themes/a-theme/layouts/project/page.html.twig index ac1fe0b8e..d77a4c677 100644 --- a/tests/fixtures/website/themes/a-theme/layouts/project/page.html.twig +++ b/tests/fixtures/website/themes/a-theme/layouts/project/page.html.twig @@ -1,7 +1,7 @@ -{% extends '_default/page.html.twig' %} +{% extends ['page.html.twig', '_default/page.html.twig'] %} {% block content %} -{{ page.content }} +{{ parent() }} Page from 'a-theme > layouts > project > page.html.twig' {% if page.categories is defined %}