Skip to content

Assets

Four asset attributes are available, two for each of CSS and Javascript, split by local or external location.

  • \Pinto\Attribute\Asset\Css
  • \Pinto\Attribute\Asset\Js
  • \Pinto\Attribute\Asset\ExternalCss
  • \Pinto\Attribute\Asset\ExternalJs

These attributes may be tacked above component classes, among other places.

php
#[Slots(bindPromotedProperties: true]
#[Js('script.js')] 
#[Css('styles.css')] 
final class MyComponent {}

Local assets

#[Css] and #[Js] are used for locally available assets.

The $path argument of #[Css] and #[Js] determines the file name.

Base directory

\Pinto\List\ObjectListInterface::cssDirectory and \Pinto\List\ObjectListInterface::jsDirectory of discovery determine the absolute directory where assets for a component are located on disk. Since these methods are instance based, directories may be varied by enum.

php
public function cssDirectory(): string {
  return match ($this) {
    static::Component1 => '/path/to/component1/assets/'
    static::Component2 => '/path/to/component2/assets/'
  };
}

WARNING

Pinto validates all local assets exist, otherwise exceptions are thrown.

External assets

#[ExternalCss] and #[ExternalJs] are used for externally available assets.

php
#[
  Slots(bindPromotedProperties: true),
  ExternalJs('//unpkg.com/htmx.org@1.9.12', attributes: [ 
    'integrity' => 'sha384-ujb1lZYygJmzgSwoxRggbCHcjc0rB2XoQrxeTUQyRjrOnlCoYta87iKBWq3EsdM2',
    'crossorigin' => 'anonymous',
  ]),
]
final class MyComponent {}

INFO

External assets are not validated.

Resolution

Each of #[Css], #[Js], #[ExternalCss], #[ExternalJs], may be located on components, enum cases, or enums.

  • The component class itself is checked first. If none are found,
  • The enum case is checked. If none are found,
  • The enum is checked.

Components

php
#[Css('styles.css')]  
final class MyComponent {}

Discovery enum case

php
enum PintoList implements ObjectListInterface {

  #[Css('styles.css')]  
  #[Definition(MyComponent::class)]
  case MyComponent;
}

Discovery enum

php
#[Css('styles.css')]  
enum PintoList implements ObjectListInterface {}

Assets declared at the enum level are applied to all cases and components within it, unless an enum case or component adds assets itself. For situations where assets should be merged instead, consider creating an asset-only enum case combined with #[DependencyOn].

Asset-only enum cases

Asset only enums may be declared, these enums lack an associated #[Definition] referencing an component class. These are useful when working with #[DependencyOn], and are equivalent to a Drupal libraries.yml entry without a uniquely associated component.

php
enum GlobalAssets implements ObjectListInterface {
  #[Css('global.css')] 
  #[Js('global.js')] 
  case Global;
}

Dependencies

Dependencies to other components may be declared, dynamically bringing in the assets of other components. Dependencies are resolved recursively with the same logic of Drupal libraries.

Dependencies on other components

The value of #[DependencyOn] may be the enum case of a component, from discovery:

php
enum PintoList implements ObjectListInterface {

  #[Css('styles.css')]
  #[Definition(OtherComponent::class)]
  case OtherComponent;

  #[DependencyOn(MyComponents::OtherComponent)]  
  #[Definition(MyComponent::class)]
  case MyComponent;
}

Dependencies on libraries

Or the name of a Drupal library:

php
#[Slots(bindPromotedProperties: true]
#[DependencyOn('drupal/htmx')]  
final class MyComponent {}

WARNING

Names of Drupal libraries are not validated.

Resolution

Each of #[DependencyOn], may be located on enum cases or enums.

Dependencies are always merged together.

php
enum OtherPintoList implements ObjectListInterface {
  #[Css('global.css')] 
  case Global;
}

#[DependencyOn(OtherPintoList::Global)]
enum PintoList implements ObjectListInterface {

  #[Definition(Accordion::class)]
  case Accordion;

  #[Css('card.css')]
  #[Definition(MyComponent2::class)]
  case Card;
}

In this example, both Accordion and Card use global.css via an asset-only enum, while Card uses card.css exclusively.

Dependencies are included at-most once-per-page using the same logic as Drupal libraries.