PageSourceSearch

https://nusratonline.com/js/news-feed.js

js nusratonline.com collected 2026-10-02 22:01:52 UTC 3,690 bytes, 144 lines download raw bytes

1/**
2 * News Feed - Fetches and displays RSS news about Nusrat Fateh Ali Khan
3 * Uses rss2json.com API for RSS-to-JSON conversion
4 */
5
6(function() {
7  'use strict';
8
9  const NEWS_CONFIG = {
10    // Google News RSS for NFAK
11    rssUrl: 'https://news.google.com/rss/search?q=nusrat+fateh+ali+khan&hl=en-US&gl=US&ceid=US:en',
12    // RSS2JSON API endpoint (free tier - no API key needed for basic use)
13    apiEndpoint: 'https://api.rss2json.com/v1/api.json',
14    maxItems: 6
15  };
16
17  // Fallback news items if API fails
18  const FALLBACK_NEWS = [
19    {
20      title: "Nusrat Fateh Ali Khan's Legacy Continues to Inspire Artists Worldwide",
21      link: "/blog/",
22      pubDate: new Date().toISOString(),
23      source: "NusratOnline"
24    },
25    {
26      title: "Remembering the King of Qawwali on His Birth Anniversary",
27      link: "/legacy/",
28      pubDate: new Date().toISOString(),
29      source: "NusratOnline"
30    },
31    {
32      title: "How NFAK's Music Transcends Borders and Generations",
33      link: "/articles/",
34      pubDate: new Date().toISOString(),
35      source: "NusratOnline"
36    }
37  ];
38
39  /**
40   * Format date to readable string
41   */
42  function formatDate(dateString) {
43    try {
44      const date = new Date(dateString);
45      const options = { year: 'numeric', month: 'short', day: 'numeric' };
46      return date.toLocaleDateString('en-US', options);
47    } catch (e) {
48      return '';
49    }
50  }
51
52  /**
53   * Extract source/domain from URL
54   */
55  function extractSource(url) {
56    try {
57      const hostname = new URL(url).hostname;
58      return hostname.replace('www.', '').split('.')[0];
59    } catch (e) {
60      return 'News';
61    }
62  }
63
64  /**
65   * Create HTML for a news item
66   */
67  function createNewsItemHTML(item) {
68    const title = item.title || 'Untitled';
69    const link = item.link || '#';
70    const date = formatDate(item.pubDate);
71    const source = item.source || extractSource(link);
72
73    return `
74      <a href="${link}" class="news-card" target="_blank" rel="noopener">
75        <span class="news-source">${source}</span>
76        <h4 class="news-title">${title}</h4>
77        <span class="news-date">${date}</span>
78      </a>
79    `;
80  }
81
82  /**
83   * Render news items to the container
84   */
85  function renderNews(items, container) {
86    if (!container) return;
87    
88    const html = items.slice(0, NEWS_CONFIG.maxItems)
89      .map(createNewsItemHTML)
90      .join('');
91    
92    container.innerHTML = html;
93  }
94
95  /**
96   * Show loading state
97   */
98  function showLoading(container) {
99    if (!container) return;
100    container.innerHTML = `
101      <div class="news-loading">
102        <p>Loading latest news...</p>
103      </div>
104    `;
105  }
106
107  /**
108   * Fetch news from RSS feed
109   */
110  async function fetchNews() {
111    const container = document.getElementById('news-feed-container');
112    if (!container) return;
113
114    showLoading(container);
115
116    try {
117      const apiUrl = `${NEWS_CONFIG.apiEndpoint}?rss_url=${encodeURIComponent(NEWS_CONFIG.rssUrl)}`;
118      const response = await fetch(apiUrl);
119      
120      if (!response.ok) {
121        throw new Error('Failed to fetch news');
122      }
123
124      const data = await response.json();
125      
126      if (data.status === 'ok' && data.items && data.items.length > 0) {
127        renderNews(data.items, container);
128      } else {
129        // Use fallback if no items
130        renderNews(FALLBACK_NEWS, container);
131      }
132    } catch (error) {
133      console.warn('News feed error, using fallback:', error);
134      renderNews(FALLBACK_NEWS, container);
135    }
136  }
137
138  // Initialize when DOM is ready
139  if (document.readyState === 'loading') {
140    document.addEventListener('DOMContentLoaded', fetchNews);
141  } else {
142    fetchNews();
143  }
144})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.