- Issue created by @irowboat
- 🇫🇮Finland irowboat
Also field support for Views Transforms is definitely on the wishlist.
- 🇩🇰Denmark erik_petra
You can write your own Field Transform plugins and we're currently working on a guide for it.
But a good example for it is to check out some existing ones, such assrc/Plugin/Transform/Field/EntityTransform.php
As for field support for Views Transforms, that's our next goal within Views integration.
- 🇫🇮Finland irowboat
Thanks, I got it working.
Here's some proof-of-concept code for anyone interested - Block field support for Views and Webform blocks. (Not using content/custom blocks but understanding what's happening here, should be easy to implement.)
namespace Drupal\transform_api_block_field\Plugin\Transform\Field; use Drupal\Core\Block\BlockManagerInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\group\Context\GroupRouteContext; use Drupal\transform_api\FieldTransformBase; use Drupal\transform_api_views\Transform\ViewTransform; use Drupal\views\Plugin\Block\ViewsBlock; use Drupal\webform\Entity\Webform; use Drupal\webform\Plugin\Block\WebformBlock; use Drupal\webform\WebformTokenManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Transform field plugin for block field items. * * @FieldTransform( * id = "block_field_transform", * label = @Translation("Block field transform"), * field_types = { * "block_field" * } * ) */ class BlockFieldTransform extends FieldTransformBase { /** * The block manager service. * * @var \Drupal\Core\Block\BlockManagerInterface */ protected $blockManager; /** * The group content storage service. * * @var \Drupal\group\Entity\GroupRouteContext */ protected $groupRouteContext; /** * The token manager service. * * @var \Drupal\webform\WebformTokenManagerInterface */ protected $tokenManager; /** * Constructs a BlockFieldTransform object. * * @param string $plugin_id * The plugin_id for the transform. * @param mixed $plugin_definition * The plugin implementation definition. * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition * The definition of the field to which the transform is associated. * @param array $settings * The transform settings. * @param string $label * The transform label display setting. * @param string $transform_mode * The transform mode. * @param array $third_party_settings * Any third party settings. * @param \Drupal\Core\Block\BlockManagerInterface $block_manager * The block manager service. * @param \Drupal\group\Entity\GroupRouteContext $group_route_context * The group route context to get the group entity. * @param \Drupal\webform\WebformTokenManagerInterface $token_manager * The token manager service. */ public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $transform_mode, array $third_party_settings, BlockManagerInterface $block_manager, GroupRouteContext $group_route_context, WebformTokenManagerInterface $token_manager) { parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $transform_mode, $third_party_settings); $this->blockManager = $block_manager; $this->groupRouteContext = $group_route_context; $this->tokenManager = $token_manager; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['transform_mode'], $configuration['third_party_settings'], $container->get('plugin.manager.block'), $container->get('group.group_route_context'), $container->get('webform.token_manager') ); } /** * {@inheritdoc} */ public function transformElements(FieldItemListInterface $items, $langcode) { $elements = []; if ($items->isEmpty()) { return $elements; } foreach ($items as $item) { // Assuming each $item contains the plugin_id and settings. $plugin_id = $item->get('plugin_id')->getValue(); $settings = $item->get('settings')->getValue(); // Create block plugin instance. $block_plugin = $this->blockManager->createInstance($plugin_id, $settings); // We currently only handle Views blocks and Webform blocks. // Views blocks leverage the ViewsTransform plugin, while Webform blocks // get the form elements and transform them as a simple field list. if ($block_plugin instanceof ViewsBlock) { $args = []; // If you need to pass contextual filter values, add them here. // You can get any other fields from the parent by loading the entity // with $items->getEntity(); - this is useful if you want to get a // category, or some other setting the View needs. // // Get the View id and display id, this is one way. $plugin_id_array = explode(':', $plugin_id); $view_name_array = explode('-', $plugin_id_array[1]); // Transform API Views submodule provides a ViewsTransform plugin. $elements[] = new ViewTransform($view_name_array[0], $view_name_array[1], [], $args); } elseif ($block_plugin instanceof WebformBlock) { // Get the Webform ID from the block settings. $webform_id = $settings['webform_id']; // Load the webform. $webform = Webform::load($webform_id); if ($webform) { // Return only the form elements. $webform_elements = $webform->getElementsInitialized(); $webform_elements = $this->tokenManager->replace($webform_elements, $webform); $elements[] = [ 'type' => 'webform', 'webform_id' => $webform_id, 'fields' => $this->processWebformFields($webform_elements), ]; } } } return $elements; } /** * Removes the hash from the keys of the given array for Transform API. * * Also turns the root level keys to numeric. */ protected function processWebformFields(array $array, $level = 0) { $result = []; $index = 0; foreach ($array as $key => $value) { // Remove the leading '#' from the key. $newKey = ltrim($key, '#'); // If the value is an array, process it recursively. if (is_array($value)) { $value = $this->processWebformFields($value, $level + 1); } // Add the new key-value pair to the result array. if ($level === 0) { // For the first level, use numeric keys. $result[$index] = $value; $index++; } else { // For deeper levels, retain associative keys. $result[$newKey] = $value; } } return $result; } }