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}}
```
This commit is contained in:
Rish 2021-03-01 13:57:39 +05:30 committed by Rishabh Garg
parent 874ccaef53
commit 886f564dc4
2 changed files with 33 additions and 3 deletions

View File

@ -3,7 +3,7 @@
// //
// Block helper designed for looping through posts // Block helper designed for looping through posts
const _ = require('lodash'); 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 {Utils: hbsUtils, handlebars: {createFrame}} = hbs;
const ghostHelperUtils = require('@tryghost/helpers').utils; const ghostHelperUtils = require('@tryghost/helpers').utils;
@ -15,9 +15,16 @@ module.exports = function foreach(items, options) {
if (hbsUtils.isFunction(items)) { if (hbsUtils.isFunction(items)) {
items = items.call(this); 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 // 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 // Initial values set based on parameters sent through. If nothing sent, set to defaults
const {fn, inverse, hash, data, ids} = options; const {fn, inverse, hash, data, ids} = options;

View File

@ -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 = { const arrayHash = {
posts: [ posts: [
{title: 'first'}, {title: 'second'}, {title: 'third'}, {title: 'fourth'}, {title: 'fifth'} {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 arrayHash2 = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'};
const objectHash2 = { const objectHash2 = {
@ -386,6 +402,13 @@ describe('{{#foreach}} helper', function () {
shouldCompileToExpected(templateString, objectHash, expected); shouldCompileToExpected(templateString, objectHash, expected);
}); });
it('foreach with limit 3 and post with members visibility', function () {
const templateString = '<ul>{{#foreach posts limit="3"}}<li>{{title}}</li>{{else}}not this{{/foreach}}</ul>';
const expected = '<ul><li>first</li><li>second</li><li>third</li></ul>';
shouldCompileToExpected(templateString, arrayHashWithVis, expected);
shouldCompileToExpected(templateString, objectHashWithVis, expected);
});
it('foreach with from 2', function () { it('foreach with from 2', function () {
const templateString = '<ul>{{#foreach posts from="2"}}<li>{{title}}</li>{{else}}not this{{/foreach}}</ul>'; const templateString = '<ul>{{#foreach posts from="2"}}<li>{{title}}</li>{{else}}not this{{/foreach}}</ul>';
const expected = '<ul><li>second</li><li>third</li><li>fourth</li><li>fifth</li></ul>'; const expected = '<ul><li>second</li><li>third</li><li>fourth</li><li>fifth</li></ul>';