From 95a9a133e753dc79a8391ba065028fd8b2adcfff Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Thu, 16 Nov 2023 10:40:10 +0100 Subject: [PATCH 1/8] Create extensions-api.md --- docs/architecture-concepts/extensions-api.md | 38 ++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 docs/architecture-concepts/extensions-api.md diff --git a/docs/architecture-concepts/extensions-api.md b/docs/architecture-concepts/extensions-api.md new file mode 100644 index 00000000000..843812fae68 --- /dev/null +++ b/docs/architecture-concepts/extensions-api.md @@ -0,0 +1,38 @@ +--- +navigation.priority: 1000 +--- + +# The Extensions API + +## Introduction + +The Extensions API a powerful interface designed for package developers who want to extend the functionality of HydePHP. + +Using the API, you can hook directly into the HydePHP Kernel and extend sites with custom page types and new features. + +### Prerequisites + +Before creating your extension, it will certainly be helpful if you first become familiar with +the basic internal architecture of HydePHP, as well as how the auto-discovery system works, +so you can understand how your code works with the internals. + +- [Core concepts overview](core-concepts) +- [Architecture concepts](architecture-concepts) +- [Autodiscovery](autodiscovery) + +### The why and how of the Extensions API + +HydePHP being a static site generator, the Extensions API is centered around [Page Models](page-models), +which you are hopefully already familiar with, otherwise you should read up on them first. + +What the Extensions API does is to allow you to create custom page types, and tell HydePHP how to discover them. +This may sound like a small thing, but it's actually incredibly powerful as the page models are the foundation +of HydePHP's functionality. They tell the system how to discover pages, how to render them, +and how they interact with the site. + +Any other functionality you want to add to HydePHP, such as new commands, new configuration options, +that can all be added the same way as you would in Laravel, and are thus not part of the Extensions API. + +You may want to read up on the [Laravel package development guide](https://laravel.com/docs/10.x/packages) + + From eace4dc45e98099db2da07e6e29939c04f79814b Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Thu, 16 Nov 2023 12:36:26 +0100 Subject: [PATCH 2/8] Update introduction --- docs/architecture-concepts/extensions-api.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/architecture-concepts/extensions-api.md b/docs/architecture-concepts/extensions-api.md index 843812fae68..33cc8a4a246 100644 --- a/docs/architecture-concepts/extensions-api.md +++ b/docs/architecture-concepts/extensions-api.md @@ -20,6 +20,8 @@ so you can understand how your code works with the internals. - [Architecture concepts](architecture-concepts) - [Autodiscovery](autodiscovery) +This documentation page will function heavily through examples, so it's recommended that you first read the sections in order. + ### The why and how of the Extensions API HydePHP being a static site generator, the Extensions API is centered around [Page Models](page-models), From da1dfbbe081a9373893e8f82b9df1e645b88954c Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Thu, 16 Nov 2023 12:36:47 +0100 Subject: [PATCH 3/8] Document extension creation and discovery handlers --- docs/architecture-concepts/extensions-api.md | 72 ++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/docs/architecture-concepts/extensions-api.md b/docs/architecture-concepts/extensions-api.md index 33cc8a4a246..456f85c846f 100644 --- a/docs/architecture-concepts/extensions-api.md +++ b/docs/architecture-concepts/extensions-api.md @@ -37,4 +37,76 @@ that can all be added the same way as you would in Laravel, and are thus not par You may want to read up on the [Laravel package development guide](https://laravel.com/docs/10.x/packages) +## Creating your Extension class +The entry point for your extension is your Extensions class. Within this, you can register the custom page classes for your extension. +If needed, you can also register discovery handlers which can run custom logic at various points in the boot process. + +In this article we will create an extension that registers a new type of page, a `JsonPageExtension`. + +The first step is to create a class that extends the `HydeExtension` class: + +```php +use Hyde\Foundation\Concerns\HydeExtension; + +class JsonPageExtension extends HydeExtension { + // +} +``` + +In here, we will register our extension class name in the `getPageClasses` method: + +```php +class JsonPageExtension extends HydeExtension { + public static function getPageClasses(): array { + return [ + JsonPage::class, + ]; + } +} +``` + +Hyde will then use the information from the `JsonPage` class to automatically discover the pages when booting the Kernel. + +However, if our page model has more complex requirements we can add a discovery handler, so let's take a quick look at that next. + +### Discovery handlers + +The discovery handlers lets you run code at various points of the booting process. This is usually only needed if your +page models don't contain the information required for Hyde run the standard auto-discovery, for example if you need +something custom. And while you usually only in that case need to add files to the Kernel `FileCollection`, the +`HydeExtension` class offers following three discovery handlers, in case you need them: + +```php +/** Runs during file discovery */ +public function discoverFiles(FileCollection $collection): void; + +/** Runs during page discovery */ +public function discoverPages(PageCollection $collection): void; + +/** Runs during route discovery */ +public function discoverRoutes(RouteCollection $collection): void; +``` + +Any of these can be implemented in your extension class, and they will be called during the discovery. As you can see, +the instance of the discovery collection is injected into the method for you to interact with. + +#### Discovery handler example + +Let's go crazy and implement a discovery handler to collect `JsonPage` files from an external API! We will do this +by implementing the `discoverPages` method in our extension class, and from there inject pages retrieved from our API. + +```php +class JsonPageExtension extends HydeExtension { + public function discoverPages(PageCollection $collection): void { + $pages = Http::get('https://example.com/my-api')->collect(); + + $pages->each(function (array $page) use ($collection): void { + $collection->addPage(JsonPage::fromArray($page)); + }); + } +} +``` + +Since the discovery steps are handled sequentially, the added pages will automatically be discovered as routes without +us having to implement that handler method. \ No newline at end of file From 8cfe4f697f43ba256fb297c210971b3309cd40cb Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Thu, 16 Nov 2023 18:18:20 +0100 Subject: [PATCH 4/8] Update section texts for better flow --- docs/architecture-concepts/extensions-api.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/architecture-concepts/extensions-api.md b/docs/architecture-concepts/extensions-api.md index 456f85c846f..45365f8ad22 100644 --- a/docs/architecture-concepts/extensions-api.md +++ b/docs/architecture-concepts/extensions-api.md @@ -67,15 +67,17 @@ class JsonPageExtension extends HydeExtension { ``` Hyde will then use the information from the `JsonPage` class to automatically discover the pages when booting the Kernel. +For example, if you specify the file extension and source directory, that is all Hyde needs to know to discover the pages. -However, if our page model has more complex requirements we can add a discovery handler, so let's take a quick look at that next. +If our pages need more complex discovery logic, we can create custom handlers. so let's take a quick look at that next. ### Discovery handlers The discovery handlers lets you run code at various points of the booting process. This is usually only needed if your -page models don't contain the information required for Hyde run the standard auto-discovery, for example if you need -something custom. And while you usually only in that case need to add files to the Kernel `FileCollection`, the -`HydeExtension` class offers following three discovery handlers, in case you need them: +page models cannot provide the information required for Hyde run the standard auto-discovery, and thus need custom logic. + +Usually in these cases, you would only need to add files to the Kernel `FileCollection`, +though the `HydeExtension` class offers following three discovery handlers, in case you need them: ```php /** Runs during file discovery */ @@ -109,4 +111,4 @@ class JsonPageExtension extends HydeExtension { ``` Since the discovery steps are handled sequentially, the added pages will automatically be discovered as routes without -us having to implement that handler method. \ No newline at end of file +us having to implement that handler method. As we inject the page objects directly, we bypass the need of the `FileCollection`. From aa8b6ca877179a2f309abe76dba1a7a1f8053ac9 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Thu, 16 Nov 2023 18:47:49 +0100 Subject: [PATCH 5/8] Document extension registration and packaging --- docs/architecture-concepts/extensions-api.md | 44 ++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/docs/architecture-concepts/extensions-api.md b/docs/architecture-concepts/extensions-api.md index 45365f8ad22..03d5b6c2c2f 100644 --- a/docs/architecture-concepts/extensions-api.md +++ b/docs/architecture-concepts/extensions-api.md @@ -112,3 +112,47 @@ class JsonPageExtension extends HydeExtension { Since the discovery steps are handled sequentially, the added pages will automatically be discovered as routes without us having to implement that handler method. As we inject the page objects directly, we bypass the need of the `FileCollection`. + +## Registering your extension + +Now that we have our extension class, we need to register it with HydePHP. + +It's important that your class is registered before the HydeKernel boots. Therefore, an excellent place for this is the +`register` method of your extensions service provider, where you call the `registerExtension` method of the `HydeKernel` +singleton instance, which you can access via the `Hyde\Hyde` facade, or via the service container. + +```php +use Hyde\Hyde; +use Hyde\Foundation\HydeKernel; +use Illuminate\Support\ServiceProvider; + +class JsonPageExtensionServiceProvider extends ServiceProvider { + public function register(): void { + // Via the service container: + $this->app->make(HydeKernel::class)->registerExtension(JsonPageExtension::class); + + // Or via the facade: + Hyde::registerExtension(JsonPageExtension::class); + } +} +``` + +### Packaging your extension + +To make your extension available to other HydePHP users, you can make it into a [Composer](https://getcomposer.org/) package, +and publish it to [Packagist](https://packagist.org/) for others to install. + +If you register your service provider in your package's `composer.json` file, your extension automatically be enabled when +the package is installed in a HydePHP project! + +```json +{ + "extra": { + "laravel": { + "providers": [ + "My\\Namespace\\JsonPageExtensionServiceProvider" + ] + } + } +} +``` From c4abc7f22c8f479563bf1234ee849a28d1038334 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Thu, 16 Nov 2023 18:49:54 +0100 Subject: [PATCH 6/8] Add Twitter link --- docs/architecture-concepts/extensions-api.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/architecture-concepts/extensions-api.md b/docs/architecture-concepts/extensions-api.md index 03d5b6c2c2f..a01ef904f2e 100644 --- a/docs/architecture-concepts/extensions-api.md +++ b/docs/architecture-concepts/extensions-api.md @@ -156,3 +156,8 @@ the package is installed in a HydePHP project! } } ``` + +### Telling the world about your extension + +Next up, why not send us a Tweet at [@HydeFramework](https://twitter.com/HydeFramework) and tell us about your extension, +so we can feature it? From e9573bf50d25bab5fd705c8586c7c4b5fbf3219b Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Thu, 16 Nov 2023 18:50:05 +0100 Subject: [PATCH 7/8] Format Markdown --- docs/architecture-concepts/extensions-api.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/architecture-concepts/extensions-api.md b/docs/architecture-concepts/extensions-api.md index a01ef904f2e..b513501ddb3 100644 --- a/docs/architecture-concepts/extensions-api.md +++ b/docs/architecture-concepts/extensions-api.md @@ -12,7 +12,7 @@ Using the API, you can hook directly into the HydePHP Kernel and extend sites wi ### Prerequisites -Before creating your extension, it will certainly be helpful if you first become familiar with +Before creating your extension, it will certainly be helpful if you first become familiar with the basic internal architecture of HydePHP, as well as how the auto-discovery system works, so you can understand how your code works with the internals. @@ -37,6 +37,7 @@ that can all be added the same way as you would in Laravel, and are thus not par You may want to read up on the [Laravel package development guide](https://laravel.com/docs/10.x/packages) + ## Creating your Extension class The entry point for your extension is your Extensions class. Within this, you can register the custom page classes for your extension. @@ -113,9 +114,10 @@ class JsonPageExtension extends HydeExtension { Since the discovery steps are handled sequentially, the added pages will automatically be discovered as routes without us having to implement that handler method. As we inject the page objects directly, we bypass the need of the `FileCollection`. + ## Registering your extension -Now that we have our extension class, we need to register it with HydePHP. +Now that we have our extension class, we need to register it with HydePHP. It's important that your class is registered before the HydeKernel boots. Therefore, an excellent place for this is the `register` method of your extensions service provider, where you call the `registerExtension` method of the `HydeKernel` @@ -130,7 +132,7 @@ class JsonPageExtensionServiceProvider extends ServiceProvider { public function register(): void { // Via the service container: $this->app->make(HydeKernel::class)->registerExtension(JsonPageExtension::class); - + // Or via the facade: Hyde::registerExtension(JsonPageExtension::class); } From ab6c966fa7b7548d627c0f7c1945bd57cd0a78f6 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Thu, 16 Nov 2023 19:11:43 +0100 Subject: [PATCH 8/8] Improve flow of article --- docs/architecture-concepts/extensions-api.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/architecture-concepts/extensions-api.md b/docs/architecture-concepts/extensions-api.md index b513501ddb3..9ed5a4bcab3 100644 --- a/docs/architecture-concepts/extensions-api.md +++ b/docs/architecture-concepts/extensions-api.md @@ -10,6 +10,8 @@ The Extensions API a powerful interface designed for package developers who want Using the API, you can hook directly into the HydePHP Kernel and extend sites with custom page types and new features. +This documentation page functions heavily through examples, so it's recommended that the sections are read in order. + ### Prerequisites Before creating your extension, it will certainly be helpful if you first become familiar with @@ -20,8 +22,6 @@ so you can understand how your code works with the internals. - [Architecture concepts](architecture-concepts) - [Autodiscovery](autodiscovery) -This documentation page will function heavily through examples, so it's recommended that you first read the sections in order. - ### The why and how of the Extensions API HydePHP being a static site generator, the Extensions API is centered around [Page Models](page-models), @@ -32,16 +32,15 @@ This may sound like a small thing, but it's actually incredibly powerful as the of HydePHP's functionality. They tell the system how to discover pages, how to render them, and how they interact with the site. -Any other functionality you want to add to HydePHP, such as new commands, new configuration options, -that can all be added the same way as you would in Laravel, and are thus not part of the Extensions API. - -You may want to read up on the [Laravel package development guide](https://laravel.com/docs/10.x/packages) +Any other functionality you want to add to HydePHP, such as new commands or configuration options, +can be added the same way as you would in Laravel, and are thus not part of our API. +See the [Laravel package development guide](https://laravel.com/docs/10.x/packages) for more. ## Creating your Extension class -The entry point for your extension is your Extensions class. Within this, you can register the custom page classes for your extension. -If needed, you can also register discovery handlers which can run custom logic at various points in the boot process. +The entry-point for your extension is your Extensions class. Within this, you can register the custom page classes. +If needed, you can also register discovery handlers which can run custom logic at various parts of the boot process. In this article we will create an extension that registers a new type of page, a `JsonPageExtension`.