Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
4470805
Groundwork for 6.x docset
AugustMiller May 6, 2026
1e8ab17
Upgrade guide .md stubs for 6.x
AugustMiller May 6, 2026
bab8824
Proposed outline
AugustMiller May 6, 2026
45e9a0f
Project upgrade frontmatter
AugustMiller May 6, 2026
78e3174
More stubs
AugustMiller May 6, 2026
090b5b6
Introductory content
AugustMiller May 6, 2026
d9810e8
Adapter purpose
AugustMiller May 6, 2026
6a91072
Assets
AugustMiller May 6, 2026
3801624
Behaviors/macros
AugustMiller May 6, 2026
f0a4870
Required changes
AugustMiller May 6, 2026
cdd3cc0
Base plugin class
AugustMiller May 6, 2026
6accd35
TOC
AugustMiller May 6, 2026
c7e2114
Commands
AugustMiller May 6, 2026
4465f14
Validation stub
AugustMiller May 6, 2026
9278754
Config
AugustMiller May 6, 2026
fa6fb2e
Controllers, Actions, Routing
AugustMiller May 6, 2026
6e5de0d
Events
AugustMiller May 6, 2026
c17de8a
Field types
AugustMiller May 6, 2026
ea76d1b
Filesystem types / disks
AugustMiller May 6, 2026
165c111
Subpaths
AugustMiller May 6, 2026
7fb6e35
Helpers
AugustMiller May 6, 2026
2533634
Queue, Jobs
AugustMiller May 6, 2026
97b83cd
Logs
AugustMiller May 6, 2026
47cdb2f
Mail
AugustMiller May 6, 2026
5326837
Models
AugustMiller May 6, 2026
a8938f9
Services!
AugustMiller May 6, 2026
08e94a7
Plugin getters
AugustMiller May 6, 2026
77d9474
Session
AugustMiller May 6, 2026
9214caa
Very cool 6.x note for SQLite enjoyers :)
AugustMiller May 6, 2026
38dab4e
Quick-start
AugustMiller May 6, 2026
b77f681
Hide resources + elements pages for now
AugustMiller May 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/.vuepress/anchor-prefixes.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* - `source` for GitHub-hosted file references.
*/
module.exports = {
'craft6': { base: 'https://docs.craftcms.com/api/v6/', format: 'internal' },
'craft5': { base: 'https://docs.craftcms.com/api/v5/', format: 'internal' },
'craft4': { base: 'https://docs.craftcms.com/api/v4/', format: 'internal' },
'craft3': { base: 'https://docs.craftcms.com/api/v3/', format: 'internal' },
Expand All @@ -22,6 +23,7 @@ module.exports = {
'yii2': { base: 'https://www.yiiframework.com/doc/api/2.0/', format: 'yii' },
'yii1': { base: 'https://www.yiiframework.com/doc/api/1.1/', format: 'yii' },
'guide': { base: 'https://www.yiiframework.com/doc/guide/2.0/en/', format: 'generic' },
'laravel': { base: 'https://laravel.com/docs/13.x/', format: 'generic' },
'config5': { base: '/5.x/reference/config/general.md#', format: 'config' },
'config4': { base: '/4.x/config/general.md#', format: 'config' },
'config3': { base: '/3.x/config/config-settings.md#', format: 'config' },
Expand Down
59 changes: 59 additions & 0 deletions docs/.vuepress/sets/craft-cms.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module.exports = {
icon: "/docs/icons/craft.svg",
baseDir: "",
versions: [
["6.x", { label: "6.x", stabilityFlag: 'alpha' }],
["5.x", { label: "5.x" }],
["4.x", { label: "4.x" }],
["3.x", { label: "3.x", isEol: true }],
Expand All @@ -15,6 +16,64 @@ module.exports = {
searchPlaceholder: "Search the Craft docs",
primarySet: true,
sidebar: {
"6.x": {
"/": [
{
title: "Intro",
collapsable: false,
children: [
["", "About the Alpha"],
],
},
{
title: "Projects",
collapsable: false,
children: [
"requirements",
"install",
"upgrade",
],
},
{
title: "Extensions",
collapsable: false,
children: [
"extend/introduction",
"extend/adapter",
// "extend/resources",
"extend/upgrade",
"extend/avenues",
"extend/approach",
"extend/local-dev",
],
},
{
title: "Plugin Upgrade Guide",
collapsable: false,
children: [
"extend/provider",
"extend/assets",
"extend/macros",
"extend/commands",
"extend/config",
"extend/http",
// "extend/elements",
"extend/events",
"extend/fields",
"extend/disks",
"extend/helpers",
"extend/queue",
"extend/logging",
"extend/mail",
"extend/models",
"extend/services",
"extend/session",
"extend/templates",
"extend/validation",
],
}
],
},
"5.x": {
// Sections here are greedily-matched, so the more specific ones must come first:
"/reference/": [
Expand Down
5 changes: 5 additions & 0 deletions docs/.vuepress/theme/components/PostHeading.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
class="version-warning">
You are viewing documentation for an unreleased version of {{ $activeSet.setTitle }}. Please be aware that some pages, screenshots, and technical reference may still reflect older versions.
</div>
<div
v-else-if="$activeVersionInfo && $activeVersionInfo.stabilityFlag === 'alpha'"
class="version-warning">
You are viewing documentation for an unreleased version of {{ $activeSet.setTitle }}. Please be aware that the material is changing frequently and may be incomplete or inaccurate, and links may point back to older versions.
</div>
<div
v-else-if="isSearchReferral && suggestedPath"
class="version-warning"
Expand Down
42 changes: 42 additions & 0 deletions docs/6.x/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
description: Official documentation for Craft CMS 6.x
---

# About Craft CMS

Craft is a flexible, user-friendly CMS for creating custom digital experiences on the web—and beyond.

<!-- more -->

People who use Craft love its…

- …intuitive, user-friendly [control panel](/5.x/system/control-panel.md) for content creation and administrative tasks;
- …clean-slate approach to content modeling and [front-end development](/5.x/development/README.md) that doesn’t make any assumptions about your content or how it should be delivered;
- …official Plugin Store with hundreds of free and commercial [plugins](https://plugins.craftcms.com/);
- …robust framework for [plugin development](extend/README.md);
- …active, vibrant [community](https://craftcms.com/community);

You can learn all about it at [craftcms.com](https://craftcms.com).

## Getting Started

Welcome to the alpha!
Ready to try out a bleeding-edge version of Craft?
Spin up a [new project](install.md) or [upgrade](upgrade.md) an existing one.

<Block label="Documentation Changes">

You’ll notice that the docs are relatively sparse for 6.x!
Our work so far as focused on the Laravel port and adapter, but we are slowly pivoting into feature development on the new platform.
Craft remains functionally very similar to 5.x, and most of the control panel will be identical… so we’re using this space to focus on the upgrade process!
Closer to release, we’ll start replicating the structure and content of 5.x.

</Block>

## Tech Specs

Craft is a self-hosted PHP application, built on [Laravel](https://www.laravel.com/).
It can connect to MySQL and PostgreSQL databases for content storage.
Server-side rendering is powered by [Twig](https://twig.symfony.com), and headless applications have access to content via a GraphQL API.

<See path="requirements.md" label="View System Requirements" description="Craft runs best on the latest PHP and MySQL or Postgres versions, but can be configured to work on most modern hosting platforms." />
117 changes: 117 additions & 0 deletions docs/6.x/extend/adapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# The Adapter

To reduce the friction for plugin developers (and other early-adopters, in turn), we’ve created a sophisticated compatibility layer that translates legacy API calls to the new Laravel app.

The first step to getting started with your port or compatibility release is requiring the adapter package:

```bash
composer require craftcms/yii2-adapter
```

Keep it as a dependency of your package as long as _you_ actually need it; don’t assume the project will include it!

::: tip
You must address _all_ preexisting deprecation warnings (from 5.x) for the adapter to work.
:::

The adapter package is *not* just a copy of the Craft 5.x application; if you go source-diving, you’ll find that most methods have been reduced to wrappers around the new Laravel application’s APIs.
When possible, we’ve actually extended the _new_ classes and backfilled any methods, properties, and constants that were removed, internally.

We have also added `@deprecated` tags and `#[Deprecated]` attributes to methods and classes that point to suitable replacements, and deprecation errors when old code paths are reached.

::: warning
At this point, _most plugins will be fully compatible with Craft 6.x_.

The rest of this section describes how the adapter works, and how you would go about writing a compatibility layer of your own.
Broadly speaking, this will _not_ be necessary, and you can safely continue from the [required changes](upgrade.md) page.
Consider returning here when your plugin has been fully ported!
:::

## Legacy Support

You are not obligated to provide legacy API support—especially if your plugin is not extensible by other plugins (or from individual projects).

The most common use case for this section is apt to be plugins that store fully-qualified class names in the database or project config.
As an example, a plugin that lets administrators configure notifications and stores their `type` in the database (corresponding directly to a class) should at least move the class into your new namespace and map the old name using PHP’s `class_alias()`.

While you can solve this in part with a migration that substitutes the old classes, there may be a window of time when the app expects those old classes to exist _before_ the migration can run.

::: tip
If you _do_ end up with any kind of compatibility layer, `composer.json` must include your new *and* old `autoload.psr-4` namespaces.
:::

### Your own adapter

Due to its size, Craft’s adapter lives in an external package.
It also results in all of Yii being pulled in as a dependency, which should *not* be necessary for most plugins: your goal should be to have your entire plugin *and* its own compatibility layer (if one is necessary at all) running natively in the new Laravel environment.

Your adapter’s primary function is to map existing projects’ lingering references to old classes (and class members) to their new counterparts.
Here’s an idea for the kinds of changes to expect, based on our first-party plugins:

1. Add `@deprecated` tags and move existing classes into a new `legacy/` auto-loading root. The *namespace* for legacy code should stay the same, but the *root* must be updated in `composer.json`.
2. Add your new namespace to the auto-loading configuration in `composer.json` (say, `MyOrg\\MyPlugin\\`), pointing to `src/`.
3. Create classes in `src/` using the new namespace, and gradually translate implementations. That translation process will involve reviewing the rest of the topics in the migration guide, and may come in a few different forms:
- Delete and alias completely compatible classes to make them available in your old namespace:

```php
// We’re in the old namespace!
namespace myorg\pluginname\base;

// (Optional) Keep original class definition inside conditional so it can still be picked up by IDEs:
if (false) {
/**
* @deprecated 2.0.0 {@see \MyOrg\PluginName\Contracts\SomeInterface}
*/
interface SomeInterface
{}
}

// Declare alias to new class:
class_alias(\MyOrg\PluginName\Contracts\SomeInterface::class, SomeInterface::class))
```

- For classes with shallow inheritance (in particular, those whose parents all belong to your plugin or an external dependency other than Craft or Yii), you can instead move the implementation into the new namespace and `extend` it in the old. (See: `craft\auth\methods\RecoveryCodes`)
- For classes that have been split up, restructured, or are otherwise incompatible, you can keep parts or whole legacy classes around. Whenever feasible, log deprecation before calling your new API:

```php
namespace myorg\pluginname\services;

use MyOrg\PluginName\Shipping\Actions\ConfirmSignature;
use MyOrg\PluginName\Models\Delivery;

class Shipping
{
public function confirmSignature(Delivery $delivery, Asset $proof): void
{
\CraftCms\Cms\Support\Facades\Deprecator::log(__METHOD__, 'myorg\pluginname\services\Shipping::confirmSignature() is deprecated. Dispatch the MyOrg\PluginName\Shipping\Actions\ConfirmSignature action, instead.');

// Supposing we implemented this as a job or event
ConfirmSignature::dispatch($delivery, $proof);
}
}
```

Here’s an example of a plugin class that had previously mounted “services” an exposed them via getters:

```php
namespace myorg\myplugin;

use CraftCms\Cms\Support\Facades\Deprecator;

class Analytics extends \MyOrg\MyPlugin\Analytics
{
// ...

public function getReports(): Reports
{
Deprecator::log(__METHOD__, 'myorg\myplugin\Analytics::getReports() is deprecated. Get an instance of MyOrg\MyPlugin\Analytics\Reports\Manager using the Laravel service container, instead.');

return app(MyOrg\MyPlugin\Analytics\Reports\Manager::class);
}
}
```

The legacy events system belonged almost entirely to Yii, so you will not be able to proxy events without the adapter.
If this continuity is important to you and downstream developers, you can either require the adapter or provide clear upgrade instructions to reduce their workload.

See `craft\elements\User` for an example of a class that forwards new events to Yii. We elected to group classes’ proxy handlers in a static `registerEvents()` method, which we call from a central location: `CraftCms\Yii2Adapter\Event\EventCompatibility::boot()`
19 changes: 19 additions & 0 deletions docs/6.x/extend/approach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Approach

Simple plugins (like those that exist mostly to handle or alter an event) can probably be **fully ported** and released as an alpha.

We recommend that developers of larger plugins (which provide entirely new features or new types of existing components) make the minimum required updates for compatibility, then use the alpha to gradually migrate. This will unblock others who wish to test the upgrade process in real projects and report issues with Craft, the compatibility layer, or your plugin.

::: tip
If you maintain a plugin that provides its own extension surface (events, service APIs, etc.), you should decide and telegraph whether you intend to fully port your plugin during the alpha, and whether you intend to ship a compatibility layer.
:::

## Necessity

Some low-level plugins may not be strictly necessary in the Laravel ecosystem, but developers will still appreciate a configuration layer that is accessible via the control panel and tracked in project config.

Examples of this are:

- **Mail transport adapters** — Projects can set up mailers via `config/mail.php` and select one in <Journey path="Settings, Email" />
- **Custom log back-ends** — As with prior versions of Craft, plugins may not be initialized early enough in the app’s lifecycle to capture a complete picture. Consider whether projects can effectively use Laravel’s built-in [logging](laravellogging) tools.
- **Filesystem types** — Developers can directly configure *disks* and use them for volumes. The <Journey path="Settings, Filesystems" /> screen also acts as a disk configurator.
Loading
Loading