better modalCard, integrated i18n with vuejs-i18n and drupal's strings_i18n_json_export

remain to automaticly export jsons and updated json files with webpack
and to understand how to access nested translations
This commit is contained in:
Bachir Soussi Chiadmi 2020-12-07 23:11:31 +01:00
parent a4e689c27a
commit 417b084216
23 changed files with 25454 additions and 20 deletions

View File

@ -13,7 +13,8 @@ module.exports = {
alias: {
'vue': 'vue/dist/vue.js',
'theme': utils.resolve(themePath),
'vuejs': utils.resolve(themePath+'/vuejs')
'vuejs': utils.resolve(themePath+'/vuejs'),
'assets': utils.resolve(themePath+'/assets')
}
},
entry: {
@ -39,6 +40,11 @@ module.exports = {
test: /\.vue$/,
use: 'vue-loader'
},
{
resourceQuery: /blockType=i18n/,
type: 'javascript/auto',
loader: '@kazupon/vue-i18n-loader'
},
{
test: /\.js$/,
use: {
@ -83,7 +89,7 @@ module.exports = {
new VueLoaderPlugin(),
new ESLintPlugin({
// fix: true
// exclude: ['node_modules', 'vendor', 'web/core']
// exclude: ['web/.eslintrc.json']
// cache: false,
// ignore: true,
// useEslintrc: false,

View File

@ -60,6 +60,8 @@
"drupal/search_api_solr": "^4.1.7",
"drupal/select_translation": "^1.x-dev",
"drupal/simplenews": "^1.x-dev",
"drupal/string_translation_ui": "^1.2",
"drupal/strings_i18n_json_export": "1.x-dev@dev",
"drupal/subrequests": "^2.0",
"drupal/telephone_formatter": "^1.0@beta",
"drupal/telephone_validation": "^2.1",

157
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "a39c2661f765eebdcbdb7b7732b68200",
"content-hash": "6938e0a5a4fcfb66f59d10750617e9b4",
"packages": [
{
"name": "alchemy/zippy",
@ -10625,6 +10625,160 @@
"source": "https://git.drupalcode.org/project/state_machine"
}
},
{
"name": "drupal/string_translation_ui",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://git.drupalcode.org/project/string_translation_ui.git",
"reference": "8.x-1.2"
},
"dist": {
"type": "zip",
"url": "https://ftp.drupal.org/files/projects/string_translation_ui-8.x-1.2.zip",
"reference": "8.x-1.2",
"shasum": "bd65fb664d36cc5c87358cdb3cc29ecf06458ae1"
},
"require": {
"drupal/core": "^8 || ^9"
},
"type": "drupal-module",
"extra": {
"drupal": {
"version": "8.x-1.2",
"datestamp": "1602689262",
"security-coverage": {
"status": "covered",
"message": "Covered by Drupal's security advisory policy"
}
}
},
"notification-url": "https://packages.drupal.org/8/downloads",
"license": [
"GPL-2.0-or-later"
],
"authors": [
{
"name": "RenatoG",
"homepage": "https://www.drupal.org/user/3326031"
},
{
"name": "andre.bonon",
"homepage": "https://www.drupal.org/user/2376168"
},
{
"name": "dandr",
"homepage": "https://www.drupal.org/user/3637314"
},
{
"name": "fadonascimento",
"homepage": "https://www.drupal.org/user/2847931"
},
{
"name": "htakeo",
"homepage": "https://www.drupal.org/user/1260884"
},
{
"name": "lisotton",
"homepage": "https://www.drupal.org/user/1902738"
},
{
"name": "rafaelMattioni",
"homepage": "https://www.drupal.org/user/3073853"
},
{
"name": "rodrigoeg",
"homepage": "https://www.drupal.org/user/725006"
},
{
"name": "thalles",
"homepage": "https://www.drupal.org/user/3589086"
},
{
"name": "willianp",
"homepage": "https://www.drupal.org/user/3649792"
}
],
"description": "Provides a admin area to insert new strings to be translatable.",
"homepage": "https://www.drupal.org/project/string_translation_ui",
"support": {
"source": "https://git.drupalcode.org/project/string_translation_ui"
}
},
{
"name": "drupal/strings_i18n_json_export",
"version": "dev-1.x",
"source": {
"type": "git",
"url": "https://git.drupalcode.org/project/strings_i18n_json_export.git",
"reference": "851c9053765b42d379c71c46fa4d8a2bcb60454a"
},
"require": {
"drupal/core": "^8"
},
"type": "drupal-module",
"extra": {
"branch-alias": {
"dev-1.x": "1.x-dev"
},
"drupal": {
"version": "8.x-1.1+2-dev",
"datestamp": "1580323935",
"security-coverage": {
"status": "not-covered",
"message": "Dev releases are not covered by Drupal security advisories."
}
}
},
"notification-url": "https://packages.drupal.org/8/downloads",
"license": [
"GPL-2.0-or-later"
],
"authors": [
{
"name": "RenatoG",
"homepage": "https://www.drupal.org/user/3326031"
},
{
"name": "andre.bonon",
"homepage": "https://www.drupal.org/user/2376168"
},
{
"name": "dandr",
"homepage": "https://www.drupal.org/user/3637314"
},
{
"name": "fadonascimento",
"homepage": "https://www.drupal.org/user/2847931"
},
{
"name": "htakeo",
"homepage": "https://www.drupal.org/user/1260884"
},
{
"name": "lisotton",
"homepage": "https://www.drupal.org/user/1902738"
},
{
"name": "rafaelMattioni",
"homepage": "https://www.drupal.org/user/3073853"
},
{
"name": "rodrigoeg",
"homepage": "https://www.drupal.org/user/725006"
},
{
"name": "willianp",
"homepage": "https://www.drupal.org/user/3649792"
}
],
"description": "Allows you to export strings to a JSON i18n file",
"homepage": "https://www.drupal.org/project/strings_i18n_json_export",
"support": {
"source": "https://git.drupalcode.org/project/strings_i18n_json_export"
},
"time": "2020-01-29T18:50:40+00:00"
},
{
"name": "drupal/subrequests",
"version": "2.3.0",
@ -17542,6 +17696,7 @@
"drupal/search_api_page": 20,
"drupal/select_translation": 20,
"drupal/simplenews": 20,
"drupal/strings_i18n_json_export": 20,
"drupal/telephone_formatter": 10,
"drupal/translate_side_by_side": 20,
"drupal/translation_views": 20,

View File

@ -155,6 +155,8 @@ module:
smtp: 0
sophron: 0
state_machine: 0
string_translation_ui: 0
strings_i18n_json_export: 0
synonyms: 0
syslog: 0
system: 0

View File

@ -0,0 +1 @@
export_type: '0'

View File

@ -0,0 +1,17 @@
uuid: 616a982c-cdd0-41b6-9a25-7f7365f0f2f7
langcode: en
status: true
dependencies:
module:
- strings_i18n_json_export
title: 'Default cron handler'
id: strings_i18n_json_export_cron
weight: 0
module: strings_i18n_json_export
callback: strings_i18n_json_export_cron
scheduler:
id: simple
launcher:
id: serial
logger:
id: database

View File

@ -1026,6 +1026,72 @@ display:
separator: ', '
field_api_classes: false
plugin_id: field
tid:
id: tid
table: taxonomy_term_field_revision
field: tid
relationship: none
group_type: group
admin_label: ''
label: ''
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: false
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: number_integer
settings:
thousand_separator: ''
prefix_suffix: true
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
entity_type: taxonomy_term
entity_field: tid
plugin_id: field
cache_metadata:
max-age: -1
contexts:

16
package-lock.json generated
View File

@ -3033,6 +3033,16 @@
}
}
},
"@kazupon/vue-i18n-loader": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/@kazupon/vue-i18n-loader/-/vue-i18n-loader-0.5.0.tgz",
"integrity": "sha512-Tp2mXKemf9/RBhI9CW14JjR9oKjL2KH7tV6S0eKEjIBuQBAOFNuPJu3ouacmz9hgoXbNp+nusw3MVQmxZWFR9g==",
"dev": true,
"requires": {
"js-yaml": "^3.13.1",
"json5": "^2.1.1"
}
},
"@nodelib/fs.scandir": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
@ -11729,6 +11739,12 @@
"integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
"dev": true
},
"vue-i18n": {
"version": "8.22.2",
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.22.2.tgz",
"integrity": "sha512-rb569fVJInPUgS/bbCxEQ9DrAoFTntuJvYoK4Fpk2VfNbA09WzdTKk57ppjz3S+ps9hW+p9H+2ASgMvojedkow==",
"dev": true
},
"vue-infinite-loading": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/vue-infinite-loading/-/vue-infinite-loading-2.4.5.tgz",

View File

@ -32,6 +32,7 @@
"devDependencies": {
"@babel/core": "^7.12.9",
"@babel/preset-env": "^7.12.7",
"@kazupon/vue-i18n-loader": "^0.5.0",
"@vue/test-utils": "^1.1.1",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.1.0",
@ -61,6 +62,7 @@
"uglifyjs-webpack-plugin": "^2.2.0",
"url-loader": "^4.1.1",
"vue-eslint-parser": "^7.1.1",
"vue-i18n": "^8.22.2",
"vue-jest": "^3.0.7",
"vue-js-modal": "^2.0.0-rc.6",
"vue-loader": "^15.9.5",

1
web/.eslintrc.js Normal file
View File

@ -0,0 +1 @@
// i am here only to overwrite the drupal's .eslintrc.json who is extending with core/.eslintrc.json

View File

@ -1771,9 +1771,28 @@ article.card {
height: 610px; }
article.card.modal-card > .col {
flex-basis: 50%; }
article.card.modal-card section.col-right header {
article.card.modal-card section.col-right > *:not(nav.tools) {
position: relative;
padding: 0.5em;
box-sizing: border-box;
width: 100%; }
article.card.modal-card section.col-right header {
bottom: auto; }
article.card.modal-card section.col-right section.samples ul {
display: flex;
flex-flow: row wrap;
font-size: 0.882em;
font-weight: 300; }
article.card.modal-card section.col-right section.samples ul span.showroom {
font-weight: 500; }
article.card.modal-card section.col-right section.body p {
font-size: 0.882em;
font-weight: 300;
line-height: 1.35; }
article.card.modal-card section.col-right nav.tools {
opacity: 1; }
article.card.modal-card section.col-right nav.tools section.close span.btn.mdi-close {
cursor: pointer; }
#main-content > article.article div.cols {
display: grid;

File diff suppressed because one or more lines are too long

View File

@ -26,6 +26,11 @@ Vue.use(VModal)
import store from 'vuejs/store'
import router from 'vuejs/route'
// import VueI18n from 'vue-i18n'
// Vue.use(VueI18n)
// import * as Locales from 'assets/i18n/locales.json'
import i18n from 'vuejs/i18n'
import VUserBlock from 'vuejs/components/Block/UserBlock'
import VMainContent from 'vuejs/components/Content/MainContent'
import VSearchBlock from 'vuejs/components/Block/SearchBlock'
@ -43,9 +48,10 @@ import 'theme/assets/styles/main.scss'
_v_pagetitle_block, _v_search_block,
_v_main_content, _v_left_content
const _is_front = drupalSettings.path.isFront
console.log('drupalSettings', drupalSettings)
// let _I18n
// ___ _ _
// |_ _|_ _ (_) |_
// | || ' \| | _|
@ -70,6 +76,8 @@ import 'theme/assets/styles/main.scss'
function initVues () {
// only launch views if we are not in commerce pages
if (!checkNoVuePages()) {
initVi18n()
initVStore()
initVRouter()
initVSiteBrandingBlock()
initVPagetitleBlock()
@ -81,6 +89,23 @@ import 'theme/assets/styles/main.scss'
initVUserBlock()
}
function initVi18n () {
i18n.locale = drupalDecoupled.lang_code
console.log('i18n.messages', i18n.messages)
// const locales = {
// ...Locales
// }
// _I18n = new VueI18n({
// locale: drupalDecoupled.lang_code,
// locales
// })
// console.log('_I18n', _I18n)
}
function initVStore () {
store.dispatch('Showrooms/getItems')
}
function initVRouter () {
// we need this to update the title and body classes while using history nav
router.beforeEach((to, from, next) => {
@ -136,6 +161,7 @@ import 'theme/assets/styles/main.scss'
function initVSiteBrandingBlock () {
_v_sitebranding_block = new Vue({
store,
i18n,
router,
el: '#block-sitebranding',
methods: {
@ -165,6 +191,7 @@ import 'theme/assets/styles/main.scss'
// create the vue
_v_pagetitle_block = new Vue({
store,
i18n,
router,
el: $blk,
computed: {
@ -195,6 +222,7 @@ import 'theme/assets/styles/main.scss'
_v_user_block = new Vue({
store,
i18n,
// computed: {
// ...mapState({
// isloggedin: state => state.User.isloggedin
@ -223,6 +251,7 @@ import 'theme/assets/styles/main.scss'
_v_header_menu = new Vue({
store,
i18n,
router,
el: '#block-header',
methods: {
@ -246,6 +275,7 @@ import 'theme/assets/styles/main.scss'
const main_html = $main_content.innerHTML
_v_main_content = new Vue({
store,
i18n,
render: h => h(VMainContent, { props: { id: id, html: main_html, isfront: drupalSettings.path.isFront } })
}).$mount('#' + id)
}
@ -271,6 +301,7 @@ import 'theme/assets/styles/main.scss'
// in any case create the vue
_v_search_block = new Vue({
store,
i18n,
render: h => h(VSearchBlock, { props: { blockid: id, formhtml: formhtml } })
}).$mount('#' + id)
}
@ -280,6 +311,7 @@ import 'theme/assets/styles/main.scss'
// in any case create the vue
_v_left_content = new Vue({
store,
i18n,
render: h => h(VLeftContent, { props: { id: id } })
}).$mount('#' + id)
}

View File

@ -867,10 +867,41 @@ article.card{
flex-basis: 50%;
}
section.col-right{
header{
>*:not(nav.tools){
position: relative;
padding: 0.5em;
box-sizing: border-box;
width: 100%;
}
header{
bottom: auto;
}
section.samples{
ul{
display: flex;
flex-flow: row wrap;
font-size: 0.882em;
font-weight: 300;
// line-height: 1.35;
span.showroom{ font-weight: 500; }
}
}
section.body{
p{
font-size: 0.882em;
font-weight: 300;
line-height: 1.35;
}
}
nav.tools{
opacity: 1;
section.close{
span.btn.mdi-close{
cursor:pointer;
}
}
}
}
}
}

View File

@ -50,7 +50,7 @@
:items="item.images"
:index="lightbox_index"
srcName="src"
loop="true"
:loop="true"
@close="lightbox_index = null">
</CoolLightBox>
</article>

View File

@ -7,6 +7,12 @@
<span class="ref">{{ item.field_reference }}</span>
</header>
<nav class="tools">
<section class="tool close">
<span
class="btn mdi mdi-close"
@click.prevent="onCloseModalCard"
/>
</section>
<section class="tool flags">
<span class="btn mdi mdi-folder-outline"/>
<div class="tool-content">
@ -27,6 +33,18 @@
</div>
</section>
</nav>
<section class="samples">
<h3>{{ $t("Validation.Bundle") }}</h3>
<ul>
<li
v-for="sample in item.field_samples"
:key="sample.target_id"
>
<span class="showroom">{{ showrooms[sample.target_id].name }}</span>: {{ sample.location }}
</li>
</ul>
</section>
<section class="body" v-html="item.body.processed"/>
</section>
<section class="col col-left images" v-switcher>
<figure
@ -50,7 +68,7 @@
:items="item.images"
:index="lightbox_index"
srcName="src"
loop="true"
:loop="true"
@close="lightbox_index = null">
</CoolLightBox>
</article>
@ -73,9 +91,13 @@ export default {
},
computed: {
...mapState({
flagcolls: state => state.User.flagcolls
flagcolls: state => state.User.flagcolls,
showrooms: state => state.Showrooms.showrooms_by_tid
})
},
created () {
console.log('modale item', this.item)
},
methods: {
...mapActions({
flagUnflag: 'User/flagUnflag'
@ -105,6 +127,9 @@ export default {
this.loadingFlag = false;
})
}
},
onCloseModalCard (e) {
this.$modal.hideAll()
}
}
}

View File

@ -64,7 +64,7 @@
<CoolLightBox
:items="content.lightbox_items"
:index="lightbox_index"
loop
:loop="true"
@close="lightbox_index = null">
</CoolLightBox>
<div class="gallery-wrapper">

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,20 @@
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import * as en from './en.json'
import * as fr from './fr.json'
Vue.use(VueI18n)
const messages = {
en: {
...en.default
},
fr: {
...fr.default
}
}
export default new VueI18n({
locale: 'en',
messages
})

View File

@ -0,0 +1,8 @@
{
"en": {
"samples": "Samples"
},
"fr": {
"samples": "Échantillons"
}
}

View File

@ -8,7 +8,8 @@ export default {
// initial state
state: {
items: []
items: [],
showrooms_by_tid: {}
},
// getters
@ -18,6 +19,9 @@ export default {
mutations: {
setItems (state, items) {
state.items = state.items.concat(items)
items.forEach((item, i) => {
state.showrooms_by_tid[item.tid] = item
})
}
},