Bachir Soussi Chiadmi
417b084216
remain to automaticly export jsons and updated json files with webpack and to understand how to access nested translations
388 lines
12 KiB
Vue
388 lines
12 KiB
Vue
<template>
|
|
<div class="loading" v-if="!content || loading">
|
|
<span>Loading ...</span>
|
|
</div>
|
|
<article class="article" v-else>
|
|
<nav class="prevnext top">
|
|
<ul>
|
|
<li>
|
|
<a
|
|
@click.prevent="onPrev"
|
|
href="#"
|
|
v-if="prevnext.prev"
|
|
v-html="prevnext.prev.title"
|
|
/>
|
|
</li>
|
|
<li>
|
|
<a
|
|
@click.prevent="onNext"
|
|
href="#"
|
|
v-if="prevnext.next"
|
|
v-html="prevnext.next.title"
|
|
/>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
<div class="cols">
|
|
<div class="col col-left">
|
|
<section v-if="content.image_accroche" class="accroche">
|
|
<figure>
|
|
<img
|
|
:src="content.image_accroche.src"
|
|
:alt="content.image_accroche.alt"
|
|
:title="content.image_accroche.title"
|
|
/>
|
|
</figure>
|
|
</section>
|
|
<section class="taxonomy">
|
|
<div class="thesaurus">
|
|
<ul>
|
|
<li
|
|
v-for="term in content.field_thesaurus" v-bind:key="term.id"
|
|
>{{ term.name }}</li>
|
|
</ul>
|
|
</div>
|
|
<div class="tags">
|
|
<ul>
|
|
<li
|
|
v-for="term in content.field_tags" v-bind:key="term.id"
|
|
>{{ term.name }}</li>
|
|
</ul>
|
|
</div>
|
|
</section>
|
|
<section v-if="content.field_showroom" class="showroom">
|
|
<h2>{{ content.field_showroom.name }}</h2>
|
|
<a class="mail" :href="'mail:'+content.field_showroom.field_public_email">
|
|
{{ content.field_showroom.field_public_email }}</a>
|
|
<br/>
|
|
<a class="phone" :href="'tel:' + content.field_showroom.field_public_phone">
|
|
{{ content.field_showroom.field_public_phone }}</a>
|
|
</section>
|
|
</div> <!-- //col-left -->
|
|
<div class="col col-right">
|
|
<section class="body" v-html="content.body"></section>
|
|
<CoolLightBox
|
|
:items="content.lightbox_items"
|
|
:index="lightbox_index"
|
|
:loop="true"
|
|
@close="lightbox_index = null">
|
|
</CoolLightBox>
|
|
<div class="gallery-wrapper">
|
|
<div
|
|
class="image"
|
|
v-for="(image, imageIndex) in content.lightbox_items"
|
|
:key="imageIndex"
|
|
@click="setLightboxIndex(imageIndex)"
|
|
:style="{ backgroundImage: 'url(' + image.thumb + ')' }"
|
|
></div>
|
|
</div>
|
|
<aside class="linked-materials">
|
|
<h3 class="field__label">Linked Materials</h3>
|
|
<div class="card-list">
|
|
<ul class="">
|
|
<li v-for="node in content.field_linked_materials" v-bind:key="node.id">
|
|
<Card :item="node" />
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</aside>
|
|
</div> <!-- // col-right -->
|
|
</div> <!-- // cols -->
|
|
<nav class="prevnext bottom">
|
|
<ul>
|
|
<li>
|
|
<a
|
|
@click.prevent="onPrev"
|
|
href="#"
|
|
v-if="prevnext.prev"
|
|
v-html="prevnext.prev.title"
|
|
/>
|
|
</li>
|
|
<li>
|
|
<a
|
|
@click.prevent="onNext"
|
|
href="#"
|
|
v-if="prevnext.next"
|
|
v-html="prevnext.next.title"
|
|
/>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
</article>
|
|
</template>
|
|
|
|
<script>
|
|
import router from 'vuejs/route'
|
|
import store from 'vuejs/store'
|
|
import { JSONAPI } from 'vuejs/api/json-axios'
|
|
import qs from 'querystring-es3'
|
|
import Card from 'vuejs/components/Content/Card'
|
|
|
|
import { mapState, mapActions } from 'vuex'
|
|
|
|
export default {
|
|
name: "Article",
|
|
router,
|
|
store,
|
|
props: ['item'],
|
|
data(){
|
|
return {
|
|
index:-1,
|
|
prevnext:{},
|
|
uuid:null,
|
|
content:null,
|
|
loading:true,
|
|
lightbox_index:null,
|
|
}
|
|
},
|
|
computed: {
|
|
...mapState({
|
|
items: state => state.Blabla.items
|
|
})
|
|
},
|
|
created(){
|
|
this.getArticle()
|
|
},
|
|
methods: {
|
|
...mapActions({
|
|
getItems: 'Blabla/getItems',
|
|
getItemIndex: 'Blabla/getItemIndex',
|
|
getPrevNextItems: 'Blabla/getPrevNextItems'
|
|
}),
|
|
getArticle(){
|
|
console.log(this.$route);
|
|
// get the article uuid
|
|
if(this.$route.query.uuid){
|
|
// we come from internal link with vuejs
|
|
// directly record uuid
|
|
this.uuid = this.$route.query.uuid
|
|
}else if(drupalDecoupled.entity_type == 'node' && drupalDecoupled.entity_bundle == 'article'){
|
|
// we landed in an internal page
|
|
// get the uuid from drupalDeclouped, provided by materio_decoupled.module
|
|
this.uuid = drupalDecoupled.entity_uuid
|
|
}
|
|
|
|
if(this.uuid){
|
|
this.loadArticle()
|
|
// get the prev next items
|
|
if(!this.items.length){
|
|
// if items list not yet loaded preload them
|
|
this.getItems().then(() => {
|
|
// then get the index
|
|
this.getIndex()
|
|
})
|
|
}else{
|
|
// or directly get the index
|
|
this.getIndex()
|
|
}
|
|
}else{
|
|
// if for any reason we dont have the uuid
|
|
// redirect to home
|
|
this.$route.replace('home')
|
|
}
|
|
},
|
|
getIndex(){
|
|
console.log("Article getIndex");
|
|
this.getItemIndex(this.uuid).then((index) => {
|
|
this.index = index
|
|
// console.log('article index', index, this);
|
|
this.getPrevNextItems(index).then((pn) => {
|
|
this.prevnext = pn
|
|
})
|
|
})
|
|
},
|
|
loadArticle(){
|
|
console.log('loadArticle', this.uuid)
|
|
this.loading = true;
|
|
let params = {
|
|
include:'field_linked_materials.images,field_showroom,field_tags,field_thesaurus,field_visuel,uid'
|
|
}
|
|
let q = qs.stringify(params)
|
|
JSONAPI.get(`node/article/${this.uuid}?${q}`)
|
|
.then(({ data }) => {
|
|
console.log('loadArticle data', data)
|
|
this.parseData(data)
|
|
})
|
|
.catch(( error ) => {
|
|
console.warn('Issue with loadArticle', error)
|
|
Promise.reject(error)
|
|
})
|
|
},
|
|
parseData(data){
|
|
let attrs = data.data.attributes
|
|
let relations = data.data.relationships
|
|
console.log('relations', relations);
|
|
let inc = data.included
|
|
console.log('included', inc);
|
|
|
|
this.content = {
|
|
title:attrs.title,
|
|
body: attrs.body.value
|
|
}
|
|
|
|
// build lightbox array
|
|
// will be filled by videos and field_visuel
|
|
this.content.lightbox_items = [];
|
|
|
|
// parse embeded videos pushing it in lightbox
|
|
for(let key in attrs.field_video){
|
|
let videolink = attrs.field_video[key]
|
|
// console.log('videolink', videolink);
|
|
let provider_regex = /https:\/\/(www\.)?(?<provider>youtube|vimeo)\.com\/.+/;
|
|
let match = provider_regex.exec(videolink)
|
|
// console.log('provider', match.groups.provider);
|
|
let video_id = null;
|
|
let video_thumb = null;
|
|
switch (match.groups.provider) {
|
|
case 'vimeo':
|
|
let vimeo_regex = /https:\/\/vimeo\.com\/(?<id>\d+)/;
|
|
video_id = vimeo_regex.exec(videolink).groups.id || null;
|
|
// TODO: get the vimeo thumb https://coderwall.com/p/fdrdmg/get-a-thumbnail-from-a-vimeo-video
|
|
video_thumb = "http://blogpeda.ac-poitiers.fr/ent-lyc/files/2015/06/Vimeo_icon_block.png"
|
|
break;
|
|
case 'youtube':
|
|
let youtube_regex = /https:\/\/(www\.)?youtube\.com\/watch\?v=(?<id>.+)/;
|
|
video_id = youtube_regex.exec(videolink).groups.id || null;
|
|
video_thumb = "http://img.youtube.com/vi/"+video_id+"/0.jpg"
|
|
break;
|
|
}
|
|
// console.log('video_id', video_id);
|
|
|
|
this.content.lightbox_items.push({
|
|
src: videolink,
|
|
title: "",
|
|
description: "",
|
|
thumb: video_thumb
|
|
});
|
|
// this.content.videos.push({
|
|
// provider: match.groups.provider,
|
|
// id: video_id,
|
|
// href: videolink
|
|
// });
|
|
}
|
|
|
|
// parse all relationships
|
|
for (let key in relations) {
|
|
// skip loop if the property is from prototype
|
|
if (!relations.hasOwnProperty(key)) continue;
|
|
|
|
let relation_obj = relations[key]
|
|
console.log("relation", key, relation_obj);
|
|
// console.log('typeof relation_obj.data', typeof relation_obj.data);
|
|
if(!relation_obj.data) continue;
|
|
|
|
// showroom is unique field so no array in data
|
|
// we parse it here
|
|
switch (key) {
|
|
case 'field_showroom':
|
|
let included = inc.find((i) => { return i.id == relation_obj.data.id })
|
|
// console.log('included',included);
|
|
this.content[key] = included.attributes;
|
|
break
|
|
}
|
|
|
|
// skip relation_obj if data is not array
|
|
if(!Array.isArray(relation_obj.data)) continue
|
|
// create empty field array
|
|
this.content[key] = []
|
|
// parse relationship values using included
|
|
let field = {}
|
|
// loop through all relation items
|
|
relation_obj.data.forEach((e) => {
|
|
// get the included values for each item using id
|
|
let included = inc.find((i) => { return i.id == e.id })
|
|
// if we not found an included item skip the item
|
|
if(typeof included != 'undefined'){
|
|
// fill the item values
|
|
switch (key) {
|
|
case 'field_visuel':
|
|
// build the field object (not used for now)
|
|
field = e.meta
|
|
field.id = e.id
|
|
field.src = included.attributes.uri.url
|
|
field.thumb = included.links.article_card_medium.href
|
|
break;
|
|
case 'field_linked_materials':
|
|
field = included.attributes
|
|
field.id = field.uuid = included.id
|
|
// get the linked material included images
|
|
field.images = [];
|
|
included.relationships.images.data.forEach((img) => {
|
|
// console.log('href', img.meta.imageDerivatives.links.card_medium.href);
|
|
if(img.meta.imageDerivatives){
|
|
field.images.push({
|
|
title:img.meta.title,
|
|
src: img.meta.imageDerivatives.links.hd.href,
|
|
img_styles: {
|
|
card_medium: img.meta.imageDerivatives.links.card_medium.href,
|
|
card_full: img.meta.imageDerivatives.links.card_full.href
|
|
}
|
|
})
|
|
}
|
|
})
|
|
break;
|
|
case 'field_thesaurus':
|
|
case 'field_tags':
|
|
field = included.attributes
|
|
field.id = included.id
|
|
break;
|
|
default:
|
|
}
|
|
this.content[key].push(field)
|
|
}
|
|
})
|
|
|
|
}
|
|
// extract first visuel as accroche
|
|
this.content.image_accroche = this.content.field_visuel.shift()
|
|
|
|
// fill the lightbox
|
|
for(let visuel of this.content.field_visuel){
|
|
this.content.lightbox_items.push(visuel);
|
|
}
|
|
console.log('this.content.lightbox_items', this.content.lightbox_items);
|
|
|
|
// update main page title
|
|
this.$store.commit('Common/setPagetitle', this.content.title)
|
|
|
|
this.loading = false;
|
|
console.log('article.content',this.content);
|
|
|
|
},
|
|
onNext(){
|
|
// console.log('clicked on next', this.prevnext.next);
|
|
let alias = this.prevnext.next.view_node.replace(/^.?\/blabla\//g, '')
|
|
this.$router.push({
|
|
name:`article`,
|
|
params: { alias:alias },
|
|
query: { uuid: this.prevnext.next.uuid }
|
|
})
|
|
},
|
|
onPrev(){
|
|
// console.log('clicked on prev', this.prevnext.next);
|
|
let alias = this.prevnext.prev.view_node.replace(/^.?\/blabla\//g, '')
|
|
this.$router.push({
|
|
name:`article`,
|
|
params: { alias:alias },
|
|
query: { uuid: this.prevnext.prev.uuid }
|
|
})
|
|
},
|
|
setLightboxIndex(index) {
|
|
this.lightbox_index = index
|
|
}
|
|
},
|
|
components: {
|
|
Card
|
|
},
|
|
watch: {
|
|
'$route' (to, from) {
|
|
console.log('route change')
|
|
this.getArticle()
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
</style>
|