Browse Source

Proof of concept with tables.

main
Rosie Le Faive 4 weeks ago
parent
commit
3a0d1c1ee2
  1. 17
      css/metadata_profile.css
  2. 4
      metadata_profile.libraries.yml
  3. 13
      metadata_profile.routing.yml
  4. 214
      src/Controller/MetadataProfileController.php

17
css/metadata_profile.css

@ -0,0 +1,17 @@
.field-info-table {
max-width: 40rem;
}
.field-info-table td {
max-width: 49%;
}
.field-info {
padding-bottom: 3rem;
border-bottom: gainsboro 1px solid;
margin-bottom: 3rem;
}
.field-info h2 {
display: inline-block;
}
.field-info .edit-link {
display: block;
}

4
metadata_profile.libraries.yml

@ -0,0 +1,4 @@
metadata_profile:
css:
theme:
css/metadata_profile.css: {}

13
metadata_profile.routing.yml

@ -0,0 +1,13 @@
metadata_profile.node_profile:
path: '/admin/structure/types/manage/{content_type}/metadata_profile'
defaults:
_controller: '\Drupal\metadata_profile\Controller\MetadataProfileController::profile'
_title: 'Metadata Profile'
requirements:
_access: 'TRUE'
content_type: '[a-zA-Z_]+'
options:
parameters:
content_type:
type: string

214
src/Controller/MetadataProfileController.php

@ -0,0 +1,214 @@
<?php
namespace Drupal\metadata_profile\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\Core\Config\Config;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Field\Annotation\FieldType;
class MetadataProfileController extends ControllerBase {
use MessengerTrait;
protected EntityFieldManagerInterface $entityFieldManager;
protected FieldTypePluginManagerInterface $fieldTypePluginManager;
public function __construct(EntityFieldManagerInterface $entity_field_manager, FieldTypePluginManagerInterface $field_type_plugin_manager) {
$this->entityFieldManager = $entity_field_manager;
$this->fieldTypePluginManager = $field_type_plugin_manager;
}
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_field.manager'),
$container->get('plugin.manager.field.field_type')
);
}
public function profile( $content_type) {
// Get core content type information.
$node_type = $this->config('node.type.' . $content_type);
if (!$node_type) {
return ['#markup'=> 'Not a valid content type.'];
}
$build = $this->format_bundle($node_type);
$build['children'] = [
'#type' => 'container',
'#weight' => '9',
];
// Get field information.
$field_definitions = $this->entityFieldManager->getFieldDefinitions('node', $content_type);
foreach ($field_definitions as $field_name => $field_definition) {
$build['children'][$field_name] = $this->format_field($field_name, $field_definition);
}
return $build;
}
/**
* Format information about a bundle.
*/
protected function format_bundle(Config $bundle) {
$build = [
'#type' => 'container',
'#attached' => ['library' => ['metadata_profile/metadata_profile']],
'title' => [
'#plain_text' => $bundle->get('name'),
'#prefix' => '<h1>',
'#suffix' => '</h1>',
],
'machine_name' => [
'#plain_text' => $bundle->get('type'),
'#prefix' => ' (',
'#suffix' => ')',
],
'description' => [
'#plain_text' => $bundle->get('description'),
'#prefix' => '<p>',
'#suffix' => '</p>',
],
];
return $build;
}
protected function format_field(string $field_name, FieldDefinitionInterface $field_definition) {
$render_array = [];
if (str_starts_with($field_name, 'field_') or $field_name == 'title') {
$render_array = [
'#type' => 'container',
'#attributes' => ['class' => ['field-info']],
'#weight' => $this->format_weight($field_definition),
'title' => [
'#plain_text' => $field_definition->getLabel(),
'#prefix' => '<h2 id="' . $field_name . '">',
'#suffix' => '</h2> ',
],
'machine_name' => [
'#plain_text' => $field_name,
'#prefix' => '(',
'#suffix' => ') ',
],
'edit_link' => [
'#type' => 'link',
'#url' => Url::fromRoute('entity.field_config.node_field_edit_form', [
'node_type' => $field_definition->getTargetBundle(),
'field_config' => $field_definition->id(),
'destination' => Url::fromRoute('metadata_profile.node_profile', ['content_type' => $field_definition->getTargetBundle()], ['fragment' => $field_name])->toString(),
]),
'#title' => $this->t('Edit'),
'#attributes' => ['class' => ['edit-link']],
],
'table' => [
'#type' => 'table',
'#header' => ['',''],
'#rows' => $this->getFieldTableRows($field_definition),
'#attributes' => ['class' => ['field-info-table']],
],
'description' => [
'#type' => 'markup',
'#markup' => $field_definition->getDescription() ?: $this->t('[No description]'),
],
'target_bundles' => [
'#title' => $this->t('Target Bundles'),
'#type' => 'container',
'bundles' => $this->format_target_bundles($field_definition),
],
];
}
return $render_array;
}
protected function getFieldTableRows(FieldDefinitionInterface $field_definition) {
$rows = [
[$this->t('Type:'), $this->format_type($field_definition)],
[$this->t('Required:'), $this->format_required($field_definition)],
[$this->t('Repeatable:'), $this->format_cardinality($field_definition)],
];
// TODO: use a class inheritance method to get entity reference and typed relation in one shot.
if (in_array($field_definition->getType(), ['entity_reference', 'typed_relation'])) {
$rows[] = [$this->t('Create new'), $this->format_create_new($field_definition)];
}
return $rows;
}
protected function format_type(FieldDefinitionInterface $field_definition) {
$type = $field_definition->getType();
$type_label = $this->fieldTypePluginManager->getDefinition($type)['label'];
if (in_array($type, ['entity_reference', 'typed_relation'])) {
$type_label = $type_label . ' (' . $field_definition->getSetting('target_type') . ')';
}
return $type_label;
}
protected function format_required(FieldDefinitionInterface $field_definition) {
if ($field_definition->isRequired()) {
return $this->t('Required');
}
else {
return $this->t('Not required');
}
}
protected function format_weight(FieldDefinitionInterface $field_definition) {
return $field_definition->getDisplayOptions('form')['weight'];
}
protected function format_cardinality(FieldDefinitionInterface $field_definition) {
$cardinality = $field_definition->getFieldStorageDefinition()->getCardinality();
if ($cardinality == 1) {
return $this->t('Not repeatable');
} elseif ($cardinality < 0) {
return $this->t('Repeatable');
} elseif ($cardinality > 1) {
return $this->t('Repeatable, limit :limit', [':limit' => $cardinality]);
}
return NULL;
}
protected function format_create_new(FieldDefinitionInterface $field_definition) {
$create_new_bundle = $field_definition->getSetting('handler_settings')['auto_create_bundle'];
$create_new = $field_definition->getSetting('handler_settings')['auto_create_bundle'];
if ($create_new) {
return $create_new_bundle ? 'Create new (' . $create_new_bundle . ')' : 'Create new';
}
else {
return $this->t('Do not create new');
}
}
protected function format_target_bundles(FieldDefinitionInterface $field_definition) {
$handler = $field_definition->getSetting('handler');
$setting = $field_definition->getSetting('handler_settings');
if (!$setting) {
return [];
}
$target_bundles = $setting['target_bundles'];
foreach ($target_bundles as $index => $bundle) {
if ($handler == 'default:taxonomy_term') {
$bundle_config = $this->entityTypeManager()->getStorage('taxonomy_vocabulary')->load($bundle);
}
// TODO: ADD NODE ETC
if ($bundle_config) {
$target_bundles[$index] = $bundle_config->get('name') . ' (' . $bundle . ')';
}
}
return [
'#theme' => 'item_list',
'#title' => $this->t('Target bundles:'),
'#items' => $target_bundles,
'#type' => 'ul'
];
}
}
Loading…
Cancel
Save