<commit_before>// # Ghost Head Helper
// Usage: `{{ghost_head}}`
//
// Outputs scripts and other assets at the top of a Ghost theme
const {metaData, escapeExpression, SafeString, logging, settingsCache, config, blogIcon, urlUtils} = require('../services/proxy');
const _ = require('lodash');
const debug = require('ghost-ignition').debug('ghost_head');
const templateStyles = require('./tpl/styles');

const getMetaData = metaData.get;

function writeMetaTag(property, content, type) {
    type = type || property.substring(0, 7) === 'twitter' ? 'name' : 'property';
    return '<meta ' + type + '="' + property + '" content="' + content + '" />';
}

function finaliseStructuredData(meta) {
    const head = [];

    _.each(meta.structuredData, function (content, property) {
        if (property === 'article:tag') {
            _.each(meta.keywords, function (keyword) {
                if (keyword !== '') {
                    keyword = escapeExpression(keyword);
                    head.push(writeMetaTag(property,
                        escapeExpression(keyword)));
                }
            });
            head.push('');
        } else if (content !== null && content !== undefined) {
            head.push(writeMetaTag(property,
                escapeExpression(content)));
        }
    });

    return head;
}

function getMembersHelper() {
    const stripeDirectSecretKey = settingsCache.get('stripe_secret_key');
    const stripeDirectPublishableKey = settingsCache.get('stripe_publishable_key');
    const stripeConnectAccountId = settingsCache.get('stripe_connect_account_id');

    let membersHelper = `<script defer src="https://unpkg.com/@tryghost/portal@~0.15.0/umd/portal.min.js" data-ghost="${urlUtils.getSiteUrl()}"></script>`;
    membersHelper += (`<style> ${templateStyles}</style>`);
    if ((!!stripeDirectSecretKey && !!stripeDirectPublishableKey) || !!stripeConnectAccountId) {
        membersHelper += '<script async src="https://js.stripe.com/v3/"></script>';
    }
    return membersHelper;
}

/**
 * **NOTE**
 * Express adds `_locals`, see https://github.com/expressjs/express/blob/4.15.4/lib/response.js#L962.
 * But `options.data.root.context` is available next to `root._locals.context`, because
 * Express creates a `renderOptions` object, see https://github.com/expressjs/express/blob/4.15.4/lib/application.js#L554
 * and merges all locals to the root of the object. Very confusing, because the data is available in different layers.
 *
 * Express forwards the data like this to the hbs engine:
 * {
 *   post: {},             - res.render('view', databaseResponse)<commit_msg>Bumped portal to 1.0.0-rc<commit_after>// # Ghost Head Helper
// Usage: `{{ghost_head}}`
//
// Outputs scripts and other assets at the top of a Ghost theme
const {metaData, escapeExpression, SafeString, logging, settingsCache, config, blogIcon, urlUtils} = require('../services/proxy');
const _ = require('lodash');
const debug = require('ghost-ignition').debug('ghost_head');
const templateStyles = require('./tpl/styles');

const getMetaData = metaData.get;

function writeMetaTag(property, content, type) {
    type = type || property.substring(0, 7) === 'twitter' ? 'name' : 'property';
    return '<meta ' + type + '="' + property + '" content="' + content + '" />';
}

function finaliseStructuredData(meta) {
    const head = [];

    _.each(meta.structuredData, function (content, property) {
        if (property === 'article:tag') {
            _.each(meta.keywords, function (keyword) {
                if (keyword !== '') {
                    keyword = escapeExpression(keyword);
                    head.push(writeMetaTag(property,
                        escapeExpression(keyword)));
                }
            });
            head.push('');
        } else if (content !== null && content !== undefined) {
            head.push(writeMetaTag(property,
                escapeExpression(content)));
        }
    });

    return head;
}

function getMembersHelper() {
    const stripeDirectSecretKey = settingsCache.get('stripe_secret_key');
    const stripeDirectPublishableKey = settingsCache.get('stripe_publishable_key');
    const stripeConnectAccountId = settingsCache.get('stripe_connect_account_id');

    let membersHelper = `<script defer src="https://unpkg.com/@tryghost/portal@~1.0.0-rc/umd/portal.min.js" data-ghost="${urlUtils.getSiteUrl()}"></script>`;
    membersHelper += (`<style> ${templateStyles}</style>`);
    if ((!!stripeDirectSecretKey && !!stripeDirectPublishableKey) || !!stripeConnectAccountId) {
        membersHelper += '<script async src="https://js.stripe.com/v3/"></script>';
    }
    return membersHelper;
}

/**
 * **NOTE**
 * Express adds `_locals`, see https://github.com/expressjs/express/blob/4.15.4/lib/response.js#L962.
 * But `options.data.root.context` is available next to `root._locals.context`, because
 * Express creates a `renderOptions` object, see https://github.com/expressjs/express/blob/4.15.4/lib/application.js#L554
 * and merges all locals to the root of the object. Very confusing, because the data is available in different layers.
 *
 * Express forwards the data like this to the hbs engine:
 * {
 *   post: {},             - res.render('view', databaseResponse)
{'fraction_non_alphanumeric': 0.1517687333586915, 'fraction_numerical': 0.008368200836820083, 'mean_word_length': 3.28257328990228, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4607560', 'n_tokens_mistral': 1539, 'n_tokens_neox': 1489, 'n_words': 344}