Working on i18n

This commit is contained in:
Bob den Otter
2018-11-24 16:48:42 +01:00
parent 5933ee4ead
commit b4e7a522a1
8 changed files with 134 additions and 91 deletions

View File

@@ -40,7 +40,7 @@ homepage:
uses: title
group: meta
viewless: true
locales: ['nl', 'en', 'pt_BR']
locales: ['en', 'nl', 'pt_BR']
singleton: true
default_status: published
icon_many: "fa:home"

View File

@@ -114,9 +114,9 @@ class ContentTypesParser extends BaseParser
}
if (!isset($contentType['locales'])) {
$contentType['locales'] = false;
$contentType['locales'] = [];
} else if (is_string($contentType['locales'])) {
$contentType['locales'] = false;
$contentType['locales'] = (array) $contentType['locales'];
}
[$fields, $groups] = $this->parseFieldsAndGroups($contentType['fields']);

View File

@@ -43,8 +43,8 @@ class ContentEditController extends BaseController
$twigvars = [
'record' => $content,
'locales' => $content->getDefinition()->get('locales'),
'currentlocale' => $request->query->get('locale'),
'locales' => $content->getLocales(),
'currentlocale' => $this->getEditLocale($request, $content),
];
return $this->renderTemplate('content/edit.html.twig', $twigvars);
@@ -57,8 +57,6 @@ class ContentEditController extends BaseController
{
$token = new CsrfToken('editrecord', $request->request->get('_csrf_token'));
// dd($token);
if (! $this->csrfTokenManager->isTokenValid($token)) {
throw new InvalidCsrfTokenException();
}
@@ -72,14 +70,13 @@ class ContentEditController extends BaseController
$url = $urlGenerator->generate('bolt_content_edit', ['id' => $content->getId()]);
dump($url);
return new RedirectResponse('http://nu.nl');
return new RedirectResponse($url);
}
private function contentFromPost(?Content $content, Request $request): Content
{
$post = $request->request->all();
$locale = $this->getPostedLocale($post);
if (! $content) {
@@ -89,20 +86,18 @@ class ContentEditController extends BaseController
$content->setConfig($this->config);
}
$locale = $this->getPostedLocale($post);
$content->setStatus(current($post['status']));
$content->setPublishedAt(new Carbon($post['publishedAt']));
$content->setDepublishedAt(new Carbon($post['depublishedAt']));
foreach ($post['fields'] as $key => $postfield) {
$this->updateFieldFromPost($key, $postfield, $content);
$this->updateFieldFromPost($key, $postfield, $content, $locale);
}
return $content;
}
private function updateFieldFromPost(string $key, $postfield, Content $content): void
private function updateFieldFromPost(string $key, $postfield, Content $content, string $locale): void
{
if ($content->hasField($key)) {
$field = $content->getField($key);
@@ -114,11 +109,31 @@ class ContentEditController extends BaseController
}
$field->setValue((array) $postfield);
if ($field->getDefinition()->get('localise')) {
$field->setLocale($locale);
} else {
$field->setLocale('');
}
}
private function getPostedLocale($post)
private function getEditLocale(Request $request, Content $content): string
{
$locale = $post->get('locale');
$locale = $request->query->get('locale');
$locales = $content->getLocales();
if (!$locales->contains($locale)) {
$locale = $locales->first();
}
return $locale;
}
private function getPostedLocale(array $post): string
{
$locale = $post['_edit_locale'] ?: '';
return $locale;
}

View File

@@ -49,62 +49,4 @@ class ContentLocalisationController extends BaseController
]);
}
/**
* @Route("/edit/{id}", name="bolt_content_edit_post", methods={"POST"})
*/
public function editPost(Request $request, ObjectManager $manager, UrlGeneratorInterface $urlGenerator, ?Content $content = null): Response
{
$token = new CsrfToken('editrecord', $request->request->get('_csrf_token'));
if (! $this->csrfTokenManager->isTokenValid($token)) {
throw new InvalidCsrfTokenException();
}
$content = $this->contentFromPost($content, $request);
$manager->persist($content);
$manager->flush();
$this->addFlash('success', 'content.updated_successfully');
$url = $urlGenerator->generate('bolt_content_edit', ['id' => $content->getId()]);
return new RedirectResponse($url);
}
private function contentFromPost(?Content $content, Request $request): Content
{
$post = $request->request->all();
if (! $content) {
$content = new Content();
$content->setAuthor($this->getUser());
$content->setContentType($request->attributes->get('id'));
$content->setConfig($this->config);
}
$content->setStatus(current($post['status']));
$content->setPublishedAt(new Carbon($post['publishedAt']));
$content->setDepublishedAt(new Carbon($post['depublishedAt']));
foreach ($post['fields'] as $key => $postfield) {
$this->updateFieldFromPost($key, $postfield, $content);
}
return $content;
}
private function updateFieldFromPost(string $key, $postfield, Content $content): void
{
if ($content->hasField($key)) {
$field = $content->getField($key);
} else {
$fields = collect($content->getDefinition()->get('fields'));
$field = Field::factory($fields->get($key)['type']);
$field->setName($key);
$content->addField($field);
}
$field->setValue((array) $postfield);
}
}

View File

@@ -175,6 +175,18 @@ class Content
return $this->contentTypeDefinition;
}
public function getLocales()
{
$locales = $this->getDefinition()->get('locales');
return collect($locales);
}
public function getDefaultLocale()
{
return $this->getLocales()->first();
}
public function getSummary(): array
{
return [
@@ -297,6 +309,52 @@ class Content
return $this->fields;
}
/**
* @return Collection|Field[]
*/
public function getLocalisedFields(string $locale = '', bool $fallback = true): \Tightenco\Collect\Support\Collection
{
if (!$locale) {
$locale = $this->getDefaultLocale();
}
$fields = collect([]);
foreach ($this->getDefinition()->get('fields') as $name => $field) {
$field = $this->getLocalisedField($name, $locale, $fallback, $field);
$fields->put($name, $field);
}
return $fields;
}
public function getLocalisedField(string $name, string $locale = '', bool $fallback = true, array $definition = [])
{
// First, see if we have the field, in the correct locale
foreach ($this->fields as $field) {
if ($field->getName() == $name && in_array($field->getLocale(), [$locale, ''])) {
return $field;
}
}
// Second, see if we have the field, in the fallback locale
if ($fallback) {
foreach ($this->fields as $field) {
if ($field->getName() == $name && $field->getLocale() == $this->getDefaultLocale()) {
return $field;
}
}
}
// Third, see if we can create the field on the fly
if (!empty($definition)) {
return Field::factory($definition['type'], $name, $definition);
}
// Alas, return an empty array
return [];
}
public function hasField(string $name): bool
{
return collect($this->fields)->contains('name', $name);

View File

@@ -122,15 +122,23 @@ class Field
/**
* @return Field
*/
public static function factory(string $name = 'generic'): self
public static function factory(string $type = 'generic', string $name = '', array $definition = []): self
{
$classname = '\\Bolt\\Entity\\Field\\' . ucwords($name) . 'Field';
$classname = '\\Bolt\\Entity\\Field\\' . ucwords($type) . 'Field';
if (class_exists($classname)) {
$field = new $classname();
} else {
$field = new self();
}
if (!empty($name)) {
$field->setName($name);
}
if (!empty($definition)) {
$field->setDefinition($type, $definition);
}
return $field;
}

View File

@@ -25,7 +25,7 @@ class LocaleExtension extends AbstractExtension
public function __construct(string $locales, UrlGeneratorInterface $urlGenerator)
{
$this->localeCodes = explode('|', $locales);
$this->localeCodes = collect(explode('|', $locales));
$this->urlGenerator = $urlGenerator;
}
@@ -39,6 +39,7 @@ class LocaleExtension extends AbstractExtension
return [
new TwigFunction('locales', [$this, 'getLocales'], $env),
new TwigFunction('contentlocales', [$this, 'getContentLocales'], $env),
new TwigFunction('locale', [$this, 'getLocale']),
new TwigFunction('flag', [$this, 'flag'], $safe),
];
@@ -60,6 +61,18 @@ class LocaleExtension extends AbstractExtension
return $this->locales;
}
$this->locales = $this->localeHelper($env, $this->localeCodes);
return $this->locales;
}
public function getContentLocales(Twig_Environment $env, Collection $localeCodes)
{
return $this->localeHelper($env, $localeCodes);
}
private function localeHelper(Twig_Environment $env, Collection $localeCodes)
{
// Get the route and route params, to set the new localised link
$globals = $env->getGlobals();
@@ -68,23 +81,31 @@ class LocaleExtension extends AbstractExtension
$route = $request->attributes->get('_route');
$routeParams = $request->attributes->get('_route_params');
$this->locales = new Collection();
foreach ($this->localeCodes as $localeCode) {
$locales = new Collection();
foreach ($localeCodes as $localeCode) {
$locale = $this->localeInfo($localeCode);
$routeParams['locale'] = $locale->get('code');
$locale->put('link', $this->urlGenerator->generate($route, $routeParams));
$this->locales->push($locale);
$locales->push($locale);
}
return $this->locales;
return $locales;
}
public function flag($localeCode)
{
$locale = $this->localeInfo($localeCode);
return $locale->get('flag');
$html = sprintf(
'<span class="fp mr-1 %s" title="%s - %s / %s"></span>',
$locale->get('flag'),
$locale->get('name'),
$locale->get('localisedname'),
$locale->get('code')
);
return $html;
}
private function localeInfo($localeCode)

View File

@@ -16,7 +16,8 @@
{% block vue_id 'editor' %}
{% block topsection %}
{{ dump(record.definition) }}
{{ dump(locales()) }}
{{ dump(contentlocales(locales)) }}
{{ dump(locales) }}
{{ dump(currentlocale) }}
{% endblock %}
@@ -26,7 +27,7 @@
<form method="post" id="editcontent">
<input type="hidden" name="_csrf_token" value="{{ csrf_token('editrecord') }}">
{#<input type="hidden" name="_edit_locale" value="{{ currentlocale }}">#}
<input type="hidden" name="_edit_locale" value="{{ currentlocale }}">
<!-- fields -->
{% set groups = record.definition.groups %}
@@ -46,12 +47,9 @@
{% for key, fielddefinition in record.definition.fields %}
{% set type = fielddefinition.type %}
{% set field = record.field(key) %}
{% set field = record.localisedfield(key, currentlocale, false, fielddefinition) %}
{% set fieldgroup = fielddefinition.group %}
{% if not field %}
{% set field = fieldfactory(key, fielddefinition) %}
{% endif %}
{% if fieldgroup == group %}
{% include[
@@ -94,11 +92,12 @@
{% if record.id %}
<div class="card mb-3">
<div class="card-body">
<p>Currently: <b>{{ currentlocale }}</b>.</p>
<p>{{ 'field.current_locale'|trans }}:
{{ flag(currentlocale) }}<b>{{ currentlocale }}</b>.</p>
<general-language
label="{{ 'field.locale'|trans }}"
label="{{ 'field.switch_to_locale'|trans }}"
current="{{ currentlocale }}"
:locales="{{ locales() }}"
:locales="{{ contentlocales(locales) }}"
></general-language>
<a href="{{ path('bolt_content_edit_locales', {'id': record.id}) }}" class="btn btn-light btn-small">