UNPKG

hexo-theme-essence

Version:

A Simple Clean Theme for Hexo with user-friendly Navigation System.

248 lines (199 loc) 6 kB
/* global hexo */ 'use strict'; function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var moment = _interopDefault(require('moment')); var hexoUtil = require('hexo-util'); var defaults = { pages: { author: true, comments: false, content: false, date: false, excerpt: false, link: false, path: true, permalink: false, raw: false, slug: false, text: true, title: true, updated: true, }, posts: { author: true, categories: true, comments: false, content: false, date: false, excerpt: false, link: false, path: true, permalink: false, raw: false, slug: false, tags: true, text: true, title: true, updated: true, }, }; function ignoreSettings (config) { const ignore = config.ignore || {}; ignore.paths = ignore.paths ? ignore.paths.map((path) => path.toLowerCase()) : []; ignore.tags = ignore.tags ? ignore.tags.map((tag) => tag.replace('#', '').toLowerCase()) : []; return ignore; } function isIgnored (content, settings) { if (content.hidden === false) return false; if (content.password || content.hidden) return true; const pathIgnored = settings.paths.find((path) => content.path.includes(path)); if (pathIgnored) return true; const tags = content.tags ? content.tags.map(mapTags) : []; const tagIgnored = tags.filter((tag) => settings.tags.includes(tag)).length; if (tagIgnored) return true; return false; } function hasLayout(content){ // console.log(content.layout, typeof(content.layout)); if(content.layout === false || content.layout === 'false') return false; return true; } function mapTags (tag) { return typeof tag === 'object' ? tag.name.toLowerCase() : tag; } function has (obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); } function minify (str) { return hexoUtil.stripHTML(str .replace(/<div(\s+?)id="encrypted(([\s\S])*?)<\/div>/g, ' ') .replace(/<div(\s+?)id="enckey(([\s\S])*?)<\/div>/g, ' ') ).trim().replace(/\s{2,}/g, ' '); } function getProps (ref) { return Object.getOwnPropertyNames(ref).filter((key) => ref[key]); } function catags ({ name, slug, permalink }) { return { name, slug, permalink }; } function setContent (obj, item, ref, cfg) { switch (item) { case 'excerpt': obj.excerpt = minify(ref.excerpt); break; case 'description': obj.description = minify(ref.description); break; case 'text': obj.text = minify(ref.content); break; case 'categories': obj.categories = ref.categories.map(catags); break; case 'tags': obj.tags = ref.tags.map(catags); break; case 'date': obj.date = cfg.dateFormat ? moment(ref.date).format(cfg.dateFormat) : ref.date; break; case 'updated': obj.updated = cfg.dateFormat ? moment(ref.updated).format(cfg.dateFormat) : ref.updated; break; default: obj[item] = ref[item]; } return obj; } function reduceContent (props, content, cfg) { return props.reduce((obj, item) => setContent(obj, item, content, cfg), {}); } function reduceCategs (posts) { const source = posts .map((post) => ({ categories: post.categories ? post.categories.map(JSON.stringify) : [], tags: post.tags ? post.tags.map(JSON.stringify) : [], })) .reduce( (res, item) => { res.categories.push(...item.categories); res.tags.push(...item.tags); return res; }, { categories: [], tags: [] }, ); const categories = [...new Set(source.categories)].map(JSON.parse); const tags = [...new Set(source.tags)].map(JSON.parse); return { categories, tags }; } hexo.extend.generator.register('json-content', function (site) { const { config } = this.theme; if(!config.search.enable) return []; const defs = { meta: true }; const opts = config.search || {}; const options = { ...defs, ...opts }; const pages = has(options, 'pages') ? options.pages : defaults.pages; const posts = has(options, 'posts') ? options.posts : defaults.posts; const ignore = ignoreSettings(options); const categs = { categories: [], tags: [], }; let output = options.meta ? { meta: { title: config.title, subtitle: config.subtitle, description: config.description, author: config.author, url: config.url, root: config.root, }, } : {}; // console.log('config: ', config); if (pages) { const pagesProps = getProps(pages); const pagesValid = site.pages.filter((page) => !isIgnored(page, ignore) && hasLayout(page)); const pagesContent = pagesValid.map((page) => reduceContent(pagesProps, page, options), ); if (posts || options.meta) { output = Object.assign(output, { pages: pagesContent }); const pagesCategs = reduceCategs(pagesContent); categs.categories.push(...pagesCategs.categories); categs.tags.push(...pagesCategs.tags); } else { output = pagesContent; } } if (posts) { const postsProps = getProps(posts); const postsSorted = site.posts.sort('-date'); const postsValid = postsSorted.filter((post) => { const include = options.drafts || post.published; return include && !isIgnored(post, ignore); }); const postsContent = postsValid.map((post) => reduceContent(postsProps, post, options), ); if (pages || options.meta) { output = Object.assign(output, { posts: postsContent }); const postsCategs = reduceCategs(postsContent); categs.categories.push(...postsCategs.categories); categs.tags.push(...postsCategs.tags); } else { output = postsContent; } } if (pages || posts || options.meta) Object.assign(output, reduceCategs([categs])); return { path: 'search.json', data: JSON.stringify(output), }; });