{"id":7798,"date":"2026-06-09T13:37:46","date_gmt":"2026-06-09T19:37:46","guid":{"rendered":"https:\/\/evida.ugto.mx\/catalogo\/?page_id=7798"},"modified":"2026-06-09T13:41:00","modified_gmt":"2026-06-09T19:41:00","slug":"oferta-educativa-de-microcredenciales","status":"publish","type":"page","link":"https:\/\/evida.ugto.mx\/catalogo\/oferta-educativa-de-microcredenciales\/","title":{"rendered":"Oferta Educativa de Microcredenciales"},"content":{"rendered":"\n<div class=\"wp-block-cover alignfull\" style=\"min-height:400px;aspect-ratio:unset;\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"308\" class=\"wp-block-cover__image-background wp-image-7799 size-large\" alt=\"\" src=\"https:\/\/i0.wp.com\/evida.ugto.mx\/catalogo\/wp-content\/uploads\/sites\/5\/2026\/06\/microcredenciales.jpg?resize=1024%2C308&#038;ssl=1\" data-object-fit=\"cover\" srcset=\"https:\/\/i0.wp.com\/evida.ugto.mx\/catalogo\/wp-content\/uploads\/sites\/5\/2026\/06\/microcredenciales-scaled.jpg?resize=1024%2C308&amp;ssl=1 1024w, https:\/\/i0.wp.com\/evida.ugto.mx\/catalogo\/wp-content\/uploads\/sites\/5\/2026\/06\/microcredenciales-scaled.jpg?resize=300%2C90&amp;ssl=1 300w, https:\/\/i0.wp.com\/evida.ugto.mx\/catalogo\/wp-content\/uploads\/sites\/5\/2026\/06\/microcredenciales-scaled.jpg?resize=768%2C231&amp;ssl=1 768w, https:\/\/i0.wp.com\/evida.ugto.mx\/catalogo\/wp-content\/uploads\/sites\/5\/2026\/06\/microcredenciales-scaled.jpg?resize=1536%2C461&amp;ssl=1 1536w, https:\/\/i0.wp.com\/evida.ugto.mx\/catalogo\/wp-content\/uploads\/sites\/5\/2026\/06\/microcredenciales-scaled.jpg?resize=2048%2C615&amp;ssl=1 2048w, https:\/\/i0.wp.com\/evida.ugto.mx\/catalogo\/wp-content\/uploads\/sites\/5\/2026\/06\/microcredenciales-scaled.jpg?w=2400&amp;ssl=1 2400w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><span aria-hidden=\"true\" class=\"wp-block-cover__background has-background-dim-30 has-background-dim\" style=\"background-color:#546056\"><\/span><div class=\"wp-block-cover__inner-container is-layout-flow wp-block-cover-is-layout-flow\">\n<h2 class=\"wp-block-heading has-text-align-center has-nv-site-bg-color has-text-color has-link-color has-x-large-font-size wp-elements-a1e6a5a882af11408b0c3635aff8d6be\"><strong>Oferta educativa de microcredenciales<\/strong><\/h2>\n<\/div><\/div>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-text-align-center has-text-color has-link-color wp-elements-e509b6ba9b180199fa032fe65b411242 wp-block-paragraph\" style=\"color:#8c6e39;font-size:35px\"><strong>Introducci\u00f3n<\/strong><\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">Impulsa tu perfil profesional. Valida tus competencias y conocimientos con nuestras microcrendeciales oficiales. Programas dise\u00f1ados para fortalecer tu trayectoria, brind\u00e1ndote el respaldo institucional necesario para destacar en el competitivo mercado laboral actual.<\/p>\n\n\n\n<style>\n  :root {\n    --primary: #0f6cbd;\n    --primary-dark: #0b5aa0;\n    --primary-soft: #eaf4ff;\n    --text: #1f2937;\n    --text-soft: #6b7280;\n    --border: #e5e7eb;\n    --bg: #f5f7fb;\n    --white: #ffffff;\n    --shadow-sm: 0 4px 10px rgba(15, 23, 42, 0.06);\n    --shadow-md: 0 12px 30px rgba(15, 23, 42, 0.10);\n    --radius: 18px;\n  }\n\n  \/* --- Estilos Generales --- *\/\n  body {\n    background: linear-gradient(180deg, #f8fafc 0%, #f3f6fb 100%);\n  }\n\n  #directorio-app {\n    font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n    max-width: 1180px;\n    margin: 0 auto;\n    padding: 20px 16px 40px;\n    color: var(--text);\n    min-height: 400px;\n  }\n\n  \/* --- Barra Superior --- *\/\n  #top-bar {\n    background: rgba(255, 255, 255, 0.92);\n    backdrop-filter: blur(8px);\n    padding: 18px 20px;\n    border-radius: 20px;\n    border: 1px solid rgba(229, 231, 235, 0.9);\n    box-shadow: var(--shadow-sm);\n    margin-bottom: 32px;\n    display: flex;\n    flex-wrap: wrap;\n    gap: 16px;\n    align-items: center;\n    justify-content: space-between;\n  }\n\n  .nav-group {\n    display: flex;\n    align-items: center;\n    gap: 12px;\n  }\n\n  #top-bar-title {\n    margin: 0;\n    font-size: 1.25rem !important;\n    font-weight: 700;\n    color: var(--text) !important;\n    letter-spacing: -0.02em;\n  }\n\n  \/* Bot\u00f3n Volver *\/\n  #btn-back {\n    display: none;\n    background: var(--white);\n    border: 1px solid var(--border);\n    padding: 10px 16px;\n    border-radius: 12px;\n    cursor: pointer;\n    font-weight: 600;\n    color: var(--text-soft);\n    transition: all 0.25s ease;\n    box-shadow: 0 2px 6px rgba(0,0,0,0.04);\n  }\n\n  #btn-back:hover {\n    background: #f8fafc;\n    color: var(--text);\n    transform: translateY(-1px);\n  }\n\n  \/* Buscador *\/\n  .search-box {\n    display: flex;\n    gap: 0;\n    flex: 1;\n    max-width: 520px;\n    min-width: 260px;\n  }\n\n  .search-input {\n    flex: 1;\n    padding: 14px 16px;\n    border: 1px solid var(--border);\n    border-right: none;\n    border-radius: 14px 0 0 14px;\n    font-size: 0.98rem;\n    outline: none;\n    background: #fff;\n    color: var(--text);\n    transition: all 0.2s ease;\n  }\n\n  .search-input::placeholder {\n    color: #9ca3af;\n  }\n\n  .search-input:focus {\n    border-color: var(--primary);\n    box-shadow: inset 0 1px 2px rgba(0,0,0,0.03);\n  }\n\n  .search-btn {\n    padding: 14px 22px;\n    background: linear-gradient(135deg, var(--primary) 0%, #1380d8 100%);\n    color: white;\n    border: 1px solid var(--primary);\n    border-radius: 0 14px 14px 0;\n    cursor: pointer;\n    font-weight: 700;\n    transition: all 0.25s ease;\n  }\n\n  .search-btn:hover {\n    background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary) 100%);\n    transform: translateY(-1px);\n  }\n\n  \/* --- Vista categor\u00edas --- *\/\n  #categories-view {\n    display: block;\n  }\n\n  .grid-container {\n    display: grid;\n    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));\n    gap: 22px;\n  }\n\n  .cat-card {\n    background: linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);\n    border: 1px solid var(--border);\n    border-radius: 22px;\n    padding: 28px 22px;\n    text-align: center;\n    cursor: pointer;\n    transition: all 0.28s ease;\n    box-shadow: var(--shadow-sm);\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n    align-items: center;\n    min-height: 180px;\n    position: relative;\n    overflow: hidden;\n  }\n\n  .cat-card::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    background: radial-gradient(circle at top right, rgba(15,108,189,0.08), transparent 35%);\n    pointer-events: none;\n  }\n\n  .cat-card:hover {\n    transform: translateY(-6px);\n    box-shadow: var(--shadow-md);\n    border-color: #cfe4f8;\n  }\n\n  .cat-icon {\n    width: 64px;\n    height: 64px;\n    border-radius: 18px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    font-size: 2rem;\n    margin-bottom: 16px;\n    background: linear-gradient(135deg, var(--primary-soft) 0%, #dbeafe 100%);\n    color: var(--primary);\n    box-shadow: inset 0 1px 0 rgba(255,255,255,0.7);\n  }\n\n  .cat-name {\n    font-weight: 700;\n    font-size: 1.1rem;\n    color: var(--text);\n    line-height: 1.35;\n    max-width: 90%;\n    letter-spacing: -0.01em;\n  }\n\n  .cat-count {\n    margin-top: 12px;\n    font-size: 0.86rem;\n    color: var(--primary);\n    background: var(--primary-soft);\n    padding: 6px 12px;\n    border-radius: 999px;\n    font-weight: 600;\n    border: 1px solid #d7e9fb;\n  }\n\n  \/* --- Vista de entradas --- *\/\n  #posts-view {\n    display: none;\n  }\n\n  .view-title {\n    font-size: 1.6rem;\n    font-weight: 800;\n    margin-bottom: 22px;\n    padding-bottom: 12px;\n    border-bottom: 1px solid var(--border);\n    color: var(--text);\n    letter-spacing: -0.02em;\n  }\n\n  .post-card {\n    background: #ffffff;\n    border: 1px solid var(--border);\n    border-left: 5px solid var(--primary);\n    padding: 20px 22px;\n    margin-bottom: 16px;\n    border-radius: 16px;\n    transition: all 0.22s ease;\n    box-shadow: var(--shadow-sm);\n  }\n\n  .post-card:hover {\n    transform: translateY(-2px);\n    box-shadow: var(--shadow-md);\n    background: #fcfeff;\n  }\n\n  .post-title a {\n    text-decoration: none;\n    color: var(--text);\n    font-size: 1.1rem;\n    font-weight: 700;\n    line-height: 1.4;\n    transition: color 0.2s ease;\n  }\n\n  .post-title a:hover {\n    color: var(--primary);\n  }\n\n  .post-meta {\n    margin-top: 10px;\n    font-size: 0.92rem;\n    color: var(--text-soft);\n  }\n\n  .post-meta strong {\n    color: var(--primary);\n    font-weight: 700;\n  }\n\n  \/* --- Loader y paginaci\u00f3n --- *\/\n  .loader-container {\n    text-align: center;\n    padding: 48px 20px;\n    color: var(--text-soft);\n    width: 100%;\n    background: #fff;\n    border-radius: 18px;\n    border: 1px solid var(--border);\n    box-shadow: var(--shadow-sm);\n  }\n\n  .spinner {\n    border: 4px solid #e5e7eb;\n    border-top: 4px solid var(--primary);\n    border-radius: 50%;\n    width: 42px;\n    height: 42px;\n    animation: spin 1s linear infinite;\n    margin: 0 auto 16px auto;\n  }\n\n  @keyframes spin {\n    0% { transform: rotate(0deg); }\n    100% { transform: rotate(360deg); }\n  }\n\n  #pagination {\n    display: flex;\n    justify-content: center;\n    gap: 12px;\n    margin-top: 30px;\n    align-items: center;\n    flex-wrap: wrap;\n  }\n\n  .page-btn {\n    padding: 10px 16px;\n    border: 1px solid #cfe0f2;\n    background: #fff;\n    color: var(--primary);\n    border-radius: 12px;\n    cursor: pointer;\n    font-weight: 700;\n    transition: all 0.2s ease;\n    box-shadow: 0 2px 6px rgba(0,0,0,0.04);\n  }\n\n  .page-btn:disabled {\n    border-color: #e5e7eb;\n    color: #b5bcc7;\n    background: #f9fafb;\n    cursor: not-allowed;\n    box-shadow: none;\n  }\n\n  .page-btn:hover:not(:disabled) {\n    background: var(--primary-soft);\n    transform: translateY(-1px);\n  }\n\n  #page-indicator {\n    font-size: 0.95rem;\n    color: var(--text-soft);\n    font-weight: 600;\n    padding: 0 6px;\n  }\n\n  \/* --- Responsive --- *\/\n  @media (max-width: 768px) {\n    #directorio-app {\n      padding: 14px 12px 30px;\n    }\n\n    #top-bar {\n      padding: 16px;\n      border-radius: 18px;\n    }\n\n    .search-box {\n      max-width: 100%;\n      width: 100%;\n    }\n\n    .grid-container {\n      grid-template-columns: 1fr;\n      gap: 16px;\n    }\n\n    .cat-card {\n      min-height: 160px;\n      padding: 24px 18px;\n    }\n\n    .view-title {\n      font-size: 1.35rem;\n    }\n  }\n<\/style>\n\n<div id=\"directorio-app\">\n\n  <!-- Barra Superior -->\n  <div id=\"top-bar\">\n    <div class=\"nav-group\">\n      <button id=\"btn-back\" title=\"Volver a las categor\u00edas\">\u2190 Volver al Directorio<\/button>\n      <h3 style=\"margin:0; font-size:1.1rem; color:#555;\" id=\"top-bar-title\">Directorio de programas<\/h3>\n    <\/div>\n\n    <div class=\"search-box\">\n      <input type=\"text\" id=\"global-search\" class=\"search-input\" placeholder=\"Buscar programa...\">\n      <button id=\"btn-search-trigger\" class=\"search-btn\">Buscar<\/button>\n    <\/div>\n  <\/div>\n\n  <!-- VISTA 1: GRID CATEGOR\u00cdAS -->\n  <div id=\"categories-view\">\n    <div id=\"cat-grid\" class=\"grid-container\">\n      <div class=\"loader-container\">\n        <div class=\"spinner\"><\/div>\n        <p>Analizando cat\u00e1logo de cursos&#8230;<\/p>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <!-- VISTA 2: LISTA DE ENTRADAS -->\n  <div id=\"posts-view\">\n    <h2 id=\"results-title\" class=\"view-title\">Resultados<\/h2>\n    <div id=\"posts-list\">\n      <!-- Aqu\u00ed se inyectan las entradas -->\n    <\/div>\n    \n    <div id=\"pagination\" style=\"display:none;\">\n      <button id=\"prev-btn\" class=\"page-btn\">Anterior<\/button>\n      <span id=\"page-indicator\">P\u00e1gina 1<\/span>\n      <button id=\"next-btn\" class=\"page-btn\">Siguiente<\/button>\n    <\/div>\n  <\/div>\n\n<\/div>\n\n<script>\ndocument.addEventListener('DOMContentLoaded', function() {\n\n  \/\/ --- 1. CONFIGURACI\u00d3N ---\n  const config = {\n    baseUrl: '\/catalogo',       \/\/ URL base de tu sitio WordPress\n    taxonomy: 'tipo',      \/\/ Slug exacto de la taxonom\u00eda\n    termId: 56,                 \/\/ ID del t\u00e9rmino\n    perPage: 15                 \/\/ Entradas por p\u00e1gina\n  };\n\n  \/\/ --- 2. ESTADO GLOBAL ---\n  let state = {\n    view: 'categories', \n    currentCategoryName: '',\n    currentCategoryId: '',\n    searchTerm: '',\n    page: 1,\n    totalPages: 1,\n    localCategoryCounts: {} \n  };\n\n  \/\/ --- 3. REFERENCIAS DOM ---\n  const els = {\n    backBtn: document.getElementById('btn-back'),\n    topTitle: document.getElementById('top-bar-title'),\n    searchInput: document.getElementById('global-search'),\n    searchBtn: document.getElementById('btn-search-trigger'),\n    catView: document.getElementById('categories-view'),\n    catGrid: document.getElementById('cat-grid'),\n    postView: document.getElementById('posts-view'),\n    postList: document.getElementById('posts-list'),\n    resultsTitle: document.getElementById('results-title'),\n    pagination: document.getElementById('pagination'),\n    prevBtn: document.getElementById('prev-btn'),\n    nextBtn: document.getElementById('next-btn'),\n    pageInd: document.getElementById('page-indicator')\n  };\n\n  \/\/ --- 4. INICIALIZACI\u00d3N ---\n  init();\n\n  function init() {\n    initCategories();\n    setupEventListeners();\n  }\n\n  function setupEventListeners() {\n    els.searchBtn.addEventListener('click', () => performSearch());\n    els.searchInput.addEventListener('keypress', (e) => {\n      if(e.key === 'Enter') performSearch();\n    });\n    els.backBtn.addEventListener('click', () => {\n      switchView('categories');\n      els.searchInput.value = '';\n    });\n    els.prevBtn.addEventListener('click', () => changePage(-1));\n    els.nextBtn.addEventListener('click', () => changePage(1));\n  }\n\n  function switchView(viewName) {\n    state.view = viewName;\n    if (viewName === 'categories') {\n      els.catView.style.display = 'block';\n      els.postView.style.display = 'none';\n      els.backBtn.style.display = 'none';\n      els.topTitle.textContent = 'Directorio de Cursos';\n      state.currentCategoryId = '';\n      state.searchTerm = '';\n    } else {\n      els.catView.style.display = 'none';\n      els.postView.style.display = 'block';\n      els.backBtn.style.display = 'inline-block';\n    }\n  }\n\n  \/\/ --- 6. L\u00d3GICA DE CONTEO REAL (BLINDADA) ---\n  \n  async function initCategories() {\n    try {\n      \/\/ Paso A: Escanear TODOS los posts pidiendo expl\u00edcitamente el campo de la taxonom\u00eda\n      const allCategoryIds = await fetchAllInstanceCategoryIds();\n      \n      if (allCategoryIds.length === 0) {\n        els.catGrid.innerHTML = `\n          <div style=\"text-align:center; color:#666; grid-column: 1 \/ -1;\">\n            <p>No se encontraron programas.<\/p>\n            <small style=\"color:#999;\">Nota: Aseg\u00farese de que la taxonom\u00eda <b>'${config.taxonomy}'<\/b> tiene activado 'Show in REST API' en WordPress.<\/small>\n          <\/div>`;\n        return;\n      }\n\n      \/\/ Paso B: Calcular conteo local\n      const counts = {};\n      allCategoryIds.forEach(id => {\n        counts[id] = (counts[id] || 0) + 1;\n      });\n      state.localCategoryCounts = counts;\n\n      const uniqueIds = Object.keys(counts);\n      const categoriesDetails = await fetchCategoriesDetails(uniqueIds);\n      \n      renderCategories(categoriesDetails);\n\n    } catch (error) {\n      console.error(error);\n      els.catGrid.innerHTML = '<p style=\"text-align:center; color:red;\">Error de conexi\u00f3n con el cat\u00e1logo.<\/p>';\n    }\n  }\n\n  async function fetchAllInstanceCategoryIds() {\n    let allIds = [];\n    let page = 1;\n    let hasMore = true;\n    const taxField = config.taxonomy; \/\/ 'modalidad'\n\n    \/\/ Pedimos el campo 'modalidad' (o el nombre de la tax) expl\u00edcitamente en _fields\n    while (hasMore) {\n      const response = await fetch(`${config.baseUrl}\/wp-json\/wp\/v2\/posts?${config.taxonomy}=${config.termId}&per_page=100&page=${page}&_fields=categories,${taxField}`);\n      \n      if (!response.ok) break; \n\n      const posts = await response.json();\n      if (posts.length === 0) break;\n\n      posts.forEach(p => {\n        \/\/ --- FILTRO ESTRICTO ---\n        \/\/ Si la API devuelve un post pero este NO tiene el ID 16 en su campo 'modalidad',\n        \/\/ significa que la API ignor\u00f3 el filtro. Lo descartamos manualmente.\n        if (p[taxField]) {\n            \/\/ Si el campo existe, verificamos que incluya nuestro ID (16)\n            if (!p[taxField].includes(config.termId)) {\n                return; \/\/ Ignorar este post intruso\n            }\n        } else {\n            \/\/ Si el campo NO viene en la respuesta, no podemos confiar en este post.\n            \/\/ Probablemente la taxonom\u00eda no est\u00e1 expuesta en REST API.\n            \/\/ Lo descartamos para no inflar n\u00fameros falsos.\n            return; \n        }\n\n        \/\/ Si pas\u00f3 el filtro, guardamos sus categor\u00edas\n        if (p.categories) {\n           allIds.push(...p.categories);\n        }\n      });\n\n      const totalPages = parseInt(response.headers.get('X-WP-TotalPages') || '1');\n      if (page >= totalPages) hasMore = false;\n      else page++;\n    }\n    return allIds;\n  }\n\n  async function fetchCategoriesDetails(ids) {\n    const idsString = ids.slice(0, 100).join(','); \n    const response = await fetch(`${config.baseUrl}\/wp-json\/wp\/v2\/categories?include=${idsString}&per_page=100`);\n    if (!response.ok) throw new Error('Error fetching category details');\n    return await response.json();\n  }\n\n  function renderCategories(cats) {\n    cats.sort((a,b) => a.name.localeCompare(b.name));\n    els.catGrid.innerHTML = '';\n    \n    cats.forEach(cat => {\n      const realCount = state.localCategoryCounts[cat.id] || 0;\n      const card = document.createElement('div');\n      card.className = 'cat-card';\n      card.innerHTML = `\n        <div class=\"cat-icon\">\ud83d\udcc2<\/div>\n        <div class=\"cat-name\">${cat.name}<\/div>\n        <div class=\"cat-count\">${realCount} programas<\/div>\n      `;\n      card.addEventListener('click', () => {\n        state.currentCategoryId = cat.id;\n        state.currentCategoryName = cat.name;\n        state.searchTerm = '';\n        state.page = 1;\n        loadPosts();\n      });\n      els.catGrid.appendChild(card);\n    });\n  }\n\n  function performSearch() {\n    const term = els.searchInput.value.trim();\n    if (!term) return; \n    state.searchTerm = term;\n    state.currentCategoryId = ''; \n    state.page = 1;\n    loadPosts();\n  }\n\n  function changePage(delta) {\n    state.page += delta;\n    loadPosts();\n  }\n\n  \/\/ --- 7. CARGA DE CURSOS (Con Filtro Visual) ---\n  function loadPosts() {\n    switchView('posts');\n    els.postList.innerHTML = `<div class=\"loader-container\"><div class=\"spinner\"><\/div><p>Cargando programas...<\/p><\/div>`;\n    \n    if (state.searchTerm) els.resultsTitle.textContent = `Resultados para: \"${state.searchTerm}\"`;\n    else if (state.currentCategoryName) els.resultsTitle.textContent = `Categor\u00eda: ${state.currentCategoryName}`;\n    else els.resultsTitle.textContent = 'Todos los programas';\n\n    const containerTop = document.getElementById('directorio-app').offsetTop;\n    window.scrollTo({ top: containerTop - 20, behavior: 'smooth' });\n\n    let url = `${config.baseUrl}\/wp-json\/wp\/v2\/posts?`;\n    url += `${config.taxonomy}=${config.termId}`; \n    url += `&per_page=${config.perPage}`;\n    url += `&page=${state.page}`;\n    url += `&_embed`; \/\/ Trae todos los datos para mostrar\n\n    if (state.currentCategoryId) url += `&categories=${state.currentCategoryId}`;\n    if (state.searchTerm) url += `&search=${encodeURIComponent(state.searchTerm)}`;\n\n    fetch(url)\n      .then(res => {\n        if (!res.ok) {\n           if(state.page > 1) { state.page = 1; return loadPosts(); }\n           throw new Error('Error al obtener datos');\n        }\n        const totalPages = res.headers.get('X-WP-TotalPages');\n        state.totalPages = totalPages ? parseInt(totalPages) : 1;\n        return res.json();\n      })\n      .then(posts => {\n        \/\/ Filtro visual extra: Si la API falla en filtrar, lo hacemos aqu\u00ed tambi\u00e9n\n        \/\/ (Nota: _embed a veces oculta el campo ra\u00edz, as\u00ed que confiamos en el conteo inicial,\n        \/\/ pero si se cuela algo muy obvio tratamos de filtrarlo si el campo est\u00e1 disponible)\n        const validPosts = posts.filter(p => {\n            if (p[config.taxonomy] && Array.isArray(p[config.taxonomy])) {\n                return p[config.taxonomy].includes(config.termId);\n            }\n            return true; \/\/ Si no podemos verificar en esta vista detallada, lo mostramos.\n        });\n        \n        renderPosts(validPosts);\n        updatePagination();\n      })\n      .catch(err => {\n        console.warn(err);\n        els.postList.innerHTML = `<div class=\"loader-container\"><p>\u26a0\ufe0f No se encontraron programas.<\/p><button class=\"page-btn\" onclick=\"document.getElementById('btn-back').click()\">Volver<\/button><\/div>`;\n        els.pagination.style.display = 'none';\n      });\n  }\n\n  function renderPosts(posts) {\n    if (!posts || posts.length === 0) {\n      els.postList.innerHTML = '<p style=\"text-align:center;\">No hay resultados.<\/p>';\n      return;\n    }\n\n    let html = '';\n    posts.forEach(post => {\n      let duracion = '';\n      if (post.acf && post.acf.duracion) duracion = ` \u2022 \u23f1 ${post.acf.duracion}`;\n      \n      let catName = '';\n      if (post._embedded && post._embedded['wp:term']) {\n        const terms = post._embedded['wp:term'].flat();\n        const cat = terms.find(t => t.taxonomy === 'category');\n        if (cat) catName = cat.name;\n      }\n\n      html += `\n        <div class=\"post-card\">\n          <div class=\"post-title\"><a href=\"${post.link}\">${post.title.rendered}<\/a><\/div>\n          <div class=\"post-meta\">${catName ? `<strong>${catName}<\/strong>` : ''} ${duracion}<\/div>\n        <\/div>\n      `;\n    });\n    els.postList.innerHTML = html;\n  }\n\n  function updatePagination() {\n    if (state.totalPages > 1) {\n      els.pagination.style.display = 'flex';\n      els.pageInd.textContent = `P\u00e1gina ${state.page} de ${state.totalPages}`;\n      els.prevBtn.disabled = (state.page <= 1);\n      els.nextBtn.disabled = (state.page >= state.totalPages);\n    } else {\n      els.pagination.style.display = 'none';\n    }\n  }\n});\n<\/script>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading has-text-align-center has-text-color has-link-color wp-elements-15c6da49d53e5890f1c12abc391a7467\" style=\"color:#8c6e39\">Cont\u00e1ctanos<\/h2>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">\u00bfTienes dudas o comentarios sobre nuestra oferta educativa? El \u00e1rea de Educaci\u00f3n Continua del Ecosistema VIDA UG est\u00e1 aqu\u00ed para ayudarte. Llena el siguiente formulario y nos pondremos en contacto contigo a la brevedad:<\/p>\n\n\n\n<div class=\"wp-block-contact-form-7-contact-form-selector aligncenter\">\n<div class=\"wpcf7 no-js\" id=\"wpcf7-f5562-o1\" lang=\"es-ES\" dir=\"ltr\" data-wpcf7-id=\"5562\">\n<div class=\"screen-reader-response\"><p role=\"status\" aria-live=\"polite\" aria-atomic=\"true\"><\/p> <ul><\/ul><\/div>\n<form action=\"\/catalogo\/wp-json\/wp\/v2\/pages\/7798#wpcf7-f5562-o1\" method=\"post\" class=\"wpcf7-form init\" aria-label=\"Formulario de contacto\" novalidate=\"novalidate\" data-status=\"init\">\n<fieldset class=\"hidden-fields-container\"><input type=\"hidden\" name=\"_wpcf7\" value=\"5562\" \/><input type=\"hidden\" name=\"_wpcf7_version\" value=\"6.1.6\" \/><input type=\"hidden\" name=\"_wpcf7_locale\" value=\"es_ES\" \/><input type=\"hidden\" name=\"_wpcf7_unit_tag\" value=\"wpcf7-f5562-o1\" \/><input type=\"hidden\" name=\"_wpcf7_container_post\" value=\"0\" \/><input type=\"hidden\" name=\"_wpcf7_posted_data_hash\" value=\"\" \/><input type=\"hidden\" name=\"_wpcf7_recaptcha_response\" value=\"\" \/>\n<\/fieldset>\n<p><label> Tu nombre<br \/>\n<span class=\"wpcf7-form-control-wrap\" data-name=\"your-name\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text wpcf7-validates-as-required\" autocomplete=\"name\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"your-name\" \/><\/span> <\/label>\n<\/p>\n<p><label> Tu correo electr\u00f3nico<br \/>\n<span class=\"wpcf7-form-control-wrap\" data-name=\"your-email\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-email wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-email\" autocomplete=\"email\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"email\" name=\"your-email\" \/><\/span> <\/label>\n<\/p>\n<p><label> Asunto<br \/>\n<span class=\"wpcf7-form-control-wrap\" data-name=\"your-subject\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text wpcf7-validates-as-required\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"your-subject\" \/><\/span> <\/label>\n<\/p>\n<p><label> Tu mensaje (opcional)<br \/>\n<span class=\"wpcf7-form-control-wrap\" data-name=\"your-message\"><textarea cols=\"40\" rows=\"10\" maxlength=\"2000\" class=\"wpcf7-form-control wpcf7-textarea\" aria-invalid=\"false\" name=\"your-message\"><\/textarea><\/span> <\/label>\n<\/p>\n<p><input class=\"wpcf7-form-control wpcf7-submit has-spinner\" type=\"submit\" value=\"Enviar\" \/>\n<\/p><p style=\"display: none !important;\" class=\"akismet-fields-container\" data-prefix=\"_wpcf7_ak_\"><label>&#916;<textarea name=\"_wpcf7_ak_hp_textarea\" cols=\"45\" rows=\"8\" maxlength=\"100\"><\/textarea><\/label><input type=\"hidden\" id=\"ak_js_1\" name=\"_wpcf7_ak_js\" value=\"160\"\/><script data-jetpack-boost=\"ignore\">\ndocument.getElementById( \"ak_js_1\" ).setAttribute( \"value\", ( new Date() ).getTime() );\n<\/script>\n<\/p><div class=\"wpcf7-response-output\" aria-hidden=\"true\"><\/div>\n<\/form>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Introducci\u00f3n Impulsa tu perfil profesional. Valida tus competencias y conocimientos con nuestras microcrendeciales oficiales. Programas dise\u00f1ados para fortalecer tu trayectoria, brind\u00e1ndote el respaldo institucional necesario para destacar en el competitivo mercado laboral actual. \u2190 Volver al Directorio Directorio de programas Buscar Analizando cat\u00e1logo de cursos&#8230; Resultados Anterior P\u00e1gina 1 Siguiente Cont\u00e1ctanos \u00bfTienes dudas o comentarios&hellip;&nbsp;<a href=\"https:\/\/evida.ugto.mx\/catalogo\/oferta-educativa-de-microcredenciales\/\" rel=\"bookmark\">Leer m\u00e1s &raquo;<span class=\"screen-reader-text\">Oferta Educativa de Microcredenciales<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"neve_meta_sidebar":"full-width","neve_meta_container":"default","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"on","footnotes":""},"class_list":["post-7798","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/evida.ugto.mx\/catalogo\/wp-json\/wp\/v2\/pages\/7798","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/evida.ugto.mx\/catalogo\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/evida.ugto.mx\/catalogo\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/evida.ugto.mx\/catalogo\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/evida.ugto.mx\/catalogo\/wp-json\/wp\/v2\/comments?post=7798"}],"version-history":[{"count":1,"href":"https:\/\/evida.ugto.mx\/catalogo\/wp-json\/wp\/v2\/pages\/7798\/revisions"}],"predecessor-version":[{"id":7802,"href":"https:\/\/evida.ugto.mx\/catalogo\/wp-json\/wp\/v2\/pages\/7798\/revisions\/7802"}],"wp:attachment":[{"href":"https:\/\/evida.ugto.mx\/catalogo\/wp-json\/wp\/v2\/media?parent=7798"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}