File: /var/www/vcz/wp-content/themes/volonteka/vendor/timber/timber/docs/guides/extending-timber.md
---
title: "Extending Timber"
menu:
main:
parent: "guides"
---
Myth: Timber is for making simple themes. Fact: It's for making incredibly complex themes _look_ easy. But yes, you can also make simple sites from it.
The beauty of Timber is that the object-oriented nature lets you extend it to match the exact requirements of your theme.
## An example that extends TimberPost
Timber's objects like `Timber\Post`, `Timber\Term`, etc. are a great starting point to build your own subclass from. For example, on this project each post was a part of an "issue" of a magazine. I wanted an easy way to reference the issue in the twig file:
```twig
<h1>{{ post.title }}</h1>
<h3>From the {{ post.issue.title }} issue</h3>
```
Of course, `Timber\Post` has no built-in concept of an issue (which I've built as a custom taxonomy called "issues"). So we're going to extend TimberPost to give it one:
```php
<?php
class MySitePost extends Timber\Post {
var $_issue;
public function issue() {
$issues = $this->get_terms('issues');
if (is_array($issues) && count($issues)) {
return $issues[0];
}
}
}
```
So now I've got an easy way to refer to the {{ post.issue }} in our twig templates. If you want to make this production-ready I recommend a bit of internal caching so that you don't re-query every time you need to get the
issue data:
```php
<?php
class MySitePost extends Timber\Post {
var $_issue;
public function issue() {
if (!$this->_issue) {
$issues = $this->get_terms('issues');
if (is_array($issues) && count($issues)) {
$this->_issue = $issues[0];
}
}
return $this->_issue;
}
}
```
Right now I'm in the midst of building a complex site for a hybrid foundation and publication. The posts on the site have some very specific requirements that requires a fair amount of logic. I can take the simple `Timber\Post` object and extend it to make it work perfectly for this theme.
For example, I have a plugin that let's people insert manually related posts, but if they don't, WordPress will pull some automatically based on how the post is tagged.
```php
<?php
class MySitePost extends Timber\Post {
function get_related_auto() {
$tags = $this->tags();
if (is_array($tags) && count($tags)) {
$search_tag = $tags[0];
$related = Timber::get_posts('tag_id='.$search_tag->ID);
return $related;
} else {
//not tagged, cant do related on it
return false;
}
}
function get_related_manual() {
if (isset($this->related_manual) && is_array($this->related_manual)){
foreach($this->related_manual as &$related){
$related = new MySitePost($related);
}
return $this->related_manual;
}
return false;
}
function related($limit = 3) {
$related = $this->get_related_manual();
if (!$related){
$related = $this->get_related_auto();
}
if (is_array($related)) {
array_splice($related, 0, $limit);
}
return $related;
}
}
```
These can get pretty complex. And that's the beauty. The complexity lives inside the context of the object, but very simple when it comes to your templates.
## Adding functionality to Twig
You can extend Twig by adding custom functionality like functions or filters. Timber provides its own classes (`Timber\Twig_Function` and `Timber\Twig_Filter`) to provide better compatibility with different versions of Twig.
**functions.php**
```php
<?php
add_filter( 'timber/twig', 'add_to_twig' );
/**
* Adds functionality to Twig.
*
* @param \Twig\Environment $twig The Twig environment.
* @return \Twig\Environment
*/
function add_to_twig( $twig ) {
// Adding a function.
$twig->addFunction( new Timber\Twig_Function( 'edit_post_link', 'edit_post_link' ) );
// Adding functions as filters.
$twig->addFilter( new Timber\Twig_Filter( 'whateverify', 'whateverify' ) );
$twig->addFilter( new Timber\Twig_Filter( 'slugify', function( $title ) {
return sanitize_title( $title );
} ) );
return $twig;
}
function whateverify( $text ) {
$text .= ' or whatever';
return $text;
}
```
This can now be called in your twig files with:
```twig
<h2 id="{{ post.title|slugify }}">{{ post.title|whateverify }}</h2>
```
Which will output:
```twig
<h2 id="hello-world">Hello World! or whatever</h2>
```