Kirby

Blog (RSS)

News about Kirby and stuff

Follow kirby on Twitter
@getkirby for more
updates.

Tags

How to handle tags

We all remember those days when every blog had a tagcloud with variable font sizes to show the most important tags – man, this has been so cool six years ago. But still tags are a great way to separate your content into different categories and make it easier for your visitors to find the articles and pages they are looking for.

With the latest release of Kirby it has become very easy to add tags to your pages and to build a tag filter – or if you prefer "tagcloud".

Adding Tags to your content

The perfect format to add tags to your content is a comma separated list.

Title: Some title
----
Text: Some great text
----
Tags: design, photography, architecture, whatever
----

Looks quite natural, right?

Filtering content by tag

The new filterBy() method is built to make it possible to filter pages by a certain value in a field and even to filter pages by a certain value in a separated list like the tags list above. So we can use that to filter a set of pages by tag in a single line:

$filtered = $page->children()->filterBy('tags', 'design', ',');

This will search through all children of the current page and return all pages with the tag "design". The third argument of the method is telling it to search in a comma separated list. If you prefer to separate your tags with any other character you are free to do that and specify that separation character here.

Do you still remember that tutorial about how to build a blog? In our blog.php template we fetched the latest articles like this:

$articles = $pages->find('blog')
                  ->children()
                  ->visible()
                  ->flip()
                  ->paginate(10);

So if you want to filter them by a specific tag, go for:

$articles = $pages->find('blog')
                  ->children()
                  ->visible()
                  ->filterBy('tags', 'design', ',')
                  ->flip()
                  ->paginate(10);

Controlling the filter by URL

At the end we want to be able to have different URLs for each tag filter. So something like http://yourdomain.com/blog/tag:fun should show all articles with tagged fun and http://yourdomain.com/blog/tag:design should show all design articles.

It's very easy to fetch those parameters passed by the URL with Kirby:

// url: http://yourdomain.com/blog/tag:design
echo param('tag');
// result: design

// url: http://yourdomain.com/blog/tag:fun
echo param('tag');
// result: fun

So what we need to do is to replace 'design' in our articles example above with the param function.

$articles = $pages->find('blog')
                  ->children()
                  ->visible()
                  ->filterBy('tags', param('tag'), ',')
                  ->flip()
                  ->paginate(10);

Now you can filter all your articles in your blog by specifying the tag in the URL.

Of course we want to make sure that the filter is only applied when a tag is added to the URL. We need a little if clause to do that:

if(param('tag')) {

  $articles = $pages->find('blog')
                    ->children()
                    ->visible()
                    ->filterBy('tags', param('tag'), ',')
                    ->flip()
                    ->paginate(10);

} else {

  $articles = $pages->find('blog')
                    ->children()
                    ->visible()
                    ->flip()
                    ->paginate(10);

}

That's it! Our tag filter is read :)

The tagcloud plugin

But still nobody knows about those tags and the URLs. So we need our "tagcloud"

I've prepared a little tagcloud plugin, which you can use to generate a cloud like the one in the sidebar of this blog.

Download the code for it and add it to site/plugins/tagcloud.php. If the plugins folder is not there yet, create one.

Using the tagcloud plugin in your templates

The tagcloud plugin will return an array of all tags, which have been found. You can use that to build a simple HTML list for example and style that later.

In your blog template you can add the tagcloud like this:

<?php

$blog = $pages->find('blog');
$tags = tagcloud($blog);

?>
<ul class="tagcloud">
  <?php foreach($tags as $tag): ?>
  <li<?php if($tag->isActive()) echo ' class="active"' ?>><a href="<?php echo $tag->url() ?>"><?php echo $tag->name() ?></a></li>
  <?php endforeach ?>
</ul>

When you loop through the result of tagcloud() each tag has the following methods:

$tag->name()

The name of the current tag.

$tag->isActive()

This will check if the tag is also currently passed by the URL and is then marked as active. This makes it possible to add an active class to the tag element for example to give it a different style when the tag is "selected".

$tag->url()

The tagcloud plugin automatically generates a tag url, for each found tag. So if you use the tagcloud plugin on http://yourdomain.com/blog $tag->url() will give you something like http://yourdomain.com/blog/tag:design

$tag->results()

This will return the number of found pages for the current tag. You can use that to display how many pages have been found or to generate an old-school cloud with different font sizes :)

Plugin options

The plugin has a bunch of options available to customize it. Here's an example with the full stack of options:

$blog     = $pages->find('blog');
$tagcloud = tagcloud($blog, array(
  'limit'    => 20,
  'field'    => 'keywords',
  'children' => 'all',
  'baseurl'  => 'http://mycustomurl.com/blog',
  'param'    => 'keyword',
  'sort'     => 'name',
  'sortdir'  => 'asc'
));

limit

Specify the number of tags in the cloud. If no limit is set, all tags will be displayed.

field

You can change the fieldname here, in which the tagcloud plugin will search for tags.

children

By default the plugin will search in all visible children, but you can also set this to 'all' or 'invisible'

baseurl

If you want to specify a different base URL for all tag URLs, you can do that here. By default the plugin will use the URL of the passed main page.

param

You can even change the name of the param in the URL. So if you rather have an URL like http://yourdomain.com/blog/keyword:design, you can change this here.

sort

By default the plugin sorts the result by the number of pages found per tag. You can also sort it by tag name of course.

sortdir

Specify the sort direction here. Default is 'desc'

Conclusion

I hope this plugin will help you to build categories and tag filters for your site. If you got any questions, please let me know.

‹ Back

blog comments powered by Disqus