Browse Source

:recycle: tweaking endpoints to add galleries for single image blocks | tweaking frontend to accomodate new single image galleries

tags/0.9.0
TOJ 5 years ago
parent
commit
156dd1bf31

+ 3
- 37
plugins/cia-endpoints/includes/class.make-endpoint.php View File

@@ -62,30 +62,6 @@ class Make_Endpoint_For extends WP_REST_Controller {
62 62
         return new WP_REST_Response( $this->prepare_all_items_for_response($args), 200 );
63 63
     }
64 64
 
65
-    private function _getAttachments($item, $galleries) {
66
-        // Get media
67
-        $desiredSizes = ['thumbnail', 'medium', 'large', 'full'];
68
-        $all_image_ids_in_gallery = array();
69
-        $all_image_ids = array();
70
-        foreach ( $galleries as $gallery ) {
71
-            array_push( $all_image_ids_in_gallery, $gallery[attrs][ids] );
72
-        }
73
-        foreach ( $all_image_ids_in_gallery as $ids ) {
74
-            foreach ( $ids as $id ) {
75
-                array_push($all_image_ids, $id);
76
-            }
77
-        }
78
-        $attachment_map = array();
79
-        foreach ( $all_image_ids as $id ) {
80
-            $imageSizes = array();
81
-            foreach ( $desiredSizes as $size ) {
82
-                $imageSizes[$size] = wp_get_attachment_image_url( $id, $size );
83
-            }
84
-            // store size:url map under image id
85
-            $attachment_map[$id] = $imageSizes;
86
-        }
87
-        return $attachment_map;
88
-    }
89 65
     public function prepare_single_item_for_response( $args ) {
90 66
         $collection = array();
91 67
 
@@ -95,21 +71,14 @@ class Make_Endpoint_For extends WP_REST_Controller {
95 71
 
96 72
             // Get those Block!
97 73
             $filtered[blocks] = get_rearrange_blocks(
98
-                parse_blocks( $item->post_content )
74
+                parse_blocks($item->post_content)
99 75
             );
100 76
 
101
-            // Galleries From blocks
102
-            $media_ids = array();
103
-            foreach ( get_attached_media( '', $item->ID ) as $attached_media ):
104
-                array_push($media_ids, $attached_media->ID);
105
-            endforeach;
106
-
107 77
             $filtered[galleries] = get_ids_from_gallery_block(
108
-                parse_blocks( $item->post_content )
78
+                parse_blocks($item->post_content)
109 79
             );
110 80
 
111
-            // Find all image info
112
-            $filtered[attached] = $this->_getAttachments( $item, $filtered[galleries] );
81
+            $filtered[attached] = get_images_from_content($item->post_content);
113 82
 
114 83
             // For your hero URL
115 84
             $filtered[hero] = get_post_meta( $item->ID, 'hero_header', true );
@@ -129,9 +98,6 @@ class Make_Endpoint_For extends WP_REST_Controller {
129 98
         foreach( get_posts($args) as $item ) {
130 99
             $filtered = default_post_format( $item, true );
131 100
 
132
-            // Find all image info
133
-            $filtered[attached] = $this->_getAttachments( $item, $filtered[galleries] );
134
-
135 101
             // For your hero URL
136 102
             $filtered[hero] = get_post_meta( $item->ID, 'hero_header', true );
137 103
 

+ 26
- 1
plugins/cia-endpoints/includes/reformat-blocks.php View File

@@ -18,9 +18,34 @@
18 18
         $parsed_blocks = array();
19 19
         foreach ($blocks as $block) {
20 20
             if($block[blockName] === "core/gallery") {
21
-                array_push($parsed_blocks, $block);
21
+                array_push($parsed_blocks, $block[attrs]);
22
+            } elseif ($block[blockName] === "core/image") {
23
+                $ids = [];
24
+                $galleryFormat = [];
25
+                array_push($ids, $block[attrs][id]);
26
+                $galleryFormat[ids] = $ids;
27
+                $galleryFormat[columns] = 1;
28
+                $galleryFormat[linkTo] = 'none';
29
+                array_push($parsed_blocks, $galleryFormat);
22 30
             }
23 31
         }
24 32
         return $parsed_blocks;
25 33
     }
34
+    function get_images_from_content($content) {
35
+        $parse_images = array();
36
+
37
+        $dom = new DOMDocument();
38
+        @ $dom->loadHTML($content);
39
+        $images = $dom->getElementsByTagName('img');
40
+
41
+        foreach ($images as $image) {
42
+            if($image->getAttribute('data-id')) {
43
+                $parse_images[$image->getAttribute('data-id')] = $image->getAttribute('src');
44
+            } else {
45
+                $class_pieces = explode("-", $image->getAttribute('class'));
46
+                $parse_images[end($class_pieces)] = $image->getAttribute('src');
47
+            }
48
+        }
49
+        return $parse_images;
50
+    }
26 51
 ?>

+ 9
- 4
vue-theme/src/components/content-block/block.vue View File

@@ -10,8 +10,10 @@ figure.block.embed(v-if="block[0].blockName == 'core/embed'")
10 10
     .not-youtube(v-else)
11 11
         p not youtube: {{ block[0].attrs }}
12 12
 
13
-rblock(v-else-if="typeof block === 'object'" :block="block")
14
-        
13
+//- Block clicking on certain block elements
14
+//- so we can choose when to open the gallery
15
+rblock(v-else-if="typeof block === 'object'" :block="block" @click.prevent.stop="openGallery")
16
+
15 17
 .block.single(v-else)
16 18
     .single--content(v-html="block")
17 19
 </template>
@@ -27,12 +29,15 @@ export default {
27 29
     methods: {
28 30
         fixYoutubeUrl(url) {
29 31
             let videoUid = url.split('https://youtu.be/').filter(pieces => pieces.length > 0)[0]
30
-            
32
+
31 33
             if(!videoUid) {
32 34
                 videoUid = url.split('https://www.youtube.com/watch?v=').filter(pieces => pieces.length > 0)[0]
33 35
             }
34
-            
36
+
35 37
             return `https://www.youtube.com/embed/${videoUid}`
38
+        },
39
+        openGallery(e) {
40
+            this.$emit('open-gallery', e.target)
36 41
         }
37 42
     },
38 43
     data() {

+ 8
- 8
vue-theme/src/components/gallery.vue View File

@@ -2,27 +2,26 @@
2 2
 .gallery.active.f-col.center
3 3
     button(@click="hideGallery").hide hide gallery &#x25B2
4 4
     figure.f-col.center
5
-        img(v-if="Object.values(images).length > 0" :src="Object.values(images)[selected]['large']")
6
-        p active: {{ selected }}        
5
+        p {{images}}
6
+        img(:src="Object.values(images)[selected]")
7
+        p active: {{ selected }}
7 8
         .titledesc.t-left
8 9
             h2 Title goes here: create responsive designs that fit different screen sizes
9 10
             p Description goes here: London. Michaelmas term lately over, and the Lord Chancellor sitting in Lincoln's Inn Hall. Implacable November weather. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
10 11
 
11 12
     .controls.f-row
12 13
         button(v-if="selected > 0" @click="prev") &#x25C0prev
13
-        .f-grow 
14
+        .f-grow
14 15
         button(v-if="selected < Object.values(images).length - 1" @click="next") next &#x25B6
15 16
 </template>
16 17
 
17 18
 <script>
18
-import { mapGetters } from 'vuex'
19
-
20 19
 export default {
21 20
     props: {
22 21
         activeImageIndex: { type: Number, required: true, default: 0 },
23 22
         images: { type: Object, required: true }
24 23
     },
25
-    data() { 
24
+    data() {
26 25
         return {
27 26
             selected: 0
28 27
         }
@@ -71,6 +70,7 @@ export default {
71 70
 @import '../sss/variables.sss'
72 71
 
73 72
 .gallery
73
+    overflow: hidden
74 74
     .wrap
75 75
         /* width: 60vw */
76 76
     &.active
@@ -103,8 +103,8 @@ export default {
103 103
                 max-width: 80vw
104 104
                 bottom: 1vh
105 105
                 background-color: rgba(255, 255, 255, 0.6)
106
-                padding: 4px 
107
-                text-align: left 
106
+                padding: 4px
107
+                text-align: left
108 108
                 h2, p
109 109
                     color: $cia_black
110 110
         .controls

+ 27
- 19
vue-theme/src/pages/single.vue View File

@@ -1,5 +1,7 @@
1 1
 <template lang="pug">
2 2
 .page--single.f-row.between
3
+    gallery(v-if="activeGalleryIndex >= 0" :activeImageIndex="activeImageIndex" :images="imagesInGallery" @close="closeGallery")
4
+
3 5
     article(v-if="!post")
4 6
         header
5 7
             p loading...
@@ -14,7 +16,7 @@
14 16
                 p start: {{ dateFrom(post.start) }}
15 17
                 p end: {{ dateFrom(post.end) }}
16 18
 
17
-        block.post-single.block-wrapper(v-for="(block, index) in post.blocks" :block="block" :key="`block-${index}`")
19
+        block.post-single.block-wrapper(v-for="(block, index) in post.blocks" :block="block" @open-gallery="openGallery" :key="`block-${index}`")
18 20
 
19 21
         credits(v-if="type === 'episodes'" :post="post")
20 22
 
@@ -72,7 +74,8 @@ export default {
72 74
         },
73 75
 
74 76
         idsForGallery() {
75
-            return this.post.galleries[this.activeGalleryIndex].attrs.ids
77
+            if(!this.post || this.activeGalleryIndex < 0) return []
78
+            return this.post.galleries[this.activeGalleryIndex].ids
76 79
         },
77 80
         /**
78 81
          * We need a convenient way to get all the images
@@ -82,12 +85,9 @@ export default {
82 85
          */
83 86
         imagesInGallery() {
84 87
             if(!this.activeGalleryIndex < 0) return {}
85
-            // Create a map of images by their ID
86
-            // {
87
-            //     imageId: { 'thumbnail': url, 'large': url }
88
-            // }
88
+
89 89
             return this.idsForGallery.reduce((imageMap, id) => {
90
-                imageMap[id] = this.post.attached[id]
90
+                imageMap[id] = this.post.attached[parseInt(id)]
91 91
                 return imageMap
92 92
             }, {})
93 93
         },
@@ -103,23 +103,29 @@ export default {
103 103
         }
104 104
     },
105 105
     methods: {
106
-        getImageIdsForGallery(galleryIndex) {
107
-            console.log(galleryIndex)
108
-            return galleryIndex >= 0 ? this.post.galleries[galleryIndex].attrs.ids : []
109
-        },
110 106
         /**
111 107
          * We set the active gallery to the index.
112 108
          * Everything kicks off when activeGallery
113 109
          * is set. We also need to set the activeImageID
114 110
          * to the image clicked
115
-         * @param {number} galleryIndex
116
-         * @param {string} imageID
111
+         * @param {string} imageInfo
117 112
          */
118
-        openGallery(galleryIndex, imageID) {
119
-            this.activeGalleryIndex = galleryIndex
120
-            this.activeImageID = imageID ? imageID : 0
113
+        openGallery(imageInfo) {
114
+            const byIndex = this.post.galleries.reduce((byIndex, gallery, index) => {
115
+                byIndex[index] = gallery.ids
116
+                return byIndex
117
+            }, {})
118
+            let matchingIndex = 0
119
+            Object.keys(byIndex).forEach(galleryIndex => {
120
+                if(byIndex[galleryIndex].includes(parseInt(imageInfo.dataset.id))) matchingIndex = galleryIndex
121
+            })
122
+            this.activeGalleryIndex = matchingIndex
123
+            this.activeImageID = imageInfo.dataset.id ? parseInt(imageInfo.dataset.id) : parseInt(imageInfo.className.split('-').pop())
124
+        },
125
+        closeGallery() {
126
+            this.activeGalleryIndex = -1
127
+            this.activeImageID = -1
121 128
         },
122
-
123 129
         /**
124 130
          * Everytime the posts object changes
125 131
          * we use this to set a new HERO
@@ -155,11 +161,14 @@ export default {
155 161
             if(!this[`all${type}Loaded`] && allPostsOfType.length < 1) {
156 162
                 const res = await this.$store.dispatch(`getAll${type}`)
157 163
                 allPostsOfType = res
158
-                console.log(`reloaded ${type}...`)
164
+                // console.log(`reloaded ${type}...`)
159 165
             }
166
+
167
+            if(Object.values(allPostsOfType).length < 1) return
160 168
             const singlePostData = Object.values(allPostsOfType).filter(post => post.slug == this.$route.params.slug)[0]
161 169
 
162 170
             if(!singlePostData) return
171
+
163 172
             await this.$store.dispatch(`getSingle${dePluralize(type)}`, singlePostData.id)
164 173
         }
165 174
     },
@@ -168,7 +177,6 @@ export default {
168 177
             this.checkAndSetHero(newVal)
169 178
         },
170 179
         $route(newVal, oldVal) {
171
-            console.log('route changed...')
172 180
             this.loadPostData()
173 181
         }
174 182
     },

+ 8
- 1
vue-theme/src/store/index.js View File

@@ -14,7 +14,7 @@ import exhibitions from './modules/exhibition'
14 14
 
15 15
 const debug = process.env.NODE_ENV !== 'production'
16 16
 
17
-// Vue.config.devtools = true 
17
+// Vue.config.devtools = true
18 18
 
19 19
 // Current page state
20 20
 const state = {
@@ -24,6 +24,7 @@ const state = {
24 24
     text: 'sample hero text',
25 25
     playbutton: true
26 26
   },
27
+  currentGallery: null,
27 28
   view: 'list'
28 29
 }
29 30
 
@@ -35,6 +36,12 @@ const mutations = {
35 36
       state.hero.text = hero
36 37
     }
37 38
   },
39
+  SET_GALLERY(state, idList) {
40
+    state.gallery = idList
41
+  },
42
+  CLEAR_GALLERY(state) {
43
+    state.gallery = null
44
+  }
38 45
 }
39 46
 
40 47
 const store = new Vuex.Store({

Loading…
Cancel
Save