webflorist/htmlfactory

此软件包最新版本(v1.1.15)没有提供许可证信息。

Laravel 的便捷且强大的 HTML 构建器

v1.1.15 2022-09-06 12:16 UTC

README

Laravel (>=v5.5) 的便捷且强大的 HTML 构建器

Build Status Latest Stable Version

描述

此软件包提供了在 Laravel 中构建 HTML 的功能,无需编写任何 HTML。

此软件包允许您

  • 使用所有相关 HTML 元素的静态工厂方法。
  • 通过流畅的方法调用链设置 HTML 属性(对当前元素有效)。
  • 充分利用 IDE 的好处(自动完成)。
  • 使用 Decorator 类为特定前端框架设置输出样式
  • 保持视图的前端无关性。
  • 使用 DecoratorsComponents 扩展其功能。
  • 生成符合无障碍规范的 HTML 5 输出。

此软件包用作 webflorist/formfactory 的基础。如果您想在 Laravel 中轻松创建表单,请查看此软件包。

安装

  1. 通过 composer 需求此软件包: composer require webflorist/htmlfactory
  2. 发布配置: php artisan vendor:publish --provider="Webflorist\HtmlFactory\HtmlFactoryServiceProvider"
  3. 在新发布的配置文件(位于 app/config/htmlfactory.php)中设置 decorators 配置。

请注意,此软件包配置为自动发现 Laravel。因此,软件包的 Service Provider Webflorist\HtmlFactory\HtmlFactoryServiceProviderHtml Facade Webflorist\HtmlFactory\HtmlFactoryFacade 将自动注册到 Laravel 中。

配置

可以通过 config/htmlfactory.php 配置软件包。目前只有一个设置

  • decorators:设置应加载的装饰器分组 ID。结果,所有相应的装饰器都将应用于生成的 HTML 元素(例如,'bootstrap:v3')。

基本概念

以下是此软件包基本概念的定义,以便更好地理解本文档

请注意,每当本文档使用术语 Element 时,它还包括 Component 类(除非另有说明),因为它们在技术上也是 Element 类。

用法

使用 Html- 外观或简单实例化相应的 ElementComponent 类生成 HTML 元素或组件。

由于此软件包是以 IDE 友好的方式构建的,因此您只需在您的自动完成 IDE 中键入 Html::,就应该立即获得可用元素以及包含的组件的列表。(当然,此自动完成不会与您的自己的组件一起工作。)

使用 generate() 方法生成最终 HTML 字符串。但是,由于 HtmlFactory 包的 Element 类包含一个执行此操作的魔法 __toString() 方法,因此在 blade 模板中使用 Html 外观时可以省略 generate() 方法。

基本示例

以下是从 Laravel-blade 模板中生成 div 元素的一个非常基本的示例

Blade Code:
-----------
{!! Html::div() !!}

Generated HTML:
---------------
<div></div>

使用流畅方法修改元素

可以通过链式调用Element的各种流畅方法来进一步修改(例如添加HTML属性或内容)。在您的自动完成功能下,您只需输入例如Html::div()->,就应该立即得到该元素可用的方法列表。以下是提供的方法概览

添加HTML属性

现在假设,我们想要给Element添加一些HTML属性

  • 一个值为myIdid属性
  • 一个值为bar的data-attribute data-foo
  • 一个名为myClass的class

我们可以通过应用这些修改的相应方法来实现这一点

Blade Code:
-----------
{!! Html::div()
    ->id('myId')
    ->data('foo','bar')
    ->addClass('myClass')
 !!}

Generated HTML:
---------------
<div id="myId" data-foo="bar" class="myClass">
    <span>Hello world!</span>
</div>

一般来说,设置HTML属性的方法的名称与它们的名称相同(例如,可以使用id()方法设置id属性)。以下是一些例外

  • 包含连字符(例如accept-charset)的属性的setter方法与驼峰式命名的属性名称相同(例如acceptCharset())。
  • 具有多个值的属性具有以add为前缀(并采用驼峰式)的相应方法。一个例子是,对于上面示例中使用的class属性,有addClass()
  • data-属性通过data()方法设置,该方法将数据属性的后缀作为它的第一个参数,将值作为它的第二个参数(如上面的示例所示)。

请注意,由于该包旨在仅输出有效的HTML,因此可用的方法因元素而异。例如,您不能在div元素上使用selected()方法,因为根据HTML标准,这是不允许的。

所有HTML属性的值也可以是闭包。闭包将Element对象本身作为它的唯一参数来处理。以下是一个示例

Blade Code:
-----------
{!! Html::div()
    ->id('myId')
    ->title(
        function ($element) {
            return "This div's id is ".$element->attributes->id;
        }
    )
 !!}

Generated HTML:
---------------
<div id="myId" title="The ID of this div is myId"></div>
添加Vue指令

除了标准的HTML属性外,您还可以通过相应的元素方法设置所有可能的Vue指令(请参阅Vue指令)

此外,还提供了最常见的DOM事件的vOn()的快捷方法

添加内容

当然,ContainerElement也可以有内容。让我们看看这个示例

Blade Code:
-----------
{!! Html::div()
    ->content([
        Html::span()->content('Hello world!'),
        "What's up?"
    ])
 !!}

Generated HTML:
---------------
<div>
    <span>Hello world!</span>
    What's up?
</div>

content()方法接受一个子元素或子元素的数组作为其参数。子元素可以是另一个Element对象或简单的文本字符串。还有额外的prependContent()appendContent()方法,它们在现有内容之前或之后添加内容。以下是所有内容相关方法的概览

在Element之前或之后插入一个兄弟元素

以下方法允许您在Element之前或之后插入一个兄弟元素(无论是纯文本还是另一个Element)。

将一个元素包裹在另一个元素中。

您还可以将包装器应用到元素上。请看这个示例

Blade Code:
-----------
{!! Html::div()
    ->id('myDivElement')
    ->wrap(
        Html::div()->addClass('wrapper')
    )
 !!}

Generated HTML:
---------------
<div class="wrapper">
    <div id="myDivElement"></div>
</div>
应用Blade视图以渲染元素

您还可以使用view()方法将Blade视图应用到元素上。元素本身在视图中作为$el可用。要渲染它,请调用$el->renderHtml()

以下是一个示例

Blade Code:
-----------
{!! Html::div()
    ->content('Hello World!')
    ->view('my-view')
!!}
 
 
my-view.blade.php:
-----------
<div class="my-view-wrapper">
    before element
    {!! $el->renderHtml() !!}
    after element    
</div>

Generated HTML:
---------------
<div class="my-view-wrapper">
    before element
    <div>Hello World!</div>
    after element
</div>
闭包装饰器

有时您可能希望对单个元素应用一些复杂的装饰,或者影响全局装饰器类(请参阅以下说明)应用后的Element。您可以使用Element方法decorate()来做到这一点。该方法接受一个闭包作为其唯一参数,该闭包将Element本身作为其唯一属性传递

请看这个示例

Blade Code:
-----------
{!! Html::div()
    ->id('myId')
    ->data('foo','bar')
    ->content(
        Html::span()->content('Hello world!')
    )
    ->wrap(
        Html::div()->addClass('wrapper')
    )
    ->decorate( function($element) {
        $element
            ->id('myDecoratedId')
            ->data('decorated-foo','decorated-bar')
            ->appendContent("What's up?");
        $element->wrapper->addClass('decoratedWrapper');
    })
 !!}

Generated HTML:
---------------
<div class="wrapper decoratedWrapper">
    <div id="myDecoratedId" data-foo="bar" data-decorated-foor="decorated-bar">
        <span>Hello world!</span>
        What's up?
    </div>
</div>

可扩展性

组件

在某些情况下,您可能希望快速创建更复杂的HTML元素,这些元素已经预先设置了某些属性、内容或包装器,提供了额外的功能,甚至需要某些构造参数。您还可能希望通过Html外观(例如,通过Html::myCustomComponent())访问此组件。所有这些都可以通过创建Components来实现。

组件基本上是一个类,它扩展了 Element 类之一或另一个 Component 类。在 Components 文件夹中已经包含了一些组件。这些包括 InputElement 的扩展以及 ButtonElement,为可能的 '类型' 提供组件。

组件注册

要使用 Html 表面创建组件,必须满足以下条件:

  • 组件必须实现 RegisteredComponentInterface,强制存在静态的 getAccessor() 方法,该方法应返回一个方法名,通过这个方法名可以通过 Html 表面创建该组件。
  • 组件必须注册到 HtmlFactory 服务。

注册可以通过以下方法之一完成:

  • 注册一个单个(完全限定)类名作为组件。
    app(Webflorist\HtmlFactory\HtmlFactory::class)->components->register(string $className, bool $force = false)
    示例
    app(Webflorist\HtmlFactory\HtmlFactory::class)->components->register('FQCN\Of\My\AwesomeComponent')
  • 从目录中的文件注册组件。
    app(Webflorist\HtmlFactory\HtmlFactory::class)->components->registerFromFolder(string $namespace, string $folder, bool $force = false):
    示例
    app(Webflorist\HtmlFactory\HtmlFactory::class)->components->registerFromFolder('Fully\Qualified\Namespace','/path/to/my/awesome_components'):

关于 $force 参数:通常,如果另一个组件已使用相同的访问器安装,HtmlFactory 将抛出错误。可以通过将 $force 设置为 true 来规避这种情况。(这样也可以覆盖包含的组件。)

执行这些注册的最佳位置是在你的 AppServiceProviderboot() 方法中(或任何其他 ServiceProvider)。

请注意,如果你不打算通过 Html 表面使其可实例化(例如,如果你使用自己的 Service/Facade 或使用 new 关键字实例化对象),则不需要实现 RegisteredComponentInterface 或注册组件。

自定义组件。

要自定义你的组件,你可以实现以下钩子方法

(确保在覆盖这些方法时也调用父方法,特别是在扩展其他组件时,以确保不丢失任何功能。)

当然,你也可以创建自己的构造函数(例如,添加必需的参数)。只需确保调用父构造函数。

当然,你还可以添加额外的流畅设置器,以便在视图中调用组件。该包已包括一些特质,它们提供了一些通用的流畅设置器和相应的属性。您可以在命名空间 Webflorist\HtmlFactory\Components\Traits 中找到它们。

示例

让我们以包含的 SubmitButtonComponent 作为一个非常基本的示例

namespace Webflorist\HtmlFactory\Components;

use Webflorist\HtmlFactory\Components\Contracts\RegisteredComponentInterface;
use Webflorist\HtmlFactory\Elements\ButtonElement;

class SubmitButtonComponent extends ButtonElement implements RegisteredComponentInterface
{

    protected function setUp()
    {
        parent::setUp();
        $this->type('submit');
    }

    static function getAccessor(): string
    {
        return 'submitButton';
    }

}

该组件实现了 setUp() 方法,将属性 type 设置为默认值 submit。此外,它还实现了 RegisteredComponentInterface 并将 submitButton 定义为其访问器。(此外,所有包含的组件都在 HtmlFactoryServiceProviderboot 方法中注册。)

这使以下用法成为可能

Blade Code:
-----------
{!! Html::submitButton() !!}

Generated HTML:
---------------
<button type="submit"></button>

因此,Html::submitButton() 的输出与 Html::button()->type('submit') 相同。

查看其他包含的组件以获取更多示例!

装饰器

自定义 HtmlFactory 输出的第二种方法是使用装饰器。装饰器是定义了它们可以处理哪些 Elements 的类。例如,你可以创建一个装饰器,它将 CSS 类添加到所有 ButtonElements。装饰器也是应用前端框架特定修改(例如,当使用 bootstrap 作为前端框架时,将 form-control 类添加到字段元素)的绝佳方式。装饰器本身还可以声明一个组-ID,这意味着只有当其组-ID 出现在 decorators 配置字符串中时,装饰器才会应用。

装饰器必须扩展抽象类 Webflorist\HtmlFactory\Decorators\Abstracts\Decorator,强制实现以下抽象方法

注册装饰器

装饰器必须使用以下方法之一注册到 HtmlFactory 服务:

  • 注册一个单个(完全限定)类名作为装饰器。
    app(Webflorist\HtmlFactory\HtmlFactory::class)->decorators->register(string $className)
    示例
    app(Webflorist\HtmlFactory\HtmlFactory::class)->decorators->register('FQCN\Of\My\AwesomeDecorator')
  • 从目录中的文件注册装饰器。
    app(Webflorist\HtmlFactory\HtmlFactory::class)->decorators->registerFromFolder(string $namespace, string $folder):
    示例
    app(Webflorist\HtmlFactory\HtmlFactory::class)->decorators->registerFromFolder('Fully\Qualified\Namespace','/path/to/my/awesome_decorators'):

与组件一样,执行这些注册的最佳位置是在你的 AppServiceProviderboot() 方法中(或任何其他 ServiceProvider)。

示例

HtmlFactory已经包含了一些内置装饰器。让我们来看看DecorateButtonElement

use Webflorist\HtmlFactory\Decorators\Abstracts\Decorator;
use Webflorist\HtmlFactory\Elements\ButtonElement;

class DecorateButtonElement extends Decorator
{

    public static function getGroupId()
    {
        return 'bootstrap:v3';
    }

    public static function getSupportedElements(): array
    {
        return [
            ButtonElement::class
        ];
    }

    public function decorate()
    {
        $this->element->addClass('btn');

    }
}

其功能相当明显。只有当当前配置htmlfactory.decorators中存在'bootstrap:3'时,装饰器才会被应用。此外,它只应用于与Webflorist\HtmlFactory\Elements\ButtonElement相同或为其后代的元素或组件。其功能是向按钮添加特定的Bootstrap CSS类'btn'。

查看其他内置装饰器以获取更多示例!