Iniciativa para Consumir desde un rss de BBC para crear un listado de noticias en el footer y unas utilidades de traduccion y otra de recorte de string para limitar los caracteres visualizacion

This commit is contained in:
Cesar Mendivil 2024-10-16 11:46:40 -07:00
parent 8c64465d16
commit a6b71625ec
11 changed files with 249 additions and 74 deletions

View File

@ -20,6 +20,20 @@ module.exports = {
remoteJsonUrl: `http://localhost:8000/data/language/languages.json`,
},
},
{
resolve: `gatsby-source-rss-feed`,
options: {
url: `https://feeds.bbci.co.uk/news/technology/rss.xml`,
name: `BBCNewsTech`,
parserOption: {
customFields: {
channel: ['title', 'description', 'link', 'image', 'generator', 'lastBuildDate', 'copyright', 'language', 'ttl'],
item: ['title', 'description', 'link', 'guid', 'pubDate', 'media','thumbnail','url','attrs'], // Campos personalizados si el feed tiene elementos adicionales
},
},
},
},
],
trailingSlash: 'always',
};

View File

@ -33,8 +33,8 @@ exports.onCreateWebpackConfig = ({
);
}
}
// Add path-browserify to the fallback configuration
config.resolve.fallback = {
// Add path-browserify and timers-browserify to the fallback configuration
config.resolve.fallback = {
...config.resolve.fallback,
path: require.resolve('path-browserify'),
};

142
package-lock.json generated
View File

@ -13,6 +13,7 @@
"gatsby": "^4.24.1",
"gatsby-plugin-intl": "^5.10.0",
"gatsby-plugin-resolve-src": "^2.1.0",
"gatsby-source-rss-feed": "^1.2.2",
"lightgallery": "^2.5.0",
"mini-css-extract-plugin": "^2.7.7",
"path-browserify": "^1.0.1",
@ -21,7 +22,9 @@
"react-dom": "^17.0.2",
"react-intl": "^6.6.8",
"react-modal-video": "^1.2.9",
"swiper": "^8.3.2"
"swiper": "^8.3.2",
"timers-browserify": "^2.0.12",
"xml2js": "^0.6.2"
},
"devDependencies": {
"eslint": "^7.32.0",
@ -8314,9 +8317,12 @@
}
},
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/function.prototype.name": {
"version": "1.1.5",
@ -8823,6 +8829,15 @@
"node": ">=14.15.0"
}
},
"node_modules/gatsby-source-rss-feed": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/gatsby-source-rss-feed/-/gatsby-source-rss-feed-1.2.2.tgz",
"integrity": "sha512-Ris5Dtdj856aups8xzPtNOG6prKjaGzcXxRdFrgExQBVv2o1fUPHwj7OGrdV32tNUg2mHOZurr5qFWAdaRIMUg==",
"dependencies": {
"lodash": "^4.17.15",
"rss-parser": "^3.7.6"
}
},
"node_modules/gatsby-telemetry": {
"version": "3.24.0",
"resolved": "https://registry.npmjs.org/gatsby-telemetry/-/gatsby-telemetry-3.24.0.tgz",
@ -13618,6 +13633,27 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/rss-parser": {
"version": "3.13.0",
"resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.13.0.tgz",
"integrity": "sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w==",
"dependencies": {
"entities": "^2.0.3",
"xml2js": "^0.5.0"
}
},
"node_modules/rss-parser/node_modules/xml2js": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
"integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
"dependencies": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/run-async": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
@ -13687,6 +13723,11 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/sax": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
},
"node_modules/scheduler": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
@ -14770,6 +14811,17 @@
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
},
"node_modules/timers-browserify": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
"integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==",
"dependencies": {
"setimmediate": "^1.0.4"
},
"engines": {
"node": ">=0.6.0"
}
},
"node_modules/timers-ext": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz",
@ -15576,6 +15628,26 @@
"node": ">=8"
}
},
"node_modules/xml2js": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
"integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
"dependencies": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
"engines": {
"node": ">=4.0"
}
},
"node_modules/xmlhttprequest-ssl": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz",
@ -21761,9 +21833,9 @@
"optional": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
"function.prototype.name": {
"version": "1.1.5",
@ -22294,6 +22366,15 @@
"sharp": "^0.30.7"
}
},
"gatsby-source-rss-feed": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/gatsby-source-rss-feed/-/gatsby-source-rss-feed-1.2.2.tgz",
"integrity": "sha512-Ris5Dtdj856aups8xzPtNOG6prKjaGzcXxRdFrgExQBVv2o1fUPHwj7OGrdV32tNUg2mHOZurr5qFWAdaRIMUg==",
"requires": {
"lodash": "^4.17.15",
"rss-parser": "^3.7.6"
}
},
"gatsby-telemetry": {
"version": "3.24.0",
"resolved": "https://registry.npmjs.org/gatsby-telemetry/-/gatsby-telemetry-3.24.0.tgz",
@ -25593,6 +25674,26 @@
"glob": "^7.1.3"
}
},
"rss-parser": {
"version": "3.13.0",
"resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.13.0.tgz",
"integrity": "sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w==",
"requires": {
"entities": "^2.0.3",
"xml2js": "^0.5.0"
},
"dependencies": {
"xml2js": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
"integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
}
}
}
},
"run-async": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
@ -25641,6 +25742,11 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"sax": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
},
"scheduler": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
@ -26433,6 +26539,14 @@
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
},
"timers-browserify": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
"integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==",
"requires": {
"setimmediate": "^1.0.4"
}
},
"timers-ext": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz",
@ -27018,6 +27132,20 @@
"resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
"integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q=="
},
"xml2js": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
"integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
}
},
"xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
},
"xmlhttprequest-ssl": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz",

View File

@ -20,6 +20,7 @@
"gatsby": "^4.24.1",
"gatsby-plugin-intl": "^5.10.0",
"gatsby-plugin-resolve-src": "^2.1.0",
"gatsby-source-rss-feed": "^1.2.2",
"lightgallery": "^2.5.0",
"mini-css-extract-plugin": "^2.7.7",
"path-browserify": "^1.0.1",
@ -28,7 +29,9 @@
"react-dom": "^17.0.2",
"react-intl": "^6.6.8",
"react-modal-video": "^1.2.9",
"swiper": "^8.3.2"
"swiper": "^8.3.2",
"timers-browserify": "^2.0.12",
"xml2js": "^0.6.2"
},
"devDependencies": {
"eslint": "^7.32.0",

View File

@ -1,18 +0,0 @@
import axios from 'axios';
import xml2js from 'xml2js';
class RssService {
async getRssFeed(url) {
try {
const response = await axios.get(url);
const result = await xml2js.parseStringPromise(response.data, { mergeAttrs: true });
return result.rss.channel[0].item;
} catch (error) {
console.error('Error fetching RSS feed:', error);
return [];
}
}
}
const rssService = new RssService();
export default rssService;

View File

@ -0,0 +1,4 @@
export const shortenString = (str, maxLength) => {
if (str.length <= maxLength) return str;
return str.substring(0, maxLength) + '...';
};

View File

@ -2,8 +2,7 @@ import React,{ useEffect, useState,useContext } from 'react';
import { Link } from 'gatsby';
import api from '../../common/api';
import { LanguageContext } from '../../context/LanguageContext';
import RssFeed from '../Utils/RssFeed';
const Blog = () => {
const { currentLanguage } = useContext(LanguageContext);
const [dataBlog, setBlogs] = useState({blogs: [], faq: [],clients: [],text_traductions:[]});
@ -29,47 +28,9 @@ const Blog = () => {
<div className="blog-content">
<div className="section-head style-3 d-flex align-items-center mb-50" >
<div dangerouslySetInnerHTML={{ __html: blog_titleResult }}></div>
<Link to="/page-blog-5" className="text-muted ms-5 ps-5 mt-2">{dataBlog.text_traductions[currentLanguage] && dataBlog.text_traductions[currentLanguage].all_articles} <i className="bi bi-chevron-right ms-1"></i></Link>
<Link to="https://www.bbc.com/innovation/technology" className="text-muted ms-5 ps-5 mt-2">{dataBlog.text_traductions[currentLanguage] && dataBlog.text_traductions[currentLanguage].all_articles} <i className="bi bi-chevron-right ms-1"></i></Link>
</div>
{
dataBlog.blogs.map((post, i) => (
<div className={`card border-0 bg-transparent rounded-0 ${i !== dataBlog.blogs.length - 1 ? 'border-bottom brd-gray':''} pb-4 mb-4`} key={i}>
<div className="row align-items-center">
<div className="col-lg-4">
<Link to="/page-single-post-5" className="img img-cover">
<img src={post.cover} className="radius-2" alt="..." />
</Link>
</div>
<div className="col-lg-8">
<div className="card-body p-0">
<small className="d-block date text">
<a href="#" className="text-uppercase border-end brd-light pe-3 me-3 color-blue2 fw-bold">{post.type && post.type[currentLanguage]}</a>
<i className="bi bi-clock me-1"></i>
<a href="#" className="op-8">{ post.time && post.time[currentLanguage]}</a>
</small>
<h6 className="card-title"><Link to="/page-single-post-5">{ post.title && post.title[currentLanguage]}</Link></h6>
<div className="d-flex small mt-20 align-items-center justify-content-between op-9">
<div className="l_side d-flex align-items-center">
<span className="icon-10 rounded-circle d-inline-flex justify-content-center align-items-center text-uppercase bg-blue2 p-2 me-2 text-white">
{ post.userImage }
</span>
<a href="#">
<small className="text-muted">{ post.by && post.by[currentLanguage]}</small> { post.username }
</a>
</div>
<div className="r-side mt-1">
<i className="bi bi-chat-left-text me-1"></i>
<a href="#">{ post.comments }</a>
<i className="bi bi-eye ms-4 me-1"></i>
<a href="#">{ post.views }</a>
</div>
</div>
</div>
</div>
</div>
</div>
))
}
<RssFeed/>
</div>
</div>
<div className="col-lg-5">

View File

@ -10,10 +10,10 @@ const Footer = () => {
<div className="col-lg-3 col-sm-6">
<div className="items">
<div className="title">
Iteck - 1st Choice for IT Solutions
Nextream's Tech & Solutions
</div>
<small className="text">
Over 25 years working in IT services developing software applications and mobile apps for clients all over the world. For your very specific industry, we have highly-tailored IT solutions.
Más de 25 años trabajando en servicios de TI desarrollando aplicaciones de software y aplicaciones móviles para clientes de todo el mundo. Para su industria muy específica, contamos con soluciones de TI altamente personalizadas.
</small>
<div className="socail-icons">
<a href="#" className="icon-35 rounded-circle bg-gray overflow-hidden d-inline-flex align-items-center justify-content-center text-gray me-2">
@ -31,7 +31,7 @@ const Footer = () => {
<div className="col-lg-3 col-sm-6">
<div className="items">
<div className="title">
Information
Informacion
</div>
<small className="text mb-10 d-block">
{ footerData.address }

View File

@ -0,0 +1,83 @@
import React from 'react';
import { useStaticQuery, graphql, Link } from 'gatsby';
import { shortenString } from '../../common/shortenString';
const RssFeed = () => {
const data = useStaticQuery(graphql`
query {
allFeedBbcNewsTech(limit: 3) {
edges {
node {
title
link
content
contentSnippet
pubDate
media {
thumbnail {
attrs {
url
}
}
}
internal {
type
}
}
}
}
}
`);
// Ordenar los elementos por fecha de publicación y seleccionar los 4 más recientes
const rssItems = data.allFeedBbcNewsTech.edges
.sort((a, b) => new Date(b.pubDate) - new Date(a.pubDate));
return (
rssItems.map(({ node }, index) => (
<div className={`card border-0 bg-transparent rounded-0 ${index !== rssItems.length - 1 ? 'border-bottom brd-gray':''} pb-4 mb-4`} key={index}>
<div className="row align-items-center">
<div className="col-lg-4">
<Link to={node.link} className="img img-cover">
<img src={node.media.thumbnail.attrs.url} alt={node.title} />
</Link>
</div>
<div className="col-lg-8">
<div className="card-body p-0">
<small className="d-block date text">
<a href={node.link} className="text-uppercase border-end brd-light pe-3 me-3 color-blue2 fw-bold">{node.title}</a>
<i className="bi bi-clock me-1"></i>
<a href={node.link} className="op-8">{new Date(node.pubDate).toLocaleDateString()}</a>
</small>
<h6 className="card-title"><Link to={node.link}>{shortenString(node.content, 40) }</Link></h6>
<div className="d-flex small mt-20 align-items-center justify-content-between op-9">
<div className="l_side d-flex align-items-center">
<a href={node.link}>
<span className="icon-11 rounded-circle d-inline-flex justify-content-center align-items-center text-uppercase bg-blue2 p-2 me-2 text-white">
BBC News
</span>
<small className="text-muted"></small> Ver Más
</a>
</div>
<div className="r-side mt-1">
<i className="bi bi-chat-left-text me-1"></i>
<a href="#">{ node.comments }</a>
<i className="bi bi-eye ms-4 me-1"></i>
<a href="#">{ node.views }</a>
</div>
</div>
</div>
</div>
</div>
</div>
))
);
}
export default RssFeed;

View File

@ -116,7 +116,7 @@
"text_traductions":{
"es":{
"blog_title1":"<h3>Nextream <span>Noticias</span></h3> ",
"all_articles":"Ver artculos",
"all_articles":"Ver articulos",
"by":"Por",
"see_more":"Ver Más"
},