tatter/assets

CodeIgniter 4 的资产发布和加载

v3.0.0 2023-09-28 22:46 UTC

README

CodeIgniter 4 的资产处理

Coverage Status

快速开始

  1. 使用 Composer 安装:> composer require tatter/assets
  2. app/Config/Filters.php 中启用 assets 过滤器
  3. app/Config/Assets.php 中将 $routes 分配给其资产

特性

为 CodeIgniter 4 提供 CSS 和 JavaScript 文件的自定义加载。

安装

通过 Composer 轻松安装以利用 CodeIgniter 4 的自动加载功能并保持最新状态

  • > composer require tatter/assets

或者,通过下载源文件并将目录添加到 app/Config/Autoload.php 中来手动安装。

配置

可以通过配置文件覆盖或增强库的默认行为。将 examples/Assets.php 复制到 app/Config/Assets.php 并遵循注释中的说明。如果找不到配置文件,库将使用其默认设置。

为了使用 AssetsFilter,您必须将其应用到目标路由上。过滤器自己进行路由匹配,因此可以在 app/Config/Filters.php 中全局应用。有关更多信息,请参阅 控制器过滤器,或下面的 示例 部分。

使用

如果安装正确,CodeIgniter 4 将检测并自动加载库、配置和过滤器。

资产

您可以使用 Asset 类为单个资产文件构建标签

<?php

use Tatter\Assets\Asset;

$asset = new Asset('<link href="/assets/styles.css" rel="stylesheet" type="text/css" />');
echo view('main', ['asset' => $asset]);

...然后在您的视图文件中

<html>
<head>
	<title>Hello World</title>
	<?= $asset ?>
</head>
<body>
	...

Asset 类还提供了一些命名构造函数,以帮助您创建标签字符串

  • createFromPath(string $path) - 从相对于配置的 $directory 的文件返回一个 Asset
  • createFromUri(string $uri, string $type = null) - 从远程 URL 返回一个 Asset,可选类型(cssjsimgnull 以检测)。

命名构造函数使上述示例更加简单

<html>
<head>
	<title>Hello World</title>
	<?= \Tatter\Assets\Asset::createFromPath('styles.css') ?>
</head>
<body>
	...

捆绑

通常一个项目需要不止一个单个资产。`Bundle` 类允许您将多个 `Asset` 收集到一个实例中。使用 `head()` 和 `body()` 方法返回每个标签的目的 `Asset`,格式为标签块。

`Bundle` 可以通过两种方式创建。

类属性

创建自己的 `Bundle` 类并使用以下属性来安排您想要的资产:* $bundles:要合并的其他 `Bundle` 类的名称。* $paths:要转换为 Asset 的相对文件路径。* $uris:要转换为 Asset 的 URL。* $strings:直接传递到 Asset 中的字符串。

示例

<?php namespace App\Bundles;

use Tatter\Assets\Bundle;

class FrontendBundle extends Bundle
{
    protected $bundles = [
        StylesBundle::class,
    ];

    protected $paths = [
        'bootstrap/dist/css/bootstrap.min.css',
        'bootstrap/dist/js/bootstrap.bundle.min.js',
    ];

    protected $uris = [
        'https://pagecdn.io/lib/cleave/1.6.0/cleave.min.js',
    ];
}

define()

`Bundle` 还提供了一种初始化方法:`define()`。提供自己的方法版本以及流畅风格的定义方法以创建更复杂的集合。

示例

<?php namespace App\Bundles;

use Tatter\Assets\Asset;
use Tatter\Assets\Bundle;

class ColorBundle extends Bundle
{
    protected function define()
    {
        $this
            ->add(Asset::createFromPath('styles.css')) // Add individual Assets
            ->merge($someOtherBundle); // Or combine multiple Bundles

        // Create more complex Assets
        $source = '<script src="https://pagecdn.io/lib/cleave/1.6.0/cleave.min.js" type="text/javascript"></script>';
        $inHead = true; // Force a JavaScript Asset to the <head> tag
        $asset  = new Asset($source, $inHead);
    }
}

过滤器

如果您已配置AssetsFilter(见上文)以加载您的路由,您还必须为每个路由关联特定的资产或包。使用配置属性$routes,其中路由模式是键,值是文件路径、URL或包类名的数组。例如:

<?php namespace Config;

use Tatter\Assets\Config\Assets as AssetsConfig;

class Assets extends AssetsConfig
{
    public $routes = [
        '*' => [
            'bootstrap/bootstrap.min.css',
            'bootstrap/bootstrap.bundle.min.js',
            'font-awesome/css/all.min.css',
            'styles/main.css',
        ],
        'files' => [
            'dropzone/dropzone.min.css',
            'dropzone/dropzone.min.js',
        ],
    ];
}

如果您通过您的路由配置文件应用过滤器,您还可以将包类名作为参数提供,以与任何其他配置的路由包合并。

// **app/Config/Routes.php**
$routes->add('files', 'Files::index', ['filter' => 'assets:\App\Filters\FilesFilter']);

示例

您想创建一个简单的基于Bootstrap前端的前端文件浏览和上传的Web应用。开始您的CodeIgniter 4项目,然后添加Bootstrap和DropzoneJS来处理上传。

composer require twbs/bootstrap enyo/dropzone

注意:您需要将文件从vendor目录复制到public/assets/以使其可访问,或者使用框架的Publisher类来为您处理此操作。

同时添加此模块。

composer require tatter/assets

编辑您的Filters.php配置文件以在所有路由上启用AssetsFilter

    /**
     * List of filter aliases that are always
     * applied before and after every request.
     *
     * @var array
     */
    public $globals = [
        'before' => [
            // 'honeypot',
            // 'csrf',
        ],
        'after'  => [
            'assets' => ['except' => 'api/*'],
        ],
    ];

app/Bundles/DropzoneJS.php中创建一个新的Bundle来定义您的Bootstrap文件。

<?php namespace App\Bundles;

use Tatter\Assets\Bundle;

class DropzoneJS extends Bundle
{
    protected $paths = [
        'dropzone/dropzone.min.css',
        'dropzone/dropzone.min.js',
    ];
}

然后从本存储库将examples/Assets.php复制到app/Config/,并编辑它,以便Bootstrap将在每个路由上加载,而DropzoneJS将在特定路由上加载。

public $routes = [
    '*' => [
        'bootstrap/dist/css/bootstrap.min.css',
        'bootstrap/dist/js/bootstrap.bundle.min.js',
    ],
    'files/*' => [
        \App\Bundles\DropzoneJS::class,
    ],
    'upload' => [
        \App\Bundles\DropzoneJS::class,
    ],
];

注意:我们本来也可以为Bootstrap创建一个Bundle,但由于它们只需要一个路由,这样做也同样简单。

如果您完成了所有这些,那么您的资产应该相应地注入到您的<head><body>标签中。

您的视图文件

<html>
<head>
	<title>File Upload</title>
</head>
<body>
	<h1>Hello</h1>
	<p>Put your upload form here.</p>
</body>
</html>

...作为

<html>
<head>
	<title>File Upload</title>

<link href="http://example.com/assets/bootstrap/dist/css/bootstrap.min.css?v=1234151511412" rel="stylesheet" type="text/css" />
<link href="http://example.com/assets/dropzone/dropzone.min.css?v=12341515141241" rel="stylesheet" type="text/css" />
</head>
<body>
	<h1>Hello</h1>
	<p>Put your upload form here.</p>

<script src="http://example.com/assets/bootstrap/dist/js/bootstrap.bundle.min.js?v=12341515735743" type="text/javascript"></script>
<script src="http://example.com/assets/dropzone/dropzone.min.js?v=12341515573424" type="text/javascript"></script>
</body>
</html>

供应商类

此库包含两个抽象类存根,以简化与第三方资产的工作。VendorPublisher是框架的Publisher库的包装器,专为与Assets一起使用而准备,而VendorBundle是此库的Bundle的专门版本,专为通过VendorPublisher发布的资产处理而准备。这两个类可以大大减少管理外部来源包含的资产的工作。

让我们重新审视上面的例子... 我们不自己将文件复制到public/assets/(并且每次更新时都要重新复制),而是创建一个VendorPublisher来为我们做这个。在app/Publishers/BootstrapPublisher.php

<?php

namespace App\Publishers;

use Tatter\Assets\VendorPublisher;

class BootstrapPublisher extends VendorPublisher
{
    protected $source = 'vendor/twbs/bootstrap/dist';
    protected $path   = 'bootstrap';
}

这就完了!VendorPublisher知道$path是相对于您的资产配置文件中的目录,因此当您运行php spark publish时,所有最新的Bootstrap资产都将复制到该目录(默认:public/assets/vendor/)。

注意:由于这些是外部依赖项,请确保使用您的.gitignore文件将它们排除。

现在让我们使用这些资产。我们可以创建一个新的VendorBundle,并使用新的addPath()方法访问我们刚刚通过Composer的供应商目录发布的相同文件。在app/Bundles/BootstrapBundle.php

<?php

namespace App\Bundles;

use Tatter\Assets\VendorBundle;

class BootstrapBundle extends VendorBundle
{
    protected function define(): void
    {
        $this
            ->addPath('bootstrap/bootstrap.min.css')
            ->addPath('bootstrap/bootstrap.bundle.min.js');
    }
}

现在将新包添加到我们的app/Config/Assets.php路由中

public $routes = [
    '*' => [\App\Bundles\BootstrapBundle::class],
];

从现在起,我们可以轻松地更新Bootstrap!

测试

此库在src/Test/中包含一些PHPUnit扩展类,以协助测试Assets和Bundles。这些用于测试此库中的文件,但也可用于您的库和项目。只需扩展适当的测试用例,并添加一个带有您的类名和满足条件的提供者方法的数据提供者方法。请参阅tests/中的测试文件以获取示例。