blog-186/themes/suka/includes/helpers/tags.js

136 lines
4.5 KiB
JavaScript
Executable File

'use strict';
const urlFn = require('url');
const moment = require('moment');
const { escapeHTML, htmlTag, stripHTML } = require('hexo-util');
module.exports = function (hexo) {
const { helper } = hexo.extend;
helper.register('_meta_generator', () => `<meta name="generator" content="Hexo ${hexo.version}">`);
helper.register('css_async', (url) => `<link rel="preload" href="${url}" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link rel="stylesheet" href="${url}"></noscript>`);
helper.register('_open_graph', function (options = {}) {
function meta(name, content, escape) {
if (escape !== false && typeof content === 'string') {
content = escapeHTML(content);
}
return htmlTag('meta', { name, content });
}
function og(name, content, escape) {
if (escape !== false && typeof content === 'string') {
content = escapeHTML(content);
}
return htmlTag('meta', { property: name, content });
}
const { config, page } = this;
const { content } = page;
let images = options.image || options.images || page.photos || [];
const description = helper.get('page_descr').bind(this)();
const _tags = helper.get('page_tags').bind(this)();
let keywords;
const _title = helper.get('page_title').bind(this);
const title = (() => _title())();
const type = options.type || (this.is_post() ? 'article' : 'website');
const url = (options.url || this.url).replace('index.html', '');
const siteName = options.site_name || config.title;
const date = options.date !== false ? options.date || page.date : false;
const updated = options.updated !== false ? options.updated || page.updated : false;
const thumbnail = page.thumbnail;
const language = options.language || config.language;
const author = config.author;
// Images
if (!Array.isArray(images)) images = [images];
if (!images.length && content) {
images = images.slice();
if (content.includes('<img')) {
let img;
const imgPattern = /<img [^>]*src=['"]([^'"]+)([^>]*>)/gi;
while (img = imgPattern.exec(content)) {
images.push(img[1]);
}
}
}
images = images.map(path => {
if (!urlFn.parse(path).host) {
// resolve `path`'s absolute path relative to current page's url
// `path` can be both absolute (starts with `/`) or relative.
return urlFn.resolve(url || config.url, path);
}
return path;
});
if (thumbnail) images.unshift(thumbnail);
let result = '';
result += og('og:title', title);
result += og('og:site_name', siteName);
result += og('og:type', type);
result += og('og:url', url, false);
if (language) result += og('og:locale', language, false);
if (description) result += meta('description', description, false);
if (_tags) {
if (typeof _tags === 'string') {
keywords = _tags
} else if (_tags.length) {
keywords = _tags.map(tag => tag.name ? tag.name : tag).filter(keyword => !!keyword).join()
}
result += meta('keywords', keywords);
}
images.forEach(path => {
result += og('og:image', path, false);
});
if (date) {
if ((moment.isMoment(date) || moment.isDate(date)) && !isNaN(date.valueOf())) {
result += og('article:published_time', date.toISOString());
}
}
if (updated) {
if ((moment.isMoment(updated) || moment.isDate(updated)) && !isNaN(updated.valueOf())) {
result += og('article:modified_time', updated.toISOString());
result += og('og:updated_time', updated.toISOString());
}
}
if (this.is_post()) {
if (author) {
result += og('article:author', author);
}
if (_tags) {
result += og('article:tag', keywords);
}
if (thumbnail) {
result += meta('twitter:card', 'summary_large_image');
result += meta('twitter:image', thumbnail, false);
} else {
result += meta('twitter:card', 'summary');
}
};
return result.trim();
});
};