hexo-generator-json-content
Advanced tools
Comparing version 4.1.6 to 4.2.0
106
dist/main.js
@@ -24,3 +24,3 @@ 'use strict'; | ||
keywords: true, | ||
author: true | ||
author: true, | ||
}, | ||
@@ -44,12 +44,16 @@ | ||
keywords: true, | ||
author: true | ||
} | ||
author: true, | ||
}, | ||
}; | ||
function ignoreSettings (cfg) { | ||
function ignoreSettings(cfg) { | ||
const ignore = cfg.ignore ? cfg.ignore : {}; | ||
ignore.paths = ignore.paths ? ignore.paths.map(path => path.toLowerCase()) : []; | ||
ignore.paths = ignore.paths | ||
? ignore.paths.map((path) => path.toLowerCase()) | ||
: []; | ||
ignore.tags = ignore.tags ? ignore.tags.map(tag => tag.replace('#', '').toLowerCase()) : []; | ||
ignore.tags = ignore.tags | ||
? ignore.tags.map((tag) => tag.replace('#', '').toLowerCase()) | ||
: []; | ||
@@ -59,15 +63,23 @@ return ignore | ||
function isIgnored (content, settings) { | ||
if (content.hidden === false) { return false } | ||
function isIgnored(content, settings) { | ||
if (content.hidden === false) { | ||
return false | ||
} | ||
if (content.password || content.hidden) { return true } | ||
if (content.password || content.hidden) { | ||
return true | ||
} | ||
const pathIgnored = settings.paths.find(path => content.path.includes(path)); | ||
const pathIgnored = settings.paths.find((path) => content.path.includes(path)); | ||
if (pathIgnored) { return true } | ||
if (pathIgnored) { | ||
return true | ||
} | ||
const tags = content.tags ? content.tags.map(mapTags) : []; | ||
const tagIgnored = tags.filter(tag => settings.tags.includes(tag)).length; | ||
const tagIgnored = tags.filter((tag) => settings.tags.includes(tag)).length; | ||
if (tagIgnored) { return true } | ||
if (tagIgnored) { | ||
return true | ||
} | ||
@@ -77,23 +89,23 @@ return false | ||
function mapTags (tag) { | ||
function mapTags(tag) { | ||
return typeof tag === 'object' ? tag.name.toLowerCase() : tag | ||
} | ||
function has (obj, key) { | ||
function has(obj, key) { | ||
return Object.prototype.hasOwnProperty.call(obj, key) | ||
} | ||
function minify (str) { | ||
function minify(str) { | ||
return hexoUtil.stripHTML(str).trim().replace(/\s+/g, ' ') | ||
} | ||
function getProps (ref) { | ||
return Object.getOwnPropertyNames(ref).filter(item => ref[item]) | ||
function getProps(ref) { | ||
return Object.getOwnPropertyNames(ref).filter((key) => ref[key]) | ||
} | ||
function catags ({ name, slug, permalink }) { | ||
function catags({ name, slug, permalink }) { | ||
return { name, slug, permalink } | ||
} | ||
function getKeywords (str, language) { | ||
function getKeywords(str, language) { | ||
const keywords = keywordExtractor.extract(str, { | ||
@@ -103,3 +115,3 @@ language, | ||
return_changed_case: true, | ||
remove_duplicates: true | ||
remove_duplicates: true, | ||
}); | ||
@@ -110,3 +122,3 @@ | ||
function setContent (obj, item, ref, cfg) { | ||
function setContent(obj, item, ref, cfg) { | ||
switch (item) { | ||
@@ -117,2 +129,6 @@ case 'excerpt': | ||
case 'description': | ||
obj.description = minify(ref.description); | ||
break | ||
case 'text': | ||
@@ -138,7 +154,11 @@ obj.text = minify(ref.content); | ||
case 'date': | ||
obj.date = cfg.dateFormat ? moment(ref.date).format(cfg.dateFormat) : ref.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; | ||
obj.updated = cfg.dateFormat | ||
? moment(ref.updated).format(cfg.dateFormat) | ||
: ref.updated; | ||
break | ||
@@ -153,6 +173,18 @@ | ||
function reduceContent (names, content, cfg) { | ||
return names.reduce((obj, item) => setContent(obj, item, content, cfg), {}) | ||
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) : [], | ||
})); | ||
const categories = [...new Set(source.categories)].map(JSON.parse); | ||
const tags = [...new Set(source.tags)].map(JSON.parse); | ||
return { categories, tags } | ||
} | ||
const { config } = hexo; | ||
@@ -179,15 +211,11 @@ const defs = { meta: true }; | ||
if (pages) { | ||
const pagesNames = getProps(pages); | ||
const pagesProps = getProps(pages); | ||
const pagesValid = site.pages.filter(page => !isIgnored(page, ignore)); | ||
const pagesContent = pagesValid.map(page => reduceContent(pagesNames, page, json)); | ||
const pagesContent = pagesValid.map(page => reduceContent(pagesProps, page, json)); | ||
if (posts || json.meta) { | ||
output.pages = pagesContent; | ||
} else { | ||
output = pagesContent; | ||
} | ||
output = posts || json.meta ? Object.assign(output, { pages: pagesContent }) : pagesContent; | ||
} | ||
if (posts) { | ||
const postsNames = getProps(posts); | ||
const postsProps = getProps(posts); | ||
const postsSorted = site.posts.sort('-date'); | ||
@@ -198,9 +226,7 @@ const postsValid = postsSorted.filter(post => { | ||
}); | ||
const postsContent = postsValid.map(post => reduceContent(postsNames, post, json)); | ||
const postsContent = postsValid.map(post => reduceContent(postsProps, post, json)); | ||
if (pages || json.meta) { | ||
output.posts = postsContent; | ||
} else { | ||
output = postsContent; | ||
} | ||
output = pages || json.meta | ||
? Object.assign(output, { posts: postsContent }, reduceCategs(postsContent)) | ||
: postsContent; | ||
} | ||
@@ -207,0 +233,0 @@ |
@@ -20,3 +20,3 @@ import moment from 'moment'; | ||
keywords: true, | ||
author: true | ||
author: true, | ||
}, | ||
@@ -40,12 +40,16 @@ | ||
keywords: true, | ||
author: true | ||
} | ||
author: true, | ||
}, | ||
}; | ||
function ignoreSettings (cfg) { | ||
function ignoreSettings(cfg) { | ||
const ignore = cfg.ignore ? cfg.ignore : {}; | ||
ignore.paths = ignore.paths ? ignore.paths.map(path => path.toLowerCase()) : []; | ||
ignore.paths = ignore.paths | ||
? ignore.paths.map((path) => path.toLowerCase()) | ||
: []; | ||
ignore.tags = ignore.tags ? ignore.tags.map(tag => tag.replace('#', '').toLowerCase()) : []; | ||
ignore.tags = ignore.tags | ||
? ignore.tags.map((tag) => tag.replace('#', '').toLowerCase()) | ||
: []; | ||
@@ -55,15 +59,23 @@ return ignore | ||
function isIgnored (content, settings) { | ||
if (content.hidden === false) { return false } | ||
function isIgnored(content, settings) { | ||
if (content.hidden === false) { | ||
return false | ||
} | ||
if (content.password || content.hidden) { return true } | ||
if (content.password || content.hidden) { | ||
return true | ||
} | ||
const pathIgnored = settings.paths.find(path => content.path.includes(path)); | ||
const pathIgnored = settings.paths.find((path) => content.path.includes(path)); | ||
if (pathIgnored) { return true } | ||
if (pathIgnored) { | ||
return true | ||
} | ||
const tags = content.tags ? content.tags.map(mapTags) : []; | ||
const tagIgnored = tags.filter(tag => settings.tags.includes(tag)).length; | ||
const tagIgnored = tags.filter((tag) => settings.tags.includes(tag)).length; | ||
if (tagIgnored) { return true } | ||
if (tagIgnored) { | ||
return true | ||
} | ||
@@ -73,23 +85,23 @@ return false | ||
function mapTags (tag) { | ||
function mapTags(tag) { | ||
return typeof tag === 'object' ? tag.name.toLowerCase() : tag | ||
} | ||
function has (obj, key) { | ||
function has(obj, key) { | ||
return Object.prototype.hasOwnProperty.call(obj, key) | ||
} | ||
function minify (str) { | ||
function minify(str) { | ||
return stripHTML(str).trim().replace(/\s+/g, ' ') | ||
} | ||
function getProps (ref) { | ||
return Object.getOwnPropertyNames(ref).filter(item => ref[item]) | ||
function getProps(ref) { | ||
return Object.getOwnPropertyNames(ref).filter((key) => ref[key]) | ||
} | ||
function catags ({ name, slug, permalink }) { | ||
function catags({ name, slug, permalink }) { | ||
return { name, slug, permalink } | ||
} | ||
function getKeywords (str, language) { | ||
function getKeywords(str, language) { | ||
const keywords = extract(str, { | ||
@@ -99,3 +111,3 @@ language, | ||
return_changed_case: true, | ||
remove_duplicates: true | ||
remove_duplicates: true, | ||
}); | ||
@@ -106,3 +118,3 @@ | ||
function setContent (obj, item, ref, cfg) { | ||
function setContent(obj, item, ref, cfg) { | ||
switch (item) { | ||
@@ -113,2 +125,6 @@ case 'excerpt': | ||
case 'description': | ||
obj.description = minify(ref.description); | ||
break | ||
case 'text': | ||
@@ -134,7 +150,11 @@ obj.text = minify(ref.content); | ||
case 'date': | ||
obj.date = cfg.dateFormat ? moment(ref.date).format(cfg.dateFormat) : ref.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; | ||
obj.updated = cfg.dateFormat | ||
? moment(ref.updated).format(cfg.dateFormat) | ||
: ref.updated; | ||
break | ||
@@ -149,6 +169,18 @@ | ||
function reduceContent (names, content, cfg) { | ||
return names.reduce((obj, item) => setContent(obj, item, content, cfg), {}) | ||
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) : [], | ||
})); | ||
const categories = [...new Set(source.categories)].map(JSON.parse); | ||
const tags = [...new Set(source.tags)].map(JSON.parse); | ||
return { categories, tags } | ||
} | ||
const { config } = hexo; | ||
@@ -175,15 +207,11 @@ const defs = { meta: true }; | ||
if (pages) { | ||
const pagesNames = getProps(pages); | ||
const pagesProps = getProps(pages); | ||
const pagesValid = site.pages.filter(page => !isIgnored(page, ignore)); | ||
const pagesContent = pagesValid.map(page => reduceContent(pagesNames, page, json)); | ||
const pagesContent = pagesValid.map(page => reduceContent(pagesProps, page, json)); | ||
if (posts || json.meta) { | ||
output.pages = pagesContent; | ||
} else { | ||
output = pagesContent; | ||
} | ||
output = posts || json.meta ? Object.assign(output, { pages: pagesContent }) : pagesContent; | ||
} | ||
if (posts) { | ||
const postsNames = getProps(posts); | ||
const postsProps = getProps(posts); | ||
const postsSorted = site.posts.sort('-date'); | ||
@@ -194,9 +222,7 @@ const postsValid = postsSorted.filter(post => { | ||
}); | ||
const postsContent = postsValid.map(post => reduceContent(postsNames, post, json)); | ||
const postsContent = postsValid.map(post => reduceContent(postsProps, post, json)); | ||
if (pages || json.meta) { | ||
output.posts = postsContent; | ||
} else { | ||
output = postsContent; | ||
} | ||
output = pages || json.meta | ||
? Object.assign(output, { posts: postsContent }, reduceCategs(postsContent)) | ||
: postsContent; | ||
} | ||
@@ -203,0 +229,0 @@ |
{ | ||
"name": "hexo-generator-json-content", | ||
"version": "4.1.6", | ||
"version": "4.2.0", | ||
"description": "Hexo plugin to generate a JSON file with the contents of posts and pages to generic use or consumption, like AJAX site search, Twitter typehead or public content API", | ||
@@ -12,3 +12,3 @@ "scripts": { | ||
"push": "git push && git push --tags", | ||
"lint": "eslint src --color --fix", | ||
"lint": "prettier --write ./src/**/*.js", | ||
"dist": "run-s dist:*", | ||
@@ -42,12 +42,6 @@ "dist:lint": "npm run lint", | ||
"devDependencies": { | ||
"babel-eslint": "^10.0.1", | ||
"eslint": "^6.0.0", | ||
"eslint-config-standard": "^12.0.0", | ||
"eslint-plugin-import": "^2.16.0", | ||
"eslint-plugin-node": "^9.1.0", | ||
"eslint-plugin-promise": "^4.0.1", | ||
"eslint-plugin-standard": "^4.0.0", | ||
"husky": "^2.4.1", | ||
"husky": "^4.2.3", | ||
"npm-run-all": "^4.1.5", | ||
"rollup": "^1.4.0", | ||
"prettier": "^2.0.1", | ||
"rollup": "^2.1.0", | ||
"shx": "^0.3.2" | ||
@@ -54,0 +48,0 @@ }, |
@@ -7,35 +7,29 @@ # hexo-generator-json-content | ||
## News | ||
<!-- vscode-markdown-toc --> | ||
* [News](#News) | ||
* [Installation](#Installation) | ||
* [Usage](#Usage) | ||
* [Settings](#Settings) | ||
* [Defaults](#Defaults) | ||
* [Keywords](#Keywords) | ||
* [Date formats](#Dateformats) | ||
* [Output](#Output) | ||
* [Sections](#Sections) | ||
* [Excluding fields](#Excludingfields) | ||
* [Drafts](#Drafts) | ||
* [Skip indexing](#Skipindexing) | ||
* [Custom file name](#Customfilename) | ||
It is now possible to: | ||
<!-- vscode-markdown-toc-config | ||
numbering=false | ||
autoSave=true | ||
/vscode-markdown-toc-config --> | ||
<!-- /vscode-markdown-toc --> | ||
- Customize the output file name | ||
- Include drafts on indexed content | ||
- Skip indexing by tag, besides by category or path | ||
## <a name='News'></a>News | ||
### Breaking change | ||
To know new features and bugfixes, please visit [releases index](https://github.com/alexbruno/hexo-generator-json-content/releases). | ||
`ignore` settings are a bit different now. It expects to receive one or two lists: `paths` and `tags`. | ||
## <a name='Installation'></a>Installation | ||
## Table of contents | ||
- [hexo-generator-json-content](#hexo-generator-json-content) | ||
- [News](#news) | ||
- [Breaking change](#breaking-change) | ||
- [Table of contents](#table-of-contents) | ||
- [Installation](#installation) | ||
- [Usage](#usage) | ||
- [Settings](#settings) | ||
- [Defaults](#defaults) | ||
- [Keywords](#keywords) | ||
- [Date formats](#date-formats) | ||
- [Output](#output) | ||
- [Sections](#sections) | ||
- [Excluding fields](#excluding-fields) | ||
- [Drafts](#drafts) | ||
- [Skip indexing](#skip-indexing) | ||
- [Custom file name](#custom-file-name) | ||
## Installation | ||
```bash | ||
@@ -45,3 +39,3 @@ npm i -S hexo-generator-json-content | ||
## Usage | ||
## <a name='Usage'></a>Usage | ||
@@ -83,3 +77,4 @@ Hexo will run the generator _automagically_ when you run `hexo serve` or `hexo generate`. :smirk: | ||
path: post.path, | ||
excerpt: post.excerpt, //-> only text ;) | ||
excerpt: post.excerpt, //-> only text minified ;) | ||
description: post.description, //-> only text minified ;) | ||
keywords: null, //-> it needs settings | ||
@@ -100,2 +95,12 @@ text: post.content, //-> only text minified ;) | ||
}] | ||
}], | ||
categories: [{ //-> Posts categories index ;) | ||
name: category.name, | ||
slug: category.slug, | ||
permalink: category.permalink | ||
}], | ||
tags: [{ //-> Posts tags index ;) | ||
name: tag.name, | ||
slug: tag.slug, | ||
permalink: tag.permalink | ||
}] | ||
@@ -106,7 +111,7 @@ ``` | ||
## Settings | ||
## <a name='Settings'></a>Settings | ||
You can customize settings in `_config.yml`. | ||
### Defaults | ||
### <a name='Defaults'></a>Defaults | ||
@@ -156,3 +161,3 @@ Default settings are: | ||
### Keywords | ||
### <a name='Keywords'></a>Keywords | ||
@@ -176,3 +181,3 @@ `keywords` options extracts keywords from excerpt. | ||
### Date formats | ||
### <a name='Dateformats'></a>Date formats | ||
@@ -192,5 +197,5 @@ `dateFormat` option sets an output format for datetime objects `date` and `updated`. | ||
## Output | ||
## <a name='Output'></a>Output | ||
### Sections | ||
### <a name='Sections'></a>Sections | ||
@@ -235,3 +240,3 @@ By default, the JSON output includes `meta`, `pages` and `posts` sections. If only one of these sections is enabled by config, the json output will consist of a single array. | ||
### Excluding fields | ||
### <a name='Excludingfields'></a>Excluding fields | ||
@@ -242,3 +247,3 @@ You can exclude `meta`, `pages` or `posts` contents from output JSON by setting `meta`, `pages`, or `posts` to `false`. | ||
### Drafts | ||
### <a name='Drafts'></a>Drafts | ||
@@ -255,3 +260,3 @@ By default, drafts are automatically skipped from indexing. | ||
### Skip indexing | ||
### <a name='Skipindexing'></a>Skip indexing | ||
@@ -281,3 +286,3 @@ Any `post` or `page` protected with password will be automatically skipped from indexing. | ||
### Custom file name | ||
### <a name='Customfilename'></a>Custom file name | ||
@@ -284,0 +289,0 @@ By default, the output file is `content.json`, but is possible to customize the file name: |
20193
5
6
370
284