J'ai une fonction, dans functions.php
(tout le code ci-dessous), qui ajoute une publication après x
quantité de paragraphes à un message single.php
donné. J'ai un type de message personnalisé appelé advertising
qui comporte un champ Titre, Image et URL pour le message publicitaire. Dans toute publication single.php
, j'ai une case à cocher pour afficher la publicité (vrai/faux) et un champ numérique permettant à l'auteur de choisir le nombre de paragraphes à ignorer avant l'insertion de la publicité illustrée.
MISE À JOUR CODE: code ci-dessous fonctionne, mais je ne peux pas obtenir un message aléatoire. Il continue de tirer le dernier message absolu sans se tourner vers les autres.
// http parser
function addhttp($url) {
if (!preg_match("~^(?:f|ht)tps?://~i", $url)) {
$url = "http://" . $url;
}
return $url;
}
// filter content with ad
add_filter( 'the_content', 'prefix_insert_post_ads' );
function prefix_insert_post_ads( $content ) {
// checkbox to show ad, default true
if ( get_field('show_advertisement') ) {
if ( is_single() && ! is_admin() ) {
// get post-type
$random_ad = get_posts(array(
'numberposts' => 1,
'post_type' => 'advertising',
'order' => 'Rand',
'posts_per_page'=>'1'
));
// get post-type fields
$random_ad = array_shift($random_ad);
$link = addhttp( get_field('advertisement_link', $random_ad->ID));
$image = get_field('upload_advertisement', $random_ad->ID);
// get html
$ad_code = '<a href="'.$link.'" target="_blank"><img src="'.$image.'" /></a>';
// show ad after # paragraphs
$show_after = get_field('advertisement_show_after');
// return appended $content
return prefix_insert_after_paragraph( $ad_code, $show_after, $content );
} else {
// do nothing
}
} else {
return $content;
}
}
// insert ad into post
function prefix_insert_after_paragraph( $insertion, $paragraph_id, $content ) {
$closing_p = '</p>';
$paragraphs = explode( $closing_p, $content );
foreach ($paragraphs as $index => $paragraph) {
if ( trim( $paragraph ) ) {
$paragraphs[$index] .= $closing_p;
}
if ( $paragraph_id == $index + 1 ) {
$paragraphs[$index] .= $insertion;
}
}
return implode( '', $paragraphs );
}
EDIT: RESOLU! order
a été remplacé par orderby
et le code ci-dessus fonctionne.
Comme nous l'avons déjà indiqué, l'ordre et la recherche aléatoires sont des opérations assez coûteuses à exécuter. Voyons donc comment nous allons régler ce problème.
Étant donné que vous n'avez besoin que d'un message de votre type de message personnalisé, nous n'avons besoin que d'un seul ID aléatoire que nous pouvons transmettre à get_post()
afin d'obtenir le message souhaité. Au lieu d'obtenir la publication de manière aléatoire de la base de données, nous interrogerons tous les types de publication personnalisés ( ou au moins tous les ID de publication ), l'enregistrerons dans un transitoire, puis nous pourrons simplement sélectionner un identifiant aléatoire à partir de cette option.
Regardons un code: ( Ceci va dans functions.php )
function get_random_id( $post_type = '' )
{
$q = [];
// Make sure we have a post type set, check if it exists and sanitize
$post_type = filter_var( $post_type, FILTER_SANITIZE_STRING );
if ( !$post_type )
return $q;
if ( !post_type_exists( $post_type ) )
return $q;
// The post type exist and is valid, lets continue
$transient_name = 'Rand_ids_' . md5( $post_type );
// Get the transient, if we have one already
if ( false === ( $q = get_transient ( $transient_name ) ) ) {
$args = [
'post_type' => $post_type,
'posts_per_page' => -1,
'fields' => 'ids', // get only post ID's
// Add any additional arguments
];
$q = get_posts( $args );
// Set the transient
set_transient( $transient_name, $q, 30*DAY_IN_SECONDS );
} // endif get_transient
return $q;
}
Ce que nous avons fait, nous avons maintenant enregistré tous les identifiants de type de publication personnalisés dans un transitoire. Cela augmentera considérablement les performances. Le transitoire est défini sur 30 jours, nous devons donc vider et recréer le transitoire dès que nous publions un nouveau type de publication personnalisé.
Permet d'utiliser le hook d'action transition_post_status
: ( Ceci va dans functions.php )
add_action( 'transition_post_status', function ( $new_status, $old_status, $post )
{
// Make sure we only target our specific post type
if ( 'advertising' !== $post->post_type )
return;
global $wpdb;
// Delete the transients
$wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE ('_transient%_Rand_ids_%')" );
$wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE ('_transient_timeout%_Rand_ids_%')" );
// Lets rebuild the transient
get_random_id( $post->post_type );
}, 10, 3 );
Tout ce qui nous reste à faire est d’obtenir un ID de publication aléatoire de notre fonction get_random_id()
et de le transmettre à get_post()
pour obtenir l’objet de publication.
// Get the array of post ID's
$post_type_posts = get_random_id( 'advertising' );
// Make sure we have posts
if ( $post_type_posts ) {
// Get the post object of the id first in line
shuffle( $post_type_posts );
$single_post = get_post( $post_type_posts[0] );
// Display the post content
}
De cette façon, vous économisez beaucoup sur les ressources et cela est beaucoup plus rapide que de simplement laisser SQL choisir une publication aléatoire dans la base de données.
À titre d’exemple, le filtre de votre annonceur peut ressembler à ce qui suit:
add_filter( 'the_content', 'prefix_insert_post_ads' );
function prefix_insert_post_ads( $content ) {
// checkbox to show ad, default true
if ( get_field('show_advertisement') ) {
if ( is_single() &&
! is_admin()
) {
// Get the array of post ID's
$post_type_posts = get_random_id( 'advertising' );
// Make sure we have posts
if ( $post_type_posts ) {
// Get the post object of the id first in line
shuffle( $post_type_posts );
$random_ad = get_post( $post_type_posts[0] );
// Display the post content
$link = addhttp( get_field('advertisement_link', $random_ad->ID));
$image = get_field('upload_advertisement', $random_ad->ID);
// get html
$ad_code = '<a href="'.$link.'" target="_blank"><img src="'.$image.'" /></a>';
// show ad after # paragraphs
$show_after = get_field('advertisement_show_after');
// return appended $content
return prefix_insert_after_paragraph( $ad_code, $show_after, $content );
}
}
}
return $content;
}
Commencez par recevoir le message publicitaire aléatoire par get_posts
$random_ad = get_posts(array(
'numberposts' => 1,
'post_type' => 'advertising',
'orderby' => 'Rand'
));
Maintenant, récupère les champs personnalisés de ce message aléatoire
if (!empty($random_ad)) {
$random_ad = array_shift($random_ad);
$link = addhttp( get_field('advertisement_link', $random_ad->ID));
$image = get_field('upload_advertisement', $random_ad->ID);
}
Construisez votre annonce HTML et insérez où vous voulez!
$ad_code = '<a href="'.$link.'" target="_blank"><img src="'.$image.'" /></a>';
L'utilisation d'un décalage aléatoire peut constituer une alternative plus rapide que la commande par Rand()
dans la requête SQL générée:
if( $count = wp_count_posts( 'advertising' )->publish )
{
$random_ad = get_posts(
[
'post_status' => 'publish',
'offset' => Rand( 0, $count - 1 ),
'posts_per_page' => 1,
'post_type' => 'advertising'
]
);
}
où nous utilisons offset
pour définir la partie SQL LIMIT x, 1
, où x
dépend du nombre de publications.
Notez que cela n’est peut-être pas le cas great pour un très grand nombre de lignes, mais il existe également un intéressant benchmark feuille par Josh Hartman .
Pieter Goosen a également une approche intéressante dans son answer , qui devrait vous offrir une bien meilleure alternative que de commander par Rand()
.