From 886f564dc4d11ea28169f056108665cbe9cb82e0 Mon Sep 17 00:00:00 2001 From: Rish Date: Mon, 1 Mar 2021 13:57:39 +0530 Subject: [PATCH] Updated default visibility in foreach for posts to all closes https://github.com/TryGhost/Team/issues/485 In order to loop over all posts, we currently need to pass a visibility="all" flag to a foreach as default for all items in current `visibility` helper is set to `public`. For a post, this behaviour is unintuitive, and inconsistent with the API. Instead, the default visibility should be "all" for the posts. The update allows themes to get all posts directly without passing in visibility - ``` {{#get "posts"}} {{#foreach posts}} //Loops over all posts, not just `public` {{/foreach}} {{/get}} ``` --- core/frontend/helpers/foreach.js | 13 ++++++++++--- test/unit/helpers/foreach_spec.js | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/core/frontend/helpers/foreach.js b/core/frontend/helpers/foreach.js index 7612a62ac6..c1111fdbac 100644 --- a/core/frontend/helpers/foreach.js +++ b/core/frontend/helpers/foreach.js @@ -3,7 +3,7 @@ // // Block helper designed for looping through posts const _ = require('lodash'); -const {logging, i18n, hbs} = require('../services/proxy'); +const {logging, i18n, hbs, checks} = require('../services/proxy'); const {Utils: hbsUtils, handlebars: {createFrame}} = hbs; const ghostHelperUtils = require('@tryghost/helpers').utils; @@ -15,9 +15,16 @@ module.exports = function foreach(items, options) { if (hbsUtils.isFunction(items)) { items = items.call(this); } - + let visibility = options.hash.visibility; + if (_.isArray(items) && items.length > 0 && checks.isPost(items[0])) { + visibility = visibility || 'all'; + } else if (_.isObject(items) && _.isArray(Object.values(items))) { + if (Object.values(items).length > 0 && checks.isPost(Object.values(items)[0])) { + visibility = visibility || 'all'; + } + } // Exclude items which should not be visible in the theme - items = ghostHelperUtils.visibility.filter(items, options.hash.visibility); + items = ghostHelperUtils.visibility.filter(items, visibility); // Initial values set based on parameters sent through. If nothing sent, set to defaults const {fn, inverse, hash, data, ids} = options; diff --git a/test/unit/helpers/foreach_spec.js b/test/unit/helpers/foreach_spec.js index fbd0cc81ee..14db57d101 100644 --- a/test/unit/helpers/foreach_spec.js +++ b/test/unit/helpers/foreach_spec.js @@ -260,12 +260,28 @@ describe('{{#foreach}} helper', function () { } }; + const objectHashWithVis = { + posts: { + first: {title: 'first', visibility: 'members', slug: 'first', html: ''}, + second: {title: 'second'}, + third: {title: 'third'}, + fourth: {title: 'fourth'}, + fifth: {title: 'fifth'} + } + }; + const arrayHash = { posts: [ {title: 'first'}, {title: 'second'}, {title: 'third'}, {title: 'fourth'}, {title: 'fifth'} ] }; + const arrayHashWithVis = { + posts: [ + {title: 'first', visibility: 'members', slug: 'first', html: ''}, {title: 'second'}, {title: 'third'}, {title: 'fourth'}, {title: 'fifth'} + ] + }; + const arrayHash2 = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'}; const objectHash2 = { @@ -386,6 +402,13 @@ describe('{{#foreach}} helper', function () { shouldCompileToExpected(templateString, objectHash, expected); }); + it('foreach with limit 3 and post with members visibility', function () { + const templateString = ''; + const expected = ''; + shouldCompileToExpected(templateString, arrayHashWithVis, expected); + shouldCompileToExpected(templateString, objectHashWithVis, expected); + }); + it('foreach with from 2', function () { const templateString = ''; const expected = '';