Helps you create themes faster with sustainable code. With Timber, you write HTML using Twig Templates http://www.upstatement.com/timber/
With the upcoming release of Timber 2.0, we will not release a 2.0 version and beyond as a plugin, but only as a Composer package. We advise everyone to switch to the Composer based install as soon as possible.
You will find an extensive list with guides and the reasons why we are not going to release Timber 2.0 as a plugin anymore.
Timber helps you create fully-customized WordPress themes faster with more sustainable code. With Timber, you write your HTML using the Twig Template Engine separate from your PHP files. This cleans up your theme code so, for example, your PHP file can focus on being the data/logic, while your Twig file can focus 100% on the HTML and display.
Once Timber is installed and activated in your plugin directory, it gives any WordPress theme the ability to take advantage of the power of Twig and other Timber features.
Please post on StackOverflow under the “Timber” tag. Please use GitHub issues only for specific bugs, feature requests and other types of issues.
For an example, try modifying your home.php
or index.php
with something like this:
$context = array();
$context[‘message’] = ‘Hello Timber!’;
Timber::render( ‘welcome.twig’, $context );
Then create a subdirectory called views
in your theme folder. Then create a file views/welcome.twig
with these contents:
<div class="welcome"> <h3>{{ message }}</h3> </div>
When you visit this page, you’ll see both the data from PHP come through as you’ve marked it up. For more, continue with the official Getting Started Guide
You bet! Watch these Video Tutorials to see how.
Tens of thousands of sites now use Timber. You can check some of them out in the Showcase.
Does jQuery make JavaScript harder? Yes, it’s an extra piece to learn — but it super-charges your ability to write unencumbered JavaScript (and prevents you from having to learn lots of the messy internals). If your answer is “jQuery sucks and everyone should learn how to write vanilla JavaScript or they’re rotten stupid people,” this tool isn’t for you.
Whatever. It simplifies the silly stuff so that you can focus on building more complicated sites and apps. jQuery simplifies Javascript, but you can still use the full range of JavaScript’s abilities.
At Upstatement we’re using it in dozens of sites (and many more planned) — thousands of other developers are using it too. This isn’t going anywhere. Twig is the chosen language for other PHP platforms like Symfony, Drupal 8 and Craft.
Full Changelog: https://github.com/timber/timber/compare/1.22.1…1.23.0
Fixes and improvements
Improve composer version ranges by @gchtr in #2550
@Web-Assembler made their first contribution in #2523
Fixes and improvements
thumbnail()
method return type by @titouanmathis in https://github.com/timber/timber/pull/2463Bump version of Upstatement/Routes to 0.8.1 by @jarednova in https://github.com/timber/timber/pull/2512
@titouanmathis made their first contribution in https://github.com/timber/timber/pull/2463
Full Changelog: https://github.com/timber/timber/compare/1.19.0…1.19.1
Changes for Theme Developers
timber/loader/loader
filter #2324 (thanks @neojp)Fixes and improvements
get_the_date
and get_the_time
filters #2350 (thanks @shvlv)wp:more
tag works with noteaser
#2348 #2351 (thanks @jhhazelaar)home_url()
should be used instead of site_url()
#2356 #2357 (thanks @Levdbas)Timber::get_sites
returned the same locale for all sites #1908 #2369 (thanks @highbelt)Fix for proper ignoring of the Cache directory on case-insensitive file systems #342 #2416 (thanks @toonvandeputte)
Fixed a bug when using switch_to_blog()
in combination with Timber images #1312 #2478 (thanks @gchtr)
Fixes and improvements
Fixes and improvements
Timber\PostCollection
s) #2314 (thanks @nlemoine)Changes for Theme Developers
Fixes and improvements
Changes for Theme Developers
timber/allow_fs_write
to ensure compatibility with WordPress VIP and other hosts with filewrite restrictions. #2250 (thanks @mjangda)Fixes and improvements
{{ dump() }}
when WP_DEBUG = FALSE doesn’t cause a fatal error #2217, #2282Changes for Theme Developers
* Allows for translation of time_ago Twig filter #2214 #2215 (thanks @gchtr)
Fixes and improvements
* Fixed an issue where an excessive amount of DELETEs could hit the DB #1834 #2243 (thanks @chads2000 @dennisjac)
* Fix an issue with blank user names #2232 (thanks @flip111)
Fixes and improvements
* Fix error with S3 URLs and resize filters #2213 (thanks @hoangnd25)
Fixes and improvements
* Fixed an issue where null results from PostGetter::get_posts
could trigger a fatal error #2199 (thanks @jhhazelaar)
* Removed a useless and confusing error_log message when a post_type
isn’t found in a class map #2202 (thanks @gchtr)
* Fixed a documentation issue that gave phpStorm a bad time with query_post
#2205 (thanks @mweimerskirch)
Fixes and improvements
– Fixed an issue where a custom field named “content” could conflict with {{ post.content }}
– Fixed an issue where Timber/User::$id
was returned as a string instead of an integer (thanks @rubas)
Changes for Theme Developers
– Timber’s data to Apache/Nginx error logs (via error_log()
) is now prefixed with [ Timber ]
Fixes and improvements
– {{ post.date }} and {{ post.time }} now use date_i18n
under the hood instead of mysql2date
#2104 #2126 (thanks @palmiak)
– WordPress 4.9.8 is the new min supported version.
Changes for Theme Developers
– We’re now using minimum versions of Twig 1.41 and 2.10
– Twig introduced a filter filter (you read that right, a filter named filter — like {{ sizes | filter(v => v > 38) }}
. This wrecked havoc on our own pre-existing Timber filter filter {{ posts | filter({post_title:"Cheese", post_content:"Yum!"}, "AND") }}
. In #2124 we gave Twig’s filter the preferred treatment. However, if the arguments look like you intend to use the old filter (which is a wrapper for WordPress’s WP_List_Util class) we use what’s there. Want to keep using the class Timber filter filter? Switch it to wp_list_filter
as in {{ posts | wp_list_filter({post_title:"Cheese", post_content:"Yum!"}, "AND") }}
(thanks @palmiak @gchtr @nlemoine @aj-adl @rubas @xdevelx and others)
Fixes and improvements
– Fix issue with debug on/off in certain installs #2084 (thanks @kmonahan)
– Fix link to admin pages #2112 (thanks @Beee4life)
Fixes and improvements
– Fix resizing for images with UTF-8 characters in their filename #2072
– Added tests to cover RTL languages and special characters in image file names #2072
– Fixed MenuItem menu recursion #2071 #2083
Changes for Theme Developers
– Added new found_posts
property for Timber\PostQuery
. Now you can check how many posts were found in a query.
General Note
– If you use WPML with Timber, please upgrade to WPML 4.2.8. The WPML team has removed their included Twig version which means no more conflicts!
Fixes and improvements
– Fix to menu items getting incorrect classes in WPML and others #1974
– Fixed issue with Timber not respecting comment order #1731 #2015
Changes for Theme Developers
– Theme methods (theme.get and theme.display) for headers are now exposed by Timber\Theme #2051 (thanks @dtvn)
Fixes and improvements
– Allows for a MenuItem’s Menu to be unknown #2024 #2025
Important Note
If you use WPML, please do not upgrade to 1.10.* yet. Because WPML also uses Twig, there is a conflict with loading Twig versions. They will release an update soon to keep things in sync. Until then, please use version 1.9.2
Fixes and improvements
– You can now skip the eager loading of meta vars through a filter #2014 (thanks @aj-adl @gchtr)
– Use Twig 1.38 to prevent compatibility issues with WPML and other plug-ins
– This restores the prior behavior before #1813 / 1.9.3 when using Timber::get_posts. This is now controllable by devs via a filter #1989 (thanks @palmiak)
– Add support for non-cookied comment awaiting moderation message #1954 (thanks @codeclarified)
– Avoids a potential WSOD when incorrectly specifying template filenames #1984 (thanks @aj-adl)
– Fixes a bug introduced in #1813 that was watching for the query param of supress_filters
(instead of the correct spelling: suppress_filters
)
– Fixes a bug where the last menu item received incorrect CSS classes #2009 #1974 (thanks @strategio)
Changes for Theme Developers
– You can use WordPress’s behavior of get_posts
(versus WP_Query
) via a filter. By default, Timber uses the behaviors of WP_Query in Timber’s queries #1989 (thanks @palmiak)
– If you run into problems with unknown Twig_SimpleFilter
or unknown Twig_Filter
classes, you can use Timber\Twig_Filter
instead.
– Fixed Timber::get_posts
so that its default query parameters mirror WordPress’s get_posts
#1812 (thanks @bartvanraaij)
– You can now more easily work with menu locations and filters #1959 #2018 (thanks @gchtr)
Changes for Theme Developers
– You can use Timber::context()
as an alias for Timber::get_context()
. It’s prettier, it also will prep you for Timber 2.0 where Timber::get_context()
is deprecated #1938
Fixes and improvements
– Integration of newest version of Upstatement/Routes which uses (newest) version 1.2.0 of AltoRouter #1946 (thanks @seanstickle)
Changes for Theme Developers
– You can now pass params to {{ user.avatar }}
such as {{ user.avatar({size: 128}) }}
#1730 (thanks @palmiak)
Fixes and improvements
– Fix for PHP 7.3 compatibility #1915 (thanks @palmiak)
– Fix for URLHelper::is_external for URLs without protocol #1924 (thanks @hacknug)
Timber now requires PHP 5.6 or greater. While Timber may work on PHP 5.5 and older versions; support will no longer be maintained in future versions.
Changes for Theme Developers
– Adds support for roles on the user object. Example: {{ post.author.roles }}
which returns an array of roles #1898 (thanks @palmiak)
– Adds support for capabilities on the user object. Example: {{post.author.can("moderate_comments")}}
which returns true or false #1898 (thanks @palmiak)
Fixes and improvements
* Fix an error with handling args for nav menus #1865 (thanks @palmiak)
* Allowed tags won’t be stripped when automatically generating an excerpt #1886 (thanks @davefx)
* Fix for JPG/WEBP conversion for some older PHP installs #1854
Fixes and improvements
* Resolve potential pagination issue #1642 (thanks @gchtr)
Fixes and improvements
* Hotfix for PHP versions 5.5 and 5.4
Changes for Theme Developers
– You can now change the query parameters that are used when getting a post’s terms through $post->terms()
. #1802
– New attributes for responsive images post.thumbnail.srcset
and post.thumbnail.sizes
#1819 (thanks @maxxwv)
Fixes and improvements
– Using WordPress’s wp_check_filetype_and_ext
for the mime_type mess #1843 (thanks @gchtr)
– Fixed how some previewed data (when looking at an unsaved post from the admin) is handled so that parenting relationships match what happens when published #1752
– Timber\Menu now respects modifications sent through WP’s wp_nav_menu_objects
filter #1814 (thanks @pascalknecht)
Fixes and improvements
– Fixed how mime_type was figured out in some PHP installs #1798
Changes for Theme Developers
– Webp is now supported as a conversion format ( {{ post.thumbnail.src | towebp }}
) @mhz-tamb @pascalknecht #1638 #1777 #1780
– Timber now recognizes that SVGs shouldn’t be resized as if they are rasters (for retina, etc.) @palmiak #1726 #1736
Fixes and improvements
– Clean-up on i18n function calls @drzraf #1753
– Fixed some odd port handling @pascalknecht #1760
– Fixed how terms are retrived through a post @shvlv #1729
Fixes and improvements
– Fixes issues previewing custom fields with ACF #1712
– Fixes some edge cases with Menu Item classes #1709
– Improved efficiency of Post class instantiation #1660
Fixes and improvements
– Fixed some issues with animated gif resizing when Imagick isn’t available #1653
– Fixed incorrect reporting of depth level in some comments #1648
– Fixed issues with preview permissions #1607
– Fixed issue with image resize in some WPML setups #1625
– Fixes compatibility issues with Twig 2.4 (and later) #1641
Changes for Theme Developers
– You can now easily access all of a MenuItem’s master object properties through {{ item.master_object }}
What’s a master object? It’s when a Menu Item has been created directly from a Post or Term in the WP Admin #1577 #1572
– Enabled methods for getting media from posts, you can now do {{ post.video }}
, {{ post.audio }}
and {{ post.gallery }}
to retrieve media include in the body of a post #1583 (thanks @marciojc)
– You can now get ACF’s field object data: {{ post.field_object('my_field').key }}
#1597 #1599 (thanks @palmiak)
– You can use the |filter
filter on arrays to return items like so:{% for post in posts|filter('my-slug') %}
{{ post.title }}
{% endfor %}
by default it looks for slugs, but you can also get into particular fields:{% for post in posts|filter({post_title: "Cheese", post_content:"Method Man"}) %}
{{ post.title }}
{% endfor %}
… this will return posts that match both parameters. #1594 thanks @pablo-sg-pacheco
Fixes and improvements
– Fixed a bug where multi-level menus weren’t receiving proper data
Fixes and improvements
– Transparent PNGs now work with letterboxing #1554 (thanks @nlemoine)
Changes for Theme Developers
– You can now interact with Terms in Twig the same as PHP (ex: {% set term = Term(34, "arts") %}
). The second arg will default to a subclass of Timber\Term if it exists #1159 (@jarednova)
– You can now get {{ theme.version }} to get the theme version! #1555 (thanks @herrschuessler)
Fixes and improvements
– home_url
value is now cached, performance win for polylang! #1507 (thanks @oxyc)
– Post::$css_class is only fetched if requested #1522 (thanks @ruscon)
– Improved flexibility of PostCollection to be filterable #1544 (thanks @gchtr)
– More test coverage
Changes for Theme Developers
– None! But the above fixes have significant changes in the code which necessitated the “.x” version jump
Fixes and improvements
– Fix for WPML URLs in some situations #1513 (thanks @ChrisManganaro)
– Fix for PHP 5.5 issue with some URLs #1518 (thanks @danFWD)
Fixes and Improvements
– Improve GIF resize performance #1495 (thanks @ahallais)
– Fix for get_host which could generate an unnecessary warning #1490 (thanks @ahallais)
Changes for Theme Developers
– Improve loader performance and logic #1476 #1489 #1491 (thanks @heino). This introduces potential changes if you were loading templates in a non-standard way and with multiple sources (ex: from a theme and plugin directory). Non-existing templates are no longer passed all the way to Twig’s render()
, which currently generates an exception.
{{ posts.pagination }}
in your Twig templates without any further PHP work (thanks @lggorman)<p>
tags{{ function('my_cool_function', 'my_argument') }}
(thanks @gchtr)FunctionWrapper
with appropriate warnings and Twig 2.0 compatibility (thank you thank you @gchtr)post.children()
(thanks @njbarrett){{ post.authors }}
939331e282fd54bf3e210645964504304f2b071btimber/post/content/show_password_form_for_protected
) 0f9b20ec90b34059634c25bc27671875c18f8fcbtimber/loader/custom
) (thanks @tnottu!) 9097984a7c3df23068056d7835465e0690338567|e('wp_kses_post')
and |e('esc_url')
(thanks @matgargano){{ post.type }}
behavior for existing custom fields (@jarednova) 6c9574912e526b8589eb134b79820c7e239a1dda{{ post.type }}
this makes it easy to access things like {{post.type.labels.name}}
right in Twig https://github.com/timber/timber/pull/1003{{ post.preview }}
which makes it easy to customize like {{post.preview.length(50).read_more("Keep Reading").end('........')}}
https://github.com/timber/timber/pull/1015Timber::get_term
(thanks @connorjburton!) 58fe671757b30a8eb9de2589bbb817448662e121Timber::get_pids
(@jarednova) 4278d11d25aaca0d60cbde32c32783dc0effac6b{{ user }}
object to contextBug Fixes
Fix to “next” in pagination (thanks @connorjburton) #900
{{post.parent.children}}
used to return unpublished posts due to underlying behavior in WordPress, it now only returns published posts (thanks @connorjburton) #883list
(thanks @lggorman){{comment.status}}
when working with comments (thanks @simonmilz)