From 6f34dd7c00bf0bd152a97b175390be00c3a0ba31 Mon Sep 17 00:00:00 2001 From: Daniel Karbach <daniel.karbach@localhorst.tv> Date: Tue, 23 Aug 2022 10:45:48 +0200 Subject: [PATCH] technique translations --- app/Models/Technique.php | 9 +++++ app/Models/TechniqueTranslation.php | 11 ++++++ ...12_create_technique_translations_table.php | 37 +++++++++++++++++++ resources/js/components/techniques/Detail.js | 21 ++++++++--- resources/js/components/techniques/Outline.js | 10 +++-- resources/js/helpers/Technique.js | 15 ++++++++ 6 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 app/Models/TechniqueTranslation.php create mode 100644 database/migrations/2022_08_23_082412_create_technique_translations_table.php create mode 100644 resources/js/helpers/Technique.js diff --git a/app/Models/Technique.php b/app/Models/Technique.php index 1a54a0e..256afc0 100644 --- a/app/Models/Technique.php +++ b/app/Models/Technique.php @@ -17,7 +17,16 @@ class Technique extends Model ->using(TechniqueChapter::class); } + public function translations() { + return $this->hasMany(TechniqueTranslation::class); + } + protected $casts = [ 'index' => 'boolean', ]; + + protected $with = [ + 'translations', + ]; + } diff --git a/app/Models/TechniqueTranslation.php b/app/Models/TechniqueTranslation.php new file mode 100644 index 0000000..e7c7603 --- /dev/null +++ b/app/Models/TechniqueTranslation.php @@ -0,0 +1,11 @@ +<?php + +namespace App\Models; + +use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Model; + +class TechniqueTranslation extends Model +{ + use HasFactory; +} diff --git a/database/migrations/2022_08_23_082412_create_technique_translations_table.php b/database/migrations/2022_08_23_082412_create_technique_translations_table.php new file mode 100644 index 0000000..20c6083 --- /dev/null +++ b/database/migrations/2022_08_23_082412_create_technique_translations_table.php @@ -0,0 +1,37 @@ +<?php + +use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; + +return new class extends Migration +{ + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + Schema::create('technique_translations', function (Blueprint $table) { + $table->id(); + $table->foreignId('technique_id')->constrained(); + $table->string('locale'); + $table->text('title'); + $table->text('short'); + $table->text('description'); + $table->timestamps(); + $table->unique(['technique_id', 'locale']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('technique_translations'); + } +}; diff --git a/resources/js/components/techniques/Detail.js b/resources/js/components/techniques/Detail.js index d586a9a..d955397 100644 --- a/resources/js/components/techniques/Detail.js +++ b/resources/js/components/techniques/Detail.js @@ -1,19 +1,30 @@ import PropTypes from 'prop-types'; import React from 'react'; import { Container } from 'react-bootstrap'; +import { withTranslation } from 'react-i18next'; import Outline from './Outline'; +import { getTranslation } from '../../helpers/Technique'; +import i18n from '../../i18n'; const Detail = ({ technique }) => <Container as="article"> - <h1>{technique.title}</h1> + <h1>{getTranslation(technique, 'title', i18n.language)}</h1> <Outline technique={technique} /> - <div dangerouslySetInnerHTML={{ __html: technique.description }} /> + <div dangerouslySetInnerHTML={{ + __html: getTranslation(technique, 'description', i18n.language), + }} /> {technique.chapters ? technique.chapters.map(chapter => <section id={`c${chapter.id}`} key={`c${chapter.id}`}> {chapter.pivot.level ? - React.createElement(`h${chapter.pivot.level}`, {}, chapter.title) + React.createElement( + `h${chapter.pivot.level}`, + {}, + getTranslation(chapter, 'title', i18n.language), + ) : null} - <div dangerouslySetInnerHTML={{ __html: chapter.description }} /> + <div dangerouslySetInnerHTML={{ + __html: getTranslation(chapter, 'description', i18n.language), + }} /> </section> ) : null} </Container>; @@ -27,4 +38,4 @@ Detail.propTypes = { }), }; -export default Detail; +export default withTranslation()(Detail); diff --git a/resources/js/components/techniques/Outline.js b/resources/js/components/techniques/Outline.js index bf98eba..ae18aa8 100644 --- a/resources/js/components/techniques/Outline.js +++ b/resources/js/components/techniques/Outline.js @@ -1,6 +1,10 @@ import PropTypes from 'prop-types'; import React from 'react'; import { ListGroup } from 'react-bootstrap'; +import { withTranslation } from 'react-i18next'; + +import { getTranslation } from '../../helpers/Technique'; +import i18n from '../../i18n'; const Outline = ({ technique }) => technique.chapters && technique.chapters.length ? <aside className="tech-outline mb-3 ms-3"> @@ -10,9 +14,9 @@ const Outline = ({ technique }) => technique.chapters && technique.chapters.leng action href={`#c${chapter.id}`} key={`c${chapter.id}`} - title={chapter.short || null} + title={getTranslation(chapter, 'short', i18n.language) || null} > - {chapter.title} + {getTranslation(chapter, 'title', i18n.language)} </ListGroup.Item> : null)} </ListGroup> @@ -26,4 +30,4 @@ Outline.propTypes = { }), }; -export default Outline; +export default withTranslation()(Outline); diff --git a/resources/js/helpers/Technique.js b/resources/js/helpers/Technique.js new file mode 100644 index 0000000..ea60cc7 --- /dev/null +++ b/resources/js/helpers/Technique.js @@ -0,0 +1,15 @@ +export const getTranslation = (tech, prop, lang) => { + const direct = tech.translations.find(t => t.locale === lang); + if (direct) { + return direct[prop]; + } + const sameLang = tech.translations.find(t => t.locale.substr(0, 2) === lang.substr(0, 2)); + if (sameLang) { + return sameLang[prop]; + } + return tech[prop]; +}; + +export default { + getTranslation, +}; -- 2.39.5