How to create filters for categories with php and html to use in Wordpress page?

Asked

Viewed 1,133 times

1

Hello,

I would like to create a filter for categories of posts in WP. As in this example https://bootsnipp.com/snippets/N6vrp.

But I don’t know much php, so I don’t know how to do it, so when I click the 'categoria1' button, only posts from this category appear. And when you click 'All' the posts of all categories appear..

My code is like this for now.

<?php get_header(); ?>

<?php
/* 
Template Name: Arquivo Posts
*/
?>
<div class="container">
    <h1 style="text-align: center; color: white; margin-bottom: 30px;">Noticias</h1>
    <div class="filtro" style="text-align: center;">
        <a href="<?php get_posts('orderby=date&order=DESC&category_name=categoria1'); ?>">Categoria 1</a> 
        <a>Categoria 2</a> <a>Todos</a> </div>

<div class="row">

        <?php if (have_posts()) : while (have_posts()) : the_post(); ?>

        <div class="col-xs-12 col-sm-6 col-md-4 " style="text-align: center;">
            <a href="<?php the_permalink(); ?>">
            <div class="imgPost"><?php the_post_thumbnail(); ?></div>
            <h2><?php the_title(); ?></a></h2>
            <p><em><?php echo ucfirst(get_the_time('l, j \d\e F \d\e Y')); ?></em></p>
            <hr>
        </div>

        <?php endwhile; else: ?>
            <p><?php _e('Desculpe, não há posts a serem exibidos.'); ?></p>
        <?php endif; ?>
</div>
</div>

<?php get_footer(); ?>

Someone can help me?

Thank you

2 answers

1

Caroline, all right?

I needed to perform a type of filter like this once, and I managed to do it with a few steps.

Come on:

1 - First you should download the Isotope plugin and then insert inside some folder of your Wordpress theme (https://isotope.metafizzy.co/);

2 - Then insert this code below into the functions.php of your Wordpress theme:

if (!is_admin()) add_action( 'wp_enqueue_scripts', 'add_jquery_to_my_theme' );

function add_jquery_to_my_theme() {
// scrap WP jquery and register from google cdn - load in footer
wp_deregister_script('jquery');
wp_register_script('jquery', "http" . ($_SERVER['SERVER_PORT'] == 443 ? "s" : "") . "://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js", false, null, true );    
// load jquery
wp_enqueue_script('jquery');
}

if (!is_admin()) add_action( 'wp_enqueue_scripts', 'load_isotope' );

function load_isotope() {
// script will load in footer
wp_enqueue_script( 'isotope-js',  get_stylesheet_directory_uri() . '/path/to/jquery.isotope.min.js', true );
}

The first if you add jQuery in your theme, and the second if you call the plugin Isotope. Remember to correctly set the exact path of the plugin in your theme.

3 - Then in your page template in the theme, you should add this code below:

<ul id="filtros">
    <?php
        $terms = get_terms("category");
        $count = count($terms);
            echo '<li><a href="javascript:void(0)" title="" data-filter=".all" class="active">Todos</a></li>';
        if ( $count > 0 ){

            foreach ( $terms as $term ) {

                $termname = strtolower($term->name);
                $termname = str_replace(' ', '-', $termname);
                echo '<li><a href="javascript:void(0)" title="" data-filter=".'.$termname.'">'.$term->name.'</a></li>';
            }
        }
    ?>
</ul>

<div id="post">

   <?php 
   $args = array( 'post_type' => 'post', 'posts_per_page' => -1 );
   $loop = new WP_Query( $args );
   while ( $loop->have_posts() ) : $loop->the_post(); 

      $terms = get_the_terms( $post->ID, 'category' );                      
      if ( $terms && ! is_wp_error( $terms ) ) : 

          $links = array();

          foreach ( $terms as $term ) {
              $links[] = $term->name;
          }

          $tax_links = join( " ", str_replace(' ', '-', $links));          
          $tax = strtolower($tax_links);
      else :    
      $tax = '';                    
      endif; 
      ?>

      <div class="all post-item <?php echo $tax; ?>">
          <a href="<?php the_permalink(); ?>">
              <div class="imgPost"><?php the_post_thumbnail(); ?></div>
              <h2><?php the_title(); ?></h2>
              <p><em><?php echo ucfirst(get_the_time('l, j \d\e F \d\e Y')); ?></em></p>
          </a>
      </div>

    <?php endwhile; ?>

4 - Now you will insert, inside the header or in the footer of your theme (do tests), the function that makes the filter feature work:

<script>
    (function($){

    var $container = $('#post');

    // create a clone that will be used for measuring container width
    $containerProxy = $container.clone().empty().css({ visibility: 'hidden' });   

    $container.after( $containerProxy );  

    // get the first item to use for measuring columnWidth
    var $item = $container.find('.post-item').eq(0);

    $container.imagesLoaded(function(){
        $(window).smartresize( function() {

            // calculate columnWidth
            var colWidth = Math.floor( $containerProxy.width() / 2 ); // Change this number to your desired amount of columns

            // set width of container based on columnWidth
            $container.css({
                width: colWidth * 2 // Change this number to your desired amount of columns
            })
            .isotope({

                // disable automatic resizing when window is resized
                resizable: false,

                // set columnWidth option for masonry
                masonry: {
                    columnWidth: colWidth
                }
            });

        // trigger smartresize for first time
        }).smartresize();
    });

    // filter items when filter link is clicked
    $('#filtros a').click(function(){

        var selector = $(this).attr('data-filter');
        $container.isotope({ filter: selector, animationEngine : "css" });
        $('#filtros a.active').removeClass('active');
        $(this).addClass('active');
        return false;

    });

} ) ( jQuery );
</script>

5 - Finally add css:

/**** Isotope Filtering ****/

.isotope-item {
  z-index: 2;
}

.isotope-hidden.isotope-item {
  pointer-events: none;
  z-index: 1;
}

/**** Isotope CSS3 transitions ****/

.isotope,
.isotope .isotope-item {
  -webkit-transition-duration: 0.8s;
     -moz-transition-duration: 0.8s;
      -ms-transition-duration: 0.8s;
       -o-transition-duration: 0.8s;
          transition-duration: 0.8s;
}

.isotope {
  -webkit-transition-property: height;
     -moz-transition-property: height;
      -ms-transition-property: height;
       -o-transition-property: height;
          transition-property: height;
}

.isotope .isotope-item {
  -webkit-transition-property: -webkit-transform, opacity;
     -moz-transition-property:    -moz-transform, opacity;
      -ms-transition-property:     -ms-transform, opacity;
       -o-transition-property:      -o-transform, opacity;
          transition-property:         transform, opacity;
}

/**** disabling Isotope CSS3 transitions ****/

.isotope.no-transition,
.isotope.no-transition .isotope-item,
.isotope .isotope-item.no-transition {
  -webkit-transition-duration: 0s;
     -moz-transition-duration: 0s;
      -ms-transition-duration: 0s;
       -o-transition-duration: 0s;
          transition-duration: 0s;
}

From there it is already to work. Then it would be at your discretion to later improve the look to suit your needs.

If it still doesn’t work, check the path of your plugin if it is accurate or do more tests by removing the code from the first if, in step 2, because it may be jQuery conflict.

I hope I’ve helped.

  • I’ll try now and tell you the results, thank you very much

  • Hi, I put it like this in my functions Function load_isotope() { // script will load in footer wp_enqueue_script( 'Isotope-js', get_stylesheet_directory_uri() . '/lib/js/Isotope.pkgd.min.js', true ); } But it’s not working, pq the filter doesn’t work. I was wondering if there’s a way in this function, point directly to the link. which would be that, https://unpkg.com/[email protected]/dist/Isotope.pkgd.min.js, correct?

  • And in step 2, where I call "://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js" I already have a script in my header that loads exactly the same link, so the first function is required? I’m sorry if the questions seem silly, but I don’t know much about Js or Php, I know well html and css. These others are still right at the beginning. Thank you.

  • Caroline, did you ever look at the source code of your page through your browser, to see if Isotope was loaded correctly? Type, when you click on the url there, open the js file?

  • If it is opening normally from source code, it might just be jQuery conflict, because it’s like I told you, it can happen because there is already a jQuery call in your header. Try to remove the first if from the code I gave you.

  • Brício, I checked and it’s there yes, I even took a screenshot to send you, but I can’t send the comments here. And open the file normally. I took the first if but tb is not working. The filter links are like this. <a href="javascript:void(0)" title="" data-filter=". system">System</a> Maybe the script for step 4 that ñ is working? I am placing it above the </header>. And it is appearing in the browser tb,normal. I put this script in all positions on footer, but tb unsuccessfully.

  • You would be able to show in some demonstration environment or is only local at the moment?

  • Sorry! In step 3, note that I forgot to close the <div id="post">

  • Caroline, do the following: Fix the closure of <div id="post">; then remove the two ifs from your functions.php and call only the Isotope in your footer, in the default way: <script type="text/javascript" src="<? php echo get_template_directory_uri(); ? >/js/jquery.isotope.min.js"></script>

  • I did here quickly and it already worked for me. Remember to insert the function of step 4 just below the plugin call.

  • Ah! Another detail I noticed is that you will have to download an older version of the Isotope plugin ( v1.5.25 - https://redvinestudio.com/demo-pages/wordpress-isotope-portfolio/js/jquery.isotope.min.js ). I tested with the current version and it didn’t work, ok?

  • I did!! But there is a huge space between a post and another, and I can not solve. I’ve looked at the classes that are in the css you gave me, but nothing is related. It seems to have a giant margin on the left and right of each post. And by placing inside grids and columns like col-Sm-4, it only shrinks the photo. the space goes on. can you tell me if there’s any class that’s doing this?

  • Right! Glad it worked out! In case you don’t need to use these bootstrap classes. The amount of column you define in the function itself, in that part: // calculate columnWidth

  • Brício, thank you very much. gave everything right :3

  • Great! If you can mark as solved, it will facilitate for other people with the same question.

Show 10 more comments

-2

Using only PHP is difficult to make this feature happen. Basically when we make a looping we pass the parameter of the category we want to filter...

First it is important to understand that you need to be on a "Category.php" template page and have a looping of your categories. This looping is basically an array that can contain all your categories registered in Wordpress.

In this situation when you select an item from this list Wordpress will reload the page passing the parameter chosen to the URL and displaying the posts on this page.

But to exchange posts without the page reload is necessary to use Ajax.

I’ve used something close to this example: https://kilowp.com/tutorials/create-an-ajax-powered-posts-filter/

There are some plugins that make it easy enough to include this feature in the theme.

I’ve used this plugin and it worked very well: https://br.wordpress.org/plugins/ajax-filter-search/

  • I’ll try and tell you the results, thank you

  • Thank you also. But his reply had a more immediate result :3

Browser other questions tagged

You are not signed in. Login or sign up in order to post.