From 4f4b756fb8e0e33cc2d4d7e5aa2f7bef60282f0f Mon Sep 17 00:00:00 2001 From: Florian BOUILLON Date: Tue, 16 Mar 2021 11:10:53 +0100 Subject: [PATCH] Added Support for image:image in easy-sitemap Signed-off-by: Florian BOUILLON --- .../__snapshots__/index.test.ts.snap | 18 ++++-- packages/easy-sitemap/__tests__/index.test.ts | 55 ++++++++++++++++++- packages/easy-sitemap/package.json | 7 ++- packages/easy-sitemap/src/Sitemap.ts | 44 ++++++++++++++- 4 files changed, 114 insertions(+), 10 deletions(-) diff --git a/packages/easy-sitemap/__tests__/__snapshots__/index.test.ts.snap b/packages/easy-sitemap/__tests__/__snapshots__/index.test.ts.snap index dbb1d4d..d5f69a1 100644 --- a/packages/easy-sitemap/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/easy-sitemap/__tests__/__snapshots__/index.test.ts.snap @@ -1,11 +1,19 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Basic Sitemap Tests should not add changefreq if value is incorrect 1`] = `"https://www.example.com/path"`; +exports[`Basic Sitemap Tests should not add changefreq if value is incorrect 1`] = `"https://www.example.com/path"`; -exports[`Basic Sitemap Tests should not add priority when it is incorrect 1`] = `"https://www.example.com/path"`; +exports[`Basic Sitemap Tests should not add priority when it is incorrect 1`] = `"https://www.example.com/path"`; -exports[`Basic Sitemap Tests should return a basic sitemap 1`] = `"https://www.example.com/pathhttps://www.example.com/"`; +exports[`Basic Sitemap Tests should return a basic sitemap 1`] = `"https://www.example.com/pathhttps://www.example.com/"`; -exports[`Basic Sitemap Tests should return a sitemap 1`] = `"https://www.example.com/pathalways2021-01-20T00:00:00.000Z1https://www.example.com/"`; +exports[`Basic Sitemap Tests should return a sitemap 1`] = `"https://www.example.com/pathalways2021-01-20T00:00:00.000Z1https://www.example.com/"`; -exports[`Basic Sitemap Tests should return an empty sitemap 1`] = `""`; +exports[`Basic Sitemap Tests should return an empty sitemap 1`] = `""`; + +exports[`image:image tests should build corretcly with multiple image:image 1`] = `"https://www.example.com/pathhttps://www.example.com/testImage CaptionNantesTitleExample license urlhttps://www.example.com/test-2Image Caption2ParisTitle2Example license url"`; + +exports[`image:image tests should build corretcly with single image:image 1`] = `"https://www.example.com/pathhttps://www.example.com/testImage CaptionNantesTitleExample license url"`; + +exports[`image:image tests should skip image:image if no location is set 1`] = `"https://www.example.com/path"`; + +exports[`image:image tests should skip image:image if there is more than 1000 images 1`] = `"https://www.example.com/path"`; diff --git a/packages/easy-sitemap/__tests__/index.test.ts b/packages/easy-sitemap/__tests__/index.test.ts index cc62d56..c58f415 100644 --- a/packages/easy-sitemap/__tests__/index.test.ts +++ b/packages/easy-sitemap/__tests__/index.test.ts @@ -39,5 +39,58 @@ describe('Basic Sitemap Tests', () => { }) expect(sitemap.build()).toMatchSnapshot() }) - +}) + +describe('image:image tests', () => { + it('should build corretcly with single image:image', () => { + const sitemap = new Sitemap('https://www.example.com') + sitemap.addEntry('/path', { + images: [{ + location: '/test', + geoLocation: 'Nantes', + title: 'Title', + caption: 'Image Caption', + license: 'Example license url' + }] + }) + expect(sitemap.build()).toMatchSnapshot() + }) + it('should skip image:image if no location is set', () => { + const sitemap = new Sitemap('https://www.example.com') + sitemap.addEntry('/path', { + // @ts-expect-error + images: [{ + geoLocation: 'Nantes', + }] + }) + expect(sitemap.build()).toMatchSnapshot() + }) + it('should skip image:image if there is more than 1000 images', () => { + const sitemap = new Sitemap('https://www.example.com') + sitemap.addEntry('/path', { + images: Array.from(new Array(1001)).map(() => ({ + location: '/test', + })) + }) + expect(sitemap.build()).toMatchSnapshot() + }) + it('should build corretcly with multiple image:image', () => { + const sitemap = new Sitemap('https://www.example.com') + sitemap.addEntry('/path', { + images: [{ + location: '/test', + geoLocation: 'Nantes', + title: 'Title', + caption: 'Image Caption', + license: 'Example license url' + }, { + location: '/test-2', + geoLocation: 'Paris', + title: 'Title2', + caption: 'Image Caption2', + license: 'Example license url' + }] + }) + expect(sitemap.build()).toMatchSnapshot() + }) }) diff --git a/packages/easy-sitemap/package.json b/packages/easy-sitemap/package.json index a19a741..ad8e1f7 100644 --- a/packages/easy-sitemap/package.json +++ b/packages/easy-sitemap/package.json @@ -25,6 +25,11 @@ }, "keywords": [ "sitemap", - "sitemap.xml" + "sitemap.xml", + "xml", + "easy-sitemap", + "generator", + "SEO", + "search-engine" ] } diff --git a/packages/easy-sitemap/src/Sitemap.ts b/packages/easy-sitemap/src/Sitemap.ts index 5cfc9fc..a9d5482 100644 --- a/packages/easy-sitemap/src/Sitemap.ts +++ b/packages/easy-sitemap/src/Sitemap.ts @@ -4,7 +4,7 @@ export default class Sitemap { private static allowedChangefreq = ['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'] - private datas = '' + private datas = '' public constructor( private domain: string, private options?: { @@ -17,10 +17,22 @@ export default class Sitemap { } } + /** + * Add a new Entry into the Sitemap + * @param path the url path + * @param options aditional datas you want in the sitemap for the `path` + */ public addEntry(path: string, options?: { changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never' lastmod?: Date priority?: 1 | 0.9 | 0.8 | 0.7 | 0.6 | 0.5 | 0.4 | 0.3 | 0.2 | 0.1 | 0 + images?: Array<{ + location: string + caption?: string + geoLocation?: string + title?: string + license?: string + }> }) { let entryString = '' @@ -35,7 +47,7 @@ export default class Sitemap { if (options) { if (options.changefreq) { if (!Sitemap.allowedChangefreq.includes(options.changefreq)) { - console.warn(`changefreq is not one of the allowed words (${options.changefreq})\nChangeFreq won't be added`) + console.warn(`changefreq is not valid (${options.changefreq})`) } else { entryString += `${options.changefreq}` } @@ -47,7 +59,26 @@ export default class Sitemap { if (options.priority <= 1 && options.priority >= 0 && options.priority.toString().length <= 3) { entryString += `${options.priority}` } else { - console.warn(`Priority is not between 0 and 1 and only containing one decimal (${options.priority})\nPriority won't be added`) + console.warn(`Priority is not valid (${options.priority})`) + } + } + if (options.images) { + if (options.images.length > 1000) { + console.warn('image cant have more than 1000 images, skipping') + } else { + for (const image of options.images) { + if (!image.location) { + console.warn('Images need a Location') + continue + } + entryString += '' + entryString += `${image.location.startsWith('/') ? `${this.domain}${image.location}` : image.location}` + entryString += this.optionalEntry('image:caption', image.caption) + entryString += this.optionalEntry('image:geo_location', image.geoLocation) + entryString += this.optionalEntry('image:title', image.title) + entryString += this.optionalEntry('image:license', image.license) + entryString += '' + } } } } @@ -59,6 +90,9 @@ export default class Sitemap { } } + /** + * Finish the Sitemap + */ public build(): string { if (this.options?.response) { this.options.response.write('') @@ -67,4 +101,8 @@ export default class Sitemap { } return this.datas + '' } + + private optionalEntry(tag: string, entry?: string) { + return entry ? `<${tag}>${entry}` : '' + } }