$css"; }); // Ocultar el enlace "Mover a la papelera" en el listado add_filter('post_row_actions', function($actions, $post) use ($ids_especiales) { if ($post->post_type === POST_ESPECIAL_TYPE && in_array($post->ID, $ids_especiales)) { unset($actions['trash']); } return $actions; }, 10, 2); // Mensaje de advertencia en los posts add_filter('display_post_states', function($post_states, $post) use ($ids_especiales) { if ($post->post_type === 'acerca' && in_array($post->ID, $ids_especiales)) { $post_states['protegido'] = '🔒 No se puede borrar'; } return $post_states; }, 10, 2); /** FIN *************POST "QUÉ ES LA CNT" */ // *** SOLO USAR UNA VEZ PARA LIMPIAR. NO FUNCIONABA LA PAGINACIÓN DE SEARCH. // add_action('init', function() { // add_rewrite_rule( // 'page/([0-9]+)/?$', // 'index.php?paged=$matches[1]', // 'top' // ); // // Solo ejecuta una vez, luego comenta estas líneas // error_log('✅ flush rewrite rules'); // flush_rewrite_rules(false); // }, 10); parent::__construct(); } function load_assets() { $version = 4; // $version_for_app = $version; $version_for_app = time(); wp_enqueue_style( 'yaro', get_template_directory_uri() . '/assets/fonts/yaro-font-family/stylesheet.css', [], $version, 'all'); wp_enqueue_style( 'twbs', get_template_directory_uri() . '/vendor/twbs/bootstrap/dist/css/bootstrap.min.css', [], $version, 'all'); wp_enqueue_style( 'twbsi', get_template_directory_uri() . '/vendor/twbs/bootstrap-icons/font/bootstrap-icons.min.css', [], $version, 'all'); wp_enqueue_style( 'lust', get_template_directory_uri() . '/style.css', [], $version, 'all'); // wp_enqueue_script( 'pop', get_template_directory_uri() . '/static/popper.min.js', [], $version, false); wp_enqueue_script( 'twbs', get_template_directory_uri() . '/vendor/twbs/bootstrap/dist/js/bootstrap.min.js', [], $version, false); wp_enqueue_script( 'lust', get_template_directory_uri() . '/assets/scripts/site.js', [], $version, false); } public function register_post_types() {} public function register_taxonomies() {} public function add_to_context( $context ) { $context['foo'] = 'bar'; $context['stuff'] = 'I am a value set in your functions.php file'; $context['notes'] = 'These values are available everytime you call Timber::context();'; $context['menu'] = Timber::get_menu( 'primary_navigation' ); $context['site'] = $this; return $context; } /** * This is where you can add your theme supports. */ public function theme_supports() { // Register navigation menus register_nav_menus( [ 'primary_navigation' => _x( 'Main menu', 'Backend - menu name', 'timber-starter' ), ] ); // Add default posts and comments RSS feed links to head. add_theme_support( 'automatic-feed-links' ); /* * Let WordPress manage the document title. * By adding theme support, we declare that this theme does not use a * hard-coded tag in the document head, and expect WordPress to * provide it for us. */ add_theme_support( 'title-tag' ); /* * Enable support for Post Thumbnails on posts and pages. * * @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/ */ add_theme_support( 'post-thumbnails' ); /* * Switch default core markup for search form, comment form, and comments * to output valid HTML5. */ add_theme_support( 'html5', [ 'comment-form', 'comment-list', 'gallery', 'caption', ] ); /* * Enable support for Post Formats. * * See: https://codex.wordpress.org/Post_Formats */ add_theme_support( 'post-formats', [ 'aside', 'image', 'video', 'quote', 'link', 'gallery', 'audio', ] ); add_theme_support( 'menus' ); } /** * This would return 'foo bar!'. * * @param string $text being 'foo', then returned 'foo bar!' */ public function myfoo( $text ) { $text .= ' bar!'; return $text; } /** * This is where you can add your own functions to twig. * * @link https://timber.github.io/docs/v2/hooks/filters/#timber/twig/filters * @param array $filters an array of Twig filters. */ public function add_filters_to_twig( $filters ) { $additional_filters = [ 'myfoo' => [ 'callable' => [ $this, 'myfoo' ], ], ]; return array_merge( $filters, $additional_filters ); } /** * This is where you can add your own functions to twig. * * @link https://timber.github.io/docs/v2/hooks/filters/#timber/twig/functions * @param array $functions an array of existing Twig functions. */ public function add_functions_to_twig( $functions ) { $additional_functions = [ 'get_theme_mod' => [ 'callable' => 'get_theme_mod', ], ]; return array_merge( $functions, $additional_functions ); } /** * Updates Twig environment options. * * @see https://twig.symfony.com/doc/2.x/api.html#environment-options * * @param array $options an array of environment options * * @return array */ public function update_twig_environment_options( $options ) { // $options['autoescape'] = true; return $options; } /** * New functions to add Sindikatua theme * @author Gustavo */ //add svg files public function add_svg_support($file_types) { $new_filetypes = array(); $new_filetypes['svg'] = 'image/svg+xml'; $file_types = array_merge($file_types, $new_filetypes); return $file_types; } // Añadir idiomas de Polylang private function getPolylangData() { $polylang_data = array(); if (function_exists('pll_the_languages')) { // Idiomas con toda la información $polylang_data['languages'] = pll_the_languages(array( 'raw' => 1, 'hide_if_no_translation' => 0, 'show_flags' => 1, 'show_names' => 1 )); // Información del idioma actual $polylang_data['current_language'] = pll_current_language(); $polylang_data['current_language_name'] = pll_current_language('name'); $polylang_data['default_language'] = pll_default_language(); // DEBUG //error_log('Languages: ' . print_r($polylang_data['languages'], true)); //error_log('Current language: ' . $polylang_data['current_language']); //error_log('Default language: ' . $polylang_data['default_language']); // URLs de home para cada idioma $polylang_data['home_urls'] = array(); foreach ($polylang_data['languages'] as $lang) { $polylang_data['home_urls'][$lang['slug']] = $lang['url']; } } // Si no hay videos en euskera, el botón euskera no detecta videos en ese idioma y te lleva a la home. if (is_post_type_archive('videos')) { foreach ($polylang_data['languages'] as $slug => &$lang) { if ($slug === 'es') { $lang['url'] = home_url('/es/videos/'); } elseif ($slug === 'eu') { $lang['url'] = home_url('/eu/bideoak/'); } } } return $polylang_data; } private function getIconsRRSS() { $icons_rrss = []; for ($i = 1; $i <= 4; $i++) { $img = get_field('rrss_img_' . $i, 'option'); $url = get_field('rrss_url_' . $i, 'option'); if ($img || $url) { $icons_rrss[] = [ 'imagen' => $img, 'url' => $url ]; } } return $icons_rrss; } private function getLogosHeader ($max_logos = 2) { $logos = []; for ($i = 1; $i <= $max_logos; $i++) { $logoHeader = get_field('logo_header_' . $i, 'option'); $textoHeader = get_field('texto_header_' . $i, 'option'); if ($logoHeader || $textoHeader) { $logos[] = [ 'logo' => $logoHeader, 'texto' => $textoHeader ]; } } return $logos; } private function getPaginasAcerca() { return Timber::get_posts([ 'post_type' => 'acerca', 'post_status' => 'publish', 'orderby' => 'menu_order', 'order' => 'ASC', 'posts_per_page' => -1, ]); } private function getDocumentos() { $args = ([ 'post_type' => 'documento', 'post_status' => 'publish', 'orderby' => 'menu_order', 'order' => 'ASC', 'posts_per_page' => -1, 'lang' => '', ]); $posts = Timber::get_posts($args); //error_log('✅ Número de posts "Documentos" encontrados: ' . count($posts)); $documentos = []; foreach ($posts as $post) { $doc = [ 'id' => $post->ID, 'title' => $post->title, 'link' => $post->link, 'content' => $post->content, 'excerpt' => $post->excerpt, 'lang' => pll_get_post_language($post->ID), ]; $archivo = get_field('documento', $post->ID); if ($archivo && is_array($archivo)) { $doc['documento_url'] = $archivo['url'] ?? ''; $doc['documento_filename'] = $archivo['filename'] ?? ''; $doc['documento_filesize'] = size_format($archivo['filesize'] ?? 0); $doc['documento_extension'] = pathinfo($archivo['filename'] ?? '', PATHINFO_EXTENSION); $doc['thumbnail'] = get_the_post_thumbnail_url($post->ID, 'medium'); } $documentos[] = $doc; } return $documentos; } private function getEnlaces() { $grupos = []; // Buscar página por su slug & Cambia dinámicamente según idioma $page = get_page_by_path( pll_current_language() === 'eu' ? 'loturak' : 'enlaces' ); //error_log('✅ Página "enlaces" encontrada con ID: ' . $page->ID); if (!$page) { error_log('🔴 Página "enlaces" no encontrada con get_page_by_path().'); return []; } if (!have_rows('grupos_enlaces', $page->ID)) { error_log('🔴 Array vacío'); return []; } else { //error_log('✅ "grupos_enlaces" tiene filas.'); } // Si se encuentra la página y el campo tiene filas if ($page && have_rows('grupos_enlaces', $page->ID)) { $field = get_field('grupos_enlaces', $page->ID); //error_log('📦 Contenido de get_field: ' . print_r($field, true)); while (have_rows('grupos_enlaces', $page->ID)) { the_row(); $grupo = [ 'titulo' => get_sub_field('titulo_grupo'), 'enlaces' => [] ]; // Recorrer enlaces dentro del grupo if (have_rows('enlaces')) { while (have_rows('enlaces')) { the_row(); $titulo_enlace = get_sub_field('titulo_enlace'); $url_enlace = get_sub_field('url_enlace'); if (!empty($titulo_enlace) && !empty($url_enlace)) { $enlace = [ 'titulo' => $titulo_enlace, 'url' => $url_enlace, 'target' => get_sub_field('target_enlace') ?: '_self' ]; $grupo['enlaces'][] = $enlace; } } } // Añadir grupo solo si tiene título y enlaces válidos if (!empty($grupo['titulo']) && !empty($grupo['enlaces'])) { $grupos[] = $grupo; } } } return $grupos; } //Which paths is for 'servicios' public function whichPathIs() { $current_post = get_post(); $slug_actual = $current_post->post_name; // Determinar qué página padre buscar según el slug actual if ($slug_actual === 'servicios-publicos') { $path = 'accion-sindical/servicios-publicos'; $tipo = 'publicos'; } elseif ($slug_actual === 'servicios-privados') { $path = 'accion-sindical/servicios-privados'; $tipo = 'privados'; } elseif ($slug_actual === 'zerbitzu-publikoak') { $path = 'ekintza-sindikala/zerbitzu-publikoak'; $tipo = 'publikoak'; } elseif ($slug_actual === 'zerbitzu-pribatuak') { $path = 'ekintza-sindikala/zerbitzu-pribatuak'; $tipo = 'pribatuak'; } else { return [ 'path' => null, 'tipo' => null, 'found' => false ]; } return [ 'path' => $path, 'tipo' => $tipo, 'found' => true ]; } /** Servicios públicos y privados */ private function getSubpaginasServicios() { $pathInfo = $this->whichPathIs(); // Si no encontramos una página válida, retornar vacío if (!$pathInfo['found']) { return [ 'subpaginas' => [], 'pagination_Servicios' => null ]; } $full_path = $pathInfo['path']; $pag_servicios = get_page_by_path($full_path); if (!$pag_servicios) { error_log("🔴 Página '$pathTipo.$path' no encontrada."); return [ 'subpaginas' => [], 'pagination_Servicios' => null ]; } $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; // Obtener el número de página actual $posts_per_page = 6; global $wp_query; // Guardar la query global actual $temp_query = $wp_query; $wp_query = new \WP_Query([ // Crear nueva WP_Query 'post_type' => 'page', 'post_status' => 'publish', 'post_parent' => $pag_servicios->ID, 'orderby' => 'menu_order', 'order' => 'ASC', 'posts_per_page' => $posts_per_page, 'paged' => $paged, ]); $subpaginas = Timber::get_posts(); // Timber::get_posts() SIN PARÁMETROS usa la query global ($wp_query) foreach ($subpaginas as $pagina) { $pagina->thumbnail = get_the_post_thumbnail_url($pagina->ID); $pagina->tipo_servicio = $pathInfo['tipo']; } $pagination = new \Timber\Pagination($wp_query->max_num_pages); // Crear objeto de paginación $wp_query = $temp_query; // Restaurar query original return $subpaginas; } public function getContactoFields() { $post = Timber::get_post(); if (!$post) { return []; } $form_shortcode = get_field('etiqueta_formulario', $post->ID); // o el campo ACF donde esté el shortcode //error_log('✅ ID Página "Contactos": ' . $post->ID); $contactsFields = [ 'nombre' => get_field('nombre_contacto', $post->ID), 'direccion' => get_field('direccion', $post->ID), 'url_mapa' => get_field('url_mapa', $post->ID), 'forma_contacto' => get_field('forma_contacto', $post->ID), 'url_web' => get_field('url_web', $post->ID), 'url_facebook' => get_field('url_facebook', $post->ID), 'url_twitter' => get_field('url_twitter', $post->ID), 'form' => !empty($form_shortcode) ? do_shortcode($form_shortcode) : '', ]; return $contactsFields; } private function getPostIndustry() { $pag_industry = get_page_by_path('accion-sindical/industria'); if (!$pag_industry) { error_log('🔴 Página "Industria" no encontrada.'); return []; } else { //error_log('✅ Página "Industria" encontrada.'); } $subpaginas = Timber::get_posts([ 'post_type' => 'page', 'post_status' => 'publish', 'post_parent' => $pag_industry->ID, 'orderby' => 'menu_order', 'order' => 'ASC', 'posts_per_page' => -1, ]); foreach ($subpaginas as $pagina) { //$pagina->imagen = $pagina->thumbnail ? $pagina->thumbnail->src('medium') : null; $pagina->thumbnail= get_the_post_thumbnail_url($pagina->ID); } return $subpaginas; } private function getListContacts() { $contactos_page = Timber::get_posts([ 'post_type' => 'page', 'name' => 'kontaktua', // slug en euskera 'posts_per_page' => 1 ])[0] ?? null; // Si no encuentra en euskera, busca en castellano if (!$contactos_page) { $contactos_page = Timber::get_posts([ 'post_type' => 'page', 'name' => 'contactos', // slug en castellano 'posts_per_page' => 1 ])[0] ?? null; } return $contactos_page ? Timber::get_posts([ 'post_type' => 'page', 'post_parent' => $contactos_page->ID, 'orderby' => 'menu_order', 'order' => 'ASC' ]) : []; } //Global variables public function add_global_context($context) { // GLobales $context['logos_header'] = $this->getLogosHeader(); $context['redes_sociales'] = $this->getIconsRRSS(); $context['listContacts'] = $this->getListContacts(); $context['footer_1'] = get_field('footer_text_1', 'option'); $context['footer_2'] = get_field('footer_text_2', 'option'); //Otras páginas //$context['videos'] = $this->getVideos(); $context['paginas_acerca'] = $this->getPaginasAcerca(); $context['documentos'] = $this->getDocumentos(); $context['enlaces'] = $this->getEnlaces(); $context['contacto_info'] = $this->getContactoFields(); $context['posts_industry'] = $this->getPostIndustry(); $context['subpaginas_servicios'] = $this->getSubpaginasServicios(); //otros $context = array_merge($context, $this->getPolylangData()); return $context; } /** * Funciones public 'Template-Portada' */ public function getLastsPostsNews() { return Timber::get_posts([ 'post_type' => 'post', 'category_name' => 'noticias', 'posts_per_page' => -1, 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'DESC' ]); } public function getBotonesEnlaces($page_id = null) { if (is_null($page_id)) { $page_id = get_the_ID(); // Si estamos en euskera, obtener la página en español if (pll_current_language() == 'eu') { $spanish_page_id = pll_get_post($page_id, 'es'); $page_id = $spanish_page_id ?: $page_id; } } $botones = []; for ($i = 1; $i <= 4; $i++) { $imagen = get_field('imagen_boton_' . $i, $page_id); $enlace = get_field('enlace_boton_' . $i, $page_id); $botones[] = [ 'imagen' => $imagen, 'enlace' => $enlace, ]; } return $botones; } public function getLastPostOpinion() { return Timber::get_posts([ 'post_type' => 'opinion', 'posts_per_page' => 1, 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'DESC' ]); } public function getLastPostCampana() { return Timber::get_posts([ 'post_type' => 'post', 'category_name' => 'campana', 'posts_per_page' => 1, 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'DESC' ]); } public function getLastPostConflicts() { return Timber::get_posts([ 'post_type' => 'post', 'category_name' => 'conflictos laborales', 'posts_per_page' => 1, 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'DESC' ]); } public function getVideosSlider() { $post = Timber::get_post(); //error_log('✅ getVideosSlider - ID Página: ' . $post->ID); return [ 'posts' => Timber::get_posts([ 'post_type' => 'videos', 'posts_per_page' => -1, 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'DESC', 'lang' => '' // Importante: vacío para obtener todos ]), 'pagination' => null ]; } /** * Funciones globales */ // Excluir páginas de la búsqueda public function exclude_pages_from_search($query) { if (!is_admin() && $query->is_main_query() && $query->is_search()) { $query->set('meta_query', array( 'relation' => 'OR', array( 'key' => 'exclude_from_search', 'compare' => 'NOT EXISTS' ), array( 'key' => 'exclude_from_search', 'value' => '1', 'compare' => '!=' ) )); } } // genera embed para videos public function generar_embed_universal($url) { if (empty($url)) { return false; } // YouTube if (strpos($url, 'youtube.com') !== false || strpos($url, 'youtu.be') !== false) { //error_log('es un vídeo de youtube'); // Debug preg_match('/(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/', $url, $matches); if (!empty($matches[1])) { $embed_data = [ 'platform' => 'youtube', 'embed_url' => 'https://www.youtube.com/embed/' . $matches[1] . '?rel=0&modestbranding=1', 'thumbnail_url' => 'https://img.youtube.com/vi/' . $matches[1]. '/hqdefault.jpg', 'allow' => 'autoplay; encrypted-media; picture-in-picture' ]; //error_log('Embed URL generada: ' . $embed_data['embed_url']); return $embed_data; } else { error_log('No se pudo extraer ID de YouTube'); } } // Vimeo if (strpos($url, 'vimeo.com') !== false) { preg_match('/vimeo\.com\/(\d+)/', $url, $matches); if (!empty($matches[1])) { return [ 'platform' => 'vimeo', 'embed_url' => 'https://player.vimeo.com/video/' . $matches[1] . '?title=0&byline=0&portrait=0', 'allow' => 'autoplay; fullscreen; picture-in-picture' ]; } } // Si no se reconoce la plataforma return [ 'platform' => 'generic', 'embed_url' => $url, 'allow' => 'fullscreen' ]; } // Hacer función disponible en Twig public function add_videos_embed_to_twig ($twig) { //error_log('Añadiendo función generar_embed a Twig'); // Debug $twig->addFunction(new \Twig\TwigFunction('generar_embed', [$this, 'generar_embed_universal'])); return $twig; } }