• Resolved timothyf

    (@timothyf)


    A client sells ad space directly to local businesses. Each advertiser provides a jpg to post on her website. To make this work, I set up a custom post type combined with Advanced Custom Fields where she uploads the ad image, the ad link, and the begin and end dates. I use PHP to extract the active ads for positioning in several locations and have defined eight different blocks in Ad Inserter, which vary on the destination page and the device used. For 6 AI blocks, I use widgets, and these are working fine.

    The remaining 2 blocks appear on the home page and on archives/category/search pages on mobile devices. For these pages, I want to automatically insert ads after every other article content, i.e., after 1, 3, 5, etc. And the order of the ads should be randomized with every page load.

    I have the PHP code to create a list of the desired number of active ads in random order. Here’s the general format of the list:

    <div class="general-ad ad-counter-1"><a href="https://advertiser1.com" target="_blank" ><img src="ad1.jpg"></a></div>
    |rotate|
    <div class="general-ad ad-counter-2"><a href="https://advertiser2.com" target="_blank" ><img src="ad2.jpg"></a></div>
    |rotate|
    <div class="general-ad ad-counter-3"><a href="https://advertiser3.com" target="_blank" ><img src="ad3.jpg"></a></div>

    The settings:
    Automatic Insertion: After Content
    Filter insertions: 1,3,5,7 using Auto counter
    Use client-side detection to show only on Tablet and Phone

    The ads appear in the locations where I expect them, but sometimes one ad appears twice and another doesn’t appear at all.

    When I originally tested with lots of ads, I thought that putting |rotate| between the the ads worked. Now I see that |rotate| simply chooses 1 ad at random from my list to place after post 1, then randomly chooses 1 ad from the list (with replacement) for placing after post 3. When my client has only 2 active ads, there’s a 50% chance that the ad after post 1 will be the same as the ad after post 3.

    Without the |rotate| between ads, the ads in the list are treated as a block and all the ads in the list appear after post 1, after post 3, etc.

    Two solutions that I see are either a) have Ad Inserter randomly choose an ad without replacement from my ad list or b) instruct Ad Inserter to place ad #1 from my list after post 1, then place ad #2 after post 3, ad #3 after post 5, etc.

    What is the syntax to achieve either a) or b) or is there another approach that I should use?

    Thanks,
    Tim

Viewing 10 replies - 1 through 10 (of 10 total)
  • Plugin Author Spacetime

    (@spacetime)

    You are right.
    |rotate| randomly chooses one of the options.

    When there is more than one call (insertion) for the code block, each time one option is randomly chosen and inserted.

    a)
    Random choice is random – it can be anything. Multiple insertions may choose the same option.
    |rotate| feature is intended for ad rotation for a single position – to randomly choose one ad. On long run each option will have practically the same number of insertions.

    b)
    Currently this is only possible if you configure one code block for each ad and set filter for the desired position (1, 3, 5 or 7).
    Of course, this approach assumes that you provide appropriate PHP code for each code block / position.

    c)
    I’m considering a simpler option to get what you need with a single code block.
    I put it on the todo list.

    • This reply was modified 7 years, 8 months ago by Spacetime.
    Plugin Author Spacetime

    (@spacetime)

    Can you please try development version?

    I added support for ad counting.
    All you have to do is to replace |rotate| with |count|.

    Where there is more than one call for code block (like when using multiple insertions and filter) the ads separated with |count| are inserted according to the ad counter (N=x when using Label blocks debugging function).

    Thread Starter timothyf

    (@timothyf)

    Thank you for adding support for ad counting! For what I see in my initial test, the |count| feature is working fine. My testing, however, showed that I have an error in my code that I need to fix before I can be sure it works for me.

    Thanks,
    Tim

    Plugin Author Spacetime

    (@spacetime)

    OK.
    Please report here when you finish.

    Thread Starter timothyf

    (@timothyf)

    I’m continuing to have trouble with the |count| feature. It doesn’t work as expected when I randomize the ad order, which I need to do. This problem occurs a) when my query args includes ‘orderby’ => ‘rand’, b) when I run shuffle($the_query) after the query is made, or c) use a custom function to randomize the array order while creating a new array.

    To double check that my code works outside Ad Inserter, I set up a shortcode that I use in an Ad Inserter code block and on a separate page without Ad Inserter. For my query, I’m using a custom post type, selecting for ad position and meeting conditions for start date and end date. Here is my code:

    function ad_template(){
    
    $ad_date = date('Ymd');
    $return_string = '';
    $args = array(
    	'posts_per_page'	=> 3,
    	'orderby'          => 'rand',
    	'post_type'		=> 'aj-ads',
    	'meta_query'	=> array(
    		'relation'		=> 'AND',
    		array(
    			'key'		=> 'ad_position',
    			'value'		=> 'general',
    			'compare'	=> '='
    		),
    		array(
    			'key'		=> 'start_date',
    			'value'		=> $ad_date ,
    			'compare'	=> '<='
    		),
    		array(
    			'key'		=> 'stop_date',
    			'value'		=> $ad_date ,
    			'compare'	=> '>='
    		)
    	)
    );
    
    // query
    $the_query = get_posts( $args );
    $ad_counter = 1 ;
    foreach( $the_query as $the_post ) {
    	$postid = $the_post->ID ; 
    	$target = get_field('target_url', $postid); 
    	debug_to_console($ad_counter); // output counter to console
    	debug_to_console($postid);  // output associated postid to console
    	debug_to_console($target); // output associated target URL to console
    	$return_string .= '<div class="general-ad shortcode-ad ad-counter-' . $ad_counter .'"><a href="' . get_field('target_url', $postid) . '" target="_blank" class="href-counter-'. $ad_counter . '">' get_the_post_thumbnail($postid) . '</a></div>|count|'; }
    	$ad_counter ++ ;
    }
    wp_reset_query();	 // Restore global post data stomped by the_post(). 
    return $return_string;
    }
    
    add_shortcode( 'ad-query', 'ad_template' ); 

    I’m testing with 3 ads.

    – With no randomization: When orderby and shuffle and the custom shuffle function are all disabled, the query works perfectly with |count|–the ads appear in order as 1-2-3

    – With randomization: When any one of orderby, shuffle, and the custom shuffle function is enabled, |count| does not work correctly. The first AI ad matches the first ad in the randomized array, but the second and third appear to be random and duplicates often appear. As the foreach goes through its cycles, the code sends the $postid and $target to console and I can see that my query has been randomized. The AI output on the page doesn’t match the console output.

    Making this more confusing is that the classes using $ad_counter in the div wrapper and the a element are correct–they are consistently 1-2-3 even though the target_url and the post_thumbnail in the AI output don’t correspond to the $postid and $target that appear in the console. (The target_url and the post_thumbnail in the AI output do come from the same post, although often not from the expected $postid.)

    The shortcode is not working correctly in an Ad Inserter code block, but on the separate page, the shortcode always works fine with or without randomization–there’s never duplication and the console output matches the order visible on the page.

    What else I’ve tried:
    – new WP_query instead of get_posts
    – echoing output instead of return $return_string
    – an additional div wrapper
    – outputting only the post_thumbnail with no div wrapper and no a element

    I’ve tried to troubleshoot this to the best of my ability, and I’m stuck.

    Thanks,
    Tim

    Plugin Author Spacetime

    (@spacetime)

    The problem is in your function as it does not return the same order for all the calls for the page.

    You need to do shuffle only the first time and then return this order for all subsequent calls.

    Ad Inserter is called for each insertion and each time it calls your function. It always returns an ad according to the call counter, but if the order changes between the calls you get what you have described.

    Thread Starter timothyf

    (@timothyf)

    Ah, thanks for explaining that each insertion point calls the function in the AI code block–that was a point that I had misunderstood.

    To return a consistent order for all AI calls, my first thought is setting a cookie in functions.php with the randomized order and then using the AI code block to pull the data from the cookie. Do you have any suggestions for a technique that would work better?

    Plugin Author Spacetime

    (@spacetime)

    Maybe a simpler approach could work.

    When you crate the list define a constant with that list.
    Then at the beginning of your code check for this constant.
    If it is defined return the constant (list), if not, create the list and define constant.

    Thread Starter timothyf

    (@timothyf)

    Perfect! Checking a constant works great, and it was definitely easier than a cookie. Thank you so much for adding the |count| functionality, explaining how the calls work, and then suggesting a constant. I appreciate your helpfulness.

    Tim

    Plugin Author Spacetime

    (@spacetime)

    You are welcome!

    I would appreciate if you could write a nice review.

    Thank you!

Viewing 10 replies - 1 through 10 (of 10 total)
  • The topic ‘Insert single ad from PHP generated list’ is closed to new replies.