Timber - Version 0.13.0

Version Description

  • TimberMenuItems now get the WP classes you've come to know and love (.current-menu-item, etc.)
  • More test coverage for images
  • Resizing external images converts the URL into a md5 hash
  • Removed a dangerous backtrace that could overload errorlog
  • Some object caching on TimberPost->get_terms to improve performance
Download this release

Release Info

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

Code changes from version 0.12.2 to 0.13.0

admin/sample-php.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <article class="tease-post tz-post-m feed-mod" id="tz-<?php echo get_the_ID(); ?>">
2
+ <h2 class="tz-post-head"><a href="<?php echo get_permalink(); ?>"><?php the_title(); ?></a></h2>
3
+ <?php
4
+ if (get_post_thumbnail_id(get_the_ID())) {
5
+ $src = wp_get_attachment_image_src(get_post_thumbnail_id(get_the_ID()));
6
+ } else {
7
+ $src = '/wp-content/mytheme/default-missing-image.jpg';
8
+ }
9
+ ?>
10
+ <a href="<?php echo get_permalink(); ?>"><img src="<?php echo $src; ?>" /></a>
11
+ </article>
admin/sample-twig.twig ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <article class="tease-post tz-post-m feed-mod" id="tz-{{post.ID}}">
2
+ <h2 class="tz-post-head">
3
+ <a href="{{post.link}}">{{post.title|default('Post tease here and here')}}</a>
4
+ </h2>
5
+ <a href="{{post.link}}">
6
+ <img src="{{post.thumbnail.src|default('/wp-content/mytheme/default-missing-image.jpg')|resize(275, 180)}}" />
7
+ </a>
8
+ </article>
functions/functions-twig.php CHANGED
@@ -106,15 +106,16 @@ function hexrgb($hexstr) {
106
  }
107
 
108
  function wp_resize_letterbox($src, $w, $h, $color = '#000000') {
109
- $old_file = WPHelper::get_full_path($src);
110
- $new_file = WPHelper::get_letterbox_file_path($src, $w, $h);
111
- $new_file_rel = WPHelper::get_letterbox_file_rel($src, $w, $h);
 
 
112
  $new_file_boxed = str_replace('-lb-', '-lbox-', $new_file);
113
  if (file_exists($new_file_boxed)) {
114
  $new_file_rel = str_replace('-lb-', '-lbox-', $new_file_rel);
115
  return $new_file_rel;
116
  }
117
-
118
  $bg = imagecreatetruecolor($w, $h);
119
  $c = hexrgb($color);
120
 
@@ -157,6 +158,10 @@ function wp_resize_letterbox($src, $w, $h, $color = '#000000') {
157
  $new_file = str_replace('-lb-', '-lbox-', $new_file);
158
  imagejpeg($bg, $new_file);
159
  return WPHelper::get_rel_path($new_file);
 
 
 
 
160
  }
161
  return null;
162
  }
106
  }
107
 
108
  function wp_resize_letterbox($src, $w, $h, $color = '#000000') {
109
+ //$old_file = WPHelper::get_full_path($src);
110
+ $urlinfo = parse_url($src);
111
+ $old_file = $_SERVER['DOCUMENT_ROOT'].$urlinfo['path'];
112
+ $new_file = WPHelper::get_letterbox_file_path($urlinfo['path'], $w, $h);
113
+ $new_file_rel = WPHelper::get_letterbox_file_rel($urlinfo['path'], $w, $h);
114
  $new_file_boxed = str_replace('-lb-', '-lbox-', $new_file);
115
  if (file_exists($new_file_boxed)) {
116
  $new_file_rel = str_replace('-lb-', '-lbox-', $new_file_rel);
117
  return $new_file_rel;
118
  }
 
119
  $bg = imagecreatetruecolor($w, $h);
120
  $c = hexrgb($color);
121
 
158
  $new_file = str_replace('-lb-', '-lbox-', $new_file);
159
  imagejpeg($bg, $new_file);
160
  return WPHelper::get_rel_path($new_file);
161
+ } else {
162
+ if (WP_DEBUG){
163
+ WPHelper::error_log($image);
164
+ }
165
  }
166
  return null;
167
  }
functions/functions-wp-helper.php CHANGED
@@ -2,6 +2,14 @@
2
 
3
  class WPHelper {
4
 
 
 
 
 
 
 
 
 
5
  public static function is_array_assoc($arr) {
6
  if (!is_array($arr)) {
7
  return false;
2
 
3
  class WPHelper {
4
 
5
+ public static function init_transient($slug, $callback, $transient_time = 1800){
6
+ if (false===($data = get_transient($slug))){
7
+ $data = $callback();
8
+ set_transient($slug, $data, $transient_time);
9
+ }
10
+ return $data;
11
+ }
12
+
13
  public static function is_array_assoc($arr) {
14
  if (!is_array($arr)) {
15
  return false;
functions/functions-wp-image-helper.php CHANGED
@@ -10,8 +10,8 @@
10
  function img_to_jpg($src, $bghex = '#FFFFFF'){
11
  $src = str_replace(site_url(), '', $src);
12
  $output = str_replace('.png', '.jpg', $src);
13
- $input_file = $_SERVER['DOCUMENT_ROOT'] . $src;
14
- $output_file = $_SERVER['DOCUMENT_ROOT'] . $output;
15
  if (file_exists($output_file)) {
16
  return $output;
17
  }
@@ -33,7 +33,7 @@
33
  $filename = $file;
34
  $file = parse_url($file);
35
  $path_parts = pathinfo($file['path']);
36
- $basename = base64_encode($filename);
37
  $ext = $path_parts['extension'];
38
  return $dir . '/' . $basename. '.' . $ext;
39
  }
@@ -41,20 +41,18 @@
41
  public static function sideload_image($file) {
42
  $loc = self::get_sideloaded_file_loc($file);
43
  if (file_exists($loc)){
44
- error_log('already exists');
45
- return str_replace($_SERVER['DOCUMENT_ROOT'], '', $loc);
46
  }
47
- error_log('make a new one');
48
- require_once($_SERVER['DOCUMENT_ROOT'] . '/wp-admin/includes/file.php');
49
- require_once($_SERVER['DOCUMENT_ROOT'] . '/wp-admin/includes/media.php');
50
  // Download file to temp location
 
 
 
51
  $tmp = download_url($file);
52
  preg_match('/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches);
53
  $file_array['name'] = basename($matches[0]);
54
  $file_array['tmp_name'] = $tmp;
55
  // If error storing temporarily, unlink
56
  if (is_wp_error($tmp)) {
57
- error_log('theres an error');
58
  @unlink($file_array['tmp_name']);
59
  $file_array['tmp_name'] = '';
60
  }
@@ -80,14 +78,16 @@
80
  $newbase = $basename . '-r-' . $w . 'x' . $h;
81
  $new_path = $dir . '/' . $newbase . '.' . $ext;
82
  $new_path = str_replace(site_url(), '', $new_path);
83
- $new_root_path = $_SERVER['DOCUMENT_ROOT'] . $new_path;
84
- $old_root_path = $_SERVER['DOCUMENT_ROOT'] . str_replace(site_url(), '', $src);
85
-
86
  $old_root_path = str_replace('//', '/', $old_root_path);
87
  $new_root_path = str_replace('//', '/', $new_root_path);
88
  if (file_exists($new_root_path)) {
 
89
  if ($abs){
90
  return untrailingslashit(site_url()).$new_path;
 
 
91
  }
92
  return $new_path;
93
  }
@@ -118,6 +118,8 @@
118
  return untrailingslashit(site_url()).$new_path;
119
  }
120
  return $new_path;
 
 
121
  }
122
  return $src;
123
  }
10
  function img_to_jpg($src, $bghex = '#FFFFFF'){
11
  $src = str_replace(site_url(), '', $src);
12
  $output = str_replace('.png', '.jpg', $src);
13
+ $input_file = ABSPATH . $src;
14
+ $output_file = ABSPATH . $output;
15
  if (file_exists($output_file)) {
16
  return $output;
17
  }
33
  $filename = $file;
34
  $file = parse_url($file);
35
  $path_parts = pathinfo($file['path']);
36
+ $basename = md5($filename);
37
  $ext = $path_parts['extension'];
38
  return $dir . '/' . $basename. '.' . $ext;
39
  }
41
  public static function sideload_image($file) {
42
  $loc = self::get_sideloaded_file_loc($file);
43
  if (file_exists($loc)){
44
+ return str_replace(ABSPATH, '', $loc);
 
45
  }
 
 
 
46
  // Download file to temp location
47
+ if (!function_exists('download_url')){
48
+ require_once(ABSPATH.'/wp-admin/includes/file.php');
49
+ }
50
  $tmp = download_url($file);
51
  preg_match('/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches);
52
  $file_array['name'] = basename($matches[0]);
53
  $file_array['tmp_name'] = $tmp;
54
  // If error storing temporarily, unlink
55
  if (is_wp_error($tmp)) {
 
56
  @unlink($file_array['tmp_name']);
57
  $file_array['tmp_name'] = '';
58
  }
78
  $newbase = $basename . '-r-' . $w . 'x' . $h;
79
  $new_path = $dir . '/' . $newbase . '.' . $ext;
80
  $new_path = str_replace(site_url(), '', $new_path);
81
+ $new_root_path = ABSPATH . $new_path;
82
+ $old_root_path = ABSPATH . str_replace(site_url(), '', $src);
 
83
  $old_root_path = str_replace('//', '/', $old_root_path);
84
  $new_root_path = str_replace('//', '/', $new_root_path);
85
  if (file_exists($new_root_path)) {
86
+ error_log('return '.$new_path);
87
  if ($abs){
88
  return untrailingslashit(site_url()).$new_path;
89
+ } else {
90
+ return WPHelper::preslashit($new_path);
91
  }
92
  return $new_path;
93
  }
118
  return untrailingslashit(site_url()).$new_path;
119
  }
120
  return $new_path;
121
+ } else {
122
+ error_log('there was an error');
123
  }
124
  return $src;
125
  }
functions/timber-loader.php CHANGED
@@ -119,6 +119,9 @@ class TimberLoader {
119
 
120
  $loader = $this->get_loader();
121
  $params = array('debug' => WP_DEBUG, 'autoescape' => false);
 
 
 
122
  if (Timber::$cache) {
123
  $params['cache'] = TIMBER_LOC . '/twig-cache';
124
  }
119
 
120
  $loader = $this->get_loader();
121
  $params = array('debug' => WP_DEBUG, 'autoescape' => false);
122
+ if (isset(Timber::$autoescape)){
123
+ $params['autoescape'] = Timber::$autoescape;
124
+ }
125
  if (Timber::$cache) {
126
  $params['cache'] = TIMBER_LOC . '/twig-cache';
127
  }
functions/timber-menu.php CHANGED
@@ -6,8 +6,12 @@ class TimberMenu extends TimberCore {
6
  var $name = null;
7
  var $ID = null;
8
 
9
- function __construct($slug) {
10
  $locations = get_nav_menu_locations();
 
 
 
 
11
  if (is_numeric($slug)){
12
  $slug = array_search($slug, $locations);
13
  }
@@ -21,7 +25,6 @@ class TimberMenu extends TimberCore {
21
  $this->ID = $this->term_id;
22
  } else {
23
  WPHelper::error_log("Sorry, the menu you were looking for wasn't found ('".$slug."'). Here's what Timber did find:");
24
- WPHelper::error_log($locations);
25
  }
26
  return null;
27
  }
@@ -38,6 +41,7 @@ class TimberMenu extends TimberCore {
38
  function order_children($items) {
39
  $index = array();
40
  $menu = array();
 
41
  foreach($items as $item) {
42
  $index[$item->ID] = new TimberMenuItem($item);
43
  }
@@ -65,6 +69,7 @@ class TimberMenuItem extends TimberCore {
65
 
66
  function __construct($data) {
67
  $this->import($data);
 
68
  }
69
 
70
  function get_link() {
@@ -90,6 +95,10 @@ class TimberMenuItem extends TimberCore {
90
  $this->children[] = $item;
91
  }
92
 
 
 
 
 
93
  function get_children() {
94
  if (isset($this->children)) {
95
  return $this->children;
6
  var $name = null;
7
  var $ID = null;
8
 
9
+ function __construct($slug = 0) {
10
  $locations = get_nav_menu_locations();
11
+ if ($slug === 0){
12
+ reset($locations);
13
+ $slug = key($locations);
14
+ }
15
  if (is_numeric($slug)){
16
  $slug = array_search($slug, $locations);
17
  }
25
  $this->ID = $this->term_id;
26
  } else {
27
  WPHelper::error_log("Sorry, the menu you were looking for wasn't found ('".$slug."'). Here's what Timber did find:");
 
28
  }
29
  return null;
30
  }
41
  function order_children($items) {
42
  $index = array();
43
  $menu = array();
44
+ _wp_menu_item_classes_by_context($items);
45
  foreach($items as $item) {
46
  $index[$item->ID] = new TimberMenuItem($item);
47
  }
69
 
70
  function __construct($data) {
71
  $this->import($data);
72
+ $this->import_classes($data);
73
  }
74
 
75
  function get_link() {
95
  $this->children[] = $item;
96
  }
97
 
98
+ function import_classes($data){
99
+ $this->class = trim(implode(' ', $data->classes));
100
+ }
101
+
102
  function get_children() {
103
  if (isset($this->children)) {
104
  return $this->children;
functions/timber-post.php CHANGED
@@ -5,6 +5,7 @@ class TimberPost extends TimberCore {
5
  var $ImageClass = 'TimberImage';
6
  var $PostClass = 'TimberPost';
7
  var $_can_edit;
 
8
 
9
  public static $representation = 'post';
10
 
@@ -152,7 +153,18 @@ class TimberPost extends TimberCore {
152
  if ($last != '.' && $trimmed) {
153
  $text .= ' &hellip; ';
154
  }
 
 
 
 
 
 
 
 
155
  $text .= ' <a href="' . $this->get_permalink() . '" class="read-more">' . $readmore . '</a>';
 
 
 
156
  }
157
  return $text;
158
  }
@@ -191,7 +203,11 @@ class TimberPost extends TimberCore {
191
  }
192
 
193
  function get_permalink() {
194
- return get_permalink($this->ID);
 
 
 
 
195
  }
196
 
197
  function get_link() {
@@ -310,8 +326,15 @@ class TimberPost extends TimberCore {
310
  */
311
 
312
  function get_terms($tax = '', $merge = true, $TermClass = 'TimberTerm') {
 
 
 
 
 
313
  if (!strlen($tax) || $tax == 'all' || $tax == 'any') {
314
  $taxs = get_object_taxonomies($this->post_type);
 
 
315
  } else {
316
  $taxs = array($tax);
317
  }
@@ -326,12 +349,16 @@ class TimberPost extends TimberCore {
326
  foreach ($terms as &$term) {
327
  $term = new $TermClass($term->term_id);
328
  }
329
- if ($merge) {
330
  $ret = array_merge($ret, $terms);
331
  } else if (count($terms)) {
332
  $ret[$tax] = $terms;
333
  }
334
  }
 
 
 
 
335
  return $ret;
336
  }
337
 
5
  var $ImageClass = 'TimberImage';
6
  var $PostClass = 'TimberPost';
7
  var $_can_edit;
8
+ var $_get_terms;
9
 
10
  public static $representation = 'post';
11
 
153
  if ($last != '.' && $trimmed) {
154
  $text .= ' &hellip; ';
155
  }
156
+ if (!$strip){
157
+ $last_p_tag = strrpos($text, '</p>');
158
+ $text = substr($text, 0, $last_p_tag);
159
+ if ($last != '.' && $trimmed) {
160
+ $text .= ' &hellip; ';
161
+ }
162
+ }
163
+
164
  $text .= ' <a href="' . $this->get_permalink() . '" class="read-more">' . $readmore . '</a>';
165
+ if (!$strip){
166
+ $text .= '</p>';
167
+ }
168
  }
169
  return $text;
170
  }
203
  }
204
 
205
  function get_permalink() {
206
+ if (isset($this->permalink)){
207
+ return $this->permalink;
208
+ }
209
+ $this->permalink = get_permalink($this->ID);
210
+ return $this->permalink;
211
  }
212
 
213
  function get_link() {
326
  */
327
 
328
  function get_terms($tax = '', $merge = true, $TermClass = 'TimberTerm') {
329
+ if (is_string($tax)){
330
+ if (isset($this->_get_terms) && isset($this->_get_terms[$tax])){
331
+ return $this->_get_terms[$tax];
332
+ }
333
+ }
334
  if (!strlen($tax) || $tax == 'all' || $tax == 'any') {
335
  $taxs = get_object_taxonomies($this->post_type);
336
+ } else if (is_array($tax)) {
337
+ $taxs = $tax;
338
  } else {
339
  $taxs = array($tax);
340
  }
349
  foreach ($terms as &$term) {
350
  $term = new $TermClass($term->term_id);
351
  }
352
+ if ($merge && is_array($terms)) {
353
  $ret = array_merge($ret, $terms);
354
  } else if (count($terms)) {
355
  $ret[$tax] = $terms;
356
  }
357
  }
358
+ if (!isset($this->_get_terms)){
359
+ $this->_get_terms = array();
360
+ }
361
+ $this->_get_terms[$tax] = $ret;
362
  return $ret;
363
  }
364
 
functions/timber-term.php CHANGED
@@ -33,9 +33,9 @@ class TimberTerm extends TimberCore {
33
  $term->ID = $term->id;
34
  } else if (isset($term->term_id)) {
35
  $term->ID = $term->term_id;
36
- } else {
37
- //echo 'bad call';
38
- WPHelper::error_log(debug_backtrace());
39
  }
40
  if (function_exists('get_fields')) {
41
  //lets get whatever we can from advanced custom fields;
33
  $term->ID = $term->id;
34
  } else if (isset($term->term_id)) {
35
  $term->ID = $term->term_id;
36
+ } else if (is_string($tid)) {
37
+ echo 'bad call using '.$tid;
38
+ //WPHelper::error_log(debug_backtrace());
39
  }
40
  if (function_exists('get_fields')) {
41
  //lets get whatever we can from advanced custom fields;
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: jarednova
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.5
5
- Stable tag: 0.12.2
6
- Tested up to: 3.6
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -37,6 +37,13 @@ Timber is great for any WordPress developer who cares about writing good, mainta
37
 
38
  == Changelog ==
39
 
 
 
 
 
 
 
 
40
  = 0.12.2 =
41
  * TimberMenus now contain metadata 'bout the menu (thanks @bryanaka)
42
  * Fixed issue with Windows servers (thanks @kzykhys)
@@ -96,6 +103,9 @@ Timber is great for any WordPress developer who cares about writing good, mainta
96
  * print_a now includes the output of (most) methods in addition to properites.
97
  * added lots of aliases so that things like .author will work the same as .get_author
98
 
 
 
 
99
 
100
  == Installation ==
101
 
2
  Contributors: jarednova
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.5
5
+ Stable tag: 0.13.0
6
+ Tested up to: 3.6.1
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
37
 
38
  == Changelog ==
39
 
40
+ = 0.13.0 =
41
+ * TimberMenuItems now get the WP classes you've come to know and love (.current-menu-item, etc.)
42
+ * More test coverage for images
43
+ * Resizing external images converts the URL into a md5 hash
44
+ * Removed a dangerous backtrace that could overload errorlog
45
+ * Some object caching on TimberPost->get_terms to improve performance
46
+
47
  = 0.12.2 =
48
  * TimberMenus now contain metadata 'bout the menu (thanks @bryanaka)
49
  * Fixed issue with Windows servers (thanks @kzykhys)
103
  * print_a now includes the output of (most) methods in addition to properites.
104
  * added lots of aliases so that things like .author will work the same as .get_author
105
 
106
+ == Screenshots ==
107
+ <img src="/assets/sample-twig.png" />
108
+ Here's what writ
109
 
110
  == Installation ==
111
 
timber.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Timber
4
  Description: The WordPress Timber Library allows you to write themes using the power Twig templates
5
  Author: Jared Novack + Upstatement
6
- Version: 0.12.2
7
  Author URI: http://timber.upstatement.com/
8
  */
9
 
@@ -195,9 +195,9 @@ class Timber {
195
  $PostClassUse = $PostClass[$post_type];
196
  } else {
197
  if (is_array($PostClass)) {
198
- error_log($post_type . ' not found in ' . print_r($PostClass, true));
199
  } else {
200
- error_log($post_type . ' not found in ' . $PostClass);
201
  }
202
  }
203
  }
3
  Plugin Name: Timber
4
  Description: The WordPress Timber Library allows you to write themes using the power Twig templates
5
  Author: Jared Novack + Upstatement
6
+ Version: 0.13.0
7
  Author URI: http://timber.upstatement.com/
8
  */
9
 
195
  $PostClassUse = $PostClass[$post_type];
196
  } else {
197
  if (is_array($PostClass)) {
198
+ error_log($post_type.' of '.$rid.' not found in ' . print_r($PostClass, true));
199
  } else {
200
+ error_log($post_type.' not found in '.$PostClass);
201
  }
202
  }
203
  }