HydePHP consists of two primary components, Hyde/Hyde and Hyde/Framework. Development is made in the Hyde/Develop Monorepo. Major and Minor release versions are made in the Develop project. These releases are synced to the Hyde and Framework projects, and are what this changelog file tracks. Patch release versions are made in the Framework and Hyde projects independently. See https://github.com/hydephp/develop#releases for more information.
Method Hyde::url() will now return a relative URL instead of throwing an exception when supplied a path even if the site URL is not set in https://github.com/hydephp/develop/pull/1726
+
This release contains changes to how HydePHP behaves when a site URL is not set by the user.
+
These changes are made to reduce the chance of the default localhost value showing up in production environments.
+
Most notably, HydePHP now considers that default site URL localhost to mean that a site URL is not set, as the user has not set it.
+This means that things like automatic canonical URLs will not be added, as Hyde won't know how to make them without a site URL.
+The previous behaviour was that Hyde used localhost in canonical URLs, which is never useful in production environments.
+
For this reason, we felt it worth it to make this change in a minor release, as it has a such large benefit for sites.
Hyde provides DataCollections, a subset of Laravel Collections giving you
-a similar developer experience to working with Eloquent Collections. However, instead of accessing a database,
-it's all entirely file-based using static data files such as Markdown, Yaml, and JSON files which get
+
Hyde provides DataCollections, a subset of Laravel Collections giving you a similar developer experience to working with Eloquent Collections.
+However, instead of accessing a database, it'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.
-
As you have access to all standard Laravel Collection methods, you are encouraged to read the
-Laravel Collections documentation for more information.
+
As you have access to all standard Laravel Collection methods, you are encouraged to read the Laravel Collections documentation for more information.
This 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.
In short, HydePHP finds files in the specified directory, turns each file into an object, and returns a Laravel Collection of these objects.
To make collections easy to use and understand, Hyde makes a few assumptions about the structure of your collections.
Follow these conventions and creating dynamic static sites will be a breeze.
This setting allows you to enable or disable the theme toggle buttons in the navigation menu.
+
Filepath: config/hyde.php
1'theme_toggle_buttons'=>true,
+
If the Feature::Darkmode setting is disabled in the features array in the same file, this won't do anything, but if darkmode is enabled,
+setting this setting to false will make so that the buttons will not show up in the app layout nor the documentation layout;
+instead the appropriate color scheme will be automatically applied based on the browser system settings.
Hyde uses the Laravel Blade templating engine. Most parts of the included templates have been extracted into components to be customized easily.
Before editing the views you should familiarize yourself with the Laravel Blade Documentation.
All navigation menu items have an internal priority value that determines their order in the navigation.
Lower values mean that the item will be higher up in the menu. The default for pages is 999 which puts them last.
-However, some pages are autoconfigured to have a lower priority, for example, the index page defaults to a priority of 0,
+However, some pages are autoconfigured to have a lower priority, for example, the index page defaults to a priority of 0.
Here is a quick overview of what you might want to customize in your navigation menus:
diff --git a/docs/docs/1.x/page-models.html b/docs/docs/1.x/page-models.html
index 51584da8..03996a45 100644
--- a/docs/docs/1.x/page-models.html
+++ b/docs/docs/1.x/page-models.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/docs/1.x/quickstart.html b/docs/docs/1.x/quickstart.html
index 4484c9af..78948117 100644
--- a/docs/docs/1.x/quickstart.html
+++ b/docs/docs/1.x/quickstart.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/docs/1.x/realtime-compiler.html b/docs/docs/1.x/realtime-compiler.html
index 43a82f6c..a278630e 100644
--- a/docs/docs/1.x/realtime-compiler.html
+++ b/docs/docs/1.x/realtime-compiler.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/docs/1.x/search.html b/docs/docs/1.x/search.html
index 91abb657..3ed25d99 100644
--- a/docs/docs/1.x/search.html
+++ b/docs/docs/1.x/search.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/docs/1.x/search.json b/docs/docs/1.x/search.json
index dee3e089..3b86ccab 100644
--- a/docs/docs/1.x/search.json
+++ b/docs/docs/1.x/search.json
@@ -1 +1 @@
-[{"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.1 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":""},{"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"},{"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"},{"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"},{"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"},{"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"},{"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"},{"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 of course, also supply extra attributes like classes:\n\nHome","destination":"automatic-routing"},{"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"},{"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\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"},{"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"},{"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\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::version(): string\n\n__construct()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\n$hyde = new HydeKernel(string $basePath): void\n\nfeatures()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::features(): Hyde\\Facades\\Features\n\nhasFeature()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::hasFeature(string $feature): bool\n\ntoArray()\n\nGet the instance as an array.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::toArray(): array\n\nfiles()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::files(): \\Hyde\\Foundation\\Kernel\\FileCollection\n\npages()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::pages(): \\Hyde\\Foundation\\Kernel\\PageCollection\n\nroutes()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::routes(): \\Hyde\\Foundation\\Kernel\\RouteCollection\n\nmakeTitle()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::makeTitle(string $value): string\n\nnormalizeNewlines()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::normalizeNewlines(string $string): string\n\nstripNewlines()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::stripNewlines(string $string): string\n\ntrimSlashes()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::trimSlashes(string $string): string\n\nmarkdown()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::markdown(string $text, bool $normalizeIndentation): Illuminate\\Support\\HtmlString\n\nformatLink()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::formatLink(string $destination): string\n\nrelativeLink()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::relativeLink(string $destination): string\n\nmediaLink()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::mediaLink(string $destination, bool $validate): string\n\nasset()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::asset(string $name, bool $preferQualifiedUrl): string\n\nurl()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::url(string $path): string\n\nhasSiteUrl()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::hasSiteUrl(): bool\n\nfilesystem()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::filesystem(): Hyde\\Foundation\\Kernel\\Filesystem\n\npath()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::path(string $path): string\n\nvendorPath()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::vendorPath(string $path, string $package): string\n\nmediaPath()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::mediaPath(string $path): string\n\nsitePath()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::sitePath(string $path): string\n\nsiteMediaPath()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::siteMediaPath(string $path): string\n\npathToAbsolute()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::pathToAbsolute(array|string $path): array|string\n\npathToRelative()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::pathToRelative(string $path): string\n\ngetInstance()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getInstance(): Hyde\\Foundation\\HydeKernel\n\nsetInstance()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::setInstance(Hyde\\Foundation\\HydeKernel $instance): void\n\ngetBasePath()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getBasePath(): string\n\nsetBasePath()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::setBasePath(string $basePath): void\n\ngetSourceRoot()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getSourceRoot(): string\n\nsetSourceRoot()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::setSourceRoot(string $sourceRoot): void\n\ngetOutputDirectory()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getOutputDirectory(): string\n\nsetOutputDirectory()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::setOutputDirectory(string $outputDirectory): void\n\ngetMediaDirectory()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getMediaDirectory(): string\n\nsetMediaDirectory()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::setMediaDirectory(string $mediaDirectory): void\n\ngetMediaOutputDirectory()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::registerExtension(class-string<\\Hyde\\Foundation\\Concerns\\HydeExtension> $extension): void\n\ngetExtension()\n\nGet the singleton instance of the specified extension.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getExtension(class-string<T> $extension): T\n\nhasExtension()\n\nDetermine if the specified extension is registered.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::hasExtension(class-string<\\Hyde\\Foundation\\Concerns\\HydeExtension> $extension): bool\n\ngetExtensions()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getExtensions(): array\n\ngetRegisteredExtensions()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getRegisteredExtensions(): array>\n\ngetRegisteredPageClasses()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getRegisteredPageClasses(): array>\n\nshareViewData()\n\nShare data for the page being rendered.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::shareViewData(Hyde\\Pages\\Concerns\\HydePage $page): void\n\ncurrentRouteKey()\n\nGet the route key for the page being rendered.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::currentRouteKey(): string\n\ncurrentRoute()\n\nGet the route for the page being rendered.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::currentRoute(): Hyde\\Support\\Models\\Route\n\ncurrentPage()\n\nGet the page being rendered.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::currentPage(): Hyde\\Pages\\Concerns\\HydePage\n\nisBooted()\n\nDetermine if the Kernel has booted.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::isBooted(): bool\n\nboot()\n\nBoot the Hyde Kernel and run the Auto-Discovery Process.\n\n\/\/ torchlight! {\"lineNumbers\": false}\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\/\/ torchlight! {\"lineNumbers\": false}\n\/* @param callable(\\Hyde\\Foundation\\HydeKernel): void $callback \/\nHyde::booting(callable(\\Hyde\\Foundation\\HydeKernel): void): void\n\nbooted()\n\nRegister a new "booted" 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\/\/ torchlight! {\"lineNumbers\": false}\n\/* @param callable(\\Hyde\\Foundation\\HydeKernel): void $callback \/\nHyde::booted(callable(\\Hyde\\Foundation\\HydeKernel): void): void","destination":"the-hydekernel"},{"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\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. See the Post Author section for more details.\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:\nname: \"Mr. Hyde\"\nusername: mr_hyde\nwebsite: https:\/\/twitter.com\/HydeFramework\n\nWhen specifying an array you don't need all the sub-properties. The example just shows all the supported values.\nArray values here will override all the values in the authors config entry.\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\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\"\n\nSee posts\/introducing-images\nfor a detailed blog post with examples and schema information!\n{ .info }\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"},{"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.","destination":"compile-and-deploy"},{"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.\nUsing 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\nresponsive sidebar that is automatically generated based on your Markdown files. You can even customize the order,\nlabels, and even groups, of the sidebar items to suit your needs.\n\nAdditionally, if you have a _docs\/index.md file, the sidebar header will link to it, and an automatically generated\n\"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,\nsaving 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\nto keep in mind when creating blog posts 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.\nIf 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,\nand 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\nof 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,\nI 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 higher the priority the further down in the sidebar it will be.\nThe 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 Docs configuration file.\nSee the chapter in the customization page for more details.\nI personally think the config route is easier as it gives an instant overview, however the first way is nice as well.\n\nSidebar labels\n\nThe sidebar items are labelled with the label property. The default label is the filename of the file.\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 into categories. This is useful for creating a sidebar with a lot of items.\nThe Hyde docs for instance use this.\n\nThe feature is enabled automatically when one or more of your documentation pages have the navigation.group property set\nin the front matter, or when subdirectories are used. This will then switch to a slightly more compact sidebar layout with pages sorted into categories.\nAny pages without the group front matter will get put in the \"Other\" group.\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\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 sub-directories.\n\nFor example, putting a Markdown file in _docs\/getting-started\/, is equivalent to adding the same front matter seen above.\n\ninfo 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 overwrite each other.\n\ninfo Tip: When using subdirectory-based dropdowns, you can set their priority using the directory name as the array key.\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,\nincluding 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,\nfor example to specify a version like the Hyde docs does, you can specify the output directory in the Hyde configuration file.\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\".\nYou 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 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.\nLink items without an entry here will fall back to the default priority of 999, putting them last.\n\n'sidebar_order' => [\n'readme',\n'installation',\n'getting-started',\n]\n\nSee the chapter in the customization page for more details.\n\nAutomatic sidebar group labels\n\nWhen using the automatic sidebar grouping feature (based on subdirectories), the titles of the groups are generated from the directory names.\nIf these are not to your liking, for example if you need to use special characters, you can override them in the Docs configuration file.\nThe array key is the directory name, and the value is the label.\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\n\/\/ Filepath: config\/docs.php\n\n'sidebargrouplabels' => [\n'questions-and-answers' => 'Questions & Answers',\n],\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.\nYou can also disable the feature completely.\n\n'tableofcontents' => [\n'enabled' => true,\n'minheadinglevel' => 2,\n'maxheadinglevel' => 4,\n],\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.\nThis means that you can use the automatic directory-based grouping feature, but still have a \"flat\" output structure.\nNote 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\nThe HydeSearch plugin adds a search feature to documentation pages. It consists of two parts, a search index generator\nthat runs during the build command, and a frontend JavaScript plugin that adds the actual search widget.\n\ninfo Tip: The HydeSearch plugin is what powers the search feature on this site! Why not try it out?\n\nThe search feature is enabled by default. You can disable it by removing the documentationSearch from the Hyde Features config array.\n\n\/\/ filepath: config\/hyde.php\n'features' => [\nFeatures::documentationSearch(), \/\/ [tl! --]\n],\n\nUsing the search\n\nThe search works by generating a JSON search index which the JavaScript plugin loads asynchronously.\n\nTwo ways to access the search are added, one is a full page search screen that will be saved to docs\/search.html.\n\nThe second method is a button added to the documentation pages, similar to how Algolia DocSearch works.\nOpening it will open a modal with an integrated search screen. You can also open the dialogue using the keyboard shortcut \/.\n\ninfo The full page can be disabled by setting createsearchpage to false in the docs config.\n\nHiding pages from indexing\n\nIf you have a large page on your documentation site, like a changelog, you may want to hide it from the search index.\nYou can do this by adding the page identifier to the excludefromsearch array in the docs config, similar to how\nnavigation menu items are hidden. The page will still be accessible as normal but will be added to the search index JSON file.\n\n\/\/ filepath: config\/docs.php\n'excludefromsearch' => [\n'changelog',\n]\n\nLive search with the realtime compiler\n\nThe Realtime Compiler that powers the php hyde serve command will automatically generate a fresh search index each time the browser requests it.\n\nAutomatic \"Edit Page\" Button\n\nIntroduction\n\nHyde can automatically add links to documentation pages that take the user\nto a GitHub page (or similar) to edit the page. This makes it great for open-source projects\nlooking 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.\nHyde expects this to be a GitHub path, but it will probably work with other methods as well,\nif 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\nAs an example configuration, let's take a practical example of how HydePHP.com uses this feature.\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 both the documentation page footer.\nYou 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!\nJust 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"},{"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.\nBut 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.\nSome extra custom styles are made in the HydeFront package, which is pre-installed and bundled in the pre-configured Laravel Mix.\n\nTo get you started quickly, all the styles are already compiled and minified into _media\/app.css,\nwhich will be copied to the _site\/media\/app.css directory when you run php hyde build.\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 custom 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 webpack.mix.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. If you want to compile the assets for production, run npm run prod.\nYou can also run npm run watch to watch for changes in the source files and recompile the assets automatically.\n\nHow does it work?\n\nHyde uses Laravel Mix (which is a wrapper for Webpack) to compile the assets.\n\nWhen running the npm run dev\/prod command, the following happens:\n\n1. Laravel Mix will compile the resources\/assets\/app.css file into _media\/app.css using PostCSS with TailwindCSS and AutoPrefixer.\n2. Mix then copies the media folder into site\/media, this is so that they are automatically accessible to your site without having to rerun 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 Laravel Mix.\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"},{"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 blog posts 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"},{"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 which 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,\nthis 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 webpack.mix.js so Laravel Mix 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"},{"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 too by adding and editing the following in your resources\/app.css file, and then recompiling your site styles.\nThe code examples here use the Tailwind @apply directives, but you could also use border-color: something; just as well.\n\n\/* filepath resources\/app.css\n\n\/* Markdown Features *\/\n\n.prose blockquote.info {\n@apply border-blue-500;\n}\n\n.prose blockquote.success {\n@apply border-green-500;\n}\n\n.prose blockquote.warning {\n@apply border-amber-500;\n}\n\n.prose blockquote.danger {\n@apply border-red-600;\n}\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\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"},{"slug":"collections","title":"File-based Collections","content":"# File-based Collections\n\n## Introduction to Hyde Data Collections\n\nHyde provides DataCollections, a subset of Laravel Collections giving you\na 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\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\nLaravel 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\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 DataCollections 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.\n9. If the base source directory does not exist, it will be created for you.\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\\DataCollections::markdown(string $name);\n\\Hyde\\Support\\DataCollections::yaml(string $name);\n\\Hyde\\Support\\DataCollections::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, .yml\nJson ::json() stdClass OR array .json\n\n## Markdown Collections\n\n### Usage\n\n$collection = \\Hyde\\Support\\DataCollections::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\\DataCollections {\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\\DataCollections::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\\DataCollections {\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\nwarning Note that the Yaml file should start with --- to be parsed correctly.\n\n## Json Collections\n\n### Usage\n\n$collection = \\Hyde\\Support\\DataCollections::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\\DataCollections::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 DataCollections::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\nDataCollections::markdown('subdirectory_name')\n\nThis will return a Hyde DataCollections object, containing our Markdown files as MarkdownDocument objects. Here is a quick look at the object the facade returns:\n\n^ Hyde\\Support\\DataCollections {#651 \u25bc\n#items: array:3 [\u25bc\n\"testimonials\/1.md\" => 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\" => Hyde\\Markdown\\Models\\MarkdownDocument {#656 \u25b6}\n\"testimonials\/3.md\" => 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(DataCollections::markdown('testimonials') as $testimonial)\n\n{{ $testimonial->body }}\n{{ $testimonial->matter['author'] }}\n\n@endforeach","destination":"collections"},{"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 has support for adding authors in front matter, for example to\nautomatically add a link to your website or social media profiles.\nHowever, it's tedious to have to add those to each and every\npost you make, and keeping them updated is even harder.\n\nYou can predefine authors in the Hyde config.\nWhen writing posts, just specify the username in the front matter,\nand the rest of the data will be pulled from a matching entry.\n\n#### Example\n\n\/\/ torchlight! {\"lineNumbers\": false}\n'authors' => [\nAuthor::create(\nusername: 'mr_hyde', \/\/ Required username\nname: 'Mr. Hyde', \/\/ Optional display name\nwebsite: 'https:\/\/hydephp.com' \/\/ Optional website URL\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\n\nBut you only have to specify the username:\n\nauthor: mr_hyde\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[\/\/]: # ()\n[\/\/]: # (### Head and script HTML hooks)\n\n[\/\/]: # ()\n[\/\/]: # (>info 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\n[\/\/]: # ()\n[\/\/]: # (While 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,)\n\n[\/\/]: # (you 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\n[\/\/]: # ()\n[\/\/]: # (To 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).)\n\n[\/\/]: # (The HTML will be added to the ` section, or just before the closing ` tag, respectively.)\n\n[\/\/]: # (Note 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[\/\/]: # ()\n[\/\/]: # (\n[\/\/]: # (\/\/ filepath: config\/hyde.php)\n\n[\/\/]: # ('head' => '',)\n\n[\/\/]: # ('scripts' => '',)\n\n[\/\/]: # (\n[\/\/]: # ()\n[\/\/]: # (\n[\/\/]: # (# filepath: hyde.yml)\n\n[\/\/]: # (hyde:)\n\n[\/\/]: # ( head: \"\")\n\n[\/\/]: # ( scripts: \"\")\n\n[\/\/]: # (\n[\/\/]: # ()\n[\/\/]: # (You can of course also add multiple lines of HTML:)\n\n[\/\/]: # ()\n[\/\/]: # (\n[\/\/]: # (\/\/ filepath: config\/hyde.php)\n\n[\/\/]: # ('head' => )\n\n[\/\/]: # ( )\n\n[\/\/]: # (HTML,)\n\n[\/\/]: # ([\/\/]: # ()\n[\/\/]: # (\n[\/\/]: # (# filepath: hyde.yml)\n\n[\/\/]: # ()\n[\/\/]: # (hyde:)\n\n[\/\/]: # ( head: |)\n\n[\/\/]: # ( )\n\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\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, can use the route key, or just the page identifier of the page.\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### hydefrontversion and hydefrontcdn_url\n\nThese options allow you to specify the HydeFront version and CDN URL when loading app.css from the CDN.\n\nOnly change these if you know what you're doing as some versions may be incompatible with your Hyde version.\n\n\/\/ filepath config\/hyde.php\nuse \\Hyde\\Framework\\Services\\AssetService;\n\n'hydefrontversion' => AssetService::HYDEFRONTVERSION,\n'hydefrontcdnurl' => AssetService::HYDEFRONTCDNURL,\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\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\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\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"},{"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 DataCollections, 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\\DataCollections;\n\n\/\/ Gets all Markdown files in resources\/collections\/$name directory\nDataCollections::markdown(string $name);\n\n\/\/ Gets all YAML files in resources\/collections\/$name directory\nDataCollections::yaml(string $name);\n\n\/\/ Gets all JSON files in resources\/collections\/$name directory\nDataCollections::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 still be rendered to HTML.\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 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 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\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\n\/\/ torchlight! {\"lineNumbers\": false}\nLatest Posts{{-- [tl! remove] --}}\n{{ $page->matter('title') ?? $title }} {{-- [tl! add] --}}\n\nto that new view, but for this example I'm going to update the posts view.\n\n\/\/ filepath _pages\/posts.blade.php\n\/\/ torchlight! {\"lineNumbers\": false}\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"},{"slug":"navigation","title":"Navigation Menus","content":"Navigation Menus\n\nIntroduction\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\nThere are two types of navigation menus in Hyde:\n\nPrimary Navigation Menu**: This is the main navigation menu that appears on most pages of your site.\nDocumentation Sidebar**: This is a sidebar that appears on documentation pages and contains links to other documentation pages.\n\nHydePHP automatically generates all of these menus for you based on the content of your project,\nand does its best to automatically configure them in the way that you most likely want them to be.\n\nOf course, this won't always be perfect, so thankfully Hyde makes it a breeze to customize these menus to your liking.\nKeep on reading to learn how! To learn even more about the sidebars, visit the Documentation Pages documentation.\n\nQuick primer on the internals\n\nIt may be beneficial to understand the internal workings of the navigation menus to take full advantage of the options.\n\nIn short, both navigation menu types extend the same class (meaning they share the same base code), this means that the way\nthey are configured is very similar, making the documentation here applicable to both types of menus.\n\nSee the Digging Deeper section of this page if you want the full scoop on the internals!\n\nPrimer on priorities\n\nAll navigation menu items have an internal priority value that determines their order in the navigation.\nLower values mean that the item will be higher up in the menu. The default for pages is 999 which puts them last.\nHowever, some pages are autoconfigured to have a lower priority, for example, the index page defaults to a priority of 0,\n\nWhat to customize?\n\nHere is a quick overview of what you might want to customize in your navigation menus:\n\n- Navigation menu item labels - the text that appears in the menu links\n- Navigation menu item priority - control the order in which the links appear\n- Navigation menu item visibility - control if pages may show up in the menus\n- Navigation menu item grouping - group pages together in dropdowns\n\nHow and where to customize?\n\nHyde provides a few different ways to customize the navigation menus, depending on what you prefer.\n\nSpecifying the data in the front matter will override any dynamically inferred or config-defined priority.\nWhile this is useful for one-offs, it can make it harder to reorder items later on as you can't see the whole picture at once.\nIt's up to you which method you prefer to use.\n\nTo customize how a page is represented in navigation, you can either set the navigation front matter data in the page's markdown file,\nor configure it in the config file. Main navigation items are in the hyde config file, while documentation sidebar items are in the docs config file.\nGeneral options for the entire navigation menus are also available in the hyde and docs config files.\n\nNow that you know the basics, let's dive into the details of how to customize the navigation menus!\n\nFront Matter Configuration\n\nThe front matter options allow you to customize the navigation menus on a per-page basis.\nHere is a quick reference of the available options. The full documentation of each option is below.\nYou don't need to specify all the keys, only the ones you want to customize.\n\nnavigation:\nlabel: string # The text to display\npriority: int # Order is also supported\nhidden: bool # Visible is also supported (but obviously invert the value)\ngroup: string # Category is also supported\n\nlabel\n\nThe label option allows you to customize the text that appears in the navigation menu for the page.\n\nnavigation:\nlabel: \"My Custom Label\"\n\npriority\n\nThe priority option allows you to control the order in which the page appears in the navigation menu. You can also use order instead of priority.\n\nnavigation:\npriority: 10\n\nhidden\n\nThe hidden option allows you to control if the page appears in the navigation menu. You can also use visible instead of hidden, but obviously invert the value.\n\nnavigation:\nhidden: true\n\ngroup\n\nThe group option has a slightly different meaning depending on the type of navigation menu.\nFor the primary navigation menu, it allows you to group pages together in dropdowns.\nFor the sidebar, it allows you to group pages together in the sidebar under a common heading.\nYou can also use category instead of group.\n\nnavigation:\ngroup: \"My Group\"\n\nConfig File Configuration\n\nNext up, let's look at how to customize the navigation menus using the config files.\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\n- To customize the sidebar, use the setting sidebar_order in the docs.php config.\n- When customizing the sidebar, can use the route key, or just the page identifier of the page.\n\nChanging the priorities\n\nThe navigation.order and sidebar_order settings allow you to customize the order of the pages in the navigation menus.\n\nBasic syntax for changing the priorities\n\nThe cleanest way is to use the list-style syntax where each item will get the priority calculated according to its position in the list, plus an offset of 500.\nThe 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\n'navigation' => [\n'order' => [\n'home', \/\/ Gets priority 500\n'about', \/\/ Gets priority 501\n'contact', \/\/ Gets priority 502\n]\n]\n\n\/\/ filepath: config\/docs.php\n\n'sidebar_order' => [\n'readme', \/\/ Gets priority 500\n'installation', \/\/ Gets priority 501\n'getting-started', \/\/ Gets priority 502\n]\n\nExplicit syntax for changing the priorities\n\nYou can also specify explicit priorities by adding a value to the array key:\n\n\/\/ filepath: config\/hyde.php\n\n'navigation' => [\n'order' => [\n'home' => 10, \/\/ Gets priority 10\n'about' => 15, \/\/ Gets priority 15\n'contact' => 20, \/\/ Gets priority 20\n]\n]\n\n\/\/ filepath: config\/docs.php\n\n'sidebar_order' => [\n'readme' => 10, \/\/ Gets priority 10\n'installation' => 15, \/\/ Gets priority 15\n'getting-started' => 20, \/\/ Gets priority 20\n]\n\nYou can of course also combine these methods if you want:\n\n\/\/ filepath: Applicable to both\n[\n'readme' => 10, \/\/ Gets priority 10\n'installation', \/\/ Gets priority 500\n'getting-started', \/\/ Gets priority 501\n]\n\nChanging the menu item labels\n\nHyde makes a few attempts to find a suitable label for the navigation menu items to automatically create helpful titles.\n\nFrom the Hyde config you can override the label of navigation links using the by mapping the route key to the desired title.\nThis is not yet supported for the sidebar, but will be in the future.\n\n\/\/ filepath config\/hyde.php\n'navigation' => [\n'labels' => [\n'index' => 'Start',\n'docs\/index' => 'Documentation',\n]\n]\n\nExcluding Items (Blacklist)\n\nSometimes, especially if you have a lot of pages, you may want to prevent links from showing up in the main navigation menu.\nTo remove items from being automatically added, simply add the page's route key to the blacklist.\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 similar to how we add Authors. Simply add a NavItem model to the navigation.custom array.\n\nWhen linking to an external site, you should use the NavItem::forLink() method facade. The first two arguments are the\ndestination and label, both required. The third argument is the priority, which is optional, and defaults to 500.\n\n\/\/ filepath config\/hyde.php\nuse Hyde\\Framework\\Features\\Navigation\\NavItem;\n\n'navigation' => [\n'custom' => [\nNavItem::forLink('https:\/\/github.com\/hydephp\/hyde', 'GitHub', 200),\n]\n]\n\nSimplified, this will then be rendered as follows:\n\nGitHub\n\nConfigure subdirectory handling\n\nWithin the Hyde config you can configure how subdirectories should be displayed in the menu.\n\n\/\/ filepath config\/hyde.php\n'navigation' => [\n'subdirectories' => 'dropdown'\n]\n\nDropdown means that pages in subdirectories will be displayed in a dropdown menu,\nwhile flat means that pages in subdirectories will be displayed as individual items in the menu.\nHidden means that pages in subdirectories will not be displayed in the menu at all.\n\nAutomatic menu groups\n\nHydePHP has a neat feature to automatically place pages in dropdowns based on subdirectories.\n\nAutomatic navigation menu dropdowns\n\nFor pages that can be in the main site menu, this feature needs to be enabled in the hyde.php config file.\n\n\/\/ filepath config\/hyde.php\n\n'navigation' => [\n'subdirectories' => '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\nAutomatic documentation sidebar grouping\n\nThis feature works similarly to the automatic navigation menu dropdowns, but instead places the sidebar items in named groups.\nThis feature is enabled by default, so you only need to place your pages in subdirectories to have them grouped.\n\nFor example: _docs\/getting-started\/installation.md will be placed in a group called \"Getting Started\".\n\ninfo Tip: When using subdirectory-based dropdowns, you can set their priority using the directory name as the array key.\n\nDigging Deeper into the internals\n\nWhile not required to know, you may find it interesting to learn more about how the navigation is handled internally.\nThe best way to learn about this is to look at the source code, so here is a high-level overview with details on where to look in the source code.\n\nThe main navigation menu is the NavigationMenu class, and the documentation sidebar is the DocumentationSidebar class.\nBoth extend the same BaseNavigationMenu class:\n\nuse Hyde\\Framework\\Features\\Navigation\\NavigationMenu;\nuse Hyde\\Framework\\Features\\Navigation\\DocumentationSidebar;\nuse Hyde\\Framework\\Features\\Navigation\\BaseNavigationMenu;\n\nWithin the BaseNavigationMenu class, you will find the main logic for how the menus are generated,\nwhile the child implementations contain the extra logic tailored for their specific use cases.\n\nAll the navigation menus store the menu items in their $items array containing instances of the NavItem class.\n\nThe NavItem class is a simple class that contains the label and URL of the menu item and is used to represent each item in the menu.\nDropdowns are represented by DropdownNavItem instances, which extend the NavItem class and contain an array of additional NavItem instances.\n\nuse Hyde\\Framework\\Features\\Navigation\\NavItem;\nuse Hyde\\Framework\\Features\\Navigation\\DropdownNavItem;","destination":"navigation"},{"slug":"troubleshooting","title":"Troubleshooting","content":"# Troubleshooting\n\nSince Hyde has a lot of \"magic\" features which depend on some base assumptions,\nthere might be some \"gotchas\" you might run into. Here are some I can think of,\ndid 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 dev\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\nDocumentation table of contents is weird The table of contents markup is generated by the League\/CommonMark extension Make sure that your Markdown headings make sense\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"},{"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\nMethods\n\nWhich method?\n\nDepending on how you installed Hyde, there are a few different ways to update it.\n\nWe have a few methods documented here. The Git method is recommended as it is the easiest and safest way to\nupdate your project. If you are not using Git, you can still update your project using any of the manual methods.\n\nRegardless of the method you use, make sure you follow the post-update instructions at the end.\n\nUpdating just the Framework\n\nIf you just want to update the framework patch version, you can do so by running the following command:\n\ncomposer update hyde\/framework\n\nWhile the same can still be done for minor versions, it's best to also update your project scaffolding and resources to\nensure that everything is up to date, for which you should use the methods below.\n\nUsing Git\n\nFirst, make sure you have a remote set up for the base project repository.\n\ngit remote add upstream https:\/\/github.com\/hydephp\/hyde.git\n\nThen pull the latest release from the upstream repository.\n\ngit pull upstream master\n\nAfter this, you should update your composer dependencies:\n\ncomposer update\n\nNext, follow the post-update instructions.\n\nManual Update\n\nIf you are not using Git, you can still update your project. This is a bit more involved, but it is still possible.\n\n1. First, you will need to download the latest release archive from the releases page.\n2. Then extract the archive, and copy the contents into your project directory.\n\nSince this may overwrite modified files, it may be safer to use the hard update method.\n\nHard Update\n\nIf you are having trouble updating your project, you can try a hard update. In short, this approach consists of creating\na brand new project and copying over only your source and resource files. If you do not want to use Git, this may be\nthe safest option as you won't be overriding any of your existing files.\n\nIf you have changed any other files, for example in the App directory, you will need to update those files manually as well.\nThe same goes if you have created any custom Blade components or have modified Hyde ones.\n\nHere is an example CLI workflow, but you can do the same using a graphical file manager.\n\nmv my-project my-project-old\ncomposer create-project hyde\/hyde my-project\n\ncp -r my-old-project\/pages my-project\/content\/pages\ncp -r my-old-project\/posts my-project\/content\/posts\ncp -r my-old-project\/media my-project\/content\/media\ncp -r my-old-project\/docs my-project\/content\/docs\ncp -r my-old-project\/config my-project\/config\n\nNext, follow the post-update instructions. After verifying that everything is working, you can delete the old project directory.\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\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"},{"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"},{"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\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'port' => env('SERVER_PORT', 8080),\n'host' => env('SERVER_HOST', 'localhost'),\n'save_preview' => 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'dashboard' => [\n'enabled' => env('SERVER_DASHBOARD', true),\n'interactive' => true,\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\nThe live editor was added in Hyde Realtime Compiler Server v3.2.0 (December 2023)\n\nSource code\n\nGitHub**: hydephp\/realtime-compiler\nPackagist**: hydephp\/realtime-compiler","destination":"realtime-compiler"},{"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"},{"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,\nindented 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 Laravel Mix 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"},{"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\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde help\n\nYou can also always add --help to a command to show detailed usage information.\n\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde build [--run-dev] [--run-prod] [--run-prettier] [--pretty-urls] [--no-api]\n\nBuild the static site\n\n#### Options\n\n\n\n--run-dev Run the NPM dev script after build\n--run-prod Run the NPM prod script after build\n--run-prettier Format the output using NPM Prettier\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\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde serve [--host [HOST]] [--port [PORT]]\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\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde build:rss\n\nGenerate the RSS feed\n\n## Generate the docs\/search.json file\n\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde build:search\n\nGenerate the docs\/search.json file\n\n## Generate the sitemap.xml file\n\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde build:sitemap\n\nGenerate the sitemap.xml file\n\n## Scaffold a new Markdown, Blade, or documentation page file\n\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde publish:configs\n\nPublish the default configuration files\n\n## Publish one of the default homepages as index.blade.php.\n\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde publish:views []\n\nPublish the hyde components for customization. Note that existing files will be overwritten.\n\n#### Arguments\n\n\n\ncategory The category to publish\n\n## Display all Registered Routes.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde route:list\n\nDisplay all registered routes.\n\n## Publish any publishable assets from vendor packages\n\n\/\/ torchlight! {\"lineNumbers\": false}\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"},{"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 Laravel Mix 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 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 experimental 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 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"},{"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 experimental 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"},{"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\n\/\/ torchlight! {\"lineNumbers\": false}\ncomposer create-project hyde\/hyde\n\nRequirements\n\nHyde is based on Laravel 10\nwhich requires a minimum PHP version of 8.1.\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 Laravel Mix 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"},{"slug":"configuration","title":"Configuration","content":"Redirecting you to customization","destination":"configuration"},{"slug":"directory-structure","title":"Directory Structure","content":"Redirecting you to architecture-concepts#directory-structure","destination":"directory-structure"},{"slug":"getting-started","title":"Getting Started","content":"Redirecting you to quickstart","destination":"getting-started"},{"slug":"installation","title":"Installation","content":"Redirecting you to quickstart","destination":"installation"}]
\ No newline at end of file
+[{"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.1 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":""},{"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"},{"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"},{"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"},{"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"},{"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"},{"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"},{"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 of course, also supply extra attributes like classes:\n\nHome","destination":"automatic-routing"},{"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"},{"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\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"},{"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"},{"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\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::version(): string\n\n__construct()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\n$hyde = new HydeKernel(string $basePath): void\n\nfeatures()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::features(): Hyde\\Facades\\Features\n\nhasFeature()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::hasFeature(string $feature): bool\n\ntoArray()\n\nGet the instance as an array.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::toArray(): array\n\nfiles()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::files(): \\Hyde\\Foundation\\Kernel\\FileCollection\n\npages()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::pages(): \\Hyde\\Foundation\\Kernel\\PageCollection\n\nroutes()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::routes(): \\Hyde\\Foundation\\Kernel\\RouteCollection\n\nmakeTitle()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::makeTitle(string $value): string\n\nnormalizeNewlines()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::normalizeNewlines(string $string): string\n\nstripNewlines()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::stripNewlines(string $string): string\n\ntrimSlashes()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::trimSlashes(string $string): string\n\nmarkdown()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::markdown(string $text, bool $normalizeIndentation): Illuminate\\Support\\HtmlString\n\nformatLink()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::formatLink(string $destination): string\n\nrelativeLink()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::relativeLink(string $destination): string\n\nmediaLink()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::mediaLink(string $destination, bool $validate): string\n\nasset()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::asset(string $name, bool $preferQualifiedUrl): string\n\nurl()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::url(string $path): string\n\nhasSiteUrl()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::hasSiteUrl(): bool\n\nfilesystem()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::filesystem(): Hyde\\Foundation\\Kernel\\Filesystem\n\npath()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::path(string $path): string\n\nvendorPath()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::vendorPath(string $path, string $package): string\n\nmediaPath()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::mediaPath(string $path): string\n\nsitePath()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::sitePath(string $path): string\n\nsiteMediaPath()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::siteMediaPath(string $path): string\n\npathToAbsolute()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::pathToAbsolute(array|string $path): array|string\n\npathToRelative()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::pathToRelative(string $path): string\n\ngetInstance()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getInstance(): Hyde\\Foundation\\HydeKernel\n\nsetInstance()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::setInstance(Hyde\\Foundation\\HydeKernel $instance): void\n\ngetBasePath()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getBasePath(): string\n\nsetBasePath()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::setBasePath(string $basePath): void\n\ngetSourceRoot()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getSourceRoot(): string\n\nsetSourceRoot()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::setSourceRoot(string $sourceRoot): void\n\ngetOutputDirectory()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getOutputDirectory(): string\n\nsetOutputDirectory()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::setOutputDirectory(string $outputDirectory): void\n\ngetMediaDirectory()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getMediaDirectory(): string\n\nsetMediaDirectory()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::setMediaDirectory(string $mediaDirectory): void\n\ngetMediaOutputDirectory()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::registerExtension(class-string<\\Hyde\\Foundation\\Concerns\\HydeExtension> $extension): void\n\ngetExtension()\n\nGet the singleton instance of the specified extension.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getExtension(class-string<T> $extension): T\n\nhasExtension()\n\nDetermine if the specified extension is registered.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::hasExtension(class-string<\\Hyde\\Foundation\\Concerns\\HydeExtension> $extension): bool\n\ngetExtensions()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getExtensions(): array\n\ngetRegisteredExtensions()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getRegisteredExtensions(): array>\n\ngetRegisteredPageClasses()\n\nNo description provided.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::getRegisteredPageClasses(): array>\n\nshareViewData()\n\nShare data for the page being rendered.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::shareViewData(Hyde\\Pages\\Concerns\\HydePage $page): void\n\ncurrentRouteKey()\n\nGet the route key for the page being rendered.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::currentRouteKey(): string\n\ncurrentRoute()\n\nGet the route for the page being rendered.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::currentRoute(): Hyde\\Support\\Models\\Route\n\ncurrentPage()\n\nGet the page being rendered.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::currentPage(): Hyde\\Pages\\Concerns\\HydePage\n\nisBooted()\n\nDetermine if the Kernel has booted.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nHyde::isBooted(): bool\n\nboot()\n\nBoot the Hyde Kernel and run the Auto-Discovery Process.\n\n\/\/ torchlight! {\"lineNumbers\": false}\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\/\/ torchlight! {\"lineNumbers\": false}\n\/* @param callable(\\Hyde\\Foundation\\HydeKernel): void $callback \/\nHyde::booting(callable(\\Hyde\\Foundation\\HydeKernel): void): void\n\nbooted()\n\nRegister a new "booted" 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\/\/ torchlight! {\"lineNumbers\": false}\n\/* @param callable(\\Hyde\\Foundation\\HydeKernel): void $callback \/\nHyde::booted(callable(\\Hyde\\Foundation\\HydeKernel): void): void","destination":"the-hydekernel"},{"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\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. See the Post Author section for more details.\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:\nname: \"Mr. Hyde\"\nusername: mr_hyde\nwebsite: https:\/\/twitter.com\/HydeFramework\n\nWhen specifying an array you don't need all the sub-properties. The example just shows all the supported values.\nArray values here will override all the values in the authors config entry.\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\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\"\n\nSee posts\/introducing-images\nfor a detailed blog post with examples and schema information!\n{ .info }\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"},{"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.","destination":"compile-and-deploy"},{"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.\nUsing 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\nresponsive sidebar that is automatically generated based on your Markdown files. You can even customize the order,\nlabels, and even groups, of the sidebar items to suit your needs.\n\nAdditionally, if you have a _docs\/index.md file, the sidebar header will link to it, and an automatically generated\n\"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,\nsaving 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\nto keep in mind when creating blog posts 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.\nIf 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,\nand 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\nof 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,\nI 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 higher the priority the further down in the sidebar it will be.\nThe 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 Docs configuration file.\nSee the chapter in the customization page for more details.\nI personally think the config route is easier as it gives an instant overview, however the first way is nice as well.\n\nSidebar labels\n\nThe sidebar items are labelled with the label property. The default label is the filename of the file.\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 into categories. This is useful for creating a sidebar with a lot of items.\nThe Hyde docs for instance use this.\n\nThe feature is enabled automatically when one or more of your documentation pages have the navigation.group property set\nin the front matter, or when subdirectories are used. This will then switch to a slightly more compact sidebar layout with pages sorted into categories.\nAny pages without the group front matter will get put in the \"Other\" group.\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\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 sub-directories.\n\nFor example, putting a Markdown file in _docs\/getting-started\/, is equivalent to adding the same front matter seen above.\n\ninfo 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 overwrite each other.\n\ninfo Tip: When using subdirectory-based dropdowns, you can set their priority using the directory name as the array key.\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,\nincluding 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,\nfor example to specify a version like the Hyde docs does, you can specify the output directory in the Hyde configuration file.\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\".\nYou 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 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.\nLink items without an entry here will fall back to the default priority of 999, putting them last.\n\n'sidebar_order' => [\n'readme',\n'installation',\n'getting-started',\n]\n\nSee the chapter in the customization page for more details.\n\nAutomatic sidebar group labels\n\nWhen using the automatic sidebar grouping feature (based on subdirectories), the titles of the groups are generated from the directory names.\nIf these are not to your liking, for example if you need to use special characters, you can override them in the Docs configuration file.\nThe array key is the directory name, and the value is the label.\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\n\/\/ Filepath: config\/docs.php\n\n'sidebargrouplabels' => [\n'questions-and-answers' => 'Questions & Answers',\n],\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.\nYou can also disable the feature completely.\n\n'tableofcontents' => [\n'enabled' => true,\n'minheadinglevel' => 2,\n'maxheadinglevel' => 4,\n],\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.\nThis means that you can use the automatic directory-based grouping feature, but still have a \"flat\" output structure.\nNote 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\nThe HydeSearch plugin adds a search feature to documentation pages. It consists of two parts, a search index generator\nthat runs during the build command, and a frontend JavaScript plugin that adds the actual search widget.\n\ninfo Tip: The HydeSearch plugin is what powers the search feature on this site! Why not try it out?\n\nThe search feature is enabled by default. You can disable it by removing the documentationSearch from the Hyde Features config array.\n\n\/\/ filepath: config\/hyde.php\n'features' => [\nFeatures::documentationSearch(), \/\/ [tl! --]\n],\n\nUsing the search\n\nThe search works by generating a JSON search index which the JavaScript plugin loads asynchronously.\n\nTwo ways to access the search are added, one is a full page search screen that will be saved to docs\/search.html.\n\nThe second method is a button added to the documentation pages, similar to how Algolia DocSearch works.\nOpening it will open a modal with an integrated search screen. You can also open the dialogue using the keyboard shortcut \/.\n\ninfo The full page can be disabled by setting createsearchpage to false in the docs config.\n\nHiding pages from indexing\n\nIf you have a large page on your documentation site, like a changelog, you may want to hide it from the search index.\nYou can do this by adding the page identifier to the excludefromsearch array in the docs config, similar to how\nnavigation menu items are hidden. The page will still be accessible as normal but will be added to the search index JSON file.\n\n\/\/ filepath: config\/docs.php\n'excludefromsearch' => [\n'changelog',\n]\n\nLive search with the realtime compiler\n\nThe Realtime Compiler that powers the php hyde serve command will automatically generate a fresh search index each time the browser requests it.\n\nAutomatic \"Edit Page\" Button\n\nIntroduction\n\nHyde can automatically add links to documentation pages that take the user\nto a GitHub page (or similar) to edit the page. This makes it great for open-source projects\nlooking 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.\nHyde expects this to be a GitHub path, but it will probably work with other methods as well,\nif 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\nAs an example configuration, let's take a practical example of how HydePHP.com uses this feature.\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 both the documentation page footer.\nYou 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!\nJust 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"},{"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.\nBut 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.\nSome extra custom styles are made in the HydeFront package, which is pre-installed and bundled in the pre-configured Laravel Mix.\n\nTo get you started quickly, all the styles are already compiled and minified into _media\/app.css,\nwhich will be copied to the _site\/media\/app.css directory when you run php hyde build.\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 custom 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 webpack.mix.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. If you want to compile the assets for production, run npm run prod.\nYou can also run npm run watch to watch for changes in the source files and recompile the assets automatically.\n\nHow does it work?\n\nHyde uses Laravel Mix (which is a wrapper for Webpack) to compile the assets.\n\nWhen running the npm run dev\/prod command, the following happens:\n\n1. Laravel Mix will compile the resources\/assets\/app.css file into _media\/app.css using PostCSS with TailwindCSS and AutoPrefixer.\n2. Mix then copies the media folder into site\/media, this is so that they are automatically accessible to your site without having to rerun 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 Laravel Mix.\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"},{"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 blog posts 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"},{"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 which 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,\nthis 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 webpack.mix.js so Laravel Mix 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"},{"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 too by adding and editing the following in your resources\/app.css file, and then recompiling your site styles.\nThe code examples here use the Tailwind @apply directives, but you could also use border-color: something; just as well.\n\n\/* filepath resources\/app.css\n\n\/* Markdown Features *\/\n\n.prose blockquote.info {\n@apply border-blue-500;\n}\n\n.prose blockquote.success {\n@apply border-green-500;\n}\n\n.prose blockquote.warning {\n@apply border-amber-500;\n}\n\n.prose blockquote.danger {\n@apply border-red-600;\n}\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\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"},{"slug":"collections","title":"File-based Collections","content":"# File-based Collections\n\n## Introduction to Hyde Data Collections\n\nHyde provides DataCollections, 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 DataCollections 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.\n9. If the base source directory does not exist, it will be created for you.\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\\DataCollections::markdown(string $name);\n\\Hyde\\Support\\DataCollections::yaml(string $name);\n\\Hyde\\Support\\DataCollections::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, .yml\nJson ::json() stdClass OR array .json\n\n## Markdown Collections\n\n### Usage\n\n$collection = \\Hyde\\Support\\DataCollections::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\\DataCollections {\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\\DataCollections::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\\DataCollections {\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\\DataCollections::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\\DataCollections::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 DataCollections::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\nDataCollections::markdown('subdirectory_name')\n\nThis will return a Hyde DataCollections object, containing our Markdown files as MarkdownDocument objects. Here is a quick look at the object the facade returns:\n\n^ Hyde\\Support\\DataCollections {#651 \u25bc\n#items: array:3 [\u25bc\n\"testimonials\/1.md\" => 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\" => Hyde\\Markdown\\Models\\MarkdownDocument {#656 \u25b6}\n\"testimonials\/3.md\" => 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(DataCollections::markdown('testimonials') as $testimonial)\n\n{{ $testimonial->body }}\n{{ $testimonial->matter['author'] }}\n\n@endforeach","destination":"collections"},{"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 has support for adding authors in front matter, for example to\nautomatically add a link to your website or social media profiles.\nHowever, it's tedious to have to add those to each and every\npost you make, and keeping them updated is even harder.\n\nYou can predefine authors in the Hyde config.\nWhen writing posts, just specify the username in the front matter,\nand the rest of the data will be pulled from a matching entry.\n\n#### Example\n\n\/\/ torchlight! {\"lineNumbers\": false}\n'authors' => [\nAuthor::create(\nusername: 'mr_hyde', \/\/ Required username\nname: 'Mr. Hyde', \/\/ Optional display name\nwebsite: 'https:\/\/hydephp.com' \/\/ Optional website URL\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\n\nBut you only have to specify the username:\n\nauthor: mr_hyde\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[\/\/]: # ()\n[\/\/]: # (### Head and script HTML hooks)\n\n[\/\/]: # ()\n[\/\/]: # (>info 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\n[\/\/]: # ()\n[\/\/]: # (While 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,)\n\n[\/\/]: # (you 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\n[\/\/]: # ()\n[\/\/]: # (To 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).)\n\n[\/\/]: # (The HTML will be added to the ` section, or just before the closing ` tag, respectively.)\n\n[\/\/]: # (Note 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[\/\/]: # ()\n[\/\/]: # (\n[\/\/]: # (\/\/ filepath: config\/hyde.php)\n\n[\/\/]: # ('head' => '',)\n\n[\/\/]: # ('scripts' => '',)\n\n[\/\/]: # (\n[\/\/]: # ()\n[\/\/]: # (\n[\/\/]: # (# filepath: hyde.yml)\n\n[\/\/]: # (hyde:)\n\n[\/\/]: # ( head: \"\")\n\n[\/\/]: # ( scripts: \"\")\n\n[\/\/]: # (\n[\/\/]: # ()\n[\/\/]: # (You can of course also add multiple lines of HTML:)\n\n[\/\/]: # ()\n[\/\/]: # (\n[\/\/]: # (\/\/ filepath: config\/hyde.php)\n\n[\/\/]: # ('head' => )\n\n[\/\/]: # ( )\n\n[\/\/]: # (HTML,)\n\n[\/\/]: # ([\/\/]: # ()\n[\/\/]: # (\n[\/\/]: # (# filepath: hyde.yml)\n\n[\/\/]: # ()\n[\/\/]: # (hyde:)\n\n[\/\/]: # ( head: |)\n\n[\/\/]: # ( )\n\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\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, can use the route key, or just the page identifier of the page.\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### hydefrontversion and hydefrontcdn_url\n\nThese options allow you to specify the HydeFront version and CDN URL when loading app.css from the CDN.\n\nOnly change these if you know what you're doing as some versions may be incompatible with your Hyde version.\n\n\/\/ filepath config\/hyde.php\nuse \\Hyde\\Framework\\Services\\AssetService;\n\n'hydefrontversion' => AssetService::HYDEFRONTVERSION,\n'hydefrontcdnurl' => AssetService::HYDEFRONTCDNURL,\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\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\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\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"},{"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 DataCollections, 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\\DataCollections;\n\n\/\/ Gets all Markdown files in resources\/collections\/$name directory\nDataCollections::markdown(string $name);\n\n\/\/ Gets all YAML files in resources\/collections\/$name directory\nDataCollections::yaml(string $name);\n\n\/\/ Gets all JSON files in resources\/collections\/$name directory\nDataCollections::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 still be rendered to HTML.\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 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 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\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\n\/\/ torchlight! {\"lineNumbers\": false}\nLatest Posts{{-- [tl! remove] --}}\n{{ $page->matter('title') ?? $title }} {{-- [tl! add] --}}\n\nto that new view, but for this example I'm going to update the posts view.\n\n\/\/ filepath _pages\/posts.blade.php\n\/\/ torchlight! {\"lineNumbers\": false}\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"},{"slug":"navigation","title":"Navigation Menus","content":"Navigation Menus\n\nIntroduction\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\nThere are two types of navigation menus in Hyde:\n\nPrimary Navigation Menu**: This is the main navigation menu that appears on most pages of your site.\nDocumentation Sidebar**: This is a sidebar that appears on documentation pages and contains links to other documentation pages.\n\nHydePHP automatically generates all of these menus for you based on the content of your project,\nand does its best to automatically configure them in the way that you most likely want them to be.\n\nOf course, this won't always be perfect, so thankfully Hyde makes it a breeze to customize these menus to your liking.\nKeep on reading to learn how! To learn even more about the sidebars, visit the Documentation Pages documentation.\n\nQuick primer on the internals\n\nIt may be beneficial to understand the internal workings of the navigation menus to take full advantage of the options.\n\nIn short, both navigation menu types extend the same class (meaning they share the same base code), this means that the way\nthey are configured is very similar, making the documentation here applicable to both types of menus.\n\nSee the Digging Deeper section of this page if you want the full scoop on the internals!\n\nPrimer on priorities\n\nAll navigation menu items have an internal priority value that determines their order in the navigation.\nLower values mean that the item will be higher up in the menu. The default for pages is 999 which puts them last.\nHowever, some pages are autoconfigured to have a lower priority, for example, the index page defaults to a priority of 0.\n\nWhat to customize?\n\nHere is a quick overview of what you might want to customize in your navigation menus:\n\n- Navigation menu item labels - the text that appears in the menu links\n- Navigation menu item priority - control the order in which the links appear\n- Navigation menu item visibility - control if pages may show up in the menus\n- Navigation menu item grouping - group pages together in dropdowns\n\nHow and where to customize?\n\nHyde provides a few different ways to customize the navigation menus, depending on what you prefer.\n\nSpecifying the data in the front matter will override any dynamically inferred or config-defined priority.\nWhile this is useful for one-offs, it can make it harder to reorder items later on as you can't see the whole picture at once.\nIt's up to you which method you prefer to use.\n\nTo customize how a page is represented in navigation, you can either set the navigation front matter data in the page's markdown file,\nor configure it in the config file. Main navigation items are in the hyde config file, while documentation sidebar items are in the docs config file.\nGeneral options for the entire navigation menus are also available in the hyde and docs config files.\n\nNow that you know the basics, let's dive into the details of how to customize the navigation menus!\n\nFront Matter Configuration\n\nThe front matter options allow you to customize the navigation menus on a per-page basis.\nHere is a quick reference of the available options. The full documentation of each option is below.\nYou don't need to specify all the keys, only the ones you want to customize.\n\nnavigation:\nlabel: string # The text to display\npriority: int # Order is also supported\nhidden: bool # Visible is also supported (but obviously invert the value)\ngroup: string # Category is also supported\n\nlabel\n\nThe label option allows you to customize the text that appears in the navigation menu for the page.\n\nnavigation:\nlabel: \"My Custom Label\"\n\npriority\n\nThe priority option allows you to control the order in which the page appears in the navigation menu. You can also use order instead of priority.\n\nnavigation:\npriority: 10\n\nhidden\n\nThe hidden option allows you to control if the page appears in the navigation menu. You can also use visible instead of hidden, but obviously invert the value.\n\nnavigation:\nhidden: true\n\ngroup\n\nThe group option has a slightly different meaning depending on the type of navigation menu.\nFor the primary navigation menu, it allows you to group pages together in dropdowns.\nFor the sidebar, it allows you to group pages together in the sidebar under a common heading.\nYou can also use category instead of group.\n\nnavigation:\ngroup: \"My Group\"\n\nConfig File Configuration\n\nNext up, let's look at how to customize the navigation menus using the config files.\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\n- To customize the sidebar, use the setting sidebar_order in the docs.php config.\n- When customizing the sidebar, can use the route key, or just the page identifier of the page.\n\nChanging the priorities\n\nThe navigation.order and sidebar_order settings allow you to customize the order of the pages in the navigation menus.\n\nBasic syntax for changing the priorities\n\nThe cleanest way is to use the list-style syntax where each item will get the priority calculated according to its position in the list, plus an offset of 500.\nThe 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\n'navigation' => [\n'order' => [\n'home', \/\/ Gets priority 500\n'about', \/\/ Gets priority 501\n'contact', \/\/ Gets priority 502\n]\n]\n\n\/\/ filepath: config\/docs.php\n\n'sidebar_order' => [\n'readme', \/\/ Gets priority 500\n'installation', \/\/ Gets priority 501\n'getting-started', \/\/ Gets priority 502\n]\n\nExplicit syntax for changing the priorities\n\nYou can also specify explicit priorities by adding a value to the array key:\n\n\/\/ filepath: config\/hyde.php\n\n'navigation' => [\n'order' => [\n'home' => 10, \/\/ Gets priority 10\n'about' => 15, \/\/ Gets priority 15\n'contact' => 20, \/\/ Gets priority 20\n]\n]\n\n\/\/ filepath: config\/docs.php\n\n'sidebar_order' => [\n'readme' => 10, \/\/ Gets priority 10\n'installation' => 15, \/\/ Gets priority 15\n'getting-started' => 20, \/\/ Gets priority 20\n]\n\nYou can of course also combine these methods if you want:\n\n\/\/ filepath: Applicable to both\n[\n'readme' => 10, \/\/ Gets priority 10\n'installation', \/\/ Gets priority 500\n'getting-started', \/\/ Gets priority 501\n]\n\nChanging the menu item labels\n\nHyde makes a few attempts to find a suitable label for the navigation menu items to automatically create helpful titles.\n\nFrom the Hyde config you can override the label of navigation links using the by mapping the route key to the desired title.\nThis is not yet supported for the sidebar, but will be in the future.\n\n\/\/ filepath config\/hyde.php\n'navigation' => [\n'labels' => [\n'index' => 'Start',\n'docs\/index' => 'Documentation',\n]\n]\n\nExcluding Items (Blacklist)\n\nSometimes, especially if you have a lot of pages, you may want to prevent links from showing up in the main navigation menu.\nTo remove items from being automatically added, simply add the page's route key to the blacklist.\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 similar to how we add Authors. Simply add a NavItem model to the navigation.custom array.\n\nWhen linking to an external site, you should use the NavItem::forLink() method facade. The first two arguments are the\ndestination and label, both required. The third argument is the priority, which is optional, and defaults to 500.\n\n\/\/ filepath config\/hyde.php\nuse Hyde\\Framework\\Features\\Navigation\\NavItem;\n\n'navigation' => [\n'custom' => [\nNavItem::forLink('https:\/\/github.com\/hydephp\/hyde', 'GitHub', 200),\n]\n]\n\nSimplified, this will then be rendered as follows:\n\nGitHub\n\nConfigure subdirectory handling\n\nWithin the Hyde config you can configure how subdirectories should be displayed in the menu.\n\n\/\/ filepath config\/hyde.php\n'navigation' => [\n'subdirectories' => 'dropdown'\n]\n\nDropdown means that pages in subdirectories will be displayed in a dropdown menu,\nwhile flat means that pages in subdirectories will be displayed as individual items in the menu.\nHidden means that pages in subdirectories will not be displayed in the menu at all.\n\nAutomatic menu groups\n\nHydePHP has a neat feature to automatically place pages in dropdowns based on subdirectories.\n\nAutomatic navigation menu dropdowns\n\nFor pages that can be in the main site menu, this feature needs to be enabled in the hyde.php config file.\n\n\/\/ filepath config\/hyde.php\n\n'navigation' => [\n'subdirectories' => '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\nAutomatic documentation sidebar grouping\n\nThis feature works similarly to the automatic navigation menu dropdowns, but instead places the sidebar items in named groups.\nThis feature is enabled by default, so you only need to place your pages in subdirectories to have them grouped.\n\nFor example: _docs\/getting-started\/installation.md will be placed in a group called \"Getting Started\".\n\ninfo Tip: When using subdirectory-based dropdowns, you can set their priority using the directory name as the array key.\n\nDigging Deeper into the internals\n\nWhile not required to know, you may find it interesting to learn more about how the navigation is handled internally.\nThe best way to learn about this is to look at the source code, so here is a high-level overview with details on where to look in the source code.\n\nThe main navigation menu is the NavigationMenu class, and the documentation sidebar is the DocumentationSidebar class.\nBoth extend the same BaseNavigationMenu class:\n\nuse Hyde\\Framework\\Features\\Navigation\\NavigationMenu;\nuse Hyde\\Framework\\Features\\Navigation\\DocumentationSidebar;\nuse Hyde\\Framework\\Features\\Navigation\\BaseNavigationMenu;\n\nWithin the BaseNavigationMenu class, you will find the main logic for how the menus are generated,\nwhile the child implementations contain the extra logic tailored for their specific use cases.\n\nAll the navigation menus store the menu items in their $items array containing instances of the NavItem class.\n\nThe NavItem class is a simple class that contains the label and URL of the menu item and is used to represent each item in the menu.\nDropdowns are represented by DropdownNavItem instances, which extend the NavItem class and contain an array of additional NavItem instances.\n\nuse Hyde\\Framework\\Features\\Navigation\\NavItem;\nuse Hyde\\Framework\\Features\\Navigation\\DropdownNavItem;","destination":"navigation"},{"slug":"troubleshooting","title":"Troubleshooting","content":"# Troubleshooting\n\nSince Hyde has a lot of \"magic\" features which depend on some base assumptions,\nthere might be some \"gotchas\" you might run into. Here are some I can think of,\ndid 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 dev\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\nDocumentation table of contents is weird The table of contents markup is generated by the League\/CommonMark extension Make sure that your Markdown headings make sense\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"},{"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\nMethods\n\nWhich method?\n\nDepending on how you installed Hyde, there are a few different ways to update it.\n\nWe have a few methods documented here. The Git method is recommended as it is the easiest and safest way to\nupdate your project. If you are not using Git, you can still update your project using any of the manual methods.\n\nRegardless of the method you use, make sure you follow the post-update instructions at the end.\n\nUpdating just the Framework\n\nIf you just want to update the framework patch version, you can do so by running the following command:\n\ncomposer update hyde\/framework\n\nWhile the same can still be done for minor versions, it's best to also update your project scaffolding and resources to\nensure that everything is up to date, for which you should use the methods below.\n\nUsing Git\n\nFirst, make sure you have a remote set up for the base project repository.\n\ngit remote add upstream https:\/\/github.com\/hydephp\/hyde.git\n\nThen pull the latest release from the upstream repository.\n\ngit pull upstream master\n\nAfter this, you should update your composer dependencies:\n\ncomposer update\n\nNext, follow the post-update instructions.\n\nManual Update\n\nIf you are not using Git, you can still update your project. This is a bit more involved, but it is still possible.\n\n1. First, you will need to download the latest release archive from the releases page.\n2. Then extract the archive, and copy the contents into your project directory.\n\nSince this may overwrite modified files, it may be safer to use the hard update method.\n\nHard Update\n\nIf you are having trouble updating your project, you can try a hard update. In short, this approach consists of creating\na brand new project and copying over only your source and resource files. If you do not want to use Git, this may be\nthe safest option as you won't be overriding any of your existing files.\n\nIf you have changed any other files, for example in the App directory, you will need to update those files manually as well.\nThe same goes if you have created any custom Blade components or have modified Hyde ones.\n\nHere is an example CLI workflow, but you can do the same using a graphical file manager.\n\nmv my-project my-project-old\ncomposer create-project hyde\/hyde my-project\n\ncp -r my-old-project\/pages my-project\/content\/pages\ncp -r my-old-project\/posts my-project\/content\/posts\ncp -r my-old-project\/media my-project\/content\/media\ncp -r my-old-project\/docs my-project\/content\/docs\ncp -r my-old-project\/config my-project\/config\n\nNext, follow the post-update instructions. After verifying that everything is working, you can delete the old project directory.\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\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"},{"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"},{"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\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'port' => env('SERVER_PORT', 8080),\n'host' => env('SERVER_HOST', 'localhost'),\n'save_preview' => 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'dashboard' => [\n'enabled' => env('SERVER_DASHBOARD', true),\n'interactive' => true,\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\nThe live editor was added in Hyde Realtime Compiler Server v3.2.0 (December 2023)\n\nSource code\n\nGitHub**: hydephp\/realtime-compiler\nPackagist**: hydephp\/realtime-compiler","destination":"realtime-compiler"},{"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"},{"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,\nindented 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 Laravel Mix 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"},{"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\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde help\n\nYou can also always add --help to a command to show detailed usage information.\n\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde build [--run-dev] [--run-prod] [--run-prettier] [--pretty-urls] [--no-api]\n\nBuild the static site\n\n#### Options\n\n\n\n--run-dev Run the NPM dev script after build\n--run-prod Run the NPM prod script after build\n--run-prettier Format the output using NPM Prettier\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\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde serve [--host [HOST]] [--port [PORT]]\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\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde build:rss\n\nGenerate the RSS feed\n\n## Generate the docs\/search.json file\n\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde build:search\n\nGenerate the docs\/search.json file\n\n## Generate the sitemap.xml file\n\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde build:sitemap\n\nGenerate the sitemap.xml file\n\n## Scaffold a new Markdown, Blade, or documentation page file\n\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde publish:configs\n\nPublish the default configuration files\n\n## Publish one of the default homepages as index.blade.php.\n\n\/\/ torchlight! {\"lineNumbers\": false}\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\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde publish:views []\n\nPublish the hyde components for customization. Note that existing files will be overwritten.\n\n#### Arguments\n\n\n\ncategory The category to publish\n\n## Display all Registered Routes.\n\n\/\/ torchlight! {\"lineNumbers\": false}\nphp hyde route:list\n\nDisplay all registered routes.\n\n## Publish any publishable assets from vendor packages\n\n\/\/ torchlight! {\"lineNumbers\": false}\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"},{"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 Laravel Mix 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 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 experimental 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 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"},{"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 experimental 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"},{"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\n\/\/ torchlight! {\"lineNumbers\": false}\ncomposer create-project hyde\/hyde\n\nRequirements\n\nHyde is based on Laravel 10\nwhich requires a minimum PHP version of 8.1.\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 Laravel Mix 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"},{"slug":"configuration","title":"Configuration","content":"Redirecting you to customization","destination":"configuration"},{"slug":"directory-structure","title":"Directory Structure","content":"Redirecting you to architecture-concepts#directory-structure","destination":"directory-structure"},{"slug":"getting-started","title":"Getting Started","content":"Redirecting you to quickstart","destination":"getting-started"},{"slug":"installation","title":"Installation","content":"Redirecting you to quickstart","destination":"installation"}]
\ No newline at end of file
diff --git a/docs/docs/1.x/static-pages.html b/docs/docs/1.x/static-pages.html
index 1d54b10a..25e147a7 100644
--- a/docs/docs/1.x/static-pages.html
+++ b/docs/docs/1.x/static-pages.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/docs/1.x/the-hydekernel.html b/docs/docs/1.x/the-hydekernel.html
index 77c3edbb..37115dd3 100644
--- a/docs/docs/1.x/the-hydekernel.html
+++ b/docs/docs/1.x/the-hydekernel.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/docs/1.x/third-party-integrations.html b/docs/docs/1.x/third-party-integrations.html
index 932f62cb..e065c0d8 100644
--- a/docs/docs/1.x/third-party-integrations.html
+++ b/docs/docs/1.x/third-party-integrations.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/docs/1.x/troubleshooting.html b/docs/docs/1.x/troubleshooting.html
index 45b963ea..e3db1779 100644
--- a/docs/docs/1.x/troubleshooting.html
+++ b/docs/docs/1.x/troubleshooting.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/docs/1.x/ui-kit.html b/docs/docs/1.x/ui-kit.html
index eadc4152..a632bd77 100644
--- a/docs/docs/1.x/ui-kit.html
+++ b/docs/docs/1.x/ui-kit.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/docs/1.x/updating-hyde.html b/docs/docs/1.x/updating-hyde.html
index d27901c0..8ac0d911 100644
--- a/docs/docs/1.x/updating-hyde.html
+++ b/docs/docs/1.x/updating-hyde.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/feed.xml b/docs/feed.xml
index cf93f233..b142c435 100644
--- a/docs/feed.xml
+++ b/docs/feed.xml
@@ -1,2 +1,2 @@
-HydePHPhttps://hydephp.com/HydePHP RSS FeedenHydePHP 1.6.0Sat, 08 Jun 2024 14:29:33 +0000How to turn your GitHub Readme into a static websiteLearn how to create a static website based on your GitHub Readme, using HydePHP to build and deploy it to GitHub Pages - all for free and in minutes!https://hydephp.com/posts/how-to-turn-your-github-readme-into-a-static-websitehttps://hydephp.com/posts/how-to-turn-your-github-readme-into-a-static-websiteSat, 08 Jun 2024 11:32:00 +0000HydePHPtutorialsHydePHP OpenCollective LaunchHydePHP now has its own OpenCollective, providing a platform where users and companies can contribute financially to help fund the development of HydePHP.https://hydephp.com/posts/hydephp-open-collective-launchhttps://hydephp.com/posts/hydephp-open-collective-launchSat, 17 Feb 2024 00:00:00 +0000CaenannouncementsHydePHP Version v1.5 ReleasedIn this release, several new features and improvements have been introduced.https://hydephp.com/posts/hydephp-version-1-5-releasedhttps://hydephp.com/posts/hydephp-version-1-5-releasedTue, 13 Feb 2024 12:00:00 +0000CaenreleasesIntroducing the HydePHP UI KitA collection of minimalistic and un-opinionated TailwindCSS components for your HydePHP projectshttps://hydephp.com/posts/introducing-the-hydephp-ui-kithttps://hydephp.com/posts/introducing-the-hydephp-ui-kitFri, 02 Feb 2024 20:00:00 +0000CaenannouncementsIntroducing the HydePHP GitHub ActionThe easiest way to build and deploy your static sites!https://hydephp.com/posts/introducing-the-hydephp-github-actionhttps://hydephp.com/posts/introducing-the-hydephp-github-actionSun, 28 Jan 2024 16:00:00 +0000CaenannouncementsHydePHP Version v1.4 ReleasedThis new update brings Live Edit and a bunch of other DX enhancementshttps://hydephp.com/posts/hydephp-version-1-4-releasedhttps://hydephp.com/posts/hydephp-version-1-4-releasedMon, 11 Dec 2023 20:00:00 +0000CaenreleasesSunsetting the HydePHP.se domain in favour of HydePHP.comThe infrastructure domain "HydePHP.se" is sunset, in favour of the canonical HydePHP.comhttps://hydephp.com/posts/sunsetting-hydephp-dot-sehttps://hydephp.com/posts/sunsetting-hydephp-dot-seThu, 25 May 2023 14:59:00 +0000CaenannouncementsAnnouncing the First Release of HydePHPWe're excited to announce the first official release of HydePHP, a Laravel-based static site generator!https://hydephp.com/posts/announcing-the-first-release-of-hydephphttps://hydephp.com/posts/announcing-the-first-release-of-hydephpTue, 14 Mar 2023 20:00:00 +0000CaenannouncementsAnnouncing the First Release Candidate of HydePHPWe're excited to announce the first release candidate of HydePHP, a Laravel-based static site generator!https://hydephp.com/posts/announcing-the-first-release-candidate-of-hydephphttps://hydephp.com/posts/announcing-the-first-release-candidate-of-hydephpTue, 07 Mar 2023 22:33:00 +0000CaenannouncementsPreliminary Release Date: March 14, 2023The preliminary release date for the first version of HydePHP is set for March 14, 2023.https://hydephp.com/posts/release-date-announcementhttps://hydephp.com/posts/release-date-announcementSat, 11 Feb 2023 17:39:29 +0000CaennewsCreating a static photography portfolio landing site with HydePHPIn this blog post, we'll be creating a simple photography portfolio site using HydePHP and Markdown. No coding is needed!https://hydephp.com/posts/creating-a-photography-portfolio-site-with-hydephphttps://hydephp.com/posts/creating-a-photography-portfolio-site-with-hydephpSat, 27 Aug 2022 00:00:00 +0000CaentutorialsWhat is Markdown?A short introduction to the Markdown text format.https://hydephp.com/posts/what-is-markdownhttps://hydephp.com/posts/what-is-markdownSat, 06 Aug 2022 15:11:00 +0000CaengeneralAutomate HydePHP sites using GitHub Actions and GitHub PagesHydePHP is a framework for building static websites. While the most common way to interact with HydePHP is through the command line, you can actually manage an entire site using GitHub.https://hydephp.com/posts/github-actions-deploymenthttps://hydephp.com/posts/github-actions-deploymentMon, 20 Jun 2022 12:09:00 +0000CaenGuidesInternal Architecture of HydePHP - Part 3: Page ModelsIn this third instalment we take a look at how Hyde internally parses Markdown files and compiles them into HTML.https://hydephp.com/posts/internal-architecture-of-hydephp-part-3https://hydephp.com/posts/internal-architecture-of-hydephp-part-3Fri, 13 May 2022 20:00:00 +0000CaendeepdivesInternal Architecture of HydePHP - Part 2: ServicesPart two in the series on the internal architecture of HydePHP, this time we take a "Deep Dive" into Services.https://hydephp.com/posts/internal-architecture-of-hydephp-part-2https://hydephp.com/posts/internal-architecture-of-hydephp-part-2Thu, 12 May 2022 19:54:00 +0000CaendeepdivesInternal Architecture of HydePHP - Part 1: IntroductionThis first part in a series of the architecture of HydePHP will give an overview of design patterns and concepts in the Hyde Framework Core.https://hydephp.com/posts/internal-architecture-of-hydephp-part-1https://hydephp.com/posts/internal-architecture-of-hydephp-part-1Wed, 11 May 2022 20:35:00 +0000CaendeepdivesHyde Feature HighlightsLearn about some of the features Hyde has to offer.https://hydephp.com/posts/hyde-feature-highlightshttps://hydephp.com/posts/hyde-feature-highlightsSun, 17 Apr 2022 12:59:00 +0000CaenblogWhat is Hyde?Learn about Hyde and find answers to common questions!https://hydephp.com/posts/what-is-hydehttps://hydephp.com/posts/what-is-hydeWed, 13 Apr 2022 15:34:00 +0000CaenBlogIntroducing images!The v0.10.0 release introduces featured images for blog posts.https://hydephp.com/posts/introducing-imageshttps://hydephp.com/posts/introducing-imagesMon, 11 Apr 2022 14:57:00 +0000CaenblogCreating a new Hyde site from scratchThis blog post will guide you through creating a new Hyde site, while also showcasing some neat features!https://hydephp.com/posts/creating-a-new-hyde-site-from-scratchhttps://hydephp.com/posts/creating-a-new-hyde-site-from-scratchFri, 25 Mar 2022 20:49:00 +0000CaentutorialsWhy static sites?A quick run-down of the benefits of static websiteshttps://hydephp.com/posts/why-static-siteshttps://hydephp.com/posts/why-static-sitesSat, 19 Mar 2022 20:02:00 +0000CaengeneralCreating a static HTML post using HydePHPIn this tutorial, we go through the simple process of generating a static blog posthttps://hydephp.com/posts/creating-a-static-html-post-using-hydephphttps://hydephp.com/posts/creating-a-static-html-post-using-hydephpSat, 19 Mar 2022 16:19:00 +0000Caentutorials
+HydePHPhttps://hydephp.com/HydePHP RSS FeedenHydePHP 1.6.0Fri, 05 Jul 2024 13:11:56 +0000How to turn your GitHub Readme into a static websiteLearn how to create a static website based on your GitHub Readme, using HydePHP to build and deploy it to GitHub Pages - all for free and in minutes!https://hydephp.com/posts/how-to-turn-your-github-readme-into-a-static-websitehttps://hydephp.com/posts/how-to-turn-your-github-readme-into-a-static-websiteSat, 08 Jun 2024 11:32:00 +0000HydePHPtutorialsHydePHP OpenCollective LaunchHydePHP now has its own OpenCollective, providing a platform where users and companies can contribute financially to help fund the development of HydePHP.https://hydephp.com/posts/hydephp-open-collective-launchhttps://hydephp.com/posts/hydephp-open-collective-launchSat, 17 Feb 2024 00:00:00 +0000CaenannouncementsHydePHP Version v1.5 ReleasedIn this release, several new features and improvements have been introduced.https://hydephp.com/posts/hydephp-version-1-5-releasedhttps://hydephp.com/posts/hydephp-version-1-5-releasedTue, 13 Feb 2024 12:00:00 +0000CaenreleasesIntroducing the HydePHP UI KitA collection of minimalistic and un-opinionated TailwindCSS components for your HydePHP projectshttps://hydephp.com/posts/introducing-the-hydephp-ui-kithttps://hydephp.com/posts/introducing-the-hydephp-ui-kitFri, 02 Feb 2024 20:00:00 +0000CaenannouncementsIntroducing the HydePHP GitHub ActionThe easiest way to build and deploy your static sites!https://hydephp.com/posts/introducing-the-hydephp-github-actionhttps://hydephp.com/posts/introducing-the-hydephp-github-actionSun, 28 Jan 2024 16:00:00 +0000CaenannouncementsHydePHP Version v1.4 ReleasedThis new update brings Live Edit and a bunch of other DX enhancementshttps://hydephp.com/posts/hydephp-version-1-4-releasedhttps://hydephp.com/posts/hydephp-version-1-4-releasedMon, 11 Dec 2023 20:00:00 +0000CaenreleasesSunsetting the HydePHP.se domain in favour of HydePHP.comThe infrastructure domain "HydePHP.se" is sunset, in favour of the canonical HydePHP.comhttps://hydephp.com/posts/sunsetting-hydephp-dot-sehttps://hydephp.com/posts/sunsetting-hydephp-dot-seThu, 25 May 2023 14:59:00 +0000CaenannouncementsAnnouncing the First Release of HydePHPWe're excited to announce the first official release of HydePHP, a Laravel-based static site generator!https://hydephp.com/posts/announcing-the-first-release-of-hydephphttps://hydephp.com/posts/announcing-the-first-release-of-hydephpTue, 14 Mar 2023 20:00:00 +0000CaenannouncementsAnnouncing the First Release Candidate of HydePHPWe're excited to announce the first release candidate of HydePHP, a Laravel-based static site generator!https://hydephp.com/posts/announcing-the-first-release-candidate-of-hydephphttps://hydephp.com/posts/announcing-the-first-release-candidate-of-hydephpTue, 07 Mar 2023 22:33:00 +0000CaenannouncementsPreliminary Release Date: March 14, 2023The preliminary release date for the first version of HydePHP is set for March 14, 2023.https://hydephp.com/posts/release-date-announcementhttps://hydephp.com/posts/release-date-announcementSat, 11 Feb 2023 17:39:29 +0000CaennewsCreating a static photography portfolio landing site with HydePHPIn this blog post, we'll be creating a simple photography portfolio site using HydePHP and Markdown. No coding is needed!https://hydephp.com/posts/creating-a-photography-portfolio-site-with-hydephphttps://hydephp.com/posts/creating-a-photography-portfolio-site-with-hydephpSat, 27 Aug 2022 00:00:00 +0000CaentutorialsWhat is Markdown?A short introduction to the Markdown text format.https://hydephp.com/posts/what-is-markdownhttps://hydephp.com/posts/what-is-markdownSat, 06 Aug 2022 15:11:00 +0000CaengeneralAutomate HydePHP sites using GitHub Actions and GitHub PagesHydePHP is a framework for building static websites. While the most common way to interact with HydePHP is through the command line, you can actually manage an entire site using GitHub.https://hydephp.com/posts/github-actions-deploymenthttps://hydephp.com/posts/github-actions-deploymentMon, 20 Jun 2022 12:09:00 +0000CaenGuidesInternal Architecture of HydePHP - Part 3: Page ModelsIn this third instalment we take a look at how Hyde internally parses Markdown files and compiles them into HTML.https://hydephp.com/posts/internal-architecture-of-hydephp-part-3https://hydephp.com/posts/internal-architecture-of-hydephp-part-3Fri, 13 May 2022 20:00:00 +0000CaendeepdivesInternal Architecture of HydePHP - Part 2: ServicesPart two in the series on the internal architecture of HydePHP, this time we take a "Deep Dive" into Services.https://hydephp.com/posts/internal-architecture-of-hydephp-part-2https://hydephp.com/posts/internal-architecture-of-hydephp-part-2Thu, 12 May 2022 19:54:00 +0000CaendeepdivesInternal Architecture of HydePHP - Part 1: IntroductionThis first part in a series of the architecture of HydePHP will give an overview of design patterns and concepts in the Hyde Framework Core.https://hydephp.com/posts/internal-architecture-of-hydephp-part-1https://hydephp.com/posts/internal-architecture-of-hydephp-part-1Wed, 11 May 2022 20:35:00 +0000CaendeepdivesHyde Feature HighlightsLearn about some of the features Hyde has to offer.https://hydephp.com/posts/hyde-feature-highlightshttps://hydephp.com/posts/hyde-feature-highlightsSun, 17 Apr 2022 12:59:00 +0000CaenblogWhat is Hyde?Learn about Hyde and find answers to common questions!https://hydephp.com/posts/what-is-hydehttps://hydephp.com/posts/what-is-hydeWed, 13 Apr 2022 15:34:00 +0000CaenBlogIntroducing images!The v0.10.0 release introduces featured images for blog posts.https://hydephp.com/posts/introducing-imageshttps://hydephp.com/posts/introducing-imagesMon, 11 Apr 2022 14:57:00 +0000CaenblogCreating a new Hyde site from scratchThis blog post will guide you through creating a new Hyde site, while also showcasing some neat features!https://hydephp.com/posts/creating-a-new-hyde-site-from-scratchhttps://hydephp.com/posts/creating-a-new-hyde-site-from-scratchFri, 25 Mar 2022 20:49:00 +0000CaentutorialsWhy static sites?A quick run-down of the benefits of static websiteshttps://hydephp.com/posts/why-static-siteshttps://hydephp.com/posts/why-static-sitesSat, 19 Mar 2022 20:02:00 +0000CaengeneralCreating a static HTML post using HydePHPIn this tutorial, we go through the simple process of generating a static blog posthttps://hydephp.com/posts/creating-a-static-html-post-using-hydephphttps://hydephp.com/posts/creating-a-static-html-post-using-hydephpSat, 19 Mar 2022 16:19:00 +0000Caentutorials
diff --git a/docs/guides/installation.html b/docs/guides/installation.html
index 13963624..f2dbc076 100644
--- a/docs/guides/installation.html
+++ b/docs/guides/installation.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/index.html b/docs/index.html
index 92c18307..8b5c1b5f 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -72,7 +72,7 @@
-
+
diff --git a/docs/legal.html b/docs/legal.html
index 71dd2591..fa27bcee 100644
--- a/docs/legal.html
+++ b/docs/legal.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/license.html b/docs/license.html
index 510ad8bd..4a9eb6c7 100644
--- a/docs/license.html
+++ b/docs/license.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/media/app.css b/docs/media/app.css
index 98872046..ddfa0b70 100644
--- a/docs/media/app.css
+++ b/docs/media/app.css
@@ -1,2 +1,2 @@
-/*! HydeFront v3.3.4 | MIT License | https://hydephp.com*/.hyde-search-context{margin-bottom:10px}.hyde-search-results{margin-top:1.25em;max-height:60vh;overflow-y:auto}#search-status{margin-top:0}#sidebar-toggle{display:inline-block;height:2rem;position:relative;width:2rem}#sidebar-toggle span.icon-bar{background-color:#000;display:block;height:2.375px;left:5.5px;position:absolute;transition:all .3s ease-out;width:20px}#sidebar-toggle span.icon-bar:first-child{top:9px}#sidebar-toggle span.icon-bar:nth-child(2),#sidebar-toggle span.icon-bar:nth-child(3){top:15px;transform-origin:center}#sidebar-toggle span.icon-bar:last-child{top:21px}#sidebar-toggle.active span.icon-bar:first-child{opacity:0}#sidebar-toggle.active span.icon-bar:nth-child(2){transform:rotate(45deg)}#sidebar-toggle.active span.icon-bar:nth-child(3){transform:rotate(-45deg)}#sidebar-toggle.active span.icon-bar:last-child{opacity:0}.dark #sidebar-toggle span.icon-bar{background-color:#fff;height:2px}.table-of-contents{padding-bottom:.75rem}.table-of-contents>li{margin-bottom:.35rem;margin-top:.15rem}.table-of-contents ul{padding-left:.5rem}.table-of-contents a{display:block;margin-left:-2rem;opacity:.825;padding-left:2rem}.table-of-contents a:before{content:"#";font-size:75%;margin-right:4px;opacity:.5;transition:opacity .3s ease-in-out}.table-of-contents a:hover{background-color:hsla(0,0%,50%,.2);opacity:1;transition:opacity,background .3s ease-in-out}.table-of-contents a:hover:before{opacity:1}#hyde-docs .prose h1,#hyde-docs .prose h2,#hyde-docs .prose h3,#hyde-docs .prose h4,#hyde-docs .prose h5,#hyde-docs .prose h6{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}#hyde-docs .prose h1:focus .heading-permalink,#hyde-docs .prose h1:hover .heading-permalink,#hyde-docs .prose h2:focus .heading-permalink,#hyde-docs .prose h2:hover .heading-permalink,#hyde-docs .prose h3:focus .heading-permalink,#hyde-docs .prose h3:hover .heading-permalink,#hyde-docs .prose h4:focus .heading-permalink,#hyde-docs .prose h4:hover .heading-permalink,#hyde-docs .prose h5:focus .heading-permalink,#hyde-docs .prose h5:hover .heading-permalink,#hyde-docs .prose h6:focus .heading-permalink,#hyde-docs .prose h6:hover .heading-permalink{filter:grayscale(100%);opacity:.75;transition:opacity .1s ease-out}#hyde-docs .prose h1 .heading-permalink,#hyde-docs .prose h2 .heading-permalink,#hyde-docs .prose h3 .heading-permalink,#hyde-docs .prose h4 .heading-permalink,#hyde-docs .prose h5 .heading-permalink,#hyde-docs .prose h6 .heading-permalink{margin-left:.25rem;opacity:0;padding:0 .25rem;scroll-margin:1rem;transition:opacity .3s ease;visibility:hidden}#hyde-docs .prose h1 .heading-permalink:focus,#hyde-docs .prose h1 .heading-permalink:hover,#hyde-docs .prose h2 .heading-permalink:focus,#hyde-docs .prose h2 .heading-permalink:hover,#hyde-docs .prose h3 .heading-permalink:focus,#hyde-docs .prose h3 .heading-permalink:hover,#hyde-docs .prose h4 .heading-permalink:focus,#hyde-docs .prose h4 .heading-permalink:hover,#hyde-docs .prose h5 .heading-permalink:focus,#hyde-docs .prose h5 .heading-permalink:hover,#hyde-docs .prose h6 .heading-permalink:focus,#hyde-docs .prose h6 .heading-permalink:hover{filter:unset;opacity:1;visibility:visible}html{scroll-behavior:smooth}.torchlight-enabled pre{border-radius:.25rem;margin-bottom:1rem;margin-top:1rem;overflow-x:auto;padding:0}.torchlight-enabled pre code.torchlight{display:block;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;padding-bottom:1rem;padding-top:1rem}.torchlight-enabled pre code.torchlight .line{padding-left:1rem;padding-right:1rem}.torchlight-enabled pre code.torchlight .line-number,.torchlight-enabled pre code.torchlight .summary-caret{margin-right:1rem}.prose blockquote.info{--tw-border-opacity:1;border-color:rgb(59 130 246/var(--tw-border-opacity))}.prose blockquote.success{--tw-border-opacity:1;border-color:rgb(34 197 94/var(--tw-border-opacity))}.prose blockquote.warning{--tw-border-opacity:1;border-color:rgb(245 158 11/var(--tw-border-opacity))}.prose blockquote.danger{--tw-border-opacity:1;border-color:rgb(220 38 38/var(--tw-border-opacity))}code{max-width:80vw;overflow-x:auto;vertical-align:top;word-break:break-all}pre code{display:block;max-width:unset}pre>code>.filepath{float:right;opacity:.5;position:relative;right:.25rem;top:-.25rem;transition:opacity .25s}pre>code>.filepath:hover{opacity:1}.torchlight-enabled pre>code>.filepath{right:1rem}@media screen and (max-width:767px){pre>code>.filepath{display:none}}@media screen and (min-width:768px){[x-cloak].x-uncloak-md{display:revert!important}}
+/*! HydeFront v3.3.5 | MIT License | https://hydephp.com*/.hyde-search-context{margin-bottom:10px}.hyde-search-results{margin-top:1.25em;max-height:60vh;overflow-y:auto}#search-status{margin-top:0}#sidebar-toggle{display:inline-block;height:2rem;position:relative;width:2rem}#sidebar-toggle span.icon-bar{background-color:#000;display:block;height:2.375px;left:5.5px;position:absolute;transition:all .3s ease-out;width:20px}#sidebar-toggle span.icon-bar:first-child{top:9px}#sidebar-toggle span.icon-bar:nth-child(2),#sidebar-toggle span.icon-bar:nth-child(3){top:15px;transform-origin:center}#sidebar-toggle span.icon-bar:last-child{top:21px}#sidebar-toggle.active span.icon-bar:first-child{opacity:0}#sidebar-toggle.active span.icon-bar:nth-child(2){transform:rotate(45deg)}#sidebar-toggle.active span.icon-bar:nth-child(3){transform:rotate(-45deg)}#sidebar-toggle.active span.icon-bar:last-child{opacity:0}.dark #sidebar-toggle span.icon-bar{background-color:#fff;height:2px}.table-of-contents{padding-bottom:.75rem}.table-of-contents>li{margin-bottom:.35rem;margin-top:.15rem}.table-of-contents ul{padding-left:.5rem}.table-of-contents a{display:block;margin-left:-2rem;opacity:.825;padding-left:2rem}.table-of-contents a:before{content:"#";font-size:75%;margin-right:4px;opacity:.5;transition:opacity .3s ease-in-out}.table-of-contents a:hover{background-color:hsla(0,0%,50%,.2);opacity:1;transition:opacity,background .3s ease-in-out}.table-of-contents a:hover:before{opacity:1}#hyde-docs .prose h1,#hyde-docs .prose h2,#hyde-docs .prose h3,#hyde-docs .prose h4,#hyde-docs .prose h5,#hyde-docs .prose h6{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}#hyde-docs .prose h1:focus .heading-permalink,#hyde-docs .prose h1:hover .heading-permalink,#hyde-docs .prose h2:focus .heading-permalink,#hyde-docs .prose h2:hover .heading-permalink,#hyde-docs .prose h3:focus .heading-permalink,#hyde-docs .prose h3:hover .heading-permalink,#hyde-docs .prose h4:focus .heading-permalink,#hyde-docs .prose h4:hover .heading-permalink,#hyde-docs .prose h5:focus .heading-permalink,#hyde-docs .prose h5:hover .heading-permalink,#hyde-docs .prose h6:focus .heading-permalink,#hyde-docs .prose h6:hover .heading-permalink{filter:grayscale(100%);opacity:.75;transition:opacity .1s ease-out}#hyde-docs .prose h1 .heading-permalink,#hyde-docs .prose h2 .heading-permalink,#hyde-docs .prose h3 .heading-permalink,#hyde-docs .prose h4 .heading-permalink,#hyde-docs .prose h5 .heading-permalink,#hyde-docs .prose h6 .heading-permalink{margin-left:.25rem;opacity:0;padding:0 .25rem;scroll-margin:1rem;transition:opacity .3s ease;visibility:hidden}#hyde-docs .prose h1 .heading-permalink:focus,#hyde-docs .prose h1 .heading-permalink:hover,#hyde-docs .prose h2 .heading-permalink:focus,#hyde-docs .prose h2 .heading-permalink:hover,#hyde-docs .prose h3 .heading-permalink:focus,#hyde-docs .prose h3 .heading-permalink:hover,#hyde-docs .prose h4 .heading-permalink:focus,#hyde-docs .prose h4 .heading-permalink:hover,#hyde-docs .prose h5 .heading-permalink:focus,#hyde-docs .prose h5 .heading-permalink:hover,#hyde-docs .prose h6 .heading-permalink:focus,#hyde-docs .prose h6 .heading-permalink:hover{filter:unset;opacity:1;visibility:visible}html{scroll-behavior:smooth}.torchlight-enabled pre{border-radius:.25rem;margin-bottom:1rem;margin-top:1rem;overflow-x:auto;padding:0}.torchlight-enabled pre code.torchlight{display:block;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;padding-bottom:1rem;padding-top:1rem}.torchlight-enabled pre code.torchlight .line{padding-left:1rem;padding-right:1rem}.torchlight-enabled pre code.torchlight .line-number,.torchlight-enabled pre code.torchlight .summary-caret{margin-right:1rem}.prose blockquote.info{--tw-border-opacity:1;border-color:rgb(59 130 246/var(--tw-border-opacity))}.prose blockquote.success{--tw-border-opacity:1;border-color:rgb(34 197 94/var(--tw-border-opacity))}.prose blockquote.warning{--tw-border-opacity:1;border-color:rgb(245 158 11/var(--tw-border-opacity))}.prose blockquote.danger{--tw-border-opacity:1;border-color:rgb(220 38 38/var(--tw-border-opacity))}code{max-width:80vw;overflow-x:auto;vertical-align:top;word-break:break-all}pre code{display:block;max-width:unset}pre>code>.filepath{float:right;opacity:.5;position:relative;right:.25rem;top:-.25rem;transition:opacity .25s}pre>code>.filepath:hover{opacity:1}.torchlight-enabled pre>code>.filepath{right:1rem}@media screen and (max-width:767px){pre>code>.filepath{display:none}}@media screen and (min-width:768px){[x-cloak].x-uncloak-md{display:revert!important}}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}
/*! tailwindcss v3.1.4 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::-webkit-backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.prose{color:var(--tw-prose-body);max-width:96ch}.prose :where([class~=lead]):not(:where([class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;line-height:1.6;margin-bottom:1.2em;margin-top:1.2em}.prose :where(a):not(:where([class~=not-prose] *)){color:#5956eb;font-weight:500;text-decoration:none}.prose :where(a):not(:where([class~=not-prose] *)):hover{color:#4f46e5}.prose :where(strong):not(:where([class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(ol):not(:where([class~=not-prose] *)){list-style-type:decimal;padding-left:1.625em}.prose :where(ol[type=A]):not(:where([class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose] *)){list-style-type:disc;padding-left:1.625em}.prose :where(ol>li):not(:where([class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.prose :where(ul>li):not(:where([class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(hr):not(:where([class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-bottom:3em;margin-top:3em}.prose :where(blockquote):not(:where([class~=not-prose] *)){background-color:#80808020;border-left-color:#d1d5db;border-left-width:.25rem;color:unset;font-style:unset;font-weight:500;line-height:1.25em;margin-bottom:1em;margin-top:1em;padding-bottom:.25em;padding-left:.75em;padding-top:.25em;quotes:"\201C""\201D""\2018""\2019"}.prose :where(blockquote):not(:where([class~=not-prose] *)) p{margin-bottom:.25em;margin-top:.25em;padding-right:.25em}.prose :where(blockquote):not(:where([class~=not-prose] *)) p:before{content:unset}.prose :where(blockquote):not(:where([class~=not-prose] *)) p:after{content:unset}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose] *)){color:var(--tw-prose-headings);font-size:2.25em;font-weight:800;line-height:1.1111111;margin-bottom:.8888889em;margin-top:0}.prose :where(h1 strong):not(:where([class~=not-prose] *)){font-weight:900}.prose :where(h2):not(:where([class~=not-prose] *)){color:var(--tw-prose-headings);font-size:1.5em;font-weight:700;line-height:1.3333333;margin-bottom:.75em;margin-top:1.5em}.prose :where(h2 strong):not(:where([class~=not-prose] *)){font-weight:800}.prose :where(h3):not(:where([class~=not-prose] *)){color:var(--tw-prose-headings);font-size:1.25em;font-weight:600;line-height:1.6;margin-bottom:.6em;margin-top:1.6em}.prose :where(h3 strong):not(:where([class~=not-prose] *)){font-weight:700}.prose :where(h4):not(:where([class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;line-height:1.5;margin-bottom:.5em;margin-top:1.5em}.prose :where(h4 strong):not(:where([class~=not-prose] *)){font-weight:700}.prose :where(figure>*):not(:where([class~=not-prose] *)){margin-bottom:0;margin-top:0}.prose :where(figcaption):not(:where([class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose :where(code):not(:where([class~=not-prose] *)){background-color:#80808033;border-radius:4px;color:var(--tw-prose-code);font-size:.875em;font-weight:600;font:unset;margin-left:-2px;margin-right:1px;padding-left:4px;padding-right:4px}.prose :where(code):not(:where([class~=not-prose] *)):before{content:unset}.prose :where(code):not(:where([class~=not-prose] *)):after{content:unset}.prose :where(a code):not(:where([class~=not-prose] *)){color:var(--tw-prose-links)}.prose :where(pre):not(:where([class~=not-prose] *)){background-color:var(--tw-prose-pre-bg);border-radius:.375rem;color:var(--tw-prose-pre-code);font-size:.875em;font-weight:400;line-height:1.7142857;margin-bottom:1.7142857em;margin-top:1.7142857em;overflow-x:auto;padding:.8571429em 1.1428571em}.prose :where(pre):not(:where([class~=not-prose] *)) code{font-family:Fira Code Regular,Consolas,Monospace,Courier New}.prose :where(pre code):not(:where([class~=not-prose] *)){background-color:transparent;border-radius:0;border-width:0;color:inherit;font-family:inherit;font-size:inherit;font-weight:inherit;line-height:inherit;padding:0}.prose :where(pre code):not(:where([class~=not-prose] *)):before{content:none}.prose :where(pre code):not(:where([class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose] *)){font-size:.875em;line-height:1.7142857;margin-bottom:2em;margin-top:2em;table-layout:auto;text-align:left;width:100%}.prose :where(thead):not(:where([class~=not-prose] *)){border-bottom-color:var(--tw-prose-th-borders);border-bottom-width:1px}.prose :where(thead th):not(:where([class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;padding-bottom:.5714286em;padding-left:.5714286em;padding-right:.5714286em;vertical-align:bottom}.prose :where(tbody tr):not(:where([class~=not-prose] *)){border-bottom-color:var(--tw-prose-td-borders);border-bottom-width:1px}.prose :where(tbody tr:last-child):not(:where([class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose] *)){padding:.5714286em;vertical-align:baseline}.prose{--tw-prose-body:#374151;--tw-prose-headings:#111827;--tw-prose-lead:#4b5563;--tw-prose-links:#111827;--tw-prose-bold:#111827;--tw-prose-counters:#6b7280;--tw-prose-bullets:#d1d5db;--tw-prose-hr:#e5e7eb;--tw-prose-quotes:#111827;--tw-prose-quote-borders:#e5e7eb;--tw-prose-captions:#6b7280;--tw-prose-code:#111827;--tw-prose-pre-code:#e5e7eb;--tw-prose-pre-bg:#1f2937;--tw-prose-th-borders:#d1d5db;--tw-prose-td-borders:#e5e7eb;--tw-prose-invert-body:#d1d5db;--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:#9ca3af;--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:#9ca3af;--tw-prose-invert-bullets:#4b5563;--tw-prose-invert-hr:#374151;--tw-prose-invert-quotes:#f3f4f6;--tw-prose-invert-quote-borders:#374151;--tw-prose-invert-captions:#9ca3af;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:#d1d5db;--tw-prose-invert-pre-bg:rgba(0,0,0,.5);--tw-prose-invert-th-borders:#4b5563;--tw-prose-invert-td-borders:#374151;font-size:1rem;line-height:1.5em}.prose :where(p):not(:where([class~=not-prose] *)){margin-bottom:1.25em;margin-top:1.25em}.prose :where(img):not(:where([class~=not-prose] *)){margin-bottom:2em;margin-top:2em}.prose :where(video):not(:where([class~=not-prose] *)){margin-bottom:2em;margin-top:2em}.prose :where(figure):not(:where([class~=not-prose] *)){margin-bottom:2em;margin-top:2em}.prose :where(h2 code):not(:where([class~=not-prose] *)){font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose] *)){font-size:.9em}.prose :where(li):not(:where([class~=not-prose] *)){margin-bottom:.5em;margin-top:.5em}.prose :where(ol>li):not(:where([class~=not-prose] *)){padding-left:.375em}.prose :where(ul>li):not(:where([class~=not-prose] *)){padding-left:.375em}.prose>:where(ul>li p):not(:where([class~=not-prose] *)){margin-bottom:.75em;margin-top:.75em}.prose>:where(ul>li>:first-child):not(:where([class~=not-prose] *)){margin-top:1.25em}.prose>:where(ul>li>:last-child):not(:where([class~=not-prose] *)){margin-bottom:1.25em}.prose>:where(ol>li>:first-child):not(:where([class~=not-prose] *)){margin-top:1.25em}.prose>:where(ol>li>:last-child):not(:where([class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose] *)){margin-bottom:.75em;margin-top:.75em}.prose :where(hr+*):not(:where([class~=not-prose] *)){margin-top:0}.prose :where(h2+*):not(:where([class~=not-prose] *)){margin-top:0}.prose :where(h3+*):not(:where([class~=not-prose] *)){margin-top:0}.prose :where(h4+*):not(:where([class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose] *)){padding-left:0}.prose :where(thead th:last-child):not(:where([class~=not-prose] *)){padding-right:0}.prose :where(tbody td:first-child):not(:where([class~=not-prose] *)){padding-left:0}.prose :where(tbody td:last-child):not(:where([class~=not-prose] *)){padding-right:0}.prose>:where(:first-child):not(:where([class~=not-prose] *)){margin-top:0}.prose>:where(:last-child):not(:where([class~=not-prose] *)){margin-bottom:0}.sr-only{clip:rect(0,0,0,0);border-width:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}.visible{visibility:visible}.invisible{visibility:hidden}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.top-0{top:0}.right-0{right:0}.left-0{left:0}.bottom-0{bottom:0}.top-4{top:1rem}.right-4{right:1rem}.top-auto{top:auto}.left-80{left:20rem}.top-16{top:4rem}.bottom-4{bottom:1rem}.-left-64{left:-16rem}.z-10{z-index:10}.z-50{z-index:50}.z-40{z-index:40}.z-30{z-index:30}.order-first{order:-9999}.col-span-1{grid-column:span 1/span 1}.float-right{float:right}.float-left{float:left}.clear-both{clear:both}.m-8{margin:2rem}.m-0{margin:0}.m-4{margin:1rem}.m-2{margin:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0{margin-bottom:0;margin-top:0}.my-4{margin-bottom:1rem;margin-top:1rem}.my-8{margin-bottom:2rem;margin-top:2rem}.mx-0{margin-left:0;margin-right:0}.mx-4{margin-left:1rem;margin-right:1rem}.mx-8{margin-left:2rem;margin-right:2rem}.my-3{margin-bottom:.75rem;margin-top:.75rem}.my-1{margin-bottom:.25rem;margin-top:.25rem}.my-auto{margin-bottom:auto;margin-top:auto}.my-2{margin-bottom:.5rem;margin-top:.5rem}.my-5{margin-bottom:1.25rem;margin-top:1.25rem}.my-6{margin-bottom:1.5rem;margin-top:1.5rem}.mx-1{margin-left:.25rem;margin-right:.25rem}.-mx-3{margin-left:-.75rem;margin-right:-.75rem}.-mx-4{margin-left:-1rem;margin-right:-1rem}.mx-3{margin-left:.75rem;margin-right:.75rem}.ml-auto{margin-left:auto}.mr-auto{margin-right:auto}.mb-8{margin-bottom:2rem}.mb-3{margin-bottom:.75rem}.mb-5{margin-bottom:1.25rem}.mt-3{margin-top:.75rem}.mb-2{margin-bottom:.5rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.-mt-24{margin-top:-6rem}.mb-4{margin-bottom:1rem}.-mt-16{margin-top:-4rem}.mr-48{margin-right:12rem}.mt-5{margin-top:1.25rem}.mt-1{margin-top:.25rem}.ml-1{margin-left:.25rem}.mt-16{margin-top:4rem}.mb-12{margin-bottom:3rem}.mb-10{margin-bottom:2.5rem}.-mr-0{margin-right:0}.-ml-2{margin-left:-.5rem}.ml-0{margin-left:0}.mr-0{margin-right:0}.-mt-1{margin-top:-.25rem}.ml-3{margin-left:.75rem}.mb-1{margin-bottom:.25rem}.-mt-20{margin-top:-5rem}.ml-10{margin-left:2.5rem}.mt-auto{margin-top:auto}.-ml-5{margin-left:-1.25rem}.mt-10{margin-top:2.5rem}.mt-4{margin-top:1rem}.mt-8{margin-top:2rem}.mt-32{margin-top:8rem}.mt-20{margin-top:5rem}.mr-4{margin-right:1rem}.ml-2{margin-left:.5rem}.mb-6{margin-bottom:1.5rem}.mr-1{margin-right:.25rem}.-mb-2{margin-bottom:-.5rem}.-ml-4{margin-left:-1rem}.-ml-8{margin-left:-2rem}.ml-4{margin-left:1rem}.-ml-6{margin-left:-1.5rem}.mb-0{margin-bottom:0}.box-border{box-sizing:border-box}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.contents{display:contents}.hidden{display:none}.h-1{height:.25rem}.h-56{height:14rem}.h-16{height:4rem}.h-full{height:100%}.h-auto{height:auto}.h-4{height:1rem}.h-8{height:2rem}.h-10{height:2.5rem}.h-24{height:6rem}.h-6{height:1.5rem}.h-5{height:1.25rem}.h-screen{height:100vh}.h-0{height:0}.max-h-\[75vh\]{max-height:75vh}.min-h-screen{min-height:100vh}.min-h-\[calc\(100vh_-_4rem\)\]{min-height:calc(100vh - 4rem)}.min-h-\[300px\]{min-height:300px}.w-1{width:.25rem}.w-16{width:4rem}.w-full{width:100%}.w-96{width:24rem}.w-screen{width:100vw}.w-5\/6{width:83.333333%}.w-20{width:5rem}.w-auto{width:auto}.w-8{width:2rem}.w-1\/3{width:33.333333%}.w-10{width:2.5rem}.w-24{width:6rem}.w-6{width:1.5rem}.w-fit{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.w-5{width:1.25rem}.w-64{width:16rem}.w-\[70ch\]{width:70ch}.min-w-\[280px\]{min-width:280px}.min-w-\[16rem\]{min-width:16rem}.max-w-sm{max-width:24rem}.max-w-7xl{max-width:80rem}.max-w-md{max-width:28rem}.max-w-full{max-width:100%}.max-w-6xl{max-width:72rem}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-3xl{max-width:48rem}.max-w-5xl{max-width:64rem}.max-w-xl{max-width:36rem}.max-w-lg{max-width:32rem}.max-w-xs{max-width:20rem}.max-w-\[1000px\]{max-width:1000px}.flex-auto{flex:1 1 auto}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.rotate-45{--tw-rotate:45deg}.rotate-45,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.cursor-help{cursor:help}.cursor-auto{cursor:auto}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.content-center{align-content:center}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-4{gap:1rem}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.self-start{align-self:flex-start}.self-center{align-self:center}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-hidden{overflow-y:hidden}.whitespace-nowrap{white-space:nowrap}.rounded-lg{border-radius:.5rem}.rounded-full{border-radius:9999px}.rounded{border-radius:.25rem}.rounded-xl{border-radius:.75rem}.rounded-md{border-radius:.375rem}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.border-2{border-width:2px}.border{border-width:1px}.border-0{border-width:0}.border-4{border-width:4px}.border-y{border-top-width:1px}.border-b,.border-y{border-bottom-width:1px}.border-t{border-top-width:1px}.border-b-4{border-bottom-width:4px}.border-l-\[0\.325rem\]{border-left-width:.325rem}.border-l-4{border-left-width:4px}.border-solid{border-style:solid}.border-black{--tw-border-opacity:1;border-color:rgb(0 0 0/var(--tw-border-opacity))}.border-indigo-500{--tw-border-opacity:1;border-color:rgb(89 86 235/var(--tw-border-opacity))}.border-purple-500{--tw-border-opacity:1;border-color:rgb(168 85 247/var(--tw-border-opacity))}.border-blue-400{--tw-border-opacity:1;border-color:rgb(96 165 250/var(--tw-border-opacity))}.border-teal-500{--tw-border-opacity:1;border-color:rgb(20 184 166/var(--tw-border-opacity))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity))}.border-yellow-400{--tw-border-opacity:1;border-color:rgb(250 204 21/var(--tw-border-opacity))}.border-indigo-400{--tw-border-opacity:1;border-color:rgb(129 140 248/var(--tw-border-opacity))}.border-transparent{border-color:transparent}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-gray-400{--tw-bg-opacity:1;background-color:rgb(156 163 175/var(--tw-bg-opacity))}.bg-indigo-500{--tw-bg-opacity:1;background-color:rgb(89 86 235/var(--tw-bg-opacity))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}.bg-violet-300{--tw-bg-opacity:1;background-color:rgb(196 181 253/var(--tw-bg-opacity))}.bg-purple-500{--tw-bg-opacity:1;background-color:rgb(168 85 247/var(--tw-bg-opacity))}.bg-blue-400{--tw-bg-opacity:1;background-color:rgb(96 165 250/var(--tw-bg-opacity))}.bg-teal-500{--tw-bg-opacity:1;background-color:rgb(20 184 166/var(--tw-bg-opacity))}.bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity))}.bg-green-500{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity))}.bg-gray-300{--tw-bg-opacity:1;background-color:rgb(209 213 219/var(--tw-bg-opacity))}.bg-yellow-300{--tw-bg-opacity:1;background-color:rgb(253 224 71/var(--tw-bg-opacity))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.bg-black\/50{background-color:rgba(0,0,0,.5)}.bg-black\/5{background-color:rgba(0,0,0,.05)}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-purple-500{--tw-gradient-from:#a855f7;--tw-gradient-to:rgba(168,85,247,0);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.to-red-600{--tw-gradient-to:#dc2626}.bg-cover{background-size:cover}.bg-contain{background-size:contain}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.bg-no-repeat{background-repeat:no-repeat}.fill-current{fill:currentColor}.fill-black{fill:#000}.object-cover{-o-object-fit:cover;object-fit:cover}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-2{padding:.5rem}.p-0{padding:0}.p-8{padding:2rem}.p-12{padding:3rem}.py-0{padding-bottom:0;padding-top:0}.py-4{padding-bottom:1rem;padding-top:1rem}.py-8{padding-bottom:2rem;padding-top:2rem}.px-0{padding-left:0;padding-right:0}.px-4{padding-left:1rem;padding-right:1rem}.px-8{padding-left:2rem;padding-right:2rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-16{padding-bottom:4rem;padding-top:4rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-10{padding-bottom:2.5rem;padding-top:2.5rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-20{padding-bottom:5rem;padding-top:5rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-12{padding-bottom:3rem;padding-top:3rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-32{padding-bottom:8rem;padding-top:8rem}.px-10{padding-left:2.5rem;padding-right:2.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.py-24{padding-bottom:6rem;padding-top:6rem}.pb-3{padding-bottom:.75rem}.pt-4{padding-top:1rem}.pt-2{padding-top:.5rem}.pb-4{padding-bottom:1rem}.pt-36{padding-top:9rem}.pl-0{padding-left:0}.pr-0{padding-right:0}.pb-20{padding-bottom:5rem}.pl-12{padding-left:3rem}.pt-24{padding-top:6rem}.pb-32{padding-bottom:8rem}.pt-8{padding-top:2rem}.pt-10{padding-top:2.5rem}.pr-8{padding-right:2rem}.pb-8{padding-bottom:2rem}.pb-6{padding-bottom:1.5rem}.pt-7{padding-top:1.75rem}.pb-7{padding-bottom:1.75rem}.pl-6{padding-left:1.5rem}.pr-5{padding-right:1.25rem}.pl-4{padding-left:1rem}.pr-20{padding-right:5rem}.pt-1{padding-top:.25rem}.pt-12{padding-top:3rem}.pl-1{padding-left:.25rem}.pr-6{padding-right:1.5rem}.pr-4{padding-right:1rem}.pt-6{padding-top:1.5rem}.pt-3{padding-top:.75rem}.pb-12{padding-bottom:3rem}.pl-8{padding-left:2rem}.pl-2{padding-left:.5rem}.pl-5{padding-left:1.25rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-sans{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-5xl{font-size:3rem;line-height:1}.text-lg{font-size:1.125rem}.text-lg,.text-xl{line-height:1.75rem}.text-xl{font-size:1.25rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-base{font-size:1rem;line-height:1.5rem}.text-xs{font-size:.75rem;line-height:1rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-\[90\%\]{font-size:90%}.font-light{font-weight:300}.font-bold{font-weight:700}.font-black{font-weight:900}.font-semibold{font-weight:600}.font-medium{font-weight:500}.font-extrabold{font-weight:800}.font-normal{font-weight:400}.uppercase{text-transform:uppercase}.leading-normal{line-height:1.5}.leading-tight{line-height:1.25}.leading-none{line-height:1}.leading-10{line-height:2.5rem}.leading-5{line-height:1.25rem}.leading-6{line-height:1.5rem}.leading-7{line-height:1.75rem}.leading-relaxed{line-height:1.625}.leading-8{line-height:2rem}.leading-4{line-height:1rem}.tracking-wide{letter-spacing:.025em}.tracking-tight{letter-spacing:-.025em}.tracking-normal{letter-spacing:0}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.text-slate-700{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity))}.text-slate-900{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.text-violet-300{--tw-text-opacity:1;color:rgb(196 181 253/var(--tw-text-opacity))}.text-violet-900{--tw-text-opacity:1;color:rgb(76 29 149/var(--tw-text-opacity))}.text-indigo-500{--tw-text-opacity:1;color:rgb(89 86 235/var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}.text-purple-500{--tw-text-opacity:1;color:rgb(168 85 247/var(--tw-text-opacity))}.text-blue-400{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}.text-teal-500{--tw-text-opacity:1;color:rgb(20 184 166/var(--tw-text-opacity))}.text-gray-100{--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}.text-blue-500{--tw-text-opacity:1;color:rgb(59 130 246/var(--tw-text-opacity))}.text-green-500{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-indigo-700{--tw-text-opacity:1;color:rgb(67 56 202/var(--tw-text-opacity))}.text-pink-500{--tw-text-opacity:1;color:rgb(236 72 153/var(--tw-text-opacity))}.text-yellow-500{--tw-text-opacity:1;color:rgb(234 179 8/var(--tw-text-opacity))}.text-transparent{color:transparent}.text-indigo-600{--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity))}.text-slate-800{--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}.text-gray-200{--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity))}.no-underline{-webkit-text-decoration-line:none;text-decoration-line:none}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-75{opacity:.75}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.shadow-xl{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color)}.shadow-lg,.shadow-xl{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-2xl{--tw-shadow:0 25px 50px -12px rgba(0,0,0,.25);--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color)}.shadow-2xl,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.drop-shadow-2xl{--tw-drop-shadow:drop-shadow(0 25px 25px rgba(0,0,0,.15));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-shadow{transition-duration:.15s;transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-all{transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-opacity{transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-text-decoration-color,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,fill,stroke,-webkit-text-decoration-color;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,-webkit-text-decoration-color;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}.duration-75{transition-duration:75ms}.duration-300{transition-duration:.3s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}[x-cloak]{display:none!important}blockquote.info{border-color:#1e90ff}blockquote.warning{border-color:orange}blockquote.danger{border-color:red}.bg-standard{background:#fff;color:#000}.bg-offset{background-color:#f6f6f7;color:#000}.dark .bg-standard{background-color:#1e293b;color:#fff}.dark .bg-offset{background-color:#172133;color:#fff}.btn{margin:.25rem .5rem;padding:.5rem 1.5rem}.btn,.btn-lg{border-radius:.25rem}.btn-lg{margin:.25rem .75rem;padding:.75rem 2.5rem}.btn-default{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(79 70 229/var(--tw-bg-opacity));border-radius:.375rem;color:rgb(255 255 255/var(--tw-text-opacity))}.btn-default:hover{--tw-bg-opacity:1;background-color:rgb(67 56 202/var(--tw-bg-opacity))}.btn-default:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(165 180 252/var(--tw-ring-opacity));box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);outline:2px solid transparent;outline-offset:2px}.btn-primary{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity));border-radius:.375rem;color:rgb(255 255 255/var(--tw-text-opacity))}.btn-primary:hover{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity))}.btn-primary:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(147 197 253/var(--tw-ring-opacity));box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);outline:2px solid transparent;outline-offset:2px}.btn-secondary{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(100 116 139/var(--tw-bg-opacity));border-radius:.375rem;color:rgb(255 255 255/var(--tw-text-opacity))}.btn-secondary:hover{--tw-bg-opacity:1;background-color:rgb(71 85 105/var(--tw-bg-opacity))}.btn-secondary:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity));box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);outline:2px solid transparent;outline-offset:2px}img.ext-link{display:inline;margin:-4px 0 0 2px}.dark img.ext-link{filter:invert(100%)}.flex-list{display:flex;flex-direction:row;flex-wrap:wrap}.flex-list li{margin-right:2.5rem;white-space:nowrap}.list-compact li>p{margin-bottom:.25rem;margin-top:.25rem}.hover\:bg-gray-50:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.hover\:bg-black\/10:hover{background-color:rgba(0,0,0,.1)}.hover\:bg-black\/5:hover{background-color:rgba(0,0,0,.05)}.hover\:text-indigo-500:hover{--tw-text-opacity:1;color:rgb(89 86 235/var(--tw-text-opacity))}.hover\:text-gray-900:hover{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.hover\:text-black:hover{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.hover\:text-gray-700:hover{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.hover\:underline:hover{-webkit-text-decoration-line:underline;text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-xl:hover{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color)}.hover\:shadow-xl:hover,.hover\:shadow:hover{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.hover\:shadow:hover{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.focus\:not-sr-only:focus{clip:auto;height:auto;margin:0;overflow:visible;padding:0;position:static;white-space:normal;width:auto}.focus\:absolute:focus{position:absolute}.focus\:mx-auto:focus{margin-left:auto;margin-right:auto}.focus\:mt-2:focus{margin-top:.5rem}.focus\:w-64:focus{width:16rem}.focus\:p-2:focus{padding:.5rem}.group:hover .group-hover\:m-0{margin:0}.group:hover .group-hover\:bg-violet-400{--tw-bg-opacity:1;background-color:rgb(167 139 250/var(--tw-bg-opacity))}.group:hover .group-hover\:bg-violet-500{--tw-bg-opacity:1;background-color:rgb(139 92 246/var(--tw-bg-opacity))}.group:hover .group-hover\:bg-red-300{--tw-bg-opacity:1;background-color:rgb(252 165 165/var(--tw-bg-opacity))}.group:hover .group-hover\:bg-blue-300{--tw-bg-opacity:1;background-color:rgb(147 197 253/var(--tw-bg-opacity))}.group:hover .group-hover\:bg-green-300{--tw-bg-opacity:1;background-color:rgb(134 239 172/var(--tw-bg-opacity))}.group:hover .group-hover\:bg-violet-300{--tw-bg-opacity:1;background-color:rgb(196 181 253/var(--tw-bg-opacity))}.group:hover .group-hover\:text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.group:hover .group-hover\:text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.group:hover .group-hover\:opacity-100{opacity:1}.prose-h1\:mb-3 :is(:where(h1):not(:where([class~=not-prose] *))){margin-bottom:.75rem}.prose-p\:my-3 :is(:where(p):not(:where([class~=not-prose] *))){margin-bottom:.75rem;margin-top:.75rem}.dark .dark\:prose-invert{--tw-prose-body:var(--tw-prose-invert-body);--tw-prose-headings:var(--tw-prose-invert-headings);--tw-prose-lead:var(--tw-prose-invert-lead);--tw-prose-links:var(--tw-prose-invert-links);--tw-prose-bold:var(--tw-prose-invert-bold);--tw-prose-counters:var(--tw-prose-invert-counters);--tw-prose-bullets:var(--tw-prose-invert-bullets);--tw-prose-hr:var(--tw-prose-invert-hr);--tw-prose-quotes:var(--tw-prose-invert-quotes);--tw-prose-quote-borders:var(--tw-prose-invert-quote-borders);--tw-prose-captions:var(--tw-prose-invert-captions);--tw-prose-code:var(--tw-prose-invert-code);--tw-prose-pre-code:var(--tw-prose-invert-pre-code);--tw-prose-pre-bg:var(--tw-prose-invert-pre-bg);--tw-prose-th-borders:var(--tw-prose-invert-th-borders);--tw-prose-td-borders:var(--tw-prose-invert-td-borders)}.dark .dark\:prose-invert :where(a):not(:where([class~=not-prose] *)){color:#818cf8}.dark .dark\:prose-invert :where(a):not(:where([class~=not-prose] *)):hover{color:#6366f1}.dark .dark\:block{display:block}.dark .dark\:hidden{display:none}.dark .dark\:border-gray-700{--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}.dark .dark\:border-gray-600{--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity))}.dark .dark\:border-gray-800{--tw-border-opacity:1;border-color:rgb(31 41 55/var(--tw-border-opacity))}.dark .dark\:border-\[\#1b2533\]{--tw-border-opacity:1;border-color:rgb(27 37 51/var(--tw-border-opacity))}.dark .dark\:bg-slate-900{--tw-bg-opacity:1;background-color:rgb(15 23 42/var(--tw-bg-opacity))}.dark .dark\:bg-gray-500{--tw-bg-opacity:1;background-color:rgb(107 114 128/var(--tw-bg-opacity))}.dark .dark\:bg-indigo-400{--tw-bg-opacity:1;background-color:rgb(129 140 248/var(--tw-bg-opacity))}.dark .dark\:bg-yellow-500{--tw-bg-opacity:1;background-color:rgb(234 179 8/var(--tw-bg-opacity))}.dark .dark\:bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.dark .dark\:bg-slate-800{--tw-bg-opacity:1;background-color:rgb(30 41 59/var(--tw-bg-opacity))}.dark .dark\:bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.dark .dark\:bg-gray-600{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity))}.dark .dark\:bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}.dark .dark\:bg-black\/10{background-color:rgba(0,0,0,.1)}.dark .dark\:bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.dark .dark\:fill-gray-200{fill:#e5e7eb}.dark .dark\:fill-white{fill:#fff}.dark .dark\:font-medium{font-weight:500}.dark .dark\:text-slate-200{--tw-text-opacity:1;color:rgb(226 232 240/var(--tw-text-opacity))}.dark .dark\:text-gray-200{--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity))}.dark .dark\:text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}.dark .dark\:text-gray-100{--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity))}.dark .dark\:text-indigo-500{--tw-text-opacity:1;color:rgb(89 86 235/var(--tw-text-opacity))}.dark .dark\:text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.dark .dark\:text-slate-900{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.dark .dark\:text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.dark .dark\:text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.dark .dark\:text-indigo-400{--tw-text-opacity:1;color:rgb(129 140 248/var(--tw-text-opacity))}.dark .dark\:opacity-90{opacity:.9}.dark .dark\:hover\:bg-black\/10:hover{background-color:rgba(0,0,0,.1)}.dark .dark\:hover\:text-gray-100:hover{--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity))}.dark .dark\:hover\:text-white:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.dark .group:hover .dark\:group-hover\:bg-violet-200{--tw-bg-opacity:1;background-color:rgb(221 214 254/var(--tw-bg-opacity))}.dark .group:hover .dark\:group-hover\:text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}@media (min-width:640px){.sm\:mx-2{margin-left:.5rem;margin-right:.5rem}.sm\:-mx-3{margin-left:-.75rem;margin-right:-.75rem}.sm\:mb-0{margin-bottom:0}.sm\:-mr-20{margin-right:-5rem}.sm\:mr-10{margin-right:2.5rem}.sm\:mr-4{margin-right:1rem}.sm\:ml-4{margin-left:1rem}.sm\:mr-2{margin-right:.5rem}.sm\:mb-8{margin-bottom:2rem}.sm\:mt-6{margin-top:1.5rem}.sm\:mt-4{margin-top:1rem}.sm\:block{display:block}.sm\:flex{display:flex}.sm\:w-1\/2{width:50%}.sm\:w-2\/3{width:66.666667%}.sm\:w-1\/3{width:33.333333%}.sm\:w-full{width:100%}.sm\:max-w-md{max-width:28rem}.sm\:flex-row{flex-direction:row}.sm\:flex-wrap{flex-wrap:wrap}.sm\:items-center{align-items:center}.sm\:justify-center{justify-content:center}.sm\:justify-between{justify-content:space-between}.sm\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.sm\:whitespace-nowrap{white-space:nowrap}.sm\:rounded-xl{border-radius:.75rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-32{padding-bottom:8rem;padding-top:8rem}.sm\:px-8{padding-left:2rem;padding-right:2rem}.sm\:px-20{padding-left:5rem;padding-right:5rem}.sm\:pl-8{padding-left:2rem}.sm\:pl-20{padding-left:5rem}.sm\:pr-8{padding-right:2rem}.sm\:pr-10{padding-right:2.5rem}.sm\:pl-12{padding-left:3rem}.sm\:pr-4{padding-right:1rem}.sm\:pl-4{padding-left:1rem}.sm\:pr-5{padding-right:1.25rem}.sm\:pr-12{padding-right:3rem}.sm\:text-center{text-align:center}.sm\:text-5xl{font-size:3rem;line-height:1}.sm\:text-4xl{font-size:2.25rem;line-height:2.5rem}.sm\:leading-none{line-height:1}.sm\:shadow-xl{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}}@media (min-width:768px){.md\:visible{visibility:visible}.md\:top-0{top:0}.md\:left-64{left:16rem}.md\:left-0{left:0}.md\:order-none{order:0}.md\:my-6{margin-bottom:1.5rem;margin-top:1.5rem}.md\:mx-2{margin-left:.5rem;margin-right:.5rem}.md\:my-0{margin-bottom:0}.md\:mt-0,.md\:my-0{margin-top:0}.md\:mr-10{margin-right:2.5rem}.md\:mb-12{margin-bottom:3rem}.md\:mb-0{margin-bottom:0}.md\:ml-0{margin-left:0}.md\:mt-20{margin-top:5rem}.md\:ml-4{margin-left:1rem}.md\:mt-8{margin-top:2rem}.md\:block{display:block}.md\:inline-block{display:inline-block}.md\:inline{display:inline}.md\:flex{display:flex}.md\:hidden{display:none}.md\:h-full{height:100%}.md\:min-h-screen{min-height:100vh}.md\:w-1\/2{width:50%}.md\:w-96{width:24rem}.md\:w-1\/3{width:33.333333%}.md\:w-2\/3{width:66.666667%}.md\:w-auto{width:auto}.md\:w-full{width:100%}.md\:w-\[calc\(100vw_-_16rem\)\]{width:calc(100vw - 16rem)}.md\:max-w-lg{max-width:32rem}.md\:max-w-3xl{max-width:48rem}.md\:max-w-none{max-width:none}.md\:max-w-2xl{max-width:42rem}.md\:flex-grow-0{flex-grow:0}.md\:flex-grow{flex-grow:1}.md\:flex-row{flex-direction:row}.md\:flex-nowrap{flex-wrap:nowrap}.md\:items-start{align-items:flex-start}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}.md\:space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.md\:border-none{border-style:none}.md\:bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.md\:bg-transparent{background-color:transparent}.md\:bg-left{background-position:0}.md\:py-40{padding-bottom:10rem;padding-top:10rem}.md\:px-0{padding-left:0;padding-right:0}.md\:px-3{padding-left:.75rem;padding-right:.75rem}.md\:px-32{padding-left:8rem;padding-right:8rem}.md\:px-20{padding-left:5rem;padding-right:5rem}.md\:py-0{padding-bottom:0;padding-top:0}.md\:px-16{padding-left:4rem;padding-right:4rem}.md\:py-16{padding-bottom:4rem;padding-top:4rem}.md\:pb-0{padding-bottom:0}.md\:pt-64{padding-top:16rem}.md\:pt-40{padding-top:10rem}.md\:pb-64{padding-bottom:16rem}.md\:pb-56{padding-bottom:14rem}.md\:pt-16{padding-top:4rem}.md\:pt-20{padding-top:5rem}.md\:pb-24{padding-bottom:6rem}.md\:pl-10{padding-left:2.5rem}.md\:pl-6{padding-left:1.5rem}.md\:pl-0{padding-left:0}.md\:text-left{text-align:left}.md\:text-center{text-align:center}.md\:text-3xl{font-size:1.875rem;line-height:2.25rem}.md\:text-lg{font-size:1.125rem;line-height:1.75rem}.md\:text-4xl{font-size:2.25rem;line-height:2.5rem}.md\:text-6xl{font-size:3.75rem;line-height:1}.md\:text-2xl{font-size:1.5rem;line-height:2rem}.md\:text-5xl{font-size:3rem;line-height:1}.md\:shadow-none{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.dark .dark\:md\:bg-transparent{background-color:transparent}}@media (min-width:1024px){.lg\:my-8{margin-bottom:2rem;margin-top:2rem}.lg\:mx-0{margin-left:0;margin-right:0}.lg\:my-0{margin-bottom:0;margin-top:0}.lg\:-mt-4{margin-top:-1rem}.lg\:mb-12{margin-bottom:3rem}.lg\:mb-0{margin-bottom:0}.lg\:mt-4{margin-top:1rem}.lg\:mt-8{margin-top:2rem}.lg\:mt-0{margin-top:0}.lg\:ml-8{margin-left:2rem}.lg\:block{display:block}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:w-3\/5{width:60%}.lg\:w-2\/5{width:40%}.lg\:w-2\/3{width:66.666667%}.lg\:w-1\/3{width:33.333333%}.lg\:w-1\/2{width:50%}.lg\:max-w-lg{max-width:32rem}.lg\:max-w-3xl{max-width:48rem}.lg\:flex-row{flex-direction:row}.lg\:flex-nowrap{flex-wrap:nowrap}.lg\:items-stretch{align-items:stretch}.lg\:space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.lg\:rounded-none{border-radius:0}.lg\:rounded-r-none{border-bottom-right-radius:0;border-top-right-radius:0}.lg\:rounded-l-lg{border-bottom-left-radius:.5rem;border-top-left-radius:.5rem}.lg\:rounded-l-none{border-bottom-left-radius:0;border-top-left-radius:0}.lg\:rounded-r-lg{border-bottom-right-radius:.5rem;border-top-right-radius:.5rem}.lg\:border-l-0{border-left-width:0}.lg\:border-r-0{border-right-width:0}.lg\:bg-center{background-position:50%}.lg\:px-5{padding-left:1.25rem;padding-right:1.25rem}.lg\:px-6{padding-left:1.5rem;padding-right:1.5rem}.lg\:px-16{padding-left:4rem;padding-right:4rem}.lg\:px-4{padding-left:1rem;padding-right:1rem}.lg\:px-8{padding-left:2rem;padding-right:2rem}.lg\:pt-24{padding-top:6rem}.lg\:pr-0{padding-right:0}.lg\:pr-32{padding-right:8rem}.lg\:pr-8{padding-right:2rem}.lg\:text-4xl{font-size:2.25rem;line-height:2.5rem}.lg\:text-5xl{font-size:3rem;line-height:1}.lg\:text-2xl{font-size:1.5rem;line-height:2rem}.lg\:text-xl{font-size:1.25rem;line-height:1.75rem}.lg\:text-lg{font-size:1.125rem;line-height:1.75rem}.lg\:text-3xl{font-size:1.875rem;line-height:2.25rem}.lg\:text-7xl{font-size:4.5rem;line-height:1}}@media (min-width:1280px){.xl\:mr-48{margin-right:12rem}.xl\:-mt-14{margin-top:-3.5rem}.xl\:mb-16{margin-bottom:4rem}.xl\:mb-6{margin-bottom:1.5rem}.xl\:mt-0{margin-top:0}.xl\:inline{display:inline}.xl\:w-1\/3{width:33.333333%}.xl\:w-1\/2{width:50%}.xl\:max-w-full{max-width:100%}.xl\:flex-row{flex-direction:row}.xl\:space-y-9>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2.25rem*var(--tw-space-y-reverse));margin-top:calc(2.25rem*(1 - var(--tw-space-y-reverse)))}.xl\:px-0{padding-left:0;padding-right:0}.xl\:px-12{padding-left:3rem;padding-right:3rem}.xl\:px-4{padding-left:1rem;padding-right:1rem}.xl\:py-3{padding-bottom:.75rem;padding-top:.75rem}.xl\:px-5{padding-left:1.25rem;padding-right:1.25rem}.xl\:pl-0{padding-left:0}.xl\:pr-0{padding-right:0}.xl\:pt-40{padding-top:10rem}.xl\:pl-10{padding-left:2.5rem}.xl\:pl-16{padding-left:4rem}.xl\:pr-20{padding-right:5rem}.xl\:pr-32{padding-right:8rem}.xl\:pl-32{padding-left:8rem}.xl\:text-4xl{font-size:2.25rem;line-height:2.5rem}.xl\:text-6xl{font-size:3.75rem;line-height:1}.xl\:text-3xl{font-size:1.875rem;line-height:2.25rem}.xl\:text-xl{font-size:1.25rem;line-height:1.75rem}.xl\:text-5xl{font-size:3rem;line-height:1}}
diff --git a/docs/posts.html b/docs/posts.html
index 98bcd30b..63a2a432 100644
--- a/docs/posts.html
+++ b/docs/posts.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/posts/announcing-the-first-release-candidate-of-hydephp.html b/docs/posts/announcing-the-first-release-candidate-of-hydephp.html
index a93f2681..50087227 100644
--- a/docs/posts/announcing-the-first-release-candidate-of-hydephp.html
+++ b/docs/posts/announcing-the-first-release-candidate-of-hydephp.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/announcing-the-first-release-of-hydephp.html b/docs/posts/announcing-the-first-release-of-hydephp.html
index 721b80c3..d50d2c0b 100644
--- a/docs/posts/announcing-the-first-release-of-hydephp.html
+++ b/docs/posts/announcing-the-first-release-of-hydephp.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/creating-a-new-hyde-site-from-scratch.html b/docs/posts/creating-a-new-hyde-site-from-scratch.html
index 39dd9446..39b3e5d6 100644
--- a/docs/posts/creating-a-new-hyde-site-from-scratch.html
+++ b/docs/posts/creating-a-new-hyde-site-from-scratch.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/creating-a-photography-portfolio-site-with-hydephp.html b/docs/posts/creating-a-photography-portfolio-site-with-hydephp.html
index 8e9ca983..d408b061 100644
--- a/docs/posts/creating-a-photography-portfolio-site-with-hydephp.html
+++ b/docs/posts/creating-a-photography-portfolio-site-with-hydephp.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/creating-a-static-html-post-using-hydephp.html b/docs/posts/creating-a-static-html-post-using-hydephp.html
index 4f1e0ac8..afd79413 100644
--- a/docs/posts/creating-a-static-html-post-using-hydephp.html
+++ b/docs/posts/creating-a-static-html-post-using-hydephp.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/github-actions-deployment.html b/docs/posts/github-actions-deployment.html
index 3292381c..5c9ade66 100644
--- a/docs/posts/github-actions-deployment.html
+++ b/docs/posts/github-actions-deployment.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/how-to-turn-your-github-readme-into-a-static-website.html b/docs/posts/how-to-turn-your-github-readme-into-a-static-website.html
index 0b0a7b0f..82737b15 100644
--- a/docs/posts/how-to-turn-your-github-readme-into-a-static-website.html
+++ b/docs/posts/how-to-turn-your-github-readme-into-a-static-website.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/hyde-feature-highlights.html b/docs/posts/hyde-feature-highlights.html
index 8373da25..ecaedbf4 100644
--- a/docs/posts/hyde-feature-highlights.html
+++ b/docs/posts/hyde-feature-highlights.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/hydephp-open-collective-launch.html b/docs/posts/hydephp-open-collective-launch.html
index 3a1ba749..f820ae93 100644
--- a/docs/posts/hydephp-open-collective-launch.html
+++ b/docs/posts/hydephp-open-collective-launch.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/hydephp-version-1-4-released.html b/docs/posts/hydephp-version-1-4-released.html
index c75777a5..b3abfeb1 100644
--- a/docs/posts/hydephp-version-1-4-released.html
+++ b/docs/posts/hydephp-version-1-4-released.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/hydephp-version-1-5-released.html b/docs/posts/hydephp-version-1-5-released.html
index 13565c52..0a561dd3 100644
--- a/docs/posts/hydephp-version-1-5-released.html
+++ b/docs/posts/hydephp-version-1-5-released.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/internal-architecture-of-hydephp-part-1.html b/docs/posts/internal-architecture-of-hydephp-part-1.html
index 8bd7228c..18a1f9f4 100644
--- a/docs/posts/internal-architecture-of-hydephp-part-1.html
+++ b/docs/posts/internal-architecture-of-hydephp-part-1.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/internal-architecture-of-hydephp-part-2.html b/docs/posts/internal-architecture-of-hydephp-part-2.html
index 6ebfb967..71cfffb1 100644
--- a/docs/posts/internal-architecture-of-hydephp-part-2.html
+++ b/docs/posts/internal-architecture-of-hydephp-part-2.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/internal-architecture-of-hydephp-part-3.html b/docs/posts/internal-architecture-of-hydephp-part-3.html
index f6aebd31..f4d2f0d7 100644
--- a/docs/posts/internal-architecture-of-hydephp-part-3.html
+++ b/docs/posts/internal-architecture-of-hydephp-part-3.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/introducing-images.html b/docs/posts/introducing-images.html
index a5663690..b646c57f 100644
--- a/docs/posts/introducing-images.html
+++ b/docs/posts/introducing-images.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/introducing-the-hydephp-github-action.html b/docs/posts/introducing-the-hydephp-github-action.html
index 887e1214..b286eb62 100644
--- a/docs/posts/introducing-the-hydephp-github-action.html
+++ b/docs/posts/introducing-the-hydephp-github-action.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/introducing-the-hydephp-ui-kit.html b/docs/posts/introducing-the-hydephp-ui-kit.html
index 5d92dda4..ad9d0dcd 100644
--- a/docs/posts/introducing-the-hydephp-ui-kit.html
+++ b/docs/posts/introducing-the-hydephp-ui-kit.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/release-date-announcement.html b/docs/posts/release-date-announcement.html
index e58d6019..f29f8f8c 100644
--- a/docs/posts/release-date-announcement.html
+++ b/docs/posts/release-date-announcement.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/sunsetting-hydephp-dot-se.html b/docs/posts/sunsetting-hydephp-dot-se.html
index 1fa88f51..7f35cdbf 100644
--- a/docs/posts/sunsetting-hydephp-dot-se.html
+++ b/docs/posts/sunsetting-hydephp-dot-se.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/what-is-hyde.html b/docs/posts/what-is-hyde.html
index 06edc089..95890759 100644
--- a/docs/posts/what-is-hyde.html
+++ b/docs/posts/what-is-hyde.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/what-is-markdown.html b/docs/posts/what-is-markdown.html
index 4ce04a12..e65adba0 100644
--- a/docs/posts/what-is-markdown.html
+++ b/docs/posts/what-is-markdown.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/posts/why-static-sites.html b/docs/posts/why-static-sites.html
index 37b785dc..cb89dc19 100644
--- a/docs/posts/why-static-sites.html
+++ b/docs/posts/why-static-sites.html
@@ -41,7 +41,7 @@
-
+
diff --git a/docs/security.html b/docs/security.html
index 7313312a..18eec8f3 100644
--- a/docs/security.html
+++ b/docs/security.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/sitemap.html b/docs/sitemap.html
index 206a00da..a8358cd8 100644
--- a/docs/sitemap.html
+++ b/docs/sitemap.html
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/sitemap.xml b/docs/sitemap.xml
index d0466274..c1ab75c6 100644
--- a/docs/sitemap.xml
+++ b/docs/sitemap.xml
@@ -1,2 +1,2 @@
-https://hydephp.com/4042024-06-08T14:28:49+00:00daily0.5https://hydephp.com/about2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/dashboard2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/demos2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/features2024-06-08T14:28:49+00:00daily0.9https://hydephp.com2024-06-08T14:28:49+00:00daily1https://hydephp.com/posts2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/brand2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/changelog2024-06-08T14:29:11+00:00daily0.9https://hydephp.com/code-of-conduct2024-06-08T14:29:12+00:00daily0.9https://hydephp.com/community2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/contact2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/contributing2024-06-08T14:29:12+00:00daily0.9https://hydephp.com/legal2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/license2024-06-08T14:29:11+00:00daily0.9https://hydephp.com/security2024-06-08T14:29:12+00:00daily0.9https://hydephp.com/sitemap2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/brand/terms2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/guides/installation2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/posts/announcing-the-first-release-candidate-of-hydephp2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/announcing-the-first-release-of-hydephp2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/creating-a-new-hyde-site-from-scratch2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/creating-a-photography-portfolio-site-with-hydephp2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/creating-a-static-html-post-using-hydephp2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/github-actions-deployment2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/how-to-turn-your-github-readme-into-a-static-website2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/hyde-feature-highlights2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/hydephp-open-collective-launch2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/hydephp-version-1-4-released2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/hydephp-version-1-5-released2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/internal-architecture-of-hydephp-part-12024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/internal-architecture-of-hydephp-part-22024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/internal-architecture-of-hydephp-part-32024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/introducing-images2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/introducing-the-hydephp-github-action2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/introducing-the-hydephp-ui-kit2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/release-date-announcement2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/sunsetting-hydephp-dot-se2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/what-is-hyde2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/what-is-markdown2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/posts/why-static-sites2024-06-08T14:28:49+00:00daily0.75https://hydephp.com/docs/1.x2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/advanced-features2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/build-tasks2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/hyde-pages2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/in-memory-pages2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/architecture-concepts2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/autodiscovery2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/automatic-routing2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/dynamic-data-discovery2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/extensions-api2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/page-models2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/the-hydekernel2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/blog-posts2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/compile-and-deploy2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/documentation-pages2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/managing-assets2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/static-pages2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/advanced-customization2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/advanced-markdown2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/collections2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/customization2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/helpers2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/navigation2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/troubleshooting2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/updating-hyde2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/extensions2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/realtime-compiler2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/third-party-integrations2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/ui-kit2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/console-commands2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/core-concepts2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/front-matter2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/quickstart2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/configuration2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/directory-structure2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/getting-started2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/docs/1.x/installation2024-06-08T14:28:49+00:00daily0.9https://hydephp.com/blog2024-06-08T14:29:33+00:00daily0.5
+https://hydephp.com/4042024-07-05T13:11:03+00:00daily0.5https://hydephp.com/about2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/dashboard2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/demos2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/features2024-07-05T13:11:03+00:00daily0.9https://hydephp.com2024-07-05T13:11:03+00:00daily1https://hydephp.com/posts2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/brand2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/changelog2024-07-05T13:11:27+00:00daily0.9https://hydephp.com/code-of-conduct2024-07-05T13:11:28+00:00daily0.9https://hydephp.com/community2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/contact2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/contributing2024-07-05T13:11:27+00:00daily0.9https://hydephp.com/legal2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/license2024-07-05T13:11:27+00:00daily0.9https://hydephp.com/security2024-07-05T13:11:27+00:00daily0.9https://hydephp.com/sitemap2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/brand/terms2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/guides/installation2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/posts/announcing-the-first-release-candidate-of-hydephp2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/announcing-the-first-release-of-hydephp2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/creating-a-new-hyde-site-from-scratch2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/creating-a-photography-portfolio-site-with-hydephp2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/creating-a-static-html-post-using-hydephp2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/github-actions-deployment2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/how-to-turn-your-github-readme-into-a-static-website2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/hyde-feature-highlights2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/hydephp-open-collective-launch2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/hydephp-version-1-4-released2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/hydephp-version-1-5-released2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/internal-architecture-of-hydephp-part-12024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/internal-architecture-of-hydephp-part-22024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/internal-architecture-of-hydephp-part-32024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/introducing-images2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/introducing-the-hydephp-github-action2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/introducing-the-hydephp-ui-kit2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/release-date-announcement2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/sunsetting-hydephp-dot-se2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/what-is-hyde2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/what-is-markdown2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/posts/why-static-sites2024-07-05T13:11:03+00:00daily0.75https://hydephp.com/docs/1.x2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/advanced-features2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/build-tasks2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/hyde-pages2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/in-memory-pages2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/architecture-concepts2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/autodiscovery2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/automatic-routing2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/dynamic-data-discovery2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/extensions-api2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/page-models2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/the-hydekernel2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/blog-posts2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/compile-and-deploy2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/documentation-pages2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/managing-assets2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/static-pages2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/advanced-customization2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/advanced-markdown2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/collections2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/customization2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/helpers2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/navigation2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/troubleshooting2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/updating-hyde2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/extensions2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/realtime-compiler2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/third-party-integrations2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/ui-kit2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/console-commands2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/core-concepts2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/front-matter2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/quickstart2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/configuration2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/directory-structure2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/getting-started2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/docs/1.x/installation2024-07-05T13:11:03+00:00daily0.9https://hydephp.com/blog2024-07-05T13:11:56+00:00daily0.5