Implementar Issues #2-4, #8-13, #16 - Funcionalidades core del tema
Implementación masiva de funcionalidades esenciales del tema apus-theme usando agentes paralelos para máxima eficiencia. **Issues Completados:** **Issue #2 - Eliminar bloat de WordPress:** - inc/performance.php: 13 funciones que remueven emojis, oEmbed, feeds, dashicons, jQuery migrate, XML-RPC, etc. - Optimización completa del frontend **Issue #3 - Desactivar búsqueda nativa:** - inc/search-disable.php: Bloquea queries de búsqueda, widget, formularios - search.php: Retorna 404 con mensaje amigable **Issue #4 - Desactivar comentarios:** - inc/comments-disable.php: 15 funciones que eliminan comentarios de frontend y backend - comments.php: Template desactivado **Issue #8 - Footer con 4 widgets:** - footer.php: Verificado con 4 áreas de widgets y copyright - assets/css/footer.css: Estilos responsive completos - Sistema de anchos configurables **Issue #9 - Jerarquía de plantillas:** - home.php, category.php, tag.php, author.php, date.php, taxonomy.php, attachment.php - 7 nuevas plantillas + 12 verificadas - Template parts completos - Paginación en todos los archives **Issue #10 - Imágenes destacadas:** - inc/featured-image.php: 12 funciones para manejo de featured images - Sin placeholders, lazy loading, alt text automático - Responsive con Bootstrap, aspect ratio **Issue #11 - Badge de categoría:** - inc/category-badge.php: Badge Bootstrap sobre H1 en single posts - Excluye "Uncategorized" - Template tag: apus_display_category_badge() **Issue #12 - TOC automático:** - inc/toc.php: Genera TOC desde H2/H3 - assets/css/toc.css: Estilos con numeración CSS counters - assets/js/toc.js: Smooth scroll, scroll spy, toggle - Configurable con apus_get_option() **Issue #13 - Posts relacionados:** - inc/related-posts.php: Query por categoría, 12 funciones - inc/admin/related-posts-options.php: Sistema de configuración - assets/css/related-posts.css: Cards responsive - Hook automático en single posts **Issue #16 - AdSense delay:** - inc/adsense-delay.php: Retardo de carga hasta scroll/click - assets/js/adsense-loader.js: Detecta interacciones - Mejora FID y TBT para Core Web Vitals **Archivos Modificados:** - functions.php: Includes de nuevos módulos, removido feed support - single.php: Integración de category badge - inc/enqueue-scripts.php: Enqueue de nuevos assets - inc/theme-options-helpers.php: Helper functions para TOC **Archivos Creados:** - 7 nuevas plantillas WordPress - 3 nuevos módulos inc/ (comments-disable, search-disable) - 8 reportes de documentación .md **Estadísticas:** - Total funciones PHP: 60+ nuevas funciones - Líneas de código: 2,500+ líneas - Archivos nuevos: 18 - Archivos modificados: 9 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -15,74 +15,74 @@ if (!defined('ABSPATH')) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Delay AdSense scripts by intercepting output buffer
|
||||
* Retarda la carga de scripts de AdSense interceptando el buffer de salida
|
||||
*
|
||||
* This function starts output buffering and replaces AdSense scripts
|
||||
* with delayed versions when the page is rendered.
|
||||
* Esta función inicia el output buffering y reemplaza los scripts de AdSense
|
||||
* con versiones retrasadas cuando se renderiza la página.
|
||||
*/
|
||||
function apus_delay_adsense_scripts() {
|
||||
// Only run on frontend
|
||||
// Solo ejecutar en frontend
|
||||
if (is_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if AdSense delay is enabled in theme options
|
||||
$delay_enabled = get_theme_mod('apus_adsense_delay_enabled', true);
|
||||
// Verificar si el retardo de AdSense está habilitado en las opciones del tema
|
||||
$delay_enabled = apus_get_option('apus_adsense_delay_enabled', '1');
|
||||
|
||||
if (!$delay_enabled) {
|
||||
if ($delay_enabled !== '1') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Start output buffering
|
||||
// Iniciar output buffering
|
||||
ob_start('apus_replace_adsense_scripts');
|
||||
}
|
||||
add_action('template_redirect', 'apus_delay_adsense_scripts', 1);
|
||||
|
||||
/**
|
||||
* Replace AdSense scripts with delayed versions
|
||||
* Reemplaza scripts de AdSense con versiones retrasadas
|
||||
*
|
||||
* This function processes the HTML output and replaces standard AdSense
|
||||
* script tags with delayed loading versions.
|
||||
* Esta función procesa la salida HTML y reemplaza las etiquetas de script
|
||||
* estándar de AdSense con versiones de carga retrasada.
|
||||
*
|
||||
* @param string $html The HTML content to process
|
||||
* @return string Modified HTML with delayed AdSense scripts
|
||||
* @param string $html El contenido HTML a procesar
|
||||
* @return string HTML modificado con scripts de AdSense retrasados
|
||||
*/
|
||||
function apus_replace_adsense_scripts($html) {
|
||||
// Only process if there's actual AdSense content
|
||||
// Solo procesar si hay contenido real de AdSense
|
||||
if (strpos($html, 'pagead2.googlesyndication.com') === false &&
|
||||
strpos($html, 'adsbygoogle.js') === false) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
// Pattern to match AdSense script tags
|
||||
// Patrones para encontrar etiquetas de script de AdSense
|
||||
$patterns = array(
|
||||
// Match async script tags for AdSense
|
||||
// Buscar etiquetas de script async para AdSense
|
||||
'/<script\s+async\s+src=["\']https:\/\/pagead2\.googlesyndication\.com\/pagead\/js\/adsbygoogle\.js[^"\']*["\']\s*(?:crossorigin=["\']anonymous["\'])?\s*><\/script>/i',
|
||||
|
||||
// Match script tags without async
|
||||
// Buscar etiquetas de script sin async
|
||||
'/<script\s+src=["\']https:\/\/pagead2\.googlesyndication\.com\/pagead\/js\/adsbygoogle\.js[^"\']*["\']\s*(?:crossorigin=["\']anonymous["\'])?\s*><\/script>/i',
|
||||
|
||||
// Match inline adsbygoogle.push scripts
|
||||
// Buscar scripts inline de adsbygoogle.push
|
||||
'/<script>\s*\(adsbygoogle\s*=\s*window\.adsbygoogle\s*\|\|\s*\[\]\)\.push\(\{[^}]*\}\);\s*<\/script>/is',
|
||||
);
|
||||
|
||||
// Replace async AdSense scripts with delayed versions
|
||||
// Reemplazar scripts async de AdSense con versiones retrasadas
|
||||
$replacements = array(
|
||||
// Replace async script tag with data attribute for delayed loading
|
||||
// Reemplazar etiqueta de script async con atributo data para carga retrasada
|
||||
'<script type="text/plain" data-adsense-script src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js" crossorigin="anonymous"></script>',
|
||||
|
||||
// Replace non-async script tag
|
||||
// Reemplazar etiqueta de script no-async
|
||||
'<script type="text/plain" data-adsense-script src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js" crossorigin="anonymous"></script>',
|
||||
|
||||
// Replace inline push scripts with delayed versions
|
||||
// Reemplazar scripts de push inline con versiones retrasadas
|
||||
'<script type="text/plain" data-adsense-push>$0</script>',
|
||||
);
|
||||
|
||||
// First pass: replace script tags
|
||||
// Primera pasada: reemplazar etiquetas de script
|
||||
$html = preg_replace($patterns[0], $replacements[0], $html);
|
||||
$html = preg_replace($patterns[1], $replacements[1], $html);
|
||||
|
||||
// Second pass: replace inline push calls
|
||||
// Segunda pasada: reemplazar llamadas inline de push
|
||||
$html = preg_replace_callback(
|
||||
'/<script>\s*\(adsbygoogle\s*=\s*window\.adsbygoogle\s*\|\|\s*\[\]\)\.push\(\{[^}]*\}\);\s*<\/script>/is',
|
||||
function($matches) {
|
||||
@@ -91,30 +91,30 @@ function apus_replace_adsense_scripts($html) {
|
||||
$html
|
||||
);
|
||||
|
||||
// Add a comment to indicate processing occurred
|
||||
// Agregar comentario para indicar que se procesó (solo en modo debug)
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
$html = str_replace('</body>', '<!-- AdSense scripts delayed by Apus Theme --></body>', $html);
|
||||
$html = str_replace('</body>', '<!-- Scripts de AdSense retrasados por Apus Theme --></body>', $html);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add inline script to initialize delayed AdSense
|
||||
* Agrega script inline para inicializar AdSense retrasado
|
||||
*
|
||||
* This adds a small inline script that marks AdSense as ready to load
|
||||
* after the adsense-loader.js has been enqueued.
|
||||
* Esto agrega un pequeño script inline que marca AdSense como listo para cargar
|
||||
* después de que adsense-loader.js ha sido enqueued.
|
||||
*/
|
||||
function apus_add_adsense_init_script() {
|
||||
$delay_enabled = get_theme_mod('apus_adsense_delay_enabled', true);
|
||||
$delay_enabled = apus_get_option('apus_adsense_delay_enabled', '1');
|
||||
|
||||
if (!$delay_enabled || is_admin()) {
|
||||
if ($delay_enabled !== '1' || is_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<script>
|
||||
// Initialize AdSense delay flag
|
||||
// Inicializar flag de retardo de AdSense
|
||||
window.apusAdsenseDelayed = true;
|
||||
</script>
|
||||
<?php
|
||||
@@ -122,33 +122,29 @@ function apus_add_adsense_init_script() {
|
||||
add_action('wp_head', 'apus_add_adsense_init_script', 1);
|
||||
|
||||
/**
|
||||
* Register customizer settings for AdSense delay
|
||||
* INSTRUCCIONES DE USO:
|
||||
*
|
||||
* @param WP_Customize_Manager $wp_customize Theme Customizer object
|
||||
* Para activar el retardo de carga de AdSense:
|
||||
* 1. Ir al panel de opciones del tema (Dashboard > Apus Theme Options)
|
||||
* 2. En la sección "Performance", activar la opción "Delay AdSense Loading"
|
||||
* 3. Guardar cambios
|
||||
*
|
||||
* Comportamiento:
|
||||
* - Los scripts de AdSense NO se cargarán hasta que el usuario:
|
||||
* * Haga scroll en la página
|
||||
* * Haga click en cualquier parte
|
||||
* * Toque la pantalla (móviles)
|
||||
* * Mueva el mouse
|
||||
* * Presione una tecla
|
||||
* - Si no hay interacción, los scripts se cargarán después de 5 segundos
|
||||
*
|
||||
* Beneficios:
|
||||
* - Mejora significativa en Core Web Vitals (FID, TBT)
|
||||
* - Reduce el tiempo de carga inicial de la página
|
||||
* - No afecta la monetización (los ads se siguen mostrando)
|
||||
* - Sin layout shifts al cargar los ads
|
||||
*
|
||||
* Para desactivar:
|
||||
* - Desmarcar la opción en el panel de opciones del tema
|
||||
* - Los scripts de AdSense se cargarán normalmente
|
||||
*/
|
||||
function apus_adsense_delay_customizer($wp_customize) {
|
||||
// Add Performance section if it doesn't exist
|
||||
if (!$wp_customize->get_section('apus_performance')) {
|
||||
$wp_customize->add_section('apus_performance', array(
|
||||
'title' => __('Performance Settings', 'apus-theme'),
|
||||
'priority' => 130,
|
||||
));
|
||||
}
|
||||
|
||||
// Add setting for AdSense delay
|
||||
$wp_customize->add_setting('apus_adsense_delay_enabled', array(
|
||||
'default' => true,
|
||||
'sanitize_callback' => 'apus_sanitize_checkbox',
|
||||
'transport' => 'refresh',
|
||||
));
|
||||
|
||||
// Add control for AdSense delay
|
||||
$wp_customize->add_control('apus_adsense_delay_enabled', array(
|
||||
'label' => __('Delay AdSense Loading', 'apus-theme'),
|
||||
'description' => __('Delay AdSense scripts until user interaction to improve page load speed.', 'apus-theme'),
|
||||
'section' => 'apus_performance',
|
||||
'type' => 'checkbox',
|
||||
));
|
||||
}
|
||||
add_action('customize_register', 'apus_adsense_delay_customizer');
|
||||
|
||||
|
||||
@@ -2,207 +2,80 @@
|
||||
/**
|
||||
* Category Badge Functions
|
||||
*
|
||||
* Display category badges for posts with configurable settings.
|
||||
* Funciones para mostrar badge de categoría sobre el H1 en single posts.
|
||||
* Utiliza clases de Bootstrap para el estilo del badge.
|
||||
*
|
||||
* @package Apus_Theme
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
// Exit if accessed directly
|
||||
// Salir si se accede directamente
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Category Badge HTML
|
||||
* Obtiene el HTML del badge de categoría
|
||||
*
|
||||
* Returns HTML markup for the first category badge.
|
||||
* Can be configured to show/hide via theme customizer.
|
||||
* Retorna el HTML del badge con la primera categoría del post,
|
||||
* excluyendo "Uncategorized" y "Sin categoría".
|
||||
* Utiliza clases de Bootstrap para el estilo.
|
||||
*
|
||||
* @param int $post_id Optional. Post ID. Defaults to current post.
|
||||
* @param bool $force_show Optional. Force display regardless of settings. Default false.
|
||||
* @return string HTML markup for category badge or empty string.
|
||||
* @return string HTML del badge de categoría o string vacío
|
||||
*/
|
||||
function apus_get_category_badge($post_id = null, $force_show = false) {
|
||||
// Get post ID if not provided
|
||||
if (!$post_id) {
|
||||
$post_id = get_the_ID();
|
||||
}
|
||||
|
||||
// Check if category badges are enabled
|
||||
if (!$force_show && !apus_is_category_badge_enabled()) {
|
||||
function apus_get_category_badge() {
|
||||
// Verificar si la función está habilitada en las opciones del tema
|
||||
$enabled = apus_get_option('show_category_badge', true);
|
||||
if (!$enabled) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Get categories
|
||||
$categories = get_the_category($post_id);
|
||||
// Solo mostrar en single posts (no en páginas ni archives)
|
||||
if (!is_single()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Return empty if no categories
|
||||
// Obtener todas las categorías del post actual
|
||||
$categories = get_the_category();
|
||||
|
||||
// Si no hay categorías, retornar vacío
|
||||
if (empty($categories)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Get first category
|
||||
$category = $categories[0];
|
||||
// Filtrar categorías para excluir "Uncategorized" o "Sin categoría"
|
||||
$filtered_categories = array_filter($categories, function($category) {
|
||||
$excluded_slugs = array('uncategorized', 'sin-categoria');
|
||||
return !in_array($category->slug, $excluded_slugs);
|
||||
});
|
||||
|
||||
// Build badge HTML
|
||||
$output = '<div class="category-badge-wrapper">';
|
||||
$output .= sprintf(
|
||||
'<a href="%s" class="category-badge" rel="category tag">%s</a>',
|
||||
// Si después del filtro no quedan categorías, retornar vacío
|
||||
if (empty($filtered_categories)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Tomar la primera categoría (principal)
|
||||
$category = reset($filtered_categories);
|
||||
|
||||
// Generar HTML del badge con clases Bootstrap
|
||||
// Utiliza badge bg-primary de Bootstrap 5
|
||||
$output = sprintf(
|
||||
'<div class="category-badge mb-3"><a href="%s" class="badge bg-primary text-decoration-none" rel="category tag">%s</a></div>',
|
||||
esc_url(get_category_link($category->term_id)),
|
||||
esc_html($category->name)
|
||||
);
|
||||
$output .= '</div>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display Category Badge
|
||||
* Muestra el badge de categoría
|
||||
*
|
||||
* Echoes the category badge HTML.
|
||||
* Template tag para imprimir directamente el badge de categoría.
|
||||
* Uso en templates: <?php apus_display_category_badge(); ?>
|
||||
*
|
||||
* @param int $post_id Optional. Post ID. Defaults to current post.
|
||||
* @param bool $force_show Optional. Force display regardless of settings. Default false.
|
||||
* @return void
|
||||
*/
|
||||
function apus_the_category_badge($post_id = null, $force_show = false) {
|
||||
echo apus_get_category_badge($post_id, $force_show);
|
||||
function apus_display_category_badge() {
|
||||
echo apus_get_category_badge();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Category Badge is Enabled
|
||||
*
|
||||
* @return bool True if enabled, false otherwise.
|
||||
*/
|
||||
function apus_is_category_badge_enabled() {
|
||||
return (bool) get_theme_mod('apus_category_badge_enabled', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Category Badge Settings in Customizer
|
||||
*
|
||||
* Adds controls to enable/disable category badges.
|
||||
*
|
||||
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
|
||||
*/
|
||||
function apus_category_badge_customizer($wp_customize) {
|
||||
// Add section
|
||||
$wp_customize->add_section('apus_category_badge', array(
|
||||
'title' => __('Category Badge', 'apus-theme'),
|
||||
'priority' => 31,
|
||||
));
|
||||
|
||||
// Enable/Disable setting
|
||||
$wp_customize->add_setting('apus_category_badge_enabled', array(
|
||||
'default' => true,
|
||||
'sanitize_callback' => 'wp_validate_boolean',
|
||||
'transport' => 'refresh',
|
||||
));
|
||||
|
||||
$wp_customize->add_control('apus_category_badge_enabled', array(
|
||||
'label' => __('Enable Category Badge', 'apus-theme'),
|
||||
'description' => __('Show the first category as a badge above the post title in single posts.', 'apus-theme'),
|
||||
'section' => 'apus_category_badge',
|
||||
'type' => 'checkbox',
|
||||
));
|
||||
|
||||
// Badge background color
|
||||
$wp_customize->add_setting('apus_category_badge_bg_color', array(
|
||||
'default' => '#0073aa',
|
||||
'sanitize_callback' => 'sanitize_hex_color',
|
||||
'transport' => 'postMessage',
|
||||
));
|
||||
|
||||
$wp_customize->add_control(new WP_Customize_Color_Control($wp_customize, 'apus_category_badge_bg_color', array(
|
||||
'label' => __('Badge Background Color', 'apus-theme'),
|
||||
'section' => 'apus_category_badge',
|
||||
)));
|
||||
|
||||
// Badge text color
|
||||
$wp_customize->add_setting('apus_category_badge_text_color', array(
|
||||
'default' => '#ffffff',
|
||||
'sanitize_callback' => 'sanitize_hex_color',
|
||||
'transport' => 'postMessage',
|
||||
));
|
||||
|
||||
$wp_customize->add_control(new WP_Customize_Color_Control($wp_customize, 'apus_category_badge_text_color', array(
|
||||
'label' => __('Badge Text Color', 'apus-theme'),
|
||||
'section' => 'apus_category_badge',
|
||||
)));
|
||||
}
|
||||
add_action('customize_register', 'apus_category_badge_customizer');
|
||||
|
||||
/**
|
||||
* Output Category Badge Inline Styles
|
||||
*
|
||||
* Outputs custom CSS for category badge colors.
|
||||
*/
|
||||
function apus_category_badge_styles() {
|
||||
$bg_color = get_theme_mod('apus_category_badge_bg_color', '#0073aa');
|
||||
$text_color = get_theme_mod('apus_category_badge_text_color', '#ffffff');
|
||||
|
||||
$css = "
|
||||
<style id='apus-category-badge-inline-css'>
|
||||
.category-badge-wrapper {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.category-badge {
|
||||
display: inline-block;
|
||||
background-color: {$bg_color};
|
||||
color: {$text_color};
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
border-radius: 4px;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.category-badge:hover {
|
||||
opacity: 0.8;
|
||||
color: {$text_color};
|
||||
}
|
||||
|
||||
.category-badge:focus {
|
||||
outline: 2px solid {$bg_color};
|
||||
outline-offset: 2px;
|
||||
}
|
||||
</style>
|
||||
";
|
||||
|
||||
echo $css;
|
||||
}
|
||||
add_action('wp_head', 'apus_category_badge_styles');
|
||||
|
||||
/**
|
||||
* Customize Preview JS for Live Preview
|
||||
*
|
||||
* Adds live preview support for category badge color changes.
|
||||
*/
|
||||
function apus_category_badge_customize_preview_js() {
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
(function($) {
|
||||
// Background Color
|
||||
wp.customize('apus_category_badge_bg_color', function(value) {
|
||||
value.bind(function(newval) {
|
||||
$('.category-badge').css('background-color', newval);
|
||||
});
|
||||
});
|
||||
|
||||
// Text Color
|
||||
wp.customize('apus_category_badge_text_color', function(value) {
|
||||
value.bind(function(newval) {
|
||||
$('.category-badge').css('color', newval);
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
add_action('customize_preview_init', function() {
|
||||
add_action('wp_footer', 'apus_category_badge_customize_preview_js');
|
||||
});
|
||||
|
||||
253
wp-content/themes/apus-theme/inc/comments-disable.php
Normal file
253
wp-content/themes/apus-theme/inc/comments-disable.php
Normal file
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
/**
|
||||
* Desactivar completamente el sistema de comentarios
|
||||
*
|
||||
* Este archivo desactiva completamente los comentarios en WordPress,
|
||||
* tanto en el frontend como en el área de administración.
|
||||
*
|
||||
* @package Apus_Theme
|
||||
* @since 1.0.0
|
||||
* @link https://github.com/prime-leads-app/analisisdepreciosunitarios.com/issues/4
|
||||
*/
|
||||
|
||||
// Exit if accessed directly
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Desactivar soporte de comentarios y pingbacks
|
||||
*
|
||||
* Cierra comentarios y pingbacks para todos los post types.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @param bool $open Si los comentarios están abiertos o no.
|
||||
* @return bool Siempre retorna false.
|
||||
*/
|
||||
function apus_disable_comments_status() {
|
||||
return false;
|
||||
}
|
||||
add_filter('comments_open', 'apus_disable_comments_status', 20, 2);
|
||||
add_filter('pings_open', 'apus_disable_comments_status', 20, 2);
|
||||
|
||||
/**
|
||||
* Ocultar comentarios existentes
|
||||
*
|
||||
* Retorna un array vacío para ocultar cualquier comentario existente.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @param array $comments Array de comentarios.
|
||||
* @return array Array vacío.
|
||||
*/
|
||||
function apus_hide_existing_comments($comments) {
|
||||
return array();
|
||||
}
|
||||
add_filter('comments_array', 'apus_hide_existing_comments', 10, 2);
|
||||
|
||||
/**
|
||||
* Desactivar feeds de comentarios
|
||||
*
|
||||
* Remueve los enlaces de feeds de comentarios del head.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function apus_disable_comment_feeds() {
|
||||
// Remover enlaces de feeds de comentarios
|
||||
remove_action('wp_head', 'feed_links_extra', 3);
|
||||
|
||||
// Desactivar feeds de comentarios
|
||||
add_action('do_feed_rss2_comments', 'apus_disable_feed_comments');
|
||||
add_action('do_feed_atom_comments', 'apus_disable_feed_comments');
|
||||
}
|
||||
add_action('init', 'apus_disable_comment_feeds');
|
||||
|
||||
/**
|
||||
* Retornar error en feeds de comentarios
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function apus_disable_feed_comments() {
|
||||
wp_die(
|
||||
esc_html__('Los comentarios están desactivados en este sitio.', 'apus-theme'),
|
||||
esc_html__('Comentarios no disponibles', 'apus-theme'),
|
||||
array(
|
||||
'response' => 404,
|
||||
'back_link' => true,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Desactivar script de respuesta de comentarios
|
||||
*
|
||||
* Remueve el script comment-reply.js del frontend.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function apus_disable_comment_reply_script() {
|
||||
wp_deregister_script('comment-reply');
|
||||
}
|
||||
add_action('wp_enqueue_scripts', 'apus_disable_comment_reply_script', 100);
|
||||
|
||||
/**
|
||||
* Remover menú de comentarios del admin
|
||||
*
|
||||
* Oculta el menú "Comentarios" del área de administración.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function apus_remove_comments_admin_menu() {
|
||||
remove_menu_page('edit-comments.php');
|
||||
}
|
||||
add_action('admin_menu', 'apus_remove_comments_admin_menu');
|
||||
|
||||
/**
|
||||
* Remover comentarios de la admin bar
|
||||
*
|
||||
* Oculta el icono de comentarios de la barra de administración.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @param WP_Admin_Bar $wp_admin_bar Instancia de WP_Admin_Bar.
|
||||
*/
|
||||
function apus_remove_comments_admin_bar($wp_admin_bar) {
|
||||
$wp_admin_bar->remove_menu('comments');
|
||||
}
|
||||
add_action('admin_bar_menu', 'apus_remove_comments_admin_bar', 60);
|
||||
|
||||
/**
|
||||
* Remover metabox de comentarios del editor
|
||||
*
|
||||
* Oculta el metabox de comentarios en el editor de posts y páginas.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function apus_remove_comments_metabox() {
|
||||
// Post types por defecto
|
||||
remove_meta_box('commentstatusdiv', 'post', 'normal');
|
||||
remove_meta_box('commentstatusdiv', 'page', 'normal');
|
||||
remove_meta_box('commentsdiv', 'post', 'normal');
|
||||
remove_meta_box('commentsdiv', 'page', 'normal');
|
||||
remove_meta_box('trackbacksdiv', 'post', 'normal');
|
||||
remove_meta_box('trackbacksdiv', 'page', 'normal');
|
||||
|
||||
// Aplicar a cualquier custom post type que pueda existir
|
||||
$post_types = get_post_types(array('public' => true), 'names');
|
||||
foreach ($post_types as $post_type) {
|
||||
if (post_type_supports($post_type, 'comments')) {
|
||||
remove_post_type_support($post_type, 'comments');
|
||||
remove_post_type_support($post_type, 'trackbacks');
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action('admin_init', 'apus_remove_comments_metabox');
|
||||
|
||||
/**
|
||||
* Ocultar columna de comentarios en listados del admin
|
||||
*
|
||||
* Remueve la columna de comentarios de los listados de posts/páginas.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @param array $columns Columnas actuales.
|
||||
* @return array Columnas modificadas sin comentarios.
|
||||
*/
|
||||
function apus_remove_comments_column($columns) {
|
||||
unset($columns['comments']);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
// Aplicar a posts y páginas
|
||||
add_filter('manage_posts_columns', 'apus_remove_comments_column');
|
||||
add_filter('manage_pages_columns', 'apus_remove_comments_column');
|
||||
|
||||
/**
|
||||
* Desactivar widgets de comentarios
|
||||
*
|
||||
* Remueve los widgets relacionados con comentarios.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function apus_disable_comments_widgets() {
|
||||
unregister_widget('WP_Widget_Recent_Comments');
|
||||
}
|
||||
add_action('widgets_init', 'apus_disable_comments_widgets');
|
||||
|
||||
/**
|
||||
* Remover estilos CSS de comentarios recientes
|
||||
*
|
||||
* Remueve los estilos inline del widget de comentarios recientes.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function apus_remove_recent_comments_style() {
|
||||
global $wp_widget_factory;
|
||||
|
||||
if (isset($wp_widget_factory->widgets['WP_Widget_Recent_Comments'])) {
|
||||
remove_action('wp_head', array(
|
||||
$wp_widget_factory->widgets['WP_Widget_Recent_Comments'],
|
||||
'recent_comments_style'
|
||||
));
|
||||
}
|
||||
}
|
||||
add_action('widgets_init', 'apus_remove_recent_comments_style');
|
||||
|
||||
/**
|
||||
* Redireccionar URLs de comentarios (opcional)
|
||||
*
|
||||
* Si alguien intenta acceder directamente a URLs de comentarios,
|
||||
* redirigir al post padre.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function apus_redirect_comment_urls() {
|
||||
if (is_comment_feed()) {
|
||||
wp_safe_redirect(home_url(), 301);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
add_action('template_redirect', 'apus_redirect_comment_urls');
|
||||
|
||||
/**
|
||||
* Prevenir nuevos comentarios via REST API
|
||||
*
|
||||
* Desactiva endpoints de comentarios en REST API.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @param array $endpoints Endpoints disponibles.
|
||||
* @return array Endpoints sin comentarios.
|
||||
*/
|
||||
function apus_disable_comments_rest_api($endpoints) {
|
||||
if (isset($endpoints['/wp/v2/comments'])) {
|
||||
unset($endpoints['/wp/v2/comments']);
|
||||
}
|
||||
if (isset($endpoints['/wp/v2/comments/(?P<id>[\d]+)'])) {
|
||||
unset($endpoints['/wp/v2/comments/(?P<id>[\d]+)']);
|
||||
}
|
||||
return $endpoints;
|
||||
}
|
||||
add_filter('rest_endpoints', 'apus_disable_comments_rest_api');
|
||||
|
||||
/**
|
||||
* Ocultar opciones de comentarios en el dashboard
|
||||
*
|
||||
* Remueve metaboxes de comentarios del dashboard.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function apus_remove_dashboard_comments() {
|
||||
remove_meta_box('dashboard_recent_comments', 'dashboard', 'normal');
|
||||
}
|
||||
add_action('admin_init', 'apus_remove_dashboard_comments');
|
||||
|
||||
/**
|
||||
* Desactivar notificaciones de comentarios
|
||||
*
|
||||
* Previene el envío de emails de notificación de comentarios.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @return bool Siempre retorna false.
|
||||
*/
|
||||
function apus_disable_comment_emails() {
|
||||
return false;
|
||||
}
|
||||
add_filter('notify_post_author', 'apus_disable_comment_emails', 10, 2);
|
||||
add_filter('notify_moderator', 'apus_disable_comment_emails', 10, 2);
|
||||
@@ -145,22 +145,26 @@ function apus_enqueue_accessibility() {
|
||||
add_action('wp_enqueue_scripts', 'apus_enqueue_accessibility', 15);
|
||||
|
||||
/**
|
||||
* Enqueue AdSense loader script
|
||||
* Enqueue del script de carga retrasada de AdSense
|
||||
*
|
||||
* Este script se encarga de detectar la primera interacción del usuario
|
||||
* (scroll, click, touch, etc.) y cargar los scripts de AdSense solo
|
||||
* en ese momento, mejorando significativamente el rendimiento inicial.
|
||||
*/
|
||||
function apus_enqueue_adsense_loader() {
|
||||
// Only run on frontend
|
||||
// Solo ejecutar en frontend
|
||||
if (is_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if AdSense delay is enabled
|
||||
$delay_enabled = get_theme_mod('apus_adsense_delay_enabled', true);
|
||||
// Verificar si el retardo de AdSense está habilitado
|
||||
$delay_enabled = apus_get_option('apus_adsense_delay_enabled', '1');
|
||||
|
||||
if (!$delay_enabled) {
|
||||
if ($delay_enabled !== '1') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Enqueue AdSense loader script
|
||||
// Enqueue del script de carga de AdSense
|
||||
wp_enqueue_script(
|
||||
'apus-adsense-loader',
|
||||
get_template_directory_uri() . '/assets/js/adsense-loader.js',
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
/**
|
||||
* Featured Image Functions
|
||||
*
|
||||
* Configurable featured image display with lazy loading support.
|
||||
* Funciones para manejo de imágenes destacadas con comportamiento configurable.
|
||||
* Sin placeholders - solo muestra imagen si existe.
|
||||
* Issue #10 - Imágenes destacadas configurables
|
||||
*
|
||||
* @package Apus_Theme
|
||||
* @since 1.0.0
|
||||
@@ -14,132 +16,458 @@ if (!defined('ABSPATH')) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Featured Image HTML
|
||||
* Obtiene la imagen destacada de un post con configuración respetada
|
||||
*
|
||||
* Returns the HTML for the featured image based on theme options.
|
||||
* Supports lazy loading and configurable display per post type.
|
||||
* Retorna HTML de la imagen destacada verificando:
|
||||
* - Si las imágenes destacadas están habilitadas globalmente
|
||||
* - Si el post tiene una imagen destacada asignada
|
||||
* - Retorna HTML de la imagen o cadena vacía (sin placeholder)
|
||||
*
|
||||
* @param int $post_id Optional. Post ID. Defaults to current post.
|
||||
* @param string $size Optional. Image size. Default 'apus-featured-large'.
|
||||
* @param array $attr Optional. Additional attributes for the image.
|
||||
* @param bool $force_show Optional. Force display regardless of settings. Default false.
|
||||
* @return string HTML markup for featured image or empty string.
|
||||
* Tamaños disponibles:
|
||||
* - apus-featured-large: 1200x600 (para single posts)
|
||||
* - apus-featured-medium: 800x400 (para archives)
|
||||
* - apus-thumbnail: 400x300 (para widgets/sidebars)
|
||||
*
|
||||
* @param int|null $post_id ID del post (null = post actual)
|
||||
* @param string $size Tamaño de imagen registrado (default: apus-featured-large)
|
||||
* @param array $attr Atributos HTML adicionales para la imagen
|
||||
* @param bool $force_show Forzar mostrar ignorando configuración (default: false)
|
||||
* @return string HTML de la imagen o cadena vacía
|
||||
*/
|
||||
function apus_get_featured_image($post_id = null, $size = 'apus-featured-large', $attr = array(), $force_show = false) {
|
||||
// Get post ID if not provided
|
||||
// Obtener ID del post actual si no se especifica
|
||||
if (!$post_id) {
|
||||
$post_id = get_the_ID();
|
||||
}
|
||||
|
||||
// Check if post has thumbnail
|
||||
if (!has_post_thumbnail($post_id)) {
|
||||
// Si no hay ID válido, retornar vacío
|
||||
if (!$post_id) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Get post type
|
||||
// Verificar si el post tiene imagen destacada
|
||||
if (!has_post_thumbnail($post_id)) {
|
||||
return ''; // No placeholder - retornar vacío
|
||||
}
|
||||
|
||||
// Obtener tipo de post
|
||||
$post_type = get_post_type($post_id);
|
||||
|
||||
// Check if featured images are enabled for this post type
|
||||
// Verificar configuración global según tipo de contenido
|
||||
if (!$force_show) {
|
||||
$option_key = 'apus_featured_image_' . $post_type;
|
||||
$enabled = get_theme_mod($option_key, true); // Default enabled
|
||||
// Primero intentar con apus_get_option (sistema de opciones del tema)
|
||||
if (function_exists('apus_get_option')) {
|
||||
if ($post_type === 'post') {
|
||||
$enabled = apus_get_option('featured_image_single', true);
|
||||
} elseif ($post_type === 'page') {
|
||||
$enabled = apus_get_option('featured_image_page', true);
|
||||
} else {
|
||||
$enabled = apus_get_option('featured_image_' . $post_type, true);
|
||||
}
|
||||
} else {
|
||||
// Fallback a theme_mod
|
||||
$option_key = 'apus_featured_image_' . $post_type;
|
||||
$enabled = get_theme_mod($option_key, true);
|
||||
}
|
||||
|
||||
if (!$enabled) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// Default attributes
|
||||
// Atributos por defecto con Bootstrap img-fluid
|
||||
$default_attr = array(
|
||||
'alt' => get_the_title($post_id),
|
||||
'class' => 'img-fluid featured-image',
|
||||
'loading' => 'lazy',
|
||||
'class' => 'featured-image',
|
||||
'alt' => ''
|
||||
);
|
||||
|
||||
// Merge with custom attributes
|
||||
$attributes = wp_parse_args($attr, $default_attr);
|
||||
// Merge de atributos
|
||||
$attr = wp_parse_args($attr, $default_attr);
|
||||
|
||||
// Get the thumbnail HTML
|
||||
$thumbnail = get_the_post_thumbnail($post_id, $size, $attributes);
|
||||
// Si no hay alt text específico, usar el título del post
|
||||
if (empty($attr['alt'])) {
|
||||
$attr['alt'] = get_the_title($post_id);
|
||||
}
|
||||
|
||||
// Obtener HTML de la imagen
|
||||
$thumbnail = get_the_post_thumbnail($post_id, $size, $attr);
|
||||
|
||||
// Si no hay thumbnail, retornar vacío
|
||||
if (empty($thumbnail)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Wrap in container div
|
||||
$output = '<div class="post-thumbnail">';
|
||||
$output .= $thumbnail;
|
||||
$output .= '</div>';
|
||||
|
||||
return $output;
|
||||
// Retornar HTML de la imagen sin contenedor adicional
|
||||
return $thumbnail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display Featured Image
|
||||
* Muestra la imagen destacada de un post
|
||||
*
|
||||
* Echoes the featured image HTML.
|
||||
* Template tag para usar directamente en templates.
|
||||
* Echo wrapper de apus_get_featured_image().
|
||||
*
|
||||
* @param int $post_id Optional. Post ID. Defaults to current post.
|
||||
* @param string $size Optional. Image size. Default 'apus-featured-large'.
|
||||
* @param array $attr Optional. Additional attributes for the image.
|
||||
* @param bool $force_show Optional. Force display regardless of settings. Default false.
|
||||
* Uso en templates:
|
||||
* <?php apus_the_featured_image(); ?>
|
||||
* <?php apus_the_featured_image(null, 'apus-featured-medium'); ?>
|
||||
*
|
||||
* @param int|null $post_id ID del post (null = post actual)
|
||||
* @param string $size Tamaño de imagen registrado
|
||||
* @param array $attr Atributos HTML adicionales
|
||||
* @param bool $force_show Forzar mostrar ignorando configuración
|
||||
*/
|
||||
function apus_the_featured_image($post_id = null, $size = 'apus-featured-large', $attr = array(), $force_show = false) {
|
||||
echo apus_get_featured_image($post_id, $size, $attr, $force_show);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Featured Images are Enabled for Post Type
|
||||
* Obtiene HTML de thumbnail para archives y loops
|
||||
*
|
||||
* @param string $post_type Optional. Post type. Defaults to current post type.
|
||||
* @return bool True if enabled, false otherwise.
|
||||
* Versión optimizada para listados con tamaño medium y link al post.
|
||||
* Incluye clases responsive de Bootstrap.
|
||||
*
|
||||
* @param int|null $post_id ID del post (null = post actual)
|
||||
* @param bool $with_link Envolver en enlace al post (default: true)
|
||||
* @return string HTML del thumbnail o cadena vacía
|
||||
*/
|
||||
function apus_get_post_thumbnail($post_id = null, $with_link = true) {
|
||||
// Obtener ID del post actual si no se especifica
|
||||
if (!$post_id) {
|
||||
$post_id = get_the_ID();
|
||||
}
|
||||
|
||||
// Si no hay ID válido, retornar vacío
|
||||
if (!$post_id) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Verificar si el post tiene imagen destacada
|
||||
if (!has_post_thumbnail($post_id)) {
|
||||
return ''; // No placeholder - retornar vacío
|
||||
}
|
||||
|
||||
// Obtener la imagen con clases Bootstrap
|
||||
$image = get_the_post_thumbnail($post_id, 'apus-featured-medium', array(
|
||||
'class' => 'img-fluid post-thumbnail',
|
||||
'loading' => 'lazy',
|
||||
'alt' => get_the_title($post_id)
|
||||
));
|
||||
|
||||
// Si no hay imagen, retornar vacío
|
||||
if (!$image) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Construir HTML
|
||||
$html = '';
|
||||
|
||||
if ($with_link) {
|
||||
$html .= '<a href="' . esc_url(get_permalink($post_id)) . '" class="post-thumbnail-link d-block" aria-label="' . esc_attr(get_the_title($post_id)) . '">';
|
||||
}
|
||||
|
||||
$html .= $image;
|
||||
|
||||
if ($with_link) {
|
||||
$html .= '</a>';
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Muestra el thumbnail del post para archives
|
||||
*
|
||||
* Template tag para usar directamente en template-parts.
|
||||
* Echo wrapper de apus_get_post_thumbnail().
|
||||
*
|
||||
* Uso en templates:
|
||||
* <?php apus_the_post_thumbnail(); ?>
|
||||
* <?php apus_the_post_thumbnail(null, false); // sin link ?>
|
||||
*
|
||||
* @param int|null $post_id ID del post (null = post actual)
|
||||
* @param bool $with_link Envolver en enlace al post
|
||||
*/
|
||||
function apus_the_post_thumbnail($post_id = null, $with_link = true) {
|
||||
echo apus_get_post_thumbnail($post_id, $with_link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene HTML de thumbnail pequeño para widgets/sidebars
|
||||
*
|
||||
* Versión mini para listados compactos en sidebars.
|
||||
* Usa el tamaño apus-thumbnail (400x300).
|
||||
*
|
||||
* @param int|null $post_id ID del post (null = post actual)
|
||||
* @param bool $with_link Envolver en enlace al post (default: true)
|
||||
* @return string HTML del thumbnail o cadena vacía
|
||||
*/
|
||||
function apus_get_post_thumbnail_small($post_id = null, $with_link = true) {
|
||||
// Obtener ID del post actual si no se especifica
|
||||
if (!$post_id) {
|
||||
$post_id = get_the_ID();
|
||||
}
|
||||
|
||||
// Si no hay ID válido, retornar vacío
|
||||
if (!$post_id) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Verificar si el post tiene imagen destacada
|
||||
if (!has_post_thumbnail($post_id)) {
|
||||
return ''; // No placeholder - retornar vacío
|
||||
}
|
||||
|
||||
// Obtener la imagen
|
||||
$image = get_the_post_thumbnail($post_id, 'apus-thumbnail', array(
|
||||
'class' => 'img-fluid post-thumbnail-small',
|
||||
'loading' => 'lazy',
|
||||
'alt' => get_the_title($post_id)
|
||||
));
|
||||
|
||||
// Si no hay imagen, retornar vacío
|
||||
if (!$image) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Construir HTML
|
||||
$html = '';
|
||||
|
||||
if ($with_link) {
|
||||
$html .= '<a href="' . esc_url(get_permalink($post_id)) . '" class="post-thumbnail-link-small d-block" aria-label="' . esc_attr(get_the_title($post_id)) . '">';
|
||||
}
|
||||
|
||||
$html .= $image;
|
||||
|
||||
if ($with_link) {
|
||||
$html .= '</a>';
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Muestra el thumbnail pequeño del post
|
||||
*
|
||||
* Template tag para usar en widgets y sidebars.
|
||||
* Echo wrapper de apus_get_post_thumbnail_small().
|
||||
*
|
||||
* @param int|null $post_id ID del post (null = post actual)
|
||||
* @param bool $with_link Envolver en enlace al post
|
||||
*/
|
||||
function apus_the_post_thumbnail_small($post_id = null, $with_link = true) {
|
||||
echo apus_get_post_thumbnail_small($post_id, $with_link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifica si se debe mostrar la imagen destacada según configuración
|
||||
*
|
||||
* Función helper para usar en condicionales de templates.
|
||||
* Útil para estructuras if/else en templates.
|
||||
*
|
||||
* Uso en templates:
|
||||
* <?php if (apus_should_show_featured_image()): ?>
|
||||
* <div class="has-thumbnail">...</div>
|
||||
* <?php endif; ?>
|
||||
*
|
||||
* @param int|null $post_id ID del post (null = post actual)
|
||||
* @return bool True si debe mostrarse, false en caso contrario
|
||||
*/
|
||||
function apus_should_show_featured_image($post_id = null) {
|
||||
// Obtener ID del post actual si no se especifica
|
||||
if (!$post_id) {
|
||||
$post_id = get_the_ID();
|
||||
}
|
||||
|
||||
// Si no hay ID válido, retornar false
|
||||
if (!$post_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verificar si el post tiene imagen destacada
|
||||
if (!has_post_thumbnail($post_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Obtener tipo de post
|
||||
$post_type = get_post_type($post_id);
|
||||
|
||||
// Verificar configuración global según tipo de contenido
|
||||
if (function_exists('apus_get_option')) {
|
||||
if ($post_type === 'post') {
|
||||
$enabled = apus_get_option('featured_image_single', true);
|
||||
} elseif ($post_type === 'page') {
|
||||
$enabled = apus_get_option('featured_image_page', true);
|
||||
} else {
|
||||
$enabled = apus_get_option('featured_image_' . $post_type, true);
|
||||
}
|
||||
} else {
|
||||
// Fallback a theme_mod
|
||||
$option_key = 'apus_featured_image_' . $post_type;
|
||||
$enabled = get_theme_mod($option_key, true);
|
||||
}
|
||||
|
||||
return (bool) $enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene la URL de la imagen destacada
|
||||
*
|
||||
* Útil para backgrounds CSS o meta tags de redes sociales (Open Graph, Twitter Cards).
|
||||
*
|
||||
* Uso:
|
||||
* $image_url = apus_get_featured_image_url();
|
||||
* echo '<div style="background-image: url(' . $image_url . ')"></div>';
|
||||
*
|
||||
* @param int|null $post_id ID del post (null = post actual)
|
||||
* @param string $size Tamaño de imagen registrado (default: apus-featured-large)
|
||||
* @return string URL de la imagen o cadena vacía
|
||||
*/
|
||||
function apus_get_featured_image_url($post_id = null, $size = 'apus-featured-large') {
|
||||
// Obtener ID del post actual si no se especifica
|
||||
if (!$post_id) {
|
||||
$post_id = get_the_ID();
|
||||
}
|
||||
|
||||
// Si no hay ID válido, retornar vacío
|
||||
if (!$post_id) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Verificar si el post tiene imagen destacada
|
||||
if (!has_post_thumbnail($post_id)) {
|
||||
return ''; // No placeholder - retornar vacío
|
||||
}
|
||||
|
||||
// Obtener URL de la imagen
|
||||
$image_url = get_the_post_thumbnail_url($post_id, $size);
|
||||
|
||||
return $image_url ? esc_url($image_url) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene el contenedor responsive de imagen destacada con aspect ratio
|
||||
*
|
||||
* Incluye aspect ratio CSS y lazy loading para mejor rendimiento.
|
||||
* Evita layout shift (CLS) con ratio predefinido usando Bootstrap ratio utility.
|
||||
*
|
||||
* Uso en templates:
|
||||
* <?php echo apus_get_featured_image_responsive(); ?>
|
||||
* <?php echo apus_get_featured_image_responsive(null, 'apus-featured-medium', '16/9'); ?>
|
||||
*
|
||||
* @param int|null $post_id ID del post (null = post actual)
|
||||
* @param string $size Tamaño de imagen registrado (default: apus-featured-large)
|
||||
* @param string $aspect_ratio Ratio CSS - '2/1' para 2:1, '16/9', etc. (default: '2/1')
|
||||
* @return string HTML del contenedor con imagen o cadena vacía
|
||||
*/
|
||||
function apus_get_featured_image_responsive($post_id = null, $size = 'apus-featured-large', $aspect_ratio = '2/1') {
|
||||
// Obtener la imagen
|
||||
$image = apus_get_featured_image($post_id, $size);
|
||||
|
||||
// Si no hay imagen, retornar vacío
|
||||
if (empty($image)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Construir contenedor responsive con Bootstrap ratio y aspect-ratio CSS
|
||||
$html = '<div class="featured-image-wrapper ratio" style="--bs-aspect-ratio: ' . esc_attr($aspect_ratio) . '; aspect-ratio: ' . esc_attr($aspect_ratio) . ';">';
|
||||
$html .= $image;
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Muestra el contenedor responsive de imagen destacada
|
||||
*
|
||||
* Template tag para usar directamente en templates.
|
||||
* Echo wrapper de apus_get_featured_image_responsive().
|
||||
*
|
||||
* @param int|null $post_id ID del post (null = post actual)
|
||||
* @param string $size Tamaño de imagen registrado
|
||||
* @param string $aspect_ratio Ratio CSS (ej: '16/9', '2/1')
|
||||
*/
|
||||
function apus_the_featured_image_responsive($post_id = null, $size = 'apus-featured-large', $aspect_ratio = '2/1') {
|
||||
echo apus_get_featured_image_responsive($post_id, $size, $aspect_ratio);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifica si las imágenes destacadas están habilitadas para un tipo de post
|
||||
*
|
||||
* Función legacy mantenida por compatibilidad.
|
||||
*
|
||||
* @param string $post_type Tipo de post (vacío = post actual)
|
||||
* @return bool True si habilitadas, false en caso contrario
|
||||
*/
|
||||
function apus_is_featured_image_enabled($post_type = '') {
|
||||
if (empty($post_type)) {
|
||||
$post_type = get_post_type();
|
||||
}
|
||||
|
||||
if (!$post_type) {
|
||||
return true; // Default habilitado
|
||||
}
|
||||
|
||||
// Intentar con apus_get_option primero
|
||||
if (function_exists('apus_get_option')) {
|
||||
if ($post_type === 'post') {
|
||||
return apus_get_option('featured_image_single', true);
|
||||
} elseif ($post_type === 'page') {
|
||||
return apus_get_option('featured_image_page', true);
|
||||
} else {
|
||||
return apus_get_option('featured_image_' . $post_type, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback a theme_mod
|
||||
$option_key = 'apus_featured_image_' . $post_type;
|
||||
return (bool) get_theme_mod($option_key, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Featured Image Settings in Customizer
|
||||
* Registra configuración de imágenes destacadas en Customizer
|
||||
*
|
||||
* Adds controls to enable/disable featured images per post type.
|
||||
* Agrega controles para habilitar/deshabilitar imágenes destacadas por tipo de post.
|
||||
* Funciona como fallback si no hay panel de opciones del tema.
|
||||
*
|
||||
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
|
||||
* @param WP_Customize_Manager $wp_customize Objeto Theme Customizer
|
||||
*/
|
||||
function apus_featured_image_customizer($wp_customize) {
|
||||
// Add section
|
||||
// Solo agregar si no existe el panel de opciones del tema
|
||||
if (function_exists('apus_get_option')) {
|
||||
return; // El panel de opciones manejará esto
|
||||
}
|
||||
|
||||
// Agregar sección
|
||||
$wp_customize->add_section('apus_featured_images', array(
|
||||
'title' => __('Featured Images', 'apus-theme'),
|
||||
'title' => __('Imágenes Destacadas', 'apus-theme'),
|
||||
'description' => __('Configurar visualización de imágenes destacadas por tipo de contenido.', 'apus-theme'),
|
||||
'priority' => 30,
|
||||
));
|
||||
|
||||
// Get public post types
|
||||
// Obtener tipos de post públicos
|
||||
$post_types = get_post_types(array('public' => true), 'objects');
|
||||
|
||||
foreach ($post_types as $post_type) {
|
||||
// Skip attachments
|
||||
// Saltar attachments
|
||||
if ($post_type->name === 'attachment') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$setting_id = 'apus_featured_image_' . $post_type->name;
|
||||
|
||||
// Add setting
|
||||
// Agregar setting
|
||||
$wp_customize->add_setting($setting_id, array(
|
||||
'default' => true,
|
||||
'sanitize_callback' => 'wp_validate_boolean',
|
||||
'transport' => 'refresh',
|
||||
));
|
||||
|
||||
// Add control
|
||||
// Agregar control
|
||||
$wp_customize->add_control($setting_id, array(
|
||||
'label' => sprintf(
|
||||
/* translators: %s: post type label */
|
||||
__('Enable for %s', 'apus-theme'),
|
||||
/* translators: %s: nombre del tipo de post */
|
||||
__('Habilitar para %s', 'apus-theme'),
|
||||
$post_type->labels->name
|
||||
),
|
||||
'section' => 'apus_featured_images',
|
||||
|
||||
115
wp-content/themes/apus-theme/inc/search-disable.php
Normal file
115
wp-content/themes/apus-theme/inc/search-disable.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/**
|
||||
* Desactivar funcionalidad de búsqueda nativa de WordPress
|
||||
*
|
||||
* Este archivo desactiva completamente la búsqueda nativa de WordPress.
|
||||
* Las rutas de búsqueda retornarán 404.
|
||||
*
|
||||
* Comportamiento:
|
||||
* - Rutas de búsqueda (ej. /search/ o /?s=query desde raíz) → 404
|
||||
* - URLs válidas con parámetro ?s= → entregar página normal, ignorar parámetro
|
||||
*
|
||||
* @package Apus_Theme
|
||||
* @since 1.0.0
|
||||
* @link https://github.com/prime-leads-app/analisisdepreciosunitarios.com/issues/3
|
||||
*/
|
||||
|
||||
// Exit if accessed directly
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Desactivar widget de búsqueda de WordPress
|
||||
*
|
||||
* Remueve el widget de búsqueda del admin para prevenir su uso.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function apus_disable_search_widget() {
|
||||
unregister_widget('WP_Widget_Search');
|
||||
}
|
||||
add_action('widgets_init', 'apus_disable_search_widget');
|
||||
|
||||
/**
|
||||
* Bloquear queries de búsqueda
|
||||
*
|
||||
* Detecta búsquedas y las convierte en 404.
|
||||
* Si es una URL válida con parámetro ?s=, ignora el parámetro y entrega la página normal.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @param WP_Query $query La instancia de WP_Query.
|
||||
*/
|
||||
function apus_disable_search_queries($query) {
|
||||
// Solo procesar en el frontend y en la query principal
|
||||
if (is_admin() || !$query->is_main_query()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Si es una búsqueda
|
||||
if ($query->is_search()) {
|
||||
// Verificar si hay una página o post válido siendo solicitado
|
||||
// Si solo es búsqueda (sin otra query var significativa), retornar 404
|
||||
$query_vars = $query->query_vars;
|
||||
|
||||
// Si solo tiene el parámetro 's' y no está pidiendo una página específica
|
||||
if (isset($query_vars['s']) &&
|
||||
empty($query_vars['page_id']) &&
|
||||
empty($query_vars['pagename']) &&
|
||||
empty($query_vars['name']) &&
|
||||
empty($query_vars['p'])) {
|
||||
|
||||
// Forzar 404
|
||||
$query->set_404();
|
||||
status_header(404);
|
||||
nocache_headers();
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action('pre_get_posts', 'apus_disable_search_queries', 10);
|
||||
|
||||
/**
|
||||
* Remover enlaces de búsqueda del frontend
|
||||
*
|
||||
* Asegura que no haya formularios de búsqueda en el tema.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @return string Cadena vacía.
|
||||
*/
|
||||
function apus_disable_search_form() {
|
||||
return '';
|
||||
}
|
||||
add_filter('get_search_form', 'apus_disable_search_form');
|
||||
|
||||
/**
|
||||
* Prevenir indexación de páginas de búsqueda
|
||||
*
|
||||
* Añade noindex a cualquier página de búsqueda que pueda escapar.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function apus_noindex_search() {
|
||||
if (is_search()) {
|
||||
echo '<meta name="robots" content="noindex,nofollow">' . "\n";
|
||||
}
|
||||
}
|
||||
add_action('wp_head', 'apus_noindex_search', 1);
|
||||
|
||||
/**
|
||||
* Remover rewrite rules de búsqueda
|
||||
*
|
||||
* Elimina las reglas de reescritura relacionadas con búsqueda.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @param array $rules Reglas de reescritura de WordPress.
|
||||
* @return array Reglas modificadas sin búsqueda.
|
||||
*/
|
||||
function apus_remove_search_rewrite_rules($rules) {
|
||||
foreach ($rules as $rule => $rewrite) {
|
||||
if (preg_match('/search/', $rule)) {
|
||||
unset($rules[$rule]);
|
||||
}
|
||||
}
|
||||
return $rules;
|
||||
}
|
||||
add_filter('rewrite_rules_array', 'apus_remove_search_rewrite_rules');
|
||||
@@ -316,3 +316,30 @@ function apus_get_all_options() {
|
||||
function apus_reset_options() {
|
||||
return delete_option('apus_theme_options');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Table of Contents is enabled
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function apus_is_toc_enabled() {
|
||||
return apus_get_option('enable_toc', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get minimum headings required to display TOC
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function apus_get_toc_min_headings() {
|
||||
return (int) apus_get_option('toc_min_headings', 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TOC title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function apus_get_toc_title() {
|
||||
return apus_get_option('toc_title', __('Table of Contents', 'apus-theme'));
|
||||
}
|
||||
|
||||
@@ -79,13 +79,19 @@ function apus_generate_heading_id($text, $index) {
|
||||
* @return string HTML for the table of contents
|
||||
*/
|
||||
function apus_generate_toc($headings) {
|
||||
if (empty($headings) || count($headings) < 2) {
|
||||
return ''; // Don't show TOC if there are fewer than 2 headings
|
||||
// Get minimum headings required from theme options
|
||||
$min_headings = (int) apus_get_option('toc_min_headings', 2);
|
||||
|
||||
if (empty($headings) || count($headings) < $min_headings) {
|
||||
return ''; // Don't show TOC if there are fewer headings than required
|
||||
}
|
||||
|
||||
$toc_html = '<nav class="apus-toc" aria-label="' . esc_attr__('Table of Contents', 'apus-theme') . '">';
|
||||
// Get custom TOC title from theme options
|
||||
$toc_title = apus_get_toc_title();
|
||||
|
||||
$toc_html = '<nav class="apus-toc" aria-label="' . esc_attr($toc_title) . '">';
|
||||
$toc_html .= '<div class="apus-toc-header">';
|
||||
$toc_html .= '<h2 class="apus-toc-title">' . esc_html__('Table of Contents', 'apus-theme') . '</h2>';
|
||||
$toc_html .= '<h2 class="apus-toc-title">' . esc_html($toc_title) . '</h2>';
|
||||
$toc_html .= '<button class="apus-toc-toggle" aria-expanded="true" aria-controls="apus-toc-list">';
|
||||
$toc_html .= '<span class="toggle-icon" aria-hidden="true"></span>';
|
||||
$toc_html .= '<span class="screen-reader-text">' . esc_html__('Toggle Table of Contents', 'apus-theme') . '</span>';
|
||||
@@ -183,6 +189,13 @@ function apus_add_heading_ids($content) {
|
||||
* Hooks into apus_before_post_content to display TOC on single posts.
|
||||
*/
|
||||
function apus_display_toc() {
|
||||
// Check if TOC is enabled in theme options
|
||||
$toc_enabled = apus_get_option('enable_toc', true);
|
||||
|
||||
if (!$toc_enabled) {
|
||||
return; // TOC disabled in theme options
|
||||
}
|
||||
|
||||
// Only show on single posts
|
||||
if (!is_single()) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user