is_main_query()) return; if (!function_exists('pll_current_language') || !function_exists('pll_get_post')) return; // Solo actuar cuando WP cree que está en el home/front page if (!$query->is_home() && !$query->is_front_page()) return; $lang = pll_current_language(); if (!$lang || $lang === 'es') return; $translated_id = pll_get_post(26542, $lang); if (!$translated_id) return; // Forzar carga de la página traducida como si fuera la portada estática $query->set('page_id', $translated_id); $query->set('post_type', 'page'); $query->is_home = false; $query->is_front_page = true; $query->is_singular = true; $query->is_page = true; }, 1); // Asegura que option_page_on_front devuelve la página traducida al idioma actual // (necesario para is_front_page() y para que el template FSE lo reconozca) add_filter('option_page_on_front', function($value) { if (!function_exists('pll_current_language') || !function_exists('pll_get_post')) return $value; static $running = false; if ($running) return $value; // evitar recursión $running = true; $lang = pll_current_language(); $running = false; if (!$lang || $lang === 'es') return $value; $translated = pll_get_post((int) $value, $lang); return $translated ?: $value; }); // ── Traducir links de categoría "Esta semana" / "Semana pasada" al idioma actual ─ // Las categorías traducidas EN/FR/IT/PT dan 404 (bug WP_Tax_Query AND 0=1 con Polylang). // Solución: redirigir ES cat URL → post traducido directamente (no a la categoría). // Para "Otras semanas" (cartas-de-otras-semanas, count=729): se deja como está. add_action('wp_footer', function() { if (!function_exists('pll_current_language') || !function_exists('pll_get_post')) return; $lang = pll_current_language(); if (!$lang || $lang === 'es') return; global $wpdb; $map = []; // Categorías de carta única (count=1) → redirigir al post traducido $single_carta_cats = [ 'cartasemana' => 6, 'carta-semana-pasada' => 22, ]; foreach ($single_carta_cats as $slug => $es_cat_id) { // term_taxonomy_id de la categoría ES (bypassa Polylang) $tt_id = (int) $wpdb->get_var($wpdb->prepare( "SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy='category'", $es_cat_id )); if (!$tt_id) continue; // Post ES más reciente en esa categoría $es_post_id = (int) $wpdb->get_var($wpdb->prepare( "SELECT p.ID FROM {$wpdb->posts} p JOIN {$wpdb->term_relationships} tr ON p.ID=tr.object_id WHERE tr.term_taxonomy_id=%d AND p.post_status='publish' ORDER BY p.post_date DESC LIMIT 1", $tt_id )); if (!$es_post_id) continue; // Post traducido $trans_id = pll_get_post($es_post_id, $lang); if (!$trans_id) continue; $trans_url = get_permalink($trans_id); if ($trans_url) { $map[home_url('/category/' . $slug . '/')] = $trans_url; } } if (empty($map)) return; ?> 'group_user_foto_perfil', 'title' => 'Foto de perfil', 'fields' => [[ 'key' => 'field_user_foto_perfil', 'label' => 'Foto', 'name' => 'foto_perfil', 'type' => 'image', 'instructions' => 'Sube una foto cuadrada del autor (mínimo 100×100px).', 'return_format' => 'url', 'preview_size' => 'thumbnail', 'upload_folder' => 'autores', ]], 'location' => [[ ['param' => 'user_form', 'operator' => '==', 'value' => 'all'], ]], ]); }); // Usar la foto del autor en lugar del Gravatar cuando existe // Lee el attachment ID guardado en el meta 'foto_perfil' (campo ACF) add_filter('get_avatar_url', function($url, $id_or_email, $args) { $user_id = null; if (is_numeric($id_or_email)) $user_id = (int) $id_or_email; elseif ($id_or_email instanceof WP_User) $user_id = $id_or_email->ID; elseif (is_string($id_or_email)) { $user = get_user_by('email', $id_or_email); if ($user) $user_id = $user->ID; } if (!$user_id) return $url; $attach_id = get_user_meta($user_id, 'foto_perfil', true); if ($attach_id) { $foto = wp_get_attachment_image_url((int) $attach_id, 'full'); if ($foto) return $foto; } return $url; }, 10, 3); // ── Ordenar por fecha los resultados del buscador ACF en campos de portada ─ add_filter('acf/fields/relationship/query/key=field_portada_articulos', function($args) { $args['orderby'] = 'date'; $args['order'] = 'DESC'; return $args; }); add_filter('acf/fields/relationship/query/key=field_portada_multimedia', function($args) { $args['orderby'] = 'date'; $args['order'] = 'DESC'; return $args; }); // ── Campos ACF para la portada ──────────────────────────────────────────── add_action('acf/init', function() { if (!function_exists('acf_add_local_field_group')) return; $front_page_id = (int) get_option('page_on_front'); acf_add_local_field_group([ 'key' => 'group_portada_fea', 'title' => 'Contenido de la portada', 'fields' => [ [ 'key' => 'field_portada_articulos', 'label' => 'Artículos seleccionados', 'name' => 'portada_articulos', 'type' => 'relationship', 'instructions' => 'Elige los artículos que aparecerán en la portada esta semana (máx. 9). Puedes buscar por título.', 'post_type' => ['post'], 'post_status' => ['publish', 'draft'], 'filters' => ['search', 'taxonomy'], 'elements' => ['featured_image'], 'min' => 0, 'max' => 9, 'return_format' => 'object', 'query_args' => ['orderby' => 'date', 'order' => 'DESC'], ], [ 'key' => 'field_portada_multimedia', 'label' => 'Multimedia seleccionado', 'name' => 'portada_multimedia', 'type' => 'relationship', 'instructions' => 'Elige los vídeos o audios para la portada (máx. 4).', 'post_type' => ['post'], 'post_status' => ['publish', 'draft'], 'filters' => ['search'], 'elements' => ['featured_image'], 'min' => 0, 'max' => 4, 'return_format' => 'object', 'query_args' => ['orderby' => 'date', 'order' => 'DESC'], ], ], 'location' => [[ ['param' => 'page', 'operator' => '==', 'value' => (string) $front_page_id], ]], 'position' => 'normal', 'style' => 'default', 'label_placement' => 'top', ]); }); // ── Selector de idioma (dropdown con bandera + 2 letras) ───────────────── add_action('wp_head', function() { if (!function_exists('pll_the_languages')) return; ?> '🇪🇸', 'en' => '🇬🇧', 'fr' => '🇫🇷', 'it' => '🇮🇹', 'pt' => '🇵🇹']; $langs = pll_the_languages(['raw' => 1, 'hide_if_no_translation' => 0]); if (!$langs) return; $current = array_filter($langs, fn($l) => $l['current_lang']); $current = $current ? array_values($current)[0] : null; $cur_slug = $current ? $current['slug'] : 'es'; $cur_flag = $flags[$cur_slug] ?? '🌐'; $cur_code = strtoupper($cur_slug); $items = ''; foreach ($langs as $l) { $flag = $flags[$l['slug']] ?? '🌐'; $code = strtoupper($l['slug']); $cur = $l['current_lang'] ? ' aria-current="true"' : ''; $items .= '
';
$html .= '';
if ($title) {
$html .= '';
}
return $html;
});
// ── Reescribir links internos al idioma activo (Polylang) ─────────────────
add_filter('the_content', function($content) {
if (!function_exists('pll_current_language') || !function_exists('pll_get_post')) return $content;
$lang = pll_current_language();
if (!$lang || $lang === 'es') return $content;
return preg_replace_callback(
'/]*\s)?href=["\']([^"\']+)["\']([^>]*)>/i',
function($m) use ($lang) {
$href = $m[2];
$home = home_url();
if (strpos($href, $home) === false) return $m[0];
$post_id = url_to_postid($href);
if (!$post_id) return $m[0];
$translated_id = pll_get_post($post_id, $lang);
if (!$translated_id || $translated_id === $post_id) return $m[0];
$new_url = get_permalink($translated_id);
if (!$new_url) return $m[0];
return str_replace($href, $new_url, $m[0]);
},
$content
);
}, 20);
// ── Ordenar categoría Evangelios y Comentarios por título ASC ─────────────
add_action('pre_get_posts', function($query) {
if ($query->is_main_query() && $query->is_category('evangelios-y-comentarios')) {
$query->set('orderby', 'title');
$query->set('order', 'ASC');
}
});
// ── Acordeón de versículos en posts de Evangelios y Comentarios ───────────
add_action('wp_footer', function() {
if (!is_single()) return;
global $post;
if (!has_category('evangelios-y-comentarios', $post)) return;
?>
]*href=["\']([^"\']+)["\']/', $post->post_content, $m);
$slugs = [];
foreach ($m[1] as $url) {
$slug = basename(rtrim(parse_url($url, PHP_URL_PATH), '/'));
if ($slug) {
$slugs[] = $slug;
}
}
$slugs = array_values(array_unique(array_filter($slugs)));
if (empty($slugs)) return;
// Una sola query: slug → author_id
$ph = implode(',', array_fill(0, count($slugs), '%s'));
$rows = $wpdb->get_results(
$wpdb->prepare(
"SELECT post_name, post_author FROM {$wpdb->posts}
WHERE post_name IN ($ph) AND post_status IN ('publish','draft') AND post_type='post'",
$slugs
)
);
// Construir mapa slug → avatar_url (reutilizando cache de autor)
$author_cache = [];
$avatar_map = [];
foreach ($rows as $row) {
$aid = (int) $row->post_author;
if (!isset($author_cache[$aid])) {
$user = get_userdata($aid);
$author_cache[$aid] = ['src' => get_avatar_url($aid, ['size' => 40, 'default' => 'identicon']), 'name' => $user ? $user->display_name : ''];
}
if ($author_cache[$aid]) {
$avatar_map[$row->post_name] = $author_cache[$aid];
}
}
if (empty($avatar_map)) return;
?>
0 ? "HAVING cnt >= $min_count" : '';
$order = $min_count > 0 ? 'cnt DESC' : 'u.display_name ASC';
return $wpdb->get_results("
SELECT u.ID, u.display_name, COUNT(*) as cnt
FROM {$wpdb->posts} p
JOIN {$wpdb->term_relationships} tr ON tr.object_id = p.ID
JOIN {$wpdb->users} u ON u.ID = p.post_author
WHERE p.post_type = 'post'
AND p.post_status = 'publish'
AND tr.term_taxonomy_id = $ttid
AND u.ID NOT IN ($excl)
GROUP BY p.post_author
$having
ORDER BY $order
");
}
function fea_autores_html($rows, $show_count = false, $extra_class = "") {
$extra = $extra_class ? ' ' . $extra_class : '';
$out = 'No hay datos disponibles.
'; $n = count($rows); $out = 'No hay datos disponibles.
'; $n = count($rows); $out = 'No hay contenido en esta sección todavía.
'; $items = []; foreach ($posts as $p) { $url = get_permalink($p->ID); $thumb = get_the_post_thumbnail_url($p->ID, 'medium'); if (!$thumb && preg_match('~youtube\.com/watch\?v=([a-zA-Z0-9_-]+)~', $p->post_content, $m)) { $thumb = 'https://img.youtube.com/vi/' . $m[1] . '/mqdefault.jpg'; } if (!$thumb && preg_match('~| '; $html .= ' |
| '; $html .= ' |
No hay comentarios para este evangelio.
'; // Group by cita $groups = []; foreach ($rows as $r) $groups[$r->cita][] = $r; // Sort groups numerically by chapter, then verse uksort($groups, function($a, $b) { [$ca, $va] = fea_cita_sort_key($a); [$cb, $vb] = fea_cita_sort_key($b); return $ca !== $cb ? $ca - $cb : $va - $vb; }); // Avatar URL by email (Gravatar, with fallback) $avatar_cache = []; $avatar_url = function(string $email, int $id) use (&$avatar_cache): string { if (!isset($avatar_cache[$id])) { $url = get_avatar_url($id, ['size' => 40, 'default' => 'mystery']); $avatar_cache[$id] = $url ?: 'https://www.gravatar.com/avatar/' . md5(strtolower(trim($email))) . '?s=40&d=mystery'; } return $avatar_cache[$id]; }; $html = ']*)>\s*(]*>)\s*((JUAN|LUCAS|MARCOS|MATEO)\s+(\d+),\s*([\d\-–\s]+))\s*()\s*
~i', function($m) use ($bookmap) { $abbr = $bookmap[strtoupper($m[4])] ?? ''; if (!$abbr) return $m[0]; $anchor = strtolower($abbr . '-' . $m[5] . '-' . preg_replace('/[\s–\-]+/', '-', trim($m[6]))); $anchor = rtrim($anchor, '-'); return '' . $m[2] . $m[3] . $m[7] . '
'; }, $content ); }, 9); // priority 9 so it runs before the_content shortcode processing add_filter('the_content', function($content) { if (!is_single()) return $content; global $post; if (!in_category('comentarios-al-evangelio', $post)) return $content; $carta_id = get_post_meta($post->ID, '_carta_id', true); $cita = get_post_meta($post->ID, '_cita_evangelio', true); if (!$carta_id && !$cita) return $content; $html = ''; // .fea-com-footer return $content . $html; }); add_action('wp_head', function() { if (!is_single()) return; global $post; if (!$post || !in_category('comentarios-al-evangelio', $post)) return; ?>