Search code examples
javascriptphpwordpresscustom-post-typecustom-taxonomy

How can I create a filterable portfolio in PHP (wordpress)?


I am currently working on my own personal portfolio website. I've made a custom post type using Pods to create portfolio items and i want to use the wordpress tags as the filter.

I've successfully received the portfolio items and the filters. But how can i make them clickable/filterable ? Everything I've found includes portfolio plugins etc. But I don't want to use that, is just want to create my own simple filterable portfolio.

Can someone help me out ?

Here is the code:

Filters:

$tags = get_tags();
    $html = '<div class="post_tags centered-content"> <a href="" class="button" title="Alle projecten">Alles</a>';
    foreach ( $tags as $tag ) {
        $tag_link = get_tag_link( $tag->term_id );

        $html .= "<a href='#{$tag->slug}' title='{$tag->name} filter' class='button outline {$tag->slug}'>";
        $html .= "{$tag->name}</a>";
    }
    $html .= '</div>';
    echo $html;

Portfolio items:

function getPortfolio(){
    global $post;

    $portfolioargs = array(
        'posts_per_page' => 999,
        'orderby' => 'date',
        'order' => 'DESC',
        'post_type' => 'portfolio',
        'post_status' => 'publish',
        'suppress_filters' => false
    );
    $portfolioitems = get_posts($portfolioargs);    

    foreach ($portfolioitems as $portfolioitem) {
        $feat_image =  wp_get_attachment_image_src( get_post_thumbnail_id($portfolioitem->ID), 'full' );
        $tags = wp_get_post_tags($portfolioitem->ID);

        echo '<div class="card portfolio">';
            echo '<a href="'. get_the_permalink($portfolioitem->ID) .'">';
                echo '<figure>';
                    echo '<img src="'. pods_image_url($feat_image, 'card') .'"/>';
                echo '</figure>';
            echo '</a>';
            echo '<div class="card-title-wrapper">';
                echo '<h3>'. $portfolioitem->post_title .'</h3>';
                echo '<span class="card-subtitle mdi mdi-tag-outline mdi-15px">';
                    foreach ( $tags as $tag ) {
                        echo $tag->name . ', ';
                    }
                echo '</span>';
            echo '</div>';
            echo '<div class="card-content">';
                echo '<p>'. $portfolioitem->post_content .'</p>';
            echo '</div>';          
            echo '<div class="card-actions">';
                echo '<a href="'. get_the_permalink($portfolioitem->ID) .'" class="button flat">Lees meer</a>';
                echo '<a href="'. $portfolioitem->website_url .'" class="button flat" target="_blank">Bekijk website</a>';
            echo '</div>';
        echo '</div>';
    }
}

Check the screenshot here


Solution

  • In my opinion the best way to make these tags work as a filter is "AJAX". here i have written your "tags" code to work as a javascript filter . hope it helps. at first let rewrite your code to show tags , i add a line (created an input to send it with AJAX):

     $tags = get_tags();
     $html = '<div class="post_tags centered-content"> 
     <input type='hidden' name='tag_filter' value=''>
     <a href="" class="button" title="Alle projecten">Alles</a>';
     foreach ( $tags as $tag ) {
        $tag_link = get_tag_link( $tag->term_id );
    
        $html .= "<a title='{$tag->name} filter' class='button outline filterBtn {$tag->slug}'>";
        $html .= "{$tag->name}</a>";
    }
    $html .= '</div>';
    echo $html;
    

    then we will have our javascript (jquery) to send the selected tag values:

    $('.filterBtn').click(function(){
        var selected_tag = $(this).text();
        $('input[name="tag_filter"]').val(selected_tag);
        $.ajax({
          url: '<?php echo admin_url('admin-ajax.php'); ?>',
          type: 'post',
          data: { action: 'data_fetch', filter: $('input[name="tag_filter"]').val()},
          success: function (data) {
             $('#yourResultDIV').html(data);
          }
        });
    })
    

    the next part is our PHP code to produce result base on our selected filter: (in functions.php)

    add_action('wp_ajax_data_fetch' , 'resultsLoad');
    add_action('wp_ajax_nopriv_data_fetch','resultsLoad');
    
    function resultsLoad(){
    $filter = $_POST['filter'];
    
    
    global $post;
    
    $portfolioargs = array(
        'posts_per_page' => 999,
        'orderby' => 'date',
        'order' => 'DESC',
        'post_type' => 'portfolio',
        'post_status' => 'publish',
        'tag' => $filter
    );
    $portfolioitems = get_posts($portfolioargs);    
    
    
    
    foreach ($portfolioitems as $portfolioitem) {
        $feat_image =  wp_get_attachment_image_src( get_post_thumbnail_id($portfolioitem->ID), 'full' );
        $tags = wp_get_post_tags($portfolioitem->ID);
    
        echo '<div class="card portfolio">';
            echo '<a href="'. get_the_permalink($portfolioitem->ID) .'">';
                echo '<figure>';
                    echo '<img src="'. pods_image_url($feat_image, 'card') .'"/>';
                echo '</figure>';
            echo '</a>';
            echo '<div class="card-title-wrapper">';
                echo '<h3>'. $portfolioitem->post_title .'</h3>';
                echo '<span class="card-subtitle mdi mdi-tag-outline mdi-15px">';
                    foreach ( $tags as $tag ) {
                        echo $tag->name . ', ';
                    }
                echo '</span>';
            echo '</div>';
            echo '<div class="card-content">';
                echo '<p>'. $portfolioitem->post_content .'</p>';
            echo '</div>';          
            echo '<div class="card-actions">';
                echo '<a href="'. get_the_permalink($portfolioitem->ID) .'" class="button flat">Lees meer</a>';
                echo '<a href="'. $portfolioitem->website_url .'" class="button flat" target="_blank">Bekijk website</a>';
            echo '</div>';
        echo '</div>';
    }
    
    
    die();
    }