Skip to content

Instantly share code, notes, and snippets.

@knorthfield
Created February 6, 2026 11:39
Show Gist options
  • Select an option

  • Save knorthfield/09926db0d090e9177ea9a4057293f4b2 to your computer and use it in GitHub Desktop.

Select an option

Save knorthfield/09926db0d090e9177ea9a4057293f4b2 to your computer and use it in GitHub Desktop.
<?php
namespace Valet\Drivers\Custom;
use Valet\Drivers\ValetDriver;
class HydeValetDriver extends ValetDriver
{
/**
* The output directory where Hyde compiles static files.
*/
private string $buildPath = '/_site';
/**
* Determine if the driver serves the request.
*
* Detects a HydePHP project by looking for the `hyde` CLI executable
* and the hyde configuration file.
*/
public function serves(string $sitePath, string $siteName, string $uri): bool
{
return file_exists($sitePath . '/hyde')
&& file_exists($sitePath . '/config/hyde.php')
&& is_dir($sitePath . $this->buildPath);
}
/**
* Determine if the incoming request is for a static file.
*
* Hyde compiles everything to static HTML/CSS/JS in _site/,
* so we check there for any matching file.
*/
public function isStaticFile(string $sitePath, string $siteName, string $uri): string|false
{
$staticPath = $sitePath . $this->buildPath . $uri;
// Direct file match (CSS, JS, images, etc.)
if ($this->isActualFile($staticPath)) {
return $staticPath;
}
// Clean URL support: /about -> /about.html
if ($this->isActualFile($staticPath . '.html')) {
return $staticPath . '.html';
}
// Directory with index: /docs/ -> /docs/index.html
if (is_dir($staticPath) && $this->isActualFile($staticPath . '/index.html')) {
return $staticPath . '/index.html';
}
return false;
}
/**
* Get the fully resolved path to the application's front controller.
*
* Since Hyde generates static HTML, we serve index.html as the front controller.
*/
public function frontControllerPath(string $sitePath, string $siteName, string $uri): ?string
{
// Try to serve the URI as a static file first
$staticFile = $this->isStaticFile($sitePath, $siteName, $uri);
if ($staticFile) {
return $staticFile;
}
// Fall back to the site root index.html
$indexPath = $sitePath . $this->buildPath . '/index.html';
if (file_exists($indexPath)) {
return $indexPath;
}
return null;
}
/**
* Get the log file paths for Herd's log viewer.
*/
public function logFilesPaths(): array
{
return ['/storage/logs'];
}
/**
* Display information about the Hyde site in Herd's Site Manager.
*/
public function siteInformation(string $sitePath, string $phpBinary): array
{
$info = [
'Overview' => [
'Framework' => 'HydePHP',
'Build Directory' => '_site',
],
];
// Read Hyde config for site name/URL if available
$configFile = $sitePath . '/config/hyde.php';
if (file_exists($configFile)) {
$info['Overview']['Config'] = 'config/hyde.php';
}
// Get composer.json for version info
$composerFile = $sitePath . '/composer.lock';
if (file_exists($composerFile)) {
$lock = json_decode(file_get_contents($composerFile), true);
foreach ($lock['packages'] ?? [] as $package) {
if ($package['name'] === 'hyde/framework') {
$info['Overview']['Hyde Version'] = $package['version'];
break;
}
}
}
// Count built pages
$buildDir = $sitePath . '/_site';
if (is_dir($buildDir)) {
$htmlFiles = glob($buildDir . '/{,*/,*/*/,*/*/*/}*.html', GLOB_BRACE);
$info['Build'] = [
'Pages' => count($htmlFiles) . ' HTML files',
'Built' => date('Y-m-d H:i:s', filemtime($buildDir)),
];
} else {
$info['Build'] = [
'Status' => '⚠ Not built yet — run: php hyde build',
];
}
return $info;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment