Timber - Version 0.15.5

Version Description

  • Post formats: {{post.format}} !
Download this release

Release Info

Developer jarednova
Plugin Icon 128x128 Timber
Version 0.15.5
Comparing to
See all releases

Code changes from version 0.15.3 to 0.15.5

README.md CHANGED
@@ -9,7 +9,7 @@ By Jared Novack (<a href="http://twitter.com/jarednova">@JaredNova</a>) and <a h
9
  ### Because WordPress is awesome, but the_loop isn't
10
  Timber helps you create fully-customized WordPress themes faster with more sustainable code. With Timber, you write your HTML using the [Twig Template Engine](http://twig.sensiolabs.org/) separate from your PHP files.
11
 
12
- This cleans-up your theme code so, for example, your php file can focus on being the data, while your twig file can focus 100% on the HTML and display.
13
 
14
  This is what Timber's `.twig` files look like:
15
 
@@ -29,13 +29,13 @@ Once Timber is installed and activated in your plugin directory, it gives any Wo
29
  ### Looking for docs?
30
  * [Timber Documentation](https://github.com/jarednova/timber/wiki/)
31
  * [Twig Reference](http://twig.sensiolabs.org/doc/templates.html)
32
- * **[Video Tutorials](https://github.com/jarednova/timber/wiki/Video-Tutorials)**
33
  * [Overview / Getting Started Guide](https://github.com/jarednova/timber/wiki/getting-started)
34
 
35
  * * *
36
 
37
  ### Installation
38
- Just drag the `timber` folder into `wp-content/plugins` -- then activate in your WordPress admin.
39
 
40
  * * *
41
 
9
  ### Because WordPress is awesome, but the_loop isn't
10
  Timber helps you create fully-customized WordPress themes faster with more sustainable code. With Timber, you write your HTML using the [Twig Template Engine](http://twig.sensiolabs.org/) separate from your PHP files.
11
 
12
+ 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.
13
 
14
  This is what Timber's `.twig` files look like:
15
 
29
  ### Looking for docs?
30
  * [Timber Documentation](https://github.com/jarednova/timber/wiki/)
31
  * [Twig Reference](http://twig.sensiolabs.org/doc/templates.html)
32
+ * [Video Tutorials](https://github.com/jarednova/timber/wiki/Video-Tutorials)
33
  * [Overview / Getting Started Guide](https://github.com/jarednova/timber/wiki/getting-started)
34
 
35
  * * *
36
 
37
  ### Installation
38
+ Just drag the `timber` folder into `wp-content/plugins` -- then activate in your WordPress admin. If you're looking for a 'blank' theme to start developing with, drag the `timber-starter-theme` from the timber directory into your themes directory.
39
 
40
  * * *
41
 
functions/functions-twig.php CHANGED
@@ -252,6 +252,8 @@ function twig_body_class($body_classes) {
252
  }
253
 
254
  function render_twig_string($string, $data = array()) {
 
 
255
  $loader = new Twig_Loader_String();
256
  $twig = new Twig_Environment($loader);
257
  return $twig->render($string, $data);
252
  }
253
 
254
  function render_twig_string($string, $data = array()) {
255
+ $timber_loader = new TimberLoader();
256
+ $timber_loader->get_twig();
257
  $loader = new Twig_Loader_String();
258
  $twig = new Twig_Environment($loader);
259
  return $twig->render($string, $data);
functions/timber-archives.php ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class TimberArchives extends TimberCore {
3
+ function __construct($args){
4
+ $this->init($args);
5
+ }
6
+
7
+ function init($args){
8
+ $this->items = $this->get_items($args);
9
+ }
10
+
11
+ function get_archives_link($url, $text) {
12
+ $ret['text'] = $ret['title'] = $ret['name'] = wptexturize($text);
13
+ $ret['url'] = $ret['link'] = esc_url($url);
14
+ return $ret;
15
+ }
16
+
17
+ function get_items_yearly($args, $last_changed, $join, $where, $order, $limit){
18
+ global $wpdb;
19
+ $output = array();
20
+ $query = "SELECT YEAR(post_date) AS `year`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date) ORDER BY post_date $order $limit";
21
+ $key = md5( $query );
22
+ $key = "wp_get_archives:$key:$last_changed";
23
+ if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
24
+ $results = $wpdb->get_results( $query );
25
+ wp_cache_set( $key, $results, 'posts' );
26
+ }
27
+ if ( $results ) {
28
+ foreach ( (array) $results as $result) {
29
+ $url = get_year_link($result->year);
30
+ $text = sprintf('%d', $result->year);
31
+ $output[] = self::get_archives_link($url, $text);
32
+ }
33
+ }
34
+ return $output;
35
+ }
36
+
37
+ function get_items_montly($args, $last_changed, $join, $where, $order, $limit){
38
+ global $wpdb, $wp_locale;
39
+ $output = array();
40
+ $defaults = array(
41
+ 'show_year' => true,
42
+ );
43
+ $r = wp_parse_args( $args, $defaults );
44
+ extract( $r, EXTR_SKIP );
45
+ $where = $where;
46
+ //will need to specify which year we're looking for
47
+ $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date $order $limit";
48
+ $key = md5( $query );
49
+ $key = "wp_get_archives:$key:$last_changed";
50
+ if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
51
+ $results = $wpdb->get_results( $query );
52
+ wp_cache_set( $key, $results, 'posts' );
53
+ }
54
+ if ( $results ) {
55
+ foreach ( (array) $results as $result ) {
56
+ $url = get_month_link( $result->year, $result->month );
57
+ /* translators: 1: month name, 2: 4-digit year */
58
+ if ($show_year){
59
+ $text = sprintf(__('%1$s %2$d'), $wp_locale->get_month($result->month), $result->year);
60
+ } else {
61
+ $text = sprintf(__('%1$s'), $wp_locale->get_month($result->month));
62
+ }
63
+ $output[] = self::get_archives_link($url, $text);
64
+ }
65
+ }
66
+ return $output;
67
+ }
68
+
69
+ function get_items($args){
70
+ global $wpdb, $wp_locale;
71
+
72
+ $defaults = array(
73
+ 'type' => 'monthly', 'limit' => '',
74
+ 'format' => 'html', 'before' => '',
75
+ 'after' => '', 'show_post_count' => false,
76
+ 'order' => 'DESC',
77
+ );
78
+
79
+ $r = wp_parse_args( $args, $defaults );
80
+ extract( $r, EXTR_SKIP );
81
+
82
+ if ( '' == $type )
83
+ $type = 'monthly';
84
+
85
+ if ( '' != $limit ) {
86
+ $limit = absint($limit);
87
+ $limit = ' LIMIT '.$limit;
88
+ }
89
+
90
+ $order = strtoupper( $order );
91
+ if ( $order !== 'ASC' ){
92
+ $order = 'DESC';
93
+ }
94
+
95
+ // this is what will separate dates on weekly archive links
96
+ $archive_week_separator = '&#8211;';
97
+
98
+ // over-ride general date format ? 0 = no: use the date format set in Options, 1 = yes: over-ride
99
+ $archive_date_format_over_ride = 0;
100
+
101
+ // options for daily archive (only if you over-ride the general date format)
102
+ $archive_day_date_format = 'Y/m/d';
103
+
104
+ // options for weekly archive (only if you over-ride the general date format)
105
+ $archive_week_start_date_format = 'Y/m/d';
106
+ $archive_week_end_date_format = 'Y/m/d';
107
+
108
+ if ( !$archive_date_format_over_ride ) {
109
+ $archive_day_date_format = get_option('date_format');
110
+ $archive_week_start_date_format = get_option('date_format');
111
+ $archive_week_end_date_format = get_option('date_format');
112
+ }
113
+
114
+ $where = apply_filters( 'getarchives_where', "WHERE post_type = 'post' AND post_status = 'publish'", $r );
115
+ $join = apply_filters( 'getarchives_join', '', $r );
116
+
117
+ $output = array();
118
+
119
+ $last_changed = wp_cache_get( 'last_changed', 'posts' );
120
+ if ( ! $last_changed ) {
121
+ $last_changed = microtime();
122
+ wp_cache_set( 'last_changed', $last_changed, 'posts' );
123
+ }
124
+
125
+ if ( 'monthly' == $type ) {
126
+ $output = $this->get_items_montly($args, $last_changed, $join, $where, $order, $limit);
127
+ } elseif ('yearly' == $type) {
128
+ $output = $this->get_items_yearly($args, $last_changed, $join, $where, $order, $limit);
129
+ } elseif ( 'yearlymonthly' == $type || 'yearmonth' == $type){
130
+ $years = $this->get_items_yearly($args, $last_changed, $join, $where, $order, $limit);
131
+ foreach($years as &$year){
132
+ $args = array('show_year' => false);
133
+ $year['children'] = $this->get_items_montly($args, $last_changed, $join, $where, $order, $limit);
134
+ }
135
+ $output = $years;
136
+ } elseif ( 'daily' == $type ) {
137
+ $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, DAYOFMONTH(post_date) AS `dayofmonth`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date), DAYOFMONTH(post_date) ORDER BY post_date $order $limit";
138
+ $key = md5( $query );
139
+ $key = "wp_get_archives:$key:$last_changed";
140
+ if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
141
+ $results = $wpdb->get_results( $query );
142
+ $cache[ $key ] = $results;
143
+ wp_cache_set( $key, $results, 'posts' );
144
+ }
145
+ if ( $results ) {
146
+ $afterafter = $after;
147
+ foreach ( (array) $results as $result ) {
148
+ $url = get_day_link($result->year, $result->month, $result->dayofmonth);
149
+ $date = sprintf('%1$d-%2$02d-%3$02d 00:00:00', $result->year, $result->month, $result->dayofmonth);
150
+ $text = mysql2date($archive_day_date_format, $date);
151
+ $output[] = self::get_archives_link($url, $text);
152
+ }
153
+ }
154
+ } elseif ( 'weekly' == $type ) {
155
+ $week = _wp_mysql_week( '`post_date`' );
156
+ $query = "SELECT DISTINCT $week AS `week`, YEAR( `post_date` ) AS `yr`, DATE_FORMAT( `post_date`, '%Y-%m-%d' ) AS `yyyymmdd`, count( `ID` ) AS `posts` FROM `$wpdb->posts` $join $where GROUP BY $week, YEAR( `post_date` ) ORDER BY `post_date` $order $limit";
157
+ $key = md5( $query );
158
+ $key = "wp_get_archives:$key:$last_changed";
159
+ if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
160
+ $results = $wpdb->get_results( $query );
161
+ wp_cache_set( $key, $results, 'posts' );
162
+ }
163
+ $arc_w_last = '';
164
+ $afterafter = $after;
165
+ if ( $results ) {
166
+ foreach ( (array) $results as $result ) {
167
+ if ( $result->week != $arc_w_last ) {
168
+ $arc_year = $result->yr;
169
+ $arc_w_last = $result->week;
170
+ $arc_week = get_weekstartend($result->yyyymmdd, get_option('start_of_week'));
171
+ $arc_week_start = date_i18n($archive_week_start_date_format, $arc_week['start']);
172
+ $arc_week_end = date_i18n($archive_week_end_date_format, $arc_week['end']);
173
+ $url = sprintf('%1$s/%2$s%3$sm%4$s%5$s%6$sw%7$s%8$d', home_url(), '', '?', '=', $arc_year, '&amp;', '=', $result->week);
174
+ $text = $arc_week_start . $archive_week_separator . $arc_week_end;
175
+ $output[] = self::get_archives_link($url, $text);
176
+ }
177
+ }
178
+ }
179
+ } elseif ( ( 'postbypost' == $type ) || ('alpha' == $type) ) {
180
+ $orderby = ('alpha' == $type) ? 'post_title ASC ' : 'post_date DESC ';
181
+ $query = "SELECT * FROM $wpdb->posts $join $where ORDER BY $orderby $limit";
182
+ $key = md5( $query );
183
+ $key = "wp_get_archives:$key:$last_changed";
184
+ if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
185
+ $results = $wpdb->get_results( $query );
186
+ wp_cache_set( $key, $results, 'posts' );
187
+ }
188
+ if ( $results ) {
189
+ foreach ( (array) $results as $result ) {
190
+ if ( $result->post_date != '0000-00-00 00:00:00' ) {
191
+ $url = get_permalink( $result );
192
+ if ( $result->post_title ) {
193
+ /** This filter is documented in wp-includes/post-template.php */
194
+ $text = strip_tags( apply_filters( 'the_title', $result->post_title, $result->ID ) );
195
+ } else {
196
+ $text = $result->ID;
197
+ }
198
+ $output .= get_archives_link($url, $text, $format, $before, $after);
199
+ }
200
+ }
201
+ }
202
+ }
203
+ return $output;
204
+ }
205
+ }
functions/timber-comment.php CHANGED
@@ -3,6 +3,7 @@
3
  class TimberComment extends TimberCore {
4
 
5
  var $PostClass = 'TimberPost';
 
6
 
7
  public static $representation = 'comment';
8
 
@@ -75,18 +76,24 @@ class TimberComment extends TimberCore {
75
  $comment_id = $this->ID;
76
  }
77
  //Could not find a WP function to fetch all comment meta data, so I made one.
78
- global $wpdb;
79
- $query = $wpdb->prepare("SELECT * FROM $wpdb->commentmeta WHERE comment_id = %d", $comment_id);
80
- $metas = $wpdb->get_results($query);
81
- $customs = array();
82
- foreach($metas as $meta_row){
83
- $customs[$meta_row->meta_key] = maybe_unserialize($meta_row->meta_value);
84
  }
85
- return $customs;
 
86
  }
87
 
88
  private function get_meta_field($field_name){
89
-
 
 
 
 
 
90
  }
91
 
92
  /* AVATAR Stuff
3
  class TimberComment extends TimberCore {
4
 
5
  var $PostClass = 'TimberPost';
6
+ var $object_type = 'comment';
7
 
8
  public static $representation = 'comment';
9
 
76
  $comment_id = $this->ID;
77
  }
78
  //Could not find a WP function to fetch all comment meta data, so I made one.
79
+ $comment_metas = apply_filters('timber_comment_get_meta_pre', array(), $this->ID);
80
+ $comment_metas = get_comment_meta($this->ID);
81
+ foreach($comment_metas as &$cm){
82
+ if (is_array($cm) && count($cm) == 1){
83
+ $cm = $cm[0];
84
+ }
85
  }
86
+ $comment_metas = apply_filters('timber_comment_get_meta', $comment_metas, $this->ID);
87
+ return $comment_metas;
88
  }
89
 
90
  private function get_meta_field($field_name){
91
+ $value = apply_filters('timber_comment_get_meta_field_pre', null, $this->ID, $field_name, $this);
92
+ if ($value === null){
93
+ $value = get_comment_meta($this->ID, $field_name, true);
94
+ }
95
+ $value = apply_filters('timber_comment_get_meta_field', $value, $this->ID, $field_name, $this);
96
+ return $value;
97
  }
98
 
99
  /* AVATAR Stuff
functions/timber-core.php CHANGED
@@ -13,6 +13,10 @@ class TimberCore {
13
  }
14
  }
15
 
 
 
 
 
16
  function can_edit() {
17
  if (isset($this->_can_edit)) {
18
  return $this->_can_edit;
13
  }
14
  }
15
 
16
+ function update($key, $value){
17
+ update_metadata($this->object_type, $this->ID, $key, $value);
18
+ }
19
+
20
  function can_edit() {
21
  if (isset($this->_can_edit)) {
22
  return $this->_can_edit;
functions/timber-helper.php CHANGED
@@ -2,10 +2,22 @@
2
 
3
  class TimberHelper {
4
 
5
- public static function transient($slug, $callback, $transient_time = 1800){
6
- if (false === ($data = get_transient($slug)) || WP_DEBUG){
 
 
 
 
 
 
 
 
 
 
 
7
  $data = $callback();
8
  set_transient($slug, $data, $transient_time);
 
9
  }
10
  return $data;
11
  }
@@ -264,10 +276,12 @@ class TimberHelper {
264
 
265
  public static function get_post_by_meta($key, $value) {
266
  global $wpdb;
267
- $query = $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s ORDER BY post_id LIMIT 1", $key, $value);
268
- $result = $wpdb->get_var($query);
269
- if ($result && get_post($result)) {
270
- return $result;
 
 
271
  }
272
  return 0;
273
  }
2
 
3
  class TimberHelper {
4
 
5
+ public static function transient($slug, $callback, $transient_time = 0){
6
+ $disable_transients = false;
7
+ if (defined('WP_DISABLE_TRANSIENTS')){
8
+ $disable_transients = WP_DISABLE_TRANSIENTS;
9
+ }
10
+ if (false === ($data = get_transient($slug)) || $disable_transients){
11
+ $cache_lock_slug = $slug.'_lock';
12
+ if (get_transient($cache_lock_slug)){
13
+ //the server is currently executing the process.
14
+ //We're just gonna dump these users. Sorry!
15
+ return false;
16
+ }
17
+ set_transient($cache_lock_slug, true, $transient_time);
18
  $data = $callback();
19
  set_transient($slug, $data, $transient_time);
20
+ delete_transient($cache_lock_slug);
21
  }
22
  return $data;
23
  }
276
 
277
  public static function get_post_by_meta($key, $value) {
278
  global $wpdb;
279
+ $query = $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s ORDER BY post_id", $key, $value);
280
+ $results = $wpdb->get_col($query);
281
+ foreach($results as $result){
282
+ if ($result && get_post($result)) {
283
+ return $result;
284
+ }
285
  }
286
  return 0;
287
  }
functions/timber-image-helper.php CHANGED
@@ -88,7 +88,7 @@
88
  if (empty($src)){
89
  return '';
90
  }
91
- if (strstr($src, 'http') && !strstr($src, site_url())) {
92
  $src = self::sideload_image($src);
93
  }
94
  $abs = false;
@@ -152,4 +152,4 @@
152
  }
153
 
154
  class WPImageHelper extends TimberImageHelper {
155
- }
88
  if (empty($src)){
89
  return '';
90
  }
91
+ if (strstr($src, 'http') && !strstr($src, home_url())) {
92
  $src = self::sideload_image($src);
93
  }
94
  $abs = false;
152
  }
153
 
154
  class WPImageHelper extends TimberImageHelper {
155
+ }
functions/timber-image.php CHANGED
@@ -5,6 +5,7 @@ class TimberImage extends TimberCore {
5
  var $_can_edit;
6
  var $abs_url;
7
  var $PostClass = 'TimberPost';
 
8
 
9
  public static $representation = 'image';
10
 
@@ -29,7 +30,8 @@ class TimberImage extends TimberCore {
29
  }
30
 
31
  if ($size && is_string($size) && isset($this->sizes[$size])) {
32
- return reset(image_downsize($this->ID, $size));
 
33
  }
34
 
35
  if (!isset($this->file) && isset($this->_wp_attached_file)) {
5
  var $_can_edit;
6
  var $abs_url;
7
  var $PostClass = 'TimberPost';
8
+ var $object_type = 'image';
9
 
10
  public static $representation = 'image';
11
 
30
  }
31
 
32
  if ($size && is_string($size) && isset($this->sizes[$size])) {
33
+ $image = image_downsize($this->ID, $size);
34
+ return reset($image);
35
  }
36
 
37
  if (!isset($this->file) && isset($this->_wp_attached_file)) {
functions/timber-post.php CHANGED
@@ -6,11 +6,13 @@ class TimberPost extends TimberCore {
6
  var $PostClass = 'TimberPost';
7
  var $_can_edit;
8
  var $_get_terms;
 
9
 
10
  var $_custom_imported = false;
11
 
12
  public static $representation = 'post';
13
 
 
14
  /**
15
  * If you send the contructor nothing it will try to figure out the current post id based on being inside The_Loop
16
  * @param mixed $pid
@@ -188,6 +190,7 @@ class TimberPost extends TimberCore {
188
  }
189
 
190
  function get_post_custom($pid) {
 
191
  $customs = get_post_custom($pid);
192
  if (!is_array($customs) || empty($customs)){
193
  return;
@@ -196,7 +199,7 @@ class TimberPost extends TimberCore {
196
  $v = $value[0];
197
  $customs[$key] = maybe_unserialize($v);
198
  }
199
- $customs = apply_filters('post_get_meta', $customs, $pid);
200
  return $customs;
201
  }
202
 
@@ -365,7 +368,9 @@ class TimberPost extends TimberCore {
365
  if (!is_array($terms) && is_object($terms) && get_class($terms) == 'WP_Error'){
366
  //something is very wrong
367
  TimberHelper::error_log('You have an error retrieving terms on a post in timber-post.php:367');
 
368
  TimberHelper::error_log($terms);
 
369
  } else {
370
  foreach ($terms as &$term) {
371
  $term = new $TermClass($term->term_id);
@@ -444,11 +449,11 @@ class TimberPost extends TimberCore {
444
  }
445
 
446
  public function get_field($field_name) {
447
- $value = null;
448
- $value = apply_filters('timber_post_get_meta_field', $value, $this->ID, $field_name);
449
  if ($value === null){
450
- $value = get_post_meta($this->ID, $field, true);
451
  }
 
452
  return $value;
453
  }
454
 
@@ -456,6 +461,10 @@ class TimberPost extends TimberCore {
456
  $this->$field_name = $this->get_field($field_name);
457
  }
458
 
 
 
 
 
459
  //Aliases
460
  public function author() {
461
  return $this->get_author();
@@ -482,13 +491,17 @@ class TimberPost extends TimberCore {
482
  }
483
 
484
  public function display_date(){
485
- return date(get_option('date_format'), strtotime($this->post_date));
486
  }
487
 
488
  public function edit_link(){
489
  return $this->get_edit_url();
490
  }
491
 
 
 
 
 
492
  public function link() {
493
  return $this->get_permalink();
494
  }
6
  var $PostClass = 'TimberPost';
7
  var $_can_edit;
8
  var $_get_terms;
9
+ var $object_type = 'post';
10
 
11
  var $_custom_imported = false;
12
 
13
  public static $representation = 'post';
14
 
15
+
16
  /**
17
  * If you send the contructor nothing it will try to figure out the current post id based on being inside The_Loop
18
  * @param mixed $pid
190
  }
191
 
192
  function get_post_custom($pid) {
193
+ $customs = apply_filters('timber_post_get_meta_pre', array(), $pid, $this);
194
  $customs = get_post_custom($pid);
195
  if (!is_array($customs) || empty($customs)){
196
  return;
199
  $v = $value[0];
200
  $customs[$key] = maybe_unserialize($v);
201
  }
202
+ $customs = apply_filters('timber_post_get_meta', $customs, $pid, $this);
203
  return $customs;
204
  }
205
 
368
  if (!is_array($terms) && is_object($terms) && get_class($terms) == 'WP_Error'){
369
  //something is very wrong
370
  TimberHelper::error_log('You have an error retrieving terms on a post in timber-post.php:367');
371
+ TimberHelper::error_log('tax = '.$tax);
372
  TimberHelper::error_log($terms);
373
+
374
  } else {
375
  foreach ($terms as &$term) {
376
  $term = new $TermClass($term->term_id);
449
  }
450
 
451
  public function get_field($field_name) {
452
+ $value = apply_filters('timber_post_get_meta_field_pre', null, $this->ID, $field_name, $this);
 
453
  if ($value === null){
454
+ $value = get_post_meta($this->ID, $field_name, true);
455
  }
456
+ $value = apply_filters('timber_post_get_meta_field', $value, $this->ID, $field_name, $this);
457
  return $value;
458
  }
459
 
461
  $this->$field_name = $this->get_field($field_name);
462
  }
463
 
464
+ function get_format(){
465
+ return get_post_format($this->ID);
466
+ }
467
+
468
  //Aliases
469
  public function author() {
470
  return $this->get_author();
491
  }
492
 
493
  public function display_date(){
494
+ return date_i18n(get_option('date_format') , strtotime($this->post_date));
495
  }
496
 
497
  public function edit_link(){
498
  return $this->get_edit_url();
499
  }
500
 
501
+ public function format(){
502
+ return $this->get_format();
503
+ }
504
+
505
  public function link() {
506
  return $this->get_permalink();
507
  }
functions/timber-term.php CHANGED
@@ -6,6 +6,7 @@ class TimberTerm extends TimberCore {
6
  var $_children;
7
  var $PostClass = 'TimberPost';
8
  var $TermClass = 'TimberTerm';
 
9
 
10
  public static $representation = 'term';
11
 
@@ -97,7 +98,7 @@ class TimberTerm extends TimberCore {
97
  public function get_meta_field($field_name){
98
  if (!isset($this->$field_name)){
99
  $field = '';
100
- $field = apply_filters('timber_term_get_meta_field', $field, $field_name, $this);
101
  $this->$field_name = $field;
102
  }
103
  return $this->$field_name;
@@ -195,6 +196,10 @@ class TimberTerm extends TimberCore {
195
  return $this->get_posts($numberposts_or_args, $post_type_or_class, $post_class);
196
  }
197
 
 
 
 
 
198
  public function url(){
199
  return $this->get_url();
200
  }
6
  var $_children;
7
  var $PostClass = 'TimberPost';
8
  var $TermClass = 'TimberTerm';
9
+ var $object_type = 'term';
10
 
11
  public static $representation = 'term';
12
 
98
  public function get_meta_field($field_name){
99
  if (!isset($this->$field_name)){
100
  $field = '';
101
+ $field = apply_filters('timber_term_get_meta_field', $field, $this->ID, $field_name, $this);
102
  $this->$field_name = $field;
103
  }
104
  return $this->$field_name;
196
  return $this->get_posts($numberposts_or_args, $post_type_or_class, $post_class);
197
  }
198
 
199
+ public function title(){
200
+ return $this->name;
201
+ }
202
+
203
  public function url(){
204
  return $this->get_url();
205
  }
functions/timber-theme.php CHANGED
@@ -11,6 +11,7 @@
11
  $this->name = $data->get('Name');
12
  $ss = $data->get_stylesheet();
13
  $this->slug = $ss;
 
14
  $this->parent_slug = $data->get('Template');
15
  if ($this->parent_slug && $this->parent_slug != $this->slug){
16
  $this->parent = new TimberTheme($this->parent_slug);
11
  $this->name = $data->get('Name');
12
  $ss = $data->get_stylesheet();
13
  $this->slug = $ss;
14
+ $this->path = '/'.str_replace(ABSPATH, '', get_stylesheet_directory());
15
  $this->parent_slug = $data->get('Template');
16
  if ($this->parent_slug && $this->parent_slug != $this->slug){
17
  $this->parent = new TimberTheme($this->parent_slug);
functions/timber-user.php CHANGED
@@ -3,6 +3,7 @@
3
  class TimberUser extends TimberCore {
4
 
5
  var $_link;
 
6
 
7
  public static $representation = 'user';
8
 
@@ -23,11 +24,11 @@ class TimberUser extends TimberCore {
23
 
24
  function get_meta($field_name){
25
  $value = null;
26
- $value = apply_filters('timber_user_get_meta_field_pre', $value, $this->ID, $field_name);
27
  if ($value === null){
28
- $value = get_post_meta($this->ID, $field, true);
29
  }
30
- $value = apply_filters('timber_user_get_meta_field', $value, $this->ID, $field_name);
31
  return $value;
32
  }
33
 
@@ -61,18 +62,18 @@ class TimberUser extends TimberCore {
61
 
62
  function get_meta_field($field_name){
63
  $value = null;
64
- $value = apply_filters('timber_user_get_meta_field_pre', $value, $field_name, $this->ID);
65
  if ($value === null){
66
- $value = get_post_meta($this->ID, $field, true);
67
  }
68
- $value = apply_filters('timber_user_get_meta_field', $value, $field_name, $this->ID);
69
  return $value;
70
  }
71
 
72
  function get_custom() {
73
  if ($this->ID) {
74
  $um = array();
75
- $um = apply_filters('timber_user_get_meta_pre', $um, $this->ID);
76
  if (empty($um)){
77
  $um = get_user_meta($this->ID);
78
  }
@@ -83,7 +84,7 @@ class TimberUser extends TimberCore {
83
  }
84
  $custom[$key] = maybe_unserialize($value);
85
  }
86
- $custom = apply_filters('timber_user_get_meta', $custom, $this->ID);
87
  return $custom;
88
  }
89
  return null;
3
  class TimberUser extends TimberCore {
4
 
5
  var $_link;
6
+ var $object_type = 'user';
7
 
8
  public static $representation = 'user';
9
 
24
 
25
  function get_meta($field_name){
26
  $value = null;
27
+ $value = apply_filters('timber_user_get_meta_field_pre', $value, $this->ID, $field_name, $this);
28
  if ($value === null){
29
+ $value = get_post_meta($this->ID, $field_name, true);
30
  }
31
+ $value = apply_filters('timber_user_get_meta_field', $value, $this->ID, $field_name, $this);
32
  return $value;
33
  }
34
 
62
 
63
  function get_meta_field($field_name){
64
  $value = null;
65
+ $value = apply_filters('timber_user_get_meta_field_pre', $value, $this->ID, $field_name, $this);
66
  if ($value === null){
67
+ $value = get_user_meta($this->ID, $field_name, true);
68
  }
69
+ $value = apply_filters('timber_user_get_meta_field', $value, $this->ID, $field_name, $this);
70
  return $value;
71
  }
72
 
73
  function get_custom() {
74
  if ($this->ID) {
75
  $um = array();
76
+ $um = apply_filters('timber_user_get_meta_pre', $um, $this->ID, $this);
77
  if (empty($um)){
78
  $um = get_user_meta($this->ID);
79
  }
84
  }
85
  $custom[$key] = maybe_unserialize($value);
86
  }
87
+ $custom = apply_filters('timber_user_get_meta', $custom, $this->ID, $this);
88
  return $custom;
89
  }
90
  return null;
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Contributors: jarednova
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.5
5
- Stable tag: 0.15.3
6
  Tested up to: 3.7.1
7
  PHP version: 5.3.0 or greater
8
  License: GPLv2 or later
@@ -41,8 +41,19 @@ Timber is great for any WordPress developer who cares about writing good, mainta
41
 
42
  == Changelog ==
43
 
 
 
 
 
 
 
 
 
 
 
 
44
  = 0.15.3 =
45
- * Upgreaded to Twig 1.14.2
46
  * Added composer integration
47
  * Bunch of new tests
48
  * Comments now support gravatrs (thanks @asecondwill)
@@ -59,6 +70,8 @@ Timber is great for any WordPress developer who cares about writing good, mainta
59
  * Cacheing!!!
60
  * Cacheing!!
61
  * Cacheing!!!! Timber::render('mytemplate.twig', $data, $expires_time_in_secs);
 
 
62
  * Added post.get_next / post.get_prev for TimberPosts
63
  * Fixed a thing to make get_preview easier when you want to omit the 'Read More' link
64
  * Read the [Full Release Notes](https://github.com/jarednova/timber/releases/tag/0.15.0)
@@ -103,8 +116,8 @@ Timber is great for any WordPress developer who cares about writing good, mainta
103
  * A few fixes that catch issues with absolute vs. relative URLs in resize
104
 
105
  = 0.12.0 =
106
- * Pagination is refactored to be more intuitive, and well, better.
107
- * Resize is also refactored to respect absolute vs. relative URLs
108
  * Got rid of lots of old, bogus code.
109
 
110
  = 0.11.0 =
@@ -148,7 +161,7 @@ Timber is great for any WordPress developer who cares about writing good, mainta
148
  * load_template for routing can now accept a query argument
149
  * load_template will wait to load a template so that 'init' actions can fire.
150
  * way more inline documentation
151
- * print_a now includes the output of (most) methods in addition to properites.
152
  * added lots of aliases so that things like .author will work the same as .get_author
153
 
154
  == Screenshots ==
@@ -188,8 +201,11 @@ At Upstatement we've now used it on more than a dozen client sites. You can chec
188
  = Doesn't this all make WordPress harder since there's more to learn? =
189
  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 JS or they're rotten stupid people," this tool isn't for you.
190
 
 
 
 
191
  = Will you support it? =
192
- As stated above, we're using it in dozens of sites (and dozens more planned). This isn't going anywhere. Twig is the chosen language for other PHP platforms like Symfony, Drupal8 and Craft. WordPress will eventually adopt Twig too.
193
 
194
  = Support? =
195
  Leave a [GitHub issue](https://github.com/jarednova/timber/issues?state=open) and I'll holler back.
2
  Contributors: jarednova
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.5
5
+ Stable tag: 0.15.5
6
  Tested up to: 3.7.1
7
  PHP version: 5.3.0 or greater
8
  License: GPLv2 or later
41
 
42
  == Changelog ==
43
 
44
+ = 0.15.5 =
45
+ * Post formats: {{post.format}} !
46
+
47
+ = 0.15.4 =
48
+ * More improvements to filters to support external integration with Pods and other WP frameworks
49
+ * Fixed bug on date internationalization (thanks @slimndap)
50
+ * Fixed bug on using existing image sizes (thanks @matthewsoares)
51
+ * Fixed bug on homeurl vs siteurl (thanks @ciarand)
52
+ * Added a cache lock to the TimberHelper::transient method
53
+ * Added an in-development version of a TimberArchives object
54
+
55
  = 0.15.3 =
56
+ * Upgrayedd to Twig 1.14.2
57
  * Added composer integration
58
  * Bunch of new tests
59
  * Comments now support gravatrs (thanks @asecondwill)
70
  * Cacheing!!!
71
  * Cacheing!!
72
  * Cacheing!!!! Timber::render('mytemplate.twig', $data, $expires_time_in_secs);
73
+ * Timber::render now automatically echos. Don't want it to? See below...
74
+ * New Timber::compile method which _doesn't_ automatically echo. (Same args as Timber::render)
75
  * Added post.get_next / post.get_prev for TimberPosts
76
  * Fixed a thing to make get_preview easier when you want to omit the 'Read More' link
77
  * Read the [Full Release Notes](https://github.com/jarednova/timber/releases/tag/0.15.0)
116
  * A few fixes that catch issues with absolute vs. relative URLs in resize
117
 
118
  = 0.12.0 =
119
+ * Pagination is re-factored to be more intuitive, and well, better.
120
+ * Resize is also re-factored to respect absolute vs. relative URLs
121
  * Got rid of lots of old, bogus code.
122
 
123
  = 0.11.0 =
161
  * load_template for routing can now accept a query argument
162
  * load_template will wait to load a template so that 'init' actions can fire.
163
  * way more inline documentation
164
+ * print_a now includes the output of (most) methods in addition to properties.
165
  * added lots of aliases so that things like .author will work the same as .get_author
166
 
167
  == Screenshots ==
201
  = Doesn't this all make WordPress harder since there's more to learn? =
202
  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 JS or they're rotten stupid people," this tool isn't for you.
203
 
204
+ = Oh, Timber is simple code so it's for making simple themes =
205
+ Whatever. It simplifies the silly stuff so that you can focus on building more complicated sites and apps. Django simplifies Python, but you can still use the full range of Python's abilities.
206
+
207
  = Will you support it? =
208
+ As stated above, we're using it in dozens of sites (and dozens more planned) -- dozens 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. WordPress will eventually adopt Twig too, I promise you that.
209
 
210
  = Support? =
211
  Leave a [GitHub issue](https://github.com/jarednova/timber/issues?state=open) and I'll holler back.
timber.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Timber
4
  Plugin URI: http://timber.upstatement.com
5
  Description: The WordPress Timber Library allows you to write themes using the power Twig templates
6
  Author: Jared Novack + Upstatement
7
- Version: 0.15.3
8
  Author URI: http://upstatement.com/
9
  */
10
 
@@ -23,8 +23,12 @@ require_once(__DIR__ . '/functions/timber-term.php');
23
  require_once(__DIR__ . '/functions/timber-term-getter.php');
24
  require_once(__DIR__ . '/functions/timber-image.php');
25
  require_once(__DIR__ . '/functions/timber-menu.php');
26
- require_once(__DIR__ . '/functions/timber-theme.php');
 
 
27
  require_once(__DIR__ . '/functions/timber-site.php');
 
 
28
 
29
  require_once(__DIR__ . '/functions/timber-loader.php');
30
  require_once(__DIR__ . '/functions/timber-function-wrapper.php');
@@ -456,8 +460,19 @@ class Timber {
456
  if ($force_header) {
457
  add_filter('status_header', function($status_header, $header, $text, $protocol) use ($force_header) {
458
  $text = get_status_header_desc($force_header);
459
- return "$protocol $force_header $text";
 
460
  }, 10, 4 );
 
 
 
 
 
 
 
 
 
 
461
  }
462
 
463
  if ($query) {
4
  Plugin URI: http://timber.upstatement.com
5
  Description: The WordPress Timber Library allows you to write themes using the power Twig templates
6
  Author: Jared Novack + Upstatement
7
+ Version: 0.15.5
8
  Author URI: http://upstatement.com/
9
  */
10
 
23
  require_once(__DIR__ . '/functions/timber-term-getter.php');
24
  require_once(__DIR__ . '/functions/timber-image.php');
25
  require_once(__DIR__ . '/functions/timber-menu.php');
26
+
27
+ //Other 2nd-class citizens
28
+ require_once(__DIR__ . '/functions/timber-archives.php');
29
  require_once(__DIR__ . '/functions/timber-site.php');
30
+ require_once(__DIR__ . '/functions/timber-theme.php');
31
+
32
 
33
  require_once(__DIR__ . '/functions/timber-loader.php');
34
  require_once(__DIR__ . '/functions/timber-function-wrapper.php');
460
  if ($force_header) {
461
  add_filter('status_header', function($status_header, $header, $text, $protocol) use ($force_header) {
462
  $text = get_status_header_desc($force_header);
463
+ $header_string = "$protocol $force_header $text";
464
+ return $header_string;
465
  }, 10, 4 );
466
+ add_filter('body_class', function($classes) use ($force_header) {
467
+ if (isset($classes) && is_array($classes) && $force_header != 404){
468
+ foreach($classes as &$class){
469
+ if (strstr($class, '404')){
470
+ $class = '';
471
+ }
472
+ }
473
+ }
474
+ return $classes;
475
+ });
476
  }
477
 
478
  if ($query) {