{"id":1449,"date":"2026-09-13T13:56:07","date_gmt":"2026-09-13T11:56:07","guid":{"rendered":"https:\/\/betterthansilence.de\/radio\/?p=1449"},"modified":"2026-09-13T14:42:30","modified_gmt":"2026-09-13T12:42:30","slug":"allesongs","status":"publish","type":"post","link":"https:\/\/betterthansilence.de\/radio\/allesongs\/","title":{"rendered":"ALLE SONGS AUF EINEN BLICK"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Hier findet ihr alle Songs, die wir auf BETTER THAN SILENCE bisher gespielt haben.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein KLICK auf den Spaltenkopf sortiert so, wie ihr es wollt&#8230;<\/p>\n\n\n\n<style>\n  .music-container {\n    font-family: inherit;\n    font-size: var(--wp--preset--font-size--small, 0.875rem);\n    margin: 20px 0;\n  }\n  .music-stats {\n    font-size: 1em;\n    font-weight: 600;\n    margin-bottom: 10px;\n    color: var(--wp--preset--color--primary, #222222);\n  }\n  .music-search {\n    width: 100%;\n    padding: 8px 12px;\n    margin-bottom: 12px;\n    border: 1px solid #ccc;\n    border-radius: 5px;\n    font-size: inherit;\n    box-sizing: border-box;\n  }\n  .music-table {\n    width: 100%;\n    border-collapse: collapse;\n    margin-top: 10px;\n    font-size: inherit;\n  }\n  .music-table th {\n    background-color: var(--wp--preset--color--primary, #222222);\n    color: var(--wp--preset--color--white, #ffffff);\n    padding: 8px 10px;\n    text-align: left;\n    cursor: pointer;\n    user-select: none;\n  }\n  .music-table th:hover {\n    opacity: 0.9;\n  }\n  .music-table th.sort-asc::after {\n    content: \" \u25b2\";\n    font-size: 0.8em;\n  }\n  .music-table th.sort-desc::after {\n    content: \" \u25bc\";\n    font-size: 0.8em;\n  }\n  .music-table td {\n    padding: 8px 10px;\n    border-bottom: 1px solid #e0e0e0;\n  }\n  .music-table tr:nth-child(even) {\n    background-color: #f9f9f9;\n  }\n  .col-center {\n    text-align: center;\n  }\n<\/style>\n\n<div class=\"music-container\">\n  <!-- Teaser \/ Statistik-Anzeige -->\n  <div id=\"musicStats\" class=\"music-stats\">Lade Statistik&#8230;<\/div>\n\n  <input type=\"text\" id=\"musicSearch\" class=\"music-search\" placeholder=\"\ud83d\udd0d Suche nach Interpret, Titel, Album...\" onkeyup=\"filterMusicTable()\">\n\n  <table class=\"music-table\">\n    <thead>\n      <tr>\n        <th onclick=\"sortTable('title')\" id=\"th-title\">Titel<\/th>\n        <th onclick=\"sortTable('artist')\" id=\"th-artist\">Interpret<\/th>\n        <th onclick=\"sortTable('album')\" id=\"th-album\">Album<\/th>\n        <th onclick=\"sortTable('playlist')\" id=\"th-playlist\" class=\"col-center\">Sendung<\/th>\n      <\/tr>\n    <\/thead>\n    <tbody id=\"musicTableBody\">\n      <tr><td colspan=\"4\">Lade Musikbibliothek&#8230;<\/td><\/tr>\n    <\/tbody>\n  <\/table>\n<\/div>\n\n<script>\n  const csvUrl = 'https:\/\/betterthansilence.de\/wp-content\/uploads\/csv\/MyDeezerLibrary.csv';\n  \n  let globalData = [];\n  let currentSortKey = '';\n  let currentSortAsc = true;\n\n  function loadPapaParse() {\n    return new Promise((resolve, reject) => {\n      if (window.Papa) {\n        resolve();\n        return;\n      }\n      const script = document.createElement('script');\n      script.src = 'https:\/\/cdn.jsdelivr.net\/npm\/papaparse@5.4.1\/papaparse.min.js';\n      script.onload = () => resolve();\n      script.onerror = () => reject(new Error('PapaParse konnte nicht geladen werden.'));\n      document.head.appendChild(script);\n    });\n  }\n\n  function getValue(row, keys) {\n    for (let key of keys) {\n      if (row[key] !== undefined && row[key] !== null) {\n        return row[key];\n      }\n    }\n    return '';\n  }\n\n  function extractPlaylistNumber(str) {\n    if (!str) return '';\n    const match = String(str).match(\/(?:#|NI)?\\s*(\\d+)\/i);\n    return match ? parseInt(match[1], 10) : str;\n  }\n\n  \/\/ Teaser-Statistik berechnen\n  function updateStats() {\n    const totalSongs = globalData.length;\n    const sendungenSet = new Set();\n\n    globalData.forEach(row => {\n      const rawSendung = getValue(row, ['Playlist name', 'Playlist-Nummer', 'Sendung', 'Playlist']);\n      const sendungNum = extractPlaylistNumber(rawSendung);\n      if (sendungNum !== '') {\n        sendungenSet.add(sendungNum);\n      }\n    });\n\n    const totalSendungen = sendungenSet.size;\n    const statsElem = document.getElementById('musicStats');\n\n    if (totalSongs > 0) {\n      statsElem.innerHTML = `\ud83c\udfb5 <strong>${totalSongs} Songs<\/strong> aus <strong>${totalSendungen} Sendungen<\/strong>`;\n    } else {\n      statsElem.innerHTML = '';\n    }\n  }\n\n  function renderData(data) {\n    const tbody = document.getElementById('musicTableBody');\n    tbody.innerHTML = '';\n\n    if (!data || data.length === 0) {\n      tbody.innerHTML = '<tr><td colspan=\"4\">Keine Daten gefunden.<\/td><\/tr>';\n      return;\n    }\n\n    data.forEach(row => {\n      const title = getValue(row, ['Track name', 'Titel', 'Title', 'Track']);\n      const artist = getValue(row, ['Artist name', 'Interpret', 'Artist']);\n      const album = getValue(row, ['Album', 'Album name']);\n      const playlistRaw = getValue(row, ['Playlist name', 'Playlist-Nummer', 'Sendung', 'Playlist']);\n      const playlistNum = extractPlaylistNumber(playlistRaw);\n\n      if (title || artist) {\n        const tr = document.createElement('tr');\n        tr.innerHTML = `\n          <td><strong>${title}<\/strong><\/td>\n          <td>${artist}<\/td>\n          <td>${album}<\/td>\n          <td class=\"col-center\">${playlistNum}<\/td>\n        `;\n        tbody.appendChild(tr);\n      }\n    });\n\n    filterMusicTable();\n  }\n\n  function sortTable(key) {\n    if (currentSortKey === key) {\n      currentSortAsc = !currentSortAsc;\n    } else {\n      currentSortKey = key;\n      currentSortAsc = true;\n    }\n\n    document.querySelectorAll('.music-table th').forEach(th => {\n      th.classList.remove('sort-asc', 'sort-desc');\n    });\n    const activeHeader = document.getElementById('th-' + key);\n    if (activeHeader) {\n      activeHeader.classList.add(currentSortAsc ? 'sort-asc' : 'sort-desc');\n    }\n\n    globalData.sort((a, b) => {\n      let valA = '';\n      let valB = '';\n\n      if (key === 'title') {\n        valA = String(getValue(a, ['Track name', 'Titel', 'Title', 'Track'])).toLowerCase();\n        valB = String(getValue(b, ['Track name', 'Titel', 'Title', 'Track'])).toLowerCase();\n      } else if (key === 'artist') {\n        valA = String(getValue(a, ['Artist name', 'Interpret', 'Artist'])).toLowerCase();\n        valB = String(getValue(b, ['Artist name', 'Interpret', 'Artist'])).toLowerCase();\n      } else if (key === 'album') {\n        valA = String(getValue(a, ['Album', 'Album name'])).toLowerCase();\n        valB = String(getValue(b, ['Album', 'Album name'])).toLowerCase();\n      } else if (key === 'playlist') {\n        valA = extractPlaylistNumber(getValue(a, ['Playlist name', 'Playlist-Nummer', 'Sendung', 'Playlist']));\n        valB = extractPlaylistNumber(getValue(b, ['Playlist name', 'Playlist-Nummer', 'Sendung', 'Playlist']));\n        \n        if (typeof valA === 'number' && typeof valB === 'number') {\n          return currentSortAsc ? valA - valB : valB - valA;\n        }\n      }\n\n      return currentSortAsc \n        ? String(valA).localeCompare(String(valB), undefined, { numeric: true, sensitivity: 'base' }) \n        : String(valB).localeCompare(String(valA), undefined, { numeric: true, sensitivity: 'base' });\n    });\n\n    renderData(globalData);\n  }\n\n  async function initMusicTable() {\n    try {\n      await loadPapaParse();\n\n      const response = await fetch(csvUrl);\n      if (!response.ok) throw new Error('HTTP Fehler: ' + response.status);\n\n      const csvText = await response.text();\n\n      Papa.parse(csvText, {\n        header: true,\n        skipEmptyLines: true,\n        complete: function(results) {\n          \/\/ Nur Zeilen mit Mindestdaten behalten\n          globalData = results.data.filter(row => {\n            const t = getValue(row, ['Track name', 'Titel', 'Title', 'Track']);\n            const a = getValue(row, ['Artist name', 'Interpret', 'Artist']);\n            return t || a;\n          });\n\n          updateStats();\n          sortTable('artist');\n        }\n      });\n    } catch (err) {\n      console.error('Fehler beim Laden:', err);\n      document.getElementById('musicTableBody').innerHTML = \n        '<tr><td colspan=\"4\" style=\"color:red;\">Fehler beim Laden der CSV-Datei.<\/td><\/tr>';\n      document.getElementById('musicStats').innerHTML = '';\n    }\n  }\n\n  function filterMusicTable() {\n    const filter = document.getElementById('musicSearch').value.toLowerCase();\n    const rows = document.querySelectorAll('#musicTableBody tr');\n    let visibleCount = 0;\n\n    rows.forEach(row => {\n      const text = row.innerText.toLowerCase();\n      if (text.includes(filter)) {\n        row.style.display = '';\n        visibleCount++;\n      } else {\n        row.style.display = 'none';\n      }\n    });\n\n    \/\/ Teaser anpassen, falls gesucht wird\n    const statsElem = document.getElementById('musicStats');\n    if (filter.trim() !== '') {\n      statsElem.innerHTML = `\ud83d\udd0d Zeige <strong>${visibleCount} von ${globalData.length} Songs<\/strong>`;\n    } else {\n      updateStats();\n    }\n  }\n\n  initMusicTable();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Hier findet ihr alle Songs, die wir auf BETTER THAN SILENCE bisher gespielt haben. Ein KLICK auf den Spaltenkopf sortiert so, wie ihr es wollt&#8230; Lade Statistik&#8230; Titel Interpret Album Sendung Lade Musikbibliothek&#8230;<\/p>\n","protected":false},"author":1,"featured_media":49,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-1449","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-beitrag"],"_links":{"self":[{"href":"https:\/\/betterthansilence.de\/radio\/wp-json\/wp\/v2\/posts\/1449","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/betterthansilence.de\/radio\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/betterthansilence.de\/radio\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/betterthansilence.de\/radio\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/betterthansilence.de\/radio\/wp-json\/wp\/v2\/comments?post=1449"}],"version-history":[{"count":9,"href":"https:\/\/betterthansilence.de\/radio\/wp-json\/wp\/v2\/posts\/1449\/revisions"}],"predecessor-version":[{"id":1467,"href":"https:\/\/betterthansilence.de\/radio\/wp-json\/wp\/v2\/posts\/1449\/revisions\/1467"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/betterthansilence.de\/radio\/wp-json\/wp\/v2\/media\/49"}],"wp:attachment":[{"href":"https:\/\/betterthansilence.de\/radio\/wp-json\/wp\/v2\/media?parent=1449"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/betterthansilence.de\/radio\/wp-json\/wp\/v2\/categories?post=1449"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/betterthansilence.de\/radio\/wp-json\/wp\/v2\/tags?post=1449"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}