Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support creating/editing array language variables with using new entries field #7011

Open
wants to merge 2 commits into
base: v5/develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 66 additions & 25 deletions config/areas/languages/dialogs.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,29 @@
'label' => I18n::translate('language.variable.key'),
'type' => 'text'
],
'multiple' => [
'label' => I18n::translate('language.variable.multiple'),
'type' => 'toggle',
'default' => false
],
'value' => [
'buttons' => false,
'counter' => false,
'label' => I18n::translate('language.variable.value'),
'type' => 'textarea'
'type' => 'textarea',
'when' => [
'multiple' => false
]
],
'entries' => [
'field' => ['type' => 'text'],
'label' => I18n::translate('language.variable.entries'),
'help' => I18n::translate('language.variable.entries.help'),
'type' => 'entries',
'min' => 1,
'when' => [
'multiple' => true
]
]
];

Expand Down Expand Up @@ -191,8 +209,13 @@
$request = App::instance()->request();
$language = Find::language($languageCode);

$key = $request->get('key', '');
$value = $request->get('value', '');
$key = $request->get('key', '');
$multiple = $request->get('multiple', false);

$value = match ($multiple) {
true => $request->get('entries', []),
default => $request->get('value', '')
};

LanguageVariable::create($key, $value);

Expand Down Expand Up @@ -230,7 +253,8 @@
'language.translation.update' => [
'pattern' => 'languages/(:any)/translations/(:any)/update',
'load' => function (string $languageCode, string $translationKey) use ($translationDialogFields) {
$variable = Find::language($languageCode)->variable($translationKey, true);
$language = Find::language($languageCode);
$variable = $language->variable($translationKey, true);

if ($variable->exists() === false) {
throw new NotFoundException(
Expand All @@ -239,39 +263,56 @@
}

$fields = $translationDialogFields;
$fields['key']['disabled'] = true;
$fields['value']['autofocus'] = true;

// shows info text when variable is an array
// TODO: 5.0: use entries field instead showing info text
$isVariableArray = is_array($variable->value()) === true;
// the key and multiple fields cannot be changed
$fields['key']['disabled'] = true;
$fields['multiple']['disabled'] = true;

// check if the variable is an array
$isVariableArray = match ($language->isDefault()) {
true => $variable->isArray(),
false => Find::language('default')->variable($translationKey, true)->isArray()
};

// set the correct value field
// when value is string, load value for value field
// when value is array, load value for entries field
if ($isVariableArray === true) {
$fields['value'] = [
'label' => I18n::translate('info'),
'type' => 'info',
'text' => 'You are using an array variable for this key. Please modify it in the language file in /site/languages',
$fields['entries']['autofocus'] = true;
$value = [
'entries' => $variable->value(),
'key' => $variable->key(),
'multiple' => true,
'value' => ''
];
} else {
$fields['value']['autofocus'] = true;
$value = [
'entries' => [],
'key' => $variable->key(),
'multiple' => false,
'value' => ''
];
}

return [
'component' => 'k-form-dialog',
'props' => [
'cancelButton' => $isVariableArray === false,
'fields' => $fields,
'size' => 'large',
'submitButton' => $isVariableArray === false,
'value' => [
'key' => $variable->key(),
'value' => $variable->value()
]
],
'fields' => $fields,
'size' => 'large',
'value' => $value
]
];
},
'submit' => function (string $languageCode, string $translationKey) {
Find::language($languageCode)->variable($translationKey, true)->update(
App::instance()->request()->get('value', '')
);
$request = App::instance()->request();
$multiple = $request->get('multiple', false);
$value = match ($multiple) {
true => $request->get('entries', []),
default => $request->get('value', '')
};

Find::language($languageCode)->variable($translationKey, true)->update($value);

return true;
}
Expand Down
3 changes: 3 additions & 0 deletions i18n/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,10 @@
"language.variables.empty": "No translations yet",

"language.variable.delete.confirm": "Do you really want to delete the variable for {key}?",
"language.variable.entries": "Entries",
"language.variable.entries.help": "This strings will be used for translations count. Each entry corresponds to a different case counter. For example: 0, 1, 2 and more",
Comment on lines +452 to +453
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be more fitting with the existing language.variable.value:

Suggested change
"language.variable.entries": "Entries",
"language.variable.entries.help": "This strings will be used for translations count. Each entry corresponds to a different case counter. For example: 0, 1, 2 and more",
"language.variable.values": "Values",
"language.variable.values.help": "These values will be used according to the translation count. Each entry corresponds to a different case, e.g. for 0, for 1, for 2 and more.",

"language.variable.key": "Key",
"language.variable.multiple": "Multiple",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"language.variable.multiple": "Multiple",
"language.variable.multiple": "Different strings based on count",

Not so happy with this either. But I think the multiple field needs more explanatory label and maybe also on/off texts.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely. I'm not happy with the labels and help texts either. That's why I mentioned it in the PR description. It needs to be more descriptive and clear.

"language.variable.notFound": "The variable could not be found",
"language.variable.value": "Value",

Expand Down
8 changes: 7 additions & 1 deletion panel/src/components/Dialogs/Elements/Fields.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<k-fieldset
v-if="hasFields"
:fields="fields"
:value="value"
:value="formValue"
class="k-dialog-fields"
@input="$emit('input', $event)"
@submit="$emit('submit', $event)"
Expand Down Expand Up @@ -45,6 +45,12 @@ export default {
mixins: [props],
emits: ["input", "submit"],
computed: {
formValue() {
return {
...this.$helper.field.form(this.fields),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Why is this needed?

Copy link
Member Author

@afbora afbora Feb 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question.

For this line:
https://github.com/getkirby/kirby/blob/lab/afbora/support-array-language-variables/config/areas/languages/dialogs.php#L55

Otherwise default value of multiple field is null. We have two condition fields value and entries. When multiple disabled value field visible and when enabled entries field visible. So when multiple value is null, no fields visible.

Not sure this is a correct solution.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we don't use default there but rather add here https://github.com/getkirby/kirby/blob/lab/afbora/support-array-language-variables/config/areas/languages/dialogs.php#L202-L205 something like

'value' => [
  'multiple' => false
]

Copy link
Member Author

@afbora afbora Feb 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it seems to be working.

What I'm wondering is; does this change I made really solve the problem of default values ​​in dialogs? Maybe we can use it in other dialogs or in the future.

If my solution is correct I would prefer the method where the fields work exactly as intended. Otherwise I'm fine with your solution 👍

...this.value
};
},
hasFields() {
return this.$helper.object.length(this.fields) > 0;
}
Expand Down
22 changes: 19 additions & 3 deletions src/Cms/LanguageVariable.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function __construct(
*/
public static function create(
string $key,
string|null $value = null
string|array|null $value = null
): static {
if (is_numeric($key) === true) {
throw new InvalidArgumentException(
Expand Down Expand Up @@ -90,6 +90,14 @@ public function delete(): bool
return true;
}

/**
* Returns the default language variable
*/
public function defaultLanguageVariable(): LanguageVariable
{
return $this->kirby->defaultLanguage()->variable($this->key);
}

/**
* Checks if a language variable exists in the default language
*/
Expand All @@ -99,6 +107,14 @@ public function exists(): bool
return isset($language->translations()[$this->key]) === true;
}

/**
* Checks if the value is an array
*/
public function isArray(): bool
{
return is_array($this->value());
}

/**
* Returns the unique key for the variable
*/
Expand All @@ -110,7 +126,7 @@ public function key(): string
/**
* Sets a new value for the language variable
*/
public function update(string|null $value = null): static
public function update(string|array|null $value = null): static
{
$translations = $this->language->translations();
$translations[$this->key] = $value ?? '';
Expand All @@ -123,7 +139,7 @@ public function update(string|null $value = null): static
/**
* Returns the value if the variable has been translated.
*/
public function value(): string|null
public function value(): string|array|null
{
return $this->language->translations()[$this->key] ?? null;
}
Expand Down
Loading