Skip to content

Commit c0df45b

Browse files
authored
Merge pull request #1465 from hydephp/document-extensions-api
Document the Extensions API
2 parents 64bb5df + ab6c966 commit c0df45b

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
---
2+
navigation.priority: 1000
3+
---
4+
5+
# The Extensions API
6+
7+
## Introduction
8+
9+
The Extensions API a powerful interface designed for package developers who want to extend the functionality of HydePHP.
10+
11+
Using the API, you can hook directly into the HydePHP Kernel and extend sites with custom page types and new features.
12+
13+
This documentation page functions heavily through examples, so it's recommended that the sections are read in order.
14+
15+
### Prerequisites
16+
17+
Before creating your extension, it will certainly be helpful if you first become familiar with
18+
the basic internal architecture of HydePHP, as well as how the auto-discovery system works,
19+
so you can understand how your code works with the internals.
20+
21+
- [Core concepts overview](core-concepts)
22+
- [Architecture concepts](architecture-concepts)
23+
- [Autodiscovery](autodiscovery)
24+
25+
### The why and how of the Extensions API
26+
27+
HydePHP being a static site generator, the Extensions API is centered around [Page Models](page-models),
28+
which you are hopefully already familiar with, otherwise you should read up on them first.
29+
30+
What the Extensions API does is to allow you to create custom page types, and tell HydePHP how to discover them.
31+
This may sound like a small thing, but it's actually incredibly powerful as the page models are the foundation
32+
of HydePHP's functionality. They tell the system how to discover pages, how to render them,
33+
and how they interact with the site.
34+
35+
Any other functionality you want to add to HydePHP, such as new commands or configuration options,
36+
can be added the same way as you would in Laravel, and are thus not part of our API.
37+
See the [Laravel package development guide](https://laravel.com/docs/10.x/packages) for more.
38+
39+
40+
## Creating your Extension class
41+
42+
The entry-point for your extension is your Extensions class. Within this, you can register the custom page classes.
43+
If needed, you can also register discovery handlers which can run custom logic at various parts of the boot process.
44+
45+
In this article we will create an extension that registers a new type of page, a `JsonPageExtension`.
46+
47+
The first step is to create a class that extends the `HydeExtension` class:
48+
49+
```php
50+
use Hyde\Foundation\Concerns\HydeExtension;
51+
52+
class JsonPageExtension extends HydeExtension {
53+
//
54+
}
55+
```
56+
57+
In here, we will register our extension class name in the `getPageClasses` method:
58+
59+
```php
60+
class JsonPageExtension extends HydeExtension {
61+
public static function getPageClasses(): array {
62+
return [
63+
JsonPage::class,
64+
];
65+
}
66+
}
67+
```
68+
69+
Hyde will then use the information from the `JsonPage` class to automatically discover the pages when booting the Kernel.
70+
For example, if you specify the file extension and source directory, that is all Hyde needs to know to discover the pages.
71+
72+
If our pages need more complex discovery logic, we can create custom handlers. so let's take a quick look at that next.
73+
74+
### Discovery handlers
75+
76+
The discovery handlers lets you run code at various points of the booting process. This is usually only needed if your
77+
page models cannot provide the information required for Hyde run the standard auto-discovery, and thus need custom logic.
78+
79+
Usually in these cases, you would only need to add files to the Kernel `FileCollection`,
80+
though the `HydeExtension` class offers following three discovery handlers, in case you need them:
81+
82+
```php
83+
/** Runs during file discovery */
84+
public function discoverFiles(FileCollection $collection): void;
85+
86+
/** Runs during page discovery */
87+
public function discoverPages(PageCollection $collection): void;
88+
89+
/** Runs during route discovery */
90+
public function discoverRoutes(RouteCollection $collection): void;
91+
```
92+
93+
Any of these can be implemented in your extension class, and they will be called during the discovery. As you can see,
94+
the instance of the discovery collection is injected into the method for you to interact with.
95+
96+
#### Discovery handler example
97+
98+
Let's go crazy and implement a discovery handler to collect `JsonPage` files from an external API! We will do this
99+
by implementing the `discoverPages` method in our extension class, and from there inject pages retrieved from our API.
100+
101+
```php
102+
class JsonPageExtension extends HydeExtension {
103+
public function discoverPages(PageCollection $collection): void {
104+
$pages = Http::get('https://example.com/my-api')->collect();
105+
106+
$pages->each(function (array $page) use ($collection): void {
107+
$collection->addPage(JsonPage::fromArray($page));
108+
});
109+
}
110+
}
111+
```
112+
113+
Since the discovery steps are handled sequentially, the added pages will automatically be discovered as routes without
114+
us having to implement that handler method. As we inject the page objects directly, we bypass the need of the `FileCollection`.
115+
116+
117+
## Registering your extension
118+
119+
Now that we have our extension class, we need to register it with HydePHP.
120+
121+
It's important that your class is registered before the HydeKernel boots. Therefore, an excellent place for this is the
122+
`register` method of your extensions service provider, where you call the `registerExtension` method of the `HydeKernel`
123+
singleton instance, which you can access via the `Hyde\Hyde` facade, or via the service container.
124+
125+
```php
126+
use Hyde\Hyde;
127+
use Hyde\Foundation\HydeKernel;
128+
use Illuminate\Support\ServiceProvider;
129+
130+
class JsonPageExtensionServiceProvider extends ServiceProvider {
131+
public function register(): void {
132+
// Via the service container:
133+
$this->app->make(HydeKernel::class)->registerExtension(JsonPageExtension::class);
134+
135+
// Or via the facade:
136+
Hyde::registerExtension(JsonPageExtension::class);
137+
}
138+
}
139+
```
140+
141+
### Packaging your extension
142+
143+
To make your extension available to other HydePHP users, you can make it into a [Composer](https://getcomposer.org/) package,
144+
and publish it to [Packagist](https://packagist.org/) for others to install.
145+
146+
If you register your service provider in your package's `composer.json` file, your extension automatically be enabled when
147+
the package is installed in a HydePHP project!
148+
149+
```json
150+
{
151+
"extra": {
152+
"laravel": {
153+
"providers": [
154+
"My\\Namespace\\JsonPageExtensionServiceProvider"
155+
]
156+
}
157+
}
158+
}
159+
```
160+
161+
### Telling the world about your extension
162+
163+
Next up, why not send us a Tweet at [@HydeFramework](https://twitter.com/HydeFramework) and tell us about your extension,
164+
so we can feature it?

0 commit comments

Comments
 (0)