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!
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...