-
-
Notifications
You must be signed in to change notification settings - Fork 168
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
New language:variables
root
#6212
base: v5/develop
Are you sure you want to change the base?
Changes from 3 commits
5ce59f3
437745f
b1b372f
b171903
1628be7
b56dad6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,7 +48,7 @@ class Language implements Stringable | |
protected bool $single; | ||
protected array $slugs; | ||
protected array $smartypants; | ||
protected array $translations; | ||
protected LanguageTranslations $translations; | ||
protected string|null $url; | ||
|
||
/** | ||
|
@@ -68,14 +68,15 @@ public function __construct(array $props) | |
$this->single = $props['single'] ?? false; | ||
$this->slugs = $props['slugs'] ?? []; | ||
$this->smartypants = $props['smartypants'] ?? []; | ||
$this->translations = $props['translations'] ?? []; | ||
$this->url = $props['url'] ?? null; | ||
|
||
if ($locale = $props['locale'] ?? null) { | ||
$this->locale = Locale::normalize($locale); | ||
} else { | ||
$this->locale = [LC_ALL => $this->code]; | ||
} | ||
|
||
$this->translations = new LanguageTranslations($this, $props['translations'] ?? []); | ||
} | ||
|
||
/** | ||
|
@@ -130,7 +131,7 @@ public function clone(array $props = []): static | |
'name' => $this->name, | ||
'slugs' => $this->slugs, | ||
'smartypants' => $this->smartypants, | ||
'translations' => $this->translations, | ||
'translations' => $this->translations->toArray(), | ||
'url' => $this->url, | ||
], $props)); | ||
} | ||
|
@@ -235,6 +236,9 @@ public function delete(): bool | |
throw new Exception('The language could not be deleted'); | ||
} | ||
|
||
// delete custom translations file if defined | ||
$language->translations()->delete(); | ||
|
||
// if needed, convert content storage to single lang | ||
foreach ($kirby->models() as $model) { | ||
if ($language->isLast() === true) { | ||
|
@@ -482,12 +486,19 @@ public function save(): static | |
'direction' => $this->direction(), | ||
'locale' => Locale::export($this->locale()), | ||
'name' => $this->name(), | ||
'translations' => $this->translations(), | ||
'translations' => $this->translations()->toArray(), | ||
'url' => $this->url, | ||
]; | ||
|
||
ksort($data); | ||
|
||
// save translations to the custom root and remove translations | ||
// to prevent duplication write into the language file | ||
if ($this->translations()->root() !== null) { | ||
$this->translations()->save($data['translations'] ?? []); | ||
$data['translations'] = []; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about instead of unsetting it here, we do an if-else clause: The if part writes it to the dedicated root, the else part adds it to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If custom root is already set ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What I meant: $data = [
...$existingData,
'code' => $this->code(),
'default' => $this->isDefault(),
'direction' => $this->direction(),
'locale' => Locale::export($this->locale()),
'name' => $this->name(),
'url' => $this->url,
];
ksort($data);
// save translations to the custom root and remove translations
// to prevent duplication write into the language file
if ($this->translations()->root() !== null) {
$this->translations()->save();
} else {
$data['translations'] = $this->translations()->toArray();
} (not passing anything to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to empty to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But if we don't add it to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, |
||
|
||
Data::write($this->root(), $data); | ||
|
||
return $this; | ||
|
@@ -548,9 +559,9 @@ public function toArray(): array | |
} | ||
|
||
/** | ||
* Returns the translation strings for this language | ||
* Returns the language translations object for this language | ||
*/ | ||
public function translations(): array | ||
afbora marked this conversation as resolved.
Show resolved
Hide resolved
|
||
public function translations(): LanguageTranslations | ||
{ | ||
return $this->translations; | ||
} | ||
|
@@ -594,7 +605,7 @@ public function update(array|null $props = null): static | |
$language = $language->clone($props); | ||
|
||
if (isset($props['translations']) === true) { | ||
$language->translations = $props['translations']; | ||
$language->translations = $language->translations->update($props['translations'] ?? null); | ||
} | ||
|
||
// validate the language rules after before hook was applied | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,133 @@ | ||||||||||||||||||
<?php | ||||||||||||||||||
|
||||||||||||||||||
namespace Kirby\Cms; | ||||||||||||||||||
|
||||||||||||||||||
use Kirby\Data\Data; | ||||||||||||||||||
use Kirby\Exception\Exception; | ||||||||||||||||||
use Kirby\Filesystem\F; | ||||||||||||||||||
use Throwable; | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* Manages the translations string for a language, | ||||||||||||||||||
* either from the language file or `translations` root | ||||||||||||||||||
* @since 5.0.0 | ||||||||||||||||||
* | ||||||||||||||||||
* @package Kirby Cms | ||||||||||||||||||
* @author Ahmet Bora <[email protected]> | ||||||||||||||||||
* @link https://getkirby.com | ||||||||||||||||||
* @copyright Bastian Allgeier | ||||||||||||||||||
* @license https://getkirby.com/license | ||||||||||||||||||
*/ | ||||||||||||||||||
class LanguageTranslations | ||||||||||||||||||
{ | ||||||||||||||||||
public function __construct( | ||||||||||||||||||
protected Language $language, | ||||||||||||||||||
protected array $data = [] | ||||||||||||||||||
) { | ||||||||||||||||||
$this->data = [...$this->load(), ...$this->data]; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* Deletes the current language translations file | ||||||||||||||||||
* if custom root defined | ||||||||||||||||||
*/ | ||||||||||||||||||
public function delete(): void | ||||||||||||||||||
{ | ||||||||||||||||||
if ($file = $this->root()) { | ||||||||||||||||||
if (F::remove($file) !== true) { | ||||||||||||||||||
throw new Exception('The language translations could not be deleted'); | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* Returns a single translation string by key | ||||||||||||||||||
*/ | ||||||||||||||||||
public function get(string $key, string|null $default = null): string|null | ||||||||||||||||||
{ | ||||||||||||||||||
return $this->data[$key] ?? $default; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* Loads the language translations based on custom roots | ||||||||||||||||||
*/ | ||||||||||||||||||
public function load(): array | ||||||||||||||||||
{ | ||||||||||||||||||
if ($file = static::root()) { | ||||||||||||||||||
afbora marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
try { | ||||||||||||||||||
return Data::read($file); | ||||||||||||||||||
} catch (Throwable) { | ||||||||||||||||||
// skip when an exception thrown | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
return []; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* Saves the language translations in the custom root | ||||||||||||||||||
* @return $this | ||||||||||||||||||
* @internal | ||||||||||||||||||
*/ | ||||||||||||||||||
public function save(array $translations = []): static | ||||||||||||||||||
distantnative marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
{ | ||||||||||||||||||
$this->data = $translations; | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
|
||||||||||||||||||
if ($root = $this->root()) { | ||||||||||||||||||
Data::write($root, $this->data); | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
return $this; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* Returns custom translations root path if defined | ||||||||||||||||||
*/ | ||||||||||||||||||
public function root(): string|null | ||||||||||||||||||
{ | ||||||||||||||||||
if ($root = App::instance()->root('translations')) { | ||||||||||||||||||
return $root . '/' . $this->language->code() . '.php'; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
return null; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* Removes a translation key | ||||||||||||||||||
* | ||||||||||||||||||
* @return $this | ||||||||||||||||||
*/ | ||||||||||||||||||
public function remove(string $key): static | ||||||||||||||||||
{ | ||||||||||||||||||
unset($this->data[$key]); | ||||||||||||||||||
return $this; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* Sets the translation key | ||||||||||||||||||
* | ||||||||||||||||||
* @return $this | ||||||||||||||||||
*/ | ||||||||||||||||||
public function set(string $key, string|null $value = null): static | ||||||||||||||||||
{ | ||||||||||||||||||
$this->data[$key] = $value; | ||||||||||||||||||
return $this; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* Returns translations | ||||||||||||||||||
*/ | ||||||||||||||||||
public function toArray(): array | ||||||||||||||||||
{ | ||||||||||||||||||
return $this->data; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* Updates the translations data | ||||||||||||||||||
*/ | ||||||||||||||||||
public function update(array $data = []): static | ||||||||||||||||||
{ | ||||||||||||||||||
$this->data = $data; | ||||||||||||||||||
return $this; | ||||||||||||||||||
} | ||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question:
I don't have a good idea yet, but wondering if it's too confusing to havei18n:translations
andtranslations
? Maybelanguages:translations
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bastianallgeier What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was our last decision for the language variable permissions? I wonder if we maybe should go the same route here with naming as for permissions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now to be
languageVariables.create|update|delete
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could go for
language:variables
maybeI know that it totally clashes with the translations naming everywhere. But I think it makes sense to fully commit to one naming convention here and language variables are at least not giving us any more headaches with the entire content translations vs. ui translations monster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe even
i18n:variables
then?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure for this PR, @bastianallgeier ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say that it belongs to the language and thus the language namespace feels better to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My point there is that so far we don't have a language namespace anyways, we are creating a new one. And what if language is the i18n namespace?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still about the root and I think we are mixing them up here. The i18n roots are all in our kirby folder to store interface translations and slug rules. The language:variables root would be a custom project root inside of site.