correction doublons index Ajax + découplage slug categories couleurs
This commit is contained in:
29
category.php
29
category.php
@@ -10,10 +10,10 @@ if ( ! is_user_logged_in() ) $excluded_ids[] = 9; // Vie du labo
|
|||||||
// Parent category slug for color theming
|
// Parent category slug for color theming
|
||||||
if ($category->parent) {
|
if ($category->parent) {
|
||||||
$parent_cat = get_category($category->parent);
|
$parent_cat = get_category($category->parent);
|
||||||
$context['parent_slug'] = $parent_cat->slug;
|
$context['parent_slug'] = thalim_category_color_slug($parent_cat->term_id, $parent_cat->slug);
|
||||||
$context['active_rubrique'] = $parent_cat->term_id;
|
$context['active_rubrique'] = $parent_cat->term_id;
|
||||||
} else {
|
} else {
|
||||||
$context['parent_slug'] = $category->slug;
|
$context['parent_slug'] = thalim_category_color_slug($category->term_id, $category->slug);
|
||||||
$context['active_rubrique'] = $category->term_id;
|
$context['active_rubrique'] = $category->term_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,6 +227,12 @@ if (!$is_direct && !empty($children)) {
|
|||||||
} else {
|
} else {
|
||||||
$context['is_parent'] = false;
|
$context['is_parent'] = false;
|
||||||
$context['is_direct'] = $is_direct;
|
$context['is_direct'] = $is_direct;
|
||||||
|
|
||||||
|
// Épinglés sortis du flux principal (et exclus de la pagination AJAX par thalim_load_more_posts),
|
||||||
|
// affichés dans un bloc dédié en tête. Garde l'initial et l'AJAX sur le même univers : sinon la
|
||||||
|
// fenêtre de pagination se décale et le post de la couture est dupliqué.
|
||||||
|
$pinned_ids = thalim_get_active_pinned_ids( $category->term_id );
|
||||||
|
|
||||||
$query_args = array_merge([
|
$query_args = array_merge([
|
||||||
'post_type' => 'post',
|
'post_type' => 'post',
|
||||||
'tax_query' => [[
|
'tax_query' => [[
|
||||||
@@ -241,8 +247,23 @@ if (!$is_direct && !empty($children)) {
|
|||||||
'lang' => '',
|
'lang' => '',
|
||||||
'thalim_event_date_order' => true,
|
'thalim_event_date_order' => true,
|
||||||
], $extra_query_args);
|
], $extra_query_args);
|
||||||
$posts = $sort_with_pinned( Timber::get_posts($query_args) );
|
if ( $pinned_ids ) {
|
||||||
$context['cards'] = thalim_get_cards_data($posts);
|
$query_args['post__not_in'] = $pinned_ids;
|
||||||
|
}
|
||||||
|
$posts = Timber::get_posts($query_args);
|
||||||
|
|
||||||
|
// Pinned posts, respecting the active axe/date filters (so a pin outside the filter doesn't show).
|
||||||
|
$pinned_posts = $pinned_ids ? Timber::get_posts( array_merge([
|
||||||
|
'post_type' => 'post',
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'post__in' => $pinned_ids,
|
||||||
|
'orderby' => 'post__in',
|
||||||
|
'posts_per_page' => -1,
|
||||||
|
'lang' => '',
|
||||||
|
], $extra_query_args ) ) : [];
|
||||||
|
|
||||||
|
$context['cards'] = thalim_get_cards_data($pinned_posts) + thalim_get_cards_data($posts);
|
||||||
|
$context['pinned_posts'] = $pinned_posts;
|
||||||
$context['posts'] = $posts;
|
$context['posts'] = $posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,6 +125,24 @@ function thalim_cat_name( $cat, string $lang = null ): string {
|
|||||||
return ( $en !== '' && $en !== false ) ? $en : $fallback;
|
return ( $en !== '' && $en !== false ) ? $en : $fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clé couleur stable d'une catégorie racine, indexée sur le term_id (immuable)
|
||||||
|
* plutôt que sur le slug (que l'admin peut régénérer en renommant la catégorie).
|
||||||
|
* Renvoie la clé canonique attendue par les classes CSS .gradient--{clé} /
|
||||||
|
* .category--{clé} (_postcard.scss, _single.scss, _category.scss).
|
||||||
|
* Fallback sur le slug live pour toute racine hors des 5 rubriques connues.
|
||||||
|
*/
|
||||||
|
function thalim_category_color_slug( $root_term_id, $fallback_slug = '' ) {
|
||||||
|
$map = [
|
||||||
|
1 => 'le-laboratoire',
|
||||||
|
3 => 'manifestations-scientifiques',
|
||||||
|
4 => 'publications-et-productions',
|
||||||
|
5 => 'mediation-scientifique',
|
||||||
|
6 => 'ressources',
|
||||||
|
];
|
||||||
|
return $map[ (int) $root_term_id ] ?? $fallback_slug;
|
||||||
|
}
|
||||||
|
|
||||||
// Register bilingual and en_url as Twig filters
|
// Register bilingual and en_url as Twig filters
|
||||||
add_filter( 'timber/twig', function ( $twig ) {
|
add_filter( 'timber/twig', function ( $twig ) {
|
||||||
$twig->addFilter( new \Twig\TwigFilter( 'bilingual', 'thalim_bilingual' ) );
|
$twig->addFilter( new \Twig\TwigFilter( 'bilingual', 'thalim_bilingual' ) );
|
||||||
@@ -910,6 +928,41 @@ add_filter( 'login_redirect', function( $redirect_to, $requested, $user ) {
|
|||||||
return $redirect_to;
|
return $redirect_to;
|
||||||
}, 10, 3 );
|
}, 10, 3 );
|
||||||
|
|
||||||
|
// Return the IDs of posts currently pinned ("épinglé dans la catégorie") in a given category.
|
||||||
|
// A pin is active if epingler_dans_la_categorie == 1 AND date_de_fin_depinglage is empty/0000-00-00/future.
|
||||||
|
// Shared by category.php (pull them out of the main flow) and the AJAX handler (exclude them from
|
||||||
|
// pagination) so both sides stay in sync — a mismatch shifts the page boundary and dupes posts.
|
||||||
|
function thalim_get_active_pinned_ids( $category_id ) {
|
||||||
|
if ( ! $category_id ) return [];
|
||||||
|
$today = date( 'Y-m-d' );
|
||||||
|
$pinned_query = new WP_Query([
|
||||||
|
'post_type' => 'post',
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'posts_per_page' => -1,
|
||||||
|
'fields' => 'ids',
|
||||||
|
'no_found_rows' => true,
|
||||||
|
'lang' => '',
|
||||||
|
'tax_query' => [[
|
||||||
|
'taxonomy' => 'category',
|
||||||
|
'field' => 'term_id',
|
||||||
|
'terms' => [ $category_id ],
|
||||||
|
'include_children' => false,
|
||||||
|
]],
|
||||||
|
'meta_query' => [[
|
||||||
|
'key' => 'epingler_dans_la_categorie',
|
||||||
|
'value' => '1',
|
||||||
|
]],
|
||||||
|
]);
|
||||||
|
$pinned_ids = [];
|
||||||
|
foreach ( $pinned_query->posts as $pid ) {
|
||||||
|
$fin = get_post_meta( $pid, 'date_de_fin_depinglage', true );
|
||||||
|
if ( empty( $fin ) || $fin === '0000-00-00' || $fin >= $today ) {
|
||||||
|
$pinned_ids[] = $pid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $pinned_ids;
|
||||||
|
}
|
||||||
|
|
||||||
// AJAX handler for infinite scroll on category pages
|
// AJAX handler for infinite scroll on category pages
|
||||||
function thalim_load_more_posts() {
|
function thalim_load_more_posts() {
|
||||||
check_ajax_referer('load_more_posts', 'nonce');
|
check_ajax_referer('load_more_posts', 'nonce');
|
||||||
@@ -930,6 +983,7 @@ function thalim_load_more_posts() {
|
|||||||
|
|
||||||
$query_args = [
|
$query_args = [
|
||||||
'post_type' => 'post',
|
'post_type' => 'post',
|
||||||
|
'post_status' => 'publish', // admin-ajax => is_admin() true: sans ça WP ajoute future/draft/pending et décale la pagination vs le front
|
||||||
'posts_per_page' => 12,
|
'posts_per_page' => 12,
|
||||||
'paged' => $page,
|
'paged' => $page,
|
||||||
'orderby' => 'date',
|
'orderby' => 'date',
|
||||||
@@ -1005,33 +1059,10 @@ function thalim_load_more_posts() {
|
|||||||
$query_args['thalim_event_date_filter'] = ['from' => $date_from, 'to' => $date_to];
|
$query_args['thalim_event_date_filter'] = ['from' => $date_from, 'to' => $date_to];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exclude pinned posts on category pages to avoid duplicates (they already appear at the top)
|
// Exclude pinned posts on category pages to avoid duplicates (they already appear at the top,
|
||||||
|
// pulled out of the main flow by category.php). Must mirror category.php exactly.
|
||||||
if ($category) {
|
if ($category) {
|
||||||
$today = date( 'Y-m-d' );
|
$pinned_ids = thalim_get_active_pinned_ids( $category );
|
||||||
$pinned_query = new WP_Query([
|
|
||||||
'post_type' => 'post',
|
|
||||||
'posts_per_page' => -1,
|
|
||||||
'fields' => 'ids',
|
|
||||||
'no_found_rows' => true,
|
|
||||||
'lang' => '',
|
|
||||||
'tax_query' => [[
|
|
||||||
'taxonomy' => 'category',
|
|
||||||
'field' => 'term_id',
|
|
||||||
'terms' => [$category],
|
|
||||||
'include_children' => false,
|
|
||||||
]],
|
|
||||||
'meta_query' => [[
|
|
||||||
'key' => 'epingler_dans_la_categorie',
|
|
||||||
'value' => '1',
|
|
||||||
]],
|
|
||||||
]);
|
|
||||||
$pinned_ids = [];
|
|
||||||
foreach ( $pinned_query->posts as $pid ) {
|
|
||||||
$fin = get_post_meta( $pid, 'date_de_fin_depinglage', true );
|
|
||||||
if ( empty( $fin ) || $fin === '0000-00-00' || $fin >= $today ) {
|
|
||||||
$pinned_ids[] = $pid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( ! empty( $pinned_ids ) ) {
|
if ( ! empty( $pinned_ids ) ) {
|
||||||
$query_args['post__not_in'] = $pinned_ids;
|
$query_args['post__not_in'] = $pinned_ids;
|
||||||
}
|
}
|
||||||
@@ -1192,6 +1223,7 @@ function thalim_load_more_agenda() {
|
|||||||
|
|
||||||
$query_args = [
|
$query_args = [
|
||||||
'post_type' => 'post',
|
'post_type' => 'post',
|
||||||
|
'post_status' => 'publish', // admin-ajax => is_admin() true: sans ça WP ajoute future/draft/pending et décale la pagination vs le front
|
||||||
'posts_per_page' => 12,
|
'posts_per_page' => 12,
|
||||||
'paged' => $page,
|
'paged' => $page,
|
||||||
'orderby' => 'date',
|
'orderby' => 'date',
|
||||||
@@ -1292,7 +1324,7 @@ add_filter('posts_orderby', function ($orderby, $query) {
|
|||||||
. " WHEN thalim_ed.meta_value " . sprintf($valid, 'thalim_ed.meta_value', 'thalim_ed.meta_value') . " THEN thalim_ed.meta_value"
|
. " WHEN thalim_ed.meta_value " . sprintf($valid, 'thalim_ed.meta_value', 'thalim_ed.meta_value') . " THEN thalim_ed.meta_value"
|
||||||
. " WHEN thalim_dt.meta_value " . sprintf($valid, 'thalim_dt.meta_value', 'thalim_dt.meta_value') . " THEN thalim_dt.meta_value"
|
. " WHEN thalim_dt.meta_value " . sprintf($valid, 'thalim_dt.meta_value', 'thalim_dt.meta_value') . " THEN thalim_dt.meta_value"
|
||||||
. " ELSE {$wpdb->posts}.post_date"
|
. " ELSE {$wpdb->posts}.post_date"
|
||||||
. " END DESC";
|
. " END DESC, {$wpdb->posts}.ID DESC"; // tiebreaker déterministe: sans lui, les dates ex-æquo paginent de façon instable entre les requêtes séparées (initial vs AJAX)
|
||||||
}, 10, 2);
|
}, 10, 2);
|
||||||
|
|
||||||
// Event date range filter: uses same CASE logic as ordering so date_de_debut/datetime take priority over post_date.
|
// Event date range filter: uses same CASE logic as ordering so date_de_debut/datetime take priority over post_date.
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ function thalim_get_card_data($post_id) {
|
|||||||
} else {
|
} else {
|
||||||
$root = $cat;
|
$root = $cat;
|
||||||
}
|
}
|
||||||
$data['parent_slug'] = $root->slug;
|
$data['parent_slug'] = thalim_category_color_slug($root->term_id, $root->slug);
|
||||||
$data['card_category_name'] = thalim_cat_name($cat);
|
$data['card_category_name'] = thalim_cat_name($cat);
|
||||||
$data['card_category_url'] = get_category_link($cat->term_id);
|
$data['card_category_url'] = get_category_link($cat->term_id);
|
||||||
break;
|
break;
|
||||||
@@ -132,7 +132,7 @@ function thalim_get_card_data($post_id) {
|
|||||||
if (in_array($cat->term_id, $excluded_ids)) continue;
|
if (in_array($cat->term_id, $excluded_ids)) continue;
|
||||||
$ancestor_ids = get_ancestors($cat->term_id, 'category');
|
$ancestor_ids = get_ancestors($cat->term_id, 'category');
|
||||||
$root = !empty($ancestor_ids) ? get_category(end($ancestor_ids)) : $cat;
|
$root = !empty($ancestor_ids) ? get_category(end($ancestor_ids)) : $cat;
|
||||||
$data['parent_slug'] = $root->slug;
|
$data['parent_slug'] = thalim_category_color_slug($root->term_id, $root->slug);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,12 +144,12 @@ function thalim_get_single_data($post_id) {
|
|||||||
$ancestor_ids = get_ancestors($cat->term_id, 'category');
|
$ancestor_ids = get_ancestors($cat->term_id, 'category');
|
||||||
if (!empty($ancestor_ids)) {
|
if (!empty($ancestor_ids)) {
|
||||||
$root = get_category(end($ancestor_ids));
|
$root = get_category(end($ancestor_ids));
|
||||||
$data['parent_slug'] = $root->slug;
|
$data['parent_slug'] = thalim_category_color_slug($root->term_id, $root->slug);
|
||||||
$data['parent_name'] = $root->name;
|
$data['parent_name'] = $root->name;
|
||||||
$data['parent_link'] = get_category_link($root->term_id);
|
$data['parent_link'] = get_category_link($root->term_id);
|
||||||
$data['category_name'] = $cat->name;
|
$data['category_name'] = $cat->name;
|
||||||
} else {
|
} else {
|
||||||
$data['parent_slug'] = $cat->slug;
|
$data['parent_slug'] = thalim_category_color_slug($cat->term_id, $cat->slug);
|
||||||
$data['parent_name'] = $cat->name;
|
$data['parent_name'] = $cat->name;
|
||||||
$data['parent_link'] = get_category_link($cat->term_id);
|
$data['parent_link'] = get_category_link($cat->term_id);
|
||||||
$data['category_name'] = $lang === 'en' ? 'Other' : 'Autre';
|
$data['category_name'] = $lang === 'en' ? 'Other' : 'Autre';
|
||||||
|
|||||||
@@ -85,6 +85,9 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<section class="subcategory-section">
|
<section class="subcategory-section">
|
||||||
<div class="post-grid" id="post-grid">
|
<div class="post-grid" id="post-grid">
|
||||||
|
{% for post in pinned_posts %}
|
||||||
|
{% include 'partials/post-card.twig' with { post: post, card: cards[post.ID], show_category: true, type_only: true } %}
|
||||||
|
{% endfor %}
|
||||||
{% for post in posts %}
|
{% for post in posts %}
|
||||||
{% include 'partials/post-card.twig' with { post: post, card: cards[post.ID], show_category: true, type_only: true } %}
|
{% include 'partials/post-card.twig' with { post: post, card: cards[post.ID], show_category: true, type_only: true } %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
Reference in New Issue
Block a user