[{"slug":"README","title":"Hyde Documentation","content":"Hyde Documentation\n\nThis is the source for the HydePHP Documentation. Updates here are automatically propagated to the HydePHP.com website.\n\nThis document is not propagated to the website. It is only for the GitHub development repository.","destination":"README.html"},{"slug":"base-markdown-page-methods","title":"Base Markdown Page Methods","content":"make()\n\nCreate a new page instance. Static alias for the constructor.\n\nBaseMarkdownPage::make(string $identifier, Hyde\\Markdown\\Models\\FrontMatter|array $matter, Hyde\\Markdown\\Models\\Markdown|string $markdown): static\n\n__construct()\n\nConstruct a new page instance.\n\n$page = new BaseMarkdownPage(string $identifier, Hyde\\Markdown\\Models\\FrontMatter|array $matter, Hyde\\Markdown\\Models\\Markdown|string $markdown): void\n\nmarkdown()\n\nReturn the document&#039;s Markdown object.\n\n$page->markdown(): Hyde\\Markdown\\Models\\Markdown\n\ncompile()\n\nCompile the page into static HTML.\n\n$page->compile(): string \/\/ The compiled HTML for the page.\n\nsave()\n\nSave the Markdown page object to disk by compiling the front matter array to YAML and writing the body to the file.\n\n$page->save(): $this","destination":"base-markdown-page-methods.html"},{"slug":"blade-page-methods","title":"Blade Page Methods","content":"__construct()\n\nNo description provided.\n\n\/* @param string $identifier The identifier, which also serves as the view key. \/\n$page = new BladePage(string $identifier, Hyde\\Markdown\\Models\\FrontMatter|array $matter): void\n\ngetBladeView()\n\nGet the Blade template\/view key for the page.\n\n$page->getBladeView(): string\n\ncompile()\n\nCompile the page into static HTML.\n\n$page->compile(): string \/\/ The compiled HTML for the page.","destination":"blade-page-methods.html"},{"slug":"documentation-page-methods","title":"Documentation Page Methods","content":"home()\n\nNo description provided.\n\nDocumentationPage::home(): Hyde\\Support\\Models\\Route\n\nhomeRouteName()\n\nNo description provided.\n\nDocumentationPage::homeRouteName(): string\n\ngetOnlineSourcePath()\n\nNo description provided.\n\n$page->getOnlineSourcePath(): string|false\n\ngetRouteKey()\n\nGet the route key for the page.\n\nIf flattened outputs are enabled, this will use the identifier basename so nested pages are flattened.\n\n$page->getRouteKey(): string\n\ngetOutputPath()\n\nGet the path where the compiled page will be saved.\n\nIf flattened outputs are enabled, this will use the identifier basename so nested pages are flattened.\n\n$page->getOutputPath(): string","destination":"documentation-page-methods.html"},{"slug":"html-page-methods","title":"Html Page Methods","content":"contents()\n\nNo description provided.\n\n$page->contents(): string\n\ncompile()\n\nNo description provided.\n\n$page->compile(): string\n\ngetBladeView()\n\nNo description provided.\n\n$page->getBladeView(): string","destination":"html-page-methods.html"},{"slug":"hyde-kernel-base-methods","title":"Hyde Kernel Base Methods","content":"version()\n\nNo description provided.\n\nHyde::version(): string\n\n__construct()\n\nNo description provided.\n\n$hyde = new HydeKernel(string $basePath): void\n\nfeatures()\n\nNo description provided.\n\nHyde::features(): Hyde\\Facades\\Features\n\nhasFeature()\n\nNo description provided.\n\nHyde::hasFeature(Hyde\\Enums\\Feature $feature): bool\n\ntoArray()\n\nGet the instance as an array.\n\nHyde::toArray(): array","destination":"hyde-kernel-base-methods.html"},{"slug":"hyde-kernel-boot-methods","title":"Hyde Kernel Boot Methods","content":"isBooted()\n\nDetermine if the Kernel has booted.\n\nHyde::isBooted(): bool\n\nboot()\n\nBoot the Hyde Kernel and run the Auto-Discovery Process.\n\nHyde::boot(): void\n\nbooting()\n\nRegister a new boot listener.\n\nYour callback will be called before the kernel is booted. You can use this to register your own routes, pages, etc. The kernel instance will be passed to your callback.\n\n\/* @param callable(\\Hyde\\Foundation\\HydeKernel): void $callback \/\nHyde::booting(callable(\\Hyde\\Foundation\\HydeKernel): void): void\n\nbooted()\n\nRegister a new &quot;booted&quot; listener.\n\nYour callback will be called after the kernel is booted. You can use this to run any logic after discovery has completed. The kernel instance will be passed to your callback.\n\n\/* @param callable(\\Hyde\\Foundation\\HydeKernel): void $callback \/\nHyde::booted(callable(\\Hyde\\Foundation\\HydeKernel): void): void","destination":"hyde-kernel-boot-methods.html"},{"slug":"hyde-kernel-extensions-methods","title":"Hyde Kernel Extensions Methods","content":"registerExtension()\n\nRegister a HydePHP extension within the HydeKernel.\n\nTypically, you would call this method in the register method of a service provider. If your package uses the standard Laravel (Composer) package discovery feature, the extension will automatically be enabled when the package is installed.\n\nHyde::registerExtension(class-string&lt;\\Hyde\\Foundation\\Concerns\\HydeExtension&gt; $extension): void\n\ngetExtension()\n\nGet the singleton instance of the specified extension.\n\nHyde::getExtension(class-string&lt;T&gt; $extension): T\n\nhasExtension()\n\nDetermine if the specified extension is registered.\n\nHyde::hasExtension(class-string&lt;\\Hyde\\Foundation\\Concerns\\HydeExtension&gt; $extension): bool\n\ngetExtensions()\n\nNo description provided.\n\nHyde::getExtensions(): array\n\ngetRegisteredExtensions()\n\nNo description provided.\n\nHyde::getRegisteredExtensions(): array>\n\ngetRegisteredPageClasses()\n\nNo description provided.\n\nHyde::getRegisteredPageClasses(): array>","destination":"hyde-kernel-extensions-methods.html"},{"slug":"hyde-kernel-filesystem-methods","title":"Hyde Kernel Filesystem Methods","content":"filesystem()\n\nNo description provided.\n\nHyde::filesystem(): Hyde\\Foundation\\Kernel\\Filesystem\n\npath()\n\nNo description provided.\n\nHyde::path(string $path): string\n\nvendorPath()\n\nNo description provided.\n\nHyde::vendorPath(string $path, string $package): string\n\nsitePath()\n\nNo description provided.\n\nHyde::sitePath(string $path): string\n\npathToAbsolute()\n\nNo description provided.\n\nHyde::pathToAbsolute(array|string $path): array|string\n\npathToRelative()\n\nNo description provided.\n\nHyde::pathToRelative(string $path): string\n\nassets()\n\nNo description provided.\n\nHyde::assets(): \\Illuminate\\Support\\Collection","destination":"hyde-kernel-filesystem-methods.html"},{"slug":"hyde-kernel-foundation-methods","title":"Hyde Kernel Foundation Methods","content":"files()\n\nNo description provided.\n\nHyde::files(): Hyde\\Foundation\\Kernel\\FileCollection\n\npages()\n\nNo description provided.\n\nHyde::pages(): Hyde\\Foundation\\Kernel\\PageCollection\n\nroutes()\n\nNo description provided.\n\nHyde::routes(): Hyde\\Foundation\\Kernel\\RouteCollection","destination":"hyde-kernel-foundation-methods.html"},{"slug":"hyde-kernel-hyperlink-methods","title":"Hyde Kernel Hyperlink Methods","content":"formatLink()\n\nNo description provided.\n\nHyde::formatLink(string $destination): string\n\nrelativeLink()\n\nNo description provided.\n\nHyde::relativeLink(string $destination): string\n\nasset()\n\nNo description provided.\n\nHyde::asset(string $name): Hyde\\Support\\Filesystem\\MediaFile\n\nThrows:** \\Hyde\\Framework\\Exceptions\\FileNotFoundException If the file does not exist in the _media source directory.\n\nurl()\n\nNo description provided.\n\nHyde::url(string $path): string\n\nroute()\n\nNo description provided.\n\nHyde::route(string $key): Hyde\\Support\\Models\\Route\n\nhasSiteUrl()\n\nNo description provided.\n\nHyde::hasSiteUrl(): bool","destination":"hyde-kernel-hyperlink-methods.html"},{"slug":"hyde-kernel-kernel-methods","title":"Hyde Kernel Kernel Methods","content":"getInstance()\n\nNo description provided.\n\nHyde::getInstance(): Hyde\\Foundation\\HydeKernel\n\nsetInstance()\n\nNo description provided.\n\nHyde::setInstance(Hyde\\Foundation\\HydeKernel $instance): void\n\ngetBasePath()\n\nNo description provided.\n\nHyde::getBasePath(): string\n\nsetBasePath()\n\nNo description provided.\n\nHyde::setBasePath(string $basePath): void\n\ngetSourceRoot()\n\nNo description provided.\n\nHyde::getSourceRoot(): string\n\nsetSourceRoot()\n\nNo description provided.\n\nHyde::setSourceRoot(string $sourceRoot): void\n\ngetOutputDirectory()\n\nNo description provided.\n\nHyde::getOutputDirectory(): string\n\nsetOutputDirectory()\n\nNo description provided.\n\nHyde::setOutputDirectory(string $outputDirectory): void\n\ngetMediaDirectory()\n\nNo description provided.\n\nHyde::getMediaDirectory(): string\n\nsetMediaDirectory()\n\nNo description provided.\n\nHyde::setMediaDirectory(string $mediaDirectory): void\n\ngetMediaOutputDirectory()\n\nNo description provided.\n\nHyde::getMediaOutputDirectory(): string","destination":"hyde-kernel-kernel-methods.html"},{"slug":"hyde-kernel-string-methods","title":"Hyde Kernel String Methods","content":"makeTitle()\n\nNo description provided.\n\nHyde::makeTitle(string $value): string\n\nmakeSlug()\n\nNo description provided.\n\nHyde::makeSlug(string $value): string\n\nnormalizeNewlines()\n\nNo description provided.\n\nHyde::normalizeNewlines(string $string): string\n\nstripNewlines()\n\nNo description provided.\n\nHyde::stripNewlines(string $string): string\n\ntrimSlashes()\n\nNo description provided.\n\nHyde::trimSlashes(string $string): string\n\nmarkdown()\n\nNo description provided.\n\nHyde::markdown(string $text, bool $normalizeIndentation): Illuminate\\Support\\HtmlString","destination":"hyde-kernel-string-methods.html"},{"slug":"hyde-kernel-view-methods","title":"Hyde Kernel View Methods","content":"shareViewData()\n\nShare data for the page being rendered.\n\nHyde::shareViewData(Hyde\\Pages\\Concerns\\HydePage $page): void\n\ncurrentRouteKey()\n\nGet the route key for the page being rendered.\n\nHyde::currentRouteKey(): string\n\ncurrentRoute()\n\nGet the route for the page being rendered.\n\nHyde::currentRoute(): Hyde\\Support\\Models\\Route\n\ncurrentPage()\n\nGet the page being rendered.\n\nHyde::currentPage(): Hyde\\Pages\\Concerns\\HydePage","destination":"hyde-kernel-view-methods.html"},{"slug":"hyde-page-methods","title":"Hyde Page Methods","content":"make()\n\nCreate a new page instance. Static alias for the constructor.\n\nHydePage::make(string $identifier, Hyde\\Markdown\\Models\\FrontMatter|array $matter): static\n\nisDiscoverable()\n\nReturns whether the page type is discoverable through auto-discovery.\n\nHydePage::isDiscoverable(): bool\n\nget()\n\nGet a page instance from the Kernel&#039;s page index by its identifier.\n\nHydePage::get(string $identifier): static\n\nThrows:** \\Hyde\\Framework\\Exceptions\\FileNotFoundException If the page does not exist.\n\nparse()\n\nParse a source file into a new page model instance.\n\n\/* @param string $identifier The identifier of the page to parse. \/\nHydePage::parse(string $identifier): static \/\/ New page model instance for the parsed source file.\n\nThrows:** \\Hyde\\Framework\\Exceptions\\FileNotFoundException If the file does not exist.\n\nfiles()\n\nGet an array of all the source file identifiers for the model.\n\nNote that the values do not include the source directory or file extension.\n\nHydePage::files(): array\n\nall()\n\nGet a collection of all pages, parsed into page models.\n\nHydePage::all(): \\Hyde\\Foundation\\Kernel\\PageCollection\n\nsourceDirectory()\n\nGet the directory where source files are stored for the page type.\n\nHydePage::sourceDirectory(): string\n\noutputDirectory()\n\nGet the output subdirectory to store compiled HTML files for the page type.\n\nHydePage::outputDirectory(): string\n\nfileExtension()\n\nGet the file extension of the source files for the page type.\n\nHydePage::fileExtension(): string\n\nsetSourceDirectory()\n\nSet the output directory for the page type.\n\nHydePage::setSourceDirectory(string $sourceDirectory): void\n\nsetOutputDirectory()\n\nSet the source directory for the page type.\n\nHydePage::setOutputDirectory(string $outputDirectory): void\n\nsetFileExtension()\n\nSet the file extension for the page type.\n\nHydePage::setFileExtension(string $fileExtension): void\n\nsourcePath()\n\nQualify a page identifier into file path to the source file, relative to the project root.\n\nHydePage::sourcePath(string $identifier): string\n\noutputPath()\n\nQualify a page identifier into a target output file path, relative to the _site output directory.\n\nHydePage::outputPath(string $identifier): string\n\npath()\n\nGet an absolute file path to the page&#039;s source directory, or a file within it.\n\nHydePage::path(string $path): string\n\npathToIdentifier()\n\nFormat a filename to an identifier for a given model. Unlike the basename function, any nested paths within the source directory are retained in order to satisfy the page identifier definition.\n\n\/* @param string $path Example: index.blade.php \/\nHydePage::pathToIdentifier(string $path): string \/\/ Example: index\n\nbaseRouteKey()\n\nGet the route key base for the page model.\n\nThis is the same value as the output directory.\n\nHydePage::baseRouteKey(): string\n\n__construct()\n\nConstruct a new page instance.\n\n$page = new HydePage(string $identifier, Hyde\\Markdown\\Models\\FrontMatter|array $matter): void\n\ncompile()\n\nCompile the page into static HTML.\n\n$page->compile(): string \/\/ The compiled HTML for the page.\n\ntoArray()\n\nGet the instance as an array.\n\n$page->toArray(): array\n\ngetSourcePath()\n\nGet the path to the instance source file, relative to the project root.\n\n$page->getSourcePath(): string\n\ngetOutputPath()\n\nGet the path where the compiled page will be saved.\n\n$page->getOutputPath(): string \/\/ Path relative to the site output directory.\n\ngetRouteKey()\n\nGet the route key for the page.\n\nThe route key is the page URL path, relative to the site root, but without any file extensions. For example, if the page will be saved to _site\/docs\/index.html, the key is docs\/index.\n\nRoute keys are used to identify page routes, similar to how named routes work in Laravel, only that here the name is not just arbitrary, but also defines the output location, as the route key is used to determine the output path which is $routeKey.html.\n\n$page->getRouteKey(): string\n\ngetRoute()\n\nGet the route object for the page.\n\n$page->getRoute(): Hyde\\Support\\Models\\Route\n\ngetLink()\n\nFormat the page instance to a URL path, with support for pretty URLs if enabled.\n\nNote that the link is always relative to site root, and does not contain ..\/ segments.\n\n$page->getLink(): string\n\ngetIdentifier()\n\nGet the page model&#039;s identifier property.\n\nThe identifier is the part between the source directory and the file extension. It may also be known as a &#039;slug&#039;, or previously &#039;basename&#039;, but it retains the nested path structure if the page is stored in a subdirectory.\n\nFor example, the identifier of a source file stored as &#039;_pages\/about\/contact.md&#039; would be &#039;about\/contact&#039;, and &#039;pages\/about.md&#039; would simply be &#039;about&#039;.\n\n$page->getIdentifier(): string\n\ngetBladeView()\n\nGet the Blade template\/view key for the page.\n\n$page->getBladeView(): string\n\ntitle()\n\nGet the page title to display in HTML tags like ` and ` tags.\n\n$page->title(): string\n\nmetadata()\n\nGet the generated metadata for the page.\n\n$page->metadata(): Hyde\\Framework\\Features\\Metadata\\PageMetadataBag\n\nshowInNavigation()\n\nCan the page be shown in the navigation menu?\n\n$page->showInNavigation(): bool\n\nnavigationMenuPriority()\n\nGet the priority of the page in the navigation menu.\n\n$page->navigationMenuPriority(): int\n\nnavigationMenuLabel()\n\nGet the label of the page in the navigation menu.\n\n$page->navigationMenuLabel(): string\n\nnavigationMenuGroup()\n\nGet the group of the page in the navigation menu, if any.\n\n$page->navigationMenuGroup(): string\n\ngetCanonicalUrl()\n\nGet the canonical URL for the page to use in the `` tag.\n\nIt can be explicitly set in the front matter using the canonicalUrl key, otherwise it will be generated based on the site URL and the output path, unless there is no configured base URL, leading to this returning null.\n\n$page->getCanonicalUrl(): string","destination":"hyde-page-methods.html"},{"slug":"in-memory-page-methods","title":"In Memory Page Methods","content":"make()\n\nStatic alias for the constructor.\n\nInMemoryPage::make(string $identifier, Hyde\\Markdown\\Models\\FrontMatter|array $matter, string $contents, string $view): static\n\n__construct()\n\nCreate a new in-memory\/virtual page instance.\n\nThe in-memory page class offers two content options. You can either pass a string to the $contents parameter, Hyde will then save that literally as the page&#039;s contents. Alternatively, you can pass a view name to the $view parameter, and Hyde will use that view to render the page contents with the supplied front matter during the static site build process.\n\nNote that $contents take precedence over $view, so if you pass both, only $contents will be used. You can also register a macro with the name &#039;compile&#039; to overload the default compile method.\n\nIf the identifier for an in-memory page is &quot;foo\/bar&quot; the page will be saved to &quot;_site\/foo\/bar.html&quot;. You can then also use the route helper to get a link to it by using the route key &quot;foo\/bar&quot;. Take note that the identifier must be unique to prevent overwriting other pages. all this data will be passed to the view rendering engine.\nParameter $view:** The view key or Blade file for the view to use to render the page contents.\nParameter $matter:** The front matter of the page. When using the Blade view rendering option,\n\n$page = new InMemoryPage(string $identifier, \\Hyde\\Markdown\\Models\\FrontMatter|array $matter, string $contents, string $view): void\n\ngetContents()\n\nGet the contents of the page. This will be saved as-is to the output file when this strategy is used.\n\n$page->getContents(): string\n\ngetBladeView()\n\nGet the view key or Blade file for the view to use to render the page contents when this strategy is used.\n\n$page->getBladeView(): string\n\ncompile()\n\nGet the contents that will be saved to disk for this page.\n\nIn order to make your virtual page easy to use we provide a few options for how the page can be compiled. If you want even more control, you can register a macro with the name &#039;compile&#039; to overload the method, or simply extend the class and override the method yourself, either in a standard or anonymous class.\n\n$page->compile(): string\n\nmacro()\n\nRegister a macro for the instance.\n\nUnlike most macros you might be used to, these are not static, meaning they belong to the instance. If you have the need for a macro to be used for multiple pages, you should create a custom page class instead.\n\n$page->macro(string $name, callable $macro): void\n\nhasMacro()\n\nDetermine if a macro with the given name is registered for the instance.\n\n$page->hasMacro(string $method): bool\n\n__call()\n\nDynamically handle macro calls to the class.\n\n$page->__call(string $method, array $parameters): mixed","destination":"in-memory-page-methods.html"},{"slug":"interacts-with-front-matter-methods","title":"Interacts with Front Matter Methods","content":"data()\n\nGet a value from the computed page data, or fallback to the page&#039;s front matter, then to the default value.\n\n$page->data(string $key, mixed $default): \\Hyde\\Markdown\\Models\\FrontMatter|mixed\n\nmatter()\n\nGet the front matter object, or a value from within.\n\n$page->matter(string $key, mixed $default): \\Hyde\\Markdown\\Models\\FrontMatter|mixed\n\nhas()\n\nSee if a value exists in the computed page data or the front matter.\n\n$page->has(string $key): bool","destination":"interacts-with-front-matter-methods.html"},{"slug":"markdown-page-methods","title":"Markdown Page Methods","content":"","destination":"markdown-page-methods.html"},{"slug":"markdown-post-methods","title":"Markdown Post Methods","content":"getLatestPosts()\n\nNo description provided.\n\nMarkdownPost::getLatestPosts(): \\Hyde\\Foundation\\Kernel\\PageCollection\n\ntoArray()\n\nNo description provided.\n\n$page->toArray(): array","destination":"markdown-post-methods.html"},{"slug":"advanced-features","title":"Advanced Features in HydePHP","content":"Advanced Features in HydePHP\n\nPreface\n\nHydePHP is a simple, yet powerful, static site generator. It is designed to be easy to use and easy to extend.\n\nThis section of the documentation will cover some of the more advanced (but optional) features of the framework.\n\nPrerequisites\n\nTo fully understand the features described in these chapters, it may be beneficial to first skim through the\nArchitecture Concepts chapters, or at the very least, the Core Concepts page.\n\nYou are also expected to have a basic understanding of PHP, and object-oriented programming principles.\n\nHaving some familiarity with Laravel will also be beneficial, as HydePHP is built on top of the Laravel framework.\n\nTable of Contents\n\n[Blade]: @foreach(glob(DocumentationPage::path('advanced-features\/*.md')) as $file)   {{ Hyde::makeTitle(basename($file, '.md')) }}   @endforeach","destination":"advanced-features.html"},{"slug":"build-tasks","title":"Custom Build Tasks","content":"Custom Build Tasks\n\nIntroduction\n\nThe Build Task API offers a simple way to hook into the build process.\nThe build tasks are very powerful and allow for limitless customizability.\n\nThe built-in Hyde features like sitemap generation and RSS feeds are created using tasks like these.\nMaybe you want to create your own, to for example upload the site to FTP or copy the files to a public directory?\nYou can also overload the built-in tasks to customize them to your needs.\n\nGood to know before you start\n\nTypes of tasks\n\nThere are two types, PreBuildTasks and PostBuildTasks. As the names suggest, PreBuildTasks are executed before the site is built, and PostBuildTasks are executed after the site is built.\n\nTo choose which type of task you want to create, you extend either the PreBuildTask or PostBuildTask class.\nBoth of these have the exact same helpers and API available, so the only difference between them is when they are executed. The classes are otherwise identical.\n\nAbout these examples\n\nFor most of these examples we will focus on the PostBuildTasks as they are the most common.\n\nFor all these examples we assume you put the file in the App\/Actions directory, but you can put them anywhere.\n\nInteracting with output\n\nIn a way, build tasks are like micro-commands, as they can interact directly with the build commands I\/O. Please take a look at the Laravel Console Documentation for the full list of available methods.\n\nIn addition, there are some extra helpers available in the base BuildTask class that allow you to fluently format output to the console, which you will see in the examples below.\n\nCreating Build Tasks\n\nMinimal example\n\nHere is a minimal example to give you an idea of what we are working with.\n\nclass SimpleBuildTask extends PostBuildTask\n{\npublic function handle(): void\n{\n\/\/\n}\n}\n\nAs you can see, at their core, build tasks are simple classes containing a handle() method,\nwhich as I'm sure you have guessed, is the method that is executed when the task is run by the build command.\n\nIf you want the task to run before the build, you would extend the PreBuildTask class instead.\n\nAutomatic output\n\nWhen running the build command, you will see the following output added after the build is complete.\n\nGeneric build task... Done in 0.26ms\n\nAs you can see, some extra output including execution time tracking is added for us. We can of course customize all of this if we want, as you will learn a bit further down.\n\nFull example\n\nHere is a full example, with all the namespaces included, as well as the most common fluent output helpers.\n\ninfo('Hello World!');\n}\n\npublic function printFinishMessage(): void\n{\n$this->line('Goodbye World!');\n}\n}\n\nYou can see a full API reference further below. But in short, the $message property is the message that runs before the task is executed, and the printFinishMessage() method is the message that runs after the task is executed.\n\nRunning this task will produce the following output:\n\n$ php hyde build\nSay hello... Hello World!\nGoodbye World!\n\nAs you can see, there is no execution time tracking here, since we overrode the printFinishMessage() method that normally prints this. You can of course call the withExecutionTime() method to add this back in. See more in the API reference below.\n\nRegistering the Tasks\n\nThere are a few ways to register these tasks so Hyde can find them.\n\nThey are shown here in order of presumed convenience, but you are free to choose whichever you prefer. The latter options are more suited for extension developers.\n\nAutodiscovery registration\n\nThe easiest way to register build tasks is to not do it -- just let Hyde do it for you!\n\nAny classes that end in BuildTask.php that are stored in app\/Actions  will be autoloaded and registered to run automatically.\n\nFor example: app\/Actions\/ExampleBuildTask.php.\n\nConfig file registration\n\nIf you want, you can also register build tasks of any namespace in the convenient build_tasks array which is in the main configuration file, config\/hyde.php.\n\n\/\/ filepath config\/hyde.php\n'build_tasks' => [\n\\App\\Actions\\SimpleTask::class,\n\\MyPackage\\Tasks\\MyBuildTask::class,\n],\n\nProgrammatic registration\n\ninfo This option assumes you are familiar with Laravel's service container and service providers.\n\nIf you are developing an extension, you can either instruct users register your tasks with the config option above,\nor you can register the extensions programmatically, I recommend you do this in the boot method of a service provider.\n\nThe build tasks are registered in an internal array of the BuildService class, which is bound as a singleton in the underlying Laravel service container.\nTo actually register your task, provide the fully qualified class name of the task to the BuildTaskService::registerTask() method.\n\nHere is an example of how to do this using a service provider. Though you could technically do it anywhere using the app() helper,\njust as long as it's done early enough in the application lifecycle, so it's registered before the build command is executed.\n\nclass MyServiceProvider extends ServiceProvider\n{\npublic function boot(): void\n{\n$this->app->make(\\Hyde\\Framework\\Services\\BuildTaskService::class)\n            ->registerTask(\\MyPackage\\Tasks\\MyBuildTask::class);\n}\n}\n\nError Handling\n\nIf an exception is thrown in a build task, the build command will catch it and display the error message to the user.\n\nHelper Methods\n\nOutput helpers\n\nWhen a build task is called by the site build command, it gets access to the Laravel and Symfony console output helpers through the $output property.\n\npublic function handle(): void\n{\n\/* @var \\Illuminate\\Console\\OutputStyle $output \/\n\n$this->output->info('Hello World!');\n$this->output->error('Something went wrong!');\n$this->output->writeln('This is a line of text');\n}\n\nSkipping tasks\n\ninfo This feature was added in HydePHP v1.6.0\n\nIf you for some reason need to skip the task during its execution, you can call the skip() method.\n\npublic function handle(): void\n{\nif ($this->someCondition() !== true) {\n$this->skip('Some condition was not met');\n\n\/\/ The task will not be executed past this point\n}\n}\n\nThis will then halt the execution of the task, and display a notice with the message you provided to the console.","destination":"build-tasks.html"},{"slug":"hyde-pages","title":"HydePage API Reference","content":"# HydePage API Reference\n\nwarning This article covers advanced information, and you are expected to already be familiar with Page Models and OOP\n\n## Abstract\n\nThis page contains the full API references for the built-in HydePage classes. Most users will not need to know about\nthe inner workings of classes, but if you're interested in extending HydePHP, or just curious, this page is for you.\nIt is especially useful if you're looking to implement your own page classes, or if you are creating advanced Blade templates.\n\n### About the reference\n\nThis document is heavily based around the actual source code, as I believe the best way to understand the code is to read it.\nHowever, large parts of the code are simplified for brevity and illustration. The code is not meant to be copy-pasted, but\nrather used as a reference so that you know what to look for in the actual source code, if you want to dig deeper.\n\n#### Inheritance\n\nSince all HydePages extend the base HydePage class, those shared methods are only listed once,\nunder the HydePage class documentation which is conveniently located just below this section.\n\n### Table of Contents\n\nClass                                   Description\n\nHydePage                   The base class for all Hyde pages.\nBaseMarkdownPage   The base class for all Markdown pages.\nInMemoryPage           Extendable class for in-memory pages.\nBladePage              Class for Blade pages.\nMarkdownPage           Class for Markdown pages.\nMarkdownPost           Class for Markdown posts.\nDocumentationPage Class for documentation pages.\nHtmlPage                   Class for HTML pages.\n\n## HydePage\n\nThe base class for all Hyde pages. All other page classes extend this class.\n\nUnlike other frameworks, you generally don't instantiate pages yourself in Hyde. Instead, the page models act as\nblueprints defining information for Hyde to know how to parse a file, and what data around it should be generated.\n\nTo get a parsed file instance, you'd typically just create a source file, and you can then access the parsed file\nfrom the HydeKernel's page index.\n\nIn Blade views, you can always access the current page instance being rendered using the $page variable.\n\n### Quick Reference\n\nClass Name Namespace             Source Code                                                                                        API Docs\n\nHydePage Hyde\\Pages\\Concerns Open in GitHub Live API Docs\n\n### Base Structure\n\n\/**\n * The base class for all Hyde pages. Here simplified for the sake of brevity.\n *\/\nabstract class HydePage\n{\n\/**\n     * The directory in which source files are stored. Relative to the project root.\n     *\/\npublic static string $sourceDirectory;\n\n\/**\n     * The output subdirectory to store compiled HTML. Relative to the _site output directory.\n     *\/\npublic static string $outputDirectory;\n\n\/**\n     * The file extension of the source files.\n     *\/\npublic static string $fileExtension;\n\n\/**\n     * The default template to use for rendering the page.\n     *\/\npublic static string $template;\n\n\/**\n     * The page instance identifier.\n     *\/\npublic readonly string $identifier;\n\n\/**\n     * The page instance route key.\n     *\/\npublic readonly string $routeKey;\n\n\/**\n     * The parsed front matter.\n     *\/\npublic FrontMatter $matter;\n\n\/**\n     * The generated page metadata.\n     *\/\npublic PageMetadataBag $metadata;\n\n\/**\n     * The generated page navigation data.\n     *\/\npublic NavigationData $navigation;\n}\n\n### Methods\n\nwarning Heads up! The following methods are defined in the HydePage class, and are thus available to all page classes. Since the HydePage class is abstract, you cannot instantiate it directly, and many of the static methods are also only callable from the child classes.\n\n[Blade]: {{ Hyde\\Markdown\\Models\\Markdown::fromFile(DocumentationPage::sourcePath('_data\/partials\/hyde-pages-api\/hyde-page-methods'))->toHtml($page::class) }}\n\n[Blade]: {{ Hyde\\Markdown\\Models\\Markdown::fromFile(DocumentationPage::sourcePath('_data\/partials\/hyde-pages-api\/interacts-with-front-matter-methods'))->toHtml($page::class) }}\n\n## BaseMarkdownPage\n\nThe base class for all Markdown-based page models, with additional helpers tailored for Markdown pages.\n\n### Quick Reference\n\nClass Name         Namespace             Source Code                                                                                                API Docs\n\nBaseMarkdownPage Hyde\\Pages\\Concerns Open in GitHub Live API Docs\n\n### Base Structure\n\n\/**\n * The base class for all Markdown-based page models. Here simplified for the sake of brevity.\n *\/\nabstract class BaseMarkdownPage extends HydePage\n{\npublic Markdown $markdown;\n\npublic static string $fileExtension = '.md';\n}\n\n### Methods\n\n[Blade]: {{ Hyde\\Markdown\\Models\\Markdown::fromFile(DocumentationPage::sourcePath('_data\/partials\/hyde-pages-api\/base-markdown-page-methods'))->toHtml($page::class) }}\n\n## InMemoryPage\n\nBefore we take a look at the common page classes, you'll usually use, let's first take a look at one that's quite interesting.\n\nThis class is especially useful for one-off custom pages. But if your usage grows, or if you want to utilize Hyde\nautodiscovery, you may benefit from creating a custom page class instead, as that will give you full control.\n\nYou can learn more about the InMemoryPage class in the InMemoryPage documentation.\n\n### Quick Reference\n\nClass Name     Namespace    Source Code                                                                                   API Docs\n\nInMemoryPage Hyde\\Pages Open in GitHub Live API Docs\n\n### Base Structure\n\nAs the class is not discoverable, the static path properties are not initialized. Instead, you solely rely on the contents\/view properties.\n\nYou can also define macros which allow you to both add methods to the instance, but also to overload some built-in ones like the compile method.\n\n\/**\n * The InMemoryPage class, here simplified for the sake of brevity.\n *\/\nclass InMemoryPage extends HydePage\n{\npublic static string $sourceDirectory;\npublic static string $outputDirectory;\npublic static string $fileExtension;\n\nprotected string $contents;\nprotected string $view;\n\n\/* @var array \/\nprotected array $macros = [];\n}\n\n### Methods\n\n[Blade]: {{ Hyde\\Markdown\\Models\\Markdown::fromFile(DocumentationPage::sourcePath('_data\/partials\/hyde-pages-api\/in-memory-page-methods'))->toHtml($page::class) }}\n\n## BladePage\n\nPage class for Blade pages.\n\nBlade pages are stored in the _pages directory and using the .blade.php extension.\nThey will be compiled using the Laravel Blade engine the _site\/ directory.\n\n### Quick Reference\n\nClass Name  Namespace    Source Code                                                                                API Docs\n\nBladePage Hyde\\Pages Open in GitHub Live API Docs\n\n### Base Structure\n\nclass BladePage extends HydePage\n{\npublic static string $sourceDirectory = '_pages';\npublic static string $outputDirectory = '';\npublic static string $fileExtension = '.blade.php';\n}\n\n### Methods\n\n[Blade]: {{ Hyde\\Markdown\\Models\\Markdown::fromFile(DocumentationPage::sourcePath('_data\/partials\/hyde-pages-api\/blade-page-methods'))->toHtml($page::class) }}\n\n## MarkdownPage\n\nPage class for Markdown pages.\n\nMarkdown pages are stored in the _pages directory and using the .md extension.\nThe Markdown will be compiled to HTML using a minimalistic layout to the _site\/ directory.\n\n### Quick Reference\n\nClass Name     Namespace    Source Code                                                                                   API Docs\n\nMarkdownPage Hyde\\Pages Open in GitHub Live API Docs\n\n### Base Structure\n\nclass MarkdownPage extends BaseMarkdownPage\n{\npublic static string $sourceDirectory = '_pages';\npublic static string $outputDirectory = '';\npublic static string $template = 'hyde::layouts\/page';\n}\n\n### Methods\n\nThis class does not define any additional methods.\n\n## MarkdownPost\n\nPage class for Markdown blog posts.\n\nMarkdown posts are stored in the _posts directory and using the .md extension.\nThe Markdown will be compiled to HTML using the blog post layout to the _site\/posts\/ directory.\n\n### Quick Reference\n\nClass Name     Namespace    Source Code                                                                                   API Docs\n\nMarkdownPost Hyde\\Pages Open in GitHub Live API Docs\n\n### Base Structure\n\nclass MarkdownPost extends BaseMarkdownPage\n{\npublic static string $sourceDirectory = '_posts';\npublic static string $outputDirectory = 'posts';\npublic static string $template = 'hyde::layouts\/post';\n\npublic ?string $description;\npublic ?string $category;\npublic ?DateString $date;\npublic ?PostAuthor $author;\npublic ?FeaturedImage $image;\n}\n\n### Methods\n\n[Blade]: {{ Hyde\\Markdown\\Models\\Markdown::fromFile(DocumentationPage::sourcePath('_data\/partials\/hyde-pages-api\/markdown-post-methods'))->toHtml($page::class) }}\n\n## DocumentationPage\n\nPage class for documentation pages.\n\nDocumentation pages are stored in the _docs directory and using the .md extension.\nThe Markdown will be compiled to HTML using the documentation page layout to the _site\/docs\/ directory.\n\n### Quick Reference\n\nClass Name          Namespace    Source Code                                                                                        API Docs\n\nDocumentationPage Hyde\\Pages Open in GitHub Live API Docs\n\n### Base Structure\n\nclass DocumentationPage extends BaseMarkdownPage\n{\npublic static string $sourceDirectory = '_docs';\npublic static string $outputDirectory = 'docs';\npublic static string $template = 'hyde::layouts\/docs';\n}\n\n### Methods\n\n[Blade]: {{ Hyde\\Markdown\\Models\\Markdown::fromFile(DocumentationPage::sourcePath('_data\/partials\/hyde-pages-api\/documentation-page-methods'))->toHtml($page::class) }}\n\n## HtmlPage\n\nPage class for HTML pages.\n\nHTML pages are stored in the _pages directory and using the .html extension.\nThese pages will be copied exactly as they are to the _site\/ directory.\n\n### Quick Reference\n\nClass Name Namespace    Source Code                                                                               API Docs\n\nHtmlPage Hyde\\Pages Open in GitHub Live API Docs\n\n### Base Structure\n\nclass HtmlPage extends HydePage\n{\npublic static string $sourceDirectory = '_pages';\npublic static string $outputDirectory = '';\npublic static string $fileExtension = '.html';\n}\n\n### Methods\n\n[Blade]: {{ Hyde\\Markdown\\Models\\Markdown::fromFile(DocumentationPage::sourcePath('_data\/partials\/hyde-pages-api\/html-page-methods'))->toHtml($page::class) }}","destination":"hyde-pages.html"},{"slug":"in-memory-pages","title":"InMemoryPages","content":"InMemoryPages\n\nIntroduction\n\nThis class is a special page class that is not backed by a file on disk, but rather generated at runtime. While it will\nprobably not be useful for the majority of users, it's a great class to know about if you are a package developer,\nbut feel free to skip this section if you're not interested in this.\n\nWhen to use\n\nThis class is especially useful for one-off custom pages. But if your usage grows, or if you want to utilize Hyde\nautodiscovery, you may benefit from creating a custom page class instead, as that will give you full control.\n\nAbout discovery\n\nSince the InMemoryPages are not present in the filesystem, they cannot be found by the auto-discovery process.\nInstead, it's up to the developer to manually register them. If you are working on your own project, you can do this in\nthe boot method of a service provider, such as the AppServiceProvider which is already present in your app\/ directory.\n\nIf you are developing a package, you may instead want to register the page in your package extension class, within the\npage collection callback. In either case, if you want your page to be able to be fully processed by Hyde, you need to\nmake sure you register it before the full application is booted so that routes can be generated.\n\nTo see how to register the page, see the examples below. But first we must look at how to actually create the page.\n\nCreating the Page\n\nTo create an InMemoryPage, you need to instantiate it with the required parameters.\n\nSince a page would not be useful without any content to render, the class offers two content options through the constructor.\n\nYou can either pass a string to the $contents parameter, Hyde will then save that literally as the page's contents.\n\n$page = new InMemoryPage(contents: 'Hello World!');\n\nAlternatively, you can pass a Blade view name to the $view parameter, and Hyde will use that view to render the page\ncontents with the supplied front matter during the static site build process.\n\nwarning Note that $contents take precedence over $view, so if you pass both, only $contents will be used.\n\nYou can also register a macro with the name compile to overload the default compile method.\n\nAPI Reference\n\nTo see all the methods available, please see the InMemoryPage API reference.","destination":"in-memory-pages.html"},{"slug":"navigation-api","title":"Navigation API","content":"Navigation API\n\nwarning This article covers advanced information that is only relevant if you want to create custom navigation menus. Instead, you may want to read the Navigation article for a general overview.\n\nAbstract\n\nThis article describes the Navigation API introduced in HydePHP v2. Both the main navigation menu and the documentation sidebar bundled with HydePHP are built with this API.\nHowever, if you are interested in creating your own custom navigation menus, you can also utilize this API - and this article will show you how.\n\nThis article is intended for advanced users, as most users will not need to create custom navigation menus.\nFor this reason, the documentation is very code-driven due to the technical nature of the API.\nWe'll also be mixing in some practical examples of Blade and PHP code to illustrate how you can use the API in your own projects.\n\nOverview\n\nThe Navigation API consists of a set of classes within the Hyde\\Framework\\Features\\Navigation namespace.\n\nTogether, these form an object-oriented way to create and interact with navigation menus and their items.\n\nIn short, a navigation menu is an instance of the NavigationMenu class. Each menu contains a collection of NavigationItem or NavigationGroup classes.\nThe former represents a single item in the menu, while the latter represents a group of items.\n\nVisualisation\n\nHere is a visual representation of the structure of a navigation menu:\n\nnamespace Hyde\\Framework\\Features\\Navigation;\n\nclass NavigationMenu {\nprotected Collection $items = [\nnew NavigationItem(destination: 'index.html', label: 'Home'),\nnew NavigationItem(destination: 'posts.html', label: 'Blog'),\nnew NavigationGroup(label: 'About', items: [\nnew NavigationItem(destination: 'about.html', label: 'About Us'),\nnew NavigationItem(destination: 'team.html', label: 'Our Team'),\n]),\n];\n}\n\nBuilt-in Menus\n\nHydePHP comes with two built-in menus: the main navigation menu and the documentation sidebar, both represented as child classes of the NavigationMenu class.\nThey are bound into the service container as singletons and can be accessed through dependency injection.\n\nuse Hyde\\Framework\\Features\\Navigation\\MainNavigationMenu;\nuse Hyde\\Framework\\Features\\Navigation\\DocumentationSidebar;\n\n\/* @var \\Hyde\\Framework\\Features\\Navigation\\MainNavigationMenu $menu \/\n$menu = app('navigation.main')\n\n\/* @var DocumentationSidebar $sidebar \/\n$sidebar= app('navigation.sidebar')\n\nYou can also get them through the static get helpers on the menu classes themselves.\n\nuse Hyde\\Framework\\Features\\Navigation\\MainNavigationMenu;\nuse Hyde\\Framework\\Features\\Navigation\\DocumentationSidebar;\n\n$menu = MainNavigationMenu::get();\n$sidebar = DocumentationSidebar::get();\n\ninfo Developer tip: The menus are only generated after the Hyde Kernel is booted. If you are getting BindingResolutionExceptions, ensure that you are not trying to access the menus too early in the application lifecycle. (Consider using the booted event.)\n\nCreating Custom Menus\n\nIntroduction Overview\n\nWhen creating a custom menu, there are two ways to go about it:\n\n1. You can construct a NavigationMenu instance directly and add items to it. This works great for smaller menus that don't need any special logic, for example a footer menu or social media links.\n2. You can create a custom class that extends the NavigationMenu class. This is useful for larger menus that require more complex logic, or that you want to reuse in multiple places in your application or in a package.\n\nIn both cases, the underlying API is the same, and you can use the helper methods and features provided by the APIs.\n\nIn this section, you will first see some high level overviews of how the API can be used, then we'll dive in deeper and take a look at each class and method in detail.\n\nHigh Level Example\n\nTo illustrate how you can create a custom menu, let's make something useful: A footer menu with social media links.\n\nStep 1: Create the Menu\n\nTo create our menu, we start by constructing a new NavigationMenu instance.\nWe can then add our social media links as NavigationItem instances to the menu.\n\n$menu = new NavigationMenu();\n\n$menu->add([\n\/\/ The first parameter is the URL, and the second is the label.\nNavigationItem::create('https:\/\/twitter.com\/hydephp', 'Twitter'),\nNavigationItem::create('https:\/\/github.com\/hydephp', 'GitHub'),\nNavigationItem::create('https:\/\/hydephp.com', 'Website'),\n]);\n\nStep 2: Display the Menu\n\nWe can now iterate over the menu items to render them in our footer.\n\n\n@foreach ($menu->getItems() as $item)\ngetLink() }}\">{{ $item->getLabel() }}\n@endforeach\n\n\nThis will result in the following HTML:\n\n\nTwitter\nGitHub\nWebsite\n\n\nNext Steps & Tips\n\nOf course, this is an incredibly simplistic example to illustrate the core concepts.\nWhere the Navigation API really shines is in more complex scenarios where you want to utilize things like\nHydePHP Routes to resolve dynamic relative urls, and to use features like groups, priorities, and active states helpers to check if a menu item is the current page being viewed.\n\nThe object-oriented nature of the API also makes this perfect for package developers wanting to create dynamic and reusable navigation menus that even can be further extended and customized by the end user.\n\nHere are some general tips to keep in mind when working with the Navigation API:\n- You can use the add method to add single items or arrays of items. You can also pass an array of items directly to the menu constructor.\n- The navigation menu items is stored in a Laravel Collection, and is type safe to support both NavigationItem and NavigationGroup instances.\n- You can also construct NavigationItem instances directly, but the create method is a convenient shorthand, and can fill in data from routes, if you use them.\n- It's also possible to set an item's priority as the third parameter, but here we don't need it, as they default to the order they are added.\n\nClass Reference\n\nBelow is a reference of the classes and methods available in the Navigation API.\n\nNavigationMenu\n\nThe NavigationMenu class represents a navigation menu. It contains a collection of items, which can be either NavigationItem or NavigationGroup instances.\n\nQuick Reference\n\nHere is a quick reference of the methods available on the NavigationMenu class:\n\nuse Hyde\\Framework\\Features\\Navigation\\NavigationMenu;\n\n\/\/ Create a new NavigationMenu instance, optionally providing an array of items.\n$menu = new NavigationMenu($items = []);\n\n\/\/ Add a single item or an array of items to the menu.\n$menu->add(new NavigationItem());\n$menu->add([new NavigationItem()]);\n\n\/\/ Get all items in the menu as a sorted Collection.\n$menu->getItems(): Collection\n\nCreating Navigation Menus\n\nYou can create a new NavigationMenu instance by simply calling the constructor, optionally providing an array of items.\n\nuse Hyde\\Framework\\Features\\Navigation\\NavigationMenu;\n\n$menu = new NavigationMenu($items = []);\n\nHere is how to provide an array or Collection of NavigationItem and\/or NavigationGroup instances directly to the constructor.\n\nuse Hyde\\Framework\\Features\\Navigation\\NavigationMenu;\nuse Hyde\\Framework\\Features\\Navigation\\NavigationItem;\nuse Hyde\\Framework\\Features\\Navigation\\NavigationGroup;\n\n$menu = new NavigationMenu([\nnew NavigationItem('index.html', 'Home'),\nnew NavigationItem('posts.html', 'Blog'),\nnew NavigationGroup('About', [\nnew NavigationItem('about.html', 'About Us'),\nnew NavigationItem('team.html', 'Our Team'),\n]),\n]);\n\nAdding Items to the Menu\n\nYou can also add items to the menu after it has been created by using the add method which can take a single item or an array of items, and can be fluently chained.\n\n$menu = (new NavigationMenu())\n    ->add(new NavigationItem('contact.html', 'Contact Us'))\n    ->add([\nnew NavigationItem('privacy.html', 'Privacy Policy'),\nnew NavigationItem('terms.html', 'Terms of Service'),\n]);\n\nAccessing Items in the Menu\n\nYou can access all items in the menu by calling the getItems method, which will return a Collection of all items in the menu.\n\n$items = $menu->getItems();\n\nThe items will automatically be sorted by their priority, with lower numbers coming first, defaulting to the order they were added if no priority is set.\n\nNavigationItem\n\nThe NavigationItem class is an abstraction for a navigation menu item containing useful information like the destination, label, and priority.\n\nQuick Reference\n\nHere is a quick reference of the methods available on the NavigationItem class:\n\nuse Hyde\\Framework\\Features\\Navigation\\NavigationItem;\n\n\/\/ Create a new NavigationItem instance.\n$item = NavigationItem::create($destination, $label, $priority): NavigationItem;\n$item = new NavigationItem($destination, $label, $priority); \/\/ Same as above.\n\n\/\/ Get the link of the item.\n$item->getLink(): string;\n\n\/\/ Get the label of the item.\n$item->getLabel(): string;\n\n\/\/ Get the priority of the item.\n$item->getPriority(): int;\n\n\/\/ Check if the item is active. (Only works when the destination is a route)\n$item->isActive(): bool;\n\nBlade Example\n\nHere is an example of how you can put it all together in a Blade template:\n\ngetLink() }}\" @class(['active' => $item->isActive()])>\n{{ $item->getLabel() }}\n\nThis will output an anchor tag with the correct link and label, and if the item is active, it will add an active class to the tag.\n\nCreating Navigation Items\n\nThere are two syntaxes for creating NavigationItem instances, you can use a standard constructor or the static create method.\nBoth options provide the exact same signature and functionality, so it's just a matter of preference which one you use.\n\nThe constructors take three parameters: the destination, the label, and the optional priority.\nThe destination can be a Route instance, a route key string, or an external URL.\n\nuse Hyde\\Framework\\Features\\Navigation\\NavigationItem;\n\n$item = new NavigationItem($destination, $label, $priority);\n$item = NavigationItem::create($destination, $label, $priority);\n\nUsing Routes\n\nUsing the HydePHP routing system is the recommended way to create navigation items leading to pages within your project,\nas they will automatically have links resolved to the correct URL, and Hyde can check if the items are active.\nAdditionally, Hyde will use the page data as the label and priority defaults unless you override them.\n\nYou can create routed navigation items by providing either a Route instance or a route key string as the destination.\n\n\/\/ Using a route key string.\nnew NavigationItem('index');\n\n\/\/ Using the Routes facade to get a Route instance.\nnew NavigationItem(Routes::get('index'));\n\n\/\/ Setting the label and\/or priorities will override inferred data.\nnew NavigationItem(Routes::get('index'), 'Custom Label', 25);\n\nUsing a route key is more concise, but will not provide type safety as it will be treated as a link if the route does not exist,\nwhereas providing an invalid route key to the Routes facade will throw an exception. It's up to you which one you prefer.\n\nUsing External URLs\n\nYou can also create navigation items that link to external URLs by providing a full URL as the destination.\n\nIf you do not set a label for links, the label will default to the URL, and if you do not set a priority, it will default to 500.\n\n\/\/ This will lead directly to the link, and use it as the label with a priority of 500.\nnew NavigationItem('https:\/\/example.com');\n\n\/\/ You can also set a custom label and priority to override the defaults.\nnew NavigationItem('https:\/\/example.com', 'External Link', 25);\n\nWhile it is discouraged to use external URLs for internal pages, as Hyde won't be able to resolve relative links or check active states,\nthey are excellent for any time you want an absolute link to an external site or resource.\n\nNote that Hyde will not validate or modify the URL, so you are responsible for ensuring it's correct.\n\nAccessing the resolved links\n\nThe getLink method is designed to return a link that can be used in the href attribute of an anchor tag.\n\nIf the destination is a route, the link will be resolved to the correct URL, using relative paths if possible. It will also respect the pretty URL setting.\n\n$item = new NavigationItem(Routes::get('index'));\n$item->getLink(); \/\/ Outputs 'index.html'\n\n$item = new NavigationItem('https:\/\/example.com');\n$item->getLink(); \/\/ Outputs 'https:\/\/example.com'\n\nTip: The item instances automatically turns into the resolved link when cast to a string. Perfect for your Blade templates!\n\n{{ $item->getLabel() }}\n\nAccessing the label\n\nThe getLabel method returns the label of the item. This is the text that will be displayed in the navigation menu.\n\n$item = new NavigationItem('index', 'Home');\n$item->getLabel(); \/\/ Outputs 'Home'\n\nAccessing the priority\n\nThe getPriority method returns the priority of the item. This is a number that determines the order in which the items are displayed in the menu, where lower numbers come first.\n\n$item = new NavigationItem('index', 'Home', 25);\n$item->getPriority(); \/\/ Outputs 25\n\nChecking if the item is active\n\nThe isActive method checks if the item is active (by comparing it to the Hyde page being compiled at the moment). This is useful for highlighting the current page in the navigation menu.\n\n$item = new NavigationItem('index');\n$item->isActive(); \/\/ Outputs true if the item is the current page, otherwise false.\n\nisActive(fn($item) => $item->getLink() === 'index.html');\n\nThis is useful if you want to check for a specific query parameter, or if you want to check if the item is active based on a more complex condition.\n-->\n\nNavigationGroup\n\nThe NavigationGroup class represents a group of items in a navigation menu. It contains a label, priority, and a collection of navigation items.\nThis class is often used to create submenus or dropdowns in a navigation menu.\n\nThe NavigationGroup class extends the NavigationMenu class, and thus inherits the same base methods and functionality,\nwhile also having shared methods with the NavigationItem class to render the groups in a Blade view.\n\nQuick Reference\n\nHere is a quick reference of the methods available on the NavigationGroup class:\n\nuse Hyde\\Framework\\Features\\Navigation\\NavigationGroup;\n\n\/\/ Create a new NavigationGroup instance.\n$group = new NavigationGroup($label, $items = [], $priority = 500);\n\n\/\/ Add a single item or an array of items to the group.\n$group->add(new NavigationItem());\n$group->add([new NavigationItem()]);\n\n\/\/ Get all items in the group as a Collection sorted by priority.\n$group->getItems(): Collection\n\n\/\/ Get the label of the group.\n$group->getLabel(): string;\n\n\/\/ Get the priority of the group.\n$group->getPriority(): int;\n\n\/\/ Get the group key, which is a normalized kebab-case version of the label.\n$group->getGroupKey(): string;\n\nAs the NavigationGroup class extends the NavigationMenu class, please see the NavigationMenu section for detailed information of the methods available.\n\nUsage Scenarios\n\nHydePHP uses the NavigationGroup class to create dropdowns in the main navigation menu and the category groups in the documentation sidebar.\n\nIn your own custom menus, you can use this class for the same types of functionality, and you can even nest groups within groups to create complex navigation structures.","destination":"navigation-api.html"},{"slug":"architecture-concepts","title":"Advanced Architecture Concepts","content":"Advanced Architecture Concepts\n\nIntroduction\n\nThese chapters are written for power users and package contributors. If you're just looking to get a site up and running,\nyou can safely skip this section. The documentation here will cover advanced topics under the presumption that\nthe reader has a basic to intermediate understanding of programming, as well as PHP, object-oriented design,\nand to some extent Laravel, as the articles are heavily driven by code examples.\n\nYou are of course free to skip this entire section, as you don't need to know these things to use Hyde.\nHowever, if you want to know the \"magic\" behind Hyde, or if you want to take advantage of these powerful tools,\nthen by all means, please read on! This is also a great place to start if you want to contribute to the source code.\n\ninfo For a high-level overview of these concepts, see the Basic Architecture Concepts page.\n\nBehind the Magic\n\nWant to learn more about a particular feature? Click on the links below to visit the article.\n\n[\/\/]: # (This would be better suited for a component, but it's a fun experiment for now)\n[Blade]: @foreach(glob(DocumentationPage::path('architecture-concepts\/*.md')) as $file)   {{ Hyde::makeTitle(basename($file, '.md')) }}   @endforeach","destination":"architecture-concepts.html"},{"slug":"autodiscovery","title":"Autodiscovery","content":"Autodiscovery\n\nIntroduction\n\nHydePHP aims to reduce the amount of configuration you need to do to get a site up and running.\nTo that end, Hyde uses a process called autodiscovery to automatically find and register your pages.\n\nThis article will go into detail about how autodiscovery works as well as the lifecycle of the HydeKernel.\n\nThe short version\n\nHyde will use the information in the page model classes to scan the source directories for matching files which are\nparsed using instructions from the model's class, resulting in data used to construct objects that get stored in the HydeKernel.\n\nPrerequisites\n\nBefore reading this article, you should be familiar with the following concepts:\n-  Page Models\n-  The HydeKernel\n\nBooting Pipeline\n\nThe autodiscovery is run when the HydeKernel boots. It does so in three distinct steps, which run in sequence as each\nstep depends on the previous one. Each discovery step runs in a FoundationCollection which both runs the actual\ndiscovery process and stores the discovered data in memory.\n\nThe steps are as follows:\n\n1. Step one: The file collection discovers all the source files and stores them in memory\n2. Step two: The page collection parses all the source files into page model objects\n3. Step three: The route collection generates route objects for all the pages\n\nInteracting with the collections\n\nUsually, you will interact with the collection data through intermediaries.\n* For example, if you call MarkdownPost::get('my-post'), Hyde will retrieve that page from the page collection.\n* If you call Routes::get('index'), Hyde will retrieve that route from the route collection.\n\nThe HydeKernel\n\nIf you have not yet read the HydeKernel Documentation, here's a quick recap:\n\nThe HydeKernel encapsulates a HydePHP project, providing helpful methods for interacting with it.\nIt is also responsible for booting the application, which includes the autodiscovery process.\n\nThe kernel is created very early on in the application lifecycle, in the bootstrap.php file, where it is also bound\nas a singleton into the application service container.\n\nAt this point you might be wondering why we're talking about the kernel when this article is about autodiscovery.\nWell, as you'll see in just a moment, the kernel is responsible for initiating the autodiscovery process.\nThe kernel is also where the discovered data is stored in memory, so it's important to understand how it works.\n\nThe kernel lifecycle\n\nNow that we know the role of the HydeKernel, let's take a look at its lifecycle. The kernel is \"lazy-booted\", meaning\nthat all the heavy lifting only happens when you actually need it. Once booted, the kernel data will stay in memory\nuntil the console application is terminated.\n\nThe kernel data is primarily stored in three collections that get generated during the kernel's boot process.\nLet's take a look at a simplified version of the kernel's boot method to see how this works.\n\npublic function boot(): void\n{\n$this->files = FileCollection::boot($this);\n$this->pages = PageCollection::boot($this);\n$this->routes = RouteCollection::boot($this);\n\n\/\/ Scroll down to see what this is used for\n$this->booted = true;\n}\n\nHere you'll see that we boot the three collections. This is where all the autodiscovery magic happens!\n\nDeep dive into lazy-booting\n\nIf you're curious about how the kernel is lazy-booted, here's how it works!\nFeel free to skip this section if this doesn't interest you.\n\n\/\/ This will boot the kernel if it hasn't been booted yet\npublic function pages(): PageCollection\n{\n$this->needsToBeBooted();\n\nreturn $this->pages;\n}\n\n\/\/ This is the method that triggers the boot process\nprotected function needsToBeBooted(): void\n{\nif (! $this->booted) {\n$this->boot();\n}\n}\n\nYeah, it's really unglamorous I know. But it works! Having it like this will ensure that any time you call Hyde::pages(),\nthat underlying collection will always have been booted and be ready to use.","destination":"autodiscovery.html"},{"slug":"automatic-routing","title":"Automatic Routing","content":"Automatic Routing\n\ninfo This covers an intermediate topic which is not required for basic usage, but is useful if you want to use the framework to design custom Blade templates.\n\nHigh-level overview\n\nIf you've ever worked in an MVC framework, you are probably familiar with the concept of routing.\nAnd you are probably also familiar with how boring and tedious it can be. Thankfully, Hyde takes the pain out of routing\nthrough the Hyde Autodiscovery process.\n\nInternally, when booting the HydeCLI application, Hyde will automatically discover all the content files in the source\ndirectories, and create a route index for all of them. This index works as a two-way link between source files and compiled files.\n\nDon't worry if this sounds complex, as the key takeaway is that the index is created and maintained automatically.\nNevertheless, the routing system provides several helpers that you can optionally use in your Blade views to\nautomatically resolve relative links and other useful features.\n\nYou can see all the routes and their corresponding source files by running the hyde route:list command.\n\nphp hyde route:list\n\nAccessing routes\n\nEach route in your site is represented by a Route object. It's very easy to get a Route object instance from the Router's index.\nThere are a few ways to do this, but most commonly you'll use the Routes facade's get() method where you provide a route key,\nand it will return the Route object. The route key is generally ``. Here are some examples:\n\n\/\/ Source file: _pages\/index.md\/index.blade.php\n\/\/ Compiled file: _site\/index.html\nRoutes::get('index')\n\n\/\/ Source file: _posts\/my-post.md\n\/\/ Compiled file: _site\/posts\/my-post.html\nRoutes::get('posts\/my-post')\n\n\/\/ Source file: _docs\/readme.md\n\/\/ Compiled file: _site\/docs\/readme.html\nRoutes::get('docs\/readme')\n\nUsing the x-link component\n\nWhen designing Blade layouts it can be useful to use the x-link component to automatically resolve relative links.\n\nYou can of course use it just like a normal anchor tag like so:\n\nHome\n\nBut where it really shines is when you supply a route. This will then resolve the proper relative link, and format it to use pretty URLs if your site is configured to use them.\n\nHome\n\nYou can also supply extra attributes like classes:\n\nHome","destination":"automatic-routing.html"},{"slug":"dynamic-data-discovery","title":"Dynamic Data Discovery","content":"Dynamic Data Discovery\n\n[\/\/]: # (Adds a pseudo-subtitle)\nAKA: Front Matter & Filling in the Gaps\n\nIntroduction\n\nHyde wants to allow developers to write less, and do more. This is also a major difference between HydePHP and JekyllRB.\nJekyll will only do what you tell it to do. Hyde, on the other hand, will try to do what you want it to do.\n\nAs with all other chapters in this category, you don't need to know about this to use Hyde -- that's the whole point!\nHowever, if you're anything like me, you'll likely find this interesting to read about, even if you don't really need to know it.\n\nHyde makes great use of front matter in both Markdown and Blade files (it's true!). However, it can quickly get tedious\nand quite frankly plain boring to have to write a bunch of front matter all the time. As Hyde wants you to focus on\nyour content, and not your markup, front matter is optional and Hyde will try to fill in the gaps for you.\n\nIf you're not happy with Hyde's generated data you can always override it by adding front matter to your files.\n\nHow it Works\n\nNow, to the fun part: getting into the nitty-gritty details of how Hyde does this!\n\nTo make things simple the dynamic data is created in a special stage where the page object is being created.\nIf you have not yet read the page models chapter you might want to do so now.\nYou might also want to read about the autodiscovery lifecycle for some context as to when this happens.\n\nThe factory pipeline, in short\n\nAfter basic information about the page has been gathered, such as the source file information and the front matter,\nthe page model is run through a series of factories. These are just classes that work around the limited data\nthat is available at this point and will generate the rich data used to make your Hyde page awesome.\n\nThere are a few factory classes. The one we will be looking at here is the HydePageDataFactory class, which is\nresponsible for data applicable to all page models. Complex structures and data only relevant to some page types\nhave their own factories, making the code more modular and maintainable.\n\nIn-depth Overview of a Page Factory\n\nLet's take a look at how Hyde will discover the title of a page as an example. Since this is something used by all pages,\nthis discovery is done in the HydePageDataFactory class.\n\nFactory data input\n\nThe factory gets one input, a CoreDataObject class. Think of this like a DTO (Data Transfer Object) that holds\nimmutable data known from the start of the page construction process. It also has all the information needed\nto identify the page and its source file. Here's a simplified version of the class:\n\nclass CoreDataObject\n{\npublic readonly FrontMatter $matter;\npublic readonly Markdown|false $markdown;\n\npublic readonly string $pageClass;\npublic readonly string $identifier;\npublic readonly string $sourcePath;\npublic readonly string $outputPath;\npublic readonly string $routeKey;\n}\n\nProcessing the known data\n\nNow that we have the input we pass it to the factory, where a simple algorithm is used to find the best title for the page.\n\nprivate function findTitleForPage(): string\n{\nreturn $this->matter('title')\n?? $this->findTitleFromMarkdownHeadings()\n?? Hyde::makeTitle(basename($this->identifier));\n}\n\nAs you can see, we are using the null coalescing operator (??) to return the first non-null value. We always want the\nuser to be able to set any data explicitly, so we first check the front matter in all factory methods.\n\nIf no title is set in the matter the method will return null, and Hyde will try the next step which is to search the headings.\nIf that fails, the last step will generate a title from the file name. This ensures that no matter what, we always have a title.\n\nInjecting the data into the page\n\nOnce the data has been discovered, it is injected into the page object. This is rather unglamorous but is mentioned\nhere for completeness. It's pretty simple. The factory will always return an array of the computed data, where the keys\nalways match the property names on the page object, so we just need to loop over the array and set the properties.\n\nforeach ($data->toArray() as $key => $value) {\n$this->{$key} = $value;\n}\n\nAnd that's pretty much it! Hyde will do this for all the data it can discover, freeing you to focus on your content.","destination":"dynamic-data-discovery.html"},{"slug":"extensions-api","title":"The Extensions API","content":"The Extensions API\n\nIntroduction\n\nThe Extensions API is a powerful interface designed for package developers who want to extend the functionality of HydePHP.\n\nUsing the API, you can hook directly into the HydePHP Kernel and extend sites with custom page types and new features.\n\nThis documentation page functions heavily through examples, so it's recommended that the sections are read in order.\n\nPrerequisites\n\nBefore creating your extension, it will certainly be helpful if you first become familiar with\nthe basic internal architecture of HydePHP, as well as how the auto-discovery system works,\nso you can understand how your code works with the internals.\n\n- Core concepts overview\n- Architecture concepts\n- Autodiscovery\n\nThe why and how of the Extensions API\n\nHydePHP being a static site generator, the Extensions API is centred around Page Models,\nwhich you are hopefully already familiar with, otherwise you should read up on them first.\n\nWhat the Extensions API does is to allow you to create custom page types, and tell HydePHP how to discover them.\nThis may sound like a small thing, but it's actually incredibly powerful as the page models are the foundation\nof HydePHP's functionality. They tell the system how to discover pages, how to render them,\nand how they interact with the site.\n\nAny other functionality you want to add to HydePHP, such as new commands or configuration options,\ncan be added the same way as you would in Laravel, and are thus not part of our API.\nSee the Laravel package development guide for more.\n\nCreating Your Extension Class\n\nThe entry-point for your extension is your Extensions class. Within this, you can register the custom page classes.\nIf needed, you can also register discovery handlers which can run custom logic at various parts of the boot process.\n\nIn this article we will create an extension that registers a new type of page, a JsonPageExtension.\n\nThe first step is to create a class that extends the HydeExtension class:\n\nuse Hyde\\Foundation\\Concerns\\HydeExtension;\n\nclass JsonPageExtension extends HydeExtension {\n\/\/\n}\n\nIn here, we will register our extension class name in the getPageClasses method:\n\nclass JsonPageExtension extends HydeExtension {\npublic static function getPageClasses(): array {\nreturn [\nJsonPage::class,\n];\n}\n}\n\nHyde will then use the information from the JsonPage class to automatically discover the pages when booting the Kernel.\nFor example, if you specify the file extension and source directory, that is all Hyde needs to know to discover the pages.\n\nIf our pages need more complex discovery logic, we can create custom handlers. so let's take a quick look at that next.\n\nDiscovery handlers\n\nThe discovery handlers let you run code at various points of the booting process. This is usually only needed if your\npage models cannot provide the information required for Hyde run the standard auto-discovery, and thus need custom logic.\n\nUsually in these cases, you would only need to add files to the Kernel FileCollection,\nthough the HydeExtension class offers the following three discovery handlers, in case you need them:\n\n\/* Runs during file discovery \/\npublic function discoverFiles(FileCollection $collection): void;\n\n\/* Runs during page discovery \/\npublic function discoverPages(PageCollection $collection): void;\n\n\/* Runs during route discovery \/\npublic function discoverRoutes(RouteCollection $collection): void;\n\nAny of these can be implemented in your extension class, and they will be called during the discovery. As you can see,\nthe instance of the discovery collection is injected into the method for you to interact with.\n\nBooting and Booted Callbacks\n\nIn addition to the discovery handlers, you can also define booting and booted callbacks in your extension class. These methods allow you to run custom logic before and after the kernel boots, respectively. Both methods receive the HydeKernel instance as a parameter, allowing you to interact with the kernel directly.\n\nuse Hyde\\Foundation\\HydeKernel;\n\nclass JsonPageExtension extends HydeExtension {\npublic function booting(HydeKernel $kernel): void {\n\/\/ This runs before the kernel boots and before running auto-discovery\n}\n\npublic function booted(HydeKernel $kernel): void {\n\/\/ This runs after the kernel boots and after running auto-discovery\n}\n}\n\nThe booting callback can be used to set up the system with information needed to discover pages, while the booted callback can can be used to perform operations requiring knowledge of discovered data, even modifying them if needed.\n\nThese callbacks provide powerful hooks into the Hyde system, allowing your extensions to integrate deeply and modify Hyde's behavior as needed.\n\nDiscovery handler example\n\nLet's go crazy and implement a discovery handler to collect JsonPage files from an external API! We will do this\nby implementing the discoverPages method in our extension class, and from there inject pages retrieved from our API.\n\nclass JsonPageExtension extends HydeExtension {\npublic function discoverPages(PageCollection $collection): void {\n$pages = Http::get('https:\/\/example.com\/my-api')->collect();\n\n$pages->each(function (array $page) use ($collection): void {\n$collection->addPage(JsonPage::fromArray($page));\n});\n}\n}\n\nSince the discovery steps are handled sequentially, the added pages will automatically be discovered as routes without\nus having to implement that handler method. As we inject the page objects directly, we bypass the need for the FileCollection.\n\nRegistering Your Extension\n\nNow that we have our extension class, we need to register it with HydePHP.\n\nIt's important that your class is registered before the HydeKernel boots. Therefore, an excellent place for this is the\nregister method of your extensions service provider,  where you call the registerExtension method of the HydeKernel\nsingleton instance, which you can access via the Hyde\\Hyde facade, or via the service container.\n\nuse Hyde\\Hyde;\nuse Hyde\\Foundation\\HydeKernel;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass JsonPageExtensionServiceProvider extends ServiceProvider {\npublic function register(): void {\n\/\/ Via the service container:\n$this->app->make(HydeKernel::class)->registerExtension(JsonPageExtension::class);\n\n\/\/ Or via the facade:\nHyde::registerExtension(JsonPageExtension::class);\n}\n}\n\nPackaging your extension\n\nTo make your extension available to other HydePHP users, you can make it into a Composer package,\nand publish it to Packagist for others to install.\n\nIf you register your service provider in your package's composer.json file, your extension automatically be enabled when\nthe package is installed in a HydePHP project!\n\n{\n\"extra\": {\n\"laravel\": {\n\"providers\": [\n\"My\\\\Namespace\\\\JsonPageExtensionServiceProvider\"\n]\n}\n}\n}\n\nTelling the world about your extension\n\nNext up, why not send us a Tweet at @HydeFramework and tell us about your extension,\nso we can feature it?","destination":"extensions-api.html"},{"slug":"page-models","title":"Page models","content":"The Hyde Page Models\n\nIntroduction\n\nThe Hyde page models are an integral part of how HydePHP creates your static site. Each page in your site is represented\nby a page model. These are simply PHP classes that in addition to holding both the source content and computed data\nfor your pages, also house instructions to Hyde on how to parse, process, and render the pages to static HTML.\n\nIn this article, you'll get a high-level overview of the page models, and some code examples to give you a look inside.\n\nThe Short Version\n\nPage models are classes that have two primary concerns:\n\n1. They act as blueprints containing static instructions for how to parse, process, and, render pages.\n2. Each class instance also holds the page source contents, as well as the computed data.\n\nOther key points:\n\n- HydePHP, at the time of writing, comes with five different page classes, one for each supported type.\n- You don't construct page models yourself. HydePHP does it for you by the autodiscovery process.\n- Page models are just PHP classes. You can extend them, and you can implement your own.\n\nThe Page Model\n\nTo give you an idea of what a page model class looks like, here's a simplified version of the base MarkdownPost class,\nDon't worry if you don't understand everything yet, we'll talk more about these parts later.\n\nclass MarkdownPost extends BaseMarkdownPage\n{\npublic static string $sourceDirectory = '_posts';\npublic static string $outputDirectory = 'posts';\npublic static string $fileExtension = '.md';\npublic static string $template = 'post';\n\npublic string $identifier;\npublic string $routeKey;\npublic string $title;\n\npublic FrontMatter $matter;\npublic Markdown $markdown;\n}\n\n_Note that since Hyde pages are modular through class inheritance and traits, this example has been simplified and\nedited to show all the relevant parts inlined into one class._\n\nPage Models as Blueprints\n\nAll page models have some static properties (that is, they belong to the class, not the instance) that are used as\nblueprints, defining information for Hyde to know how to parse a file, and what data around it should be generated.\n\nLet's again take the simplified MarkdownPost class as an example, this time only showing the static properties:\n\nclass MarkdownPost extends BaseMarkdownPage\n{\npublic static string $sourceDirectory = '_posts';\npublic static string $outputDirectory = 'posts';\npublic static string $fileExtension = '.md';\npublic static string $template = 'post';\n}\n\nWhat each property does\n\nThe properties should be self-explanatory, but here's a quick rundown to give some context on how they are used,\nand how the paths relate to each other. So for the class above, Hyde will thanks to this blueprint, know to:\n* Look for files in the _posts directory, with the .md extension\n* Compile the page using the post Blade template\n* Output the compiled page to the _site\/posts directory\n\nPage Models as Data Containers\n\nAs mentioned above, each page model instance also holds the page source contents, as well as the computed data.\n\nLet's again take the simplified MarkdownPost class as an example, this time only showing the instance properties:\n\nclass MarkdownPost extends BaseMarkdownPage\n{\npublic string $identifier;\npublic string $routeKey;\npublic string $title;\n\npublic FrontMatter $matter;\npublic Markdown $markdown;\n}\n\nThere are some more properties than shown here, for example, various metadata properties, but these are the most common\nand important ones.\n\nWhile the static data gives instructions to Hyde on how to process all pages of the type, the instance data tells Hyde\nhow to process a specific page. For example, the identifier property is used to uniquely identify the page, and\nthe routeKey property is used to generate the URL for the page.\n\nThe matter and markdown properties as I'm sure you can guess, hold the page's front matter and markdown content.\nThese can then also be processed by page factories to generate the computed data like the\ntitle property.","destination":"page-models.html"},{"slug":"the-hydekernel","title":"The HydeKernel","content":"The HydeKernel\n\nIntroduction\n\nIn the centre, or should I say core, of HydePHP is the HydeKernel. The kernel encapsulates a HydePHP project and\nprovides helpful methods for interacting with it. You can think of it as the heart of HydePHP, if you're a romantic.\n\nThe HydeKernel is so important that you have probably used it already. The main entry point for the HydePHP\nAPI is the Hyde facade, which calls methods on the kernel.\n\nuse Hyde\\Hyde;\nuse Hyde\\Foundation\\HydeKernel;\n\nHyde::version(); \/\/ calls $HydeKernel->version()\n\nThe kernel is created very early on in the application lifecycle, in the bootstrap.php file, where it is also bound\nas a singleton into the application service container.\n\nAccessing the Kernel\n\nThe HydeKernel is stored as a singleton in a static property in its own class and can be accessed in a few ways.\n\nCommonly, you'll use the Hyde facade which forwards calls to the singleton instance.\nYou can also use the hyde() function to get the Kernel, and call methods on it.\n\nSince the instance is also bound into the Laravel Application Service Container you can also use Dependency Injection by type-hinting the HydeKernel::class.\n\nHere are some examples of how you can call methods on the Kernel. All methods call the same method on the same instance, so it's just a matter of preference.\n\nuse Hyde\\Hyde;\nuse Hyde\\Foundation\\HydeKernel;\n\nHyde::version();\nHyde::kernel()->version();\nHydeKernel::getInstance()->version();\napp(HydeKernel::class)->version();\nhyde()->version();\n\nThe Kernel instance is constructed and bound in the app\/bootstrap.php file.\n\nThe Kernel Lifecycle\n\nWhenever we talk about the kernel being \"booted\" we are talking about the kernel's role in the autodiscovery process.\n\nYou can read all about it in the Autodiscovery Documentation.\n\nAPI Reference\n\nSince the most common way to interact with the kernel is through the Hyde facade, we will use that for the examples.\nBut you could just as well chain the methods on the accessed kernel singleton instance if you wanted.\n\nversion()\n\nNo description provided.\n\nHyde::version(): string\n\n__construct()\n\nNo description provided.\n\n$hyde = new HydeKernel(string $basePath): void\n\nfeatures()\n\nNo description provided.\n\nHyde::features(): Hyde\\Facades\\Features\n\nhasFeature()\n\nNo description provided.\n\nHyde::hasFeature(Hyde\\Enums\\Feature $feature): bool\n\ntoArray()\n\nGet the instance as an array.\n\nHyde::toArray(): array\n\nfiles()\n\nNo description provided.\n\nHyde::files(): Hyde\\Foundation\\Kernel\\FileCollection\n\npages()\n\nNo description provided.\n\nHyde::pages(): Hyde\\Foundation\\Kernel\\PageCollection\n\nroutes()\n\nNo description provided.\n\nHyde::routes(): Hyde\\Foundation\\Kernel\\RouteCollection\n\nmakeTitle()\n\nNo description provided.\n\nHyde::makeTitle(string $value): string\n\nmakeSlug()\n\nNo description provided.\n\nHyde::makeSlug(string $value): string\n\nnormalizeNewlines()\n\nNo description provided.\n\nHyde::normalizeNewlines(string $string): string\n\nstripNewlines()\n\nNo description provided.\n\nHyde::stripNewlines(string $string): string\n\ntrimSlashes()\n\nNo description provided.\n\nHyde::trimSlashes(string $string): string\n\nmarkdown()\n\nNo description provided.\n\nHyde::markdown(string $text, bool $normalizeIndentation): Illuminate\\Support\\HtmlString\n\nformatLink()\n\nNo description provided.\n\nHyde::formatLink(string $destination): string\n\nrelativeLink()\n\nNo description provided.\n\nHyde::relativeLink(string $destination): string\n\nasset()\n\nNo description provided.\n\nHyde::asset(string $name): Hyde\\Support\\Filesystem\\MediaFile\n\nThrows:** \\Hyde\\Framework\\Exceptions\\FileNotFoundException If the file does not exist in the _media source directory.\n\nurl()\n\nNo description provided.\n\nHyde::url(string $path): string\n\nroute()\n\nNo description provided.\n\nHyde::route(string $key): Hyde\\Support\\Models\\Route\n\nhasSiteUrl()\n\nNo description provided.\n\nHyde::hasSiteUrl(): bool\n\nfilesystem()\n\nNo description provided.\n\nHyde::filesystem(): Hyde\\Foundation\\Kernel\\Filesystem\n\npath()\n\nNo description provided.\n\nHyde::path(string $path): string\n\nvendorPath()\n\nNo description provided.\n\nHyde::vendorPath(string $path, string $package): string\n\nsitePath()\n\nNo description provided.\n\nHyde::sitePath(string $path): string\n\npathToAbsolute()\n\nNo description provided.\n\nHyde::pathToAbsolute(array|string $path): array|string\n\npathToRelative()\n\nNo description provided.\n\nHyde::pathToRelative(string $path): string\n\nassets()\n\nNo description provided.\n\nHyde::assets(): \\Illuminate\\Support\\Collection\n\ngetInstance()\n\nNo description provided.\n\nHyde::getInstance(): Hyde\\Foundation\\HydeKernel\n\nsetInstance()\n\nNo description provided.\n\nHyde::setInstance(Hyde\\Foundation\\HydeKernel $instance): void\n\ngetBasePath()\n\nNo description provided.\n\nHyde::getBasePath(): string\n\nsetBasePath()\n\nNo description provided.\n\nHyde::setBasePath(string $basePath): void\n\ngetSourceRoot()\n\nNo description provided.\n\nHyde::getSourceRoot(): string\n\nsetSourceRoot()\n\nNo description provided.\n\nHyde::setSourceRoot(string $sourceRoot): void\n\ngetOutputDirectory()\n\nNo description provided.\n\nHyde::getOutputDirectory(): string\n\nsetOutputDirectory()\n\nNo description provided.\n\nHyde::setOutputDirectory(string $outputDirectory): void\n\ngetMediaDirectory()\n\nNo description provided.\n\nHyde::getMediaDirectory(): string\n\nsetMediaDirectory()\n\nNo description provided.\n\nHyde::setMediaDirectory(string $mediaDirectory): void\n\ngetMediaOutputDirectory()\n\nNo description provided.\n\nHyde::getMediaOutputDirectory(): string\n\nregisterExtension()\n\nRegister a HydePHP extension within the HydeKernel.\n\nTypically, you would call this method in the register method of a service provider. If your package uses the standard Laravel (Composer) package discovery feature, the extension will automatically be enabled when the package is installed.\n\nHyde::registerExtension(class-string&lt;\\Hyde\\Foundation\\Concerns\\HydeExtension&gt; $extension): void\n\ngetExtension()\n\nGet the singleton instance of the specified extension.\n\nHyde::getExtension(class-string&lt;T&gt; $extension): T\n\nhasExtension()\n\nDetermine if the specified extension is registered.\n\nHyde::hasExtension(class-string&lt;\\Hyde\\Foundation\\Concerns\\HydeExtension&gt; $extension): bool\n\ngetExtensions()\n\nNo description provided.\n\nHyde::getExtensions(): array\n\ngetRegisteredExtensions()\n\nNo description provided.\n\nHyde::getRegisteredExtensions(): array>\n\ngetRegisteredPageClasses()\n\nNo description provided.\n\nHyde::getRegisteredPageClasses(): array>\n\nshareViewData()\n\nShare data for the page being rendered.\n\nHyde::shareViewData(Hyde\\Pages\\Concerns\\HydePage $page): void\n\ncurrentRouteKey()\n\nGet the route key for the page being rendered.\n\nHyde::currentRouteKey(): string\n\ncurrentRoute()\n\nGet the route for the page being rendered.\n\nHyde::currentRoute(): Hyde\\Support\\Models\\Route\n\ncurrentPage()\n\nGet the page being rendered.\n\nHyde::currentPage(): Hyde\\Pages\\Concerns\\HydePage\n\nisBooted()\n\nDetermine if the Kernel has booted.\n\nHyde::isBooted(): bool\n\nboot()\n\nBoot the Hyde Kernel and run the Auto-Discovery Process.\n\nHyde::boot(): void\n\nbooting()\n\nRegister a new boot listener.\n\nYour callback will be called before the kernel is booted. You can use this to register your own routes, pages, etc. The kernel instance will be passed to your callback.\n\n\/* @param callable(\\Hyde\\Foundation\\HydeKernel): void $callback \/\nHyde::booting(callable(\\Hyde\\Foundation\\HydeKernel): void): void\n\nbooted()\n\nRegister a new &quot;booted&quot; listener.\n\nYour callback will be called after the kernel is booted. You can use this to run any logic after discovery has completed. The kernel instance will be passed to your callback.\n\n\/* @param callable(\\Hyde\\Foundation\\HydeKernel): void $callback \/\nHyde::booted(callable(\\Hyde\\Foundation\\HydeKernel): void): void","destination":"the-hydekernel.html"},{"slug":"blog-posts","title":"Creating Blog Posts","content":"Creating Blog Posts\n\nIntroduction to Hyde Posts\n\nMaking blog posts with Hyde is easy. At the most basic level, all you need is to add a Markdown file to your _posts folder.\n\nTo use the full power of the Hyde post module you'll want to add YAML Front Matter to your posts.\n\nYou can interactively scaffold posts with automatic front matter using the HydeCLI:\n\nphp hyde make:post\nLearn more about scaffolding posts, and other files, in the console commands documentation.\n\nShort Video Tutorial\n\nBest Practices and Hyde Expectations\n\nSince Hyde does a lot of things automatically, there are some things you may need\nto keep in mind when creating blog posts so that you don't get unexpected results.\n\nFilenames\n\n- Markdown post files are stored in the _posts directory\n- The filename is used as the filename for the compiled HTML\n- Filenames should use kebab-case-name followed by the extension .md\n- Files prefixed with _underscores are ignored by Hyde\n- Your post will be stored in _site\/posts\/.html\n\nExample:\n\n\u2714 posts\/hello-world.md # Valid and will be compiled to site\/posts\/hello-world.html\n\nDate Prefixes\n\nYou optionally can set a blog post's publication date by prefixing the filename with a date in ISO 8601 format (YYYY-MM-DD). Optionally, you can also include the time (HH-MM).\n\nBasic date prefix (sets date to 2024-11-05 00:00)\n2024-11-05-my-first-post.md\n\nDate and time prefix (sets date to 2024-11-05 10:30)\n2024-11-05-10-30-my-first-post.md\n\nThe date prefix will be:\n1. Stripped from the route key (resulting in clean URLs like posts\/my-first-post)\n2. Used to set the post's publication date (unless explicitly defined in front matter)\n\nImportant notes:\n- Dates must be in ISO 8601 format (YYYY-MM-DD or YYYY-MM-DD-HH-MM)\n- Days and months must use leading zeros (e.g., 2024-01-05 not 2024-1-5)\n- Time is optional and uses 24-hour format with a hyphen separator (HH-MM)\n- Front matter dates take precedence over filename dates\n- Using date prefixes is entirely optional!\n\nThis feature provides an intuitive way to organize your blog posts chronologically while maintaining clean URLs, and matches the behavior of many popular static site generators for interoperability.\n\nFront Matter\n\nFront matter is optional, but highly recommended for blog posts as the front matter is used to construct dynamic HTML\nmarkup for the post as well as meta tags and post feeds.\n\nYou are encouraged to look at the compiled HTML to learn\nand understand how your front matter is used. You can read more about the Front Matter format in the Front Matter documentation.\n\nBlog Post Example\n\nBefore digging deeper into all the supported options, let's take a look at what a basic post with front matter looks like.\n\n\/\/ filepath _posts\/my-new-post.md\ntitle: My New Post\ndescription: A short description used in previews and SEO\ncategory: blog\nauthor: Mr. Hyde\ndate: 2022-05-09 18:38\nWrite Your Markdown Here\n\nLorem ipsum dolor sit amet, consectetur adipisicing elit.\nAutem aliquid alias explicabo consequatur similique,\nanimi distinctio earum ducimus minus, magnam.\n\nSupported Front Matter Properties\n\nPost Front Matter Schema\n\nHere is a quick reference of the supported front matter properties.\nKeep on reading to see further explanations, details, and examples.\n\nKEY NAME   VALUE TYPE EXAMPLE \/ FORMAT\n\ntitle        string         \"My New Post\"\ndescription  string         \"A short description\"\ncategory     string         \"my favorite recipes\"\ndate         string         \"YYYY-MM-DD [HH:MM]\"\nauthor       string\/array   See author section\nimage        string\/array   See image section\n\nNote that YAML here is pretty forgiving. In most cases you do not need to wrap strings in quotes.\nHowever, it can help in certain edge cases, for example if the text contains special Yaml characters, thus they are included here.\n\nIn the examples below, when there are multiple examples, they signify various ways to use the same property.\n\nWhen specifying an array you don't need all the sub-properties. The examples generally show all the supported values.\n\nTitle\n\ntitle: \"My New Post\"\n\nDescription\n\ndescription: \"A short description used in previews and SEO\"\n\nCategory\n\ncategory: blog\n\ncategory: \"My favorite recipes\"\n\nDate\n\ndate: \"2022-01-01\"\n\ndate: \"2022-01-01 12:00\"\n\nAuthor\n\nSpecify a page author, either by a username for an author defined in the authors config, or by an arbitrary name,\nor by an array of author data.\n\nArbitrary name displayed \"as is\"\n\nauthor: \"Mr. Hyde\"\n\nUsername defined in authors config\n\nauthor: mr_hyde\n\nArray of author data\n\nauthor:\nThese are used in the default author templates\nname: \"Mr. Hyde\"\nusername: mr_hyde\nwebsite: https:\/\/twitter.com\/HydeFramework\n\nThese are not used in the default author templates, but can be used in your custom views\nbio: \"The mysterious author of HydePHP\"\navatar: avatar.png\nsocials:\ntwitter: \"@HydeFramework\"\ngithub: \"hydephp\"\n\nWhen using an array, you don't need to include all properties. Specified values will override the corresponding entries in the authors config.\n\nNote: Author usernames are automatically normalized (converted to lowercase with spaces replaced by underscores).\n\nImage\n\nSpecify a cover image for the post, either by a local image path for a file in the _media\/ directory, or by a full URL.\nAny array data is constructed into a dynamic fluent caption, and injected into post and page metadata.\n\nLocal image path\n\nWhen supplying an image source with a local image path, the image is expected to be stored in the _media\/ directory.\nLike all other media files, it will be copied to _site\/media\/ when the site is built, so Hyde will resolve links accordingly.\n\nimage: image.jpg\n\nFull URL\n\nFull URL starting with http(s):\/\/ or \/\/ (protocol-relative).\nThe image source will be used as-is, and no additional processing is done.\n\nimage: https:\/\/cdn.example.com\/image.jpg\n\nData-rich image and captions\n\nYou can also supply an array of data to construct a rich image with a fluent caption.\n\nimage:\nsource: Local image path or full URL\naltText: \"Alt text for image\"\ntitleText: \"Tooltip title\"\ncopyright: \"Copyright (c) 2022\"\nlicenseName: \"CC-BY-SA-4.0\"\nlicenseUrl: https:\/\/example.com\/license\/\nauthorUrl: https:\/\/photographer.example.com\/\nauthorName: \"John Doe\"\ncaption: \"Overrides the fluent caption feature\"\n\nThe data will then be used for metadata and to render a fluently worded caption. If you just want to add a quick caption, you can instead simply set the \"caption field\" to override the caption; or if you simply want a caption and no metadata this is a quick option as well.\nimage:\nsource: how-to-turn-your-github-readme-into-a-static-website-cropped.png\nalt: Example of a static website created from a GitHub Readme\ncaption: Static website from GitHub Readme with Markdown support!\n\nThe caption field supports inline Markdown formatting like bold, italic, and links. This makes it easy to add rich text formatting to your image captions.\n\nIf the alt field is missing, the caption will be used as the alt text as well.\n\nUsing Images in Posts\n\nTo use images stored in the _media\/ directory, you can use the following syntax:\n\nImage Alt\n\nNote the relative path since the blog post is compiled to posts\/example.html\n\nTo learn more, check out the managing assets chapter on the topic.","destination":"blog-posts.html"},{"slug":"compile-and-deploy","title":"Compile and Deploy Your Site","content":"Compile and Deploy Your Site\n\nRunning the Build Command\n\nNow that you have some amazing content, you'll want to compile your site into static HTML.\n\nThis is as easy as executing the build command:\n\nphp hyde build\n\nYou can also compile a single file:\n\nphp hyde rebuild\n\nAnd, you can even start a development server to compile your site on the fly:\n\nphp hyde serve\n\nFurther reading\n\ninfo Key Concept: Autodiscovery When building the site, Hyde will use all the routes generated when the auto-discovery process scanned your source directories for files. The command will then compile them into static HTML using the appropriate layout depending on what kind of page it is. Thanks to Hyde, the days of manually defining routes are over!\n\nLearn more about these commands in the console commands documentation:\n\n- Build command\n- Rebuild command\n- Serve command\n\nDeploying Your Site\n\nOne of the things that make static sites so enjoyable to work with is how easy it is to deploy them to the web.\nThis list is not exhaustive, but gives you a general idea of the most common ways to deploy your site.\nIf you have ideas to add to the documentation, please send a pull request!\n\nGeneral deployment\n\nIn essence, all you need to do is copy the contents of the _site directory to a web server, and you're done.\n\nOnce the site is compiled there is nothing to configure or worry about.\n\nFTP and File Managers\n\nIf you have a conventional web host, you can use FTP\/SFTP\/FTPS to upload your compiled site files to the web server.\nSome web hosting services also have web-based file managers.\n\nTo deploy your site using any of these methods, all you need to do is upload the entire contents of your _site\ndirectory to the web server's public document root, which is usually the public_html, htdocs, or www directory.\n\nGitHub Pages - Manually\n\nGitHub Pages is a free service that allows you to host your static site on the web.\n\nIn general, push the entire contents of your _site directory to the gh-pages branch of your repository,\nor the docs\/ directory on your main branch, depending on how you set it up.\n\nPlease see the GitHub Pages documentation for more information.\n\nGitHub Pages - CI\/CD\n\nHyde works amazing with GitHub Pages and GitHub Actions and the entire build and deploy process can be automated.\n\n- We have a great blog post on how to do this, Automate HydePHP sites using GitHub Actions and GitHub Pages.\n\n- You can also copy our sample GitHub Actions Workflow.yml file.\n\nBy the way, HydePHP.com is hosted on GitHub Pages, and the site is compiled in a GitHub Action workflow that compiles and\ndeploys the site automatically when the source is updated using this GitHub workflow.\n\nNext Steps\n\nSo what's next? Well, keep creating amazing content, and share it with the world!\n\nWe'd love to see your creations, so please share your site with us on Twitter, Facebook, or any other social media platform. Use the hashtag #HydePHP and #MadeWithHydePHP so we can find it!\n\nSEO Tips\n\nWhile HydePHP takes most of the hard work out of setting up metadata tags for search engines, there are still a few things you can do to improve your site's SEO.\n\nSet a site URL\n\nThis is the most important: Make sure you have set a SITE_URL either in the .env file or in the hyde.php configuration file. This is so that Hyde can generate absolute URLs, which are favored by search engines and required for sitemaps and RSS feeds.\n\nSitemaps and RSS Feeds\n\nNext, since HydePHP automatically generates sitemaps and RSS feeds, you should take advantage of these by submitting them to search engines. For example, Google Search Console and Bing Webmaster Tools. This will jumpstart the indexing process, and make sure new pages are indexed quickly. You will also be able to see how your site is performing in search results.\n\nSocial sharing\n\nFinally, keep sharing your content, so other people can find your site!","destination":"compile-and-deploy.html"},{"slug":"documentation-pages","title":"Creating Documentation Pages","content":"Creating Documentation Pages\n\nIntroduction to Hyde Documentation Pages\n\nWelcome to the Hyde Documentation Pages, where creating professional-looking documentation sites has never been easier. Using the Hyde Documentation module, all you need to do is place standard Markdown files in the _docs\/ directory, and Hyde takes care of the rest.\n\nHyde compiles your Markdown content into beautiful static HTML pages using a TailwindCSS frontend, complete with a responsive sidebar that is automatically generated based on your Markdown files. You can even customize the order, labels, and groups of the sidebar items to suit your needs.\n\nAdditionally, if you have an _docs\/index.md file, the sidebar header will link to it, and an automatically generated \"Docs\" link will be added to your site's main navigation menu, pointing to your documentation page.\n\nIf you have a Torchlight API token in your .env file, Hyde will even enable syntax highlighting automatically, saving you time and effort. For more information about this feature, see the extensions page.\n\nBest Practices and Hyde Expectations\n\nSince Hyde does a lot of things automatically, there are some things you may need to keep in mind when creating documentation pages so that you don't get unexpected results.\n\nFilenames\n\n- Hyde Documentation pages are files stored in the _docs directory\n- The filename is used as the filename for the compiled HTML\n- Filenames should use kebab-case-name format, followed by the appropriate extension\n- Files prefixed with _underscores are ignored by Hyde\n- You should always have an index.md file in the _docs\/ directory\n- Your page will be stored in _site\/docs\/.html unless you change it in the config\n\nAdvanced Usage and Customization\n\nLike most of HydePHP, the Hyde Documentation module is highly customizable. Much of the frontend is composed using Blade templates and components, which you can customize to your heart's content.\nSince there are so many components, it's hard to list them all here in the documentation, so I encourage you to check out the source code to see how it's all put together and find the customizations you are looking for.\n\nCreating Documentation Pages\n\nYou can create a Documentation page by adding a file to the _docs directory where the filename ends in .md.\n\nYou can also scaffold one quickly by using the HydeCLI.\n\nphp hyde make:page \"Page Title\" --type=\"docs\"\n\nThis will create the following file saved as _docs\/page-title.md\n\nPage Title\n\nFront Matter Is Optional\n\nYou don't need to use front matter to create a documentation page.\n\nHowever, Hyde still supports front matter here as it allows you to quickly override the default values.\n\nHere is a quick reference, however, you should take a look at the dynamic content section to learn more.\n\ntitle: \"Page Title\"\nnavigation:\nlabel: \"Sidebar Label\"\nhidden: true\npriority: 5\n\nDynamic Content Generation\n\nHyde makes documentation pages easy to create by automatically generating dynamic content such as the sidebar and page title. If you are not happy with the results you can customize them in the config or with front matter.\n\nFront Matter Reference\n\nBefore we look at how to override things, here is an overview of the relevant content Hyde generates, and where the data is from as well as where it can be overridden.\n\nProperty                        Description                                            Dynamic Data Source            Override in\n\ntitle (string)                The title of the page used in the HTML ` tag   The first H1 heading (# Foo`) Front matter\nnavigation.label (string)     The label for the page shown in the sidebar            The page basename              Front matter, config\nnavigation.priority (integer) The priority of the page used for ordering the sidebar Defaults to 999                Front matter, config\nnavigation.hidden (boolean)   Hides the page from the sidebar                        none                         Front matter, config\nnavigation.group (string)     The group the page belongs to in the sidebar           Subdirectory, if nested        Front matter\n\nSidebar\n\nThe sidebar is automatically generated from the files in the _docs directory. You will probably want to change the order of these items. You can do this in two ways, either in the config or with front matter using the navigation array settings.\n\nSince this feature shares a lot of similarities and implementation details with the navigation menu, I recommend you read the navigation menu documentation page as well to learn more about the fundamentals and terminology.\n\nSidebar Ordering\n\nThe sidebar is sorted\/ordered by the priority property. The lower the priority value, the higher up in the sidebar it will be. The default priority is 999. You can override the priority using the following front matter:\n\nnavigation:\npriority: 5\n\nYou can also change the order in the config\/docs.php configuration file, which may be easier to manage for larger sites.\n\nBasic Priority Syntax\n\nA nice and simple way to define the order of pages is to add their route keys as a simple list array. Hyde will then match that array order.\n\nIt may be useful to know that Hyde internally will assign a priority calculated according to its position in the list, plus an offset of 500. The offset is added to make it easier to place pages earlier in the list using front matter or with explicit priority settings.\n\n\/\/ filepath: config\/docs.php\n'sidebar' => [\n'order' => [\n'readme', \/\/ Priority: 500\n'installation', \/\/ Priority: 501\n'getting-started', \/\/ Priority: 502\n]\n]\n\nExplicit Priority Syntax\n\nYou can also specify explicit priorities by adding a value to the array keys. Hyde will then use these exact values as the priorities.\n\n\/\/ filepath: config\/docs.php\n'sidebar' => [\n'order' => [\n'readme' => 10,\n'installation' => 15,\n'getting-started' => 20,\n]\n]\n\nSidebar Labels\n\nThe sidebar items are labelled with the label property. The default label is generated from the filename of the file.\n\nYou can change it with the following front matter:\n\nnavigation:\nlabel: \"My Custom Sidebar Label\"\n\nSidebar Grouping\n\nSidebar grouping allows you to group items in the sidebar under category headings. This is useful for creating a sidebar with a lot of items. The official HydePHP.com docs, for instance, use this feature.\n\nThe feature is enabled automatically when one or more of your documentation pages have the navigation.group property set in the front matter, or when documentation pages are organized in subdirectories. Once activated, Hyde will switch to a slightly more compact sidebar layout with pages sorted into labeled groups. Any pages without the group information will be put in the \"Other\" group.\n\nUsing Front Matter\n\nTo enable sidebar grouping, you can add the following front matter to your documentation pages:\n\nnavigation:\ngroup: \"Getting Started\"\n\nAutomatic Subdirectory-Based Grouping\n\nYou can also automatically group your documentation pages by placing source files in subdirectories.\n\nFor example, putting a Markdown file in _docs\/getting-started\/ is equivalent to adding the same front matter seen above.\n\nwarning Note that when the flattened output paths setting is enabled (which it is by default), the file will still be compiled to the _site\/docs\/ directory like it would be if you didn't use the subdirectories. Note that this means that you can't have two documentation pages with the same filename as they would overwrite each other.\n\nHiding Items\n\nYou can hide items from the sidebar by adding the hidden property to the front matter:\n\nnavigation:\nhidden: true\n\nThis can be useful to create redirects or other items that should not be shown in the sidebar.\n\ninfo The index page is by default not shown as a sidebar item, but instead is linked in the sidebar header.\n\nCustomization\n\nPlease see the customization page for in-depth information on how to customize Hyde, including the documentation pages. Here is a high level overview for quick reference though.\n\nOutput Directory\n\nIf you want to store the compiled documentation pages in a different directory than the default 'docs' directory, for example to specify a version like the Hyde docs does, you can specify the output directory in the Hyde configuration file.\n\nThe path is relative to the site output, typically _site.\n\n\/\/ filepath: config\/hyde.php\n'output_directories' => [\n\\Hyde\\Pages\\DocumentationPage::class => 'docs' \/\/ default [tl! --]\n\\Hyde\\Pages\\DocumentationPage::class => 'docs\/1.x' \/\/ What the Hyde docs use [tl! ++]\n]\n\nNote that you need to take care as to not set it to something that may conflict with other parts, such as media or posts directories.\n\nAutomatic Navigation Menu\n\nBy default, a link to the documentation page is added to the navigation menu when an index.md file is found in the _docs directory. Please see the customization page for more information.\n\nSidebar Header Name\n\nBy default, the site title shown in the sidebar header is generated from the configured site name suffixed with \"docs\". You can change this in the Docs configuration file. Tip: The header will link to the docs\/index page, if it exists.\n\n'title' => 'API Documentation',\n\nSidebar Footer Customization\n\nThe sidebar footer contains, by default, a link to your site homepage. You can change this in the config\/docs.php file.\n\n\/\/ filepath: config\/docs.php\n\n'sidebar' => [\n'footer' => 'My Markdown Footer Text',\n],\n\nYou can also set the option to false to disable it entirely.\n\nSidebar Page Order\n\nTo quickly arrange the order of items in the sidebar, you can reorder the page identifiers in the list and the links will be sorted in that order. Link items without an entry here will fall back to the default priority of 999, putting them last.\n\n'sidebar' => [\n'order' => [\n'readme',\n'installation',\n'getting-started',\n],\n]\n\nSee the chapter in the customization page for more details.\n\nSetting Sidebar Group Labels\n\nWhen using the automatic sidebar grouping feature the titles of the groups are generated from the subdirectory names. If these are not to your liking, for example if you need to use special characters, you can override them in the configuration file. The array key is the directory name, and the value is the label.\n\n\/\/ filepath: config\/docs.php\n\n'sidebar' => [\n'labels' => [\n'questions-and-answers' => 'Questions & Answers',\n],\n],\n\nPlease note that this option is not added to the config file by default, as it's not a super common use case. No worries though, just add the following yourself!\n\nSetting Sidebar Group Priorities\n\nBy default, each group will be assigned the lowest priority found inside the group. However, you can specify the order and priorities for sidebar group keys the same way you can for the sidebar items.\n\nJust use the sidebar group key as instead of the page identifier\/route key:\n\n\/\/ filepath: config\/docs.php\n'sidebar' => [\n'order' => [\n'readme',\n'installation',\n'getting-started',\n],\n],\n\nNumerical Prefix Sidebar Ordering\n\nHydePHP v2 introduces sidebar item ordering based on numerical prefixes in filenames. This feature works for the documentation sidebar.\n\nThis has the great benefit of matching the sidebar layout with the file structure view. It also works especially well with subdirectory-based sidebar grouping.\n\n_docs\/\n  01-installation.md     # Priority: 1\n  02-configuration.md    # Priority: 2\n  03-usage.md            # Priority: 3\n\nAs you can see, Hyde parses the number from the filename and uses it as the priority for the page in the sidebar, while stripping the prefix from the route key.\n\nImportant Notes\n\n1. The numerical prefix remains part of the page identifier but is stripped from the route key.\nFor example: _docs\/01-installation.md has route key installation and page identifier 01-installation.\n2. You can delimit the numerical prefix with either a dash or an underscore.\nFor example: Both docs\/01-installation.md and docs\/01_installation.md are valid.\n3. Leading zeros are optional. _docs\/1-installation.md is equally valid.\n\nUsing Numerical Prefix Ordering in Subdirectories\n\nThis feature integrates well with automatic subdirectory-based sidebar grouping. Here's an example of how you could organize a documentation site:\n\n_docs\/\n  01-getting-started\/\n    01-installation.md\n    02-requirements.md\n    03-configuration.md\n  02-usage\/\n    01-quick-start.md\n    02-advanced-usage.md\n  03-features\/\n    01-feature-1.md\n    02-feature-2.md\n\nHere are two useful tips:\n\n1. You can use numerical prefixes in subdirectories to control the sidebar group order.\n2. The numbering within a subdirectory works independently of its siblings, so you can start from one in each subdirectory.\n\nTable of Contents Settings\n\nHyde automatically generates a table of contents for the page and adds it to the sidebar.\n\nIn the config\/docs.php file you can configure the behaviour, content, and the look and feel of the sidebar table of contents. You can also disable the feature completely.\n\n'sidebar' => [\n'tableofcontents' => [\n'enabled' => true,\n'minheadinglevel' => 2,\n'maxheadinglevel' => 4,\n],\n],\n\nTo customize the markup or styles of the table of contents, you can publish the x-hyde::docs.table-of-contents Blade component and modify it to your liking.\n\nUsing Flattened Output Paths\n\nIf this setting is set to true, Hyde will output all documentation pages into the same configured documentation output directory. This means that you can use the automatic directory-based grouping feature, but still have a \"flat\" output structure. Note that this means that you can't have two documentation pages with the same filename or navigation menu label as they will overwrite each other.\n\nIf you set this to false, Hyde will match the directory structure of the source files (just like all other pages).\n\n\/\/ filepath: config\/docs.php\n'flattenedoutputpaths' => true,\n\nSearch Feature\n\nIntroduction\n\nHyde includes a built-in search feature for documentation pages powered by Alpine.js. It consists of two parts:\n1. A search index generator that runs during the build command\n2. An Alpine.js powered frontend that provides the search interface\n\ninfo Tip: The search feature is what powers the search on this site! Why not try it out?\n\nThe search feature is enabled by default. You can disable it by removing the DocumentationSearch option from the Hyde Features config array:\n\n\/\/ filepath: config\/hyde.php\n'features' => [\nFeature::DocumentationSearch, \/\/ [tl! --]\n],\n\nUsing the Search\n\nThe search works by generating a JSON search index which Alpine.js loads asynchronously. There are two ways to access the search:\n\n1. A full-page search screen at docs\/search.html\n2. A modal dialog accessible via a button in the documentation pages (similar to Algolia DocSearch). You can also open this dialog using the keyboard shortcut \/\n\ninfo The full page can be disabled by setting createsearchpage to false in the docs config.\n\nSearch Features\n\nThe search implementation includes:\n- Real-time search results as you type\n- Context highlighting of search terms\n- Match counting and search timing statistics\n- Dark mode support\n- Loading state indicators\n- Keyboard navigation support\n- Mobile-responsive design\n\nHiding Pages from Indexing\n\nFor large pages like changelogs, you may want to exclude them from the search index. Add the page identifier to the excludefromsearch array in the docs config:\n\n\/\/ filepath: config\/docs.php\n'excludefromsearch' => [\n'changelog',\n]\n\nThe page will remain accessible but won't appear in search results.\n\nLive Search with the Realtime Compiler\n\nWhen using php hyde serve, the Realtime Compiler automatically generates a fresh search index each time it's requested, ensuring your search results stay current during development.\n\nAutomatic \"Edit Page\" Button\n\nIntroduction\n\nHyde can automatically add links to documentation pages that take the user to a GitHub page (or similar) to edit the page. This makes it great for open-source projects looking to allow others to contribute to the documentation in a quick and easy manner.\n\nThe feature is automatically enabled when you specify a base URL in the Docs configuration file. Hyde expects this to be a GitHub path, but it will probably work with other methods as well. If not, please send a PR and\/or create an issue on the GitHub repository!\n\ninfo Tip: This documentation site uses this feature, scroll down to the bottom of this page and try it out!\n\nConfiguration\n\nHere's an example configuration from the official HydePHP.com documentation:\n\n\/\/ filepath: config\/docs.php\n\n'sourcefilelocation_base' => 'https:\/\/github.com\/hydephp\/docs\/blob\/master\/',\n\nChanging the Button Text\n\nChanging the label is easy, just change the following config setting:\n\n\/\/ filepath: config\/docs.php\n'editsourcelink_text' => 'Edit Source on GitHub',\n\nChanging the Position\n\nBy default, the button will be shown in the documentation page footer. You can change this by setting the following config setting to 'header', 'footer', or 'both'\n\n\/\/ filepath: config\/docs.php\n'editsourcelink_position' => 'header',\n\nAdding a Button Icon\n\nThis is not included out of the box, but is easy to add with some CSS! Just target the .edit-page-link class.\n\n\/\/ filepath e.g. app.css\n.edit-page-link::before {content: \"\u270f \"}\n\nChanging the Blade View\n\nYou can also publish the edit-source-button.blade.php view and change it to your liking.","destination":"documentation-pages.html"},{"slug":"managing-assets","title":"Managing and Compiling Assets","content":"Managing and Compiling Assets\n\nIntroduction\n\nManaging and compiling assets is a very common task in web development. Unfortunately, it's rarely fun.\n\nWith Hyde, you don't have to do it, in fact, you can skip this entire page if you are happy with how it is. But as always with Hyde, you can customize everything if you want to.\n\nHyde ships with a complete frontend using Blade views, TailwindCSS styles, and Alpine.js interactions, all pre-installed and bundled in the pre-configured Tailwind and Vite setup.\n\nTo get you started quickly, all the styles are already compiled and minified into media\/app.css, which will be copied to the site\/media\/app.css directory when you run php hyde build.\n\nVite\n\nHyde uses Vite to compile assets. Vite is a build tool that aims to provide a faster and more efficient development experience for modern web projects.\n\nWhy Vite?\n\nHydePHP integrates Vite to compile assets such as CSS and JavaScript files. This integration ensures that your assets are processed efficiently, enhancing the development workflow by leveraging Vite's rapid build system.\n\nAsset Management\n\nDevelopment and Production Modes\n\nDevelopment Mode**: Use npm run dev to start the Vite development HMR server, which provides fast live reloading and efficient compilation during development.\nProduction Mode**: Use npm run build for creating optimized, minified asset bundles ready for production deployment.\n\nAsset Compilation:\n\n- Assets are compiled from the resources\/assets directory. The primary CSS file, app.css, is processed with TailwindCSS and other specified tools like PostCSS.\n- Vite automatically processes all scripts and styles, outputting compiled files to the media directory. These are copied to site\/media when the static site is built with php hyde build.\n\nwarn Note that the HydePHP Vite integration only supports CSS and JavaScript files, if you try to load other file types, they will not be processed by Vite.\n\nConfiguration:\n- You can customize Vite's behavior and output paths by modifying the pre-configured vite.config.js file in the project root directory.\n\nHot Module Replacement (HMR)\n\nVite's HMR feature allows for instant updates to the browser without requiring a full page reload. This only works through the realtime compiler when the Vite development server is also running.\n\nYou can start both of these by running npm run dev and php hyde serve in separate terminals, or using the --vite flag with the serve command:\n\nphp hyde serve --vite\n\nBlade Integration\n\nHyde effortlessly integrates Vite with Blade views, allowing you to include compiled assets in your templates. The Blade components hyde::layouts.styles and hyde::layouts.scripts are already set up to load the compiled CSS and JavaScript files.\n\nYou can check if the Vite HMR server is running with Vite::running(), and you can include CSS and JavaScript resources with Vite::asset('path'), or Vite::assets([]) to supply an array of paths.\n\nExample: Using Vite if the HMR server is enabled, or loading the compiled CSS file if not:\n\n@if(Vite::running())\n{{ Vite::assets(['resources\/assets\/app.css']) }}\n@else\n\n@endif\n\nLaravel Herd\n\nIf using Laravel Herd for HydePHP, you can still use Vite by running npm run dev. The Herd integration is in public beta, please report any issues to https:\/\/github.com\/hydephp\/realtime-compiler.\n\nAdditional Information and Answers to Common Questions\n\nIs NodeJS\/NPM Required for Using Hyde?\n\nNo, it is optional. All the compiled styles that you need are already installed, and NPM is only necessary if you want to compile your own styles.\n\nWhen Should Assets be Compiled?\n\nThe _media\/app.css file that comes with Hyde contains TailwindCSS for all classes that are used in the default Blade views, as well as the HydeFront component styles.\nIf you want to customize the Tailwind settings or add custom styles, you will need to recompile the styles yourself.\n\nFor example, if you customize the Blade views and add new classes or add new classes in Blade-based pages, you may need to compile the assets yourself to get the new styles.\nIf you use Markdown-based pages, you do not need to compile anything as those styles are already included in the compiled CSS file.\n\nHow are assets stored and managed?\n\nThe frontend assets are separated into three places.\n\n- The resources\/assets folder contain source files, meaning files that will be compiled into something else.\nHere you will find the app.css file that bootstraps the TailwindCSS styles. This file is also an excellent place\nto add your custom styles. It is also where we import HydeFront. If you compile this file in the base install,\nit will output the same file that's already included in Hyde.\n\n- The _media folder contains compiled (and usually minified) files. When Hyde compiles your static site,\nall asset files here will get copied as they are into the _site\/media folder.\n\n- The _site\/media folder contains the files that are served to the user.\n\nWhat is the difference between media and site\/media?\n\nIt may seem weird to have two folders for storing the compiled assets, but it is quite useful.\n\nThe site directory is intended to be excluded from version control, while the media folder is included in the\nversion control. You are of course free to modify this behaviour by editing the vite.config.js file to change the output directory.\n\nHow Do I Compile Assets?\n\nFirst, make sure that you have installed all the NodeJS dependencies using npm install.\nThen run npm run dev to compile the assets in development mode. For production builds, run npm run build.\n\nHow does it work?\n\nHyde uses Vite to compile assets.\n\nWhen running the npm run dev\/prod command, Vite will compile the resources\/assets\/app.css file into _media\/app.css using PostCSS with TailwindCSS and AutoPrefixer.\n\nThe compiled assets will then be automatically copied to _site\/media when you run php hyde build.\n\nTelling Hyde where to find assets\n\nCustomizing the Blade templates\n\nTo make it really easy to customize asset loading, the styles and scripts are loaded in dedicated Blade components.\n\n- Styles are loaded in hyde::layouts.styles\n- Scripts are loaded in hyde::layouts.scripts\n\nTo customize them, run the following command:\n\nphp hyde publish:views layouts\n\nThen edit the files found in resources\/views\/vendor\/hyde\/layouts directory of your project.\n\nYou might not even need to do anything!\n\nFor the absolute majority of the cases, you don't need to mess with these files. Hyde will automatically load the app.css file when it exists in the _media directory.\n\nLoading from CDN\n\nIf you want to load the same pre-compiled file included with Hyde but from a CDN, you can set loadappstylesfromcdn to true in the config\/hyde.php file. While you lose the ability to customize it, your styles will be automatically updated when needed, as the installed Framework version will automatically specify the correct version to load.\n\nUsing the TailwindCSS Play CDN\n\nwarning Note that the Play CDN is not meant for production use, so enabling it will add a warning to the web console.\n\nIf you want to use the TailwindCSS Play CDN, all you need to do is\nset useplaycdn to true in the config\/hyde.php file. This will in addition to loading the standard app.css file,\nalso add a script tag which loads the TailwindCSS Play CDN.\n\nWhat's even better is that Hyde will also inject the contents of the included tailwind.config.js file into the script tag,\nso the Play CDN styles match the ones created by Vite.\n\nAll in all, this allows you to tinker around with Tailwind without having to compile anything.\n\nManaging Images\n\nAs mentioned above, assets stored in the media folder are automatically copied to the site\/media folder,\nmaking it the recommended place to store images. You can then easily reference them in your Markdown files.\n\nReferencing images\n\nThe recommended way to reference images is with relative paths as this offers the most compatibility,\nallowing you to browse the site both locally on your filesystem and on the web when serving from a subdirectory.\n\nwarning Note: The path is relative to the compiled file in the site output\n\nThe path to use depends on the location of the page. Note the subtle difference in the path prefix.\n\n- If you are in a Blog Post or Documentation Page, use ..\/media\/image.png\n- If in a Markdown Page or Blade Page, use media\/image.png\n- While not recommended, you can also use absolute paths: \/media\/image.png\n- You can of course also use full URLs, for example when using a CDN.\n\nMaking images accessible\n\nTo improve accessibility, you should always add an alt text. Here is a full example including an image in a blog post:\n\nImage Alt # Note the relative path\n\nSetting a featured image for blog posts\n\nHyde offers great support for creating data-rich and accessible featured images for blog posts.\n\nYou can read more about this on the creating blog posts page.","destination":"managing-assets.html"},{"slug":"static-pages","title":"Creating Static Pages","content":"# Creating Static Pages\n\n## Introduction to Hyde Pages\n\nHyde offers two ways to create static pages:\nMarkdown pages which are perfect for simple pages that focus heavily on the content,\nand Blade pages which are perfect for more complex pages where you want full control over the HTML,\nand where you may want to include other components or want to use dynamic PHP code.\n\nLet's start with the basics.\n\n### Best Practices and Hyde Expectations\n\nSince Hyde does a lot of things automatically, there are some things you may need\nto keep in mind when creating pages so that you don't get unexpected results.\n\n#### Filenames\n\n- Hyde Pages are files stored in the _pages directory\n- The filename is used as the filename for the compiled HTML\n- Filenames should use kebab-case-identifier format, followed by the appropriate extension\n- Files prefixed with _underscores are ignored by Hyde\n- Your page will be stored in _site\/.html\n- Blade pages will override any Markdown pages with the same filename when compiled\n\n## Creating Markdown Pages\n\nMarkdown pages are the easiest way to create static pages. You can create a Markdown page by adding a file to the\n_pages directory where the filename ends in .md. You can also use Front Matter to add page metadata.\n\n### Scaffolding Markdown Pages\n\nScaffolding a Markdown page is as easy as using the HydeCLI.\n\nphp hyde make:page \"Page Title\"\n\nThis will create the following file saved as _pages\/page-title.md\n\ntitle: Page Title\n# Page Title\n\n\/\/ Write your content here\n\nYou can of course also create the file yourself with your text editor.\n\n### Front Matter is optional\n\nThe most common front matter used for Markdown pages is the title, which is used as the HTML ``.\n\nIf you don't supply a front matter title, Hyde will attempt to find a title in the Markdown body by searching\nfor the first level one heading (# Page Title), and if that fails, it will generate one from the filename.\n\n#### Navigation Front Matter\n\nFurthermore, you can customize how the page appears in the navigation menu using the following front matter options.\nYou can set just one or all of them, as Hyde will fill in the gaps for the rest.\n\nnavigation:\nlabel: 'string',\npriority: 'int',\nhidden: 'bool',\ngroup: 'string',\n\n- label is the text that will be displayed in the navigation menu\n- priority is the order in which the page will appear in the navigation menu (order is also supported)\n- hidden will hide the page from the navigation menu (visible is also supported, but obviously invert the value)\n- group will put the page in a dropdown menu with the specified group name (category is also supported)\n\n## Creating Blade Pages\n\nSince Hyde is based on Laravel and uses the powerful Blade templating engine, you can use Blade pages to create more\ncomplex pages with both standard HTML, PHP code, and the templating opportunities provided by Blade directives.\n\nIf you are not familiar with Blade, you may want to read the Laravel Blade docs first.\n\n### Scaffolding Blade Pages\n\nWe can scaffold Blade pages using the same CLI command as Markdown pages, however, this time we need to specify that\nwe want to use the blade page type, by using the --type option.\n\nphp hyde make:page \"Page Title\" --type=\"blade\"\n\nThis will create a file saved as _pages\/page-title.blade.php\n\nYou can of course also create the file yourself with your text editor, however,\nthe scaffolding command for Blade pages is arguably even more helpful than the\none for Markdown pages, as this one automatically adds the included app Layout.\n\nLet's take a look at the scaffolded file. You can also copy and paste this\nif you don't want to use the scaffolding command.\n\n@extends('hyde::layouts.app')\n@section('content')\n@php($title = \"Page Title\")\n\nPage Title\n\n@endsection\n\nTip: You don't have to use Blade in Blade pages. It's also perfectly fine to use plain HTML,\nhowever you still need to use the blade.php extension so Hyde can recognize it.\n\n## When to Use Which?\n\nMarkdown pages look great and work well for simple \"about\" pages and the like, but with Markdown we are still pretty limited.\n\nIf you are comfortable with it and have the need for it, use Blade to create more complex pages! And mix and match between them!\nSome page types are better suited for Markdown, and others for Blade. Don't limit yourself to just one type.\n\n### Comparison\n\nMarkdown                                            Blade\n\n\u2795 Easily created and updated                        \u2795 Full control over the HTML\n\u2795 Very fast to create simple and lightweight pages  \u2795 Use the default app layout or create your own\n\u2795 Suited for content-heavy pages such as \"about us\" \u2795 Use Blade templates and components to keep code DRY\n\u2796 Not as flexible as Blade pages                    \u2795 Use arbitrary PHP right in the page to create dynamic content\n\u2795 Access to all Blade helper directives like @foreach, @if, etc.\n\u2796 Takes longer to create as you need to write the markup\n\u2796 You may need to recompile your CSS if you add Tailwind classes\n\n### Live Demos\n\nThe Hyde website (hydephp.com) uses both Markdown and Blade pages. The homepage for example, is a Blade page and uses a bunch of custom HTML.\n\nA great example of a Markdown page can be found at hydephp.github.io\/portfolio-demo, you can see the page source here on GitHub.\n\n## Bonus: Creating HTML Pages\n\nIf you have an already created HTML page, simply drop it into the _pages directory and Hyde will copy it over as it is\ninto the _site directory. Like all other Hyde pages, the page will show up in the navigation menu using a title parsed from the filename.\nYou won't be able to change any settings with front matter, however.","destination":"static-pages.html"},{"slug":"advanced-customization","title":"Advanced Customization","content":"Advanced Customization\n\nIntroduction\n\nThis page covers advanced usage and is intended for developers who know what they are doing. Documentation here will be\nmainly example driven, as it is assumed you have somewhat of an understanding of what you are doing already.\n\nPrerequisites for customizing directories\n\ninfo Before customizing source and output directories it may be helpful to know how these settings are stored internally.\n\nThe following is a summary from the Page Models documentation:\n\nEach page type is represented by a page model class. Each of those classes have static properties that store the source and output directories.\nThese properties are set when the HydeServiceProvider\nis registered. At this point, the provider will search for any overrides in the config file.\n\nThis means that there are two options to change the source and output directories:\n1. Recommended: You can change the values in the config file, to let the HydeServiceProvider handle it for you.\n2. Advanced\/Overkill: You can also set the static properties directly in the page model classes if you prefer.\n   - You'd probably want to do this in a service provider, as it must be done before the Kernel is booted.\n   - You can use the RegistersFileLocations\ntrait to use the same registration logic as the HydeServiceProvider.\n\nCustomizing Source Directories\n\nThe directories you place your content in are important. The directory will be used to determine the proper page type and the templates used.\nIf you are not happy the with defaults, you can change them. Note that these are relative to the source_root setting,\nwhich is the root of your project, by default.\n\nNote that you need to take care of conflicts when changing the source directories. For example, if you store Markdown\nposts in the same directory as documentation pages, Hyde will not know which page type to use.\n\nIn the config file\n\n\/\/ filepath config\/hyde.php\n\n'source_directories' => [\nHtmlPage::class => '_pages',\nBladePage::class => '_pages',\nMarkdownPage::class => '_pages',\nMarkdownPost::class => '_posts',\nDocumentationPage::class => '_docs',\n],\n\nIn a service provider\n\n\/\/ filepath app\/AppServiceProvider.php\nuse Hyde\\Framework\\Concerns\\RegistersFileLocations;\n\npublic function register(): void\n{\n$this->registerSourceDirectories([\nHtmlPage::class => '_pages',\nBladePage::class => '_pages',\nMarkdownPage::class => '_pages',\nMarkdownPost::class => '_posts',\nDocumentationPage::class => '_docs',\n]);\n}\n\nCustomizing Output Directories\n\nLike source directories, the output directories are also important as they determine the output path for the compiled pages.\nwarning Note that changing output directories also affects the route keys, as those are based on the output directory. Scroll down to see the Route key impact section for more information.\n\nEach option is relative to the site's output_directory setting. Setting a value to '' will output the page to the site root.\n\nIn the config file\n\n\/\/ filepath config\/hyde.php\n'output_directories' => [\nHtmlPage::class => '',\nBladePage::class => '',\nMarkdownPage::class => '',\nMarkdownPost::class => 'posts',\nDocumentationPage::class => 'docs',\n],\n\nIn a service provider\n\n\/\/ filepath app\/AppServiceProvider.php\nuse Hyde\\Framework\\Concerns\\RegistersFileLocations;\n\npublic function register(): void\n{\n$this->registerOutputDirectories([\nHtmlPage::class => '',\nBladePage::class => '',\nMarkdownPage::class => '',\nMarkdownPost::class => 'posts',\nDocumentationPage::class => 'docs',\n]);\n}\n\nRoute key impact\n\nFor example, changing the output directory of Markdown posts to blog instead of posts will change the route key base from posts to blog.\nThis means that a file stored as _posts\/hello-world.md will have the route key blog\/hello-world instead of posts\/hello-world.\nNote that this may break your site's configuration and links, so you should always verify your site works properly after such a change.\nYou can learn more about this in the route key documentation.\n\nCustom Source Root\n\nHydePHP will by default look for the source directories shown above in the root of your project.\nIf you're not happy with this, it's easy to change! For example, you might want everything in a 'src' subdirectory.\nThat's easy enough, just set the value of the source_root setting in config\/hyde.php to 'src', or whatever you prefer!\n\n\/\/ filepath config\/hyde.php\n\n'source_root' => '', \/\/ [TL! --]\n'source_root' => 'src', \/\/ [TL! ++]\n\nAutomatic change\n\nYou can even make this change automatically with the php hyde change:sourceDirectory command!\n\nphp hyde change:sourceDirectory\n\nWhen run, Hyde will update the source directory setting in the config file, then create the directory if it doesn't exist,\nand move all source directories and their content into it.\n\nCustom Media Directory\n\nThe media directory houses assets like images and stylesheets. The default directory is _media, and upon building the site,\nHyde will copy all files in this directory to _site\/media (or whatever your configured output and media directories are).\n\nYou can change the path to this directory by setting the media_directory option in config\/hyde.php.\n\n\/\/ filepath config\/hyde.php\n'mediadirectory' => 'media',\n\nNext steps\n\n1. Note that you will likely need to manually update vite.config.js so Vite can compile the assets correctly.\n2. You will of course also need to copy over any existing files from the old directory to the new one.\n\nNote that this setting affects both source and output directories\n\nNote that this change will affect both the source and output directories. For example, if you set the value to assets,\nall files from assets will be copied to _site\/assets. If the setting starts with an underscore, that will be removed\nfrom the output directory, so files in assets will be copied to site\/assets.\n\nCustom Output Directory\n\ndanger Warning: Hyde deletes all files in the output directory before compiling the site. Don't set this path to a directory that contains important files!\n\nIf you want to store your compiled website in a different directory than the default _site, you can change the path\nusing the following configuration option in config\/hyde.php. The path is expected to be relative to your project root.\n\n\/\/ filepath config\/hyde.php\n'outputdirectory' => 'site',","destination":"advanced-customization.html"},{"slug":"advanced-markdown","title":"Advanced Markdown","content":"Advanced Markdown\n\nIntroduction\n\nSince HydePHP makes heavy use of Markdown, there are some extra features and helpers created just for Hyde to make using Markdown even easier and more powerful!\n\nUsing Blade in Markdown\n\nA special feature in Hyde, is that you can use Laravel Blade in Markdown files!\n\nTo use Blade in your Markdown files, simply use the Blade shortcode directive, followed by your desired Blade string.\n\nStandard syntax\n\n[Blade]: {{ \"Hello World!\" }} \/\/ Will render: 'Hello World!'\n\nBlade includes\n\nOnly single-line shortcode directives are supported. If you need to use multi-line Blade code, use an @include\ndirective to render a more complex Blade template. You can pass data to includes by specifying an array to the second argument.\n\n[Blade]: @include(\"hello-world\")\n[Blade]: @include(\"hello\", [\"name\" => \"World\"])\n\nEnabling Blade-supported Markdown\n\nThe feature is disabled by default since it allows arbitrary PHP to run, which could be a security risk, depending on your setup.\nHowever, if your Markdown is trusted, and you know it's safe, you can enable it in the config\/markdown.php file.\n\n\/\/ filepath: config\/markdown.php\n'enable_blade' => true,\n\nLimitations\n\nAll shortcodes must be the first word on a new line, and only single-line shortcodes are supported.\n\nColoured Blockquotes\n\nThe HydePHP Markdown converter also supports some extra directives and features. One of them being four different\ncoloured blockquotes. Simply append the desired colour after the initial > character.\n\n\u200e> Normal Blockquote\n\u200e>info Info Blockquote\n\u200e>warning Warning Blockquote\n\u200e>danger Danger Blockquote\n\u200e>success Success Blockquote\n\nNormal Blockquote\ninfo Info Blockquote\nwarning Warning Blockquote\ndanger Danger Blockquote\nsuccess Success Blockquote\n\nCustomizations\n\nYou can easily customize these styles by publishing and editing the markdown-blockquote.blade.php file.\n\nphp hyde publish:views components\n\nMarkdown usage\n\nThe coloured blockquotes also support inline Markdown, just like normal blockquotes.\n\n\u200e>info Formatting is supported!\n\nLimitations\n\nNote that these currently do not support multi-line blockquotes.\n\nCode Block Filepaths\n\nWhen browsing these documentation pages you may have noticed a label in the top right corner of code blocks specifying the file path.\nThese are also created by using a custom Hyde feature that turns code comments into automatic code blocks.\n\nUsage\n\nSimply add a code comment with the path in the first line of a fenced code block like so:\n\n\/\/ filepath: _docs\/advanced-markdown.md\n\u200e\/\/ filepath: hello-world.php\n\necho 'Hello World!';\n\nWhich becomes:\n\n\/\/ filepath: hello-world.php\n\necho 'Hello World!';\n\nAlternative syntax\n\nThe syntax is rather forgiving, by design, and supports using both \/\/ and # for comments.\nThe colon is also optional, and the 'filepath' string is case-insensitive. So the following is also perfectly valid:\n\n\u200e\/\/ filepath hello.js\nconsole.log('Hello World!');\n\nIf you have a newline after the filepath, like in the first example, it will be removed so your code stays readable.\n\nAdvanced usage\n\nIf you have enabled HTML in Markdown by setting the allow_html option to true in your config\/markdown.php file,\nanything within the path label will be rendered as HTML. This means you can add links, or even images to the label.\n\n\/\/ filepath: View file on Github\n\u200e\/\/ filepath: View file on Github\n\nLimitations\n\nThe filepaths are hidden on mobile devices using CSS to prevent them from overlapping with the code block.\n\nHeading Permalinks\n\nHyde automatically adds clickable permalink anchors to headings in documentation pages. When you hover over a heading, a # link appears that you can click to get a direct link to that section.\n\nUsage & Configuration\n\nThe feature is enabled by default for documentation pages. When enabled, Hyde will automatically add permalink anchors to headings between levels 2-4 (h2-h4). The permalinks are hidden by default and appear when hovering over the heading.\n\nYou can enable it for other page types by adding the page class to the permalinks.pages array in the config\/markdown.php file, or disable it for all pages by setting the array to an empty array.\n\n\/\/ filepath: config\/markdown.php\n'permalinks' => [\n'pages' => [\n\\Hyde\\Pages\\DocumentationPage::class,\n],\n],\n\nAdvanced Customization\n\nUnder the hood, Hyde uses a custom Blade-based heading renderer when converting Markdown to HTML. This allows for more flexibility and customization compared to standard Markdown parsers. You can also publish and customize the Blade component used to render the headings:\n\nphp hyde publish:components\n\nThis will copy the markdown-heading.blade.php component to your views directory where you can modify its markup and behavior.\n\nDynamic Markdown Links\n\nHydePHP provides a powerful feature for automatically converting Markdown links to source files to the corresponding routes in the built site.\n\nThis allows for a much better writing experience when using an IDE, as you can easily navigate to the source file by clicking on the link. Hyde will then automatically resolve the link to the correct route when building the site, formatting the links properly using dynamic relative paths and your configured pretty_urls setting.\n\nUsage\n\nUsing the feature is simple: Just use the source file path when linking to the page you want to resolve:\n\nHome\nDocs\nFeatured Post\nLogo\n\nAs you can see, it works for both pages and media assets. The leading slash is optional and will be ignored by Hyde, but including it often gives better IDE support.\n\nBehind the Scenes\n\nDuring the build process, HydePHP converts source paths to their corresponding routes and evaluates them depending on the page being rendered.\n\nIf your page is in the site root then:\n\n- \/_pages\/index.blade.php becomes index.html\n- \/_media\/logo.svg becomes media\/logo.svg\n\nIf your page is in a subdirectory then:\n\n- \/_pages\/index.blade.php becomes ..\/index.html\n- \/_media\/logo.svg becomes ..\/media\/logo.svg\n\nOf course, if your page is in a more deeply nested directory, the number of ..\/ will increase accordingly.\n\nWe will also match your configured preference for pretty_urls and only include the .html extension when desired.\n\nLimitations\n\nThere are some limitations and considerations to keep in mind when using this feature:\n\n- This feature will not work for dynamic routes (not backed by a file)\n- If you rename a file, links will break. Your IDE may warn about this.\n- If a file is not found, we will not be able to see it when evaluating links.\n- Relative links are not supported (so ..\/_pages\/index.blade.php will not work)\n\nConfiguration\n\nFull configuration reference\n\nAll Markdown-related configuration options are in the config\/markdown.php file.\nYou can find the full reference on the Customization page.\n\nRaw HTML Tags\n\nTo convert Markdown, HydePHP uses the GitHub Flavored Markdown extension, which strips out potentially unsafe HTML.\nIf you want to allow all arbitrary HTML tags, and understand the risks involved, you can enable all HTML tags by setting\nthe allow_html option to true in your config\/markdown.php file.\n\n\/\/ filepath: config\/markdown.php\n'allow_html' => true,\n\nThis will add and configure the DisallowedRawHtml CommonMark extension so that no HTML tags are stripped out.\n\nTailwind Typography Prose Classes\n\nHydePHP uses the Tailwind Typography to style rendered Markdown.\nWe do this by adding the .prose CSS class to the HTML elements containing the rendered Markdown, using the built-in Blade components.\n\nYou can easily edit these classes, for example if you want to customize the prose colours, in the config\/markdown.php file.\n\n\/\/ filepath: config\/markdown.php\n'prose_classes' => 'prose dark:prose-invert', \/\/ [tl! remove]\n'prose_classes' => 'prose dark:prose-invert prose-img:inline', \/\/ [tl! add]\n\nPlease note that if you add any new classes, you may need to recompile your CSS file.","destination":"advanced-markdown.html"},{"slug":"collections","title":"File-based Collections","content":"# File-based Collections\n\n## Introduction to Hyde Data Collections\n\nHyde provides DataCollection, a subset of Laravel Collections giving you a similar developer experience to working with Eloquent Collections.\nHowever, instead of accessing a database, it's all entirely file-based using static data files such as Markdown, Yaml, and JSON files which get\nparsed into objects that you can easily work with.\n\nAs you have access to all standard Laravel Collection methods, you are encouraged to read the Laravel Collections documentation for more information.\n\nThis article covers advanced usage intended for those who are writing their own Blade views, and is not required as Hyde comes pre-packaged with many templates for you to use.\n\n## High-Level Concept Overview\n\nIn short, HydePHP finds files in the specified directory, turns each file into an object, and returns a Laravel Collection of these objects.\n\nTo make collections easy to use and understand, Hyde makes a few assumptions about the structure of your collections.\nFollow these conventions and creating dynamic static sites will be a breeze.\n\n1. Collections are accessed through static methods in the DataCollection class.\n2. Collections are stored as files in subdirectories of the resources\/collections directory.\n3. To get a collection, specify name of the subdirectory the files are stored in.\n4. Data will be parsed into differing objects depending on which facade method you use. See the table below.\n5. The class is aliased so that you can use it in Blade files without having to include the namespace.\n6. While not enforced, each subdirectory should probably only have the same filetype to prevent developer confusion.\n7. Unlike source files for pages, files starting with underscores are not ignored.\n8. You can customize the source directory for collections through a service provider.\n\n## Available Collection Types\n\n### Quick Reference Overview\n\nThe following facade methods for creating data collections are available:\n\n\\Hyde\\Support\\DataCollection::markdown(string $name);\n\\Hyde\\Support\\DataCollection::yaml(string $name);\n\\Hyde\\Support\\DataCollection::json(string $name, bool $asArray = false);\n\n### Quick Reference Table\n\nCollection Type                       Facade Method  Returned Object Type                                                                                                                                     File Extension\n\nMarkdown ::markdown() MarkdownDocument                                          .md\nYaml         ::yaml()     FrontMatter                                                    .yaml,&nbsp; .yml\nJson         ::json()     stdClass OR&nbsp; array .json\n\n## Markdown Collections\n\n### Usage\n\n$collection = \\Hyde\\Support\\DataCollection::markdown('name');\n\n### Example returns\n\nHere is an approximation of the data types contained by the variable created above:\n\n\\Hyde\\Support\\DataCollection {\n\"testimonials\/1.md\" => Hyde\\Markdown\\Models\\MarkdownDocument\n\"testimonials\/2.md\" => Hyde\\Markdown\\Models\\MarkdownDocument\n\"testimonials\/3.md\" => Hyde\\Markdown\\Models\\MarkdownDocument\n]\n}\n\nThe returned MarkdownObjects look approximately like this:\n\n\\Hyde\\Markdown\\Models\\MarkdownDocument {\n  +matter: Hyde\\Markdown\\Models\\FrontMatter {\n     +data: array:1 [\n\"author\" => \"John Doe\"\n]\n}\n  +markdown: Hyde\\Markdown\\Models\\Markdown {\n    +body: \"Lorem ipsum dolor sit amet, consectetur adipiscing elit...\"\n}\n}\n\nAssuming the Markdown document looks like this:\n\nauthor: \"John Doe\"\nLorem ipsum dolor sit amet, consectetur adipiscing elit...\n\n## YAML Collections\n\n### Usage\n\n$collection = \\Hyde\\Support\\DataCollection::yaml('name');\n\n### Example returns\n\nHere is an approximation of the data types contained by the variable created above:\n\n\\Hyde\\Support\\DataCollection {\n\"authors\/1.yaml\" => Hyde\\Markdown\\Models\\FrontMatter {\n    +data: array:1 [\n\"name\" => \"John Doe\",\n\"email\" => \"john@example.org\"\n]\n}\n}\n\nAssuming the Yaml document looks like this:\n\nname: \"John Doe\"\nemail: \"john@example.org\"\n\n## Json Collections\n\n### Usage\n\n$collection = \\Hyde\\Support\\DataCollection::json('name');\n\nBy default, the entries will be returned as stdClass objects. If you want to return an associative array instead, pass true as the second parameter:\n\n$collection = \\Hyde\\Support\\DataCollection::json('name', true);\n\nSince both return values use native PHP types, there are no example returns added here, as I'm sure you can imagine what they look like.\n\n## Markdown Collections - Hands-on Guide\n\nI think the best way to explain DataCollections is through examples, so let's create a Blade page with customer testimonials!\n\nThis example will use Markdown Collections, but the same concepts apply to all other collection types.\n\n#### Setting up the file structure\n\nWe start by setting up our directory structure. We will create a testimonials subdirectory, which will be the collection name.\n\nIn it, we will place Markdown files. Each file will be a testimonial.\nThe Markdown will be parsed into a MarkdownDocument object which parses any optional YAML front matter.\n\nHere is the sample Markdown we will use:\n\n\/\/ filepath: resources\/collections\/testimonials\/1.md\nauthor: John Doe\nLorem ipsum dolor sit amet, consectetur adipiscing elit...\n\nLet's take a look at our directory structure. I just copied the same file a few times.\nYou can name the files anything you want, I kept it simple and just numbered them.\n\nresources\/collections\n\u2514\u2500\u2500 testimonials\n\u251c\u2500\u2500 1.md\n\u251c\u2500\u2500 2.md\n\u2514\u2500\u2500 3.md\n\n#### Using the Facade to Access the Collections\n\nNow for the fun part! We will use the DataCollection::markdown() to access all our files into a convenient object.\nThe class is registered with an alias, so you don't need to include any namespaces when in a Blade file.\n\nThe general syntax to use the facade is as follows:\n\nDataCollection::markdown('subdirectory_name')\n\nThis will return a Hyde DataCollection object, containing our Markdown files as MarkdownDocument objects. Here is a quick look at the object the facade returns:\n\n^ Hyde\\Support\\DataCollection {#651 \u25bc\n#items: array:3 [\u25bc\n\"testimonials\/1.md\" =&gt; Hyde\\Markdown\\Models\\MarkdownDocument {#653 \u25bc\n      +matter: Hyde\\Markdown\\Models\\FrontMatter {#652 \u25b6}\n      +markdown: Hyde\\Markdown\\Models\\Markdown {#654 \u25b6}\n}\n\"testimonials\/2.md\" =&gt; Hyde\\Markdown\\Models\\MarkdownDocument {#656 \u25b6}\n\"testimonials\/3.md\" =&gt; Hyde\\Markdown\\Models\\MarkdownDocument {#659 \u25b6}\n]\n}\n\n#### Implementing it in a Blade view\n\nLet's create a Blade page to display all our testimonials.\n\nphp hyde make:page \"Testimonials\" --type=\"blade\"\n\nAnd we can use the collection almost like any other Laravel one. As you can see, since each entry is a MarkdownDocument class,\nwe are able to get the author from the front matter, and the content from the body.\n\n\/\/ filepath _pages\/testimonials.blade.php\n@foreach(DataCollection::markdown('testimonials') as $testimonial)\n\n{{ $testimonial->body }}\n{{ $testimonial->matter['author'] }}\n\n@endforeach","destination":"collections.html"},{"slug":"customization","title":"Customizing Your Site","content":"# Customizing Your Site\n\n## Introduction\n\nHyde favours \"Convention over Configuration\"\nand comes preconfigured with sensible defaults. However, Hyde also strives to be modular and endlessly customizable\nif you need it. This page guides you through the many options available!\n\nAll the configuration files are stored in the config directory, and allow you to customize almost all aspects of your site.\nEach option is documented, so feel free to look through the files and get familiar with the options available to you.\n\n## Accessing Configuration Values\n\n### Configuration API Recap\n\nHydePHP uses the same configuration system as Laravel. Here's a quick recap from the Laravel Documentation:\n\nYou may easily access your configuration values using the global config function from anywhere in your project code.\nThe configuration values may be accessed using \"dot notation\" syntax, which includes the name of the file and option you wish to access.\n\n$value = config('hyde.name');\n\nA default value may also be specified and will be returned if the configuration option does not exist:\n\n$value = config('hyde.name', 'HydePHP');\n\nHydePHP also provides a strongly typed Config facade which extends the Laravel Config facade, but allows strict types:\n\nuse Hyde\\Facades\\Config;\n\n\/\/ Will always return a string, or it throws a TypeError\n$name = Config::getString('hyde.name', 'HydePHP'): string;\n\n### Dot Notation\n\nAs seen in the example above, when referencing configuration options, we often use \"dot notation\" to specify the configuration file.\nFor example, config('hyde.name') means that we are looking for the name option in the config\/hyde.php file.\n\n### Front Matter or Configuration Files?\n\nIn some cases, the same options can be set in the front matter of a page or in a configuration file. Both ways are always documented, and it's up to you to choose which one you prefer. Note that in most cases, if a setting is set in both the front matter and the configuration file, the front matter setting will take precedence.\n\n### A note on file paths\n\nWhen Hyde references files, especially when passing filenames between components, the file path is almost always\nrelative to the root of the project. Specifying absolute paths yourself could lead to unforeseen problems.\n\n## Configuration Files Overview\n\nThere are a few configuration files available in the config directory. All options are documented, so feel free to look through the files and get familiar with the options available to you.\n\nBelow are two tables over the different configuration files. Click on a file name to see the default file on GitHub.\n\n### HydePHP Configuration Files\n\nThese are the main configuration files for HydePHP and lets you customize the look and feel of your site, as well as the behaviour of HydePHP itself.\nThe main configuration file, hyde.php, is used for things ranging from site name and base URL to navigation menus and what features to enable.\n\nConfig File                                                                                                        Description\n\nhyde.php         Main HydePHP configuration file for customizing the overall project.\ndocs.php         Options for the HydePHP documentation site generator module.\nmarkdown.php Configure Markdown related services, as well as change the CommonMark extensions.\napp\/config.php    Configures the underlying Laravel application. (Commonly found as config\/app.php in Laravel apps)\n\ninfo Tip: The values in hyde.php can also be set in YAML by creating a hyde.yml file in the root of your project. See #yaml-configuration for more information.\n\n### Publishable Laravel & Package Configuration Files\n\nSince HydePHP is based on Laravel we also have a few configuration files related to them. As you most often don't need\nto edit any of these, unless you want to make changes to the underlying application, they are not present in the\nbase HydePHP installation. However, you can publish them to your project by running php hyde publish:configs.\n\nConfig File                                                                                                            Description\n\nview.php             Configures the paths for the Blade View compiler.\ncache.php           Configures the cache driver and cache path locations.\ncommands.php     Configures the Laravel Zero commands for the HydeCLI.\ntorchlight.php Configures settings for the Torchlight syntax highlighting integration.\n\n{.align-top}\n\nIf any of these files are missing, you can run php hyde publish:configs to copy the default files to your project.\n\n## Configuration Options\n\nWhile all options are already documented within the files, here are some further explanations of some of the options.\n\n### RSS feed generation\n\nWhen enabled, an RSS feed containing all your Markdown blog posts will be generated when you compile your static site.\nHere are the default settings:\n\n\/\/ filepath config\/hyde.php\n'rss' => [\n\/\/ Should the RSS feed be generated?\n'enabled' => true,\n\n\/\/ What filename should the RSS file use?\n'filename' => 'feed.xml',\n\n\/\/ The channel description.\n'description' => env('SITE_NAME', 'HydePHP').' RSS Feed',\n],\n\nwarning Note that this feature requires that a site_url is set!\n\n### Authors\n\nHyde supports adding authors to blog posts, allowing you to automatically include information like display names and website links.\nWe even support fields for avatars, biographies, and social media profiles, which you can use in your custom Blade templates.\n\nWhile you can set all this data directly in the front matter, that quickly becomes tedious and hard to maintain.\nInstead, you can predefine authors in the Hyde config. When writing posts, just specify the username in the front matter,\nand the rest of the data will be pulled from a matching entry found in the configuration file.\n\n#### Configuration\n\nAuthors are defined in the config\/hyde.php file under the authors key. Each author is keyed by their username and is configured using the Author::create() method:\n\n\/\/ filepath: config\/hyde.php\n'authors' => [\n'mr_hyde' => Author::create(\n\/\/ The following fields, along with the username, are used by the default blog post templates.\nname: 'Mr. Hyde',\nwebsite: 'https:\/\/hydephp.com',\n\n\/\/ These fields are not currently used in the default templates, but you can use them in your custom views.\nbio: 'The mysterious author of HydePHP',\navatar: 'avatar.png',\nsocials: [\n'twitter' => '@HydeFramework',\n'github' => 'hydephp',\n],\n),\n],\n\nThis is equivalent to the following front matter in a blog post:\n\nauthor:\nusername: mr_hyde\nname: Mr. Hyde\nwebsite: https:\/\/hydephp.com\nbio: The mysterious author of HydePHP\navatar: avatar.png\nsocials:\ntwitter: \"@HydeFramework\"\ngithub: hydephp\n\nBut you only have to specify the username to get all the other data.\n\nauthor: mr_hyde\n\nIf you want to override the data for a specific post, you can do so in the front matter which is great for guest authors or one-off posts.\n\n#### Available Fields\n\n- name: The author's display name (optional, generated from username if not provided)\n- website: The author's website URL (optional)\n- bio: A short biography (optional, not used in default templates)\n- avatar: Path to the author's avatar image (optional, not used in default templates)\n- socials: An array of social media links (optional, not used in default templates)\n\n#### Notes\n\n- Usernames are automatically normalized (converted to lowercase with spaces replaced by underscores)\n- The PostAuthor class includes a getPosts() method to retrieve all posts by an author\n- Authors can be accessed through Hyde::authors()\n\nFor more advanced usage and customization, refer to the source code which is well documented.\n\n### Footer\n\nMost websites have a footer with copyright details and contact information. You probably want to change the Markdown to include your information, though you are of course welcome to keep the default attribution link!\n\nThe footer component is made up of a few levels of components, depending on how much you want to customize.\n\n#### Customizing the Markdown text\n\nThere are two ways to customize the footer text. First, you can set it in the configuration file:\n\n\/\/ filepath: config\/hyde.php\n'footer' => 'Site proudly built with HydePHP \ud83c\udfa9',\n\nIf you don't want to write Markdown in the configuration file, you can create a Markdown file in your includes directory. When this file is found, it will be used instead of the configuration setting.\n\n\/\/ filepath: resources\/includes\/footer.md\nSite proudly built with HydePHP \ud83c\udfa9\n\nIn both cases the parsed Markdown will be rendered in the footer Blade component.\n\n#### Customizing the Blade component\n\nThe actual footer component is rendered using the layouts\/footer.blade.php Blade template.\n\nIn this template we automatically render the configured footer Markdown text. If you want to change this behaviour, for example, HydePHP.com uses a more sophisticated footer, simply publish the footer component.\n\n#### Disabling the footer entirely\n\nIf you don't want to have a footer on your site, you can set the 'footer' configuration option to false.\n\n\/\/ filepath: config\/hyde.php\n'footer' => 'false',\n\n#### Disabling the scroll-to-top button\n\nThe footer includes a scroll-to-top button by default. If you want to keep the footer but hide this button, add the following to your configuration file:\n\n\/\/ filepath: config\/hyde.php\n'footerscrolltotopbutton' => false,\n\n### Head and script HTML hooks\n\ninfo Note: The configuration options head and scripts were added in HydePHP v1.5. If you are running an older version, you need to use the Blade options, or upgrade your project.\n\nWhile the most robust way to add custom HTML to the head or body of your site is to publish the Blade layouts, or pushing to the meta or scripts stacks,\nyou can also add custom HTML directly in the configuration file. This works especially well to quickly add things like analytics widgets or similar in the hyde.yml file, though the possibilities are endless.\n\nTo add custom HTML to your layouts, you can use the head and scripts configuration options in the config\/hyde.php file (or the hyde.yml file).\nThe HTML will be added to the ` section, or just before the closing ` tag, respectively.\nNote that the HTML is added to all pages. If you need to add HTML to a specific page, you will need to override the layout for that page.\n\n\/\/ filepath: config\/hyde.php\n'head' => '',\n'scripts' => '',\n\n# filepath: hyde.yml\n\nhyde:\nhead: \"\"\nscripts: \"\"\n\nYou can of course also add multiple lines of HTML:\n\n\/\/ filepath: config\/hyde.php\n'head' =>\n\nHTML,\n\n# filepath: hyde.yml\n\nhyde:\nhead: |\n\n\n\n### Navigation Menu & Sidebar\n\nA great time-saving feature of HydePHP is the automatic navigation menu and documentation sidebar generation.\nHyde is designed to automatically configure these menus for you based on the content you have in your project.\n\nStill, you will likely want to customize some parts of these menus, and thankfully, Hyde makes it easy to do so.\n\n#### Customizing the navigation menu\n\n- To customize the navigation menu, use the setting navigation.order in the hyde.php config.\n- When customizing the navigation menu, you should use the route key of the page.\n- You can use either a basic list array or specify explicit priorities.\n\nLearn more in the Navigation Menu documentation.\n\n#### Customizing the documentation sidebar\n\n- To customize the sidebar, use the setting sidebar.order in the docs.php config.\n- When customizing the sidebar, you can use the route key, or just the page identifier of the page.\n- Similar to the navigation menu, you can use a basic list array or specify explicit priorities.\n- You can also use front matter in individual documentation pages to customize their appearance and behavior in the sidebar.\n\nLearn more in the Documentation Pages documentation.\n\n## Additional Advanced Options\n\nThe following configuration options in the config\/hyde.php file are intended for advanced users and\nshould only be modified if you fully understand their impact. The code examples show the default values.\n\n### media_extensions\n\nThis option allows you to specify file extensions considered as media files, which will be copied to the output directory.\nTo add more extensions, either append them to the existing array or override the entire array.\n\n\/\/ filepath config\/hyde.php\nuse \\Hyde\\Support\\Filesystem\\MediaFile;\n\n'mediaextensions' => arraymerge([], MediaFile::EXTENSIONS),\n\n### safeoutputdirectories\n\nThis setting defines a list of directories deemed safe to empty during the site build process as a safeguard to prevent accidental data loss.\nIf the site output directory is not in this list, the build command will prompt for confirmation before emptying it. It is preconfigured\nwith common directories including the default one, but you are free to change this to include any custom directories you may need.\n\n\/\/ filepath config\/hyde.php\n'safeoutputdirectories' => ['_site', 'docs', 'build'],\n\n### generatebuildmanifest\n\nDetermines whether a JSON build manifest with metadata about the build should be generated. Set to true to enable.\n\n\/\/ filepath config\/hyde.php\n'generatebuildmanifest' => true,\n\n### buildmanifestpath\n\nSpecifies the path where the build manifest should be saved, relative to the project root.\n\n\/\/ filepath config\/hyde.php\n'buildmanifestpath' => 'app\/storage\/framework\/cache\/build-manifest.json',\n\n### themetogglebuttons\n\ninfo This feature was added in HydePHP v1.7.0\n\nThis setting allows you to enable or disable the theme toggle buttons in the navigation menu.\n\n\/\/ filepath config\/hyde.php\n'themetogglebuttons' => true,\n\nIf the Feature::Darkmode setting is disabled in the features array in the same file, this won't do anything, but if darkmode is enabled,\nsetting this setting to false will make so that the buttons will not show up in the app layout nor the documentation layout;\ninstead the appropriate color scheme will be automatically applied based on the browser system settings.\n\n## Blade Views\n\nHyde uses the Laravel Blade templating engine. Most parts of the included templates have been extracted into components to be customized easily.\nBefore editing the views you should familiarize yourself with the Laravel Blade Documentation.\n\nTo edit a default Hyde component you need to publish them first using the hyde publish:views command.\n\nphp hyde publish:views\n\nThe files will then be available in the resources\/views\/vendor\/hyde directory.\n\ninfo Tip: If you use Linux\/macOS or Windows with WSL you will be able to interactively select individual files to publish.\n\n## Frontend Styles\n\nHyde is designed to not only serve as a framework but a whole starter kit and comes with a Tailwind starter template\nfor you to get up and running quickly. If you want to customize these, you are free to do so.\nPlease see the Managing Assets page to learn more.\n\n## Markdown Configuration\n\nHyde uses League CommonMark for converting Markdown into HTML, and\nuses the GitHub Flavored Markdown extension. The Markdown related settings are found in the config\/markdown.php file.\nBelow follows an overview of the Markdown configuration options available in Hyde.\n\n### CommonMark Extensions\n\nYou can add any extra CommonMark Extensions,\nor change the default ones, using the extensions array in the config file. They will then automatically be loaded into\nthe CommonMark converter environment when being set up by Hyde.\n\n\/\/ filepath: config\/markdown.php\n'extensions' => [\n\\League\\CommonMark\\Extension\\GithubFlavoredMarkdownExtension::class,\n\\League\\CommonMark\\Extension\\Attributes\\AttributesExtension::class,\n],\n\nRemember that you may need to install any third party extensions through Composer before you can use them.\n\n### CommonMark Configuration\n\nIn the same file you can also change the configuration values to be passed to the CommonMark converter environment.\nHyde handles many of the options automatically, but you may want to override some of them and\/or add your own.\n\n\/\/ filepath: config\/markdown.php\n'config' => [\n'disallowedrawhtml' => [\n'disallowed_tags' => [],\n],\n],\n\nSee the CommonMark Configuration Docs for the available options.\nAny custom options will be merged with the defaults.\n\n### Allow Raw HTML\n\nSince Hyde uses GitHub Flavored Markdown,\nsome HTML tags are stripped out by default. If you want to allow all arbitrary HTML tags, and understand the risks involved,\nyou can use the allow_html setting to enable all HTML tags.\n\n\/\/ filepath: config\/markdown.php\n'allow_html' => true,\n\n### Allow Blade Code\n\nHydePHP also allows you to use Blade code in your Markdown files. This is disabled by default, since it allows\narbitrary PHP code specified in Markdown to be executed. It's easy to enable however, using the enable_blade setting.\n\n\/\/ filepath: config\/markdown.php\n'enable_blade' => true,\n\nSee the Blade in Markdown documentation for more information on how to use this feature.\n\n## YAML Configuration\n\nThe settings in the config\/hyde.php file can also be set by using a hyde.yml file in the root of your project directory.\n\nNote that YAML settings cannot call any PHP functions, so you can't access helpers like env() for environment variables,\nnor declare authors or navigation links, as you cannot use facades and objects. But that doesn't stop you from using both\nfiles if you want to. Just keep in mind that any duplicate settings in the YAML file override any made in the PHP file.\n\nHere is an example showing some of the config\/hyde.php file settings, and how they would be set in the YAML file.\n\n# filepath hyde.yml\n\nname: HydePHP\nurl: \"http:\/\/localhost\"\npretty_urls: false\ngenerate_sitemap: true\nrss:\nenabled: true\nfilename: feed.xml\ndescription: HydePHP RSS Feed\nlanguage: en\noutputdirectory: site\n\n### Namespaced YAML Configuration\n\nIf you are running v1.2 or higher, you can also use namespaced configuration options in the YAML file.\n\nThis allows you to set the settings of any configuration file normally found in the config directory.\n\nThis feature is automatically enabled when you have a hyde: entry first in your hyde.yml file\n\n# filepath hyde.yml\n\nhyde:\nname: HydePHP\n\ndocs:\nsidebar:\nheader: \"My Docs\"\n\nThis would set the name setting in the config\/hyde.php file, and the sidebar.header setting in the config\/docs.php file.\n\nEach top level key in the YAML file is treated as a namespace, and the settings are set in the corresponding configuration file.\nYou can of course use arrays like normal even in namespaced configuration.","destination":"customization.html"},{"slug":"helpers","title":"Helpers and Utilities","content":"Helpers and Utilities\n\nIntroduction\n\nHydePHP comes with a few helper classes and utilities to make your life easier. This page will cover some of the most important ones.\nNote that these helpers targets those who write custom code and Blade templates, and that you are expected to have a basic understanding of programming and PHP.\n\nFile-based Collections\n\nHyde provides DataCollection, a subset of Laravel Collections giving you a similar developer experience to working with Eloquent Collections. However, instead of accessing a database,\nit's all entirely file-based using static data files such as Markdown, Yaml, and JSON files which get parsed into objects that you can easily work with.\n\nuse Hyde\\Support\\DataCollection;\n\n\/\/ Gets all Markdown files in resources\/collections\/$name directory\nDataCollection::markdown(string $name);\n\n\/\/ Gets all YAML files in resources\/collections\/$name directory\nDataCollection::yaml(string $name);\n\n\/\/ Gets all JSON files in resources\/collections\/$name directory\nDataCollection::json(string $name, bool $asArray = false);\n\nSee the File-based Collections documentation for the full details.\n\nFile Includes\n\nThe Includes facade provides a simple way to access partials in the includes directory.\n\nIf the file does not exist, the method will return null.\nYou can also supply a default value as the second argument.\nBoth Markdown and Blade includes will be rendered to HTML.\n\nUsing Includes\n\nIncludes are stored in the resources\/includes directory. You can access them using the Includes facade.\n\nuse Hyde\\Support\\Includes;\n\n\/\/ Get the raw contents of any arbitrary file in the includes directory\nIncludes::get('example.md');\n\n\/\/ Get the raw contents of an HTML file in the includes directory\nIncludes::html('example.html');\n\n\/\/ Get the rendered Blade of a partial file in the includes directory\nIncludes::blade('example.blade.php');\n\n\/\/ Get the rendered Markdown of a partial file in the includes directory\nIncludes::markdown('example.md');\n\nWhen using the html, markdown, and blade methods, the file extension is optional.\n\nuse Hyde\\Support\\Includes;\n\nIncludes::html('example') === Includes::html('example.html');\nIncludes::blade('example')  === Includes::blade('example.blade.php');\nIncludes::markdown('example') === Includes::markdown('example.md');\n\nAll methods will return null if the file does not exist.\nHowever, you can supply a default value as the second argument to be used instead.\nRemember that Markdown and Blade defaults will also be rendered to HTML.\n\nIncludes are particularly useful in Blade views, as you can echo them directly. You do not need to import the namespace, as it is already aliased.\n\n{{ Includes::markdown('footer.md') }}\n\nuse Hyde\\Support\\Includes;\n\n\/\/ If the file does not exist, the default value will be returned\nIncludes::markdown('example.md', 'Default content');\n\nStock Includes\n\nHydePHP also supports some drop-in includes that you can use as an alternative to some config options. These currently are as follows:\n\nFooter\n\nIf a footer.md file exists in the includes directory, Hyde will use that as the footer text, instead of the one set in the hyde.footer config option.\n\nHead\n\nIf a head.html file exists in the includes directory, Hyde will include that within the ` tag of the generated HTML, in addition to the one set in the hyde.head` config option.\n\nScripts\n\nIf a scripts.html file exists in the includes directory, Hyde will include that at the end of the ` tag of the generated HTML, in addition to the one set in the hyde.scripts` config option.\n\nReading-Time Helper\n\nThe ReadingTime helper provides a simple way to calculate the reading time of a given string, for example a blog post.\n\nCreate a new ReadingTime instance\n\nThere are a few ways to create a new ReadingTime instance. Either create a new instance directly, or use the static fromString or fromFile  helpers.\n\nIn all cases, you will end up with a ReadingTime object that you can use to get the reading time.\n\nuse Hyde\\Support\\ReadingTime;\n\n\/\/ Via constructor\n$time = new ReadingTime('Input text string');\n\n\/\/ Via static method\n$time = ReadingTime::fromString('Input text string');\n\n\/\/ Via static method (from file)\n$time = ReadingTime::fromFile('path\/to\/file.txt');\n\nGet the reading time string\n\nTo make things really easy, the ReadingTime instance can be automatically cast to a human-readable string with the default formatting.\n\n(string) ReadingTime::fromString('Input text string'); \/\/ 1min, 0sec\n\n{{ ReadingTime::fromString('Input text string') }} \/\/ 1min, 0sec\n\nYou can also call the getFormatted method directly.\n\nReadingTime::fromString('Input text string')->getFormatted(); \/\/ 1min, 0sec\n\nGet the reading time data\n\nWe also provide a few methods to get the reading time data directly.\n\n\/\/ Get the reading time in seconds\n$time->getSeconds();\n\n\/\/ Get the reading time in minutes (rounded down)\n$time->getMinutes();\n\n\/\/ Get the remaining seconds after the rounded down minutes\n\/\/ (Perfect for showing after the getMinutes() value)\n$time->getSecondsOver();\n\n\/\/ Get the word count of the input string\n$time->getWordCount();\n\nCustom formatting\n\nAdditionally, there are several ways to customize the output format.\n\nSpecify sprintf format\n\nThe getFormatted method accepts a sprintf format string as the first argument.\n\n\/\/ The default format\n$time->getFormatted('%dmin, %dsec');\n\n\/\/ Custom format\n$time->getFormatted('%d minutes and %d seconds');\n\nThe first %d will be replaced with the minutes, and the second %d will be replaced with the seconds.\n\nFormat using a custom callback\n\nYou can also use a custom callback to format the reading time string. This is perfect if you want to create custom formatting logic.\n\nThe closure will receive the minutes and seconds as integers and should return a string.\n\n$time->formatUsingClosure(function (int $minutes, int $seconds): string {\nreturn \"$minutes minutes, $seconds seconds\";\n}); \/\/ 1 minutes, 30 seconds\n\nHelper Functions\n\nHydePHP comes with a few helper functions to make your life easier.\n\nThe most common ones are documented here, however you can also see the full list in the source code helpers.php file.\n\nhyde\n\nThe hyde function is a global helper function that returns the HydeKernel instance.\nFrom this, you can access the same methods as you would from the Hyde facade.\n\nhyde(); \/\/ Returns the HydeKernel instance\n\nhyde()->routes() === Hyde::routes(); \/\/ true\n\nIt's up to you if you want to use the facade or the global function, or a mix of both.\nA benefit of using the global function is that it may have better IDE support.\n\nasset\n\nThis is an alias of the Hyde::asset() facade method and allows you to get a relative link or URL to an asset in the media directory.\n\nasset('image.png'); \/\/ Returns a relative web link to the given image\n\nGets a relative web link to the given image stored in the _site\/media folder.\nIf the image is remote (starts with http) it will be returned as is.\n\nIf true is passed as the second argument, and a base URL is set,\nthe image will be returned with a qualified absolute URL.\n\nExample usage:\n\nroute\n\ninfo Routing primer: All pages in your Hyde project are automatically tied to an internal route. You can run php hyde route:list to see a list of all routes and their route keys.\n\nThis is an alias of the Hyde::route() facade method and allows you to get a route instance by its route key.\n\nroute('index'); \/\/ Returns the route instance with the given key\n\nIf a route does not exist, null will be returned. Route instances can be cast to strings to resolve a link to the page.\n\nExample usage:\n\nHome\ngetLink() }}\">Home\n\nurl\n\nThis is an alias of the Hyde::url() facade method and formats a relative link to an absolute URL using the configured base URL.\n\nurl('page.html'); \/\/ Returns an absolute URL to the given page\n\n[\/\/]: # (If the given link is already an absolute URL, it will be returned as is.)\n\nIf a base URL is not set, an exception will be thrown.\n\nExample usage:\n\nLink\n\nPagination Utility\n\nThe Pagination class provides utilities to help you create custom pagination components.\n\nHyde comes with a simple pagination view that you can use, but you can also use the utility to create your own custom pagination components.\nYou can of course also publish and modify the default pagination view to fit your needs.\n\nThe paginator is designed to paginate Hyde pages and their routes, but can also be used with other data sources.\n\nBase usage\n\nTo use the pagination component which is generic by design, you need to create the Pagination instance yourself, with the data you want to paginate.\n\nTo get started, simply create a paginator instance with a collection or array of items (like pages), and render the component.\nYou also need to pass the current page being rendered (if you're on pagination page 3, pass that to the constructor).\n\nuse Hyde\\Support\\Paginator;\nuse Illuminate\\Contracts\\Support\\Arrayable;\n\n$paginator = new Paginator(\nArrayable|array $items = [],\nint $pageSize = 25,\nint $currentPageNumber = null,\nstring $paginationRouteBasename = null\n);\n\n@include('hyde::components.pagination-navigation')\n\nConstructor options breakdown\n\nThe first two are self-explanatory:\n\n- items - The items to paginate. This can be a collection or an array.\n- pageSize - How many items to show on each page.\n\nThe next may need some explanation:\n\ncurrentPageNumber\n\nThis current page index. You will typically get this from the URL.\n\npaginationRouteBasename\n\nThis adds an optional prefix for the navigation links. For example, if you're paginating blog posts,\nyou might want the links to be \/posts\/page-1.html instead of \/page-1.html. You would then set this to posts.\n\nPractical example\n\nHydePHP comes with a started homepage called 'posts'. This includes a component with the following code:\n\n@include('hyde::components.blog-post-feed')\n\nCreating our posts page\n\nNow, let's paginate this feed! For this example, we will assume that you ran php hyde publish:homepage posts\nand renamed the resulting index.blade.php file to posts.blade.php. We will also assume that you have a few blog posts set up.\n\nThe blog post feed component is a simple component that looks like this:\n\n\/\/ filepath _pages\/posts.blade.php\n@foreach(MarkdownPost::getLatestPosts() as $post)\n@include('hyde::components.article-excerpt')\n@endforeach\n\nSetting up the new Blade components\n\nSo we are simply going to inline component, but with the paginator we also declare. So, replace the post feed include with the following:\n\n\/\/ filepath _pages\/posts.blade.php\n@php\n$paginator = new \\Hyde\\Support\\Paginator(\n\/\/ The items to paginate\nitems: MarkdownPost::getLatestPosts(),\n\/\/ How many items to show on each page\npageSize: 5,\n\/\/ The current page index\ncurrentPageNumber: 1,\n\/\/ Links will be 'posts\/page-1.html' instead of 'page-1.html'\npaginationRouteBasename: 'posts'\n);\n@endphp\n\n@foreach($paginator->getItemsForPage() as $post)\n@include('hyde::components.article-excerpt')\n@endforeach\n\n@include('hyde::components.pagination-navigation')\n\nThis will set up the paginator loop through only the items for the current page, and render the article excerpts. The last line will render the pagination links.\n\nCreating the pagination pages\n\nHowever, we still need to create the pagination pages, because the paginator will not automatically create them for you.\n\nIn order to do this dynamically, we add the following to the boot of our AppServiceProvider (or any other provider or extension):\n\n\/\/ filepath app\/Providers\/AppServiceProvider.php\nbooted(function (HydeKernel $hyde) {\n\/\/ First we create a paginator instance using the same settings as in our view\n$paginator = new Paginator(MarkdownPost::getLatestPosts(), 5, 1, 'posts');\n\n\/\/ Then we loop through the total number of pages and create a new page for each one\nforeach (range(1, $paginator->totalPages()) as $page) {\n\/\/ Now we set the paginator to the current page number\n$paginator->setCurrentPage($page);\n\n\/\/ Now we create the paginated listing page. We set the identifier to match the route basename we set earlier.\n$listingPage = new InMemoryPage(identifier: \"posts\/page-$page\", matter: [\n\/\/ And the paginator instance. We clone it so that we don't modify the original instance.\n'paginator' => clone $paginator,\n\n\/\/ Optionally, specify a custom page title.\n'title' => \"Blog Posts - Page {$page}\",\n\/\/ Here we add the paginated collection\n'posts' => $paginator->getItemsForPage(),\n],\n\/\/ You can also use a different view if you want to, for example a simpler page just for paginated posts.\n\/\/ This uses the same view system as Laravel, so you can use any vendor view, or a view from the resources\/views directory.\n\/\/ Hyde also loads views from _pages\/, so setting posts here will load our posts page we created earlier.\nview: 'posts'\n);\n\n\/\/ This is optional, as the page does not necessarily need to be added to the page collection\n$hyde->pages()->addPage($listingPage);\n\n\/\/ This however is required, so that Hyde knows about the route as we run this after the kernel has booted\n$hyde->routes()->addRoute($listingPage->getRoute());\n}\n});\n}\n}\n\nUpdating the listing page view\n\nNow, let's update our posts page to accept the paginator data. If you want to use a different view for the paginated posts,\njust apply these changes to that new view, but for this example I'm going to update the posts view.\n\n\/\/ filepath _pages\/posts.blade.php\nLatest Posts{{-- [tl! remove] --}}\n{{ $page->matter('title') ?? $title }} {{-- [tl! add] --}}\n\n\/\/ filepath _pages\/posts.blade.php\n@php\n$paginator = new \\Hyde\\Support\\Paginator( \/\/ [tl! remove]\n$paginator = $page->matter('paginator') ?? new \\Hyde\\Support\\Paginator( \/\/ [tl! add]\nitems: MarkdownPost::getLatestPosts(),\npageSize: 5,\ncurrentPageNumber: 1,\npaginationRouteBasename: 'posts'\n);\n@endphp\n\nConclusion\n\nAnd that's it! You now have a paginated blog post feed. You can now visit \/posts\/page-1.html and see the first page of your blog posts.\nYou can then click the pagination links to navigate to the next pages.","destination":"helpers.html"},{"slug":"navigation","title":"Navigation Menus","content":"Navigation Menus\n\nIntroduction\n\nHydePHP offers automatic navigation menu generation features, designed to take the pain out of creating navigation menus.\nWhile Hyde does its best to configure these menus automatically based on understanding your project files, you may want to customize them further.\n\nThere are two types of navigation menus in Hyde:\n\n1. Primary Navigation Menu: The main navigation menu appearing on most pages of your site. Unique features include dropdowns for subdirectories, depending on configuration.\n2. Documentation Sidebar: The sidebar on documentation pages with links to other documentation pages. Unique features include automatic grouping based on subdirectories.\n\nThis documentation will guide you through the customization process of the primary navigation menu. To learn about the documentation sidebar, visit the Documentation Pages documentation.\n\nInternal Structure Overview\n\nInternally, both navigation menu types extend the same base class and thus share core functionality. This means the configuration process is similar for both types, making the documentation applicable to both.\n\nFor a deeper understanding of the internal workings, refer to the Digging Deeper section.\n\nUnderstanding Priorities\n\nAll navigation menu items have an internal priority value determining their order. Lower values place items higher in the menu. The default priority for pages is 999, placing them last unless you specify a value. Some pages, like the index page, are configured by default with the lowest priority of 0.\n\nCustomization Options\n\nHere's an overview of what you can customize in your navigation menus:\n\n- Item labels: The text displayed in menu links\n- Item priorities: Control the order in which links appear\n- Item visibility: Choose to hide or show pages in the menu\n- Item grouping: Group pages together in dropdowns or sidebar categories\n\nCustomization Methods\n\nHyde provides multiple ways to customize navigation menus to suit your needs:\n\n1. Front matter data in Markdown and Blade page files, applicable to all menu types\n2. Configuration in the hyde config file for main navigation items\n\nKeep in mind that front matter data overrides dynamically inferred or config-defined priorities. While useful for quick one-off changes on small sites, it can make reordering items later on more challenging as you can't see the entire structure at once.\n\nAdditionally, general options for the entire navigation menus are also available in the hyde config file.\n\nFront Matter Configuration\n\nFront matter options allow per-page customization of navigation menus. Here's a quick reference of available options:\n\nnavigation:\nlabel: string  # The displayed text in the navigation item link\npriority: int  # The page's priority for ordering (lower means higher up\/first)\nhidden: bool   # Whether the page should be hidden from the navigation menu\ngroup: string  # Set main menu dropdown or sidebar group key\n\nYou only need to specify the keys you want to customize.\n\nlabel\n\nCustomizes the text appearing in the navigation menu link for the page. If not set anywhere else, Hyde will search for a title in the page content or generate one from the filename.\n\nnavigation:\nlabel: \"My Custom Label\"\n\npriority\n\nControls the order in which the page appears in the navigation menu.\n\nnavigation:\npriority: 10\n\nhidden\n\nDetermines if the page appears in the navigation menu.\n\nnavigation:\nhidden: true\n\nTip: You can also use visible: false to achieve the same effect.\n\ngroup\n\nFor the primary navigation menu, this groups pages together in dropdowns. For the sidebar, it groups pages under a common heading.\n\nnavigation:\ngroup: \"My Group\"\n\nNote: Sidebar group keys are normalized, so My Group and my-group are equivalent.\n\nConfig File Configuration\n\nLet's explore how to customize the main navigation menu using configuration files:\n\n- For the main navigation menu, use the navigation setting in the hyde.php config file.\n\nWhen customizing the main navigation menu, use the route key of the page.\n\nChanging Priorities\n\nThe navigation.order setting allows you to customize the order of pages in the main navigation menu.\n\nBasic Priority Syntax\n\nA nice and simple way to define the order of pages is to add their route keys as a simple list array. We'll then match that array order.\n\nIt may be useful to know that we internally will assign a priority calculated according to its position in the list, plus an offset of 500. The offset is added to make it easier to place pages earlier in the list using front matter or with explicit priority settings.\n\n\/\/ filepath: config\/hyde.php\n'navigation' => [\n'order' => [\n'home', \/\/ Priority: 500\n'about', \/\/ Priority: 501\n'contact', \/\/ Priority: 502\n]\n]\n\nExplicit Priority Syntax\n\nYou can also specify explicit priorities by adding a value to the array keys. We'll then use these exact values as the priorities.\n\n\/\/ filepath: config\/hyde.php\n'navigation' => [\n'order' => [\n'home' => 10,\n'about' => 15,\n'contact' => 20,\n]\n]\n\nChanging Menu Item Labels\n\nHyde makes a few attempts to find suitable labels for the navigation menu items to automatically create helpful titles.\n\nIf you're not happy with these, it's easy to override navigation link labels by mapping the route key to the desired title in the Hyde config:\n\n\/\/ filepath: config\/hyde.php\n'navigation' => [\n'labels' => [\n'index' => 'Start',\n'docs\/index' => 'Documentation',\n]\n]\n\nExcluding Items (Blacklist)\n\nWhen you have many pages, it may be useful to prevent links from being added to the main navigation menu.\n\nTo exclude items from being added, simply add the page's route key to the navigation blacklist in the Hyde config:\n\n\/\/ filepath: config\/hyde.php\n'navigation' => [\n'exclude' => [\n'404'\n]\n]\n\nAdding Custom Navigation Menu Links\n\nYou can easily add custom navigation menu links in the Hyde config:\n\n\/\/ filepath: config\/hyde.php\nuse Hyde\\Facades\\Navigation;\n\n'navigation' => [\n'custom' => [\nNavigation::item(\ndestination: 'https:\/\/github.com\/hydephp\/hyde', \/\/ Required\nlabel: 'GitHub', \/\/ Optional, defaults to the destination value\npriority: 200 \/\/ Optional, defaults to 500\n),\n]\n]\n\nTip: While named arguments are used in the example for clarity, they are not required.\n\nConfigure Subdirectory Display\n\nYou can configure how subdirectories should be displayed in the menu:\n\n\/\/ filepath: config\/hyde.php\n'navigation' => [\n'subdirectory_display' => 'dropdown'\n]\n\nSupported Options:\n- dropdown: Pages in subdirectories are displayed in a dropdown menu\n- hidden: Pages in subdirectories are not displayed at all in the menus\n- flat: Pages in subdirectories are displayed as individual items\n\nAutomatic Menu Groups\n\nA handy feature HydePHP has is that it can automatically place pages in dropdowns based on subdirectory structures.\n\nAutomatic Navigation Menu Dropdowns\n\nEnable this feature in the hyde.php config file by setting the subdirectory_display key to dropdown.\n\n\/\/ filepath: config\/hyde.php\n'navigation' => [\n'subdirectory_display' => 'dropdown',\n],\n\nNow if you create a page called _pages\/about\/contact.md, it will automatically be placed in a dropdown called \"About\".\n\nDropdown Menu Notes\n\n- Dropdowns take priority over standard items. If you have a dropdown with the key about and a page with the key about, the dropdown will be created, and the page won't be in the menu.\n- Example: With this file structure: pages\/foo.md, pages\/foo\/bar.md, _pages\/foo\/baz.md, the link to foo will be lost, so please keep this in mind when using this feature.\n\nDigging Deeper Into the Internals\n\nWhile not essential, understanding the internal workings of the navigation system can be as beneficial as it's interesting. Here's a quick high-level overview of the Navigation API.\n\nNavigation Menu Classes\n\nThe main navigation menu uses the MainNavigationMenu class, while the documentation sidebar uses the DocumentationSidebar class. Both extend the base NavigationMenu class:\n\nuse Hyde\\Framework\\Features\\Navigation\\MainNavigationMenu;\nuse Hyde\\Framework\\Features\\Navigation\\DocumentationSidebar;\nuse Hyde\\Framework\\Features\\Navigation\\NavigationMenu;\n\nThe base NavigationMenu class contains the main logic for menu generation, while child implementations contain extra logic for specific use cases.\n\nAll navigation menus store items in their $items collection, containing instances of the NavigationItem class. Dropdowns are represented by NavigationGroup instances, which extend the NavigationMenu class and contain additional NavigationItem instances:\n\nuse Hyde\\Framework\\Features\\Navigation\\NavigationItem;\nuse Hyde\\Framework\\Features\\Navigation\\NavigationGroup;\n\nThe Navigation API\n\nFor advanced users and package developers, Hyde offers a Navigation API for programmatic interaction with site navigation. This API consists of a set of PHP classes allowing fluent interaction with navigation menus.\n\nFor more detailed information about the API, refer to the Navigation API documentation.","destination":"navigation.html"},{"slug":"troubleshooting","title":"Troubleshooting","content":"# Troubleshooting\n\nSince Hyde has a lot of \"magic\" features which depend on some base assumptions, there might be some \"gotchas\" you might run into. Here are some common issues you might encounter. Did you find a new one? Send a PR to update the docs!\n\ninfo Tip: You can run php hyde validate to run a series of tests to help you catch common issues.\n\n## General Tips\n\n(In no particular order of importance)\n\n1. In general, Hyde is actually pretty forgiving. While this article makes it sound like there are a lot of rules to follow,\nhonestly don't worry about it. Hyde will attempt to fix mistakes and make your life easier.\n2. You don't need to set an H1 heading in blog posts. The H1 is set by Hyde based on the front matter title.\n3. You never need front matter, though it is often useful.\nFor example, Hyde makes attempts to guess the title for a page depending on the content. (Headings, filenames, etc).\n\n## Conventions to Follow\n\n### File naming\n\nFor Hyde to be able to discover your files, you should follow the following conventions.\n\nMarkdown files should have the extension .md. Blade files should have the extension .blade.php.\n\nUnexpected behaviour might occur if you use conflicting file names.\nAll the following filenames are resolved into the same destination file:\nfoo-bar.md, Foo-Bar.md, foo-bar.blade.php, causing only one of them to be saved.\n\nRemember, files retain their base filenames when compiled to HTML.\n\n#### Summary\n\n- \u2714 Do use lowercase filenames and extensions\n- \u2714 Do use filenames written in kebab-case-format\n- \u2714 Do use the proper file extensions\n- \u274c Don't use conflicting source file names\n\n## Extra Information\n\n### Definitions\n\nWe will use the following definitions to describe the behaviour of Hyde.\n\n#### General\n\nHyde**: The application that you are using.\nHydeCLI**: The command-line interface for Hyde.\nFramework**: The package containing the core codebase.\n\n#### Path components\n\nIdentifier**: The filepath without the extension, relative to the page type source directory.\nRoute Key**: The page type's output directory plus the identifier. Example: posts\/hello-world\nBasename**: The filename without the extension. Example: hello-world\nFilename**: The full name of a file with the extension. Example: hello-world.md\nFilepath**: The full file path including extension. Example: _posts\/hello-world.md\n\nYou can read more about some of these in the Core Concepts article.\n\n## Common Issues, Causes, and Solutions\n\nIssue                                              Possible Cause \/ Issue Context                                                                                                                            Possible Solution\n\n404 error when visiting site                       Are you missing an index file in the pages directory?                                                                                                  Add an index.md or index.blade.php to the pages directory\nNavigation menu not linking to the docs            You probably don't have an index.md file in the docs directory.                                                                                      Create a docs\/index.md file\nPage not discovered when compiling                 The file name may be invalid                                                                                                                              Ensure you follow the correct file naming convention.\nPage compiles slowly                               The Torchlight extension may cause the compile times to increase as API calls need to be made.                                                            Try disabling Torchlight\nTorchlight not working                             Missing Composer package, missing API token, extension disabled in the config.                                                                            Reinstall Torchlight, add your token in the .env file, check config\nMissing styles and\/or assets                       You may have accidentally deleted the files, or you have added new Tailwind classes.                                                                      Run npm run build\nImage not found                                    You may be using a bad relative path.                                                                                                                     Ensure your relative paths are correct.  See managing-assets.\nWrong layout used                                  Hyde determines the layout template to use depending on the directory of the source file                                                                  Ensure your source file is in the right directory.\nInvalid\/no permalinks or post URIs                 You may be missing or have an invalid site URL                                                                                                            Set the site URL in the .env file\nNo styles in custom Blade pages                    When using custom blade pages need to add the styles yourself. You can do this by extending the default layout                                            Use the app layout, or by include the Blade components directly.\nOverriding Hyde views is not working               Ensure the Blade views are in the correct directory.                                                                                                      Rerun php hyde publish:views.\nStyles not updating when deploying site            It could be a caching issue. To be honest, when dealing with styles, it's always a caching issue.                                                         Clear your cache, and optionally complain to your site host\nDocumentation sidebar items are in the wrong order Double check the config, make sure the route keys are written correctly. Check that you are not overriding with front matter.                             Check config for typos and front matter\nIssues with date in blog post front matter         The date is parsed by the PHP strtotime() function. The date may be in an invalid format, or the front matter is invalid                                Ensure the date is in a format that strtotime() can parse. Wrap the front matter value in quotes.\nRSS feed not being generated                       The RSS feed requires that you have set a site URL in the Hyde config or the .env file. Also check that you have blog posts, and that they are enabled. Check your configuration files.\nSitemap not being generated                        The sitemap requires that you have set a site URL in the Hyde config or the .env file.                                                                  Check your configuration files.\nUnable to do literally anything                    If everything is broken, you may be missing a Composer package or your configuration files could be messed up.                                            Run composer install and\/or composer update. If you can run HydeCLI commands, update your configs with php hyde publish:configs, or copy them manually from GitHub or the vendor directory.\nNamespaced Yaml config (hyde.yml) not working    When using namespaced Yaml configuration, you must begin the file with hyde:, even if you just want to use another file for example docs:.            Make sure the file starts with hyde: (You don't need to specify any options, as long as it's present). See #1475\n\n### Extra troubleshooting information\n\n#### Fixing a broken config\n\nIf your configuration is broken, you might not be able to run any commands through the HydeCLI.\nTo remedy this you can copy the config files from the vendor directory into the project directory.\nYou can do this manually, or with the following rescue command:\n\ncopy vendor\/hyde\/framework\/config\/hyde.php config\/hyde.php","destination":"troubleshooting.html"},{"slug":"updating-hyde","title":"Updating Hyde Projects","content":"Updating Hyde Projects\n\nThis guide will help you update your HydePHP project to the latest version.\n\nBefore You Start\n\nWhen updating an existing installation, first ensure that you have a backup of your project in case anything goes wrong.\nThe recommended way to do this is to use Git as that allows you to smoothly roll back any changes.\n\nVersion Compatibility\n\nHydePHP follows semantic versioning, so you can expect that minor and patch releases will be backwards compatible.\nOnly major releases may introduce breaking changes, all of which are thoroughly documented in the accompanying release notes.\n\nNew features and bug fixes are added in minor and patch releases, so it is recommended to keep your project up to date.\n\nSide effects and ensuring a smooth update\n\nPlease note that due to the intricate nature of software, there is a possibility that an update contains side effects,\nhence why version controlling your site is helpful when updating versions as you can roll back changes. It can also\nbe helpful to version control the compiled HTML, so you can view a diff of the changes. Be sure to test that your site\ncan be built and that it looks as expected after updating before deploying the changes to your live site.\n\nWe of course have extensive tests in place run on each single code commit to ensure all code is functional, however,\nit is still possible that some edge cases slip through. This means that a bug fix may impact an edge case that you depend on.\n\nObligatory related XKCD: https:\/\/xkcd.com\/1172\n\nBefore you start\n\nBefore you perform an update, please make sure you have a backup of your project.\nUsing Git is highly recommended as it allows you to easily roll back changes if something goes wrong.\n\nUpdate to a Major Version\n\nWhen updating to a major version, you should read the release notes and the upgrade guide for that version.\nIf you are updating multiple major versions at once, it's recommended to update one major version at a time,\nfollowing the upgrade guide for each version. After following the upgrade guide, you can follow the post-update instructions below.\n\nUpdating to a minor or patch version\n\nUpdating a minor or patch version is easy using Composer. Just run the following command:\n\ncomposer update \"hyde\/*\" --with-dependencies\n\nNote that if you have hardcoded a version constraint in your composer.json file, you may need to update it manually.\nYou can always refer to the composer.json file in the HydePHP repository if you need a reference.\n\nAlternate Update Methods\n\nUpdating using Git (advanced)\n\nIf you are using Git, you can set the hydephp\/hyde repository as a Git remote and merge in the changes that way:\n\ngit remote add hyde https:\/\/github.com\/hydephp\/hyde.git\ngit fetch hyde\ngit merge hyde\/master # OR: Replace 'master' with the version tag you want to update to\n\nTake care of any merge conflicts that arise, then install the updated dependencies\n\ncomposer update\n\nHard update using release archive\n\nAn alternate way to update your project is to essentially do a hard reset. This is only recommended if you haven't done many modifications to the HydePHP files.\n\nEssentially: Download the latest release from GitHub, extract it to a new project directory, then copy over your source files and install the dependencies.\n\nPost-update instructions\n\nAfter updating Hyde you should update your config and resource files. This is where things can get a tiny bit dangerous\nas existing files may be overwritten. If you are using Git, you can easily take care of any merge conflicts that arise.\n\nFirst, ensure that your dependencies are up to date. If you have already done this, you can skip this step.\n\ncomposer update\n\nThen, update your config files. This is the hardest part, as you may need to manually copy in your own changes.\n\nphp hyde publish:configs\n\nIf you have published any of the included Blade components you will need to re-publish them.\n\nphp hyde publish:views layouts\nphp hyde publish:views components\n\nYou may also want to download any resources that have been updated. You download these from the Zip file of the latest release on GitHub.\n\nThe latest release can always be found at https:\/\/github.com\/hydephp\/hyde\/releases\/latest, where you can download the source code as a zip file under the \"Assets\" section.\n\nHere are the paths you may be interested in copying over: (Using Git will help a ton here as it can show you diffs of changed files, and allow you to easily merge own changes)\n\n\u251c\u2500\u2500 app\n\u2502   \u251c\u2500\u2500 Providers\n\u2502   \u2502   \u2514\u2500\u2500 AppServiceProvider.php\n\u2502   \u251c\u2500\u2500 bootstrap.php\n\u2502   \u251c\u2500\u2500 config.php\n\u2502   \u2514\u2500\u2500 storage\/\n\u251c\u2500\u2500 composer.json\n\u251c\u2500\u2500 package.json\n\u251c\u2500\u2500 resources\/\n\u251c\u2500\u2500 tailwind.config.js\n\u2514\u2500\u2500 vite.config.js\n\nNext, recompile your assets, if you are not using the built-in assets.\n\nnpm install\nnpm run dev\/prod\n\nFinally, you can rebuild your site.\n\nphp hyde build\n\nNow, you should browse your site files to ensure things are still looking as expected.","destination":"updating-hyde.html"},{"slug":"extensions","title":"Extensions & Integrations","content":"Extensions & Integrations\n\nHydePHP - Extensible by design\n\nHydePHP is designed to be extensible, and comes with a number of built-in extensions and integrations,\nas well as support for third-party extensions and integrations.\n\nFirst-Party Extensions & Integrations\n\nRealtime Compiler\n\nThe Hyde Realtime Compiler is included with Hyde installations and is what powers the php hyde serve command.\n- Learn more about the Realtime Compiler in the documentation.\n\nUI Kit\n\nThe HydePHP UI Kit is a set of minimalistic Blade & Tailwind components to kickstart development of custom Blade views for your HydePHP site.\n- Learn more at https:\/\/github.com\/hydephp\/ui-kit and see the documentation at https:\/\/hydephp.github.io\/ui-kit\n\nGitHub Action\n\nThe GitHub Action for HydePHP is hands-down the easiest way to build and deploy your Hyde site to GitHub Pages.\n- Learn more at https:\/\/github.com\/hydephp\/action and see the documentation at https:\/\/hydephp.github.io\/action\n\nIntegration with Third-Party Services\n\nAll third-party integrations are listed on the Third-Party Integrations page. Below is a summary.\n\nTorchlight\n\nTorchlight is an amazing API for syntax highlighting, and is supported natively by HydePHP.\n- Learn more about Torchlight in the documentation.\n\nContribute\n\nHave an idea for an extension or integration? Let me know! I'd love to hear from you. Get in touch on\nGitHub or send me a DM on Twitter.\nYou may also want to look at the Extension API documentation to learn how to create extensions.","destination":"extensions.html"},{"slug":"realtime-compiler","title":"Realtime Compiler","content":"Realtime Compiler\n\nThe Hyde Realtime Compiler is included with Hyde installations and is what powers the php hyde serve command,\nallowing you to preview your static site on a local development server without having to rebuild the site.\n\nUsage\n\nTo start the server, run the following command from a terminal in your project directory:\n\nphp hyde serve\n\nThis will start a local development server at http:\/\/localhost:8080\n\nwarning Please note that the server is designed for local development, and should not be used on a public network.\n\nOptions\n\n- --host=: [default: \"localhost\"]\n- --port=: [default: 8080]\n- --save-preview=: Should the served page be saved to disk? (Overrides config setting)\n- --dashboard=: Enable the realtime compiler dashboard. (Overrides config setting)\n- --pretty-urls=: Enable pretty URLs. (Overrides config setting)\n- --play-cdn=: Enable the Tailwind Play CDN. (Overrides config setting)\n- --open=false: Open the site preview in the browser.\n- --vite: Enable Vite for Hot Module Replacement (HMR).\n\nVite Integration\n\nBy adding the --vite option, the serve command will initiate Vite's development server alongside the Hyde Realtime Compiler. This setup enables Hot Module Replacement (HMR), allowing for instant updates to your site as you make changes to your assets.\n\nConfiguration\n\nThe server can be configured in the config\/hyde.php file to change the port, host, and to customize its features.\n\n\/\/ filepath config\/hyde.php\n\n'server' => [\n\/\/ The default port the preview is served on\n'port' => env('SERVER_PORT', 8080),\n\n\/\/ The default host the preview is served on\n'host' => env('SERVER_HOST', 'localhost'),\n\n\/\/ Should preview pages be saved to the output directory?\n'savepreview' => env('SERVERSAVE_PREVIEW', false),\n\n\/\/ Should the live edit feature be enabled?\n'liveedit' => env('SERVERLIVE_EDIT', true),\n],\n\nLive dashboard\n\nUsage\n\nThe realtime compiler comes with a live dashboard that you can access at http:\/\/localhost:8080\/dashboard.\n\nFrom here, you can visually interact with your site content, including creating new pages and posts.\n\nThe live dashboard is not saved to your static site, and is only available through the development server.\n\nConfiguration\n\nThe dashboard can be customized, and disabled, in the config\/hyde.php file.\n\n\/\/ filepath config\/hyde.php\n\n'server' => [\n\/\/ Configure the realtime compiler dashboard\n'dashboard' => [\n\/\/ Should the realtime compiler dashboard be enabled?\n'enabled' => env('SERVER_DASHBOARD', true),\n\n\/\/ Can the dashboard make edits to the project file system?\n'interactive' => true,\n\n\/\/ Should the dashboard show tips?\n'tips' => true,\n],\n],\n\nThe dashboard was added in Realtime Compiler v3.0.0 (March 2023), with interactive features added in v3.1.0 (October 2023)\n\nLive edit\n\nUsage\n\nThe live edit feature allows you to quickly edit Markdown-based pages (posts, docs, and pages) directly in the browser.\n\nTo enter the live editor, simply double-click on the article you want to edit, and it will be replaced with a text editor.\nWhen you're done, click the save button to save the changes to the page's source file.\n\nShortcuts\n\nThe live editor supports the following keyboard shortcuts:\n- Ctrl + E - Enter\/Exit editor\n- Ctrl + S - Save changes\n- esc - Exit editor if active\n\nConfiguration\n\nThe live editor can be disabled in the config\/hyde.php file.\nThe live editor plugin code will not be saved to your static site.\n\n\/\/ filepath config\/hyde.php\n\n'server' => [\n'liveedit' => env('SERVERLIVE_EDIT', true),\n],\n\nHerd Integration\n\nUsage\n\nSince HydePHP v2 (Realtime Compiler v4), HydePHP has a new integration with Herd to provide a seamless development experience. The realtime compiler includes a custom Valet driver that allows Herd to serve your HydePHP site.\n\nTo install the Valet driver for Herd, run the following command:\n\nphp hyde herd:install\n\nThis will copy the HydeValetDriver to your Herd configuration directory, allowing Herd to automatically serve your HydePHP site.\n\nTo use this with Vite, run npm run dev and the Herd server will pick it up.\n\ninfo The Herd integration is in public beta, please report any issues to https:\/\/github.com\/hydephp\/realtime-compiler.\n\nFeatures\n\nWhen using the Herd integration, you get the following benefits:\n\n- Automatic site detection for HydePHP projects\n- The realtime compiler is used to serve your site\n- Proper handling of static files and dynamic routes\n- Site information displayed in the Herd UI\n\nThe Herd integration requires Herd to be installed on your system.\n\nwarning The Herd integration is experimental and may be unstable. Report issues at GitHub!\n\nSource code\n\nGitHub**: hydephp\/realtime-compiler\nPackagist**: hydephp\/realtime-compiler","destination":"realtime-compiler.html"},{"slug":"third-party-integrations","title":"Integrations with Third-Party Services","content":"Integrations with Third-Party Services\n\nTorchlight\n\nTorchlight is an amazing API for syntax highlighting, and is used by this site. I cannot recommend it highly enough,\nespecially for documentation sites and code-heavy blogs! As such, HydePHP has built-in support for Torchlight,\nwhich is automatically enabled once you add an API token to your .env file. Nothing else needs to be done!\n\nGetting started\n\nTo get started you need an API token which you can get at Torchlight.dev.\nIt is entirely free for personal and open source projects, as seen on their pricing page.\n\nWhen you have an API token, set it in the .env file in the root directory of your project.\nOnce a token is set, Hyde will automatically enable the CommonMark extension.\n\nTORCHLIGHTTOKEN=torch\n\nAttribution and configuration\n\nNote that for the free plan you need to provide an attribution link. Thankfully Hyde injects a customizable link\nautomatically to all pages that use Torchlight. You can of course disable and customize this in the config\/torchlight.php file.\n\n'attribution' => [\n'enabled' => true,\n'markdown' => 'Syntax highlighting by Torchlight.dev',\n],\n\nDon't have this file? Run php hyde vendor:publish to publish it.","destination":"third-party-integrations.html"},{"slug":"ui-kit","title":"HydePHP UI Kit - Documentation","content":"HydePHP UI Kit - Documentation\n\nThe HydePHP UI Kit is a collection of minimalistic and un-opinionated TailwindCSS components for Laravel Blade,\nintended to be used with HydePHP. Note that these components may require CSS classes not present in the bundled app.css\nfile and that you may need to recompile the CSS file using the included Tailwind and Vite configuration.\n\nScreenshot\n\nHere are some of the components you can use to build your next project! As you can see, all components support both light and dark mode out of the box, just like the rest of HydePHP.\n\nComponents Screenshot\n\nComponents\n\nPlease make sure you're familiar with Laravel Blade before using the HydePHP UI Kit.\n\ninfo Tip: Most components allow you to pass any additional HTML attributes to the element!\n\nButtons\n\nPrimary\n\nPrimary Button\n\nSecondary\n\nSecondary Button\n\nInput\n\nThe base component is ``, any additional attributes will be passed to the input element as seen below.\n\nCard\n\nAn incredibly versatile component that can be used for a wide variety of purposes.\n\nIn the most basic form, a card is just a container with a white background and a shadow.\nHowever, it also supports two slots: title and footer.\n\nA card with some content.\n\n\nCard Title\n\n\n\nSome footer content.\n\n\nWhy not combine the components?\n\n\nMy Amazing Card\n\n\nA card with some content and a footer with a button.\n\n\n\nPrimary Button\n\n\n\nTypography Components\n\nHeading\n\nThis component will create a styled `` level heading centred on the page.\n\nLorem ipsum dolor sit amet.\n\nProse\n\nThis simple component will create an `` element with TailwindCSS Typography (prose) styles applied.\n\nProse Heading\nProse paragraph\n\nMarkdown\n\nThis component will convert any Markdown within it to HTML using the Hyde Markdown compiler.\n\nMarkdown Heading\n\nHello world!\n\ninfo Tip: You may also want to wrap this in the prose element or the Markdown will not be styled.\n\nWhat's Next?\n\nThe UI kit is minimal by design. It's up to you to create something amazing, we just want to give you a head start.\nYou can get surprisingly far when you combine the components. Take this newsletter signup card for example!\n\n\nLet your creativity flow!\n\n\n\n\n\nThe UI kit is minimal by design. It's up to you to create something amazing.\n\nMaybe create a form to collect newsletter subscriptions?\n\n\n\n\n\n\n\n\nSubscribe\n\n\n\nNewsletter Screenshot\n\nGitHub Repository\n\nYou can find the source code for the UI Kit on GitHub at hydephp\/ui-kit.","destination":"ui-kit.html"},{"slug":"console-commands","title":"Console Commands","content":"# Console Commands\n\nThe primary way of interacting with Hyde is through the command line using the HydeCLI.\n\nIf you have ever used the Artisan Console in Laravel you will feel right at home,\nthe HydeCLI is based on Artisan after all!\n\n## Introduction\n\nTo use the HydeCLI, run php hyde from your project directory followed by a command.\n\nAll HydeCLI commands start with php hyde. Anything in [brackets] is optional.\nIf an argument or option value has a space in it, it needs to be wrapped in quotes.\n\nThe HydeCLI exists at the root of your application as the hyde script and provides a number of helpful commands that can\nassist you while you build your site. To view a list of all available Hyde commands, you may use the list command:\n\nphp hyde list\n\n### Got stuck? The CLI can help.\n\nEvery command also includes a \"help\" screen which displays and describes the command's available arguments and options.\nTo view a help screen, precede the name of the command with help:\n\nphp hyde help\n\nYou can also always add --help to a command to show detailed usage information.\n\nphp hyde  --help\n\n## Available Commands\n\nHere is a quick reference of all the available commands. You can also run php hyde list to see this list.\n\nCommand                                 Description\n\nbuild                       Build the static site\nserve                       Start the realtime compiler server\nrebuild                   Run the static site builder for a single file\nbuild:rss               Generate the RSS feed\nbuild:search         Generate the docs\/search.json file\nbuild:sitemap       Generate the sitemap.xml file\nmake:page               Scaffold a new Markdown, Blade, or documentation page file\nmake:post               Scaffold a new Markdown blog post file\npublish:configs   Publish the default configuration files\npublish:homepage Publish one of the default homepages as index.blade.php\npublish:views       Publish the hyde components for customization. Note that existing files will be overwritten\nvendor:publish     Publish any publishable assets from vendor packages\nroute:list             Display all registered routes\nvalidate                 Run a series of tests to validate your setup and help you optimize your site\nlist           List all available commands\n\n## Build the Static Site\n\nphp hyde build [--vite] [--pretty-urls] [--no-api]\n\nBuild the static site\n\n#### Options\n\n\n\n--vite        Build frontend assets using Vite\n--pretty-urls Should links in output use pretty URLs?\n--no-api      Disable API calls, for example, Torchlight\n\n## Run the static site builder for a single file\n\nphp hyde rebuild\n\nRun the static site builder for a single file\n\n#### Arguments\n\n\n\npath The relative file path (example: \\_posts\/hello-world.md) \\n - Is required: yes\n\n## Start the Realtime Compiler Server\n\nphp hyde serve [--host [HOST]] [--port [PORT]] [--vite]\n\nStart the realtime compiler server.\n\n#### Options\n\n\n\n--host= [default: \"localhost\"]\n--port= [default: 8080]\n\n## Test and validate your project to optimize your site\n\nphp hyde validate\n\nRun a series of tests to validate your setup and help you optimize your site.\n\n## Generate the RSS Feed\n\nphp hyde build:rss\n\nGenerate the RSS feed\n\n## Generate the docs\/search.json file\n\nphp hyde build:search\n\nGenerate the docs\/search.json file\n\n## Generate the sitemap.xml file\n\nphp hyde build:sitemap\n\nGenerate the sitemap.xml file\n\n## Scaffold a new Markdown, Blade, or documentation page file\n\nphp hyde make:page [--type [TYPE]] [--blade] [--docs] [--force] [--] []\n\nScaffold a new Markdown, Blade, or documentation page file\n\n#### Arguments & Options\n\n\n\ntitle           The name of the page file to create. Will be used to generate the filename\n--type=markdown The type of page to create (markdown, blade, or docs)\n--blade         Create a Blade page\n--docs          Create a Documentation page\n--force         Overwrite any existing files\n\n## Scaffold a new Markdown blog post file\n\nphp hyde make:post [--force] [--] []\n\nScaffold a new Markdown blog post file\n\n#### Arguments & Options\n\n\n\ntitle   The title for the Post. Will also be used to generate the filename\n--force Should the generated file overwrite existing posts with the same filename?\n\n## Publish the Default Configuration Files\n\nphp hyde publish:configs\n\nPublish the default configuration files\n\n## Publish one of the default homepages as index.blade.php.\n\nphp hyde publish:homepage [--force] [--] []\n\nPublish one of the default homepages as index.blade.php.\n\n#### Arguments & Options\n\n\n\nhomepage The name of the page to publish\n--force  Overwrite any existing files\n\n## Publish the hyde components for customization\n\nphp hyde publish:views []\n\nPublish the hyde components for customization. Note that existing files will be overwritten.\n\n#### Arguments\n\n\n\ngroup  The group to publish\n\n## Display All Registered Routes.\n\nphp hyde route:list\n\nDisplay all registered routes.\n\n## Publish any publishable assets from vendor packages\n\nphp hyde vendor:publish [--existing] [--force] [--all] [--provider [PROVIDER]] [--tag [TAG]]\n\nPublish any publishable assets from vendor packages\n\n#### Options\n\n\n\n--existing  Publish and overwrite only the files that have already been published\n--force     Overwrite any existing files\n--all       Publish assets for all service providers without prompt\n--provider= The service provider that has assets you want to publish\n--tag=      One or many tags that have assets you want to publish \\n- Is multiple: yes","destination":"console-commands.html"},{"slug":"core-concepts","title":"Core HydePHP Concepts","content":"Core HydePHP Concepts\n\nIntroduction to the Hyde Framework\n\nWhat makes HydePHP special are its \"magic\" features like autodiscovery and intelligent data generation.\nAll designed so that you can focus on your content, while the framework does the heavy lifting.\n\nThis page provides a high-level overview of the framework's capabilities, so you can quickly grasp its benefits.\nAs you delve deeper into the documentation, you'll discover the details of each feature and learn how to leverage them effectively.\n\nThe HydeCLI\n\nWhen you are not writing Markdown and Blade, most of your interactions with Hyde will be through the command line\nusing the HydeCLI, which is based on the Laravel Artisan Console that you may already be familiar with.\n\nIf you want to learn about the available commands and how to use them, you can visit the Console Commands page,\nor you can run any of the built-in help commands to get a list of available commands and their descriptions.\n\nphp hyde list\nphp hyde help\nphp hyde  [--help]\n\nDirectory Structure\n\nTo take full advantage of the framework, it may first be good to familiarize ourselves with the directory structure.\n\nDirectory          Purpose\n\n_docs            For documentation pages\n_posts           For blog posts\n_pages           For static Markdown and Blade pages\n_media           Store static assets to be copied to the build directory\n_site            The build directory where your compiled site will be stored\nconfig           Configuration files for Hyde and integrations\nresources\/assets Location for CSS\/JS Vite source files (optional)\nresources\/views  Location for Blade components (optional)\napp              Location for custom PHP classes (optional)\n\nPage Models\n\nThe Hyde page models are an integral part of how HydePHP creates your static site. Each page in your site is represented\nby a page model. These are simply PHP classes that in addition to holding both the source content and computed data\nfor your pages, also house instructions to Hyde on how to parse, process, and render the pages to static HTML.\n\nThe page classes are very important and fill two roles:\n\n1. They act as blueprints containing static instructions for how to parse, process, and, render pages.\n2. Each class instance also holds the page source contents, as well as the computed data.\n\nTo learn more, you can visit the Page Models page.\n\nFile Autodiscovery\n\nContent files, meaning source Markdown and Blade files, are automatically discovered by Hyde and compiled to HTML when\nbuilding the site. This means that you don't need to worry about routing and controllers!\n\nThe directory a source file is in will determine the Blade template that is used to render it.\n\nAll source and output directories are configurable, but the defaults are as follows:\n\nPage\/File Type Source Directory Output Directory File Extensions\n\nStatic Pages   pages\/        site\/         .md, .blade.php\nBlog Posts     posts\/        site\/posts\/   .md\nDocumentation  docs\/         site\/docs\/    .md\nMedia Assets   media\/        site\/media\/   Common asset types\n\nPaths, Identifiers, and Route Keys\n\nSince HydePHP automatically discovers and compiles content files, it is important to understand how HydePHP handles paths,\nas the file names and directories they are in will directly influence how the page will be compiled.\n\nAs such, it will be helpful for you to know about the following terms:\n\nPath:** The full path to a file, including the file name, directory, and extension.\nIdentifier:** The unique identifier for a page. Unique only within the same page type.\nRoute key:** The key used to access the page in the routing system. Unique across all site pages.\n\nBoth the identifier and route key are derived from the path of the page. The identifier is the path without the file\nextension, and relative to the page type source directory. The route key is the output directory plus the identifier.\n\nThe identifier generation can be visualized as follows, where the identifier is underlined:\n\n_pages\/about\/contact.md\n\nFor a Markdown page, like the example above, the route key would be the same as the identifier, since Markdown pages are\noutput to the site root. If it was a Markdown post however, the route key would be: posts\/about\/contact.\n\nThis can be visualized as follows, assuming a blog post is stored as _posts\/hello-world.md:\n\n_site\/posts\/hello-world.html\n\nAs you can see, the route key is simply put the relative page URL, without the .html extension.\n\nConvention Over Configuration\n\nHyde favours the \"Convention over Configuration\" paradigm and thus comes preconfigured with sensible defaults.\nHowever, Hyde also strives to be modular and endlessly customizable and hackable if you need it.\nTake a look at the customization and configuration guide to see the endless options available!\n\nFront Matter\n\ninfo In a nutshell: Front Matter is a block of YAML containing metadata, stored at the top of a Markdown file.\n\nFront matter is heavily used in HydePHP to store metadata about pages. Hyde uses the front matter data to generate rich and dynamic content. For example, a blog post category, author website, or featured image.\n\nUsing front matter is optional, as Hyde will dynamically generate data based on the content itself. (Though any matter you provide will take precedence over the automatically generated data.)\n\nTo learn more, you can visit the Front Matter page.\n\nFront Matter in Markdown\n\nAll Markdown content files support Front Matter, and blog posts make heavy use of it. Here's what it may look like:\n\ntitle: \"My New Post\"\nauthor: \"Mr Hyde\"\ndate: \"2023-03-14\"\nMarkdown Comes Here\n\nLorem ipsum dolor sit amet, etc.\n\nFront Matter in Blade\n\nHydePHP has basic support for creating front-matter in Blade templates, called BladeMatter,\nwhere code in @php directives are statically parsed into page object's front matter data where it can be accessed in your templates.\n\n@php($title = 'BladeMatter Demo') \/\/ Equivalent to title: 'BladeMatter Demo' in Yaml\n\nAutomatic Routing\n\ninfo In a nutshell: Hyde will automatically create routes for your source files.\n\nIf you've ever worked in an MVC framework, you are probably familiar with the concept of routing.\nAnd you are probably also familiar with how boring and tedious it can be. Thankfully, Hyde takes the pain out of routing by doing it for you!\n\nDuring the Autodiscovery process. Hyde will automatically discover all the content files in the source directories,\nand create routes for all of them, and store them in an index which works as a two-way link between source files and compiled files.\n\nYou can see all the routes and their corresponding source files by running the hyde route:list command.\n\nphp hyde route:list\n\nTo access routes in your code, simply use the Routes facade and specify the route key for the desired page.\n\nRoutes::get('posts\/my-post')\n\nTo learn more about the routing system, please visit the routing documentation.\n\nGlobal Page Data\n\nDuring the build of each page, Hyde will inject some data available to all Blade views. If you are not planning to write\nany custom Blade templates, you can safely ignore this section. If you are, here are the three global variables you can use:\n\n- $page: The Page Object for the current page.\n- $route: The Route Object for the current page.\n- $routeKey: The Route Key for the current page.\n\nThe $page variable is likely to be the most important one, as it contains all the data for the current page.\nDepending on the page type, you will have different helpers available. But $page->matter() is likely to be very helpful.\n\nYou can see all the helpers in the Page API reference page.\n\nTerminology\n\nIn this quick reference, we'll briefly go over some terminology and concepts used in HydePHP.\nThis will help you understand the documentation and codebase better, as well as helping you know what to search for when you need help.\n\nTable of contents\n\nTools\n\n- HydePHP\n- Laravel\n- Composer\n- Tailwind CSS\n\nLanguages\n\n- Front Matter\n- Markdown\n- Blade\n- YAML\n- PHP\n- HTML\n\nGeneral Concepts\n\n- Static Sites\n- Version Control\n- Git\n\nHydePHP Features\n\n- Autodiscovery\n- Page Types\n- Page Identifiers\n- Routes\n- Route Keys\n\n[\/\/]: # (Languages and Tools)\n\nHydePHP\n\nHydePHP is a static site generator written in PHP, designed to make it easy for developers to build fast and secure websites.\nIt uses a simple directory structure and templating system to generate static websites from content files,\nand can be easily extended using PHP libraries and packages.\n\nLaravel\n\nLaravel is the PHP framework that HydePHP is built on top of. We use a specialized version called Laravel Zero,\nwhich is optimized for command-line applications.\n\nFront Matter\n\nFront Matter is a block of YAML, stored at the top of a Markdown file, enclosed by a set of triple-dashed lines.\nIt is commonly used to store metadata about the content, such as the title, author, date, etc.\n\nMarkdown\n\nMarkdown is a lightweight markup language that uses plain text formatting syntax, designed to make it easy to create\nstructured content for the web. HydePHP uses Markdown as the base for most of its content files.\n\nBlade\n\nBlade is the templating engine from Laravel, which allows developers to write clean and reusable code for the\npresentation layer of web applications. HydePHP uses Blade both for the built-in views and components,\nas well as to provide powerful templating capabilities through Blade-based pages.\n\nYAML\n\nYAML is a human-readable data serialization format used for configuration files and often used as the syntax for\nFront Matter in HydePHP content files. YAML is designed to be easily read by humans and parsed by machines,\nmaking it a popular choice for many applications and frameworks.\n\nPHP\n\nPHP is a popular server-side scripting language used for web development that can be embedded in HTML.\nHydePHP is built on top of PHP and utilizes its powerful capabilities for generating static websites.\n\nHTML\n\nHTML (Hypertext Markup Language) is the standard markup language used to create web pages and web applications.\nHydePHP uses HTML to render the static websites generated from its content files and templates.\n\nTailwind CSS\n\nTailwind CSS is a utility-first CSS framework used for rapidly building custom user interfaces.\nHydePHP supports Tailwind CSS out of the box through the built-in Blade templates,\nmaking it easy for developers to create beautiful and responsive websites without writing custom CSS.\n\nComposer\n\nComposer is a dependency manager for PHP that simplifies the process of installing and managing packages required by\nPHP applications. HydePHP uses Composer to manage its own dependencies and make it easy for users to install and use the software.\n\nStatic Sites\n\nA static website is a collection of HTML web pages that are delivered to the user's web browser exactly as they are stored\non the web server. HydePHP generates static websites, making them fast, secure, and easy to deploy.\n\nVersion Control\n\nHydePHP can be easily integrated with Git to manage website source files and track changes over time,\nas one of the many benefits with static sites is that they are designed to be version controlled.\n\nGit\n\nGit is a free and open-source distributed version control system that is widely used for software development.\nGit repositories can be hosted on GitHub, GitLab, BitBucket, or any other Git hosting service.\n\n[\/\/]: # (HydePHP Features)\n\nAutodiscovery\n\nContent files, including Markdown and Blade files, are automatically discovered and compiled to HTML during site builds.\nDuring autodiscovery, Hyde also generates dynamic data to enrich your content based on the page type.\n\nIn short the autodiscovery is split into three steps:\nFile discovery -> Page parsing -> Route generation\n\nPage Types\n\nAll pages in HydePHP are internally represented by a page object that extends the HydePage class. Each page type has its\nown page class which acts as a blueprint defining information for the framework to parse a file and generate relevant data.\n\nPage Identifiers\n\nThe page identifier is the name of the file without the file extension, relative to the page type's source directory.\nThe identifier is used to generate the route key, which is used to generate the file name for the compiled HTML file.\n\nRoutes\n\nAll pages are internally bound to a Route object, through the route key. During the build process, each route is\ncompiled to HTML using the page object's data, and saved to the output directory with a file name created from the route key.\nSince routes are generated automatically during autodiscovery, there is no need to create them manually.\n\nRoute Keys\n\nThe route key is the URL path relative to the site webroot, without the file extension. The route key is the common\nidentifier binding Page objects to Route objects, and is used to generate the file name for the compiled HTML file.\n\nRoute keys generation can be visualised as follows: \/","destination":"core-concepts.html"},{"slug":"front-matter","title":"Front Matter","content":"Front Matter\n\ninfo In a nutshell: Front Matter is a block of YAML containing metadata, stored at the top of a Markdown file.\n\nFront matter is heavily used in HydePHP to store metadata about pages. Hyde uses the front matter data to generate rich and dynamic content.\nFor example, in a blog post you may define a category, author website, or featured image. In a documentation page you may define the sidebar priority or label.\n\nUsing front matter is optional, as Hyde will dynamically generate data based on the content itself. (Though any matter you provide will take precedence over the automatically generated data.)\nWhile Hyde offers some support for front matter within Blade files, most of the time you use front matter, it will be in Markdown.\n\nFront Matter Syntax\n\nHere's a refresher on Yaml, and a quick reference of the syntax Hyde uses and expects:\n\nkey: value\nstring: \"quoted string\"\nboolean: true\ninteger: 100\narray:\nkey: value\nkey: value\n\nStrings don't need to be quoted, but it can help in certain edge cases, thus they are included here.\n\nFront Matter in Markdown\n\nAll Markdown content files support Front Matter. Blog posts for example make heavy use of it.\n\nThe specific usage and schemas used for pages are documented in their respective documentation, however, here is a primer on the fundamentals.\n\n- Front matter is stored in a block of YAML that starts and ends with a --- line.\n- The front matter should be the very first thing in the Markdown file.\n- Each key-pair value should be on its own line.\n\nTo use Front Matter, add YAML to the top of your Markdown file:\n\ntitle: \"My New Post\"\nauthor:\nname: \"John Doe\"\nwebsite: https:\/\/example.com\nMarkdown Comes Here\n\nLorem ipsum dolor sit amet, etc.\n\nFront Matter in Blade\n\nHydePHP has basic support for creating front-matter in Blade templates, called BladeMatter.\n\nThe actual syntax does not use YAML; but instead PHP. However, the parsed end result is the same. Please note that\nBladeMatter currently does not support multidimensional arrays or multi-line directives as the data is statically parsed.\n\nTo create BladeMatter, you simply use the default Laravel Blade @php directive to declare a variable in the template.\n\n@php($title = 'BladeMatter Demo')\n\nIt will then be available through the global $page variable, $page->matter('title').\nHyde will of course also use the data for contextual autoconfiguration in the same way it would with Markdown and use the value as the page title.\n\nAnother idea is to use @php($navigation = ['hidden' => true]) if you want to hide a page from the navigation. The opportunities are limitless!","destination":"front-matter.html"},{"slug":"quickstart","title":"Quickstart Guide","content":"Quickstart Guide\n\nInstalling HydePHP Using Composer\n\nThe recommended method of installing Hyde is using Composer, which installs the required dependencies on a per-project basis.\n\ncomposer create-project hyde\/hyde\n\nRequirements\n\nHyde is based on Laravel 11\nwhich requires a minimum PHP version of 8.2.\nYou should also have Composer installed.\n\nTo use some features like compiling your own assets\nyou also need NodeJS and NPM.\n\nUsing the Hyde CLI\n\nThe main way to interact with Hyde is through the HydeCLI, a Laravel Artisan-based command-line interface. Learn more about the HydeCLI in the console commands documentation.\n\nStarting a Development Server\n\nTo make previewing your site a breeze you can use the realtime compiler, which builds your pages on the fly.\n\nphp hyde serve\nSimply run the serve command, and you will be able to preview your site at http:\/\/localhost:8080.\n\nCreating Content\n\nDirectory structure\n\nCreating content with Hyde is easy! Simply place source files in one of the source directories,\nand Hyde will automatically discover, parse, and compile them to static HTML.\nThe directory and file extension of a source file will determine how HydePHP parses and compiles it.\nPlease see the directory structure section for more information.\n\nScaffolding files\n\nYou can scaffold blog post files using the php hyde make:post command which automatically creates the front matter, based on your input selections.\nYou can also scaffold pages with the php hyde make:page command.\n\nphp hyde make:post\nphp hyde make:page\n\nCompiling to static HTML\n\nNow that you have some amazing content, you'll want to compile your site into static HTML. Thankfully, this is as easy as executing the build command, after which your compiled site is stored in the _site directory.\n\nphp hyde build\n\nWhen building the site, Hyde will scan your source directories for files and compile them into static HTML using the appropriate layout depending\non what kind of page it is. You don't have to worry about routing as Hyde takes care of everything, including creating navigation menus!\n\nManaging assets\n\nHyde comes bundled with a precompiled and minified app.css file, containing all the Tailwind you need for the default views meaning that you don't even need to use NPM. However, Hyde is already configured to use Vite to compile your assets if you feel like there's a need to build the assets yourself. See more on the Managing Assets page.\n\nDeploying your site\n\nYou are now ready to show your site to the world! Simply copy the _site directory to your web server's document root, and you're ready to go.\n\nYou can even use GitHub Pages to host your site for free. That's what the Hyde website does, using an Actions CI workflow that automatically builds and deploys this site.\n\nFurther Reading\n\nHere's some ideas of what to read next:\n\n- Architecture Concepts & Directory Structure\n- Console Commands with the HydeCLI\n- Creating Blog Posts","destination":"quickstart.html"},{"slug":"release-notes","title":"HydePHP v2.0 Release Notes","content":"HydePHP v2.0 Release Notes\n\nOverview\n\nHydePHP v2.0 represents a major evolution of the framework, introducing significant improvements to the asset system, navigation API, and overall developer experience. This release modernizes the frontend tooling by replacing Laravel Mix with Vite, completely rewrites the navigation system for better flexibility, and introduces numerous performance optimizations throughout the framework.\n\nThis document will give you an overview of the changes. When you're ready to upgrade your site, take a look at the Upgrade Guide.\n\nMajor Features\n\n\ud83d\ude80 Modern Frontend Tooling with Vite\n\nWe've replaced Laravel Mix with Vite for a faster, more modern development experience:\nInstant Hot Module Replacement (HMR)** for real-time updates during development\nDirect asset compilation** into the _media folder for cleaner builds\nUpdated build command**: Use npm run build instead of npm run prod (or --vite during the site build)\nVite facade** for seamless Blade template integration\nOptimized asset serving** through the realtime compiler\nHyde Vite plugin** for enhanced integration\n\n\ud83c\udfa8 Enhanced Asset Management System\n\nThe new consolidated Asset API provides a more intuitive interface for handling media files:\nMediaFile instances** with fluent methods like getLink(), getLength(), and getMimeType()\nHydeFront facade** for CDN links and Tailwind configuration injection\nIntelligent caching** with CRC32 hashing for improved performance\nAutomatic validation** to prevent missing assets from going unnoticed\nLazy-loaded metadata** for optimal resource usage\n\n\ud83e\udded Redesigned Navigation API\n\nThe navigation system has been completely rewritten for maximum flexibility:\nYAML configuration support** for defining navigation items\nExtra attributes** for custom styling and behavior\nImproved Routes facade** with Laravel-consistent naming conventions\nNatural priority ordering** using numeric prefixes in filenames\nEnhanced sidebar management** with better organization options\n\n\ud83d\udcdd Improved Documentation Features\n\nDocumentation pages now benefit from several enhancements:\nAlpine.js-powered search** with customizable implementation\nBlade-based table of contents** that's 40x faster than before\nCustom heading renderer** with improved permalink handling\nColored blockquotes** now using Tailwind CSS classes\nSmart natural language processing** for search headings\nDynamic source file links** in Markdown documents\n\n\ud83c\udfaf Better Developer Experience\n\nNumerous quality-of-life improvements for developers:\nPHP 8.4 support** and Laravel 11 compatibility\nESM module support** for modern JavaScript development\nTailwind CSS v4** with automated upgrade tools\nEnhanced data collections** with syntax validation\nImproved error messages** with clearer exception handling\nInteractive publish:views command** on Unix systems\nExtension callbacks** with booting() and booted() methods\n\nUpgrading to v2.0\n\n\ud83d\udcd6 For complete step-by-step upgrade instructions, see the Upgrade Guide.\n\nImportant: PHP 8.2+ is now required. Laravel Mix has been replaced with Vite, and Tailwind CSS has been upgraded to v4.\n\nBreaking Changes\n\nHigh Impact Changes\n\n1. Tailwind CSS v4 Upgrade\n\nWe've upgraded from Tailwind CSS v3 to v4. Run the automated upgrade tool to migrate your custom classes:\n\nnpx @tailwindcss\/upgrade\n\nReview the Tailwind v4 Upgrade Guide for detailed breaking changes.\n\n2. ESM Module Migration\n\nFrontend tooling now uses ESM modules instead of CommonJS. If you have custom JavaScript, update to ESM syntax:\n\nBefore:\nconst module = require('module-name');\nmodule.exports = { \/* ... *\/ };\n\nAfter:\nimport module from 'module-name';\nexport default { \/* ... *\/ };\n\n3. Navigation Configuration Format\n\nUpdate your navigation configuration to use the new array-based format:\n\nBefore:\n'navigation' => [\n'custom_items' => [\n'Custom Item' => '\/custom-page',\n],\n],\n\nAfter:\n'navigation' => [\n'custom_items' => [\n['label' => 'Custom Item', 'destination' => '\/custom-page'],\n],\n],\n\n4. Features Configuration\n\nReplace static method calls with enum values in your config\/hyde.php:\n\nBefore:\n'features' => [\nFeatures::htmlPages(),\nFeatures::markdownPosts(),\n],\n\nAfter:\n'features' => [\nFeature::HtmlPages,\nFeature::MarkdownPosts,\n],\n\nGeneral Impact Changes\n\nPost Author System\n\nThe blog post author feature has been significantly improved:\n\nConfiguration changes:\n\/\/ Before\n'authors' => [\nAuthor::create('username', 'Display Name', 'https:\/\/example.com'),\n],\n\n\/\/ After\n'authors' => [\n'username' => Author::create(\nname: 'Display Name',\nwebsite: 'https:\/\/example.com',\nbio: 'Author bio',\navatar: 'avatar.png',\nsocials: ['twitter' => '@username']\n),\n],\n\nKey changes:\n- Authors are now keyed by username\n- Author::create() returns an array instead of a PostAuthor instance\n- Author::get() returns null if not found (previously created new instance)\n- Usernames are automatically normalized (lowercase, underscores for spaces)\n- Authors support biographies, avatars, and social media links\n- A new Hyde::authors() method provides access to all site authors\n- Authors can be configured via YAML\n\nThe way this system now works is that you first define authors in the config, Hyde then loads this during the booting process, and you can then access them using the get method.\n\nMedium Impact Changes\n\nAsset API Updates\n\nAll asset methods now return MediaFile instances instead of strings. This instance can be cast to a string which will automatically resolve to a relative link at that time. You can also call helper methods on it. When using Blade templates, thanks to the Stringable implementation no change will happen.\n\n\/\/ Methods renamed for clarity\nHyde::asset('image.png');        \/\/ Previously: Hyde::mediaLink()\nAsset::get('image.png');         \/\/ Previously: Asset::mediaLink()\nAsset::exists('image.png');      \/\/ Previously: Asset::hasMediaFile()\nHydeFront::cdnLink('app.css');   \/\/ Previously: Asset::cdnLink()\n\nConfiguration changes:\n- Rename hyde.enablecachebusting to hyde.cache_busting\n- Remove references to hyde.hydefrontversion and hyde.hydefrontcdn_url\n\nRoutes Facade API\n\nMethods renamed to follow Laravel conventions:\n\n\/\/ Before\n$route = Routes::get('route-name');        \/\/ Returns null if not found\n$route = Routes::getOrFail('route-name');  \/\/ Throws exception\n\n\/\/ After\n$route = Routes::find('route-name');       \/\/ Returns null if not found\n$route = Routes::get('route-name');        \/\/ Throws exception\n\nDataCollection API\n\n- Class renamed from DataCollections to DataCollection\n- Syntax validation now throws ParseException for malformed files\n- Empty data files are no longer allowed\n- Directory creation is no longer automatic\n- The route function now throws RouteNotFoundException if route not found\n\nLow Impact Changes\n\nIncludes Facade Return Types\n\nMethods now return HtmlString objects:\n\n{{-- Before: Required unescaped output --}}\n{!! Includes::html('partial') !!}\n\n{{-- After: Automatic rendering --}}\n{{ Includes::html('partial') }}\n\n\u26a0\ufe0f Security Note: Output is no longer escaped by default. Use {{ e(Includes::html('foo')) }} for user-generated content.\n\nDocumentation Search Generation\n\nThe documentation search page is now generated as an InMemoryPage instead of a post-build task, meaning it appears in the dashboard and route list.\n\nSidebar Configuration\n\nDocumentation sidebar configuration has been reorganized:\n- docs.sidebar_order \u2192 docs.sidebar.order\n- docs.tableofcontents \u2192 docs.sidebar.tableofcontents\n- docs.sidebargrouplabels \u2192 docs.sidebar.labels\n\nNew Features\n\nEnhanced Blog Posts\n\nSimplified image front matter** with new \"caption\" field\nDate prefixes in filenames** for automatic publishing dates\nRich markup data** with BlogPosting Schema.org type\nAuthor collections** accessible via Hyde::authors()\nCustom posts support** in blog feed component\n\nImproved Build System\n\nVite integration** with HMR support in realtime compiler\nSmart asset compilation** - app.js only compiles when needed\nEnvironment variable support** for saving previews\nGrouped progress bars** for InMemoryPage instances\nMedia asset transfers** via dedicated build task\n\nDeveloper Tools\n\nInteractive publish:views command** on Unix systems\nCustom HydeSearch.js** support for search customization\nExtension callbacks** with booting() and booted() methods\nDynamic source file links** in Markdown documents (for example Home)\nFilesystem::ensureParentDirectoryExists()** helper method\n\nPackage Updates\n\nRealtime Compiler\n- Simplified asset file locator for media source directory\n- Added Vite HMR support\n- Experimental Laravel Herd support\n\nHydeFront\n- Complete migration from Sass to Tailwind CSS\n- Extracted CSS component partials\n- Removed legacy hyde.css file\n\nPerformance Improvements\n\n40x faster table of contents generation** using Blade components\nCRC32 hashing** replaces MD5 for cache busting (much faster)\nLazy-loaded media metadata** with in-memory caching\nCached media assets** in HydeKernel for instant access\n\nDependency Updates\n\nPHP**: Now requires 8.2\u20138.4 (dropped 8.1 support)\nLaravel**: Upgraded to version 11\nTailwind CSS**: Upgraded to version 4\nSymfony\/Yaml**: Updated to version 7\nTorchlight**: Switched to forked version for compatibility\n\nRemoved Features\n\nDeprecated Method Removals\n- PostAuthor::getName() - use $author->name property\n- FeaturedImage::isRemote() - use Hyperlinks::isRemote()\n- DocumentationPage::getTableOfContents() - use Blade component\n- MarkdownService::withPermalinks() and canEnablePermalinks()\n\nBuild Commands\n- npm run prod - replaced by npm run build\n- --run-dev and --run-prod flags - replaced by --vite\n- --run-prettier flag and Prettier dependency removed\n\nConfiguration Options\n- hyde.hydefrontversion and hyde.hydefrontcdn_url - now handled automatically\n- hyde.enablecachebusting - renamed to hyde.cache_busting\n- hyde.navigation.subdirectories - renamed to hyde.navigation.subdirectory_display\n\nComponents and Files\n- hyde.css from HydeFront - all styles now in app.css\n- table-of-contents.css, heading-permalinks.css, blockquotes.css - styles now use Tailwind\n- .torchlight-enabled CSS class\n- ` and  components - replaced by `\n\nSupport & Resources\n\nDocumentation**: https:\/\/hydephp.com\/docs\/2.x\nUpgrade Guide**: https:\/\/hydephp.com\/docs\/2.x\/upgrade-guide\nGitHub Issues**: https:\/\/github.com\/hydephp\/hyde\/issues\nCommunity Discord**: https:\/\/discord.hydephp.com\n\nFor the complete changelog with all pull request references, see the full changelog.","destination":"release-notes.html"},{"slug":"upgrade-guide","title":"Upgrade Guide","content":"Will be filled in from UPGRADE.md before release.","destination":"upgrade-guide.html"},{"slug":"index","title":"Elegant and Powerful Static Site Generator","content":"Elegant and Powerful Static Site Generator\n\n.images-inline img { display: inline; margin: 4px 2px;}\n\nLatest Version on Packagist\nTotal Downloads on Packagist\nTest Coverage\nScrutinizer Code Quality\nPsalm Type Coverage\nLicense MIT\n{.images-inline .not-prose}\n\nAbout HydePHP\n\nHydePHP is a Static Site Generator focused on writing content, not markup. With Hyde, it is easy to create static\nwebsites, blogs, and documentation pages using Markdown and (optionally) Laravel's Blade.\n\nOperated entirely through the command-line, HydePHP provides developers with a fast and efficient way to create high-quality websites with ease.\nUnlike traditional web development frameworks, sites compiled with HydePHP don't require any server to run,\nmaking it an ideal choice for building lightweight and fast-loading websites.\n\nCompared with other static site builders, Hyde is blazingly fast and seriously simple to get started with, yet it has the\nfull power of Laravel waiting for you when you need it, as Hyde is powered by Laravel Zero, a stripped-down version of\nthe robust and popular Laravel Framework, optimized for console applications.\n\nHyde makes creating websites easy and fun by taking care of the boring stuff, like routing, writing boilerplate, and\nendless configuration. Instead, when you create a new Hyde project, everything you need to get started is already there\n-- including precompiled TailwindCSS, well-crafted Blade templates, and easy-to-use asset management.\n\nHyde was inspired by JekyllRB and is designed for developers who are comfortable writing posts in Markdown, and it requires\nvirtually no configuration out of the box as it favours convention over configuration and is preconfigured with sensible defaults.\n\nInstallation\n\nHydePHP is a command-line interface (CLI) application that is installed on a per-project basis.\n\nTo use HydePHP, your system must have PHP version 8.2 or later installed, along with Composer, and access to a terminal.\n\nThe recommended method of installation is using Composer.\n\ncomposer create-project hyde\/hyde\n\nOnce installed, you can access the HydeCLI from the project root using the hyde command.\n\nphp hyde info\n\nUsage\n\nCreating static websites with HydePHP is incredibly easy. First you need some content. You can just drop Markdown files\nin any of the source directories, or let Hyde scaffold the files for you using one of the many commands.\n\nphp hyde make:post \"My First Post\"\nphp hyde make:page \"About Me\"\n\nOnce you have some content, you can run the build command to compile the content into beautiful static HTML.\n\nphp hyde build\n\nAnd that's it, your amazing website is ready to be shared with the world!\n\nTo learn more, head over to the quickstart page.","destination":"index.html"},{"slug":"configuration","title":"Configuration","content":"Redirecting you to customization","destination":"configuration.html"},{"slug":"directory-structure","title":"Directory Structure","content":"Redirecting you to architecture-concepts#directory-structure","destination":"directory-structure.html"},{"slug":"getting-started","title":"Getting Started","content":"Redirecting you to quickstart","destination":"getting-started.html"},{"slug":"installation","title":"Installation","content":"Redirecting you to quickstart","destination":"installation.html"}]