Comparing version 1.2.2 to 2.0.0
@@ -26,4 +26,10 @@ { | ||
"always" | ||
] | ||
], | ||
"no-var": "error", | ||
"no-multi-spaces": "error", | ||
"space-in-parens": "error", | ||
"no-multiple-empty-lines": "error", | ||
"prefer-const": "error", | ||
"no-use-before-define": "error" | ||
} | ||
} |
335
lib/index.js
'use strict'; | ||
const xml = require('xml'); | ||
const baseXml = require('xml'); | ||
/** | ||
* Check first argument. If true - push last argument to second argument | ||
* | ||
* @param condition | ||
* @param array | ||
* @param data | ||
*/ | ||
function pushIfConditionTrue(condition, array, data) { | ||
if (condition) { | ||
array.push(data); | ||
class TR { | ||
constructor(options, items) { | ||
options = options || {}; | ||
this.title = options.title || ''; | ||
this.link = options.link || ''; | ||
this.description = options.description || ''; | ||
this.language = options.language || 'ru'; | ||
this.items = []; | ||
if (Array.isArray(items) && items.length > 0) { | ||
const self = this; | ||
items.forEach(function (item) { | ||
self.item(item); | ||
}); | ||
} | ||
} | ||
} | ||
/** | ||
* @param related | ||
* @param itemValues | ||
* @param relatedInfinity | ||
*/ | ||
function addRelated(related, itemValues, relatedInfinity) { | ||
let relatedResult = related.map(function (rel) { | ||
return { | ||
link: [{ | ||
_attr: { | ||
'url': rel.link, | ||
'img': rel.image_url | ||
} | ||
}, rel.text] | ||
}; | ||
}); | ||
xml() { | ||
return baseXml(this.generateXML(this)); | ||
} | ||
if (relatedInfinity) { | ||
relatedResult.push({ | ||
_attr: {'type': 'infinity'} | ||
item(data) { | ||
data = data || {}; | ||
this.items.push( | ||
this.itemData(data) | ||
); | ||
return this; | ||
} | ||
/** | ||
* Check first argument. If true - push last argument to second argument | ||
* | ||
* @param condition | ||
* @param array | ||
* @param data | ||
*/ | ||
pushIfConditionTrue(condition, array, data) { | ||
if (condition) { | ||
array.push(data); | ||
} | ||
} | ||
/** | ||
* @param related | ||
* @param itemValues | ||
* @param relatedInfinity | ||
*/ | ||
addRelated(related, itemValues, relatedInfinity) { | ||
const relatedResult = related.map(function (rel) { | ||
return { | ||
link: [{ | ||
_attr: { | ||
'url': rel.link, | ||
'img': rel.image_url | ||
} | ||
}, rel.text] | ||
}; | ||
}); | ||
if (relatedInfinity) { | ||
relatedResult.push({ | ||
_attr: {'type': 'infinity'} | ||
}); | ||
} | ||
this.pushIfConditionTrue(related, itemValues, {'yandex:related': relatedResult}); | ||
} | ||
pushIfConditionTrue(related, itemValues, {'yandex:related': relatedResult}); | ||
} | ||
/** | ||
* @param item | ||
* @param itemValues | ||
*/ | ||
pushGoals(item, itemValues) { | ||
if (item.goals.length > 0) { | ||
item.goals.forEach(goal => itemValues.push({ | ||
'turbo:goal': { | ||
_attr: { | ||
type: goal.type || 'yandex', | ||
'turbo-goal-id': goal.id, | ||
name: goal.name, | ||
id: goal.counter_id, | ||
} | ||
} | ||
})); | ||
} | ||
} | ||
/** | ||
* @param item | ||
* @param itemValues | ||
*/ | ||
function pushGoals(item, itemValues) { | ||
if (item.goals.length > 0) { | ||
item.goals.forEach(goal => itemValues.push({ | ||
'turbo:goal': { | ||
_attr: { | ||
type: goal.type || 'yandex', | ||
'turbo-goal-id': goal.id, | ||
name: goal.name, | ||
id: goal.counter_id, | ||
} | ||
getImageContent(item) { | ||
if (item.image_url.length > 0) { | ||
let imageCaption = ''; | ||
if (item.image_caption.length > 0) { | ||
imageCaption = `<figcaption>${item.image_caption}</figcaption>`; | ||
} | ||
})); | ||
return `<figure><img src="${item.image_url}" />${imageCaption}</figure>`; | ||
} | ||
return ''; | ||
} | ||
} | ||
/** | ||
* Items processing | ||
* @param items | ||
* @param channel | ||
*/ | ||
function items(items, channel) { | ||
items.forEach(function (item) { | ||
let itemValues = []; | ||
itemValues.push({_attr: {'turbo': item.turboEnabled ? 'true' : 'false'}}); | ||
itemValues.push({link: item.url}); | ||
getSubheading(item) { | ||
if (item.subheading.length > 0) { | ||
return `<h2>${item.subheading}</h2>`; | ||
} | ||
pushIfConditionTrue(item.turboSource, itemValues, {'turbo:source': item.turboSource}); | ||
pushIfConditionTrue(item.turboTopic, itemValues, {'turbo:topic': item.turboTopic}); | ||
pushIfConditionTrue(item.date, itemValues, {pubDate: new Date(item.date).toUTCString()}); | ||
pushIfConditionTrue(item.author, itemValues, {author: item.author}); | ||
return ''; | ||
} | ||
let img = '', menu = ''; | ||
getLinksString(links) { | ||
return links.map(function (item) { | ||
return `<a href="${item.link}">${item.text}</a>`; | ||
}).join(''); | ||
} | ||
if (item.image_url) { | ||
img = '<figure><img src="' + item.image_url + '" /></figure>'; | ||
getMenu(item) { | ||
if (Array.isArray(item.menu) && item.menu.length > 0) { | ||
return `<menu>${this.getLinksString(item.menu)}</menu>`; | ||
} | ||
if (Array.isArray(item.menu)) { | ||
menu = '<menu>' + item.menu.map(function (item) { | ||
return '<a href="' + item.link + '">' + item.text + '</a>'; | ||
}).join('') + '</menu>'; | ||
return ''; | ||
} | ||
getBreadcrumbs(item) { | ||
if (Array.isArray(item.breadcrumbs) && item.breadcrumbs.length > 0) { | ||
return `<div data-block="breadcrumblist">${this.getLinksString(item.breadcrumbs)}</div>`; | ||
} | ||
let fullContent = '<header>' + img + ' <h1>' + item.title + '</h1>' + menu + '</header>' + item.content; | ||
return ''; | ||
} | ||
pushGoals(item, itemValues); | ||
/** | ||
* Items processing | ||
* @param items | ||
* @param channel | ||
*/ | ||
itemsProcessing(items, channel) { | ||
const self = this; | ||
items.forEach(function (item) { | ||
const itemValues = []; | ||
itemValues.push({_attr: {'turbo': item.turboEnabled ? 'true' : 'false'}}); | ||
itemValues.push({link: item.url}); | ||
itemValues.push({'turbo:content': {_cdata: fullContent}}); | ||
self.pushIfConditionTrue(item.turboSource, itemValues, {'turbo:source': item.turboSource}); | ||
self.pushIfConditionTrue(item.turboTopic, itemValues, {'turbo:topic': item.turboTopic}); | ||
self.pushIfConditionTrue(item.date, itemValues, {pubDate: new Date(item.date).toUTCString()}); | ||
self.pushIfConditionTrue(item.author, itemValues, {author: item.author}); | ||
if (typeof item.related !== 'undefined') { | ||
addRelated(item.related, itemValues, item.relatedfinity); | ||
} | ||
const fullContent = `<header>${self.getImageContent(item)}<h1>${item.title}</h1>${self.getSubheading(item)}${self.getMenu(item)}${self.getBreadcrumbs(item)}</header>${item.content}`; | ||
channel.push({item: itemValues}); | ||
}); | ||
} | ||
self.pushGoals(item, itemValues); | ||
/** | ||
* @param data | ||
* @returns {{rss: *[]}} | ||
*/ | ||
function generateXML(data) { | ||
itemValues.push({'turbo:content': {_cdata: fullContent}}); | ||
let channel = []; | ||
if (typeof item.related !== 'undefined') { | ||
self.addRelated(item.related, itemValues, item.relatedInfinity); | ||
} | ||
channel.push({title: {_cdata: data.title}}); | ||
channel.push({link: data.link}); | ||
channel.push({description: {_cdata: data.description || data.title}}); | ||
channel.push({language: data.language}); | ||
channel.push({item: itemValues}); | ||
}); | ||
} | ||
items(data.items, channel); | ||
/** | ||
* @param options | ||
* | ||
* @returns {{rss: *[]}} | ||
*/ | ||
generateXML(options) { | ||
let _attr = { | ||
'xmlns:yandex': 'http://news.yandex.ru', | ||
'xmlns:media': 'http://search.yahoo.com/mrss/', | ||
'xmlns:turbo': 'http://turbo.yandex.ru', | ||
version: '2.0' | ||
}; | ||
const channel = []; | ||
return { | ||
rss: [ | ||
{_attr: _attr}, | ||
{channel: channel} | ||
] | ||
}; | ||
} | ||
channel.push({title: {_cdata: options.title}}); | ||
channel.push({link: options.link}); | ||
channel.push({description: {_cdata: options.description}}); | ||
channel.push({language: options.language}); | ||
/** | ||
* @param data | ||
* @returns {*} | ||
*/ | ||
function itemData(data) { | ||
return { | ||
title: data.title || '', | ||
description: data.description || '', | ||
image_url: data.image_url, | ||
url: data.url || data.link, | ||
author: data.author, | ||
date: data.date || data.pubDate, | ||
content: data.content, | ||
menu: data.menu, | ||
related: data.related, | ||
relatedfinity: data.relatedfinity || false, | ||
turboSource: data.turboSource || '', | ||
turboTopic: data.turboTopic || '', | ||
goals: data.goals || [], | ||
turboEnabled: data.turboEnabled !== undefined ? data.turboEnabled: true, | ||
}; | ||
} | ||
/** | ||
* Base function | ||
* @param options | ||
* @param items | ||
* @constructor | ||
*/ | ||
function TR(options, items) { | ||
options = options || {}; | ||
this.itemsProcessing(options.items, channel); | ||
this.title = options.title || ''; | ||
this.link = options.link || ''; | ||
this.description = options.description || ''; | ||
this.language = options.language || 'ru'; | ||
const _attr = { | ||
'xmlns:yandex': 'http://news.yandex.ru', | ||
'xmlns:media': 'http://search.yahoo.com/mrss/', | ||
'xmlns:turbo': 'http://turbo.yandex.ru', | ||
version: '2.0' | ||
}; | ||
this.items = items || []; | ||
return { | ||
rss: [ | ||
{_attr: _attr}, | ||
{channel: channel} | ||
] | ||
}; | ||
} | ||
this.item = function (data) { | ||
data = data || {}; | ||
this.items.push(itemData(data)); | ||
return this; | ||
}; | ||
this.xml = function () { | ||
return xml(generateXML(this)); | ||
}; | ||
/** | ||
* @param data | ||
* @returns {*} | ||
*/ | ||
itemData(data) { | ||
return { | ||
title: data.title || '', // h1 | ||
subheading: data.subheading || '', // h2 | ||
image_url: data.image_url || '', | ||
image_caption: data.image_caption || '', | ||
url: data.url || data.link, | ||
author: data.author, | ||
date: data.date || data.pubDate, | ||
content: data.content, | ||
menu: data.menu || [], | ||
breadcrumbs: data.breadcrumbs || [], | ||
related: data.related, | ||
relatedInfinity: data.relatedInfinity || false, | ||
turboSource: data.turboSource || '', | ||
turboTopic: data.turboTopic || '', | ||
goals: data.goals || [], | ||
turboEnabled: data.turboEnabled !== undefined ? data.turboEnabled : true, | ||
}; | ||
} | ||
} | ||
module.exports = TR; |
{ | ||
"name": "turbo-rss", | ||
"version": "1.2.2", | ||
"version": "2.0.0", | ||
"description": "RSS based, feed generator for Yandex turbo", | ||
@@ -13,3 +13,4 @@ "keywords": [ | ||
"scripts": { | ||
"test": "tape test --tap | tap-min" | ||
"test": "tape test --tap | tap-min", | ||
"coverage": "istanbul cover tape test -- -R spec" | ||
}, | ||
@@ -16,0 +17,0 @@ "homepage": "https://github.com/LightAir/turbo-rss", |
@@ -38,3 +38,5 @@ ## turbo-rss | ||
* `title` **string** Заголовок страницы. | ||
* `subheading` _optional_ **string** Подзаголовок страницы. | ||
* `image_url` _optional_ **url string** Адрес изображения, которое используется в качестве обложки. Изображение может быть в любом формате. | ||
* `image_caption` _optional_ **string** Подпись к изображению обложки. | ||
* `link` **url string** URL страницы сайта, для которой нужно сформировать Турбо-страницу. | ||
@@ -45,4 +47,5 @@ * `author` _optional_ **string** Автор статьи, размещенной на странице. | ||
* `menu` _optional_ **array** Внимание! Меню будет отображаться только в том случае, если в настройках на странице Яндекс Вебмастер -> Турбо-страницы -> Настройки, содержимое 'Меню Турбо-страниц' пустое! | ||
* `breadcrumbs` _optional_ **array** Навигационная ссылка https://yandex.ru/dev/turbo/doc/rss/elements/header.html#breadcrumbs | ||
* `related` _optional_ **array** Аффилированные ссылки `yandex:related` в конце статьи. Вы можете разместить ссылки на другие ресурсы или настроить отображение непрерывной ленты статей, реализованной, например с помощью AJAX. | ||
* `relatedfinity` _optional_ **bool** Непрерывная лента статей | ||
* `relatednfinity` _optional_ **bool** Непрерывная лента статей (Параметр был переименован из relatedfinity) | ||
* `turboSource` _optional_ **string** URL страницы-источника, который можно передать в Яндекс.Метрику. | ||
@@ -52,2 +55,3 @@ * `turboTopic` _optional_ **string** Заголовок страницы, который можно передать в Яндекс.Метрику. | ||
* `turboEnabled`_optional_ **bool** Принудительная установка атрибута "turbo". По умолчанию true. Установка в false позволит скрыть отображение турбо-страницы | ||
###### menu array | ||
@@ -58,3 +62,9 @@ menu должен содержать массив объектов со следующими опциями: | ||
* `text` **string** текст ссылки. не должен содержать html | ||
###### breadcrumbs array | ||
Один элемент хлебных крошек должен содержать массив объектов со следующими опциями: | ||
* `link` **url string** ссылка | ||
* `text` **string** текст ссылки (не должен содержать html) | ||
###### related array | ||
@@ -61,0 +71,0 @@ related должен содержать массив объектов со следующими опциями: |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
17510
221
140