diff --git a/core/config/schema/core.entity.schema.yml b/core/config/schema/core.entity.schema.yml
index 6a4bc1a..60f214b 100644
--- a/core/config/schema/core.entity.schema.yml
+++ b/core/config/schema/core.entity.schema.yml
@@ -367,8 +367,5 @@ bundle_config_entity:
type: label
label: 'Indefinite plural name'
label_count:
- type: sequence
+ type: plural_label
label: 'Count label'
- sequence:
- type: label
- label: 'Plural variant'
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBundleBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBundleBase.php
index 131af79..6b3380b 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBundleBase.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBundleBase.php
@@ -32,11 +32,9 @@
/**
* A definite singular/plural count label.
*
- * The label is an array having the plural variants as items.
- *
- * @var string[]
+ * @var string
*/
- protected $label_count = [];
+ protected $label_count;
/**
* Deletes display if a bundle is deleted.
@@ -94,7 +92,14 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti
* {@inheritdoc}
*/
public function getSingularLabel() {
- return $this->label_singular = $this->label_singular ?: Unicode::strtolower($this->label());
+ if (empty($this->label_singular)) {
+ // Provide a fallback in case label_singular is not set yet.
+ if ($this->isNew()) {
+ return '';
+ }
+ $this->label_singular = Unicode::strtolower($this->label());
+ }
+ return $this->label_singular;
}
/**
@@ -102,8 +107,13 @@ public function getSingularLabel() {
*/
public function getPluralLabel() {
if (empty($this->label_plural)) {
+ // Provide a fallback in case label_plural is not set yet.
+ if ($this->isNew()) {
+ return '';
+ }
$arguments = ['@label' => Unicode::strtolower($this->label())];
- $this->label_plural = new TranslatableMarkup('@label items', $arguments);
+ $options = ['langcode' => $this->language()->getId()];
+ $this->label_plural = new TranslatableMarkup('@label items', $arguments, $options);
}
return $this->label_plural;
}
@@ -113,14 +123,15 @@ public function getPluralLabel() {
*/
public function getCountLabel($count) {
$index = $this->getPluralIndex($count);
- if (isset($this->label_count[$index])) {
- return new FormattableMarkup($this->label_count[$index], ['@count' => $count]);
+ $label_count = empty($this->label_count) ? [] : explode(PluralTranslatableMarkup::DELIMITER, $this->label_count);
+ if (isset($label_count[$index])) {
+ return new FormattableMarkup($label_count[$index], ['@count' => $count]);
}
$arguments = [
- '@label_singular' => $this->getSingularLabel(),
- '@label_plural' => $this->getPluralLabel(),
+ '@singular' => $this->getSingularLabel(),
+ '@plural' => $this->getPluralLabel(),
];
- return new PluralTranslatableMarkup($count, '1 @label_singular', '@count @label_plural', $arguments);
+ return new PluralTranslatableMarkup($count, '1 @singular', '@count @plural', $arguments);
}
/**
diff --git a/core/modules/book/config/install/node.type.book.yml b/core/modules/book/config/install/node.type.book.yml
index 0c07a79..4deaa97 100644
--- a/core/modules/book/config/install/node.type.book.yml
+++ b/core/modules/book/config/install/node.type.book.yml
@@ -11,3 +11,6 @@ help: ''
new_revision: true
preview_mode: 1
display_submitted: true
+label_singular: 'book page'
+label_plural: 'book pages'
+label_count: "1 book page\x03@count book pages"
diff --git a/core/modules/forum/config/optional/node.type.forum.yml b/core/modules/forum/config/optional/node.type.forum.yml
index 8ed965d..a6f19e8 100644
--- a/core/modules/forum/config/optional/node.type.forum.yml
+++ b/core/modules/forum/config/optional/node.type.forum.yml
@@ -11,3 +11,6 @@ help: ''
new_revision: false
preview_mode: 1
display_submitted: true
+label_singular: 'forum topic'
+label_plural: 'forum topics'
+label_count: "1 forum topic\x03@count forum topics"
diff --git a/core/modules/node/src/NodeTypeForm.php b/core/modules/node/src/NodeTypeForm.php
index 6d160ab..f08286b 100644
--- a/core/modules/node/src/NodeTypeForm.php
+++ b/core/modules/node/src/NodeTypeForm.php
@@ -6,6 +6,7 @@
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
use Drupal\language\Entity\ContentLanguageSettings;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -184,7 +185,7 @@ public function form(array $form, FormStateInterface $form_state) {
);
$form['display']['plural'] = [
'#type' => 'fieldset',
- '#title' => $this->t('Label variants'),
+ '#title' => $this->t('Singular and plural labels'),
'#description' => $this->t('These are alternatives to the node type label for singular and plural cases.'),
];
$form['display']['plural']['label_singular'] = [
@@ -200,47 +201,20 @@ public function form(array $form, FormStateInterface $form_state) {
'#default_value' => $type->getPluralLabel(),
];
- if (\Drupal::hasService('locale.plural.formula')) {
- $langcode = $type->language()->getId();
- $plurals = \Drupal::service('locale.plural.formula')->getNumberOfPlurals($langcode);
- }
- else {
- // We assume 2 plurals if Locale's services are not available.
- $plurals = 2;
- }
- $label_count = $type->get('label_count');
-
+ $arguments = ['@plural' => $type->getPluralLabel() ?: $this->t('items')];
$form['display']['label_count'] = [
'#type' => 'fieldset',
'#title' => $this->t('Count labels'),
- '#description' => $this->t('Count labels are used to build a text representation of a certain number of @label_plural. Token @count is available and will be replaced with the number of @label_plural.', ['@label_plural' => $type->getPluralLabel()]),
+ '#description' => $this->t('Count labels are used to build a text representation of a certain number of @label_plural. Token @count is available and will be replaced with the number of @plural.', $arguments),
'#tree' => TRUE,
];
+ $plurals = $this->getNumberOfPlurals($type->language()->getId());
for ($i = 0; $i < $plurals; $i++) {
- if ($i == 0) {
- $title = $this->t('Singular form');
- }
- elseif ($plurals == 2 && $i == 1) {
- $title = $this->t('Plural form');
- }
- else {
- $title = $this->formatPlural($i, 'First plural form', '@count. plural form');
- }
- if (isset($label_count[$i])) {
- $default_value = $label_count[$i];
- }
- else {
- $arguments = [
- '@label_singular' => $type->getSingularLabel(),
- '@label_plural' => $type->getPluralLabel(),
- ];
- $default_value = $i == 0 ? $this->t('1 @label_singular', $arguments) : $this->t('@count @label_plural', $arguments);
- }
$form['display']['label_count'][$i] = [
'#type' => 'textfield',
- '#title' => $title,
- '#description' => $this->t('Text to use for this variant, @count will be replaced with the number of @label_plural.', ['@label_plural' => $type->getPluralLabel()]),
- '#default_value' => $default_value,
+ '#title' => $this->getPluralVariantLabel($plurals, $i),
+ '#description' => $this->t('Text to use for this variant, @count will be replaced with the number of @plural.', $arguments),
+ '#default_value' => $this->getPluralVariantDefaultValue($i),
];
}
@@ -268,6 +242,10 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
if ($id == '0') {
$form_state->setErrorByName('type', $this->t("Invalid machine-readable name. Enter a name other than %invalid.", array('%invalid' => $id)));
}
+
+ // Pack the label_count values as a plural_label.
+ $label_count = array_filter($form_state->getValue('label_count'));
+ $form_state->setValue('label_count', implode(PluralTranslatableMarkup::DELIMITER, $label_count));
}
/**
@@ -315,4 +293,64 @@ public function save(array $form, FormStateInterface $form_state) {
$form_state->setRedirectUrl($type->urlInfo('collection'));
}
+ /**
+ * Returns a plural variant label given the variant delta and variants count.
+ *
+ * @param int $plurals
+ * The total number of plural variants.
+ * @param int $delta
+ * The plural variant delta.
+ *
+ * @return \Drupal\Component\Render\MarkupInterface
+ * The variant label.
+ */
+ protected function getPluralVariantLabel($plurals, $delta) {
+ if ($delta == 0) {
+ return $this->t('Singular form');
+ }
+ elseif ($plurals == 2 && $delta == 1) {
+ return $this->t('Plural form');
+ }
+ return $this->formatPlural($delta, 'First plural form', '@count. plural form');
+ }
+
+ /**
+ * Retrieves a plural variant from the backend or assures a decent fallback.
+ *
+ * @param int $delta
+ * The plural variant delta.
+ *
+ * @return \Drupal\Component\Render\MarkupInterface|string
+ * The plural variant default value.
+ */
+ protected function getPluralVariantDefaultValue($delta) {
+ static $label_count;
+
+ /** @var \Drupal\node\Entity\NodeType $type */
+ $type = $this->getEntity();
+
+ if (!isset($label_count)) {
+ $label_count = $type->get('label_count');
+ $label_count = $label_count ? explode(PluralTranslatableMarkup::DELIMITER, $label_count) : [];
+ }
+
+ if (isset($label_count[$delta])) {
+ // A value was stored in the backend.
+ return $label_count[$delta];
+ }
+
+ $singular = $type->getSingularLabel();
+ $plural = $type->getPluralLabel();
+
+ if ($type->isNew() || ($delta == 0 && empty($singular) || ($delta > 0 && empty($plural)))) {
+ // Either the node type is not yet saved (we don't even know the entity
+ // label) or we cannot assure a decent fallback.
+ return '';
+ }
+
+ // Provide a fallback default value.
+ $arguments = ['@singular' => $singular, '@plural' => $plural];
+ return $delta == 0 ? $this->t('1 @singular', $arguments) : $this->t('@count @plural', $arguments);
+ }
+
}
diff --git a/core/profiles/standard/config/install/node.type.article.yml b/core/profiles/standard/config/install/node.type.article.yml
index 2a13b53..9d6f11a 100644
--- a/core/profiles/standard/config/install/node.type.article.yml
+++ b/core/profiles/standard/config/install/node.type.article.yml
@@ -10,6 +10,4 @@ preview_mode: 1
display_submitted: true
label_singular: article
label_plural: articles
-label_count:
- - '1 article'
- - '@count articles'
+label_count: "1 article\x03@count articles"
diff --git a/core/profiles/standard/config/install/node.type.page.yml b/core/profiles/standard/config/install/node.type.page.yml
index 60f4101..2c1de80 100644
--- a/core/profiles/standard/config/install/node.type.page.yml
+++ b/core/profiles/standard/config/install/node.type.page.yml
@@ -10,6 +10,4 @@ preview_mode: 1
display_submitted: false
label_singular: page
label_plural: pages
-label_count:
- - '1 page'
- - '@count pages'
+label_count: "1 page\x03@count pages"