最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

functions - issue with ifelseif in_array inside foreach loop display only one post

programmeradmin1浏览0评论

I try to attribute a specific background-color to each post if one of categories of post corresponding to one category. My function works but is restricted to display only one post in result. If I delete this function, all post are displayed.

More informations :

On my page I have buttons to filter posts by category. if I click on once I display all post for this category. But each post contains several categories. I have selected some categories to attribute a background colors for each posts, but theses categories are different of the filters buttons.

Wordpress display this error "a critical error has occurred on your site, Learn more about debugging WordPress." after the first post displayed.

here is my entire code :

<?php

add_action('wp_ajax_nopriv_filter', 'filter_ajax');
add_action('wp_ajax_filter','filter_ajax');

function filter_ajax(){

$category = $_POST['category'];

$argsf = array(
    'post_type' => 'post',
    'posts_per_page' => -1,
    'order' => 'ASC'
);

if(isset($category)){
    $argsf['category__in'] = array($category);
}

$postsf = get_posts($argsf);    

if (!empty($postsf)) {
    foreach ($postsf as $post) {
        
        $link_post = get_permalink( $post->ID );
        $image_post = get_the_post_thumbnail_url( $post->ID, $size = 'large' );
        $item1 = get_post_meta($post->ID, 'item1', true);
        $item2 = get_post_meta($post->ID, 'item2', true);
        $item3 = get_post_meta($post->ID, 'item3', true);
        $item4 = get_post_meta($post->ID, 'item4', true);
        $title = get_the_title($post->ID); 
        $post_slug = $post->post_name;
        $cats_post = wp_get_post_categories( $post->ID );
        
        function test($cats_post){
            if (in_array("14", $cats_post)){ echo'#710000';}
            elseif(in_array("5", $cats_post)){ echo'#0a005d';}
            elseif(in_array("16", $cats_post)){ echo'#65a0e8';}
            elseif(in_array("13", $cats_post)){ echo'#90744b';}
        }
    
?>  
<div class="shop w-24 pb-1" style="height:320px; min-width:320px;">
    <div class="w-100 h-100 p-2">
            
        <div class=" " style="background-color:<?php test($cats_post); ?>">
            <div class="">
                <!--<div class="" title="Locer">
                <a href="<?= $item2; ?>"><i class="icofont-opposite "></i></a>
                </div>-->
                <div class="" title="something">
                    <a href="tel:<?= $item3; ?>"><i class="im im-phone"></i> </a>
                </div>
                <div class="">
                    <span><?= $item1; ?></span>
                </div> 
            </div>
            <span class="text-uppercase col-white tsh332 fwlr text-center" style="font-size:2rem;">
                <?= $title; ?>
            </span>
            <?php if ( metadata_exists( 'post', $post->ID , 'item4' ) ){ ?> 
                <div class="">
                    <div class="b-yellow b-100">
                        <span><?= $item4; ?> </span>
                    </div>
                </div>
            <?php } ?>
        </div>
                
    </div>
</div>
<?php  }  /* fin foreach */
    }  /* fin if  */
wp_reset_postdata();
die();
}

?>

I tried that but it doesn't work :

  • get_the_category instead of wp_get_post_categories
  • has_item instead of in_array

I don't know If I must use an other foreach loop and how !

thanks

I try to attribute a specific background-color to each post if one of categories of post corresponding to one category. My function works but is restricted to display only one post in result. If I delete this function, all post are displayed.

More informations :

On my page I have buttons to filter posts by category. if I click on once I display all post for this category. But each post contains several categories. I have selected some categories to attribute a background colors for each posts, but theses categories are different of the filters buttons.

Wordpress display this error "a critical error has occurred on your site, Learn more about debugging WordPress." after the first post displayed.

here is my entire code :

<?php

add_action('wp_ajax_nopriv_filter', 'filter_ajax');
add_action('wp_ajax_filter','filter_ajax');

function filter_ajax(){

$category = $_POST['category'];

$argsf = array(
    'post_type' => 'post',
    'posts_per_page' => -1,
    'order' => 'ASC'
);

if(isset($category)){
    $argsf['category__in'] = array($category);
}

$postsf = get_posts($argsf);    

if (!empty($postsf)) {
    foreach ($postsf as $post) {
        
        $link_post = get_permalink( $post->ID );
        $image_post = get_the_post_thumbnail_url( $post->ID, $size = 'large' );
        $item1 = get_post_meta($post->ID, 'item1', true);
        $item2 = get_post_meta($post->ID, 'item2', true);
        $item3 = get_post_meta($post->ID, 'item3', true);
        $item4 = get_post_meta($post->ID, 'item4', true);
        $title = get_the_title($post->ID); 
        $post_slug = $post->post_name;
        $cats_post = wp_get_post_categories( $post->ID );
        
        function test($cats_post){
            if (in_array("14", $cats_post)){ echo'#710000';}
            elseif(in_array("5", $cats_post)){ echo'#0a005d';}
            elseif(in_array("16", $cats_post)){ echo'#65a0e8';}
            elseif(in_array("13", $cats_post)){ echo'#90744b';}
        }
    
?>  
<div class="shop w-24 pb-1" style="height:320px; min-width:320px;">
    <div class="w-100 h-100 p-2">
            
        <div class=" " style="background-color:<?php test($cats_post); ?>">
            <div class="">
                <!--<div class="" title="Locer">
                <a href="<?= $item2; ?>"><i class="icofont-opposite "></i></a>
                </div>-->
                <div class="" title="something">
                    <a href="tel:<?= $item3; ?>"><i class="im im-phone"></i> </a>
                </div>
                <div class="">
                    <span><?= $item1; ?></span>
                </div> 
            </div>
            <span class="text-uppercase col-white tsh332 fwlr text-center" style="font-size:2rem;">
                <?= $title; ?>
            </span>
            <?php if ( metadata_exists( 'post', $post->ID , 'item4' ) ){ ?> 
                <div class="">
                    <div class="b-yellow b-100">
                        <span><?= $item4; ?> </span>
                    </div>
                </div>
            <?php } ?>
        </div>
                
    </div>
</div>
<?php  }  /* fin foreach */
    }  /* fin if  */
wp_reset_postdata();
die();
}

?>

I tried that but it doesn't work :

  • get_the_category instead of wp_get_post_categories
  • has_item instead of in_array

I don't know If I must use an other foreach loop and how !

thanks

Share Improve this question edited Aug 10, 2020 at 16:09 Tom J Nowell 61k7 gold badges79 silver badges148 bronze badges asked Aug 10, 2020 at 14:53 imagIneimagIne 10512 bronze badges 7
  • What is the error? Turn on debug and then post the error here. wordpress/support/article/debugging-in-wordpress – shanebp Commented Aug 10, 2020 at 15:14
  • I would avoid declaring functions inside other functions, it has no benefits and can make debugging difficult. It's easily fixed by moving the function out of the functiion and keeping the same name – Tom J Nowell Commented Aug 10, 2020 at 16:08
  • I'm already on debug mode, I have only this error "a critical error has occurred on your site, Learn more about debugging WordPress." bit.ly/3fFRC3r – imagIne Commented Aug 10, 2020 at 16:09
  • Also, why not do this via CSS? If you use the post_class API it will output HTML classes for every tag and category that you can then pick up using CSS to set the colour. There's no need to manually insert inline CSS styling on the fly – Tom J Nowell Commented Aug 10, 2020 at 16:10
  • Tom, I tried to use the function outside foreach but I can't get wp_get_post_categories( $post->ID ). If it's possible how can I do that? – imagIne Commented Aug 10, 2020 at 16:14
 |  Show 2 more comments

1 Answer 1

Reset to default 1

There are several fatal assumptions here, and, a far better way to do it.

1. Declaring Functions inside Functions

This will cause a fatal error in a future version of PHP, makes it super difficult to debug. But worst, it's completely unnecessary.

This:


function foo () { 
    function bar () {
        //
    }
    bar();
}

Should just be this:

function bar() {
    //
}
function foo() {
    bar();
}

2. Comparing strings and numbers, with a fuzzy in_array

1 is not "1", but because the 3rd parameter was never set to true, 1 is "1". It's also true, and lots of other "truthy" values.

3. Relying on hardcoded magic values

Don't hardcode the category ID. If you delete it by accident and recreate it, the ID will change. If you migrate to a new site the ID will change. It's very easy to break.

If you can't let the user pick a term, at least use a known slug/name so it can be recreated/set.

4. Assuming the functions would return category IDs

wp_get_post_categories does not return category IDs or category names. It returns term objects. These objects contain names, descriptions, IDs, etc. I expect your code to be generating PHP warnings.

5. Hardcoding Inline Styles

You shouldn't use inline styles. Use HTML classes

The Correct Way To Do It

Use post_class to print out the posts html classes:

<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>

This gives you classes you can target with CSS for post type, tags, categories, ID, etc etc. It does this automatically, so you doon't have to tell it to add the class.

Here's an example from my own site:

<article id="post-931" class="post-931 post type-post status-publish format-standard has-post-thumbnail hentry category-development category-gutenberg tag-block-editor tag-comments tag-gutenberg tag-javascript tag-plugins tag-react tag-releases tag-wordpress">

post_class automatically generated those HTML classes for me, andif I added that post to a category named test, then category-test would appear on the frontend as a HTML class too.

So now you can target all posts in a category with a CSS file, resulting in nicer styling, smaller HTML, and easier to understand code, e.g.

.category-development { 
    background: red;
}

Now all posts I write in the development category have a red background.

Don't forget the body_class function too. It adds HTML classes for the template used, archives, etc


A final note, don't end your PHP files in ?>. It's not necessary and can actually cause an easily missed mistake with stray spaces aftering the closing tag breaking sites on older PHP versions.

发布评论

评论列表(0)

  1. 暂无评论