Filter your projects with a masonry style

How to give some life to your page with a dynamic filter for your articles or projects. It is possible using the tags of your pages with the help of some nice JS.

Masonry Style

Hello! Today you will learn how to use the Mixitup JS plug-in with Kirby to make your articles/projects filterable by tags. We will filter projects based on their category with the help of some nice and modern animations in just a few simple steps.

As usual, we will use the Kirby Starterkit for our tutorial, so if you don't already have your own, you can download it on the Kirby site. For the demo, we will load both JQuery and Mixitup plug-ins from their CDN, but you can also download them directly.

Download Kirby Starterkit Download JQuery Download Mixitup

 

Step 1 - Add content

The first thing we need to do is to add some more project pages to the Starterkit. Out of the box, it contains only 3 project pages, but if we want to see a nice filter animation on our page, we should add 2 or 3 (or more...). For the tutorial, we will just copy the 3 existing projects and change their title. You should now have something like this in your site->content->projects folder.

Step 2 - Create a controller

We'll reuse code from the filter by tag tutorial.

We could put all our code in the php snippet here, but using a controller to keep the logic out of the display is a good habit.
Let's create the folders controllers in your site folder.
What every line does is explained in the code snippet. For more details, visit this Kirby blog post.

This controller will return all the tags used on projects as well as the list of projects.

In case you've never seen a controller before, there's handy documentation available in the Kirby docs we highly recommend reading.

site/controllers/site.php

<?php
return function($site, $pages, $page) {

	// fetch all projects
	$projects = page('projects')->children()->visible();
	if($page->isHomepage()) {
		$projects = $projects->limit(3);
	}

	// fetch all tags used in projects. pluck($field, 'separator', unique)
	$tags = $projects->pluck('tags', ',', true);
 
	// Return the list of projects and tags to template
  	return compact('projects', 'tags');
};
?>

Step 3 - The buttons

We need to modify the starterkit snippet projects.php located in site/snippets/projects.php.

We're going to create a list of tags and display them as buttons (but not on the home page). The "buttons" will permit filtering dynamically the list based on the tag selected.
Here we use span to list our tags but you can also use div or button tags, whichever you prefer.

We will need to add some HTML attributes to make them work.
The buttons-filter class is used to apply styling while the filter class is used by the Mixitup plug-in.

The data-filter attribute will contain each projects' tags.

site/snippets/projects.php

<?php if(!$page->isHomepage()): ?>
<div class="buttons-filter-wrapper">
  <span class="buttons-filter filter" data-filter="all">All</span>
  <?php foreach($tags as $tag): ?>
  <span class="buttons-filter filter" data-filter=".<?php echo str::slug($tag) ?>"><?php echo html($tag) ?></span>
  <?php endforeach ?>
</div>
<?php endif ?>

Step 4 - The modified project list

We need to modify a bit the original list from the projects.php snippet.

<ul class="<?php e($page->isHomepage(), 'teaser', 'teaser-filter')?> cf">
We're using a different class for the list on the homepage and on the projects page. Here e(), the shorthand for ecco(), let's us echo a different value depending on the outcome of the first parameter: is this the homepage?

The mix class is used by the Mixitup plugin.

<?php foreach($project->tags()->split(',') as $tag): ?><?php echo str::slug($tag) ?> <?php endforeach ?> is used to add all the projects' tags as classes. This way, each button's data-filter will link to projects with the same class.

site/snippets/projects.php

<ul class="<?php e($page->isHomepage(), 'teaser', 'teaser-filter')?> cf">
  <?php foreach($projects as $project): ?>
  <li class="mix <?php foreach($project->tags()->split(',') as $tag): ?><?php echo  str::slug($tag) ?> <?php endforeach ?>">
    <h3><a href="<?php echo $project->url() ?>"><?php echo $project->title()->html() ?></a></h3>
    <p><?php echo $project->text()->excerpt(80) ?> <a href="<?php echo $project->url() ?>">read&nbsp;more&nbsp;→</a></p>
    <?php if($image = $project->images()->sortBy('sort', 'asc')->first()): ?>
    <a href="<?php echo $project->url() ?>">
      <img src="<?php echo $image->url() ?>" alt="<?php echo $project->title()->html() ?>" >
    </a>
    <?php endif ?>
  </li>
  <?php endforeach ?>
</ul>

The complete snippet

That's it for our projects snippet. Let's put it all together. Your snippet should look like this.

site/snippets/projects.php

<h2>Latest projects</h2>
<?php if(!$page->isHomepage()): ?>
<div class="buttons-filter-wrapper">
  <span class="buttons-filter filter" data-filter="all">All</span>
  <?php foreach($tags as $tag): ?>
  <span class="buttons-filter filter" data-filter=".<?php echo str::slug($tag) ?>"><?php echo html($tag) ?></span>
  <?php endforeach ?>
</div>
<?php endif ?>

<ul class="<?php e($page->isHomepage(), 'teaser', 'teaser-filter')?> cf">
  <?php foreach($projects as $project): ?>
  <li class="mix <?php foreach($project->tags()->split(',') as $tag): ?><?php echo  str::slug($tag) ?> <?php endforeach ?>">
    <h3><a href="<?php echo $project->url() ?>"><?php echo $project->title()->html() ?></a></h3>
    <p><?php echo $project->text()->excerpt(80) ?> <a href="<?php echo $project->url() ?>">read&nbsp;more&nbsp;→</a></p>
    <?php if($image = $project->images()->sortBy('sort', 'asc')->first()): ?>
    <a href="<?php echo $project->url() ?>">
      <img src="<?php echo $image->url() ?>" alt="<?php echo $project->title()->html() ?>" >
    </a>
    <?php endif ?>
  </li>
  <?php endforeach ?>
</ul>

Step 5 - Add JQuery and Mixitup JS

As we said above, you can download both JQuery and Mixitup plugins to add them to your website, or use them directly from their CDN. We use the CDN in our tutorial, and it happens in the footer.php snippet.
Notice we're using Kirby's built-in JS helper to load both files.

Learn more about Mixitup options

site/snippets/footer.php

<?= js(array('http://code.jquery.com/jquery-1.11.0.min.js','http://cdn.jsdelivr.net/jquery.mixitup/latest/jquery.mixitup.min.js'))?>

<script>
    $('.teaser-filter').mixItUp({
        animation: {
            animateResizeContainer: false,
            effects: 'fade translateZ(500px)',
            duration: 300
        }       
    });
</script>

Final step - Add some css

We use some very simple styling in this tutorial to get you started.

Here are some other style examples for you to play with:
Codepen 1 Codepen 2

site/assets/css/main.css

/*Button filter*/
.buttons-filter-wrapper{
  margin:2em 0
}
.buttons-filter{
  display:inline-block;
  background:#f4f4f4;
  padding:.7em 1em;
  border-radius:2px;
  cursor:pointer;
  margin:0 0 .5em 0
}
/*teaser elements*/
.teaser-filter li{
  -webkit-backface-visibility: hidden;
  -webkit-transform-origin: 50% 0;
  width: 100%;
  margin-bottom: 4.8px;
  margin-bottom: 1.7rem;
  /*used with the mixitup javascript plugin: filter will not work whithout it*/
  display:none;
}
/*teaser Style*/
@media(min-width:500px){
  .teaser-filter{       
    margin: 16px 0;
    margin: 1rem 0;
    -webkit-column-count: 2;
    -moz-column-count: 2;
    column-count: 2;
    -webkit-column-gap: .3rem;
    -moz-column-gap: .3rem;
    column-gap: .3rem;
    overflow:hidden;
    max-height: 1200px;
  }
}

@media(min-width:768px){
  .teaser-filter{       
    margin: 16px 0;
    margin: 1rem 0;
    -webkit-column-count: 3;
    -moz-column-count: 3;
    column-count: 3;            
    -webkit-column-gap: .3rem;
    -moz-column-gap: .3rem;
    column-gap: .3rem;
    overflow:hidden;
    max-height: 1200px;
  }  
}

Conclusion

You can now show your subpages with a very clean MASONRY styled grid based on the native Kirby tags. In this demo, tags with accents and spaces will be converted to html safe strings thanks to str::slug. We always do this for the French Kirby users ;-)

If you wish to add some suggestions, see an error, or just want to say hello, please feel free to use the comments below.

Download the full tutorial

Stay tuned!

Want to always know the latest Maco news? Subscribe and receive the newsletter straight in your inbox. No spam guarantee!

Write a comment