Version Description
- Dates now use date_i18n filter (thanks @jamesagreenleaf)
- The twig |date filter now defaults to your WP Admin settings (thanks @jamesagreenleaf)
- You can send Timber::$dirname an array to specify multiple locations of twig files within a theme
- Load views from anywhere on the server (thanks @th3fallen)
- Load twig files from anywhere on the server using an absolute path
- Use another version of Twig if you have it loaded (thanks @ButlerPCnet)
- more tests!
Download this release
Release Info
Developer | jarednova |
Plugin | Timber |
Version | 0.18.1 |
Comparing to | |
See all releases |
Code changes from version 0.18.0 to 0.18.1
- README.md +5 -7
- functions/functions-twig.php +20 -3
- functions/integrations/wpcli-timber.php +55 -13
- functions/timber-helper.php +3 -1
- functions/timber-image-helper.php +129 -42
- functions/timber-image.php +2 -1
- functions/timber-loader.php +37 -14
- functions/timber-post.php +15 -5
- functions/timber-site.php +2 -1
- functions/timber-url-helper.php +8 -0
- readme.txt +10 -1
- timber-starter-theme/single.php +7 -1
- timber-starter-theme/views/base.twig +14 -10
- timber-starter-theme/views/single-password.twig +8 -0
- timber-starter-theme/views/single.twig +2 -2
- timber.php +49 -25
README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<div style="text-align:center">
|
2 |
-
<a href="http://jarednova.github.com/timber"><img src="http://i.imgur.com/
|
3 |
<div>
|
4 |
By Jared Novack (<a href="http://twitter.com/jarednova">@JaredNova</a>) and <a href="http://upstatement.com">Upstatement</a> (<a href="http://twitter.com/upstatement">@Upstatement</a>)</div>
|
5 |
</div>
|
@@ -17,7 +17,7 @@ This is what Timber's `.twig` files look like:
|
|
17 |
{% extends "base.twig" %}
|
18 |
{% block content %}
|
19 |
<h1 class="big-title">{{foo}}</h1>
|
20 |
-
<h2>{{post.title}}</h2>
|
21 |
<img src="{{post.thumbnail.src}}" />
|
22 |
<div class="body">
|
23 |
{{post.content}}
|
@@ -49,16 +49,14 @@ Timber is a tool for developers who want to translate their HTML into high-quali
|
|
49 |
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.
|
50 |
|
51 |
#### Who is it good for?
|
52 |
-
Timber is great for any WordPress developer who cares about writing good, maintainable code. It helps teams of designers and developers working together. At [Upstatement](http://upstatement.com) we made Timber because not everyone knows the ins-and-outs of the_loop(),
|
53 |
|
54 |
#### Related Projects
|
55 |
* [**Timber Debug Bar**](https://github.com/upstatement/debug-bar-timber) Adds a debug bar panel that will show you want template is in-use and the data sent to your twig file.
|
|
|
56 |
* [**Twig**](https://github.com/fabpot/Twig) The template language used by Timber.
|
57 |
|
58 |
#### Should I use it?
|
59 |
-
|
60 |
-
|
61 |
-
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/jarednova/timber/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
|
62 |
-
|
63 |
|
64 |
|
1 |
<div style="text-align:center">
|
2 |
+
<a href="http://jarednova.github.com/timber"><img src="http://i.imgur.com/oM1AHrz.jpg" style="display:block; margin:auto; width:100%; max-width:100%"/></a>
|
3 |
<div>
|
4 |
By Jared Novack (<a href="http://twitter.com/jarednova">@JaredNova</a>) and <a href="http://upstatement.com">Upstatement</a> (<a href="http://twitter.com/upstatement">@Upstatement</a>)</div>
|
5 |
</div>
|
17 |
{% extends "base.twig" %}
|
18 |
{% block content %}
|
19 |
<h1 class="big-title">{{foo}}</h1>
|
20 |
+
<h2 class="post-title">{{post.title}}</h2>
|
21 |
<img src="{{post.thumbnail.src}}" />
|
22 |
<div class="body">
|
23 |
{{post.content}}
|
49 |
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.
|
50 |
|
51 |
#### Who is it good for?
|
52 |
+
Timber is great for any WordPress developer who cares about writing good, maintainable code. It helps teams of designers and developers working together. At [Upstatement](http://upstatement.com) we made Timber because while our entire team needs to participate in building WordPress sites, not everyone knows the ins-and-outs of the_loop(), codex and PHP (nor should they). With Timber your best WordPress dev can focus on building the .php files with requests from WordPress and pass the data into .twig files. Once there, designers can easily mark-up data and build out a site's look-and-feel.
|
53 |
|
54 |
#### Related Projects
|
55 |
* [**Timber Debug Bar**](https://github.com/upstatement/debug-bar-timber) Adds a debug bar panel that will show you want template is in-use and the data sent to your twig file.
|
56 |
+
* [**TimberPhoton**](https://github.com/slimndap/TimberPhoton) Plug-in to use JetPack's free Photon image maninpulation and CDN with Timber.
|
57 |
* [**Twig**](https://github.com/fabpot/Twig) The template language used by Timber.
|
58 |
|
59 |
#### Should I use it?
|
60 |
+
It's GPL-licensed, so please use in personal or commercial work. Just don't re-sell it. While Timber is still in development, it's also in-use on [hundreds of sites](http://jarednova.github.io/timber/#showcase). While much has been stabalized since the first major push back in June 2013, you should expect some breaking changes as development progresses towards a version 1.0.
|
|
|
|
|
|
|
61 |
|
62 |
|
functions/functions-twig.php
CHANGED
@@ -41,15 +41,20 @@ class TimberTwig {
|
|
41 |
$twig->addFilter('relative', new Twig_Filter_Function(function($link){
|
42 |
return TimberURLHelper::get_rel_url($link, true);
|
43 |
}));
|
|
|
44 |
|
45 |
$twig->addFilter('truncate', new Twig_Filter_Function(function($text, $len){
|
46 |
return TimberHelper::trim_words($text, $len);
|
47 |
}));
|
48 |
|
49 |
/* actions and filters */
|
50 |
-
$twig->addFunction(new Twig_SimpleFunction('action', function(){
|
51 |
-
|
52 |
-
|
|
|
|
|
|
|
|
|
53 |
$twig->addFilter( new Twig_SimpleFilter('apply_filters', function(){
|
54 |
$args = func_get_args();
|
55 |
$tag = current(array_splice($args, 1, 1));
|
@@ -231,6 +236,18 @@ function twig_body_class($body_classes) {
|
|
231 |
return $return;
|
232 |
}
|
233 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
234 |
/**
|
235 |
* @param string $string
|
236 |
* @param array $data
|
41 |
$twig->addFilter('relative', new Twig_Filter_Function(function($link){
|
42 |
return TimberURLHelper::get_rel_url($link, true);
|
43 |
}));
|
44 |
+
$twig->addFilter('date', new Twig_Filter_Function('twig_intl_date'));
|
45 |
|
46 |
$twig->addFilter('truncate', new Twig_Filter_Function(function($text, $len){
|
47 |
return TimberHelper::trim_words($text, $len);
|
48 |
}));
|
49 |
|
50 |
/* actions and filters */
|
51 |
+
$twig->addFunction( new Twig_SimpleFunction('action', function($context){
|
52 |
+
$args = func_get_args();
|
53 |
+
array_shift($args);
|
54 |
+
$args[] = $context;
|
55 |
+
call_user_func_array('do_action', $args);
|
56 |
+
}, array('needs_context' => true)));
|
57 |
+
|
58 |
$twig->addFilter( new Twig_SimpleFilter('apply_filters', function(){
|
59 |
$args = func_get_args();
|
60 |
$tag = current(array_splice($args, 1, 1));
|
236 |
return $return;
|
237 |
}
|
238 |
|
239 |
+
/**
|
240 |
+
* @param string $date
|
241 |
+
* @param string $format (optional)
|
242 |
+
* @return string
|
243 |
+
*/
|
244 |
+
function twig_intl_date($date, $format = null) {
|
245 |
+
if ($format === null) {
|
246 |
+
$format = get_option('date_format');
|
247 |
+
}
|
248 |
+
return date_i18n($format, strtotime($date));
|
249 |
+
}
|
250 |
+
|
251 |
/**
|
252 |
* @param string $string
|
253 |
* @param array $data
|
functions/integrations/wpcli-timber.php
CHANGED
@@ -3,32 +3,74 @@
|
|
3 |
class Timber_Command extends WP_CLI_Command{
|
4 |
|
5 |
/**
|
6 |
-
* Clears Twig's Cache
|
7 |
*
|
8 |
* ## EXAMPLES
|
9 |
*
|
10 |
-
* wp clear_cache
|
11 |
*
|
12 |
-
* @synopsis <nothing>
|
13 |
*/
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
20 |
}
|
21 |
}
|
22 |
|
23 |
/**
|
|
|
|
|
24 |
* ## EXAMPLES
|
25 |
-
*
|
|
|
|
|
26 |
*/
|
27 |
|
28 |
-
function
|
29 |
-
WP_CLI::success('
|
30 |
}
|
31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
}
|
33 |
|
34 |
-
WP_CLI::add_command( 'timber', 'Timber_Command' );
|
3 |
class Timber_Command extends WP_CLI_Command{
|
4 |
|
5 |
/**
|
6 |
+
* Clears Timber and Twig's Cache
|
7 |
*
|
8 |
* ## EXAMPLES
|
9 |
*
|
10 |
+
* wp timber clear_cache
|
11 |
*
|
|
|
12 |
*/
|
13 |
+
|
14 |
+
function clear_cache($mode = 'all'){
|
15 |
+
WP_CLI::line('#mode = '.print_r($mode, true));
|
16 |
+
if ($mode == 'all'){
|
17 |
+
self::clear_cache_twig();
|
18 |
+
self::clear_cache_timber();
|
19 |
+
}
|
20 |
+
if ($mode == 'twig'){
|
21 |
+
}
|
22 |
+
if ($mode == 'timber'){
|
23 |
+
|
24 |
}
|
25 |
}
|
26 |
|
27 |
/**
|
28 |
+
* Clears Timber's Cache
|
29 |
+
*
|
30 |
* ## EXAMPLES
|
31 |
+
*
|
32 |
+
* wp timber clear_cache_timber
|
33 |
+
*
|
34 |
*/
|
35 |
|
36 |
+
function clear_cache_timber(){
|
37 |
+
WP_CLI::success('Cleared contents of Timbers Cache');
|
38 |
}
|
39 |
|
40 |
+
/**
|
41 |
+
* Clears Twig's Cache
|
42 |
+
*
|
43 |
+
* ## EXAMPLES
|
44 |
+
*
|
45 |
+
* wp timber clear_cache_twig
|
46 |
+
*
|
47 |
+
*/
|
48 |
+
|
49 |
+
function clear_cache_twig(){
|
50 |
+
$loader = new TimberLoader();
|
51 |
+
$twig = $loader->get_twig();
|
52 |
+
$twig->clearCacheFiles();
|
53 |
+
self::rrmdir($twig->getCache());
|
54 |
+
WP_CLI::success('Cleared contents of '.$twig->getCache());
|
55 |
+
}
|
56 |
+
|
57 |
+
private function rrmdir($dir) {
|
58 |
+
if (is_dir($dir)) {
|
59 |
+
$objects = scandir($dir);
|
60 |
+
foreach ($objects as $object) {
|
61 |
+
if ($object != "." && $object != "..") {
|
62 |
+
if (filetype($dir."/".$object) == "dir"){
|
63 |
+
self::rrmdir($dir."/".$object);
|
64 |
+
rmdir($dir."/".$object);
|
65 |
+
} else {
|
66 |
+
unlink($dir."/".$object);
|
67 |
+
}
|
68 |
+
}
|
69 |
+
}
|
70 |
+
reset($objects);
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
}
|
75 |
|
76 |
+
WP_CLI::add_command( 'timber', 'Timber_Command' );
|
functions/timber-helper.php
CHANGED
@@ -460,6 +460,7 @@ class TimberHelper {
|
|
460 |
$link = add_query_arg( $add_args, $link );
|
461 |
}
|
462 |
$link .= $add_fragment;
|
|
|
463 |
$page_links[] = array('class' => 'prev page-numbers', 'link' => esc_url( apply_filters( 'paginate_links', $link )), 'title' => $prev_text);
|
464 |
}
|
465 |
for ( $n = 1; $n <= $total; $n++ ) {
|
@@ -475,6 +476,7 @@ class TimberHelper {
|
|
475 |
if ( $add_args ) {
|
476 |
$link = rtrim(add_query_arg( $add_args, $link ), '/');
|
477 |
}
|
|
|
478 |
$page_links[] = array('class' => 'page-number page-numbers', 'link' => esc_url( apply_filters( 'paginate_links', $link ) ), 'title' => $n_display, 'current' => $current == $n);
|
479 |
$dots = true;
|
480 |
} elseif ( $dots && !$show_all ) {
|
@@ -489,7 +491,7 @@ class TimberHelper {
|
|
489 |
if ( $add_args ) {
|
490 |
$link = add_query_arg( $add_args, $link );
|
491 |
}
|
492 |
-
$link = trailingslashit($link).$add_fragment;
|
493 |
$page_links[] = array('class' => 'next page-numbers', 'link' => esc_url( apply_filters( 'paginate_links', $link ) ), 'title' => $next_text);
|
494 |
}
|
495 |
return $page_links;
|
460 |
$link = add_query_arg( $add_args, $link );
|
461 |
}
|
462 |
$link .= $add_fragment;
|
463 |
+
$link = untrailingslashit($link);
|
464 |
$page_links[] = array('class' => 'prev page-numbers', 'link' => esc_url( apply_filters( 'paginate_links', $link )), 'title' => $prev_text);
|
465 |
}
|
466 |
for ( $n = 1; $n <= $total; $n++ ) {
|
476 |
if ( $add_args ) {
|
477 |
$link = rtrim(add_query_arg( $add_args, $link ), '/');
|
478 |
}
|
479 |
+
$link = untrailingslashit($link);
|
480 |
$page_links[] = array('class' => 'page-number page-numbers', 'link' => esc_url( apply_filters( 'paginate_links', $link ) ), 'title' => $n_display, 'current' => $current == $n);
|
481 |
$dots = true;
|
482 |
} elseif ( $dots && !$show_all ) {
|
491 |
if ( $add_args ) {
|
492 |
$link = add_query_arg( $add_args, $link );
|
493 |
}
|
494 |
+
$link = untrailingslashit(trailingslashit($link).$add_fragment);
|
495 |
$page_links[] = array('class' => 'next page-numbers', 'link' => esc_url( apply_filters( 'paginate_links', $link ) ), 'title' => $next_text);
|
496 |
}
|
497 |
return $page_links;
|
functions/timber-image-helper.php
CHANGED
@@ -2,6 +2,17 @@
|
|
2 |
|
3 |
class TimberImageHelper {
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
/**
|
6 |
* @param string $hexstr
|
7 |
* @return array
|
@@ -17,6 +28,50 @@
|
|
17 |
return array("red" => 0xFF & ($int >> 0x10), "green" => 0xFF & ($int >> 0x8), "blue" => 0xFF & $int);
|
18 |
}
|
19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
/**
|
21 |
* @param string $src
|
22 |
* @param int $w
|
@@ -32,6 +87,7 @@
|
|
32 |
$color = str_replace('#', '', $color);
|
33 |
$newbase = $basename . '-lbox-' . $w . 'x' . $h . '-' . $color;
|
34 |
$new_path = $dir . '/' . $newbase . '.' . $ext;
|
|
|
35 |
return $new_path;
|
36 |
}
|
37 |
|
@@ -43,18 +99,44 @@
|
|
43 |
* @return string
|
44 |
*/
|
45 |
public static function get_letterbox_file_path($src, $w, $h, $color) {
|
46 |
-
$
|
47 |
-
$basename = $path_parts['filename'];
|
48 |
-
$ext = $path_parts['extension'];
|
49 |
-
$dir = $path_parts['dirname'];
|
50 |
-
$color = str_replace('#', '', $color);
|
51 |
-
$newbase = $basename . '-lbox-' . $w . 'x' . $h . '-' . $color;
|
52 |
-
$new_path = $dir . '/' . $newbase . '.' . $ext;
|
53 |
$new_root_path = ABSPATH . $new_path;
|
54 |
$new_root_path = str_replace('//', '/', $new_root_path);
|
55 |
return $new_root_path;
|
56 |
}
|
57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
/**
|
59 |
* @param int $iid
|
60 |
* @return string
|
@@ -74,24 +156,31 @@
|
|
74 |
* @return mixed|null|string
|
75 |
*/
|
76 |
public static function letterbox($src, $w, $h, $color = '#000000', $force = false) {
|
77 |
-
$
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
|
|
82 |
}
|
83 |
-
$
|
84 |
-
$
|
|
|
|
|
|
|
85 |
$urlinfo = parse_url($src);
|
86 |
-
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
89 |
}
|
90 |
$bg = imagecreatetruecolor($w, $h);
|
91 |
$c = self::hexrgb($color);
|
92 |
$white = imagecolorallocate($bg, $c['red'], $c['green'], $c['blue']);
|
93 |
imagefill($bg, 0, 0, $white);
|
94 |
-
$image = wp_get_image_editor($
|
95 |
if (!is_wp_error($image)) {
|
96 |
$current_size = $image->get_size();
|
97 |
$ow = $current_size['width'];
|
@@ -114,18 +203,18 @@
|
|
114 |
$owt = $w;
|
115 |
$image->crop(0, 0, $ow, $oh, $owt, $oht);
|
116 |
}
|
117 |
-
$image->save($
|
118 |
$func = 'imagecreatefromjpeg';
|
119 |
-
$ext = pathinfo($
|
120 |
if ($ext == 'gif') {
|
121 |
$func = 'imagecreatefromgif';
|
122 |
} else if ($ext == 'png') {
|
123 |
$func = 'imagecreatefrompng';
|
124 |
}
|
125 |
-
$image = $func($
|
126 |
imagecopy($bg, $image, $x, $y, 0, 0, $owt, $oht);
|
127 |
-
imagejpeg($bg, $
|
128 |
-
return TimberURLHelper::get_rel_path($
|
129 |
} else {
|
130 |
TimberHelper::error_log($image);
|
131 |
}
|
@@ -138,7 +227,7 @@
|
|
138 |
* @return string
|
139 |
*/
|
140 |
public static function img_to_jpg($src, $bghex = '#FFFFFF'){
|
141 |
-
$src = str_replace(
|
142 |
$output = str_replace('.png', '.jpg', $src);
|
143 |
$input_file = ABSPATH . $src;
|
144 |
$output_file = ABSPATH . $output;
|
@@ -215,7 +304,7 @@
|
|
215 |
if (empty($src)){
|
216 |
return '';
|
217 |
}
|
218 |
-
if (strstr($src, 'http') && !strstr($src,
|
219 |
$src = self::sideload_image($src);
|
220 |
}
|
221 |
$abs = false;
|
@@ -228,31 +317,29 @@
|
|
228 |
$crop = $allowed_crop_positions[ 0 ];
|
229 |
}
|
230 |
//oh good, it's a relative image in the uploads folder!
|
231 |
-
$
|
232 |
-
$
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
$
|
239 |
-
$
|
240 |
-
$old_root_path = str_replace('//', '/', $old_root_path);
|
241 |
-
$new_root_path = str_replace('//', '/', $new_root_path);
|
242 |
if ( file_exists($new_root_path) ) {
|
243 |
if ( $force_resize ) {
|
244 |
// Force resize - warning: will regenerate the image on every pageload, use for testing purposes only!
|
245 |
unlink( $new_root_path );
|
246 |
} else {
|
247 |
if ($abs){
|
248 |
-
return untrailingslashit(
|
249 |
} else {
|
250 |
-
|
|
|
251 |
}
|
252 |
return $new_path;
|
253 |
}
|
254 |
}
|
255 |
-
|
256 |
$image = wp_get_image_editor($old_root_path);
|
257 |
|
258 |
if (!is_wp_error($image)) {
|
@@ -285,8 +372,6 @@
|
|
285 |
$src_x = round( ( $src_w - $src_wt ) / 2 );
|
286 |
$src_y = round( ( $src_h - $src_ht ) / 2 );
|
287 |
} else if ($crop == 'top') {
|
288 |
-
|
289 |
-
error_log('found it on top');
|
290 |
$src_y = 0;
|
291 |
} else if ($crop == 'bottom') {
|
292 |
$src_y = $src_h - $src_ht;
|
@@ -311,7 +396,7 @@
|
|
311 |
error_log(print_r($result, true));
|
312 |
}
|
313 |
if ($abs){
|
314 |
-
return untrailingslashit(
|
315 |
}
|
316 |
return $new_path;
|
317 |
} else if (isset($image->error_data['error_loading_image'])) {
|
@@ -322,3 +407,5 @@
|
|
322 |
return $src;
|
323 |
}
|
324 |
}
|
|
|
|
2 |
|
3 |
class TimberImageHelper {
|
4 |
|
5 |
+
public static function add_actions(){
|
6 |
+
add_action('delete_post', function($post_id){
|
7 |
+
$post = get_post($post_id);
|
8 |
+
$image_types = array('image/jpeg', 'image/png', 'image/gif', 'image/jpg');
|
9 |
+
if ($post->post_type == 'attachment' && in_array($post->post_mime_type, $image_types)){
|
10 |
+
self::delete_resized_files_from_url($post->guid);
|
11 |
+
self::delete_letterboxed_files_from_url($post->guid);
|
12 |
+
}
|
13 |
+
});
|
14 |
+
}
|
15 |
+
|
16 |
/**
|
17 |
* @param string $hexstr
|
18 |
* @return array
|
28 |
return array("red" => 0xFF & ($int >> 0x10), "green" => 0xFF & ($int >> 0x8), "blue" => 0xFF & $int);
|
29 |
}
|
30 |
|
31 |
+
private static function delete_resized_files_from_url($src){
|
32 |
+
$local = TimberURLHelper::url_to_file_system($src);
|
33 |
+
self::delete_resized_files($local);
|
34 |
+
}
|
35 |
+
|
36 |
+
private static function delete_letterboxed_files_from_url($src){
|
37 |
+
$local = TimberURLHelper::url_to_file_system($src);
|
38 |
+
self::delete_letterboxed_files($local);
|
39 |
+
}
|
40 |
+
|
41 |
+
static function delete_resized_files($local_file){
|
42 |
+
$info = pathinfo($local_file);
|
43 |
+
$dir = $info['dirname'];
|
44 |
+
$ext = $info['extension'];
|
45 |
+
$filename = $info['filename'];
|
46 |
+
$searcher = '/'.$filename.'-[0-9999999]*';
|
47 |
+
foreach (glob($dir.$searcher) as $found_file){
|
48 |
+
$regexdir = str_replace('/', '\/', $dir);
|
49 |
+
$pattern = '/'.($regexdir).'\/'.$filename.'-[0-9]*x[0-9]*-c-[a-z]*.'.$ext.'/';
|
50 |
+
$match = preg_match($pattern, $found_file);
|
51 |
+
//$match = preg_match("/\/srv\/www\/wordpress-develop\/src\/wp-content\/uploads\/2014\/05\/$filename-[0-9]*x[0-9]*-c-[a-z]*.jpg/", $found_file);
|
52 |
+
//$match = preg_match("/\/srv\/www\/wordpress-develop\/src\/wp-content\/uploads\/2014\/05\/arch-[0-9]*x[0-9]*-c-[a-z]*.jpg/", $filename);
|
53 |
+
if ($match){
|
54 |
+
unlink($found_file);
|
55 |
+
}
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
static function delete_letterboxed_files($local_file){
|
60 |
+
$info = pathinfo($local_file);
|
61 |
+
$dir = $info['dirname'];
|
62 |
+
$ext = $info['extension'];
|
63 |
+
$filename = $info['filename'];
|
64 |
+
$searcher = '/'.$filename.'-lbox-[0-9999999]*';
|
65 |
+
foreach (glob($dir.$searcher) as $found_file){
|
66 |
+
$regexdir = str_replace('/', '\/', $dir);
|
67 |
+
$pattern = '/'.($regexdir).'\/'.$filename.'-lbox-[0-9]*x[0-9]*-[a-zA-Z0-9]*.'.$ext.'/';
|
68 |
+
$match = preg_match($pattern, $found_file);
|
69 |
+
if ($match){
|
70 |
+
unlink($found_file);
|
71 |
+
}
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
75 |
/**
|
76 |
* @param string $src
|
77 |
* @param int $w
|
87 |
$color = str_replace('#', '', $color);
|
88 |
$newbase = $basename . '-lbox-' . $w . 'x' . $h . '-' . $color;
|
89 |
$new_path = $dir . '/' . $newbase . '.' . $ext;
|
90 |
+
$new_path = str_replace(home_url(), '', $new_path);
|
91 |
return $new_path;
|
92 |
}
|
93 |
|
99 |
* @return string
|
100 |
*/
|
101 |
public static function get_letterbox_file_path($src, $w, $h, $color) {
|
102 |
+
$new_path = self::get_letterbox_file_rel($src, $w, $h, $color);
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
$new_root_path = ABSPATH . $new_path;
|
104 |
$new_root_path = str_replace('//', '/', $new_root_path);
|
105 |
return $new_root_path;
|
106 |
}
|
107 |
|
108 |
+
/**
|
109 |
+
* @param string $src
|
110 |
+
* @param int $w
|
111 |
+
* @param int $h
|
112 |
+
* @param string $crop
|
113 |
+
* @return string
|
114 |
+
*/
|
115 |
+
public static function get_resize_file_rel($src, $w, $h, $crop){
|
116 |
+
$path_parts = pathinfo($src);
|
117 |
+
$basename = $path_parts['filename'];
|
118 |
+
$ext = $path_parts['extension'];
|
119 |
+
$dir = $path_parts['dirname'];
|
120 |
+
$newbase = $basename . '-' . $w . 'x' . $h . '-c-' . ( $crop ? $crop : 'f' ); // Crop will be either user named or f (false)
|
121 |
+
$new_path = $dir . '/' . $newbase . '.' . $ext;
|
122 |
+
$new_path = str_replace(home_url(), '', $new_path);
|
123 |
+
return $new_path;
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* @param string $src
|
128 |
+
* @param int $w
|
129 |
+
* @param int $h
|
130 |
+
* @param string $crop
|
131 |
+
* @return string
|
132 |
+
*/
|
133 |
+
public static function get_resize_file_path($src, $w, $h, $crop){
|
134 |
+
$new_path = self::get_resize_file_rel($src, $w, $h, $crop);
|
135 |
+
$new_root_path = ABSPATH . $new_path;
|
136 |
+
$new_root_path = TimberURLHelper::remove_double_slashes($new_root_path);
|
137 |
+
return $new_root_path;
|
138 |
+
}
|
139 |
+
|
140 |
/**
|
141 |
* @param int $iid
|
142 |
* @return string
|
156 |
* @return mixed|null|string
|
157 |
*/
|
158 |
public static function letterbox($src, $w, $h, $color = '#000000', $force = false) {
|
159 |
+
if (strstr($src, 'http') && !strstr($src, home_url())) {
|
160 |
+
$src = self::sideload_image($src);
|
161 |
+
}
|
162 |
+
$abs = false;
|
163 |
+
if (strstr($src, 'http')){
|
164 |
+
$abs = true;
|
165 |
}
|
166 |
+
$new_file_rel = self::get_letterbox_file_rel($src, $w, $h, $color);
|
167 |
+
$new_root_path = self::get_letterbox_file_path($src, $w, $h, $color);
|
168 |
+
$old_root_path = ABSPATH . str_replace(home_url(), '', $src);
|
169 |
+
$old_root_path = str_replace('//', '/', $old_root_path);
|
170 |
+
$new_root_path = str_replace('//', '/', $new_root_path);
|
171 |
$urlinfo = parse_url($src);
|
172 |
+
if (file_exists($new_root_path) && !$force) {
|
173 |
+
if ($abs){
|
174 |
+
return untrailingslashit(home_url()).$new_file_rel;
|
175 |
+
} else {
|
176 |
+
return TimberURLHelper::preslashit($new_file_rel);
|
177 |
+
}
|
178 |
}
|
179 |
$bg = imagecreatetruecolor($w, $h);
|
180 |
$c = self::hexrgb($color);
|
181 |
$white = imagecolorallocate($bg, $c['red'], $c['green'], $c['blue']);
|
182 |
imagefill($bg, 0, 0, $white);
|
183 |
+
$image = wp_get_image_editor($old_root_path);
|
184 |
if (!is_wp_error($image)) {
|
185 |
$current_size = $image->get_size();
|
186 |
$ow = $current_size['width'];
|
203 |
$owt = $w;
|
204 |
$image->crop(0, 0, $ow, $oh, $owt, $oht);
|
205 |
}
|
206 |
+
$image->save($new_root_path);
|
207 |
$func = 'imagecreatefromjpeg';
|
208 |
+
$ext = pathinfo($new_root_path, PATHINFO_EXTENSION);
|
209 |
if ($ext == 'gif') {
|
210 |
$func = 'imagecreatefromgif';
|
211 |
} else if ($ext == 'png') {
|
212 |
$func = 'imagecreatefrompng';
|
213 |
}
|
214 |
+
$image = $func($new_root_path);
|
215 |
imagecopy($bg, $image, $x, $y, 0, 0, $owt, $oht);
|
216 |
+
imagejpeg($bg, $new_root_path);
|
217 |
+
return TimberURLHelper::get_rel_path($new_root_path);
|
218 |
} else {
|
219 |
TimberHelper::error_log($image);
|
220 |
}
|
227 |
* @return string
|
228 |
*/
|
229 |
public static function img_to_jpg($src, $bghex = '#FFFFFF'){
|
230 |
+
$src = str_replace(home_url(), '', $src);
|
231 |
$output = str_replace('.png', '.jpg', $src);
|
232 |
$input_file = ABSPATH . $src;
|
233 |
$output_file = ABSPATH . $output;
|
304 |
if (empty($src)){
|
305 |
return '';
|
306 |
}
|
307 |
+
if (strstr($src, 'http') && !strstr($src, home_url())) {
|
308 |
$src = self::sideload_image($src);
|
309 |
}
|
310 |
$abs = false;
|
317 |
$crop = $allowed_crop_positions[ 0 ];
|
318 |
}
|
319 |
//oh good, it's a relative image in the uploads folder!
|
320 |
+
$new_path = self::get_resize_file_rel($src, $w, $h, $crop);
|
321 |
+
$new_root_path = self::get_resize_file_path($src, $w, $h, $crop);
|
322 |
+
if ($abs){
|
323 |
+
$old_root_path = ABSPATH . str_replace(home_url(), '', $src);
|
324 |
+
} else {
|
325 |
+
$old_root_path = ABSPATH . $src;
|
326 |
+
}
|
327 |
+
$old_root_path = TimberURLHelper::remove_double_slashes($old_root_path);
|
328 |
+
$new_root_path = TimberURLHelper::remove_double_slashes($new_root_path);
|
|
|
|
|
329 |
if ( file_exists($new_root_path) ) {
|
330 |
if ( $force_resize ) {
|
331 |
// Force resize - warning: will regenerate the image on every pageload, use for testing purposes only!
|
332 |
unlink( $new_root_path );
|
333 |
} else {
|
334 |
if ($abs){
|
335 |
+
return untrailingslashit(home_url()).$new_path;
|
336 |
} else {
|
337 |
+
$returning = TimberURLHelper::preslashit($new_path);
|
338 |
+
return $returning;
|
339 |
}
|
340 |
return $new_path;
|
341 |
}
|
342 |
}
|
|
|
343 |
$image = wp_get_image_editor($old_root_path);
|
344 |
|
345 |
if (!is_wp_error($image)) {
|
372 |
$src_x = round( ( $src_w - $src_wt ) / 2 );
|
373 |
$src_y = round( ( $src_h - $src_ht ) / 2 );
|
374 |
} else if ($crop == 'top') {
|
|
|
|
|
375 |
$src_y = 0;
|
376 |
} else if ($crop == 'bottom') {
|
377 |
$src_y = $src_h - $src_ht;
|
396 |
error_log(print_r($result, true));
|
397 |
}
|
398 |
if ($abs){
|
399 |
+
return untrailingslashit(home_url()).$new_path;
|
400 |
}
|
401 |
return $new_path;
|
402 |
} else if (isset($image->error_data['error_loading_image'])) {
|
407 |
return $src;
|
408 |
}
|
409 |
}
|
410 |
+
|
411 |
+
TimberImageHelper::add_actions();
|
functions/timber-image.php
CHANGED
@@ -104,7 +104,8 @@ class TimberImage extends TimberCore {
|
|
104 |
$dir = self::wp_upload_dir();
|
105 |
$base = ($dir["baseurl"]);
|
106 |
|
107 |
-
|
|
|
108 |
}
|
109 |
|
110 |
private static function _maybe_secure_url( $url ) {
|
104 |
$dir = self::wp_upload_dir();
|
105 |
$base = ($dir["baseurl"]);
|
106 |
|
107 |
+
$src = trailingslashit( $this->_maybe_secure_url( $base ) ) . $this->file;
|
108 |
+
return apply_filters('timber_image_src', $src);
|
109 |
}
|
110 |
|
111 |
private static function _maybe_secure_url( $url ) {
|
functions/timber-loader.php
CHANGED
@@ -116,18 +116,31 @@ class TimberLoader {
|
|
116 |
$parent_loc = str_replace('/', '\\', $parent_loc);
|
117 |
}
|
118 |
$theme_locs[] = $child_loc;
|
119 |
-
$
|
|
|
|
|
120 |
if ($child_loc != $parent_loc) {
|
121 |
$theme_locs[] = $parent_loc;
|
122 |
-
$
|
|
|
|
|
123 |
}
|
124 |
//now make sure theres a trailing slash on everything
|
125 |
-
|
126 |
-
$tl = trailingslashit($tl);
|
127 |
-
}
|
128 |
return $theme_locs;
|
129 |
}
|
130 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
/**
|
132 |
* @return array
|
133 |
*/
|
@@ -158,10 +171,12 @@ class TimberLoader {
|
|
158 |
if (is_dir($caller)) {
|
159 |
$locs[] = $caller;
|
160 |
}
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
|
|
|
|
165 |
}
|
166 |
return $locs;
|
167 |
}
|
@@ -179,6 +194,7 @@ class TimberLoader {
|
|
179 |
$locs = array_diff($locs, $this->get_locations_theme());
|
180 |
$locs = array_merge($locs, $this->get_locations_theme());
|
181 |
$locs = array_merge($locs, $this->get_locations_caller($caller));
|
|
|
182 |
$locs = array_unique($locs);
|
183 |
$locs = apply_filters('timber_locations', $locs);
|
184 |
return $locs;
|
@@ -206,20 +222,27 @@ class TimberLoader {
|
|
206 |
* @return Twig_Environment
|
207 |
*/
|
208 |
function get_twig() {
|
209 |
-
|
210 |
-
|
211 |
-
|
|
|
|
|
212 |
|
213 |
$loader = $this->get_loader();
|
214 |
$params = array('debug' => WP_DEBUG, 'autoescape' => false);
|
215 |
if (isset(Timber::$autoescape)){
|
216 |
$params['autoescape'] = Timber::$autoescape;
|
217 |
}
|
218 |
-
|
|
|
|
|
|
|
219 |
$params['cache'] = TIMBER_LOC . '/twig-cache';
|
220 |
}
|
221 |
$twig = new Twig_Environment($loader, $params);
|
222 |
-
|
|
|
|
|
223 |
$twig->addExtension($this->_get_cache_extension());
|
224 |
|
225 |
$twig = apply_filters('twig_apply_filters', $twig);
|
116 |
$parent_loc = str_replace('/', '\\', $parent_loc);
|
117 |
}
|
118 |
$theme_locs[] = $child_loc;
|
119 |
+
foreach($this->get_locations_theme_dir() as $dirname){
|
120 |
+
$theme_locs[] = trailingslashit($child_loc) . trailingslashit($dirname);
|
121 |
+
}
|
122 |
if ($child_loc != $parent_loc) {
|
123 |
$theme_locs[] = $parent_loc;
|
124 |
+
foreach($this->get_locations_theme_dir() as $dirname){
|
125 |
+
$theme_locs[] = trailingslashit($parent_loc) . trailingslashit($dirname);
|
126 |
+
}
|
127 |
}
|
128 |
//now make sure theres a trailing slash on everything
|
129 |
+
$theme_locs = array_map('trailingslashit', $theme_locs);
|
|
|
|
|
130 |
return $theme_locs;
|
131 |
}
|
132 |
|
133 |
+
/**
|
134 |
+
* returns an array of the directory inside themes that holds twig files
|
135 |
+
* @return array the names of directores, ie: array('templats', 'views');
|
136 |
+
*/
|
137 |
+
private function get_locations_theme_dir(){
|
138 |
+
if (is_string(Timber::$dirname)){
|
139 |
+
return array(Timber::$dirname);
|
140 |
+
}
|
141 |
+
return Timber::$dirname;
|
142 |
+
}
|
143 |
+
|
144 |
/**
|
145 |
* @return array
|
146 |
*/
|
171 |
if (is_dir($caller)) {
|
172 |
$locs[] = $caller;
|
173 |
}
|
174 |
+
foreach($this->get_locations_theme_dir() as $dirname){
|
175 |
+
$caller_sub = $caller . trailingslashit($dirname);
|
176 |
+
if (is_dir($caller_sub)) {
|
177 |
+
$locs[] = $caller_sub;
|
178 |
+
}
|
179 |
+
}
|
180 |
}
|
181 |
return $locs;
|
182 |
}
|
194 |
$locs = array_diff($locs, $this->get_locations_theme());
|
195 |
$locs = array_merge($locs, $this->get_locations_theme());
|
196 |
$locs = array_merge($locs, $this->get_locations_caller($caller));
|
197 |
+
//$locs[] = '/';
|
198 |
$locs = array_unique($locs);
|
199 |
$locs = apply_filters('timber_locations', $locs);
|
200 |
return $locs;
|
222 |
* @return Twig_Environment
|
223 |
*/
|
224 |
function get_twig() {
|
225 |
+
if (!class_exists('Twig_Autoloader')) {
|
226 |
+
$loader_loc = trailingslashit(TIMBER_LOC) . 'Twig/lib/Twig/Autoloader.php';
|
227 |
+
require_once($loader_loc);
|
228 |
+
Twig_Autoloader::register();
|
229 |
+
}
|
230 |
|
231 |
$loader = $this->get_loader();
|
232 |
$params = array('debug' => WP_DEBUG, 'autoescape' => false);
|
233 |
if (isset(Timber::$autoescape)){
|
234 |
$params['autoescape'] = Timber::$autoescape;
|
235 |
}
|
236 |
+
if (Timber::$cache == true){
|
237 |
+
Timber::$twig_cache = true;
|
238 |
+
}
|
239 |
+
if (Timber::$twig_cache) {
|
240 |
$params['cache'] = TIMBER_LOC . '/twig-cache';
|
241 |
}
|
242 |
$twig = new Twig_Environment($loader, $params);
|
243 |
+
if (WP_DEBUG){
|
244 |
+
$twig->addExtension(new Twig_Extension_Debug());
|
245 |
+
}
|
246 |
$twig->addExtension($this->_get_cache_extension());
|
247 |
|
248 |
$twig = apply_filters('twig_apply_filters', $twig);
|
functions/timber-post.php
CHANGED
@@ -46,7 +46,8 @@ class TimberPost extends TimberCore {
|
|
46 |
$post_info = $this->get_info($pid);
|
47 |
$this->import($post_info);
|
48 |
//cant have a function, so gots to do it this way
|
49 |
-
$
|
|
|
50 |
}
|
51 |
|
52 |
/**
|
@@ -68,7 +69,7 @@ class TimberPost extends TimberCore {
|
|
68 |
* @param string $field
|
69 |
* @param mixed $value
|
70 |
*/
|
71 |
-
function update($field, $value) {
|
72 |
if (isset($this->ID)) {
|
73 |
update_post_meta($this->ID, $field, $value);
|
74 |
$this->$field = $value;
|
@@ -675,6 +676,9 @@ class TimberPost extends TimberCore {
|
|
675 |
if (is_array($value) && count($value) == 1){
|
676 |
$value = $value[0];
|
677 |
}
|
|
|
|
|
|
|
678 |
}
|
679 |
$value = apply_filters('timber_post_get_meta_field', $value, $this->ID, $field_name, $this);
|
680 |
return $value;
|
@@ -798,7 +802,10 @@ class TimberPost extends TimberCore {
|
|
798 |
* @param string $field_name
|
799 |
* @return mixed
|
800 |
*/
|
801 |
-
public function meta($field_name){
|
|
|
|
|
|
|
802 |
return $this->get_field($field_name);
|
803 |
}
|
804 |
|
@@ -880,8 +887,11 @@ class TimberPost extends TimberCore {
|
|
880 |
* @return string
|
881 |
*/
|
882 |
public function post_class($class='') {
|
883 |
-
|
884 |
-
|
|
|
|
|
|
|
885 |
return implode(' ', $class_array);
|
886 |
}
|
887 |
|
46 |
$post_info = $this->get_info($pid);
|
47 |
$this->import($post_info);
|
48 |
//cant have a function, so gots to do it this way
|
49 |
+
$post_class = $this->post_class();
|
50 |
+
$this->class = $post_class;
|
51 |
}
|
52 |
|
53 |
/**
|
69 |
* @param string $field
|
70 |
* @param mixed $value
|
71 |
*/
|
72 |
+
public function update($field, $value) {
|
73 |
if (isset($this->ID)) {
|
74 |
update_post_meta($this->ID, $field, $value);
|
75 |
$this->$field = $value;
|
676 |
if (is_array($value) && count($value) == 1){
|
677 |
$value = $value[0];
|
678 |
}
|
679 |
+
if (is_array($value) && count($value) == 0){
|
680 |
+
$value = null;
|
681 |
+
}
|
682 |
}
|
683 |
$value = apply_filters('timber_post_get_meta_field', $value, $this->ID, $field_name, $this);
|
684 |
return $value;
|
802 |
* @param string $field_name
|
803 |
* @return mixed
|
804 |
*/
|
805 |
+
public function meta($field_name = null){
|
806 |
+
if ($field_name == null){
|
807 |
+
$field_name = 'meta';
|
808 |
+
}
|
809 |
return $this->get_field($field_name);
|
810 |
}
|
811 |
|
887 |
* @return string
|
888 |
*/
|
889 |
public function post_class($class='') {
|
890 |
+
global $post;
|
891 |
+
$old_global_post = $post;
|
892 |
+
$post = $this;
|
893 |
+
$class_array = get_post_class($class, $this->ID);
|
894 |
+
$post = $old_global_post;
|
895 |
return implode(' ', $class_array);
|
896 |
}
|
897 |
|
functions/timber-site.php
CHANGED
@@ -30,6 +30,7 @@ class TimberSite extends TimberCore {
|
|
30 |
$this->name = $this->blogname;
|
31 |
$this->title = $this->blogname;
|
32 |
$this->url = $this->siteurl;
|
|
|
33 |
$theme_slug = get_blog_option($info->blog_id, 'stylesheet');
|
34 |
$this->theme = new TimberTheme($theme_slug);
|
35 |
$this->description = get_blog_option($info->blog_id, 'blogdescription');
|
@@ -84,4 +85,4 @@ class TimberSite extends TimberCore {
|
|
84 |
function url(){
|
85 |
return $this->get_link();
|
86 |
}
|
87 |
-
}
|
30 |
$this->name = $this->blogname;
|
31 |
$this->title = $this->blogname;
|
32 |
$this->url = $this->siteurl;
|
33 |
+
$this->id = $this->ID;
|
34 |
$theme_slug = get_blog_option($info->blog_id, 'stylesheet');
|
35 |
$this->theme = new TimberTheme($theme_slug);
|
36 |
$this->description = get_blog_option($info->blog_id, 'blogdescription');
|
85 |
function url(){
|
86 |
return $this->get_link();
|
87 |
}
|
88 |
+
}
|
functions/timber-url-helper.php
CHANGED
@@ -62,6 +62,7 @@
|
|
62 |
if (isset($url_info['query']) && strlen($url_info['query'])){
|
63 |
$link .= '?'.$url_info['query'];
|
64 |
}
|
|
|
65 |
return $link;
|
66 |
}
|
67 |
|
@@ -87,6 +88,13 @@
|
|
87 |
return $old_root_path;
|
88 |
}
|
89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
/**
|
91 |
* @param string $src
|
92 |
* @return string
|
62 |
if (isset($url_info['query']) && strlen($url_info['query'])){
|
63 |
$link .= '?'.$url_info['query'];
|
64 |
}
|
65 |
+
$link = TimberURLHelper::remove_double_slashes($link);
|
66 |
return $link;
|
67 |
}
|
68 |
|
88 |
return $old_root_path;
|
89 |
}
|
90 |
|
91 |
+
public static function url_to_file_system($url){
|
92 |
+
$url_parts = parse_url($url);
|
93 |
+
$path = ABSPATH . $url_parts['path'];
|
94 |
+
$path = str_replace('//', '/', $path);
|
95 |
+
return $path;
|
96 |
+
}
|
97 |
+
|
98 |
/**
|
99 |
* @param string $src
|
100 |
* @return string
|
readme.txt
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
Contributors: jarednova
|
3 |
Tags: template engine, templates, twig
|
4 |
Requires at least: 3.7
|
5 |
-
Stable tag: 0.18.
|
6 |
Tested up to: 3.9
|
7 |
PHP version: 5.3.0 or greater
|
8 |
License: GPLv2 or later
|
@@ -41,6 +41,15 @@ Timber is great for any WordPress developer who cares about writing good, mainta
|
|
41 |
|
42 |
== Changelog ==
|
43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
= 0.18.0 =
|
45 |
* BREAKING CHANGE ALERT wp_title no longer appends bloginfo('name') to end of string (thanks @aduth)
|
46 |
* BREAKING CHANGE ALERT get_preview now respects <!-- more --> tag (thanks @jnweaver)
|
2 |
Contributors: jarednova
|
3 |
Tags: template engine, templates, twig
|
4 |
Requires at least: 3.7
|
5 |
+
Stable tag: 0.18.1
|
6 |
Tested up to: 3.9
|
7 |
PHP version: 5.3.0 or greater
|
8 |
License: GPLv2 or later
|
41 |
|
42 |
== Changelog ==
|
43 |
|
44 |
+
= 0.18.1 =
|
45 |
+
* Dates now use date_i18n filter (thanks @jamesagreenleaf)
|
46 |
+
* The twig |date filter now defaults to your WP Admin settings (thanks @jamesagreenleaf)
|
47 |
+
* You can send Timber::$dirname an array to specify multiple locations of twig files within a theme
|
48 |
+
* Load views from anywhere on the server (thanks @th3fallen)
|
49 |
+
* Load twig files from anywhere on the server using an absolute path
|
50 |
+
* Use another version of Twig if you have it loaded (thanks @ButlerPCnet)
|
51 |
+
* more tests!
|
52 |
+
|
53 |
= 0.18.0 =
|
54 |
* BREAKING CHANGE ALERT wp_title no longer appends bloginfo('name') to end of string (thanks @aduth)
|
55 |
* BREAKING CHANGE ALERT get_preview now respects <!-- more --> tag (thanks @jnweaver)
|
timber-starter-theme/single.php
CHANGED
@@ -15,4 +15,10 @@ $context['post'] = $post;
|
|
15 |
$context['wp_title'] .= ' - ' . $post->title();
|
16 |
$context['comment_form'] = TimberHelper::get_comment_form();
|
17 |
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
15 |
$context['wp_title'] .= ' - ' . $post->title();
|
16 |
$context['comment_form'] = TimberHelper::get_comment_form();
|
17 |
|
18 |
+
if (post_password_required($post->ID)){
|
19 |
+
Timber::render('single-password.twig', $context);
|
20 |
+
} else {
|
21 |
+
Timber::render(array('single-' . $post->ID . '.twig', 'single-' . $post->post_type . '.twig', 'single.twig'), $context);
|
22 |
+
}
|
23 |
+
|
24 |
+
|
timber-starter-theme/views/base.twig
CHANGED
@@ -1,14 +1,16 @@
|
|
1 |
-
{%
|
2 |
-
{%
|
|
|
|
|
|
|
3 |
{% endblock %}
|
4 |
-
|
5 |
-
<body class="{{body_class}}" data-source="base.twig">
|
6 |
<header class="header" >
|
7 |
{% block header %}
|
8 |
<div class="wrapper">
|
9 |
|
10 |
<h1 class="hdr-logo" role="banner">
|
11 |
-
<a class="hdr-logo-link" href="/" title="Timber" rel="home">{{
|
12 |
</h1>
|
13 |
<nav id="access" class="main-navigation" role="navigation">
|
14 |
<ul>
|
@@ -39,9 +41,11 @@
|
|
39 |
{% endif %}
|
40 |
</section>
|
41 |
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
|
|
|
|
46 |
</body>
|
47 |
-
</html>
|
1 |
+
{% block html_head_container %}
|
2 |
+
{% include 'html-header.twig' %}
|
3 |
+
{% block head %}
|
4 |
+
{% endblock %}
|
5 |
+
</head>
|
6 |
{% endblock %}
|
7 |
+
<body class="{{body_class}}" data-template="base.twig">
|
|
|
8 |
<header class="header" >
|
9 |
{% block header %}
|
10 |
<div class="wrapper">
|
11 |
|
12 |
<h1 class="hdr-logo" role="banner">
|
13 |
+
<a class="hdr-logo-link" href="/" title="Timber" rel="home">{{site.name}}</a>
|
14 |
</h1>
|
15 |
<nav id="access" class="main-navigation" role="navigation">
|
16 |
<ul>
|
41 |
{% endif %}
|
42 |
</section>
|
43 |
|
44 |
+
{% block footer %}
|
45 |
+
<footer id="footer">
|
46 |
+
{% include 'footer.twig' %}
|
47 |
+
</footer>
|
48 |
+
{{ function('wp_footer') }}
|
49 |
+
{% endblock %}
|
50 |
</body>
|
51 |
+
</html>
|
timber-starter-theme/views/single-password.twig
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{% extends "base.twig" %}
|
2 |
+
{% block content %}
|
3 |
+
<form class="password-form" action="/wp-login.php?action=postpass" method="post">
|
4 |
+
<label for="pwbox-{{post.ID}}">Password:</label>
|
5 |
+
<input class="password-box" name="post_password" id="pwbox-{{post.ID}}" type="password" placeholder="Password" size="20" maxlength="20" />
|
6 |
+
<input class="password-btn" type="submit" name="Submit" value="Submit" />
|
7 |
+
</form>
|
8 |
+
{% endblock %}
|
timber-starter-theme/views/single.twig
CHANGED
@@ -8,7 +8,7 @@
|
|
8 |
<h1 class="article-h1">{{post.title}}</h1>
|
9 |
|
10 |
<p class="blog-author">
|
11 |
-
<span>By</span><a href="{{post.author.path}}"> {{ post.author.name }} </a><span>•</span> {{ post.
|
12 |
</p>
|
13 |
|
14 |
<div class="article-body">
|
@@ -33,4 +33,4 @@
|
|
33 |
</article>
|
34 |
</div> <!-- /content-wrapper -->
|
35 |
|
36 |
-
{% endblock %}
|
8 |
<h1 class="article-h1">{{post.title}}</h1>
|
9 |
|
10 |
<p class="blog-author">
|
11 |
+
<span>By</span><a href="{{post.author.path}}"> {{ post.author.name }} </a><span>•</span> {{ post.post_date|date}}
|
12 |
</p>
|
13 |
|
14 |
<div class="article-body">
|
33 |
</article>
|
34 |
</div> <!-- /content-wrapper -->
|
35 |
|
36 |
+
{% endblock %}
|
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.18.
|
8 |
Author URI: http://upstatement.com/
|
9 |
*/
|
10 |
|
@@ -57,7 +57,8 @@ require_once(__DIR__ . '/functions/timber-admin.php');
|
|
57 |
class Timber {
|
58 |
|
59 |
public static $locations;
|
60 |
-
public static $dirname
|
|
|
61 |
public static $cache = false;
|
62 |
public static $auto_meta = true;
|
63 |
public static $autoescape = false;
|
@@ -80,17 +81,6 @@ class Timber {
|
|
80 |
}
|
81 |
|
82 |
protected function init_constants() {
|
83 |
-
$timber_loc = str_replace(realpath(ABSPATH), '', realpath(__DIR__));
|
84 |
-
$plugin_url_path = str_replace($_SERVER['HTTP_HOST'], '', plugins_url());
|
85 |
-
$plugin_url_path = str_replace('https://', '', $plugin_url_path);
|
86 |
-
$plugin_url_path = str_replace('http://', '', $plugin_url_path);
|
87 |
-
$timber_dirs = dirname(__FILE__);
|
88 |
-
$timber_dirs = str_replace('\\', '/', $timber_dirs);
|
89 |
-
$timber_dirs = explode('/', $timber_dirs);
|
90 |
-
$timber_dirname = array_pop($timber_dirs);
|
91 |
-
define("TIMBER", $timber_loc);
|
92 |
-
define("TIMBER_URL_PATH", trailingslashit($plugin_url_path) . trailingslashit($timber_dirname));
|
93 |
-
define("TIMBER_URL", 'http://' . $_SERVER["HTTP_HOST"] . TIMBER);
|
94 |
define("TIMBER_LOC", realpath(__DIR__));
|
95 |
}
|
96 |
|
@@ -485,9 +475,24 @@ class Timber {
|
|
485 |
}
|
486 |
$output = $loader->render($file, $data, $expires, $cache_mode);
|
487 |
}
|
|
|
488 |
return $output;
|
489 |
}
|
490 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
491 |
/**
|
492 |
* @param array $filenames
|
493 |
* @param array $data
|
@@ -508,6 +513,17 @@ class Timber {
|
|
508 |
return $output;
|
509 |
}
|
510 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
511 |
|
512 |
/* Sidebar
|
513 |
================================ */
|
@@ -610,11 +626,13 @@ class Timber {
|
|
610 |
}
|
611 |
|
612 |
public static function cancel_query(){
|
613 |
-
add_action('posts_request',
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
|
|
|
|
618 |
}
|
619 |
|
620 |
/**
|
@@ -624,7 +642,11 @@ class Timber {
|
|
624 |
* @param bool $tparams
|
625 |
*/
|
626 |
public static function load_template($template, $query = false, $force_header = 0, $tparams = false) {
|
627 |
-
|
|
|
|
|
|
|
|
|
628 |
if ($tparams){
|
629 |
global $params;
|
630 |
$params = $tparams;
|
@@ -651,7 +673,6 @@ class Timber {
|
|
651 |
if ($query) {
|
652 |
add_action('do_parse_request', function() use ($query) {
|
653 |
global $wp;
|
654 |
-
|
655 |
if ( is_callable($query) )
|
656 |
$query = call_user_func($query);
|
657 |
|
@@ -672,7 +693,9 @@ class Timber {
|
|
672 |
load_template($template);
|
673 |
die;
|
674 |
});
|
|
|
675 |
}
|
|
|
676 |
}
|
677 |
|
678 |
/* Pagination
|
@@ -685,8 +708,9 @@ class Timber {
|
|
685 |
public static function get_pagination($prefs = array()){
|
686 |
global $wp_query;
|
687 |
global $paged;
|
|
|
688 |
$args['total'] = ceil($wp_query->found_posts / $wp_query->query_vars['posts_per_page']);
|
689 |
-
if (
|
690 |
$url = explode('?', get_pagenum_link(0));
|
691 |
if (isset($url[1])){
|
692 |
parse_str($url[1], $query);
|
@@ -699,7 +723,6 @@ class Timber {
|
|
699 |
$args['base'] = str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) );
|
700 |
}
|
701 |
$args['type'] = 'array';
|
702 |
-
|
703 |
$args['current'] = max( 1, get_query_var('paged') );
|
704 |
$args['mid_size'] = max(9 - $args['current'], 3);
|
705 |
$args['prev_next'] = false;
|
@@ -709,13 +732,13 @@ class Timber {
|
|
709 |
$args = array_merge($args, $prefs);
|
710 |
}
|
711 |
$data['pages'] = TimberHelper::paginate_links($args);
|
712 |
-
$next =
|
713 |
if ($next){
|
714 |
-
$data['next'] = array('link' => $next, 'class' => 'page-numbers next');
|
715 |
}
|
716 |
$prev = previous_posts(false);
|
717 |
if ($prev){
|
718 |
-
$data['prev'] = array('link' => $prev, 'class' => 'page-numbers prev');
|
719 |
}
|
720 |
if ($paged < 2){
|
721 |
$data['prev'] = '';
|
@@ -783,3 +806,4 @@ class Timber {
|
|
783 |
|
784 |
$timber = new Timber();
|
785 |
$GLOBALS['timber'] = $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.18.1
|
8 |
Author URI: http://upstatement.com/
|
9 |
*/
|
10 |
|
57 |
class Timber {
|
58 |
|
59 |
public static $locations;
|
60 |
+
public static $dirname;
|
61 |
+
public static $twig_cache = false;
|
62 |
public static $cache = false;
|
63 |
public static $auto_meta = true;
|
64 |
public static $autoescape = false;
|
81 |
}
|
82 |
|
83 |
protected function init_constants() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
define("TIMBER_LOC", realpath(__DIR__));
|
85 |
}
|
86 |
|
475 |
}
|
476 |
$output = $loader->render($file, $data, $expires, $cache_mode);
|
477 |
}
|
478 |
+
do_action('timber_compile_done');
|
479 |
return $output;
|
480 |
}
|
481 |
|
482 |
+
/**
|
483 |
+
* @param array $string a string with twig variables
|
484 |
+
* @param array $data an array with data in it
|
485 |
+
* @return bool|string
|
486 |
+
*/
|
487 |
+
public static function compile_string($string, $data = array()){
|
488 |
+
$dummy_loader = new TimberLoader();
|
489 |
+
$dummy_loader->get_twig();
|
490 |
+
$loader = new Twig_Loader_String();
|
491 |
+
$twig = new Twig_Environment($loader);
|
492 |
+
$twig = apply_filters('twig_apply_filters', $twig);
|
493 |
+
return $twig->render($string, $data);
|
494 |
+
}
|
495 |
+
|
496 |
/**
|
497 |
* @param array $filenames
|
498 |
* @param array $data
|
513 |
return $output;
|
514 |
}
|
515 |
|
516 |
+
/**
|
517 |
+
* @param array $string a string with twig variables
|
518 |
+
* @param array $data an array with data in it
|
519 |
+
* @return bool|string
|
520 |
+
*/
|
521 |
+
public static function render_string($string, $data = array()){
|
522 |
+
$compiled = self::compile_string($string, $data);
|
523 |
+
echo $compiled;
|
524 |
+
return $compiled;
|
525 |
+
}
|
526 |
+
|
527 |
|
528 |
/* Sidebar
|
529 |
================================ */
|
626 |
}
|
627 |
|
628 |
public static function cancel_query(){
|
629 |
+
add_action('posts_request', array($this, 'cancel_query_posts_request'));
|
630 |
+
}
|
631 |
+
|
632 |
+
function cancel_query_posts_request(){
|
633 |
+
if (is_main_query()){
|
634 |
+
wp_reset_query();
|
635 |
+
}
|
636 |
}
|
637 |
|
638 |
/**
|
642 |
* @param bool $tparams
|
643 |
*/
|
644 |
public static function load_template($template, $query = false, $force_header = 0, $tparams = false) {
|
645 |
+
|
646 |
+
$fullPath = is_readable($template);
|
647 |
+
if (!$fullPath) {
|
648 |
+
$template = locate_template($template);
|
649 |
+
}
|
650 |
if ($tparams){
|
651 |
global $params;
|
652 |
$params = $tparams;
|
673 |
if ($query) {
|
674 |
add_action('do_parse_request', function() use ($query) {
|
675 |
global $wp;
|
|
|
676 |
if ( is_callable($query) )
|
677 |
$query = call_user_func($query);
|
678 |
|
693 |
load_template($template);
|
694 |
die;
|
695 |
});
|
696 |
+
return true;
|
697 |
}
|
698 |
+
return false;
|
699 |
}
|
700 |
|
701 |
/* Pagination
|
708 |
public static function get_pagination($prefs = array()){
|
709 |
global $wp_query;
|
710 |
global $paged;
|
711 |
+
global $wp_rewrite;
|
712 |
$args['total'] = ceil($wp_query->found_posts / $wp_query->query_vars['posts_per_page']);
|
713 |
+
if ($wp_rewrite->using_permalinks()){
|
714 |
$url = explode('?', get_pagenum_link(0));
|
715 |
if (isset($url[1])){
|
716 |
parse_str($url[1], $query);
|
723 |
$args['base'] = str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) );
|
724 |
}
|
725 |
$args['type'] = 'array';
|
|
|
726 |
$args['current'] = max( 1, get_query_var('paged') );
|
727 |
$args['mid_size'] = max(9 - $args['current'], 3);
|
728 |
$args['prev_next'] = false;
|
732 |
$args = array_merge($args, $prefs);
|
733 |
}
|
734 |
$data['pages'] = TimberHelper::paginate_links($args);
|
735 |
+
$next = get_next_posts_page_link($args['total']);
|
736 |
if ($next){
|
737 |
+
$data['next'] = array('link' => untrailingslashit($next), 'class' => 'page-numbers next');
|
738 |
}
|
739 |
$prev = previous_posts(false);
|
740 |
if ($prev){
|
741 |
+
$data['prev'] = array('link' => untrailingslashit($prev), 'class' => 'page-numbers prev');
|
742 |
}
|
743 |
if ($paged < 2){
|
744 |
$data['prev'] = '';
|
806 |
|
807 |
$timber = new Timber();
|
808 |
$GLOBALS['timber'] = $timber;
|
809 |
+
Timber::$dirname = 'views';
|