<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, labs} = require('../services/proxy');
const _ = require('lodash');
const debug = require('ghost-ignition').debug('ghost_head');

const getMetaData = metaData.get;
const getAssetUrl = metaData.getAssetUrl;

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

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

    _.each(metaData.structuredData, function (content, property) {
        if (property === 'article:tag') {
            _.each(metaData.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 stripePaymentProcessor = settingsCache.get('members_subscription_settings').paymentProcessors.find(
        paymentProcessor => paymentProcessor.adapter === 'stripe'
    );
    const stripeSecretToken = stripePaymentProcessor.config.secret_token;
    const stripePublicToken = stripePaymentProcessor.config.public_token;

    const stripeConnectIntegration = settingsCache.get('stripe_connect_integration');

    let membersHelper = `<script defer src="${getAssetUrl('public/members.js', true)}"></script>`;
    if (config.get('enableDeveloperExperiments')) {
        membersHelper = `<script defer src="https://unpkg.com/@tryghost/members-js@latest/umd/members.min.js"></script>`;
    }
    if ((!!stripeSecretToken && !!stripePublicToken) || !!stripeConnectIntegration.account_id) {
        membersHelper += '<script 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)
 *   context: ['post'],    - from res.locals
 *   safeVersion: '1.x',   - from res.locals
 *   _locals: {
 *     context: ['post'],
 *     safeVersion: '1.x'<commit_msg>Added new meta tag for site url behind dev flag (#11906)<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, labs, urlUtils} = require('../services/proxy');
const _ = require('lodash');
const debug = require('ghost-ignition').debug('ghost_head');

const getMetaData = metaData.get;
const getAssetUrl = metaData.getAssetUrl;

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

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

    _.each(metaData.structuredData, function (content, property) {
        if (property === 'article:tag') {
            _.each(metaData.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 stripePaymentProcessor = settingsCache.get('members_subscription_settings').paymentProcessors.find(
        paymentProcessor => paymentProcessor.adapter === 'stripe'
    );
    const stripeSecretToken = stripePaymentProcessor.config.secret_token;
    const stripePublicToken = stripePaymentProcessor.config.public_token;

    const stripeConnectIntegration = settingsCache.get('stripe_connect_integration');

    let membersHelper = `<script defer src="${getAssetUrl('public/members.js', true)}"></script>`;
    if (config.get('enableDeveloperExperiments')) {
        const siteUrl = urlUtils.getSiteUrl().replace(/\/$/, '');
        membersHelper = `<meta name="ghost:site" content='${siteUrl}' />`;
        membersHelper += `<script defer src="https://unpkg.com/@tryghost/members-js@latest/umd/members.min.js"></script>`;
    }
    if ((!!stripeSecretToken && !!stripePublicToken) || !!stripeConnectIntegration.account_id) {
        membersHelper += '<script 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)
 *   context: ['post'],    - from res.locals
 *   safeVersion: '1.x',   - from res.locals
 *   _locals: {
 *     context: ['post'],
 *     safeVersion: '1.x'
{'fraction_non_alphanumeric': 0.1477436968042396, 'fraction_numerical': 0.006905411915850329, 'mean_word_length': 3.2540983606557377, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 20, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4720799', 'n_tokens_mistral': 1817, 'n_tokens_neox': 1737, 'n_words': 401}