{"id":99,"date":"2026-07-28T17:42:48","date_gmt":"2026-07-28T17:42:48","guid":{"rendered":"https:\/\/germany-iptvpro.de\/blog\/?page_id=99"},"modified":"2026-07-28T17:50:46","modified_gmt":"2026-07-28T17:50:46","slug":"germany-iptv-pro-redaktion","status":"publish","type":"page","link":"https:\/\/germany-iptvpro.de\/blog\/germany-iptv-pro-redaktion\/","title":{"rendered":"Germany IPTV Pro Redaktion"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"99\" class=\"elementor elementor-99\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d8ce016 e-con-full e-flex e-con e-parent\" data-id=\"d8ce016\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d16a7b6 elementor-widget elementor-widget-html\" data-id=\"d16a7b6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!--\r\n=========================================================\r\nGERMANY IPTV PRO \u2014 DYNAMIC AUTHOR PAGE\r\nAdd this entire code inside one Elementor \"HTML\" widget.\r\n\r\nTarget page:\r\nhttps:\/\/germany-iptvpro.de\/blog\/germany-iptv-pro-redaktion\/\r\n\r\nImportant:\r\n- Elementor Page Layout: Full Width\r\n- Hide the default WordPress page title\r\n- The code detects WordPress under \/blog\/ automatically and falls back to the root REST API.\r\n- It can find the author by slug, display name or embedded post author data.\r\n=========================================================\r\n-->\r\n\r\n<style>\r\n  #gip-author-page,\r\n  #gip-author-page * {\r\n    box-sizing: border-box;\r\n  }\r\n\r\n  #gip-author-page {\r\n    --gip-black: #111111;\r\n    --gip-red: #d71920;\r\n    --gip-red-dark: #a90f14;\r\n    --gip-gold: #f4c95d;\r\n    --gip-navy: #172033;\r\n    --gip-text: #2b3445;\r\n    --gip-muted: #667085;\r\n    --gip-line: #e7e9ee;\r\n    --gip-soft: #f7f8fa;\r\n    --gip-white: #ffffff;\r\n    width: 100%;\r\n    max-width: 1180px;\r\n    margin: 0 auto;\r\n    padding: 28px 18px 72px;\r\n    color: var(--gip-text);\r\n    background: var(--gip-white);\r\n    font-family: Inter, Arial, Helvetica, sans-serif;\r\n    font-size: 17px;\r\n    line-height: 1.65;\r\n  }\r\n\r\n  #gip-author-page a {\r\n    color: inherit;\r\n  }\r\n\r\n  .gip-author-breadcrumbs {\r\n    margin: 0 0 24px;\r\n    color: var(--gip-muted);\r\n    font-size: 14px;\r\n  }\r\n\r\n  .gip-author-breadcrumbs a {\r\n    color: var(--gip-muted);\r\n    text-decoration: none;\r\n  }\r\n\r\n  .gip-author-breadcrumbs a:hover {\r\n    color: var(--gip-red);\r\n  }\r\n\r\n  .gip-author-profile {\r\n    position: relative;\r\n    overflow: hidden;\r\n    display: grid;\r\n    grid-template-columns: 150px minmax(0, 1fr);\r\n    gap: 30px;\r\n    align-items: center;\r\n    padding: 38px;\r\n    border: 1px solid var(--gip-line);\r\n    border-radius: 28px;\r\n    background:\r\n      radial-gradient(circle at 90% 8%, rgba(244, 201, 93, 0.22), transparent 34%),\r\n      linear-gradient(135deg, #ffffff, #fafafa);\r\n    box-shadow: 0 18px 55px rgba(15, 23, 42, 0.08);\r\n  }\r\n\r\n  .gip-author-profile::before {\r\n    content: \"\";\r\n    position: absolute;\r\n    inset: 0 auto 0 0;\r\n    width: 7px;\r\n    background: linear-gradient(\r\n      180deg,\r\n      var(--gip-black) 0 33.333%,\r\n      var(--gip-red) 33.333% 66.666%,\r\n      var(--gip-gold) 66.666% 100%\r\n    );\r\n  }\r\n\r\n  .gip-author-avatar {\r\n    overflow: hidden;\r\n    display: grid;\r\n    width: 140px;\r\n    height: 140px;\r\n    place-items: center;\r\n    border: 5px solid var(--gip-white);\r\n    border-radius: 28px;\r\n    background:\r\n      radial-gradient(circle at 32% 25%, rgba(244, 201, 93, 0.32), transparent 38%),\r\n      linear-gradient(145deg, #111111, #2b2b2b);\r\n    color: #ffffff;\r\n    box-shadow: 0 14px 35px rgba(15, 23, 42, 0.16);\r\n  }\r\n\r\n  .gip-author-avatar img {\r\n    display: block;\r\n    width: 100%;\r\n    height: 100%;\r\n    object-fit: cover;\r\n  }\r\n\r\n  .gip-author-avatar-fallback {\r\n    display: grid;\r\n    width: 76px;\r\n    height: 76px;\r\n    place-items: center;\r\n    border: 2px solid rgba(255, 255, 255, 0.22);\r\n    border-radius: 50%;\r\n    background: rgba(255, 255, 255, 0.08);\r\n    color: #ffffff;\r\n  }\r\n\r\n  .gip-author-human-icon {\r\n    display: block;\r\n    width: 46px;\r\n    height: 46px;\r\n    fill: none;\r\n    stroke: currentColor;\r\n    stroke-width: 1.8;\r\n    stroke-linecap: round;\r\n    stroke-linejoin: round;\r\n  }\r\n\r\n  .gip-author-kicker {\r\n    display: inline-flex;\r\n    align-items: center;\r\n    gap: 8px;\r\n    margin-bottom: 10px;\r\n    color: var(--gip-red-dark);\r\n    font-size: 13px;\r\n    font-weight: 800;\r\n    letter-spacing: 0.05em;\r\n    text-transform: uppercase;\r\n  }\r\n\r\n  .gip-author-kicker::before {\r\n    content: \"\";\r\n    width: 24px;\r\n    height: 4px;\r\n    border-radius: 999px;\r\n    background: linear-gradient(\r\n      90deg,\r\n      var(--gip-black) 0 33%,\r\n      var(--gip-red) 33% 66%,\r\n      var(--gip-gold) 66% 100%\r\n    );\r\n  }\r\n\r\n  #gip-author-title {\r\n    margin: 0;\r\n    color: var(--gip-navy);\r\n    font-size: clamp(34px, 5vw, 56px);\r\n    line-height: 1.08;\r\n    letter-spacing: -0.035em;\r\n  }\r\n\r\n  .gip-author-bio {\r\n    max-width: 800px;\r\n    margin: 17px 0 0;\r\n    color: #465269;\r\n    font-size: 18px;\r\n  }\r\n\r\n  .gip-author-stats {\r\n    display: flex;\r\n    flex-wrap: wrap;\r\n    gap: 10px;\r\n    margin-top: 20px;\r\n  }\r\n\r\n  .gip-author-stat {\r\n    display: inline-flex;\r\n    align-items: center;\r\n    min-height: 38px;\r\n    padding: 8px 13px;\r\n    border: 1px solid var(--gip-line);\r\n    border-radius: 999px;\r\n    background: var(--gip-white);\r\n    color: var(--gip-navy);\r\n    font-size: 14px;\r\n    font-weight: 800;\r\n  }\r\n\r\n  .gip-author-section-head {\r\n    display: flex;\r\n    flex-wrap: wrap;\r\n    justify-content: space-between;\r\n    gap: 15px;\r\n    align-items: end;\r\n    margin: 54px 0 24px;\r\n  }\r\n\r\n  .gip-author-section-head h2 {\r\n    margin: 0;\r\n    color: var(--gip-navy);\r\n    font-size: clamp(28px, 4vw, 40px);\r\n    line-height: 1.18;\r\n    letter-spacing: -0.025em;\r\n  }\r\n\r\n  .gip-author-section-head p {\r\n    margin: 6px 0 0;\r\n    color: var(--gip-muted);\r\n  }\r\n\r\n  .gip-author-grid {\r\n    display: grid;\r\n    grid-template-columns: repeat(3, minmax(0, 1fr));\r\n    gap: 24px;\r\n  }\r\n\r\n  .gip-author-card {\r\n    overflow: hidden;\r\n    display: flex;\r\n    flex-direction: column;\r\n    min-width: 0;\r\n    border: 1px solid var(--gip-line);\r\n    border-radius: 21px;\r\n    background: var(--gip-white);\r\n    box-shadow: 0 10px 30px rgba(15, 23, 42, 0.06);\r\n    transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;\r\n  }\r\n\r\n  .gip-author-card:hover {\r\n    transform: translateY(-4px);\r\n    border-color: rgba(215, 25, 32, 0.3);\r\n    box-shadow: 0 18px 42px rgba(15, 23, 42, 0.11);\r\n  }\r\n\r\n  .gip-author-card-media {\r\n    position: relative;\r\n    display: block;\r\n    overflow: hidden;\r\n    aspect-ratio: 16 \/ 9;\r\n    background:\r\n      linear-gradient(135deg, rgba(17, 17, 17, 0.95), rgba(215, 25, 32, 0.82));\r\n    text-decoration: none;\r\n  }\r\n\r\n  .gip-author-card-media img {\r\n    display: block;\r\n    width: 100%;\r\n    height: 100%;\r\n    object-fit: cover;\r\n    transition: transform 0.3s ease;\r\n  }\r\n\r\n  .gip-author-card:hover .gip-author-card-media img {\r\n    transform: scale(1.035);\r\n  }\r\n\r\n  .gip-author-placeholder {\r\n    display: grid;\r\n    width: 100%;\r\n    height: 100%;\r\n    place-items: center;\r\n    color: #ffffff;\r\n    font-size: 30px;\r\n    font-weight: 900;\r\n    letter-spacing: 0.08em;\r\n  }\r\n\r\n  .gip-author-card-body {\r\n    display: flex;\r\n    flex: 1;\r\n    flex-direction: column;\r\n    padding: 21px;\r\n  }\r\n\r\n  .gip-author-card-meta {\r\n    display: flex;\r\n    flex-wrap: wrap;\r\n    gap: 7px 10px;\r\n    margin-bottom: 12px;\r\n    color: var(--gip-muted);\r\n    font-size: 13px;\r\n  }\r\n\r\n  .gip-author-category {\r\n    color: var(--gip-red-dark);\r\n    font-weight: 800;\r\n  }\r\n\r\n  .gip-author-card h3 {\r\n    margin: 0;\r\n    color: var(--gip-navy);\r\n    font-size: 22px;\r\n    line-height: 1.3;\r\n    letter-spacing: -0.015em;\r\n  }\r\n\r\n  .gip-author-card h3 a {\r\n    color: inherit;\r\n    text-decoration: none;\r\n  }\r\n\r\n  .gip-author-card-excerpt {\r\n    margin: 13px 0 18px;\r\n    color: #536078;\r\n    font-size: 15px;\r\n  }\r\n\r\n  .gip-author-read-more {\r\n    display: inline-flex;\r\n    align-items: center;\r\n    gap: 8px;\r\n    margin-top: auto;\r\n    color: var(--gip-red) !important;\r\n    font-weight: 800;\r\n    text-decoration: none;\r\n  }\r\n\r\n  .gip-author-read-more::after {\r\n    content: \"\u2192\";\r\n    transition: transform 0.2s ease;\r\n  }\r\n\r\n  .gip-author-read-more:hover::after {\r\n    transform: translateX(4px);\r\n  }\r\n\r\n  .gip-author-loading,\r\n  .gip-author-empty,\r\n  .gip-author-error {\r\n    padding: 28px;\r\n    border: 1px solid var(--gip-line);\r\n    border-radius: 18px;\r\n    background: var(--gip-soft);\r\n    color: var(--gip-text);\r\n    text-align: center;\r\n  }\r\n\r\n  .gip-author-loader {\r\n    display: inline-block;\r\n    width: 34px;\r\n    height: 34px;\r\n    margin-bottom: 12px;\r\n    border: 4px solid #e5e7eb;\r\n    border-top-color: var(--gip-red);\r\n    border-radius: 50%;\r\n    animation: gip-author-spin 0.8s linear infinite;\r\n  }\r\n\r\n  @keyframes gip-author-spin {\r\n    to { transform: rotate(360deg); }\r\n  }\r\n\r\n  .gip-author-pagination {\r\n    display: flex;\r\n    flex-wrap: wrap;\r\n    justify-content: center;\r\n    gap: 8px;\r\n    margin-top: 38px;\r\n  }\r\n\r\n  .gip-author-page-btn {\r\n    display: grid;\r\n    min-width: 42px;\r\n    height: 42px;\r\n    place-items: center;\r\n    padding: 0 12px;\r\n    border: 1px solid var(--gip-line);\r\n    border-radius: 11px;\r\n    background: var(--gip-white);\r\n    color: var(--gip-navy);\r\n    font: inherit;\r\n    font-weight: 800;\r\n    cursor: pointer;\r\n  }\r\n\r\n  .gip-author-page-btn:hover,\r\n  .gip-author-page-btn.is-active {\r\n    border-color: var(--gip-red);\r\n    background: var(--gip-red);\r\n    color: #ffffff;\r\n  }\r\n\r\n  .gip-author-page-btn:disabled {\r\n    cursor: not-allowed;\r\n    opacity: 0.45;\r\n  }\r\n\r\n  .gip-author-cta {\r\n    margin-top: 50px;\r\n    padding: 32px;\r\n    border-radius: 24px;\r\n    background:\r\n      radial-gradient(circle at 12% 15%, rgba(244, 201, 93, 0.22), transparent 35%),\r\n      linear-gradient(135deg, #111111, #252525);\r\n    color: #ffffff;\r\n    text-align: center;\r\n  }\r\n\r\n  .gip-author-cta h2 {\r\n    margin: 0 0 10px;\r\n    color: #ffffff;\r\n    font-size: clamp(26px, 4vw, 38px);\r\n  }\r\n\r\n  .gip-author-cta p {\r\n    max-width: 700px;\r\n    margin: 0 auto 20px;\r\n    color: #ececec;\r\n  }\r\n\r\n  .gip-author-btn {\r\n    display: inline-flex;\r\n    align-items: center;\r\n    justify-content: center;\r\n    min-height: 48px;\r\n    padding: 12px 20px;\r\n    border-radius: 12px;\r\n    background: var(--gip-red);\r\n    color: #ffffff !important;\r\n    font-weight: 800;\r\n    text-decoration: none;\r\n    box-shadow: 0 8px 22px rgba(215, 25, 32, 0.3);\r\n    transition: transform 0.2s ease;\r\n  }\r\n\r\n  .gip-author-btn:hover {\r\n    transform: translateY(-2px);\r\n  }\r\n\r\n  @media (max-width: 940px) {\r\n    .gip-author-grid {\r\n      grid-template-columns: repeat(2, minmax(0, 1fr));\r\n    }\r\n  }\r\n\r\n  @media (max-width: 700px) {\r\n    #gip-author-page {\r\n      padding: 18px 13px 54px;\r\n    }\r\n\r\n    .gip-author-profile {\r\n      grid-template-columns: 1fr;\r\n      padding: 28px 22px;\r\n      text-align: center;\r\n    }\r\n\r\n    .gip-author-avatar {\r\n      margin: 0 auto;\r\n    }\r\n\r\n    .gip-author-kicker,\r\n    .gip-author-stats {\r\n      justify-content: center;\r\n    }\r\n\r\n    .gip-author-grid {\r\n      grid-template-columns: 1fr;\r\n    }\r\n\r\n    .gip-author-section-head {\r\n      align-items: start;\r\n    }\r\n  }\r\n<\/style>\r\n\r\n<main id=\"gip-author-page\">\r\n  <nav class=\"gip-author-breadcrumbs\" aria-label=\"Breadcrumb\">\r\n    <a href=\"https:\/\/germany-iptvpro.de\/\">Startseite<\/a>\r\n    <span aria-hidden=\"true\"> \u203a <\/span>\r\n    <a href=\"https:\/\/germany-iptvpro.de\/blog\/\">Ratgeber<\/a>\r\n    <span aria-hidden=\"true\"> \u203a <\/span>\r\n    <span>Germany IPTV Pro Redaktion<\/span>\r\n  <\/nav>\r\n\r\n  <header class=\"gip-author-profile\">\r\n    <div class=\"gip-author-avatar\" id=\"gip-author-avatar\" aria-hidden=\"true\">\r\n      <span class=\"gip-author-avatar-fallback\" aria-hidden=\"true\">\r\n        <svg class=\"gip-author-human-icon\" viewBox=\"0 0 24 24\" role=\"img\" aria-label=\"Autor\">\r\n          <circle cx=\"12\" cy=\"8\" r=\"4\"><\/circle>\r\n          <path d=\"M4.5 20c.8-4.1 3.3-6.2 7.5-6.2s6.7 2.1 7.5 6.2\"><\/path>\r\n        <\/svg>\r\n      <\/span>\r\n    <\/div>\r\n\r\n    <div>\r\n      <div class=\"gip-author-kicker\">Autor & Redaktion<\/div>\r\n      <h1 id=\"gip-author-title\">Germany IPTV Pro Redaktion<\/h1>\r\n      <p class=\"gip-author-bio\" id=\"gip-author-bio\">\r\n        Die Germany IPTV Pro Redaktion ver\u00f6ffentlicht verst\u00e4ndliche und praxisnahe Ratgeber\r\n        zu IPTV-Einrichtung, Ger\u00e4ten, Playern, Streaming-Qualit\u00e4t und Fehlerbehebung.\r\n      <\/p>\r\n\r\n      <div class=\"gip-author-stats\" aria-label=\"Redaktionsinformationen\">\r\n        <span class=\"gip-author-stat\" id=\"gip-author-post-count\">Beitr\u00e4ge werden geladen<\/span>\r\n        <span class=\"gip-author-stat\">IPTV Einrichtung & Ger\u00e4te<\/span>\r\n        <span class=\"gip-author-stat\">Apps, Qualit\u00e4t & Fehlerbehebung<\/span>\r\n      <\/div>\r\n    <\/div>\r\n  <\/header>\r\n\r\n  <section aria-labelledby=\"gip-author-articles-title\">\r\n    <div class=\"gip-author-section-head\">\r\n      <div>\r\n        <h2 id=\"gip-author-articles-title\">Alle Beitr\u00e4ge der Redaktion<\/h2>\r\n        <p>Automatisch nach Ver\u00f6ffentlichungsdatum sortiert.<\/p>\r\n      <\/div>\r\n    <\/div>\r\n\r\n    <div id=\"gip-author-status\" class=\"gip-author-loading\" role=\"status\" aria-live=\"polite\">\r\n      <span class=\"gip-author-loader\" aria-hidden=\"true\"><\/span>\r\n      <div>Beitr\u00e4ge werden geladen\u2026<\/div>\r\n    <\/div>\r\n\r\n    <div id=\"gip-author-grid\" class=\"gip-author-grid\" hidden><\/div>\r\n    <nav id=\"gip-author-pagination\" class=\"gip-author-pagination\" aria-label=\"Seitennavigation\" hidden><\/nav>\r\n  <\/section>\r\n\r\n  <section class=\"gip-author-cta\" aria-label=\"Germany IPTV Pro Kontakt\">\r\n    <h2>Frage zu einem IPTV-Ratgeber?<\/h2>\r\n    <p>\r\n      Senden Sie uns Ihr Ger\u00e4t, die verwendete App und eine kurze Beschreibung.\r\n      So k\u00f6nnen wir Ihre Frage schneller einordnen.\r\n    <\/p>\r\n    <a\r\n      class=\"gip-author-btn\"\r\n      href=\"https:\/\/wa.me\/33644656029?text=Hallo%2C%20ich%20komme%20%C3%BCber%20germany-iptvpro.de%20%E2%80%93%20Seite%3A%20Germany%20IPTV%20Pro%20Redaktion.%20Meine%20Frage%3A%20___.\"\r\n      target=\"_blank\"\r\n      rel=\"noopener noreferrer\"\r\n    >\r\n      WhatsApp \u00f6ffnen\r\n    <\/a>\r\n  <\/section>\r\n<\/main>\r\n\r\n<script>\r\n(function () {\r\n  \"use strict\";\r\n\r\n  const CONFIG = {\r\n    siteUrl: window.location.origin,\r\n    apiBases: [\r\n      window.location.origin + \"\/blog\/wp-json\/wp\/v2\",\r\n      window.location.origin + \"\/wp-json\/wp\/v2\"\r\n    ],\r\n    authorSlug: \"germany-iptv-pro-redaktion\",\r\n    authorDisplayName: \"Germany IPTV Pro Redaktion\",\r\n    postsPerPage: 9,\r\n    locale: \"de-DE\"\r\n  };\r\n\r\n  const state = {\r\n    apiBase: null,\r\n    authorId: null,\r\n    currentPage: 1,\r\n    totalPages: 1,\r\n    totalPosts: 0\r\n  };\r\n\r\n  const elements = {\r\n    title: document.getElementById(\"gip-author-title\"),\r\n    bio: document.getElementById(\"gip-author-bio\"),\r\n    avatar: document.getElementById(\"gip-author-avatar\"),\r\n    count: document.getElementById(\"gip-author-post-count\"),\r\n    status: document.getElementById(\"gip-author-status\"),\r\n    grid: document.getElementById(\"gip-author-grid\"),\r\n    pagination: document.getElementById(\"gip-author-pagination\")\r\n  };\r\n\r\n  function decodeHtml(value) {\r\n    const textarea = document.createElement(\"textarea\");\r\n    textarea.innerHTML = value || \"\";\r\n    return textarea.value;\r\n  }\r\n\r\n  function stripHtml(value) {\r\n    const temp = document.createElement(\"div\");\r\n    temp.innerHTML = value || \"\";\r\n    return (temp.textContent || temp.innerText || \"\").trim();\r\n  }\r\n\r\n  function trimText(value, maxLength) {\r\n    const text = String(value || \"\").trim();\r\n    if (text.length <= maxLength) return text;\r\n    return text.slice(0, maxLength).trimEnd() + \"\u2026\";\r\n  }\r\n\r\n  function getInitials(name) {\r\n    return String(name || \"GIP\")\r\n      .split(\/\\s+\/)\r\n      .filter(Boolean)\r\n      .slice(0, 3)\r\n      .map(part => part.charAt(0).toUpperCase())\r\n      .join(\"\");\r\n  }\r\n\r\n  function setStatus(type, message) {\r\n    elements.status.className =\r\n      type === \"error\"\r\n        ? \"gip-author-error\"\r\n        : type === \"empty\"\r\n          ? \"gip-author-empty\"\r\n          : \"gip-author-loading\";\r\n\r\n    elements.status.innerHTML = \"\";\r\n\r\n    if (type === \"loading\") {\r\n      const loader = document.createElement(\"span\");\r\n      loader.className = \"gip-author-loader\";\r\n      loader.setAttribute(\"aria-hidden\", \"true\");\r\n      elements.status.appendChild(loader);\r\n    }\r\n\r\n    const text = document.createElement(\"div\");\r\n    text.textContent = message;\r\n    elements.status.appendChild(text);\r\n    elements.status.hidden = false;\r\n  }\r\n\r\n  function setAvatar(author) {\r\n    const avatarUrls = author && author.avatar_urls ? author.avatar_urls : {};\r\n    const avatarUrl =\r\n      avatarUrls[\"192\"] ||\r\n      avatarUrls[\"96\"] ||\r\n      avatarUrls[\"48\"] ||\r\n      \"\";\r\n\r\n    elements.avatar.innerHTML = \"\";\r\n\r\n    if (avatarUrl) {\r\n      const image = document.createElement(\"img\");\r\n      image.src = avatarUrl;\r\n      image.alt = author.name || CONFIG.authorDisplayName;\r\n      image.width = 280;\r\n      image.height = 280;\r\n      image.loading = \"eager\";\r\n      image.decoding = \"async\";\r\n      elements.avatar.appendChild(image);\r\n      elements.avatar.removeAttribute(\"aria-hidden\");\r\n      return;\r\n    }\r\n\r\n    const fallback = document.createElement(\"span\");\r\n    fallback.className = \"gip-author-avatar-fallback\";\r\n    fallback.setAttribute(\"aria-hidden\", \"true\");\r\n    fallback.innerHTML =\r\n      '<svg class=\"gip-author-human-icon\" viewBox=\"0 0 24 24\" role=\"img\" aria-label=\"Autor\">' +\r\n      '<circle cx=\"12\" cy=\"8\" r=\"4\"><\/circle>' +\r\n      '<path d=\"M4.5 20c.8-4.1 3.3-6.2 7.5-6.2s6.7 2.1 7.5 6.2\"><\/path>' +\r\n      '<\/svg>';\r\n    elements.avatar.appendChild(fallback);\r\n  }\r\n\r\n  async function fetchJson(url) {\r\n    const response = await fetch(url, {\r\n      method: \"GET\",\r\n      credentials: \"same-origin\",\r\n      headers: { \"Accept\": \"application\/json\" }\r\n    });\r\n\r\n    if (!response.ok) {\r\n      throw new Error(\"HTTP \" + response.status);\r\n    }\r\n\r\n    return {\r\n      data: await response.json(),\r\n      headers: response.headers\r\n    };\r\n  }\r\n\r\n  async function discoverAuthorFromPosts(apiBase) {\r\n    const url =\r\n      apiBase +\r\n      \"\/posts?status=publish&per_page=100&page=1&_embed=author&orderby=date&order=desc\";\r\n\r\n    const result = await fetchJson(url);\r\n\r\n    if (!Array.isArray(result.data)) {\r\n      return null;\r\n    }\r\n\r\n    const expectedName = CONFIG.authorDisplayName.toLowerCase();\r\n    const expectedSlug = CONFIG.authorSlug.toLowerCase();\r\n\r\n    for (const post of result.data) {\r\n      const embedded = post && post._embedded ? post._embedded : {};\r\n      const authors = embedded.author;\r\n\r\n      if (!Array.isArray(authors) || !authors.length) {\r\n        continue;\r\n      }\r\n\r\n      const author = authors[0];\r\n      const name = String(author.name || \"\").toLowerCase();\r\n      const slug = String(author.slug || \"\").toLowerCase();\r\n\r\n      if (name === expectedName || slug === expectedSlug) {\r\n        return author;\r\n      }\r\n    }\r\n\r\n    return null;\r\n  }\r\n\r\n  async function resolveAuthorAtBase(apiBase) {\r\n    try {\r\n      const bySlugUrl =\r\n        apiBase +\r\n        \"\/users?slug=\" +\r\n        encodeURIComponent(CONFIG.authorSlug) +\r\n        \"&per_page=1\";\r\n\r\n      const bySlug = await fetchJson(bySlugUrl);\r\n\r\n      if (Array.isArray(bySlug.data) && bySlug.data.length) {\r\n        return bySlug.data[0];\r\n      }\r\n    } catch (error) {\r\n      console.warn(\"Author slug lookup failed:\", apiBase, error);\r\n    }\r\n\r\n    try {\r\n      const bySearchUrl =\r\n        apiBase +\r\n        \"\/users?search=\" +\r\n        encodeURIComponent(CONFIG.authorDisplayName) +\r\n        \"&per_page=100\";\r\n\r\n      const bySearch = await fetchJson(bySearchUrl);\r\n\r\n      const exactMatch = Array.isArray(bySearch.data)\r\n        ? bySearch.data.find(\r\n            user =>\r\n              String(user.name || \"\").toLowerCase() ===\r\n              CONFIG.authorDisplayName.toLowerCase()\r\n          )\r\n        : null;\r\n\r\n      if (exactMatch) {\r\n        return exactMatch;\r\n      }\r\n    } catch (error) {\r\n      console.warn(\"Author name lookup failed:\", apiBase, error);\r\n    }\r\n\r\n    try {\r\n      return await discoverAuthorFromPosts(apiBase);\r\n    } catch (error) {\r\n      console.warn(\"Embedded author discovery failed:\", apiBase, error);\r\n      return null;\r\n    }\r\n  }\r\n\r\n  async function resolveAuthor() {\r\n    for (const apiBase of CONFIG.apiBases) {\r\n      const author = await resolveAuthorAtBase(apiBase);\r\n\r\n      if (author && author.id) {\r\n        state.apiBase = apiBase;\r\n        return author;\r\n      }\r\n    }\r\n\r\n    throw new Error(\"Author not found in available REST API paths\");\r\n  }\r\n\r\n  function getFeaturedImage(post) {\r\n    const embedded = post && post._embedded ? post._embedded : {};\r\n    const media = embedded[\"wp:featuredmedia\"];\r\n\r\n    if (Array.isArray(media) && media[0] && media[0].source_url) {\r\n      return {\r\n        url: media[0].source_url,\r\n        alt:\r\n          media[0].alt_text ||\r\n          decodeHtml(post.title && post.title.rendered ? post.title.rendered : \"\")\r\n      };\r\n    }\r\n\r\n    return null;\r\n  }\r\n\r\n  function getCategoryName(post) {\r\n    const embedded = post && post._embedded ? post._embedded : {};\r\n    const terms = embedded[\"wp:term\"];\r\n\r\n    if (!Array.isArray(terms)) return \"IPTV Ratgeber\";\r\n\r\n    for (const group of terms) {\r\n      if (!Array.isArray(group)) continue;\r\n      const category = group.find(term => term && term.taxonomy === \"category\");\r\n      if (category && category.name) return decodeHtml(category.name);\r\n    }\r\n\r\n    return \"IPTV Ratgeber\";\r\n  }\r\n\r\n  function createPostCard(post) {\r\n    const article = document.createElement(\"article\");\r\n    article.className = \"gip-author-card\";\r\n\r\n    const title = decodeHtml(\r\n      post.title && post.title.rendered ? post.title.rendered : \"IPTV Ratgeber\"\r\n    );\r\n\r\n    const permalink = post.link || \"#\";\r\n    const featured = getFeaturedImage(post);\r\n    const category = getCategoryName(post);\r\n\r\n    const date = new Date(post.date);\r\n    const formattedDate = Number.isNaN(date.getTime())\r\n      ? \"\"\r\n      : new Intl.DateTimeFormat(CONFIG.locale, {\r\n          day: \"2-digit\",\r\n          month: \"2-digit\",\r\n          year: \"numeric\"\r\n        }).format(date);\r\n\r\n    const excerptSource =\r\n      post.excerpt && post.excerpt.rendered\r\n        ? stripHtml(post.excerpt.rendered)\r\n        : \"\";\r\n\r\n    const excerpt = trimText(excerptSource, 155);\r\n\r\n    const mediaLink = document.createElement(\"a\");\r\n    mediaLink.className = \"gip-author-card-media\";\r\n    mediaLink.href = permalink;\r\n    mediaLink.setAttribute(\"aria-label\", title);\r\n\r\n    if (featured) {\r\n      const image = document.createElement(\"img\");\r\n      image.src = featured.url;\r\n      image.alt = featured.alt || title;\r\n      image.width = 720;\r\n      image.height = 405;\r\n      image.loading = \"lazy\";\r\n      image.decoding = \"async\";\r\n      mediaLink.appendChild(image);\r\n    } else {\r\n      const placeholder = document.createElement(\"span\");\r\n      placeholder.className = \"gip-author-placeholder\";\r\n      placeholder.textContent = \"IPTV\";\r\n      placeholder.setAttribute(\"aria-hidden\", \"true\");\r\n      mediaLink.appendChild(placeholder);\r\n    }\r\n\r\n    const body = document.createElement(\"div\");\r\n    body.className = \"gip-author-card-body\";\r\n\r\n    const meta = document.createElement(\"div\");\r\n    meta.className = \"gip-author-card-meta\";\r\n\r\n    const categoryElement = document.createElement(\"span\");\r\n    categoryElement.className = \"gip-author-category\";\r\n    categoryElement.textContent = category;\r\n    meta.appendChild(categoryElement);\r\n\r\n    if (formattedDate) {\r\n      const separator = document.createElement(\"span\");\r\n      separator.textContent = \"\u2022\";\r\n      separator.setAttribute(\"aria-hidden\", \"true\");\r\n      meta.appendChild(separator);\r\n\r\n      const time = document.createElement(\"time\");\r\n      time.dateTime = post.date;\r\n      time.textContent = formattedDate;\r\n      meta.appendChild(time);\r\n    }\r\n\r\n    const heading = document.createElement(\"h3\");\r\n    const titleLink = document.createElement(\"a\");\r\n    titleLink.href = permalink;\r\n    titleLink.textContent = title;\r\n    heading.appendChild(titleLink);\r\n\r\n    const excerptElement = document.createElement(\"p\");\r\n    excerptElement.className = \"gip-author-card-excerpt\";\r\n    excerptElement.textContent =\r\n      excerpt || \"Praktischer IPTV-Ratgeber der Germany IPTV Pro Redaktion.\";\r\n\r\n    const readMore = document.createElement(\"a\");\r\n    readMore.className = \"gip-author-read-more\";\r\n    readMore.href = permalink;\r\n    readMore.textContent = \"Ratgeber lesen\";\r\n\r\n    body.appendChild(meta);\r\n    body.appendChild(heading);\r\n    body.appendChild(excerptElement);\r\n    body.appendChild(readMore);\r\n\r\n    article.appendChild(mediaLink);\r\n    article.appendChild(body);\r\n\r\n    return article;\r\n  }\r\n\r\n  function renderPosts(posts) {\r\n    elements.grid.innerHTML = \"\";\r\n\r\n    if (!Array.isArray(posts) || posts.length === 0) {\r\n      elements.grid.hidden = true;\r\n      elements.pagination.hidden = true;\r\n      setStatus(\"empty\", \"Noch wurden keine Beitr\u00e4ge dieser Redaktion ver\u00f6ffentlicht.\");\r\n      return;\r\n    }\r\n\r\n    const fragment = document.createDocumentFragment();\r\n\r\n    posts.forEach(post => {\r\n      fragment.appendChild(createPostCard(post));\r\n    });\r\n\r\n    elements.grid.appendChild(fragment);\r\n    elements.status.hidden = true;\r\n    elements.grid.hidden = false;\r\n  }\r\n\r\n  function createPageButton(label, page, isActive, disabled, ariaLabel) {\r\n    const button = document.createElement(\"button\");\r\n    button.type = \"button\";\r\n    button.className = \"gip-author-page-btn\" + (isActive ? \" is-active\" : \"\");\r\n    button.textContent = label;\r\n    button.disabled = Boolean(disabled);\r\n    button.setAttribute(\"aria-label\", ariaLabel || (\"Seite \" + page));\r\n\r\n    if (isActive) {\r\n      button.setAttribute(\"aria-current\", \"page\");\r\n    }\r\n\r\n    button.addEventListener(\"click\", function () {\r\n      if (!disabled && page !== state.currentPage) {\r\n        loadPosts(page);\r\n      }\r\n    });\r\n\r\n    return button;\r\n  }\r\n\r\n  function renderPagination() {\r\n    elements.pagination.innerHTML = \"\";\r\n\r\n    if (state.totalPages <= 1) {\r\n      elements.pagination.hidden = true;\r\n      return;\r\n    }\r\n\r\n    const previous = createPageButton(\r\n      \"\u2190\",\r\n      state.currentPage - 1,\r\n      false,\r\n      state.currentPage === 1,\r\n      \"Vorherige Seite\"\r\n    );\r\n\r\n    elements.pagination.appendChild(previous);\r\n\r\n    const pages = [];\r\n    const start = Math.max(1, state.currentPage - 2);\r\n    const end = Math.min(state.totalPages, state.currentPage + 2);\r\n\r\n    if (start > 1) pages.push(1);\r\n    if (start > 2) pages.push(\"\u2026\");\r\n\r\n    for (let page = start; page <= end; page += 1) {\r\n      pages.push(page);\r\n    }\r\n\r\n    if (end < state.totalPages - 1) pages.push(\"\u2026\");\r\n    if (end < state.totalPages) pages.push(state.totalPages);\r\n\r\n    pages.forEach(item => {\r\n      if (item === \"\u2026\") {\r\n        const ellipsis = document.createElement(\"span\");\r\n        ellipsis.className = \"gip-author-page-btn\";\r\n        ellipsis.textContent = \"\u2026\";\r\n        ellipsis.setAttribute(\"aria-hidden\", \"true\");\r\n        elements.pagination.appendChild(ellipsis);\r\n        return;\r\n      }\r\n\r\n      elements.pagination.appendChild(\r\n        createPageButton(\r\n          String(item),\r\n          item,\r\n          item === state.currentPage,\r\n          false,\r\n          \"Seite \" + item\r\n        )\r\n      );\r\n    });\r\n\r\n    const next = createPageButton(\r\n      \"\u2192\",\r\n      state.currentPage + 1,\r\n      false,\r\n      state.currentPage === state.totalPages,\r\n      \"N\u00e4chste Seite\"\r\n    );\r\n\r\n    elements.pagination.appendChild(next);\r\n    elements.pagination.hidden = false;\r\n  }\r\n\r\n  async function loadPosts(page) {\r\n    setStatus(\"loading\", \"Beitr\u00e4ge werden geladen\u2026\");\r\n    elements.grid.hidden = true;\r\n    elements.pagination.hidden = true;\r\n\r\n    if (!state.apiBase) {\r\n      throw new Error(\"REST API base is not resolved\");\r\n    }\r\n\r\n    const url =\r\n      state.apiBase +\r\n      \"\/posts?author=\" +\r\n      encodeURIComponent(state.authorId) +\r\n      \"&status=publish\" +\r\n      \"&_embed=1\" +\r\n      \"&per_page=\" +\r\n      encodeURIComponent(CONFIG.postsPerPage) +\r\n      \"&page=\" +\r\n      encodeURIComponent(page) +\r\n      \"&orderby=date&order=desc\";\r\n\r\n    try {\r\n      const result = await fetchJson(url);\r\n\r\n      state.currentPage = page;\r\n      state.totalPosts = Number(result.headers.get(\"X-WP-Total\")) || result.data.length;\r\n      state.totalPages = Number(result.headers.get(\"X-WP-TotalPages\")) || 1;\r\n\r\n      elements.count.textContent =\r\n        state.totalPosts === 1\r\n          ? \"1 ver\u00f6ffentlichter Ratgeber\"\r\n          : state.totalPosts + \" ver\u00f6ffentlichte Ratgeber\";\r\n\r\n      renderPosts(result.data);\r\n      renderPagination();\r\n\r\n      if (page > 1) {\r\n        document\r\n          .getElementById(\"gip-author-articles-title\")\r\n          .scrollIntoView({ behavior: \"smooth\", block: \"start\" });\r\n      }\r\n    } catch (error) {\r\n      console.error(\"Germany IPTV Pro author posts error:\", error);\r\n      elements.grid.hidden = true;\r\n      elements.pagination.hidden = true;\r\n      setStatus(\r\n        \"error\",\r\n        \"Die Beitr\u00e4ge konnten momentan nicht geladen werden. Bitte laden Sie die Seite erneut.\"\r\n      );\r\n    }\r\n  }\r\n\r\n  async function init() {\r\n    try {\r\n      const author = await resolveAuthor();\r\n\r\n      state.authorId = author.id;\r\n\r\n      elements.title.textContent = author.name || CONFIG.authorDisplayName;\r\n\r\n      const description = stripHtml(author.description || \"\");\r\n      if (description) {\r\n        elements.bio.textContent = description;\r\n      }\r\n\r\n      setAvatar(author);\r\n      await loadPosts(1);\r\n    } catch (error) {\r\n      console.error(\"Germany IPTV Pro author page error:\", error);\r\n      elements.count.textContent = \"Redaktionsprofil\";\r\n      setStatus(\r\n        \"error\",\r\n        \"Die Beitr\u00e4ge konnten nicht automatisch geladen werden. Pr\u00fcfen Sie, ob die ver\u00f6ffentlichten Blogs als Autor \u201eGermany IPTV Pro Redaktion\u201c verwenden und ob die WordPress REST API aktiv ist.\"\r\n      );\r\n    }\r\n  }\r\n\r\n  init();\r\n})();\r\n<\/script>\r\n\r\n<script type=\"application\/ld+json\">\r\n{\r\n  \"@context\": \"https:\/\/schema.org\",\r\n  \"@type\": \"ProfilePage\",\r\n  \"@id\": \"https:\/\/germany-iptvpro.de\/blog\/germany-iptv-pro-redaktion\/#profilepage\",\r\n  \"url\": \"https:\/\/germany-iptvpro.de\/blog\/germany-iptv-pro-redaktion\/\",\r\n  \"name\": \"Germany IPTV Pro Redaktion\",\r\n  \"description\": \"Die Germany IPTV Pro Redaktion ver\u00f6ffentlicht verst\u00e4ndliche und praxisnahe Ratgeber zu IPTV-Einrichtung, Ger\u00e4ten, Playern, Streaming-Qualit\u00e4t und Fehlerbehebung.\",\r\n  \"mainEntity\": {\r\n    \"@type\": \"Organization\",\r\n    \"@id\": \"https:\/\/germany-iptvpro.de\/#redaktion\",\r\n    \"name\": \"Germany IPTV Pro Redaktion\",\r\n    \"url\": \"https:\/\/germany-iptvpro.de\/blog\/germany-iptv-pro-redaktion\/\"\r\n  },\r\n  \"isPartOf\": {\r\n    \"@type\": \"WebSite\",\r\n    \"@id\": \"https:\/\/germany-iptvpro.de\/#website\",\r\n    \"url\": \"https:\/\/germany-iptvpro.de\/\",\r\n    \"name\": \"Germany IPTV Pro\"\r\n  }\r\n}\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Startseite \u203a Ratgeber \u203a Germany IPTV Pro Redaktion Autor &#038; Redaktion Germany IPTV Pro Redaktion Die Germany IPTV Pro Redaktion ver\u00f6ffentlicht verst\u00e4ndliche und praxisnahe\u2026<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"footnotes":""},"class_list":["post-99","page","type-page","status-publish","hentry"],"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/germany-iptvpro.de\/blog\/wp-json\/wp\/v2\/pages\/99","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/germany-iptvpro.de\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/germany-iptvpro.de\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/germany-iptvpro.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/germany-iptvpro.de\/blog\/wp-json\/wp\/v2\/comments?post=99"}],"version-history":[{"count":7,"href":"https:\/\/germany-iptvpro.de\/blog\/wp-json\/wp\/v2\/pages\/99\/revisions"}],"predecessor-version":[{"id":107,"href":"https:\/\/germany-iptvpro.de\/blog\/wp-json\/wp\/v2\/pages\/99\/revisions\/107"}],"wp:attachment":[{"href":"https:\/\/germany-iptvpro.de\/blog\/wp-json\/wp\/v2\/media?parent=99"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}