module
my_module.module
// Assume $entity is your translatable entity object.
$default_language_entity = $entity->getUntranslated();
$default_language_code = $default_language_entity->language()->getId();
08.10.2026 | Pascal Crott
Get default langcode from entity
my_group.module
/**
* Implements hook_tokens().
*/
function example_group_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
$replacements = [];
// Automatically expose related entities to group_relationships.
if ($type == 'group_relationship' && !empty($data[$type])) {
$token_service = \Drupal::token();
/** @var \Drupal\example\GroupRelationshipTypeServiceInterface $group_relationship_type_service */
$group_relationship_type_service = \Drupal::service('example.group_relationship_type_service');
$group_relationship = $data['group_relationship'];
assert($group_relationship instanceof GroupRelationshipInterface);
foreach ($tokens as $name => $original) {
/** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
foreach ($group_relationship_type_service->getConfiguredEntityTypes() as $entity_type_id => $entity_type) {
if ($name == $entity_type_id) {
$entity = $group_relationship->getEntity();
$bubbleable_metadata->addCacheableDependency($entity);
$replacements[$original] = $entity->label();
}
// Actual chaining of tokens handled below.
if ($entity_tokens = $token_service->findWithPrefix($tokens, $entity_type_id)) {
$replacements += $token_service->generate($entity_type_id, $entity_tokens, [$entity_type_id => $group_relationship->getEntity()], $options, $bubbleable_metadata);
}
}
}
}
return $replacements;
}
13.11.2025 | Nikolas Kopp, Pascal Crott
Token Chaining – How to access tokens for nested information
meta_base.module
/**
* Implements hook_form_FORM_ID_alter().
*
* Replace ugly "Field cannot be empty" error message for comments.
*/
function meta_base_form_comment_story_comment_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
array_unshift($form['#validate'], '_meta_base_comment_validate');
$form['comment_body']['widget']['#required'] = false;
$form['comment_body']['widget'][0]['#required'] = false;
}
/**
* Custom validation for better error message on empty comments.
*/
function _meta_base_comment_validate(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
if (empty($form_state->getValue('comment_body')[0]['value'])) {
$form_state->setErrorByName('comment_body', t('Please enter a comment. An empty comment cannot be saved.'));
}
}
27.01.2023 | Peter Gerken
Make UX better for comment fields if submitted empty
iftra_group_breadcrumbs.module
/**
* Implements hook_theme_registry_alter().
*/
function hook_theme_registry_alter(&$theme_registry) {
// Kill the gin breadcrumb preprocessor, since we do our own backend
// breadcrumb logic.
foreach ($theme_registry['breadcrumb']['preprocess functions'] as $key => $value) {
if ($value == 'gin_preprocess_breadcrumb') {
unset($theme_registry['breadcrumb']['preprocess functions'][$key]);
}
}
}
17.08.2022 | Pascal Crott
iftra_group_breadcrumbs.module
my_module.module
// Get DrupalDateTime object with current date & time (timezone from system is used).
$current_date = new DrupalDateTime();
// Get DrupalDateTime object with the value from a field of type date (timezone from system is used).
$deadline = $entity->field_date->date;
// Change timezone to 'UTC' (just for demo/devbit purpose).
$freelancer_dl->setTimezone(new DateTimeZone('UTC'));
$current_date->setTimezone(new DateTimeZone('UTC'));
// Format DrupalDateTime object (just for demo/devbit purpose).
$freelancer_dl->format(\Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
$current_date->format(\Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
// Modify DrupalDateTime object.
$deadline->modify('-2 Days');
// You can compare the DrupalDateTime objects.
if ($deadline <= $current_date) {
//...do something...
}
07.06.2022 | Fabian Alleblas