首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何轻松地更改每个包中实体的基字段定义

如何轻松地更改每个包中实体的基字段定义
EN

Drupal用户
提问于 2018-01-07 10:49:01
回答 3查看 7.1K关注 0票数 6

我们正在使用Drupal 8中的模块,它引入了一个自定义实体"group“。该实体的特征是"label“基字段,其标题为" title”。作为组管理员,您可以创建几种不同的组类型,这些类型作为组实体的可部署包处理,并继承其标签基字段。

根据组类型,我们希望覆盖窗体、视图、模板等中的通用标签标题。“标签”,“名称”,“分支”,“部门”,“部门”,.

但是,组实体不像节点模块那样在其配置表单中公开标签标题。因此,我们尝试像这样使用钩子_实体_基座_字段_信息_alter()重写标题:

代码语言:javascript
复制
/**
 * Implements hook_entity_base_field_info_alter().
 */
function mymodule_entity_base_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type) {
  if ($entity_type->id() == 'group' && !empty($fields['label'])) {
    $fields['label']->setLabel(t('Name'));
  }
}

它可以工作,但会更改所有包的标题。

我们的下一次尝试是钩子_实体_捆绑_字段_信息_alter()。它公开包信息,但不允许修改基字段。试图用不同的标题重新添加基本字段定义(为了让核心合并字段定义并覆盖基本字段定义)会导致不同的运行时异常。

因此,我们最终手工修改了表单build数组和小部件标题,这可能会在组类型数量增加时引起麻烦。

如何在每个包基上更改基字段的标题,而不必扩展组模块或手动更改组实体字段标签的所有出现情况?

EN

回答 3

Drupal用户

回答已采纳

发布于 2018-01-07 12:50:05

基字段的绑定特定标签存储在label配置实体的BaseFieldOverride中:

定义基字段覆盖实体。允许在包级别上重写基字段。插件注释@ConfigEntityType( id = "base_field_override",label =@ handlers (“基本字段覆盖”),处理程序={“存储”=“Drupal\Core\\BaseFieldOverrideStorage”,"access“= "Drupal\Core\Field\BaseFieldOverrideAccessControlHandler",},config_prefix = "base_field_override",entity_keys = "id”= "id",“标签”= "label“},config_export = "id","field_name“、"entity_type”、"bundle“、"label”、"description“、"required”、"translatable“、"default_value”、"default_value_callback“、”设置“、"field_type”、})

当您从EntityFieldManager::getFieldDefinitions($entity_类型_id,$bundle)获得一个基本字段时,为该字段设置一个新的标签并保存字段定义,那么这个标签不会存储在实体类型中(这是不可能的,因为这在代码中是一样的,对于所有的包也是一样的),但是在前面提到的基本字段中覆盖。

票数 10
EN

Drupal用户

发布于 2018-01-08 01:24:02

@4k4的回答使我们走上了正确的轨道。对于我们的解决方案,我们主要尝试更改一些以编程方式提供的基组类型的标签。

为了帮助其他人使用类似的用例,下面是我们如何做到的:

我们在提供组实体包的模块中实现了钩子_实体_捆绑_字段_信息(),然后使用BaseFieldOverride创建字段重写:

代码语言:javascript
复制
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\Entity\BaseFieldOverride;

/**
 * Implements hook_entity_bundle_field_info().
 */
function ourgroupmodule_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
  $fields = [];

  // Whether the hook implementation was called for our group type.
  if ($entity_type->id() == 'group' && $bundle == 'ourgroup' && !empty($base_field_definitions['label'])) {
    // Create a base field override with custom title.
    $field = BaseFieldOverride::createFromBaseFieldDefinition($base_field_definitions['label'], $bundle);
    $field->setLabel(t('Our group label title'));
    $fields['label'] = $field;
  }

  return $fields;
}

正如@4k4进一步指出的那样,覆盖也可以在其他地方完成。例如,在表单中,提交处理程序覆盖管理UI中创建的组的标题标签。

票数 9
EN

Drupal用户

发布于 2023-01-15 18:01:01

构建@Capi Etheriel的答案,但在创建新的包时使命名更加清晰并修复了一个bug:

代码语言:javascript
复制
public function form(array $form, FormStateInterface $form_state) {
  $form = parent::form($form, $form_state);
  ...

  $form['my_bundle_property'] = [
    '#title' => $this->t('My Bundle property'),
    '#description' => $this->t('This will override the "my_overriden_setting" setting of the "my_overriden_field" field on "my_entity_type" that this is a bundle of.',
    '#type' => 'checkboxes',
    '#options' => ['option1', 'option2],
    '#default_value' => $this->entity->get('my_bundle_property),
  ];

  return $form;
}

public function save(array $form, FormStateInterface $form_state) {
  // You must save the entity first, or the override logic will break when adding new bundles.
  $this->entity->save();

  $field_manager = \Drupal::service('entity_field.manager');
  $definitions = $field_manager->getBaseFieldDefinitions('my_entity_type');
  $override = $definitions['my_overridden_field']->getConfig($this->entity->id());

  $override->setSetting('my_overriden_setting', $this->entity->get('my_overriden_field'));
  $override->save();
  
  ...
}
票数 0
EN
页面原文内容由Drupal提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://drupal.stackexchange.com/questions/253257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档