Search code examples
node.jsmongodbgallerycloudinarykeystonejs

Issue displaying gallery images with description in Keystone.js


I am new to Keystone.js and Mongodb/nodejs development but I already love it.

I am trying to change the default gallery behavior in Keystone to add a name and a description to each of the images within a gallery since "Types.CloudinaryImages" doesn't seem to allow it. As found on Image gallery with caption using CloudinaryImage on keystonejs I have added a new "Image" model and modified the route for my home page (where the galleries should be displayed).

When checking the console log, the query does retrieve the galleries and populates the link to the images but there is something wrong with my code to display them.

Gallery Model

var keystone = require('keystone');                                                                                                                   
var Types = keystone.Field.Types;                                                                                                                     

/**                                                                                                                                                   
 * Gallery Model                                                                                                                                      
 * =============                                                                                                                                      
 */                                                                                                                                                   

var Gallery = new keystone.List('Gallery', {                                                                                                          
    map: { name: 'name' },                                                                                                                        
    autokey: { from: 'name', path: 'key', unique: true },                                                                                         
});                                                                                                                                                   

Gallery.add({                                                                                                                                         
    name: { type: String, required: true },                                                                                                       
    published: {type: Types.Select, options: 'Yes, No', default: 'No',    index: true, emptyOption: false},                                          
    publishedDate: { type: Date, index: true, dependsOn: {published:  'Yes'} },                                                                    
    heroImage: { type: Types.Relationship, ref:'Image' },                                                                                         
    images: { type: Types.Relationship, ref: 'Image', many: true },                                                                               
});                                                                                                                                                   


Gallery.track = true;                                                                                                                                 
Gallery.defaultColumns = 'title, published|20%, publishedDate|20%';                                                                                   
Gallery.register();      

Image Model

var keystone = require('keystone');                                                                                                                   
var Types = keystone.Field.Types;                                                                                                                     


/**                                                                                                                                                   
 * Image Model                                                                                                                                        
 * =============                                                                                                                                      
 */                                                                                                                                                   

var Image = new keystone.List('Image', {                                                                                                              
map: { name: 'name' },                                                                                                                            
autokey: { from: 'name', path: 'key', unique: true },                                                                                             
});                                                                                                                                                   

Image.add({                                                                                                                                           
name: { type: String, required: true },                                                                                                           
publishedDate: { type: Date, default: Date.now },                                                                                                 
image: { type: Types.CloudinaryImage, autoCleanup: true, required: true, initial: false },                             
description: { type: Types.Textarea, height: 150 },                                                                                               
});                                                                                                                                                   

Image.relationship({ ref: 'Gallery', path: 'heroImage' });                                                                                            
Image.relationship({ ref: 'Gallery', path: 'images' });                                                                                               

Image.register();

Route: index.js

var keystone = require('keystone'),                                                                                                                   
Gallery = keystone.list('Gallery'),                                                                                                               
Image = keystone.list('Image');                                                                                                                   

exports = module.exports = function (req, res) {                                                                                                      

    var view = new keystone.View(req, res);                                                                                                       
    var locals = res.locals;                                                                                                                      

    // locals.section is used to set the currently selected                                                                                       
    // item in the header navigation.                                                                                                             
    locals.section = 'home';                                                                                                                      
    locals.galleries = [];                                                                                                                        

    //Loading the galleries                                                                                                                       
    view.on('init', function(next){                                                                                                               

        var q = Gallery.model.find()                                                                                                              
           .populate('heroImage images')                                                                                                          
           .sort('sortOrder');                                                                                                                    

           q.exec(function(err, results) {                                                                                                        
               console.log(results);                                                                                                              
               locals.galleries = results;                                                                                                        
               next(err);                                                                                                                         
           });                                                                                                                                    
    });                                                                                                                                           


    // Render the view                                                                                                                            
    view.render('index');                                                                                                                         
};

View template: index.jade

//Portfolio section                                                                                                                               
section.grid#portfolio                                                                                                                            
        if galleries.length                                                                                                                       
                each gallery in galleries                                                                                                         
                               if gallery.exists                                                                                                  
                                  figure.effect-portfolio.wow.fadeInDown(data-wow-duration="1500ms")                                              
                                         img(src=gallery._.heroImage.limit(680,680))                                                              

                                         each image in gallery.images                                                                             
                                          figcaption                                                                                              
                                           a(href=image.limit(1024,768), title=gallery.name, data-lightbox-gallery="gallery1", data-lightbox-hidpi=image.limit(300,300))                                                                                                                               
                                else                                                                                                              
                                  h4.text-muted There are no images to display                                                                    

        else                                                                                                                                      
                h4.text-muted There are no image galleries yet.

Thanks a lot in advance for your help!


Solution

  • After trying different options, I have found a working solution. It may not be the best one, so if anyone as any additional remarks to make I would be grateful.

    Working solution: I have only modified the jade template to change the image source url.

    //Portfolio section                                                                                                                               
    section.grid#portfolio                                                                                                                            
            if galleries.length                                                                                                                       
                    each gallery in galleries                                                                                                         
    
                                      figure.effect-portfolio.wow.fadeInDown(data-wow-duration="1500ms")                                              
                                             img(src="#{gallery.heroImage.image.secure_url}")                                                         
    
                                             each image in gallery.images                                                                             
                                              figcaption                                                                                              
                                               a(href="#{image.image.url}", title=gallery.name, data-lightbox-gallery=gallery.name, data-lightbox-hidpi="#{image.image.url}")                                                                                                                              
    
            else                                                                                                                                      
                    h4.text-muted There are no image galleries yet.
    

    Please note that leaving the "if gallery.exists" statement doesn't work. I can't figure out why...