feat(analytics): eventos GA4 audio_play y share_click
fea-audio-player.php: el <audio> lleva data-post-id/data-voice; listener
en wp_footer dispara gtag('event','audio_play', {post_id, voice}) en el
primer play (no en cada resume).
fea-share.php: se sube también al repo (nunca se había comiteado). El
botón de Facebook lleva data-fea-share-track="facebook" + listener que
dispara gtag('event','share_click', {method, post_id}).
Ambos reusan el dataLayer/gtag que ya inicializa fea-analytics.php, sin
añadir JS de terceros. Verificado en local con Playwright (evento se
dispara correctamente en ambos casos).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,14 +9,17 @@ if (!defined('ABSPATH')) exit;
|
|||||||
|
|
||||||
/** Devuelve el HTML del reproductor para el post actual, o '' si no hay audio. */
|
/** Devuelve el HTML del reproductor para el post actual, o '' si no hay audio. */
|
||||||
function fea_audio_player_html(): string {
|
function fea_audio_player_html(): string {
|
||||||
$url = get_post_meta(get_the_ID(), 'fea_audio_url', true);
|
$id = get_the_ID();
|
||||||
|
$url = get_post_meta($id, 'fea_audio_url', true);
|
||||||
if (!$url) return '';
|
if (!$url) return '';
|
||||||
|
$voice = get_post_meta($id, 'fea_audio_voice', true) ?: 'NicoFeadulta2026';
|
||||||
return '<div class="fea-audio">'
|
return '<div class="fea-audio">'
|
||||||
. '<span class="fea-audio-label">'
|
. '<span class="fea-audio-label">'
|
||||||
. '<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true" focusable="false">'
|
. '<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true" focusable="false">'
|
||||||
. '<path fill="currentColor" d="M3 10v4h4l5 5V5L7 10H3zm13.5 2a4.5 4.5 0 0 0-2.5-4.03v8.06A4.5 4.5 0 0 0 16.5 12zM14 3.23v2.06a7 7 0 0 1 0 13.42v2.06a9 9 0 0 0 0-17.54z"/>'
|
. '<path fill="currentColor" d="M3 10v4h4l5 5V5L7 10H3zm13.5 2a4.5 4.5 0 0 0-2.5-4.03v8.06A4.5 4.5 0 0 0 16.5 12zM14 3.23v2.06a7 7 0 0 1 0 13.42v2.06a9 9 0 0 0 0-17.54z"/>'
|
||||||
. '</svg> Escucha</span>'
|
. '</svg> Escucha</span>'
|
||||||
. '<audio controls preload="none" src="' . esc_url($url) . '"></audio>'
|
. '<audio controls preload="none" src="' . esc_url($url) . '"'
|
||||||
|
. ' data-fea-audio-track data-post-id="' . esc_attr($id) . '" data-voice="' . esc_attr($voice) . '"></audio>'
|
||||||
. '</div>';
|
. '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,3 +63,27 @@ add_action('wp_head', function () {
|
|||||||
</style>
|
</style>
|
||||||
<?php
|
<?php
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Evento GA4 audio_play (issue tracking uso TTS). Un único evento por <audio>
|
||||||
|
// y carga de página, disparado en el primer 'play' (no en cada resume tras
|
||||||
|
// pausa/seek). gtag ya está definido por fea-analytics.php en wp_head prio 1,
|
||||||
|
// así que este script (footer) siempre lo encuentra disponible.
|
||||||
|
add_action('wp_footer', function () {
|
||||||
|
if (!is_singular('post')) return;
|
||||||
|
if (!get_post_meta(get_queried_object_id(), 'fea_audio_url', true)) return;
|
||||||
|
?>
|
||||||
|
<script>
|
||||||
|
document.querySelectorAll('audio[data-fea-audio-track]').forEach(function (audio) {
|
||||||
|
var fired = false;
|
||||||
|
audio.addEventListener('play', function () {
|
||||||
|
if (fired || typeof gtag !== 'function') return;
|
||||||
|
fired = true;
|
||||||
|
gtag('event', 'audio_play', {
|
||||||
|
post_id: audio.dataset.postId,
|
||||||
|
voice: audio.dataset.voice
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<?php
|
||||||
|
});
|
||||||
|
|||||||
@@ -0,0 +1,253 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* fea-share — Sección "Comparte Fe Adulta" en single posts + Open Graph tags.
|
||||||
|
* Botones: Facebook, Instagram (Web Share API + fallback copiar), Imprimir.
|
||||||
|
* Sin plugins externos, sin JS de terceros. El botón de Facebook dispara un
|
||||||
|
* evento GA4 share_click (mismo patrón que fea-audio-player.php: data-attribute
|
||||||
|
* + listener en wp_footer que llama a gtag, ya inicializado por fea-analytics.php).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Solo artículos reales: single post_type=post, excluyendo institucionales. */
|
||||||
|
function fea_share_eligible(): bool {
|
||||||
|
if (!is_singular('post')) return false;
|
||||||
|
if (function_exists('fea_hide_static_meta') && fea_hide_static_meta()) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Textos por idioma. */
|
||||||
|
function fea_share_labels(): array {
|
||||||
|
$lang = function_exists('fea_current_lang') ? fea_current_lang() : 'es';
|
||||||
|
$all = [
|
||||||
|
'es' => ['section' => 'Comparte FeAdulta', 'fb' => 'Facebook',
|
||||||
|
'ig' => 'Instagram', 'print' => 'Imprimir',
|
||||||
|
'copied' => '¡Enlace copiado! Compártelo en Instagram'],
|
||||||
|
'en' => ['section' => 'Share FeAdulta', 'fb' => 'Facebook',
|
||||||
|
'ig' => 'Instagram', 'print' => 'Print',
|
||||||
|
'copied' => 'Link copied! Share it on Instagram'],
|
||||||
|
'fr' => ['section' => 'Partager FeAdulta', 'fb' => 'Facebook',
|
||||||
|
'ig' => 'Instagram', 'print' => 'Imprimer',
|
||||||
|
'copied' => 'Lien copié ! Partagez-le sur Instagram'],
|
||||||
|
'it' => ['section' => 'Condividi FeAdulta', 'fb' => 'Facebook',
|
||||||
|
'ig' => 'Instagram', 'print' => 'Stampa',
|
||||||
|
'copied' => 'Link copiato! Condividilo su Instagram'],
|
||||||
|
'pt' => ['section' => 'Partilha FeAdulta', 'fb' => 'Facebook',
|
||||||
|
'ig' => 'Instagram', 'print' => 'Imprimir',
|
||||||
|
'copied' => 'Link copiado! Partilha-o no Instagram'],
|
||||||
|
];
|
||||||
|
return $all[$lang] ?? $all['es'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function fea_share_block_html(): string {
|
||||||
|
$t = fea_share_labels();
|
||||||
|
$url = rawurlencode(get_permalink());
|
||||||
|
|
||||||
|
$svg_fb = '<svg viewBox="0 0 24 24" width="17" height="17" aria-hidden="true" focusable="false" fill="currentColor"><path d="M22 12.06C22 6.5 17.52 2 12 2 6.48 2 2 6.5 2 12.06c0 5.02 3.66 9.18 8.44 9.94v-7.03H7.9v-2.9h2.54V9.85c0-2.51 1.49-3.9 3.78-3.9 1.09 0 2.24.2 2.24.2v2.46h-1.26c-1.24 0-1.63.78-1.63 1.57v1.88h2.78l-.44 2.9h-2.34V22c4.78-.76 8.44-4.92 8.44-9.94z"/></svg>';
|
||||||
|
$svg_ig = '<svg viewBox="0 0 24 24" width="17" height="17" aria-hidden="true" focusable="false" fill="currentColor"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 1.366.062 2.633.334 3.608 1.308.974.975 1.245 2.242 1.307 3.608.058 1.265.07 1.645.07 4.85s-.012 3.584-.07 4.85c-.062 1.366-.334 2.633-1.308 3.608-.975.974-2.242 1.245-3.608 1.307-1.265.058-1.645.07-4.849.07s-3.584-.012-4.85-.07c-1.366-.062-2.633-.334-3.608-1.308-.974-.975-1.245-2.242-1.307-3.608C2.175 15.584 2.163 15.204 2.163 12s.012-3.584.07-4.85c.062-1.366.334-2.633 1.308-3.608C4.516 2.497 5.783 2.226 7.149 2.164 8.414 2.106 8.794 2.094 12 2.094zm0-2.163c-3.259 0-3.667.014-4.947.072-1.613.074-3.067.39-4.213 1.535C1.695 2.803 1.38 4.257 1.305 5.87.014 8.194 0 8.602 0 12c0 3.259.014 3.667.072 4.947.074 1.613.39 3.067 1.535 4.213 1.146 1.145 2.6 1.46 4.213 1.535C8.333 23.986 8.741 24 12 24c3.259 0 3.667-.014 4.947-.072 1.613-.074 3.067-.39 4.213-1.535 1.145-1.146 1.46-2.6 1.535-4.213C23.986 15.667 24 15.259 24 12c0-3.259-.014-3.667-.072-4.947-.074-1.613-.39-3.067-1.535-4.213C21.247 1.695 19.793 1.38 18.18 1.305 15.807.014 15.399 0 12 0zm0 5.838a6.162 6.162 0 1 0 0 12.324 6.162 6.162 0 0 0 0-12.324zm0 10.162a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm6.406-11.845a1.44 1.44 0 1 0 0 2.881 1.44 1.44 0 0 0 0-2.881z"/></svg>';
|
||||||
|
$svg_pr = '<svg viewBox="0 0 24 24" width="17" height="17" aria-hidden="true" focusable="false" fill="currentColor"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7a1 1 0 0 1 0-2 1 1 0 0 1 0 2zm-1-9H6v4h12V3z"/></svg>';
|
||||||
|
|
||||||
|
$copied_msg = esc_js($t['copied']);
|
||||||
|
$post_id = get_the_ID();
|
||||||
|
|
||||||
|
return '
|
||||||
|
<div class="fea-share">
|
||||||
|
<div class="fea-share-rule" aria-hidden="true"></div>
|
||||||
|
<div class="fea-share-row">
|
||||||
|
<span class="fea-share-label">' . esc_html($t['section']) . '</span>
|
||||||
|
<a href="https://www.facebook.com/sharer/sharer.php?u=' . $url . '"
|
||||||
|
target="_blank" rel="noopener noreferrer nofollow"
|
||||||
|
class="fea-share-item fea-share-fb"
|
||||||
|
data-fea-share-track="facebook" data-post-id="' . esc_attr($post_id) . '">
|
||||||
|
' . $svg_fb . '<span>' . esc_html($t['fb']) . '</span>
|
||||||
|
</a>
|
||||||
|
<span class="fea-share-sep" aria-hidden="true">·</span>
|
||||||
|
<button type="button" class="fea-share-item fea-share-ig"
|
||||||
|
data-copied="' . esc_attr($t['copied']) . '">
|
||||||
|
' . $svg_ig . '<span>' . esc_html($t['ig']) . '</span>
|
||||||
|
</button>
|
||||||
|
<span class="fea-share-sep" aria-hidden="true">·</span>
|
||||||
|
<button type="button" class="fea-share-item fea-share-print"
|
||||||
|
onclick="window.print()">
|
||||||
|
' . $svg_pr . '<span>' . esc_html($t['print']) . '</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="fea-share-toast" aria-live="polite"></div>
|
||||||
|
</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function fea_share_already_rendered(string $content): bool {
|
||||||
|
return strpos($content, 'class="fea-share"') !== false
|
||||||
|
|| strpos($content, "class='fea-share'") !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Bloque al final del contenido ────────────────────────────────────────────
|
||||||
|
add_filter('the_content', function ($content) {
|
||||||
|
if (is_admin() || !fea_share_eligible() || !is_main_query() || !in_the_loop()) {
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
if (fea_share_already_rendered($content)) return $content;
|
||||||
|
return $content . fea_share_block_html();
|
||||||
|
}, 20);
|
||||||
|
|
||||||
|
add_filter('render_block', function ($block_content, $block) {
|
||||||
|
if (is_admin() || !fea_share_eligible()) return $block_content;
|
||||||
|
if (($block['blockName'] ?? '') !== 'core/post-content') return $block_content;
|
||||||
|
if (fea_share_already_rendered($block_content)) return $block_content;
|
||||||
|
return $block_content . fea_share_block_html();
|
||||||
|
}, 20, 2);
|
||||||
|
|
||||||
|
// ── CSS (screen + print) ─────────────────────────────────────────────────────
|
||||||
|
add_action('wp_head', function () {
|
||||||
|
if (!fea_share_eligible()) return;
|
||||||
|
?>
|
||||||
|
<style>
|
||||||
|
/* ── Sección compartir ── */
|
||||||
|
.fea-share { margin: 2.5rem 0 1rem; }
|
||||||
|
|
||||||
|
.fea-share-rule {
|
||||||
|
border: none; border-top: 1px solid #e2d9d0; margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fea-share-row {
|
||||||
|
display: flex; align-items: center; flex-wrap: wrap;
|
||||||
|
gap: .15rem .4rem; color: #5a4a42;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fea-share-label {
|
||||||
|
font-size: .78rem; font-weight: 700; letter-spacing: .06em;
|
||||||
|
text-transform: uppercase; color: #8a7a72; margin-right: .4rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset total de <button> + alineación compartida con <a> */
|
||||||
|
.fea-share-item {
|
||||||
|
display: inline-flex; align-items: center; gap: .32rem;
|
||||||
|
background: none; border: none; padding: 0; margin: 0; cursor: pointer;
|
||||||
|
font-family: inherit; font-size: .84rem; font-weight: 600; line-height: 1;
|
||||||
|
color: #8b1a2e; text-decoration: none;
|
||||||
|
transition: color .15s;
|
||||||
|
}
|
||||||
|
.fea-share-item:hover { color: #5a1220; }
|
||||||
|
.fea-share-item svg { display: block; flex-shrink: 0; }
|
||||||
|
|
||||||
|
.fea-share-sep { color: #c9b8ae; font-size: .84rem; line-height: 1; user-select: none; }
|
||||||
|
|
||||||
|
/* Toast */
|
||||||
|
.fea-share-toast {
|
||||||
|
font-size: .8rem; color: #1b7a34; margin-top: .5rem;
|
||||||
|
min-height: 1.1em; transition: opacity .3s;
|
||||||
|
}
|
||||||
|
.fea-share-toast.hidden { opacity: 0; }
|
||||||
|
|
||||||
|
/* ── CSS de impresión ── */
|
||||||
|
@media print {
|
||||||
|
/* Ocultar todo lo que no es contenido editorial */
|
||||||
|
#fea-beta-bar, #fea-fb,
|
||||||
|
.fea-share, .fea-share-btns,
|
||||||
|
header, nav, footer,
|
||||||
|
.wp-block-navigation, .wp-site-logo,
|
||||||
|
.fea-pensamientos-wrap, .fea-cookie-consent,
|
||||||
|
#wpadminbar { display: none !important; }
|
||||||
|
|
||||||
|
body, .entry-content, .wp-block-post-content {
|
||||||
|
font-size: 12pt; line-height: 1.6; color: #000;
|
||||||
|
background: #fff; margin: 0; padding: 0;
|
||||||
|
}
|
||||||
|
a { color: #000; text-decoration: underline; }
|
||||||
|
a[href]::after { content: none; } /* no imprimir URLs */
|
||||||
|
img { max-width: 100%; }
|
||||||
|
h1, h2, h3 { page-break-after: avoid; }
|
||||||
|
p { orphans: 3; widows: 3; }
|
||||||
|
|
||||||
|
/* Cabecera de impresión con nombre del sitio */
|
||||||
|
body::before {
|
||||||
|
content: "FeAdulta — feadulta.com";
|
||||||
|
display: block; font-size: 9pt; color: #666;
|
||||||
|
border-bottom: 1px solid #ccc; padding-bottom: 4pt;
|
||||||
|
margin-bottom: 12pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<?php
|
||||||
|
}, 20);
|
||||||
|
|
||||||
|
// ── JS: Instagram (Web Share API + fallback copiar) ──────────────────────────
|
||||||
|
add_action('wp_footer', function () {
|
||||||
|
if (!fea_share_eligible()) return;
|
||||||
|
?>
|
||||||
|
<script>
|
||||||
|
(function(){
|
||||||
|
var btn = document.querySelector('.fea-share-ig');
|
||||||
|
if (!btn) return;
|
||||||
|
var toast = document.querySelector('.fea-share-toast');
|
||||||
|
var copied = btn.getAttribute('data-copied');
|
||||||
|
var url = <?php echo json_encode(get_permalink()); ?>;
|
||||||
|
var title = <?php
|
||||||
|
$post = get_queried_object();
|
||||||
|
$raw = $post instanceof WP_Post ? get_the_title($post) : '';
|
||||||
|
$t = function_exists('fea_title') ? fea_title($raw) : $raw;
|
||||||
|
echo json_encode($t);
|
||||||
|
?>;
|
||||||
|
|
||||||
|
btn.addEventListener('click', function () {
|
||||||
|
if (navigator.share) {
|
||||||
|
navigator.share({ title: title, url: url }).catch(function(){});
|
||||||
|
} else {
|
||||||
|
navigator.clipboard.writeText(url).then(function(){
|
||||||
|
if (toast) {
|
||||||
|
toast.textContent = copied;
|
||||||
|
toast.classList.remove('hidden');
|
||||||
|
setTimeout(function(){ toast.classList.add('hidden'); }, 3000);
|
||||||
|
}
|
||||||
|
}).catch(function(){});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
document.querySelectorAll('[data-fea-share-track]').forEach(function (el) {
|
||||||
|
el.addEventListener('click', function () {
|
||||||
|
if (typeof gtag !== 'function') return;
|
||||||
|
gtag('event', 'share_click', {
|
||||||
|
method: el.dataset.feaShareTrack,
|
||||||
|
post_id: el.dataset.postId
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<?php
|
||||||
|
}, 20);
|
||||||
|
|
||||||
|
// ── Open Graph tags ───────────────────────────────────────────────────────────
|
||||||
|
add_action('wp_head', function () {
|
||||||
|
if (!fea_share_eligible()) return;
|
||||||
|
$post = get_queried_object();
|
||||||
|
if (!$post instanceof WP_Post) return;
|
||||||
|
|
||||||
|
$raw = get_the_title($post);
|
||||||
|
$title = function_exists('fea_title') ? fea_title($raw) : $raw;
|
||||||
|
$desc = has_excerpt($post)
|
||||||
|
? get_the_excerpt($post)
|
||||||
|
: wp_trim_words(wp_strip_all_tags($post->post_content), 30, '…');
|
||||||
|
$url = get_permalink($post);
|
||||||
|
|
||||||
|
$img = get_the_post_thumbnail_url($post, 'large');
|
||||||
|
if (!$img && preg_match('~<img[^>]+src="([^"]+)"~', $post->post_content, $m)) {
|
||||||
|
$img = $m[1];
|
||||||
|
}
|
||||||
|
if ($img && strpos($img, 'http') !== 0) {
|
||||||
|
if (strpos($img, '//') === 0) {
|
||||||
|
$img = (is_ssl() ? 'https:' : 'http:') . $img;
|
||||||
|
} elseif ($img[0] === '/') {
|
||||||
|
$origin = preg_replace('~^(https?://[^/]+).*~', '$1', home_url('/'));
|
||||||
|
$img = $origin . $img;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
echo '<meta property="og:type" content="article" />' . "\n";
|
||||||
|
echo '<meta property="og:site_name" content="Fe Adulta" />' . "\n";
|
||||||
|
echo '<meta property="og:title" content="' . esc_attr($title) . '" />' . "\n";
|
||||||
|
echo '<meta property="og:description" content="' . esc_attr($desc) . '" />' . "\n";
|
||||||
|
echo '<meta property="og:url" content="' . esc_url($url) . '" />' . "\n";
|
||||||
|
if ($img) {
|
||||||
|
echo '<meta property="og:image" content="' . esc_url($img) . '" />' . "\n";
|
||||||
|
}
|
||||||
|
}, 5);
|
||||||
Reference in New Issue
Block a user