Feature: #109409 - Allow configuration of resources
See forge#109409
Description
Composer-managed TYPO3
Until now, extensions could place public resources only in their
Resources/ folder. The folder name used to publish these
extension resources was a non-configurable MD5 hash.
This feature introduces the possibility to configure resources explicitly.
This includes additional public folders or files that are published into
TYPO3's public/_ folder, as well as non-public resource paths.
TYPO3 classic mode
In TYPO3 classic mode, there is no visible change for extensions
or the typo3/ package, since all files in extensions are already
located within the document root. Restricting resources to the default
locations in classic mode therefore mainly follows coding guidelines
and keeps compatibility with Composer mode.
Configuring extensions
Extensions can add Configuration/ to configure resources.
This configuration is then added to the following default configuration:
<?php
declare(strict_types=1);
use TYPO3\CMS\Core\Package\Package;
use TYPO3\CMS\Core\Package\Resource\Definition\PublicResourceDefinition;
use TYPO3\CMS\Core\Package\Resource\Definition\ResourceDefinition;
return static function (Package $package) {
$resourceDefinitions = [
new ResourceDefinition('Resources/Private'),
];
if (is_dir($package->getPackagePath() . 'Resources/Public')) {
$resourceDefinitions[] = new PublicResourceDefinition('Resources/Public');
}
return $resourceDefinitions;
};
This means that, when using the system resources API
(Feature: #107537 - System resource API for system file access and public URI generation), resource identifiers are only allowed
to reference files or folders in Resources/ and, if it exists,
Resources/. It also means that, by default, Resources/
in extensions will be published in the same way as before this change.
Example: publish an additional public folder
<?php
declare(strict_types=1);
use TYPO3\CMS\Core\Package\Package;
use TYPO3\CMS\Core\Package\Resource\Definition\PublicResourceDefinition;
use TYPO3\CMS\Core\Package\Resource\Definition\ResourceDefinition;
return static function (Package $package) {
return [
new PublicResourceDefinition('Build/Public'),
];
};
This will publish the Build/ folder as well. The published folder name
will be a hash unique to this folder.
Example: publish a single file only
Instead of publishing a whole folder, a single file can be published:
<?php
declare(strict_types=1);
use TYPO3\CMS\Core\Package\Package;
use TYPO3\CMS\Core\Package\Resource\Definition\PublicFileDefinition;
return static function (Package $package) {
return [
new PublicFileDefinition(relativePath: 'Build/styles.css'),
new PublicFileDefinition(
relativePath: 'Build/components.css',
publicPrefix: $package->getPackageKey() . '/custom/folder/my-components.css',
),
];
};
This publishes the extension file Build/ to a folder with a unique
hash, which will then contain the file styles..
Additionally, Build/ will be published to
_assets/.
Example: use a fixed prefix in _assets
By default, TYPO3 generates the public prefix automatically. A fixed prefix can be configured explicitly:
<?php
declare(strict_types=1);
use TYPO3\CMS\Core\Package\Package;
use TYPO3\CMS\Core\Package\Resource\Definition\PublicResourceDefinition;
use TYPO3\CMS\Core\Package\Resource\Definition\ResourceDefinition;
return static function (Package $package) {
return [
new PublicResourceDefinition(
relativePath: 'Build/Public',
publicPrefix: 'my-vendor/my-extension-build',
),
];
};
This publishes resources from Build/ to a stable location below
public/_.
Note
Resource definitions configured in this file amend the default configuration. They are added to the default configuration.
Important
Static public prefixes must be unique across all packages. Reusing the same public prefix in multiple packages will cause an exception.
Configuring the typo3/app package
See the system resources API (Feature: #107537 - System resource API for system file access and public URI generation) for more
information about what the typo3/ package represents.
To configure the typo3/ package, a config/
file can be added.
If it is missing, the following default configuration is used:
<?php
declare(strict_types=1);
use TYPO3\CMS\Core\Package\Resource\Definition\PublicResourceDefinition;
use TYPO3\CMS\Core\Package\VirtualAppPackage;
return static function (VirtualAppPackage $package, string $relativePublicPath) {
return [
new PublicResourceDefinition(
relativePath: $relativePublicPath . '_assets',
),
new PublicResourceDefinition(
relativePath: $relativePublicPath . 'uploads',
),
new PublicResourceDefinition(
relativePath: $relativePublicPath . 'typo3temp/assets',
),
];
};
Note
Resource definitions configured in this file amend the default configuration. They are added to the default configuration.
Note
It is also recommended not to place additional files directly into the
_assets folder anymore. Instead, configure a folder outside the
document root and let TYPO3 publish it automatically into _assets.
This is important so that third-party publishers can pick up the
publishing process and actually publish files to the intended location,
for example a CDN, instead of leaving them in the _assets folder.
If a resource definition configures a source folder that is already
within the system's public folder, publishing is skipped.
Closing notes
For now, this change mainly affects public files and folders.
Important
Only basic PHP operations are allowed in this file. TYPO3 is not bootstrapped in Composer mode when this file is evaluated. This means that, apart from classes being autoloadable, no global state is available. Think of this file as a plain PHP file that is executed directly as an entry point. Access to files within the package folder handed over as an object is allowed and intentional.
Important
Relative paths must not contain leading or trailing slashes, backpaths
such as ../, or other invalid characters.
Note
Changes to the resource configuration require execution of
composer dumpautoload or, in TYPO3 classic mode, cache:.
Impact
If no resource configuration is added to extensions, this feature has no impact on a TYPO3 installation. If such a configuration exists, it extends the default configuration.