From 1ed316c7f0d3664f61f626827af96aa38219fb6c Mon Sep 17 00:00:00 2001 From: Emma De Silva Date: Sun, 12 Jul 2026 03:43:33 +0200 Subject: [PATCH 01/15] Require the Illuminate Translation package --- composer.lock | 60 +++++++++++++++++++++++++++++--- packages/framework/composer.json | 1 + 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index e99534abeaa..5f761cd6d3e 100644 --- a/composer.lock +++ b/composer.lock @@ -997,6 +997,7 @@ "require": { "hydephp/torchlight-commonmark": "^1.0", "illuminate/support": "^11.0", + "illuminate/translation": "^11.0", "illuminate/view": "^11.0", "league/commonmark": "^2.2", "php": "^8.2", @@ -1038,7 +1039,7 @@ }, { "name": "hyde/ui-kit", - "version": "dev-remove-publications", + "version": "dev-master", "dist": { "type": "path", "url": "./packages/ui-kit", @@ -2099,6 +2100,57 @@ }, "time": "2025-05-19T12:53:09+00:00" }, + { + "name": "illuminate/translation", + "version": "v11.51.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/translation.git", + "reference": "de64584470b1d4bfc30f2c291585b873ce844ecf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/translation/zipball/de64584470b1d4bfc30f2c291585b873ce844ecf", + "reference": "de64584470b1d4bfc30f2c291585b873ce844ecf", + "shasum": "" + }, + "require": { + "illuminate/collections": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/filesystem": "^11.0", + "illuminate/macroable": "^11.0", + "illuminate/support": "^11.0", + "php": "^8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Translation\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Translation package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2025-02-14T15:47:05+00:00" + }, { "name": "illuminate/view", "version": "v11.45.2", @@ -6883,7 +6935,7 @@ }, { "name": "hyde/monorepo-dev-tools", - "version": "dev-remove-publications", + "version": "dev-master", "dist": { "type": "path", "url": "./monorepo/DevTools", @@ -6913,7 +6965,7 @@ "dist": { "type": "path", "url": "./packages/realtime-compiler", - "reference": "dd4172f14d8d59e3de65a675132510c3095c947c" + "reference": "781f00bf731ff78845452a243cf305cdc11c2226" }, "require": { "desilva/microserve": "^2.0", @@ -6965,7 +7017,7 @@ }, { "name": "hyde/testing", - "version": "dev-remove-publications", + "version": "dev-master", "dist": { "type": "path", "url": "./packages/testing", diff --git a/packages/framework/composer.json b/packages/framework/composer.json index 1ef131b128f..5e6d547c039 100644 --- a/packages/framework/composer.json +++ b/packages/framework/composer.json @@ -25,6 +25,7 @@ "php": "^8.2", "illuminate/support": "^11.0", "illuminate/view": "^11.0", + "illuminate/translation": "^11.0", "symfony/yaml": "^7.0", "league/commonmark": "^2.2", "spatie/yaml-front-matter": "^2.0.9", From 8c7e9b126068719e2b52b925c55818856a5ab004 Mon Sep 17 00:00:00 2001 From: Emma De Silva Date: Sun, 12 Jul 2026 03:45:30 +0200 Subject: [PATCH 02/15] Create TranslationServiceProvider.php --- .../Providers/TranslationServiceProvider.php | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 packages/framework/src/Foundation/Providers/TranslationServiceProvider.php diff --git a/packages/framework/src/Foundation/Providers/TranslationServiceProvider.php b/packages/framework/src/Foundation/Providers/TranslationServiceProvider.php new file mode 100644 index 00000000000..597b623c4b1 --- /dev/null +++ b/packages/framework/src/Foundation/Providers/TranslationServiceProvider.php @@ -0,0 +1,23 @@ + Date: Sun, 12 Jul 2026 03:48:01 +0200 Subject: [PATCH 03/15] Register the translation service provider --- app/config.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/config.php b/app/config.php index 26156665112..8011c43f8a8 100644 --- a/app/config.php +++ b/app/config.php @@ -74,6 +74,7 @@ Hyde\Framework\HydeServiceProvider::class, Hyde\Foundation\Providers\ViewServiceProvider::class, Hyde\Foundation\Providers\NavigationServiceProvider::class, + Hyde\Foundation\Providers\TranslationServiceProvider::class, Hyde\Console\ConsoleServiceProvider::class, ], From d34ea7a450d08336abe76a69d0a24539d81f55ea Mon Sep 17 00:00:00 2001 From: Emma De Silva Date: Sun, 12 Jul 2026 03:48:47 +0200 Subject: [PATCH 04/15] Update HYDEPHP_V3_PLANNING.md --- HYDEPHP_V3_PLANNING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/HYDEPHP_V3_PLANNING.md b/HYDEPHP_V3_PLANNING.md index 6f250e30449..0b83774e7bd 100644 --- a/HYDEPHP_V3_PLANNING.md +++ b/HYDEPHP_V3_PLANNING.md @@ -49,3 +49,7 @@ Please fill in UPGRADE.md as you make changes. - Blade in Markdown is now enabled by default, including `[Blade]:` directives and the new executable `blade render` and `blade component(name)` fenced code blocks. Existing projects with a published `config/markdown.php` retain their current `markdown.enable_blade` setting; set it to `true` to adopt the v3 default, or keep it `false` to disable both forms when compiling untrusted or unreviewed Markdown. - The `rebuild` command has been removed. If you need to build a single page programmatically, use `Hyde\Framework\Actions\StaticPageBuilder::handle()` instead. - Move any calls to `Redirect::create()` or `Redirect::store()` into the `redirects` array in `config/hyde.php`, using the old path as the key and the destination as the value. + +## Temp notes: + +Todo: Document TranslationServiceProvider must be added to config.php From 9c3695760b00a394e7e614a2a64b1e8651e53dde Mon Sep 17 00:00:00 2001 From: Emma De Silva Date: Sun, 12 Jul 2026 03:50:58 +0200 Subject: [PATCH 05/15] Extend Illuminate provider --- .../Providers/TranslationServiceProvider.php | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/packages/framework/src/Foundation/Providers/TranslationServiceProvider.php b/packages/framework/src/Foundation/Providers/TranslationServiceProvider.php index 597b623c4b1..094b699ca43 100644 --- a/packages/framework/src/Foundation/Providers/TranslationServiceProvider.php +++ b/packages/framework/src/Foundation/Providers/TranslationServiceProvider.php @@ -4,20 +4,12 @@ namespace Hyde\Foundation\Providers; -use Illuminate\Support\ServiceProvider; +use Illuminate\Translation\TranslationServiceProvider as IlluminateTranslationServiceProvider; /** * Register the Hyde translation services. */ -class TranslationServiceProvider extends ServiceProvider +class TranslationServiceProvider extends IlluminateTranslationServiceProvider { - public function register(): void - { - // - } - - public function boot(): void - { - // - } + // } From 1a4bd89cb8f41ef8e8d70b1edb4b91bd46d10908 Mon Sep 17 00:00:00 2001 From: Emma De Silva Date: Sun, 12 Jul 2026 04:00:33 +0200 Subject: [PATCH 06/15] Create localization.php --- config/localization.php | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 config/localization.php diff --git a/config/localization.php b/config/localization.php new file mode 100644 index 00000000000..8eba0c640e1 --- /dev/null +++ b/config/localization.php @@ -0,0 +1,9 @@ + [ + 'en', + 'de', + 'sv', + ] +]; From d2e4b07ef31d6924ed84a728e383ed15853d893a Mon Sep 17 00:00:00 2001 From: Emma De Silva Date: Sun, 12 Jul 2026 04:00:37 +0200 Subject: [PATCH 07/15] Revert "Update HYDEPHP_V3_PLANNING.md" This reverts commit cb16ffda05e14ceb30bed059900cb192b00d45df. --- HYDEPHP_V3_PLANNING.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/HYDEPHP_V3_PLANNING.md b/HYDEPHP_V3_PLANNING.md index 0b83774e7bd..6f250e30449 100644 --- a/HYDEPHP_V3_PLANNING.md +++ b/HYDEPHP_V3_PLANNING.md @@ -49,7 +49,3 @@ Please fill in UPGRADE.md as you make changes. - Blade in Markdown is now enabled by default, including `[Blade]:` directives and the new executable `blade render` and `blade component(name)` fenced code blocks. Existing projects with a published `config/markdown.php` retain their current `markdown.enable_blade` setting; set it to `true` to adopt the v3 default, or keep it `false` to disable both forms when compiling untrusted or unreviewed Markdown. - The `rebuild` command has been removed. If you need to build a single page programmatically, use `Hyde\Framework\Actions\StaticPageBuilder::handle()` instead. - Move any calls to `Redirect::create()` or `Redirect::store()` into the `redirects` array in `config/hyde.php`, using the old path as the key and the destination as the value. - -## Temp notes: - -Todo: Document TranslationServiceProvider must be added to config.php From de914a8ca60c8a5792fa9f9ba36b946b815e8266 Mon Sep 17 00:00:00 2001 From: Emma De Silva Date: Sun, 12 Jul 2026 04:00:59 +0200 Subject: [PATCH 08/15] Create SCRATCHPAD.md --- SCRATCHPAD.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 SCRATCHPAD.md diff --git a/SCRATCHPAD.md b/SCRATCHPAD.md new file mode 100644 index 00000000000..47a3e7bd050 --- /dev/null +++ b/SCRATCHPAD.md @@ -0,0 +1,6 @@ +## Temp notes: + +Todo: Document TranslationServiceProvider must be added to config.php + +Copy localization.php to framework and add tests to ensure its up to date + From c08eaa4cba81167e427c8301a5dab2d2c5923191 Mon Sep 17 00:00:00 2001 From: Emma De Silva Date: Sun, 12 Jul 2026 04:01:30 +0200 Subject: [PATCH 09/15] Create demo setup --- _pages/index.blade.php | 87 +---------------------------------------- config/localization.php | 1 - lang/en/main.php | 5 +++ lang/sv/main.php | 5 +++ 4 files changed, 11 insertions(+), 87 deletions(-) create mode 100644 lang/en/main.php create mode 100644 lang/sv/main.php diff --git a/_pages/index.blade.php b/_pages/index.blade.php index 7d6a48ff7af..4b9521b14ab 100644 --- a/_pages/index.blade.php +++ b/_pages/index.blade.php @@ -1,86 +1 @@ - - - - - - - - Welcome to HydePHP! - - - - - - - -
-
- -
-

- You're running on HydePHP -

-
-
-

- Leap into the future of static HTML blogs and documentation with the tools you already know and love. - Made with Tailwind, Laravel, and Coffee. -

-
- -
-

- This is the default homepage stored as index.blade.php, however you can publish any of the built-in views using the following command: - - -

php hyde publish:homepage
-

-
- -
- Resources for getting started - -
-
-
- -
-
- - +{{ __('main.welcome') }} \ No newline at end of file diff --git a/config/localization.php b/config/localization.php index 8eba0c640e1..ff904c067c1 100644 --- a/config/localization.php +++ b/config/localization.php @@ -3,7 +3,6 @@ return [ 'languages' => [ 'en', - 'de', 'sv', ] ]; diff --git a/lang/en/main.php b/lang/en/main.php new file mode 100644 index 00000000000..921d5010ffd --- /dev/null +++ b/lang/en/main.php @@ -0,0 +1,5 @@ + 'Hello World!', +]; diff --git a/lang/sv/main.php b/lang/sv/main.php new file mode 100644 index 00000000000..fbd099dd2b7 --- /dev/null +++ b/lang/sv/main.php @@ -0,0 +1,5 @@ + 'Hej Världen!', +]; From 4054ee71c060ca6608ad894be48052e813cb00b4 Mon Sep 17 00:00:00 2001 From: Emma De Silva Date: Sun, 12 Jul 2026 04:21:03 +0200 Subject: [PATCH 10/15] Create first localization proof of concept --- packages/framework/config/localization.php | 26 +++++++++++ .../framework/src/Facades/Localization.php | 44 +++++++++++++++++++ .../src/Foundation/Kernel/PageCollection.php | 32 ++++++++++++-- .../Providers/TranslationServiceProvider.php | 19 +++++++- .../Framework/Actions/StaticPageBuilder.php | 26 ++++++++++- .../framework/src/Pages/Concerns/HydePage.php | 32 +++++++++++++- 6 files changed, 172 insertions(+), 7 deletions(-) create mode 100644 packages/framework/config/localization.php create mode 100644 packages/framework/src/Facades/Localization.php diff --git a/packages/framework/config/localization.php b/packages/framework/config/localization.php new file mode 100644 index 00000000000..8a7e59656a0 --- /dev/null +++ b/packages/framework/config/localization.php @@ -0,0 +1,26 @@ + [ + // + ], +]; diff --git a/packages/framework/src/Facades/Localization.php b/packages/framework/src/Facades/Localization.php new file mode 100644 index 00000000000..0ef842ef9d0 --- /dev/null +++ b/packages/framework/src/Facades/Localization.php @@ -0,0 +1,44 @@ + 0; + } + + /** + * Get the languages the site is compiled for, in the order they are configured. + * + * @return array + */ + public static function languages(): array + { + return array_values(Config::getArray('localization.languages', [])); + } + + /** + * Get the default language of the site, which is the first configured language. + */ + public static function defaultLanguage(): string + { + return static::languages()[0] ?? Config::getString('app.locale', 'en'); + } +} diff --git a/packages/framework/src/Foundation/Kernel/PageCollection.php b/packages/framework/src/Foundation/Kernel/PageCollection.php index 4cc4d85eac2..3f04d3f1415 100644 --- a/packages/framework/src/Foundation/Kernel/PageCollection.php +++ b/packages/framework/src/Foundation/Kernel/PageCollection.php @@ -4,6 +4,7 @@ namespace Hyde\Foundation\Kernel; +use Hyde\Facades\Localization; use Hyde\Foundation\Concerns\BaseFoundationCollection; use Hyde\Framework\Exceptions\FileNotFoundException; use Hyde\Pages\Concerns\HydePage; @@ -30,13 +31,21 @@ final class PageCollection extends BaseFoundationCollection { public function addPage(HydePage $page): void { - $this->put($page->getSourcePath(), $page); + $this->put(static::makeKey($page), $page); } protected function runDiscovery(): void { $this->kernel->files()->each(function (SourceFile $file): void { - $this->addPage($this->parsePage($file->pageClass, $file->getPath())); + $page = $this->parsePage($file->pageClass, $file->getPath()); + + if (Localization::enabled()) { + foreach (Localization::languages() as $language) { + $this->addPage($page->withLanguage($language)); + } + } else { + $this->addPage($page); + } }); } @@ -56,7 +65,24 @@ protected static function parsePage(string $pageClass, string $path): HydePage public function getPage(string $sourcePath): HydePage { - return $this->get($sourcePath) ?? throw new FileNotFoundException($sourcePath); + // When the site is localized, each source file has one page per language, + // so we resolve the page for the default language when given a source path. + + return $this->get($sourcePath) + ?? $this->get(static::makeLocalizedKey(Localization::defaultLanguage(), $sourcePath)) + ?? throw new FileNotFoundException($sourcePath); + } + + protected static function makeKey(HydePage $page): string + { + return $page->getLanguage() === null + ? $page->getSourcePath() + : static::makeLocalizedKey($page->getLanguage(), $page->getSourcePath()); + } + + protected static function makeLocalizedKey(string $language, string $sourcePath): string + { + return "$language::$sourcePath"; } /** @param class-string<\Hyde\Pages\Concerns\HydePage>|null $pageClass */ diff --git a/packages/framework/src/Foundation/Providers/TranslationServiceProvider.php b/packages/framework/src/Foundation/Providers/TranslationServiceProvider.php index 094b699ca43..e06ec1c1e05 100644 --- a/packages/framework/src/Foundation/Providers/TranslationServiceProvider.php +++ b/packages/framework/src/Foundation/Providers/TranslationServiceProvider.php @@ -4,12 +4,29 @@ namespace Hyde\Foundation\Providers; +use Hyde\Facades\Config; +use Hyde\Facades\Localization; use Illuminate\Translation\TranslationServiceProvider as IlluminateTranslationServiceProvider; /** * Register the Hyde translation services. + * + * Translation strings are loaded from the lang/{language} directories in the project root, + * and can be used in any page or component using the standard Laravel __() helper. */ class TranslationServiceProvider extends IlluminateTranslationServiceProvider { - // + public function register(): void + { + // The translator resolves its locale from the app config, which for a localized site + // defaults to the first configured language. The static site builder then swaps the + // locale for each page it compiles, so that each language gets its own strings. + + $language = Config::getNullableString('app.locale') ?? Localization::defaultLanguage(); + + $this->app['config']->set('app.locale', $language); + $this->app['config']->set('app.fallback_locale', Config::getNullableString('app.fallback_locale') ?? $language); + + parent::register(); + } } diff --git a/packages/framework/src/Framework/Actions/StaticPageBuilder.php b/packages/framework/src/Framework/Actions/StaticPageBuilder.php index ddd89c87613..51d8b2bcfba 100644 --- a/packages/framework/src/Framework/Actions/StaticPageBuilder.php +++ b/packages/framework/src/Framework/Actions/StaticPageBuilder.php @@ -8,6 +8,7 @@ use Hyde\Facades\Filesystem; use Hyde\Framework\Concerns\InteractsWithDirectories; use Hyde\Pages\Concerns\HydePage; +use Illuminate\Support\Facades\App; /** * Converts a Hyde page object into a static HTML page. @@ -27,8 +28,31 @@ public static function handle(HydePage $page): string Hyde::shareViewData($page); - Filesystem::putContents($path, $page->compile()); + Filesystem::putContents($path, static::compilePage($page)); return $path; } + + /** + * Compile the page, using the page's language as the app locale when the site is localized, + * so that translation strings are resolved for the language the page is being built for. + */ + protected static function compilePage(HydePage $page): string + { + $language = $page->getLanguage(); + + if ($language === null) { + return $page->compile(); + } + + $locale = App::getLocale(); + + App::setLocale($language); + + try { + return $page->compile(); + } finally { + App::setLocale($locale); + } + } } diff --git a/packages/framework/src/Pages/Concerns/HydePage.php b/packages/framework/src/Pages/Concerns/HydePage.php index e60e44dc187..5944e0db034 100644 --- a/packages/framework/src/Pages/Concerns/HydePage.php +++ b/packages/framework/src/Pages/Concerns/HydePage.php @@ -67,6 +67,9 @@ abstract class HydePage implements PageSchema, SerializableContract public PageMetadataBag $metadata; public NavigationData $navigation; + /** The language the page is compiled for, if the site is localized. */ + protected ?string $language = null; + /** * Create a new page instance. Static alias for the constructor. */ @@ -284,7 +287,9 @@ public function getSourcePath(): string */ public function getOutputPath(): string { - return unslash(static::outputPath($this->identifier)); + return $this->language === null + ? unslash(static::outputPath($this->identifier)) + : "{$this->getRouteKey()}.html"; } // Section: Routing @@ -301,7 +306,30 @@ public function getOutputPath(): string */ public function getRouteKey(): string { - return $this->routeKey; + return $this->language === null ? $this->routeKey : unslash("{$this->language}/{$this->routeKey}"); + } + + /** + * Get the language the page is compiled for, or null if the site is not localized. + */ + public function getLanguage(): ?string + { + return $this->language; + } + + /** + * Get a copy of the page that is compiled for the given language. + * + * The page keeps its source file and Blade view, but is routed to a language + * subdirectory, and is compiled with the given language as the app locale. + */ + public function withLanguage(string $language): static + { + $page = clone $this; + + $page->language = $language; + + return $page; } /** From ecc1e42f52dc2506dead0248cbcaf610d95786a9 Mon Sep 17 00:00:00 2001 From: Emma De Silva Date: Sun, 12 Jul 2026 04:40:37 +0200 Subject: [PATCH 11/15] Ensure the realtime compiler can serve localized paths --- .../framework/src/Facades/Localization.php | 30 +++++++++++++++++++ .../Framework/Actions/StaticPageBuilder.php | 18 ++--------- .../src/Http/DashboardController.php | 3 +- .../src/Routing/PageRouter.php | 3 +- 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/packages/framework/src/Facades/Localization.php b/packages/framework/src/Facades/Localization.php index 0ef842ef9d0..2db4713e9d6 100644 --- a/packages/framework/src/Facades/Localization.php +++ b/packages/framework/src/Facades/Localization.php @@ -4,7 +4,9 @@ namespace Hyde\Facades; +use Closure; use Hyde\Facades\Config; +use Illuminate\Support\Facades\App; use function count; @@ -41,4 +43,32 @@ public static function defaultLanguage(): string { return static::languages()[0] ?? Config::getString('app.locale', 'en'); } + + /** + * Run the callback using the given language as the app locale, so that translation + * strings are resolved for it, then restore the previously active locale. + * + * Passing a null language runs the callback as is, using the default locale. + * + * @template T + * + * @param \Closure(): T $callback + * @return T + */ + public static function usingLanguage(?string $language, Closure $callback): mixed + { + if ($language === null) { + return $callback(); + } + + $locale = App::getLocale(); + + App::setLocale($language); + + try { + return $callback(); + } finally { + App::setLocale($locale); + } + } } diff --git a/packages/framework/src/Framework/Actions/StaticPageBuilder.php b/packages/framework/src/Framework/Actions/StaticPageBuilder.php index 51d8b2bcfba..2164728b31f 100644 --- a/packages/framework/src/Framework/Actions/StaticPageBuilder.php +++ b/packages/framework/src/Framework/Actions/StaticPageBuilder.php @@ -7,8 +7,8 @@ use Hyde\Hyde; use Hyde\Facades\Filesystem; use Hyde\Framework\Concerns\InteractsWithDirectories; +use Hyde\Facades\Localization; use Hyde\Pages\Concerns\HydePage; -use Illuminate\Support\Facades\App; /** * Converts a Hyde page object into a static HTML page. @@ -39,20 +39,6 @@ public static function handle(HydePage $page): string */ protected static function compilePage(HydePage $page): string { - $language = $page->getLanguage(); - - if ($language === null) { - return $page->compile(); - } - - $locale = App::getLocale(); - - App::setLocale($language); - - try { - return $page->compile(); - } finally { - App::setLocale($locale); - } + return Localization::usingLanguage($page->getLanguage(), fn (): string => $page->compile()); } } diff --git a/packages/realtime-compiler/src/Http/DashboardController.php b/packages/realtime-compiler/src/Http/DashboardController.php index 5a46b46bcf1..e246f58a8c0 100644 --- a/packages/realtime-compiler/src/Http/DashboardController.php +++ b/packages/realtime-compiler/src/Http/DashboardController.php @@ -16,6 +16,7 @@ use Desilva\Microserve\Request; use Desilva\Microserve\Response; use Hyde\Facades\Filesystem; +use Hyde\Facades\Localization; use Hyde\Pages\Concerns\HydePage; use Hyde\Pages\DocumentationPage; use Hyde\Support\Models\RouteKey; @@ -280,7 +281,7 @@ public static function renderIndexPage(HydePage $page): string } else { Hyde::shareViewData($page); - $contents = $page->compile(); + $contents = Localization::usingLanguage($page->getLanguage(), fn (): string => $page->compile()); } if (self::isLoadedInIframe()) { diff --git a/packages/realtime-compiler/src/Routing/PageRouter.php b/packages/realtime-compiler/src/Routing/PageRouter.php index 4fbca1c5f8f..0f038776578 100644 --- a/packages/realtime-compiler/src/Routing/PageRouter.php +++ b/packages/realtime-compiler/src/Routing/PageRouter.php @@ -6,6 +6,7 @@ use Desilva\Microserve\Request; use Desilva\Microserve\Response; +use Hyde\Facades\Localization; use Hyde\Foundation\Facades\Routes; use Hyde\Support\Models\Route; use Hyde\Pages\Concerns\BaseMarkdownPage; @@ -94,7 +95,7 @@ protected function getHtml(HydePage $page): string } else { Hyde::shareViewData($page); - $contents = $page->compile(); + $contents = Localization::usingLanguage($page->getLanguage(), fn (): string => $page->compile()); } if ($page instanceof BaseMarkdownPage && LiveEditController::enabled()) { From 887e610b26e5f01b3f077b31977d2d258d2ee517 Mon Sep 17 00:00:00 2001 From: Emma De Silva Date: Sun, 12 Jul 2026 04:44:51 +0200 Subject: [PATCH 12/15] Generate redirects for roots for localized sites --- .../src/Foundation/Kernel/PageCollection.php | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/packages/framework/src/Foundation/Kernel/PageCollection.php b/packages/framework/src/Foundation/Kernel/PageCollection.php index 3f04d3f1415..50442ed6d81 100644 --- a/packages/framework/src/Foundation/Kernel/PageCollection.php +++ b/packages/framework/src/Foundation/Kernel/PageCollection.php @@ -4,11 +4,16 @@ namespace Hyde\Foundation\Kernel; +use Hyde\Hyde; use Hyde\Facades\Localization; use Hyde\Foundation\Concerns\BaseFoundationCollection; use Hyde\Framework\Exceptions\FileNotFoundException; use Hyde\Pages\Concerns\HydePage; use Hyde\Support\Filesystem\SourceFile; +use Hyde\Support\Models\Redirect; + +use function str_repeat; +use function substr_count; /** * The PageCollection contains all the instantiated pages. @@ -43,12 +48,39 @@ protected function runDiscovery(): void foreach (Localization::languages() as $language) { $this->addPage($page->withLanguage($language)); } + + $this->addDefaultLanguageRedirect($page); } else { $this->addPage($page); } }); } + /** + * Add a redirect from the unprefixed route key to the default language, so that + * for example `/foo` sends the visitor to `/en/foo` when English is the default. + */ + protected function addDefaultLanguageRedirect(HydePage $page): void + { + $routeKey = $page->getRouteKey(); + + $this->addPage(new Redirect($routeKey, static::makeRedirectDestination($routeKey), matter: [ + 'navigation' => ['hidden' => true], + ])); + } + + protected static function makeRedirectDestination(string $routeKey): string + { + // The destination is relative to the redirect page, which sits at the unprefixed + // route key, so we need to walk back up to the site webroot before descending + // into the language directory. For example, `posts/hello` redirects to + // `../en/posts/hello.html`, which resolves to `/en/posts/hello.html`. + + $depth = substr_count($routeKey, '/'); + + return str_repeat('../', $depth).Hyde::formatLink(Localization::defaultLanguage()."/$routeKey.html"); + } + protected function runExtensionHandlers(): void { /** @var class-string<\Hyde\Foundation\Concerns\HydeExtension> $extension */ From fbf30f876a3295b3ab1fb9cc57c4c12ac005083f Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Sun, 12 Jul 2026 02:45:10 +0000 Subject: [PATCH 13/15] Apply fixes from StyleCI --- config/localization.php | 2 +- packages/framework/src/Facades/Localization.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/config/localization.php b/config/localization.php index ff904c067c1..22b797b568d 100644 --- a/config/localization.php +++ b/config/localization.php @@ -4,5 +4,5 @@ 'languages' => [ 'en', 'sv', - ] + ], ]; diff --git a/packages/framework/src/Facades/Localization.php b/packages/framework/src/Facades/Localization.php index 2db4713e9d6..9300d7b7193 100644 --- a/packages/framework/src/Facades/Localization.php +++ b/packages/framework/src/Facades/Localization.php @@ -5,7 +5,6 @@ namespace Hyde\Facades; use Closure; -use Hyde\Facades\Config; use Illuminate\Support\Facades\App; use function count; From ccf4c9ef82de587f0174070b58f5d18f246f291a Mon Sep 17 00:00:00 2001 From: Emma De Silva Date: Sun, 12 Jul 2026 15:32:58 +0200 Subject: [PATCH 14/15] Stash --- _pages/index.blade.php | 1 - _site/404.html | 13 ++++++++++++ _site/en/404.html | 48 ++++++++++++++++++++++++++++++++++++++++++ _site/en/index.html | 0 _site/index.html | 13 ++++++++++++ _site/sitemap.xml | 2 ++ _site/sv/404.html | 48 ++++++++++++++++++++++++++++++++++++++++++ _site/sv/index.html | 0 lang/sv/main.php | 7 ++++++ 9 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 _site/404.html create mode 100644 _site/en/404.html create mode 100644 _site/en/index.html create mode 100644 _site/index.html create mode 100644 _site/sitemap.xml create mode 100644 _site/sv/404.html create mode 100644 _site/sv/index.html diff --git a/_pages/index.blade.php b/_pages/index.blade.php index 4b9521b14ab..e69de29bb2d 100644 --- a/_pages/index.blade.php +++ b/_pages/index.blade.php @@ -1 +0,0 @@ -{{ __('main.welcome') }} \ No newline at end of file diff --git a/_site/404.html b/_site/404.html new file mode 100644 index 00000000000..cc9fb2738c9 --- /dev/null +++ b/_site/404.html @@ -0,0 +1,13 @@ + + + + + + + + Redirecting to en/404.html + + + Redirecting to en/404.html. + + diff --git a/_site/en/404.html b/_site/en/404.html new file mode 100644 index 00000000000..6b3cd800f60 --- /dev/null +++ b/_site/en/404.html @@ -0,0 +1,48 @@ + + + + + 404 - Page not found + + + + + + + + + + + + + + + +
+
+
+
+ 404 +
+ +
+ +

+ Sorry, the page you are looking for could not be found. +

+ + + + +
+ +
+ +
+
+
+
+ + diff --git a/_site/en/index.html b/_site/en/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/_site/index.html b/_site/index.html new file mode 100644 index 00000000000..af38169243e --- /dev/null +++ b/_site/index.html @@ -0,0 +1,13 @@ + + + + + + + + Redirecting to en/index.html + + + Redirecting to en/index.html. + + diff --git a/_site/sitemap.xml b/_site/sitemap.xml new file mode 100644 index 00000000000..673c337a59f --- /dev/null +++ b/_site/sitemap.xml @@ -0,0 +1,2 @@ + +hydephp.com/en/404.html2026-07-11T22:32:45+00:00monthly0.25hydephp.com/sv/404.html2026-07-11T22:32:45+00:00monthly0.25hydephp.com/404.html2026-07-12T02:50:28+00:00monthly0.25hydephp.com/en/index.html2026-07-12T02:50:07+00:00daily1hydephp.com/sv/index.html2026-07-12T02:50:07+00:00daily1hydephp.com/index.html2026-07-12T02:50:28+00:00weekly0.5 diff --git a/_site/sv/404.html b/_site/sv/404.html new file mode 100644 index 00000000000..6b3cd800f60 --- /dev/null +++ b/_site/sv/404.html @@ -0,0 +1,48 @@ + + + + + 404 - Page not found + + + + + + + + + + + + + + + +
+
+
+
+ 404 +
+ +
+ +

+ Sorry, the page you are looking for could not be found. +

+ + + + +
+ +
+ +
+
+
+
+ + diff --git a/_site/sv/index.html b/_site/sv/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/lang/sv/main.php b/lang/sv/main.php index fbd099dd2b7..47b5ee19546 100644 --- a/lang/sv/main.php +++ b/lang/sv/main.php @@ -1,5 +1,12 @@ 'Hello World!', +]; + + +// lang/sv/main.php return [ 'welcome' => 'Hej Världen!', ]; From e8e7835b416dfeb9f363635b7d42ef8aa3227ff3 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Sun, 12 Jul 2026 14:37:54 +0000 Subject: [PATCH 15/15] Apply fixes from StyleCI --- lang/sv/main.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lang/sv/main.php b/lang/sv/main.php index 47b5ee19546..4367b310460 100644 --- a/lang/sv/main.php +++ b/lang/sv/main.php @@ -5,7 +5,6 @@ 'welcome' => 'Hello World!', ]; - // lang/sv/main.php return [ 'welcome' => 'Hej Världen!',