Skip to content

Commit

Permalink
Merge pull request #89 from curbengh/post-category
Browse files Browse the repository at this point in the history
feat: import nested categories
  • Loading branch information
curbengh committed Aug 1, 2020
2 parents 881f860 + b17721c commit bf32100
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 2 deletions.
5 changes: 5 additions & 0 deletions lib/feed.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,16 @@ const template = {
status: 'wp:status',
type: 'wp:post_type',
tags: ['category[@domain="post_tag"]', '.'],
categories: ['category[@domain="category"]', '.'],
image_url: 'wp:attachment_url',
image_meta: ['wp:postmeta', {
key: 'wp:meta_key',
value: 'wp:meta_value'
}]
}],
categories: ['//wp:category', {
name: 'wp:cat_name',
parent: 'wp:category_parent'
}]
}
};
Expand Down
36 changes: 34 additions & 2 deletions lib/migrator.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ module.exports = async function(args) {
return tomd.turndown(str);
};

const nestCats = (items, name = '', link = 'parent') => {
return items
.filter(item => item[link] === name)
.map(item => [item.name, nestCats(items, item.name)].flat(Infinity));
};

const arrayToObj = inArray => {
if (inArray.length) return Object.fromEntries(inArray.map(({name, parent}) => [name, parent]));
return {};
};

try {
if (!source) {
const help = [
Expand Down Expand Up @@ -69,8 +80,11 @@ module.exports = async function(args) {
if (typeof limit !== 'number' || limit > feed.items.length || limit <= 0) limit = feed.items.length;
let postLimit = 0;

const { categories: siteCatsArray } = feed;
const siteCatsObj = arrayToObj(siteCatsArray);

for (const item of feed.items) {
const { link, date, id, comment, slug, status, type, tags, image_url, image_meta } = item;
const { link, date, id, comment, slug, status, type, tags, categories: postCats, image_url, image_meta } = item;
let { title, content, description } = item;
const layout = status === 'draft' ? 'draft' : 'post';

Expand Down Expand Up @@ -154,13 +168,31 @@ module.exports = async function(args) {

if (title.includes('"')) title = title.replace(/"/g, '\\"');

const newPostCats = [];
const filterPostCats = postCats => {
postCats.forEach(cat => {
const siteCat = siteCatsObj[cat] ? siteCatsObj[cat] : '';
const newPostCatsObj = arrayToObj(newPostCats)[cat];

// Avoid duplicate objects
if (typeof newPostCatsObj === 'undefined') newPostCats.push({ name: cat, parent: siteCat });

if (siteCat) {
filterPostCats([siteCat]);
}
});
};
filterPostCats(postCats);
const categories = nestCats(newPostCats);

const data = {
title,
id,
date,
content,
layout,
tags
tags,
categories
};

if (type === 'page') data.layout = 'page';
Expand Down
102 changes: 102 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,108 @@ describe('migrator', function() {
await unlink(path);
});

it('nested categories - two-level', async () => {
const title = 'foo';
const postCats = ['lorem', 'ipsum', 'dolor'];
const [lorem, ipsum, dolor] = postCats;
const xml = `<rss><channel><title>test</title>
<wp:category>
<wp:cat_name>${ipsum}</wp:cat_name>
<wp:category_parent>${lorem}</wp:category_parent>
</wp:category>
<wp:category>
<wp:cat_name>${lorem}</wp:cat_name>
<wp:category_parent></wp:category_parent>
</wp:category>
<wp:category>
<wp:cat_name>${dolor}</wp:cat_name>
<wp:category_parent></wp:category_parent>
</wp:category>
<item><title>${title}</title><content:encoded>foobar</content:encoded>
<category domain="category">${lorem}</category>
<category domain="category">${ipsum}</category>
<category domain="category">${dolor}</category>
</item>
</channel></rss>`;
const path = join(__dirname, 'excerpt.xml');
await writeFile(path, xml);
await m({ _: [path] });

const post = await readFile(join(hexo.source_dir, '_posts', title + '.md'));
const { categories } = fm(post);
categories.should.have.deep.members([['lorem', 'ipsum'], ['dolor']]);

await unlink(path);
});

it('nested categories - three-level', async () => {
const title = 'foo';
const postCats = ['lorem', 'ipsum', 'dolor', 'foo', 'bar'];
const [lorem, ipsum, dolor, foo, bar] = postCats;
const xml = `<rss><channel><title>test</title>
<wp:category>
<wp:cat_name>${dolor}</wp:cat_name>
<wp:category_parent>${ipsum}</wp:category_parent>
</wp:category>
<wp:category>
<wp:cat_name>${ipsum}</wp:cat_name>
<wp:category_parent>${lorem}</wp:category_parent>
</wp:category>
<wp:category>
<wp:cat_name>${lorem}</wp:cat_name>
<wp:category_parent></wp:category_parent>
</wp:category>
<wp:category>
<wp:cat_name>${bar}</wp:cat_name>
<wp:category_parent>${foo}</wp:category_parent>
</wp:category>
<wp:category>
<wp:cat_name>${foo}</wp:cat_name>
<wp:category_parent></wp:category_parent>
</wp:category>
<item><title>${title}</title><content:encoded>foobar</content:encoded>
<category domain="category">${lorem}</category>
<category domain="category">${ipsum}</category>
<category domain="category">${dolor}</category>
<category domain="category">${foo}</category>
<category domain="category">${bar}</category>
</item>
</channel></rss>`;
const path = join(__dirname, 'excerpt.xml');
await writeFile(path, xml);
await m({ _: [path] });

const post = await readFile(join(hexo.source_dir, '_posts', title + '.md'));
const { categories } = fm(post);
categories.should.have.deep.members([['lorem', 'ipsum', 'dolor'], ['foo', 'bar']]);

await unlink(path);
});

// #36
it('non-nested categories', async () => {
const title = 'foo';
const postCats = ['lorem', 'ipsum', 'dolor'];
const postCatsArray = postCats.map(cat => [cat]);
const [lorem, ipsum, dolor] = postCats;
const xml = `<rss><channel><title>test</title>
<item><title>${title}</title><content:encoded>foobar</content:encoded>
<category domain="category">${lorem}</category>
<category domain="category">${ipsum}</category>
<category domain="category">${dolor}</category>
</item>
</channel></rss>`;
const path = join(__dirname, 'excerpt.xml');
await writeFile(path, xml);
await m({ _: [path] });

const post = await readFile(join(hexo.source_dir, '_posts', title + '.md'));
const { categories } = fm(post);
categories.should.have.deep.members(postCatsArray);

await unlink(path);
});

it('excerpt', async () => {
const content = 'foo<!-- more -->bar';
const xml = `<rss><channel><title>test</title>
Expand Down

0 comments on commit bf32100

Please sign in to comment.