function highlightAnchorLinks() {
// Get the menu elements
const primaryMenu = document.getElementById('primary-menu');
const mobileMenu = document.getElementById('mobile-menu');
// Get all anchor links within the primary menu
const primaryAnchorLinks = primaryMenu.querySelectorAll('li > a[href*="#"]');
// Get all anchor links within the mobile menu
const mobileAnchorLinks = mobileMenu.querySelectorAll('li > a[href*="#"]');
// Function to extract the target ID from the href attribute
const extractTargetId = (href) => {
const hashIndex = href.indexOf('#');
return hashIndex !== -1 ? href.substring(hashIndex + 1) : null;
};
// Create an intersection observer instance for the primary menu
const primaryObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
const targetId = entry.target.getAttribute('id');
const listItem = primaryMenu.querySelector(`li > a[href$="#${targetId}"]`).parentNode;
if (entry.isIntersecting && entry.intersectionRatio >= 0.5) {
const activeListItem = primaryMenu.querySelector('.current-menu-item');
if (activeListItem) {
activeListItem.classList.remove('current-menu-item', 'current_page_item');
}
listItem.classList.add('current-menu-item', 'current_page_item');
} else {
listItem.classList.remove('current-menu-item', 'current_page_item');
}
});
}, { threshold: [0.5] });
// Create an intersection observer instance for the mobile menu
const mobileObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
const targetId = entry.target.getAttribute('id');
const listItem = mobileMenu.querySelector(`li > a[href$="#${targetId}"]`).parentNode;
if (entry.isIntersecting && entry.intersectionRatio >= 0.5) {
const activeListItem = mobileMenu.querySelector('.current-menu-item');
if (activeListItem) {
activeListItem.classList.remove('current-menu-item', 'current_page_item');
}
listItem.classList.add('current-menu-item', 'current_page_item');
} else {
listItem.classList.remove('current-menu-item', 'current_page_item');
}
});
}, { threshold: [0.5] });
// Observe each section for the primary menu
primaryAnchorLinks.forEach(anchorLink => {
const targetId = extractTargetId(anchorLink.getAttribute('href'));
const section = document.getElementById(targetId);
if (section) {
primaryObserver.observe(section);
}
});
// Observe each section for the mobile menu
mobileAnchorLinks.forEach(anchorLink => {
const targetId = extractTargetId(anchorLink.getAttribute('href'));
const section = document.getElementById(targetId);
if (section) {
mobileObserver.observe(section);
}
});
}
// Call the function when the DOM is fully loaded
document.addEventListener('DOMContentLoaded', highlightAnchorLinks);
Autor: Jordi Mont
Hooks portfolio block Kadence
/**
* Server rendering for Post Block Inner Loop
*
* @param array $attributes the block attributes.
*/
function kadence_blocks_pro_render_portfolio_block_loop( $attributes ) {
$image_align = ( isset( $attributes['alignImage'] ) && isset( $attributes['displayImage'] ) && true === $attributes['displayImage'] && has_post_thumbnail() ? $attributes['alignImage'] : 'none' );
echo '<div class="kb-blocks-portfolio-grid-item">';
do_action( 'kadence_blocks_portfolio_loop_start', $attributes );
echo '<div class="kb-blocks-portfolio-grid-item-inner-wrap kb-feat-image-align-' . esc_attr( $image_align ) . '">';
/**
* Kadence Blocks Portfolio Loop Start
*
* @hooked kb_blocks_pro_get_portfolio_image - 20
*/
do_action( 'kadence_blocks_portfolio_loop_image', $attributes );
echo '<div class="kb-portfolio-grid-item-inner">';
/**
* Kadence Blocks Portfolio before Hover content.
*
* @hooked kb_blocks_pro_portfolio_hover_link - 10
* @hooked kb_blocks_pro_portfolio_hover_divs - 20
*/
do_action( 'kadence_blocks_portfolio_loop_before_content', $attributes );
echo '<div class="kb-portfolio-content-item-inner">';
/**
* Kadence Blocks Portfolio Hover content.
*
* @hooked kb_blocks_pro_get_portfolio_lightbox - 20
* @hooked kb_blocks_pro_get_portfolio_title - 20
* @hooked kb_blocks_pro_get_portfolio_taxonomies - 30
* @hooked kb_blocks_pro_get_portfolio_excerpt - 40
*/
do_action( 'kadence_blocks_portfolio_loop_content_inner', $attributes );
echo '</div>';
echo '</div>';
echo '</div>';
do_action( 'kadence_blocks_portfolio_loop_end', $attributes );
echo '</div>';
}Ruta: /wp-content/plugins/kadence-blocks-pro/dist/dynamicblocks/portfolio-grid-carousel.php
Database Cleaner & Optimizer
Descripció
El millor netejador de bases de dades des del 2022! Netegeu la vostra base de dades de veritat, sigui quina sigui la seva mida. També se centra en allò que importa, per tal que el vostre WordPress sigui més ràpid. Una interfície d’usuari amigable i moderna us ajudarà a fer-ho tot perfecte. Si hi ha massa dades per eliminar, Database Cleaner utilitzarà sol·licituds asíncrones per processar-les a poc a poc per evitar errors i temps d’espera.
Enllaç: https://wordpress.org/plugins/database-cleaner/
Per provar encara…
Thrive Automator
Descripció:
Thrive Automator és un connector GRATUÏT que us permet crear automatitzacions potents connectant les vostres eines preferides amb el vostre lloc web de WordPress.
Enllaç: https://wordpress.org/plugins/thrive-automator/
No provat encara…
IndexNow Plugin
Descripció
El connector IndexNow per a WordPress permet l’enviament automàtic d’URL dels llocs de WordPress als diversos motors de cerca sense necessitat de registrar-se i verificar el vostre lloc amb ells. Un cop instal·lat, el connector generarà i allotjarà automàticament la clau API al vostre lloc. Detecta la creació/actualització/supressió de pàgines a WordPress i envia automàticament els URL en segon pla. Això garanteix que els motors de cerca sempre tindran les últimes actualitzacions sobre el vostre lloc. Aquest connector envia URL a un punt final genèric “https://api.indexnow.org/indexnow” i aquests URL es comparteixen amb tots els motors de cerca participants.
Enlaç: https://wordpress.org/plugins/indexnow/
No provat encara…
Burst Statistics – Privacy-Friendly Analytics for WordPress
Descripció:
Obteniu informació detallada sobre el comportament dels visitants amb Burst Statistics, el tauler d’anàlisi de privadesa de Really Simple Plugins.
Enllaç: https://wordpress.org/plugins/burst-statistics/
Provant a Milimetricmkt.com
Extendify — Gutenberg Patterns and Templates
Descripció:
Extendify és la plataforma d’eines de disseny i creació de llocs per a persones que volen crear un bell lloc web de WordPress amb una biblioteca de patrons i dissenys de pàgina completa per a l’editor de blocs Gutenberg.
Feu que un bell lloc web de WordPress sigui més fàcil i ràpid que mai amb la biblioteca d’Extendify de patrons de blocs, plantilles i dissenys de pàgina per a Gutenberg.
Enllaç: https://wordpress.org/plugins/extendify/
Per provar encara…
Local Google Fonts
Descripció:
Allotja els teus tipus de lletra de Google usats al teu servidor i fes que el teu lloc compleixi més amb GDPR 💯.
Enllaç: https://wordpress.org/plugins/local-google-fonts/
Backuply – Backup, Restore, Migrate and Clone
Backuply és un connector de WordPress que ajuda a fer una còpia de seguretat del lloc web de WordPress.
Permet còpies, enviar a remot, i restaurar. També serveix per fer canvis de domini/servidor.
Enllaç: https://wordpress.org/plugins/backuply/
Per provar encara.
Afegim a la url del CTP la taxonomia
Codi per afegir a la url d’un Cutsom Post Type, una taxonomia.
Ex:
Passem de: Domini/directorio/slug-post/
A: Domini/directorio/Taxonomia/slug-post/
A tindre en compte: quan declarem el CTP, l’opció de slug ha de tindre un, en el cas de l’exemple una forma com: directorio/%tax%
El codi el que fa és substituir el %tax% per la categoria i després fem la configuració del rewrite perquè aquests enllaços no siguin 404.
/**
* Afegim a la url de wordpress la taxonomia
* Fem servir el "post_type_link" per trucar el link
* Fem servir el "generate_rewrite_rules" perque no surti 404 al visitar el link trucat.
* Hem de referscar els enllaços permanets
*
*
*/
add_filter('post_type_link', 'my_custom_permalink', 10, 3);
function my_custom_permalink($permalink, $post_id, $leavename)
{
if ((strpos($permalink, '%tax%') === FALSE)) // %tax% -> string que posem al slug del CTP. Ex: directorio/%tax%
return $permalink;
$post = get_post($post_id);
if (!$post) return $permalink;
$y_terms = wp_get_object_terms($post->ID, 'categorias_directorio'); // canviar per el nom de la categoria
if (!is_wp_error($y_terms) && !empty($y_terms) && is_object($y_terms[0])) $y_taxonomy_slug = $y_terms[0]->slug;
return str_replace('%tax%', $y_taxonomy_slug, $permalink); // %tax%
}
function directorio_cpt_generating_rule($wp_rewrite)
{
$rules = array();
$terms = get_terms(array(
'taxonomy' => 'categorias_directorio', // canviar per el nom de la categoria
'hide_empty' => false,
));
$post_type = 'directorio'; // canviar per el nom del CTP
foreach ($terms as $term) {
// canviar per el slug del CTP. Primera part nom normal. Taxonomia. Nom del CTP.
$rules['directorio/' . $term->slug . '/([^/]*)$'] = 'index.php?post_type=' . $post_type . '&directorio=$matches[1]&name=$matches[1]';
}
// merge with global rules
$wp_rewrite->rules = $rules + $wp_rewrite->rules;
}
add_filter('generate_rewrite_rules', 'directorio_cpt_generating_rule');