Alias: "Block-SDC"
%%{init: {'theme': 'dark', 'textColor': 'white' } }%%
sequenceDiagram
Block->>Block: Generate build render array
Block->>Theme: Theme file
Theme->>Theme: `templates/sdc_block.twig.html`
Theme->>SDC: Include Single Directory Component
SDC->>SDC: `sdc-my-component`
src/Plugin/Block/MyComponentSdcBlock.php
<?php
declare(strict_types=1);
namespace Drupal\my_components\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides an SDC block.
*
* @Block(
* id = "my_components_sdc_block",
* admin_label = @Translation("SDC Block"),
* category = @Translation("My Component"),
* )
*/
final class MyComponentSdcBlock extends BlockBase implements ContainerFactoryPluginInterface {
/**
* @param array $configuration
* @param string $plugin_id
* @param mixed $plugin_definition
* @param CacheBackendInterface $cacheBackend
* @param TimeInterface $datetime
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
private readonly TimeInterface $datetime
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
}
/**
* @param ContainerInterface $container
* @param array $configuration
* @param string $plugin_id
* @param mixed $plugin_definition
*
* @return static
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('datetime.time')
);
}
/**
* {@inheritdoc}
*/
public function build(): array {
$data = [
'text' => 'Block SDC',
'subtitle' => 'My Text',
'requested' => $this->datetime->getRequestTime()
];
$build['content'] = [
'#theme' => 'sdc_block',
'#data' => $data,
];
return $build;
}
}templates/sdc_block.twig.html
{{
include('my_components:sdc-my-component', {
text: content.data.text,
subtitle: content.data.subtitle,
requested: content.data.requested,
},
with_context = false)
}}Components to be place inside a module or theme within a components directory.
.my_components
│
├── src
│ └── Plugin
│ └── Block
│ └── MyComponentSdcBlock.php
├── assets
│ └── css
│ └── component.css
├── components
│ └── sdc-my-component
│ ├── sdc-my-component.component.yml
│ ├── sdc-my-component.css
│ ├── sdc-my-component.js
│ ├── sdc-my-component.twig
│ └── README.md
├── my_components.info.yml
├── my_components.module
├── my_components.services.yml
├── src
└── templates
sdc-my-component
├── sdc-my-component.component.yml
├── sdc-my-component.css
├── sdc-my-component.js
├── sdc-my-component.twig
Note: CSS and JS files are optional and loaded only if present.
File: sdc-my-component.component.yml
'$schema': 'https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json'
name: My Component
status: stable
props:
type: object
properties:
text:
title: Text
type: string
subtitle:
title: Sub Title
type: string
title: Requested
type: stringFile: sdc-my-component.twig
<sdc-my-component class="composition-vertical">
<div class="headline">
{{ text }}
{% if subtitle | length %}
<h3>{{ subtitle }}</h3>
{% endif %}
<p>{{ requested }}</p>
</div>
</sdc-my-component>File: sdc-my-component.js (optional)
(function(Drupal) {
Drupal.behaviors.sdcMyComponent = {
attach(context) {
console.log('@todo My Component.');
},
};
})(Drupal);File: sdc-my-component.css (optional)
@import url("../../assets/css/component.css");
.headline {
color: green;
margin: 1em 0;
}