Timber - Version 0.14.1

Version Description

  • Added hooks to play nicely with Timber Debug Bar
  • Fixed-up Timber Term aliases, link, path, etc.
  • Add DB queries now get properly prepared
  • Supports custom author permalinks
  • Simplified TimberPost processing; shaved some processing time off
Download this release

Release Info

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

Code changes from version 0.14.0 to 0.14.1

README.md CHANGED
@@ -32,6 +32,13 @@ Once Timber is installed and activated in your plugin directory, it gives any Wo
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
  #### What does it look like?
36
  Nothing. Timber is meant for you to build a theme on. Like the [Starkers](https://github.com/viewportindustries/starkers) or [Boilerplate theme](https://github.com/zencoder/html5-boilerplate-for-wordpress) it comes style-free, because you're the style expert. Instead, Timber handles the logic you need to make a kick-ass looking site.
37
 
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
+
42
  #### What does it look like?
43
  Nothing. Timber is meant for you to build a theme on. Like the [Starkers](https://github.com/viewportindustries/starkers) or [Boilerplate theme](https://github.com/zencoder/html5-boilerplate-for-wordpress) it comes style-free, because you're the style expert. Instead, Timber handles the logic you need to make a kick-ass looking site.
44
 
admin/sample-php.php DELETED
@@ -1,11 +0,0 @@
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 DELETED
@@ -1,8 +0,0 @@
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>
 
 
 
 
 
 
 
 
admin/timber-admin.php CHANGED
@@ -16,7 +16,7 @@ class TimberAdmin {
16
  }
17
 
18
  function settings_link( $links, $file ) {
19
- if (strstr($file, 'timber')){
20
  return array_merge(
21
  array(
22
  'settings' => '<a href="' . get_bloginfo( 'wpurl' ) . '/wp-admin/themes.php?page=timber-getting-started">Starter Guide</a>'
@@ -45,7 +45,7 @@ class TimberAdmin {
45
  $data['timber_base'] = TIMBER_URL_PATH;
46
  $data['home_file']['path'] = trailingslashit(get_stylesheet_directory()) . $data['home_file']['name'];
47
  $data['home_file']['contents'] = htmlentities(file_get_contents(realpath($data['home_file']['path'])));
48
- $data['home_file']['location'] = str_replace($_SERVER['DOCUMENT_ROOT'], '', trailingslashit(get_stylesheet_directory()));
49
  Timber::render('timber-admin.twig', $data);
50
  }
51
 
16
  }
17
 
18
  function settings_link( $links, $file ) {
19
+ if (strstr($file, 'timber/timber.php')){
20
  return array_merge(
21
  array(
22
  'settings' => '<a href="' . get_bloginfo( 'wpurl' ) . '/wp-admin/themes.php?page=timber-getting-started">Starter Guide</a>'
45
  $data['timber_base'] = TIMBER_URL_PATH;
46
  $data['home_file']['path'] = trailingslashit(get_stylesheet_directory()) . $data['home_file']['name'];
47
  $data['home_file']['contents'] = htmlentities(file_get_contents(realpath($data['home_file']['path'])));
48
+ $data['home_file']['location'] = str_replace(ABSPATH, '', trailingslashit(get_stylesheet_directory()));
49
  Timber::render('timber-admin.twig', $data);
50
  }
51
 
functions/functions-timber-helper.php CHANGED
@@ -3,7 +3,7 @@
3
  class TimberHelper {
4
 
5
  public static function transient($slug, $callback, $transient_time = 1800){
6
- if (false===($data = get_transient($slug))){
7
  $data = $callback();
8
  set_transient($slug, $data, $transient_time);
9
  }
@@ -23,7 +23,7 @@ class TimberHelper {
23
  $time = $time[1] + $time[0];
24
  $finish = $time;
25
  $total_time = round(($finish - $start), 4);
26
- return 'Page generated in '.$total_time.' seconds.';
27
  }
28
 
29
  public static function is_array_assoc($arr) {
@@ -76,14 +76,23 @@ class TimberHelper {
76
  }
77
 
78
  public static function get_full_path($src) {
79
- $root = $_SERVER['DOCUMENT_ROOT'];
80
  $old_root_path = $root . $src;
81
  $old_root_path = str_replace('//', '/', $old_root_path);
82
  return $old_root_path;
83
  }
84
 
 
 
 
 
 
 
 
 
 
85
  public static function get_rel_path($src) {
86
- return str_replace($_SERVER['DOCUMENT_ROOT'], '', $src);
87
  }
88
 
89
  public static function get_letterbox_file_rel($src, $w, $h) {
@@ -97,14 +106,13 @@ class TimberHelper {
97
  }
98
 
99
  public static function get_letterbox_file_path($src, $w, $h) {
100
- $root = $_SERVER['DOCUMENT_ROOT'];
101
  $path_parts = pathinfo($src);
102
  $basename = $path_parts['filename'];
103
  $ext = $path_parts['extension'];
104
  $dir = $path_parts['dirname'];
105
  $newbase = $basename . '-lb-' . $w . 'x' . $h;
106
  $new_path = $dir . '/' . $newbase . '.' . $ext;
107
- $new_root_path = $root . $new_path;
108
  $new_root_path = str_replace('//', '/', $new_root_path);
109
  return $new_root_path;
110
  }
@@ -142,6 +150,9 @@ class TimberHelper {
142
  }
143
 
144
  public static function error_log($arg) {
 
 
 
145
  if (is_object($arg) || is_array($arg)) {
146
  $arg = print_r($arg, true);
147
  }
@@ -256,12 +267,12 @@ class TimberHelper {
256
 
257
  public static function get_posts_by_meta($key, $value) {
258
  global $wpdb;
259
- $query = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '$key' AND meta_value = '$value'";
260
- $results = $wpdb->get_results($query);
261
  $pids = array();
262
  foreach ($results as $result) {
263
- if (get_post($result->post_id)) {
264
- $pids[] = $result->post_id;
265
  }
266
  }
267
  if (count($pids)) {
@@ -272,17 +283,17 @@ class TimberHelper {
272
 
273
  public static function get_post_by_meta($key, $value) {
274
  global $wpdb;
275
- $query = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '$key' AND meta_value = '$value' ORDER BY post_id";
276
- $result = $wpdb->get_row($query);
277
- if ($result && get_post($result->post_id)) {
278
- return $result->post_id;
279
  }
280
  return 0;
281
  }
282
 
283
  public static function get_term_id_by_term_taxonomy_id($ttid){
284
  global $wpdb;
285
- $query = "SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = '$ttid'";
286
  return $wpdb->get_var($query);
287
  }
288
 
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
  }
23
  $time = $time[1] + $time[0];
24
  $finish = $time;
25
  $total_time = round(($finish - $start), 4);
26
+ return $total_time.' seconds.';
27
  }
28
 
29
  public static function is_array_assoc($arr) {
76
  }
77
 
78
  public static function get_full_path($src) {
79
+ $root = ABSPATH;
80
  $old_root_path = $root . $src;
81
  $old_root_path = str_replace('//', '/', $old_root_path);
82
  return $old_root_path;
83
  }
84
 
85
+ public static function get_rel_url($url){
86
+ if (!strstr($url, $_SERVER['HTTP_HOST'])){
87
+ return $url;
88
+ }
89
+ $url = str_replace('http://', '', $url);
90
+ $url = str_replace('https://', '', $url);
91
+ return str_replace($_SERVER['HTTP_HOST'], '', $url);
92
+ }
93
+
94
  public static function get_rel_path($src) {
95
+ return str_replace(ABSPATH, '', $src);
96
  }
97
 
98
  public static function get_letterbox_file_rel($src, $w, $h) {
106
  }
107
 
108
  public static function get_letterbox_file_path($src, $w, $h) {
 
109
  $path_parts = pathinfo($src);
110
  $basename = $path_parts['filename'];
111
  $ext = $path_parts['extension'];
112
  $dir = $path_parts['dirname'];
113
  $newbase = $basename . '-lb-' . $w . 'x' . $h;
114
  $new_path = $dir . '/' . $newbase . '.' . $ext;
115
+ $new_root_path = ABSPATH . $new_path;
116
  $new_root_path = str_replace('//', '/', $new_root_path);
117
  return $new_root_path;
118
  }
150
  }
151
 
152
  public static function error_log($arg) {
153
+ if (!WP_DEBUG){
154
+ return;
155
+ }
156
  if (is_object($arg) || is_array($arg)) {
157
  $arg = print_r($arg, true);
158
  }
267
 
268
  public static function get_posts_by_meta($key, $value) {
269
  global $wpdb;
270
+ $query = $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s", $key, $value);
271
+ $results = $wpdb->col($query);
272
  $pids = array();
273
  foreach ($results as $result) {
274
+ if (get_post($result)) {
275
+ $pids[] = $result;
276
  }
277
  }
278
  if (count($pids)) {
283
 
284
  public static function get_post_by_meta($key, $value) {
285
  global $wpdb;
286
+ $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);
287
+ $result = $wpdb->get_var($query);
288
+ if ($result && get_post($result)) {
289
+ return $result;
290
  }
291
  return 0;
292
  }
293
 
294
  public static function get_term_id_by_term_taxonomy_id($ttid){
295
  global $wpdb;
296
+ $query = $wpdb->prepare("SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %s", $ttid);
297
  return $wpdb->get_var($query);
298
  }
299
 
functions/functions-timber-image-helper.php CHANGED
@@ -121,7 +121,7 @@
121
  }
122
  return $new_path;
123
  } else if (isset($image->error_data['error_loading_image'])) {
124
- error_log('Error loading '.$image->error_data['error_loading_image']);
125
  } else {
126
  TimberHelper::error_log($image);
127
  }
121
  }
122
  return $new_path;
123
  } else if (isset($image->error_data['error_loading_image'])) {
124
+ TimberHelper::error_log('Error loading '.$image->error_data['error_loading_image']);
125
  } else {
126
  TimberHelper::error_log($image);
127
  }
functions/functions-twig.php CHANGED
@@ -69,6 +69,15 @@ class TimberTwig {
69
  }
70
  return new TimberImage($pid);
71
  }));
 
 
 
 
 
 
 
 
 
72
 
73
  /* bloginfo and translate */
74
  $twig->addFunction('bloginfo', new Twig_SimpleFunction('bloginfo', function($show = '', $filter = 'raw'){
@@ -141,7 +150,7 @@ function hexrgb($hexstr) {
141
  function wp_resize_letterbox($src, $w, $h, $color = '#000000') {
142
  //$old_file = TimberHelper::get_full_path($src);
143
  $urlinfo = parse_url($src);
144
- $old_file = $_SERVER['DOCUMENT_ROOT'].$urlinfo['path'];
145
  $new_file = TimberHelper::get_letterbox_file_path($urlinfo['path'], $w, $h);
146
  $new_file_rel = TimberHelper::get_letterbox_file_rel($urlinfo['path'], $w, $h);
147
  $new_file_boxed = str_replace('-lb-', '-lbox-', $new_file);
@@ -192,9 +201,7 @@ function wp_resize_letterbox($src, $w, $h, $color = '#000000') {
192
  imagejpeg($bg, $new_file);
193
  return TimberHelper::get_rel_path($new_file);
194
  } else {
195
- if (WP_DEBUG){
196
- TimberHelper::error_log($image);
197
- }
198
  }
199
  return null;
200
  }
69
  }
70
  return new TimberImage($pid);
71
  }));
72
+ $twig->addFunction(new Twig_SimpleFunction('TimberTerm', function($pid){
73
+ if (is_array($pid)){
74
+ foreach($pid as &$p){
75
+ $p = new TimberTerm($p);
76
+ }
77
+ return $pid;
78
+ }
79
+ return new TimberTerm($pid);
80
+ }));
81
 
82
  /* bloginfo and translate */
83
  $twig->addFunction('bloginfo', new Twig_SimpleFunction('bloginfo', function($show = '', $filter = 'raw'){
150
  function wp_resize_letterbox($src, $w, $h, $color = '#000000') {
151
  //$old_file = TimberHelper::get_full_path($src);
152
  $urlinfo = parse_url($src);
153
+ $old_file = ABSPATH.$urlinfo['path'];
154
  $new_file = TimberHelper::get_letterbox_file_path($urlinfo['path'], $w, $h);
155
  $new_file_rel = TimberHelper::get_letterbox_file_rel($urlinfo['path'], $w, $h);
156
  $new_file_boxed = str_replace('-lb-', '-lbox-', $new_file);
201
  imagejpeg($bg, $new_file);
202
  return TimberHelper::get_rel_path($new_file);
203
  } else {
204
+ TimberHelper::error_log($image);
 
 
205
  }
206
  return null;
207
  }
functions/timber-image.php CHANGED
@@ -87,7 +87,7 @@ class TimberImage extends TimberCore {
87
  $this->$key = $value[0];
88
  }
89
  } else {
90
- error_log('Not able to init in TimberImage with iid=' . $iid);
91
  }
92
  }
93
 
87
  $this->$key = $value[0];
88
  }
89
  } else {
90
+ TimberHelper::error_log('Not able to init in TimberImage with iid=' . $iid);
91
  }
92
  }
93
 
functions/timber-loader.php CHANGED
@@ -10,6 +10,11 @@ class TimberLoader {
10
 
11
  function render($file, $data = null) {
12
  $twig = $this->get_twig();
 
 
 
 
 
13
  return $twig->render($file, $data);
14
  }
15
 
10
 
11
  function render($file, $data = null) {
12
  $twig = $this->get_twig();
13
+ if (strlen($file)){
14
+ $loader = $this->get_loader();
15
+ $result = $loader->getCacheKey($file);
16
+ do_action('timber_loader_render_file', $result);
17
+ }
18
  return $twig->render($file, $data);
19
  }
20
 
functions/timber-menu.php CHANGED
@@ -8,15 +8,14 @@ class TimberMenu extends TimberCore {
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
  }
18
- if (isset($locations[$slug])) {
19
- $menu_id = $locations[$slug];
20
  $menu = wp_get_nav_menu_items($menu_id);
21
  $menu = self::order_children($menu);
22
  $this->items = $menu;
@@ -29,6 +28,40 @@ class TimberMenu extends TimberCore {
29
  return null;
30
  }
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  function find_parent_item_in_menu($menu_items, $parent_id) {
33
  foreach ($menu_items as &$item) {
34
  if ($item->ID == $parent_id) {
@@ -72,10 +105,6 @@ class TimberMenuItem extends TimberCore {
72
  $this->import_classes($data);
73
  }
74
 
75
- function get_link() {
76
- return $this->get_path();
77
- }
78
-
79
  function name() {
80
  return $this->post_title;
81
  }
@@ -84,8 +113,12 @@ class TimberMenuItem extends TimberCore {
84
  return $this->post_name;
85
  }
86
 
 
 
 
 
87
  function get_path() {
88
- return $this->url_to_path($this->url);
89
  }
90
 
91
  function add_child($item) {
@@ -111,6 +144,10 @@ class TimberMenuItem extends TimberCore {
111
  return $this->get_link();
112
  }
113
 
 
 
 
 
114
  function permalink(){
115
  return $this->get_link();
116
  }
8
 
9
  function __construct($slug = 0) {
10
  $locations = get_nav_menu_locations();
11
+ if ($slug != 0 && is_numeric($slug)){
12
+ $menu_id = $slug;
13
+ } else if (count($locations)){
14
+ $menu_id = $this->get_menu_id_from_locations($slug, $locations);
15
+ } else {
16
+ $menu_id = $this->get_menu_id_from_terms($slug);
17
  }
18
+ if ($menu_id){
 
19
  $menu = wp_get_nav_menu_items($menu_id);
20
  $menu = self::order_children($menu);
21
  $this->items = $menu;
28
  return null;
29
  }
30
 
31
+ private function get_menu_id_from_locations($slug, $locations){
32
+ if ($slug === 0){
33
+ $slug = $this->get_menu_id_from_terms($slug);
34
+ }
35
+ if (is_numeric($slug)){
36
+ $slug = array_search($slug, $locations);
37
+ }
38
+ if (isset($locations[$slug])) {
39
+ return $locations[$slug];
40
+ }
41
+ }
42
+
43
+ private function get_menu_id_from_terms($slug = 0){
44
+ if (!is_numeric($slug) && is_string($slug)){
45
+ //we have a string so lets search for that
46
+ $menu_id = get_term_by('slug', $slug, 'nav_menu');
47
+ if ($menu_id){
48
+ return $menu_id;
49
+ }
50
+ $menu_id = get_term_by('name', $slug, 'nav_menu');
51
+ if ($menu_id){
52
+ return $menu_id;
53
+ }
54
+ }
55
+ $menus = get_terms( 'nav_menu', array( 'hide_empty' => true ) );
56
+ if (is_array($menus) && count($menus)){
57
+ if (isset($menus[0]->term_id)){
58
+ return $menus[0]->term_id;
59
+ }
60
+ }
61
+ return 0;
62
+ }
63
+
64
+
65
  function find_parent_item_in_menu($menu_items, $parent_id) {
66
  foreach ($menu_items as &$item) {
67
  if ($item->ID == $parent_id) {
105
  $this->import_classes($data);
106
  }
107
 
 
 
 
 
108
  function name() {
109
  return $this->post_title;
110
  }
113
  return $this->post_name;
114
  }
115
 
116
+ function get_link() {
117
+ return $this->url;
118
+ }
119
+
120
  function get_path() {
121
+ return TimberHelper::get_rel_url($this->url);
122
  }
123
 
124
  function add_child($item) {
144
  return $this->get_link();
145
  }
146
 
147
+ function path(){
148
+ return $this->get_path();
149
+ }
150
+
151
  function permalink(){
152
  return $this->get_link();
153
  }
functions/timber-post.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
-
3
  class TimberPost extends TimberCore {
4
 
5
  var $ImageClass = 'TimberImage';
@@ -7,6 +7,8 @@ class TimberPost extends TimberCore {
7
  var $_can_edit;
8
  var $_get_terms;
9
 
 
 
10
  public static $representation = 'post';
11
 
12
  /**
@@ -29,14 +31,14 @@ class TimberPost extends TimberCore {
29
  $this->ID = $pid;
30
  }
31
  $this->init($pid);
32
- return $this;
33
  }
34
 
35
  function init($pid = false) {
36
  if ($pid === false) {
37
  $pid = get_the_ID();
38
  }
39
- $this->import_info($pid);
 
40
  }
41
 
42
  /**
@@ -81,6 +83,7 @@ class TimberPost extends TimberCore {
81
  return $post;
82
  }
83
  }
 
84
  return $pid;
85
  }
86
 
@@ -114,7 +117,7 @@ class TimberPost extends TimberCore {
114
 
115
  function get_post_id_by_name($post_name) {
116
  global $wpdb;
117
- $query = "SELECT ID FROM $wpdb->posts WHERE post_name = '$post_name'";
118
  $result = $wpdb->get_row($query);
119
  return $result->ID;
120
  }
@@ -174,20 +177,24 @@ class TimberPost extends TimberCore {
174
  * @param integer $pid a post ID number
175
  * @nodoc
176
  */
177
- function import_custom($pid) {
 
 
 
 
 
 
 
 
178
  $customs = get_post_custom($pid);
179
- if (!is_array($customs)){
180
  return;
181
  }
182
  foreach ($customs as $key => $value) {
183
  $v = $value[0];
184
- $this->$key = $v;
185
- if (is_serialized($v)) {
186
- if (gettype(unserialize($v)) == 'array') {
187
- $this->$key = unserialize($v);
188
- }
189
- }
190
  }
 
191
  }
192
 
193
  /**
@@ -220,11 +227,6 @@ class TimberPost extends TimberCore {
220
  return null;
221
  }
222
 
223
- function import_info($pid) {
224
- $post_info = $this->get_info($pid);
225
- $this->import($post_info);
226
- }
227
-
228
  function get_parent() {
229
  if (!$this->post_parent) {
230
  return false;
@@ -245,21 +247,14 @@ class TimberPost extends TimberCore {
245
  }
246
 
247
  function get_info($pid) {
248
- global $wp_rewrite;
249
  $post = $this->prepare_post_info($pid);
250
- if (!isset($post->post_title)) {
251
  return null;
252
  }
253
  $post->slug = $post->post_name;
254
- $post->display_date = date(get_option('date_format'), strtotime($post->post_date));
255
- $this->import_custom($post->ID);
256
  $post->status = $post->post_status;
257
- if (!isset($wp_rewrite)) {
258
- return $post;
259
- } else {
260
- $post->permalink = get_permalink($post->ID);
261
- $post->path = $this->url_to_path($post->permalink);
262
- }
263
  return $post;
264
  }
265
 
@@ -461,10 +456,19 @@ class TimberPost extends TimberCore {
461
  return $this->get_content();
462
  }
463
 
 
 
 
 
464
  function link() {
465
  return $this->get_permalink();
466
  }
467
 
 
 
 
 
 
468
  function permalink() {
469
  return $this->get_permalink();
470
  }
1
  <?php
2
+
3
  class TimberPost extends TimberCore {
4
 
5
  var $ImageClass = 'TimberImage';
7
  var $_can_edit;
8
  var $_get_terms;
9
 
10
+ var $_custom_imported = false;
11
+
12
  public static $representation = 'post';
13
 
14
  /**
31
  $this->ID = $pid;
32
  }
33
  $this->init($pid);
 
34
  }
35
 
36
  function init($pid = false) {
37
  if ($pid === false) {
38
  $pid = get_the_ID();
39
  }
40
+ $post_info = $this->get_info($pid);
41
+ $this->import($post_info);
42
  }
43
 
44
  /**
83
  return $post;
84
  }
85
  }
86
+ //we can skip if already is WP_Post
87
  return $pid;
88
  }
89
 
117
 
118
  function get_post_id_by_name($post_name) {
119
  global $wpdb;
120
+ $query = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name = %s LIMIT 1", $post_name);
121
  $result = $wpdb->get_row($query);
122
  return $result->ID;
123
  }
177
  * @param integer $pid a post ID number
178
  * @nodoc
179
  */
180
+ function import_custom($pid = false){
181
+ if (!$pid){
182
+ $pid = $this->ID;
183
+ }
184
+ $customs = $this->get_post_custom($pid);
185
+ $this->import($customs);
186
+ }
187
+
188
+ function get_post_custom($pid) {
189
  $customs = get_post_custom($pid);
190
+ if (!is_array($customs) || empty($customs)){
191
  return;
192
  }
193
  foreach ($customs as $key => $value) {
194
  $v = $value[0];
195
+ $customs[$key] = maybe_unserialize($v);
 
 
 
 
 
196
  }
197
+ return $customs;
198
  }
199
 
200
  /**
227
  return null;
228
  }
229
 
 
 
 
 
 
230
  function get_parent() {
231
  if (!$this->post_parent) {
232
  return false;
247
  }
248
 
249
  function get_info($pid) {
 
250
  $post = $this->prepare_post_info($pid);
251
+ if (!isset($post->post_status)) {
252
  return null;
253
  }
254
  $post->slug = $post->post_name;
 
 
255
  $post->status = $post->post_status;
256
+ $customs = $this->get_post_custom($post->ID);
257
+ $post = (object) array_merge((array) $post, (array) $customs);
 
 
 
 
258
  return $post;
259
  }
260
 
456
  return $this->get_content();
457
  }
458
 
459
+ function display_date(){
460
+ return date(get_option('date_format'), strtotime($this->post_date));
461
+ }
462
+
463
  function link() {
464
  return $this->get_permalink();
465
  }
466
 
467
+ function path(){
468
+ $path = TimberHelper::get_rel_url($this->get_permalink());
469
+ return TimberHelper::preslashit($path);
470
+ }
471
+
472
  function permalink() {
473
  return $this->get_permalink();
474
  }
functions/timber-term.php CHANGED
@@ -34,7 +34,7 @@ class TimberTerm extends TimberCore {
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
  //TimberHelper::error_log(debug_backtrace());
39
  }
40
  if (function_exists('get_fields')) {
@@ -63,7 +63,7 @@ class TimberTerm extends TimberCore {
63
  }
64
  $tid = self::get_tid($tid);
65
  global $wpdb;
66
- $query = "SELECT * FROM $wpdb->term_taxonomy WHERE term_id = '$tid'";
67
  $tax = $wpdb->get_row($query);
68
  if (isset($tax) && isset($tax->taxonomy)) {
69
  if ($tax->taxonomy) {
@@ -83,9 +83,9 @@ class TimberTerm extends TimberCore {
83
  $tid = $tid->term_id;
84
  }
85
  if (is_numeric($tid)) {
86
- $query = "SELECT * FROM $wpdb->terms WHERE term_id = '$tid'";
87
  } else {
88
- $query = "SELECT * FROM $wpdb->terms WHERE slug = '$tid'";
89
  }
90
 
91
  $result = $wpdb->get_row($query);
@@ -97,19 +97,16 @@ class TimberTerm extends TimberCore {
97
  }
98
 
99
  function get_path() {
100
- return get_term_link($this);
 
101
  }
102
 
103
  function get_link() {
104
- return $this->get_path();
105
  }
106
 
107
  function get_url() {
108
- $base = $this->taxonomy;
109
- if ($base == 'post_tag') {
110
- $base = 'tag';
111
- }
112
- return $base . '/' . $this->slug;
113
  }
114
 
115
  function get_posts($numberposts = 10, $post_type = 'any', $PostClass = '') {
@@ -131,12 +128,18 @@ class TimberTerm extends TimberCore {
131
  /* Alias
132
  ====================== */
133
 
 
 
 
 
 
 
 
 
134
  public function url(){
135
  return $this->get_url();
136
  }
137
 
138
- public function link(){
139
- return $this->get_link();
140
- }
141
 
142
  }
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
  //TimberHelper::error_log(debug_backtrace());
39
  }
40
  if (function_exists('get_fields')) {
63
  }
64
  $tid = self::get_tid($tid);
65
  global $wpdb;
66
+ $query = $wpdb->prepare("SELECT * FROM $wpdb->term_taxonomy WHERE term_id = %d LIMIT 1", $tid);
67
  $tax = $wpdb->get_row($query);
68
  if (isset($tax) && isset($tax->taxonomy)) {
69
  if ($tax->taxonomy) {
83
  $tid = $tid->term_id;
84
  }
85
  if (is_numeric($tid)) {
86
+ $query = $wpdb->prepare("SELECT * FROM $wpdb->terms WHERE term_id = %d", $tid);
87
  } else {
88
+ $query = $wpdb->prepare("SELECT * FROM $wpdb->terms WHERE slug = %s", $tid);
89
  }
90
 
91
  $result = $wpdb->get_row($query);
97
  }
98
 
99
  function get_path() {
100
+ $link = $this->get_link();
101
+ return TimberHelper::get_rel_url($link);
102
  }
103
 
104
  function get_link() {
105
+ return get_term_link($this);
106
  }
107
 
108
  function get_url() {
109
+ return $this->get_link();
 
 
 
 
110
  }
111
 
112
  function get_posts($numberposts = 10, $post_type = 'any', $PostClass = '') {
128
  /* Alias
129
  ====================== */
130
 
131
+ public function link(){
132
+ return $this->get_link();
133
+ }
134
+
135
+ public function path(){
136
+ return $this->get_path();
137
+ }
138
+
139
  public function url(){
140
  return $this->get_url();
141
  }
142
 
143
+
 
 
144
 
145
  }
functions/timber-theme.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class TimberTheme extends TimberCore {
4
+
5
+ function __construct($slug = null){
6
+ $this->init($slug);
7
+ }
8
+
9
+ function init($slug = null){
10
+ $data = wp_get_theme($slug);
11
+ $this->name = $data->get('Name');
12
+ $ss = get_stylesheet_directory();
13
+ $ss = explode('/', $ss);
14
+ $this->slug = array_pop($ss);
15
+ $this->parent_slug = $data->get('Template');
16
+ if ($this->parent_slug != $this->slug){
17
+ //$this->parent = new TimberTheme($this->parent_slug);
18
+ }
19
+ //$this->import($data);
20
+ //$this->slug =
21
+ }
22
+
23
+ }
functions/timber-user.php CHANGED
@@ -8,20 +8,18 @@ class TimberUser extends TimberCore {
8
 
9
  public function get_link() {
10
  $p = TimberHelper::get_path_base();
11
- return $p . 'author/' . $this->slug();
 
12
  }
13
 
14
  function init($uid = false) {
15
  if (!$uid) {
16
  $uid = get_current_user_id();
17
  }
18
- if (function_exists('get_userdata')) {
19
- $data = get_userdata($uid);
20
- if (is_object($data) && isset($data)) {
21
- $this->import($data->data);
22
- }
23
  }
24
-
25
  $this->ID = $uid;
26
  $this->import_custom();
27
  }
8
 
9
  public function get_link() {
10
  $p = TimberHelper::get_path_base();
11
+ global $wp_rewrite;
12
+ return $p . trailingslashit($wp_rewrite->author_base) . $this->slug();
13
  }
14
 
15
  function init($uid = false) {
16
  if (!$uid) {
17
  $uid = get_current_user_id();
18
  }
19
+ $data = get_userdata($uid);
20
+ if (is_object($data) && isset($data)) {
21
+ $this->import($data->data);
 
 
22
  }
 
23
  $this->ID = $uid;
24
  $this->import_custom();
25
  }
readme.txt CHANGED
@@ -2,8 +2,9 @@
2
  Contributors: jarednova
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.5
5
- Stable tag: 0.13.5
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,6 +38,13 @@ Timber is great for any WordPress developer who cares about writing good, mainta
37
 
38
  == Changelog ==
39
 
 
 
 
 
 
 
 
40
  = 0.14.0 =
41
  * More flexiblity for custom routes (thanks @mgmartel)
42
  * Added filters for core objects (TimberPost and TimberTerm). This greatly helps when you need to have retrived custom fields or repeaters interprted as posts or terms
2
  Contributors: jarednova
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.5
5
+ Stable tag: 0.14.1
6
  Tested up to: 3.6.1
7
+ PHP version: 5.3.0 or greater
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
38
 
39
  == Changelog ==
40
 
41
+ = 0.14.1 =
42
+ * Added hooks to play nicely with Timber Debug Bar
43
+ * Fixed-up Timber Term aliases, link, path, etc.
44
+ * Add DB queries now get properly prepared
45
+ * Supports custom author permalinks
46
+ * Simplified TimberPost processing; shaved some processing time off
47
+
48
  = 0.14.0 =
49
  * More flexiblity for custom routes (thanks @mgmartel)
50
  * Added filters for core objects (TimberPost and TimberTerm). This greatly helps when you need to have retrived custom fields or repeaters interprted as posts or terms
timber-starter-theme/functions.php CHANGED
@@ -10,10 +10,10 @@
10
  add_action('wp_enqueue_scripts', 'load_scripts');
11
 
12
  define('THEME_URL', get_template_directory_uri());
13
-
14
  function add_to_context($data){
15
  /* this is where you can add your own data to Timber's context object */
16
- $data['foo'] = 'bar';
 
17
  return $data;
18
  }
19
 
10
  add_action('wp_enqueue_scripts', 'load_scripts');
11
 
12
  define('THEME_URL', get_template_directory_uri());
 
13
  function add_to_context($data){
14
  /* this is where you can add your own data to Timber's context object */
15
+ $data['qux'] = 'I am a value set in your functions.php file';
16
+ $data['menu'] = new TimberMenu();
17
  return $data;
18
  }
19
 
timber-starter-theme/index.php CHANGED
@@ -14,13 +14,10 @@
14
  */
15
 
16
  if (!class_exists('Timber')){
17
- echo 'Timber not activated';
18
  }
19
-
20
  $data = Timber::get_context();
21
- $data['menu'] = new TimberMenu();
22
- $posts = Timber::get_posts('TimberPost');
23
- $data['posts'] = $posts;
24
  $data['foo'] = 'bar';
25
  $templates = array('index.twig');
26
  if (is_home()){
14
  */
15
 
16
  if (!class_exists('Timber')){
17
+ echo 'Timber not activated. Make sure you activate the plugin in <a href="/wp-admin/plugins.php#timber">/wp-admin/plugins.php</a>';
18
  }
 
19
  $data = Timber::get_context();
20
+ $data['posts'] = Timber::get_posts();
 
 
21
  $data['foo'] = 'bar';
22
  $templates = array('index.twig');
23
  if (is_home()){
timber-starter-theme/views/base.twig CHANGED
@@ -8,11 +8,16 @@
8
  <div class="wrapper">
9
 
10
  <h1 class="hdr-logo" role="banner">
11
- <a class="ink-logo-text" href="/" title="Timber" rel="home">Timber</a>
12
  </h1>
13
-
14
- <nav id="access" class="ink-navigation" role="navigation">
15
- {{wp_nav_menu}}
 
 
 
 
 
16
  </nav><!-- #access -->
17
 
18
  </div>
8
  <div class="wrapper">
9
 
10
  <h1 class="hdr-logo" role="banner">
11
+ <a class="hdr-logo-link" href="/" title="Timber" rel="home">{{bloginfo('name')}}</a>
12
  </h1>
13
+ <nav id="access" class="main-navigation" role="navigation">
14
+ <ul>
15
+ {% for item in menu.items %}
16
+ <li id="menu-item-{{item.ID}}" class="menu-item menu-item-type-{{item.type}} menu-item-object-{{item.object}} menu-item-{{item.ID}}">
17
+ <a href="{{item.link}}">{{item.title}}</a>
18
+ </li>
19
+ {% endfor %}
20
+ </ul>
21
  </nav><!-- #access -->
22
 
23
  </div>
timber-starter-theme/views/index.twig CHANGED
@@ -2,6 +2,7 @@
2
 
3
  {% block content %}
4
  <h2>{{foo}}</h2>
 
5
  {% for post in posts %}
6
  {% include ['tease-'~post.post_type~'.twig', 'tease.twig'] %}
7
  {% endfor %}
2
 
3
  {% block content %}
4
  <h2>{{foo}}</h2>
5
+ <p>{{qux}}</p>
6
  {% for post in posts %}
7
  {% include ['tease-'~post.post_type~'.twig', 'tease.twig'] %}
8
  {% endfor %}
timber.php CHANGED
@@ -1,10 +1,11 @@
1
  <?php
2
  /*
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.14.0
7
- Author URI: http://timber.upstatement.com/
8
  */
9
 
10
  global $wp_version;
@@ -22,13 +23,13 @@ require_once(__DIR__ . '/functions/timber-term.php');
22
  require_once(__DIR__ . '/functions/timber-term-getter.php');
23
  require_once(__DIR__ . '/functions/timber-image.php');
24
  require_once(__DIR__ . '/functions/timber-menu.php');
 
25
 
26
  require_once(__DIR__ . '/functions/timber-loader.php');
27
  require_once(__DIR__ . '/functions/timber-function-wrapper.php');
28
 
29
  require_once(__DIR__ . '/admin/timber-admin.php');
30
 
31
-
32
  /** Usage:
33
  *
34
  * $posts = Timber::get_posts();
@@ -48,13 +49,14 @@ class Timber {
48
  public static $locations;
49
  public static $dirname = 'views';
50
  public static $cache = false;
 
51
 
52
  protected $router;
53
 
54
  public function __construct(){
55
  $this->test_compatibility();
56
  $this->init_constants();
57
- add_action('init', array(&$this, 'init_routes'));
58
  }
59
 
60
  protected function test_compatibility(){
@@ -67,7 +69,7 @@ class Timber {
67
  }
68
 
69
  protected function init_constants() {
70
- $timber_loc = str_replace(realpath($_SERVER['DOCUMENT_ROOT']), '', realpath(__DIR__));
71
  $plugin_url_path = str_replace($_SERVER['HTTP_HOST'], '', plugins_url());
72
  $plugin_url_path = str_replace('https://', '', $plugin_url_path);
73
  $plugin_url_path = str_replace('http://', '', $plugin_url_path);
@@ -122,7 +124,7 @@ class Timber {
122
  //return self::get_posts_from_wp_query(array(), $PostClass);
123
  return null;
124
  } else {
125
- error_log('I have failed you! in timber.php::94');
126
  TimberHelper::error_log($query);
127
  }
128
  return $query;
@@ -161,18 +163,18 @@ class Timber {
161
 
162
  public static function get_posts_from_slug($slug, $PostClass) {
163
  global $wpdb;
164
- $query = "SELECT ID FROM $wpdb->posts WHERE post_name = '$slug'";
165
  if (strstr($slug, '#')) {
166
  //we have a post_type directive here
167
  $q = explode('#', $slug);
168
  $q = array_filter($q);
169
  $q = array_values($q);
170
  if (count($q) == 1){
171
- $query = "SELECT ID FROM $wpdb->posts WHERE post_name = '$q[0]'";
172
  } else if (count($q) == 2){
173
- $query = "SELECT ID FROM $wpdb->posts WHERE post_name = '$q[1]' AND post_type = '$q[0]'";
174
  } else {
175
- error_log('something we dont understand about '.$slug);
176
  }
177
  }
178
  $results = $wpdb->get_col($query);
@@ -180,6 +182,7 @@ class Timber {
180
  }
181
 
182
  public static function get_posts_from_wp_query($query = array(), $PostClass = 'TimberPost') {
 
183
  $results = get_posts($query);
184
  return self::handle_post_results($results, $PostClass);
185
  }
@@ -193,6 +196,7 @@ class Timber {
193
  }
194
 
195
  public static function handle_post_results($results, $PostClass = 'TimberPost') {
 
196
  $posts = array();
197
  foreach ($results as $rid) {
198
  $PostClassUse = $PostClass;
@@ -203,14 +207,14 @@ class Timber {
203
  $PostClassUse = $PostClass[$post_type];
204
  } else {
205
  if (is_array($PostClass)) {
206
- error_log($post_type.' of '.$rid.' not found in ' . print_r($PostClass, true));
207
  } else {
208
- error_log($post_type.' not found in '.$PostClass);
209
  }
210
  }
211
  }
212
  $post = new $PostClassUse($rid);
213
- if (isset($post->post_title)) {
214
  $posts[] = $post;
215
  }
216
  }
@@ -288,7 +292,7 @@ class Timber {
288
  if (function_exists('wp_nav_menu')) {
289
  $data['wp_nav_menu'] = wp_nav_menu(array('container_class' => 'menu-header', 'echo' => false, 'menu_class' => 'nav-menu'));
290
  }
291
- $data['theme_dir'] = str_replace($_SERVER['DOCUMENT_ROOT'], '', get_stylesheet_directory());
292
  $data['language_attributes'] = TimberHelper::function_wrapper('language_attributes');
293
  $data['stylesheet_uri'] = get_stylesheet_uri();
294
  $data['template_uri'] = get_template_directory_uri();
@@ -302,6 +306,8 @@ class Timber {
302
  $file = $loader->choose_template($filenames);
303
  $output = '';
304
  if (strlen($file)) {
 
 
305
  $output = $loader->render($file, $data);
306
  }
307
  if ($echo) {
@@ -338,7 +344,7 @@ class Timber {
338
  }
339
  }
340
  if (!$found) {
341
- error_log('error loading your sidebar, check to make sure the file exists');
342
  }
343
  $ret = ob_get_contents();
344
  ob_end_clean();
@@ -379,6 +385,14 @@ class Timber {
379
  $timber->router->map($route, $callback);
380
  }
381
 
 
 
 
 
 
 
 
 
382
 
383
  public static function load_template($template, $query = false, $force_header = 0) {
384
  $template = locate_template($template);
@@ -454,7 +468,7 @@ class Timber {
454
 
455
  public static function get_calling_script_path($offset = 0) {
456
  $dir = self::get_calling_script_dir($offset);
457
- return str_replace($_SERVER['DOCUMENT_ROOT'], '', realpath($dir));
458
  }
459
 
460
  public static function get_calling_script_dir($offset = 0) {
1
  <?php
2
  /*
3
  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.14.1
8
+ Author URI: http://upstatement.com/
9
  */
10
 
11
  global $wp_version;
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
 
28
  require_once(__DIR__ . '/functions/timber-loader.php');
29
  require_once(__DIR__ . '/functions/timber-function-wrapper.php');
30
 
31
  require_once(__DIR__ . '/admin/timber-admin.php');
32
 
 
33
  /** Usage:
34
  *
35
  * $posts = Timber::get_posts();
49
  public static $locations;
50
  public static $dirname = 'views';
51
  public static $cache = false;
52
+ public static $auto_meta = true;
53
 
54
  protected $router;
55
 
56
  public function __construct(){
57
  $this->test_compatibility();
58
  $this->init_constants();
59
+ add_action('init', array($this, 'init_routes'));
60
  }
61
 
62
  protected function test_compatibility(){
69
  }
70
 
71
  protected function init_constants() {
72
+ $timber_loc = str_replace(realpath(ABSPATH), '', realpath(__DIR__));
73
  $plugin_url_path = str_replace($_SERVER['HTTP_HOST'], '', plugins_url());
74
  $plugin_url_path = str_replace('https://', '', $plugin_url_path);
75
  $plugin_url_path = str_replace('http://', '', $plugin_url_path);
124
  //return self::get_posts_from_wp_query(array(), $PostClass);
125
  return null;
126
  } else {
127
+ TimberHelper::error_log('I have failed you! in timber.php::94');
128
  TimberHelper::error_log($query);
129
  }
130
  return $query;
163
 
164
  public static function get_posts_from_slug($slug, $PostClass) {
165
  global $wpdb;
166
+ $query = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name = %s", $slug);
167
  if (strstr($slug, '#')) {
168
  //we have a post_type directive here
169
  $q = explode('#', $slug);
170
  $q = array_filter($q);
171
  $q = array_values($q);
172
  if (count($q) == 1){
173
+ $query = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name = %s", $q[0]);
174
  } else if (count($q) == 2){
175
+ $query = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name = %s AND post_type = %s LIMIT 1", $q[1], $q[0]);
176
  } else {
177
+ TimberHelper::error_log('something we dont understand about '.$slug);
178
  }
179
  }
180
  $results = $wpdb->get_col($query);
182
  }
183
 
184
  public static function get_posts_from_wp_query($query = array(), $PostClass = 'TimberPost') {
185
+ $start = TimberHelper::start_timer();
186
  $results = get_posts($query);
187
  return self::handle_post_results($results, $PostClass);
188
  }
196
  }
197
 
198
  public static function handle_post_results($results, $PostClass = 'TimberPost') {
199
+ $start = TimberHelper::start_timer();
200
  $posts = array();
201
  foreach ($results as $rid) {
202
  $PostClassUse = $PostClass;
207
  $PostClassUse = $PostClass[$post_type];
208
  } else {
209
  if (is_array($PostClass)) {
210
+ TimberHelper::error_log($post_type.' of '.$rid.' not found in ' . print_r($PostClass, true));
211
  } else {
212
+ TimberHelper::error_log($post_type.' not found in '.$PostClass);
213
  }
214
  }
215
  }
216
  $post = new $PostClassUse($rid);
217
+ if (isset($post->ID)) {
218
  $posts[] = $post;
219
  }
220
  }
292
  if (function_exists('wp_nav_menu')) {
293
  $data['wp_nav_menu'] = wp_nav_menu(array('container_class' => 'menu-header', 'echo' => false, 'menu_class' => 'nav-menu'));
294
  }
295
+ $data['theme_dir'] = str_replace(ABSPATH, '', get_stylesheet_directory());
296
  $data['language_attributes'] = TimberHelper::function_wrapper('language_attributes');
297
  $data['stylesheet_uri'] = get_stylesheet_uri();
298
  $data['template_uri'] = get_template_directory_uri();
306
  $file = $loader->choose_template($filenames);
307
  $output = '';
308
  if (strlen($file)) {
309
+ $file = apply_filters('timber_render_file', $file);
310
+ $data = apply_filters('timber_render_data', $data);
311
  $output = $loader->render($file, $data);
312
  }
313
  if ($echo) {
344
  }
345
  }
346
  if (!$found) {
347
+ TimberHelper::error_log('error loading your sidebar, check to make sure the file exists');
348
  }
349
  $ret = ob_get_contents();
350
  ob_end_clean();
385
  $timber->router->map($route, $callback);
386
  }
387
 
388
+ public static function cancel_query(){
389
+ add_action('posts_request', function(){
390
+ if (is_main_query()){
391
+ wp_reset_query();
392
+ }
393
+ });
394
+ }
395
+
396
 
397
  public static function load_template($template, $query = false, $force_header = 0) {
398
  $template = locate_template($template);
468
 
469
  public static function get_calling_script_path($offset = 0) {
470
  $dir = self::get_calling_script_dir($offset);
471
+ return str_replace(ABSPATH, '', realpath($dir));
472
  }
473
 
474
  public static function get_calling_script_dir($offset = 0) {