Version Description
- Fixed how Timber loads with Composer (thanks @connorjburton and @mrgrain)
- Updated docs! (thanks @lggorman and @kateboudreau)
- Fixed ImageHelper paths (thanks @TuureKaunisto)
- Added new filters for render (thanks @johnbillion)
- Fixed issue with timestamp conversion (thanks @thedamon)
- Fixed localization bugs (thanks @FlyingDR)
Download this release
Release Info
Developer | jarednova |
Plugin | Timber |
Version | 1.1.0 |
Comparing to | |
See all releases |
Code changes from version 1.0.5 to 1.1.0
- README.md +8 -2
- init.php +0 -6
- lib/Admin.php +4 -4
- lib/Core.php +1 -1
- lib/ImageHelper.php +3 -3
- lib/Loader.php +34 -45
- lib/Menu.php +1 -2
- lib/Post.php +13 -14
- lib/PostType.php +3 -3
- lib/Site.php +20 -13
- lib/TermGetter.php +2 -2
- lib/Timber.php +43 -27
- lib/Twig.php +1 -1
- lib/User.php +2 -1
- readme.txt +9 -1
- timber-starter-theme/templates/menu.twig +10 -8
- timber.php +2 -1
- vendor/autoload.php +1 -1
- vendor/composer/autoload_files.php +0 -10
- vendor/composer/autoload_real.php +3 -17
- vendor/composer/installed.json +6 -6
- vendor/twig/twig/CHANGELOG +9 -0
- vendor/twig/twig/doc/advanced.rst +1 -1
- vendor/twig/twig/doc/intro.rst +3 -3
- vendor/twig/twig/doc/recipes.rst +2 -2
- vendor/twig/twig/doc/tags/extends.rst +2 -2
- vendor/twig/twig/doc/templates.rst +14 -13
- vendor/twig/twig/ext/twig/php_twig.h +1 -1
- vendor/twig/twig/ext/twig/twig.c +1 -1
- vendor/twig/twig/lib/Twig/Environment.php +38 -1
- vendor/twig/twig/lib/Twig/ExpressionParser.php +4 -3
- vendor/twig/twig/lib/Twig/Node/Macro.php +5 -0
- vendor/twig/twig/lib/Twig/Template.php +7 -1
- vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php +5 -0
- vendor/twig/twig/test/Twig/Tests/Node/MacroTest.php +4 -0
- vendor/twig/twig/test/Twig/Tests/TemplateTest.php +2 -2
README.md
CHANGED
@@ -6,7 +6,7 @@ By Jared Novack (<a href="https://twitter.com/jarednova">@JaredNova</a>) and <a
|
|
6 |
|
7 |
[![Build Status](https://img.shields.io/travis/timber/timber/master.svg?style=flat-square)](https://travis-ci.org/timber/timber)
|
8 |
[![Coverage Status](https://img.shields.io/coveralls/timber/timber.svg?style=flat-square)](https://coveralls.io/r/timber/timber?branch=master)
|
9 |
-
[![Dependency Status](https://
|
10 |
[![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/timber/timber.svg?style=flat-square)](https://scrutinizer-ci.com/g/timber/timber/?branch=master)
|
11 |
[![Latest Stable Version](https://img.shields.io/packagist/v/timber/timber.svg?style=flat-square)](https://packagist.org/packages/timber/timber)
|
12 |
[![WordPress Download Count](https://img.shields.io/wordpress/plugin/dt/timber-library.svg?style=flat-square)](https://wordpress.org/plugins/timber-library/)
|
@@ -56,7 +56,12 @@ If your theme is not setup to pull in Composer's autoload file, you will need to
|
|
56 |
require_once(__DIR__ . '/vendor/autoload.php');
|
57 |
```
|
58 |
|
59 |
-
|
|
|
|
|
|
|
|
|
|
|
60 |
* * *
|
61 |
|
62 |
### Mission Statement
|
@@ -82,6 +87,7 @@ Timber is great for any WordPress developer who cares about writing good, mainta
|
|
82 |
|
83 |
#### Projects that use Timber
|
84 |
* [**Gantry5**](https://wordpress.org/plugins/gantry5/) a framework for theme development
|
|
|
85 |
|
86 |
#### Helpful Links
|
87 |
* [**CSS Tricks**](https://css-tricks.com/timber-and-twig-reignited-my-love-for-wordpress/) introduction to Timber by [@tjFogarty](https://github.com/tjFogarty)
|
6 |
|
7 |
[![Build Status](https://img.shields.io/travis/timber/timber/master.svg?style=flat-square)](https://travis-ci.org/timber/timber)
|
8 |
[![Coverage Status](https://img.shields.io/coveralls/timber/timber.svg?style=flat-square)](https://coveralls.io/r/timber/timber?branch=master)
|
9 |
+
[![Dependency Status](https://www.versioneye.com/user/projects/574e40e6e298f30048059b9f/badge.svg?style=flat-square)](https://www.versioneye.com/user/projects/574e40e6e298f30048059b9f)
|
10 |
[![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/timber/timber.svg?style=flat-square)](https://scrutinizer-ci.com/g/timber/timber/?branch=master)
|
11 |
[![Latest Stable Version](https://img.shields.io/packagist/v/timber/timber.svg?style=flat-square)](https://packagist.org/packages/timber/timber)
|
12 |
[![WordPress Download Count](https://img.shields.io/wordpress/plugin/dt/timber-library.svg?style=flat-square)](https://wordpress.org/plugins/timber-library/)
|
56 |
require_once(__DIR__ . '/vendor/autoload.php');
|
57 |
```
|
58 |
|
59 |
+
at the top of your `functions.php` file.
|
60 |
+
|
61 |
+
Initialize Timber with
|
62 |
+
```php
|
63 |
+
$timber = new \Timber\Timber();
|
64 |
+
```
|
65 |
* * *
|
66 |
|
67 |
### Mission Statement
|
87 |
|
88 |
#### Projects that use Timber
|
89 |
* [**Gantry5**](https://wordpress.org/plugins/gantry5/) a framework for theme development
|
90 |
+
* [**Branch**](https://github.com/JeyKeu/branch/) Bootstrap + Timber = Branch starter theme!
|
91 |
|
92 |
#### Helpful Links
|
93 |
* [**CSS Tricks**](https://css-tricks.com/timber-and-twig-reignited-my-love-for-wordpress/) introduction to Timber by [@tjFogarty](https://github.com/tjFogarty)
|
init.php
DELETED
@@ -1,6 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
use Timber\Timber;
|
4 |
-
|
5 |
-
$timber = new Timber();
|
6 |
-
Timber::$dirname = 'views';
|
|
|
|
|
|
|
|
|
|
|
|
lib/Admin.php
CHANGED
@@ -5,10 +5,10 @@ namespace Timber;
|
|
5 |
class Admin {
|
6 |
|
7 |
public static function init() {
|
8 |
-
$filter = add_filter('plugin_row_meta', array(
|
9 |
-
$action = add_action('in_plugin_update_message-timber-library/timber.php', array(
|
10 |
-
$action = add_action('in_plugin_update_message-timber/timber.php', array(
|
11 |
-
if ($filter && $action) {
|
12 |
return true;
|
13 |
}
|
14 |
}
|
5 |
class Admin {
|
6 |
|
7 |
public static function init() {
|
8 |
+
$filter = add_filter('plugin_row_meta', array(__CLASS__, 'meta_links'), 10, 2);
|
9 |
+
$action = add_action('in_plugin_update_message-timber-library/timber.php', array(__CLASS__, 'in_plugin_update_message'), 10, 2);
|
10 |
+
$action = add_action('in_plugin_update_message-timber/timber.php', array(__CLASS__, 'in_plugin_update_message'), 10, 2);
|
11 |
+
if ( $filter && $action ) {
|
12 |
return true;
|
13 |
}
|
14 |
}
|
lib/Core.php
CHANGED
@@ -62,7 +62,7 @@ abstract class Core {
|
|
62 |
}
|
63 |
if ( is_array($info) ) {
|
64 |
foreach ( $info as $key => $value ) {
|
65 |
-
if ( $key === '' || ord(
|
66 |
continue;
|
67 |
}
|
68 |
if ( !empty($key) && $force ) {
|
62 |
}
|
63 |
if ( is_array($info) ) {
|
64 |
foreach ( $info as $key => $value ) {
|
65 |
+
if ( $key === '' || ord($key[0]) === 0 ) {
|
66 |
continue;
|
67 |
}
|
68 |
if ( !empty($key) && $force ) {
|
lib/ImageHelper.php
CHANGED
@@ -187,7 +187,7 @@ class ImageHelper {
|
|
187 |
*/
|
188 |
protected static function add_constants() {
|
189 |
if ( !defined('WP_CONTENT_SUBDIR') ) {
|
190 |
-
$wp_content_path = str_replace(
|
191 |
define('WP_CONTENT_SUBDIR', $wp_content_path);
|
192 |
}
|
193 |
}
|
@@ -199,7 +199,7 @@ class ImageHelper {
|
|
199 |
*/
|
200 |
static function add_filters() {
|
201 |
add_filter('upload_dir', function( $arr ) {
|
202 |
-
$arr['relative'] = str_replace(
|
203 |
return $arr;
|
204 |
} );
|
205 |
}
|
@@ -351,7 +351,7 @@ class ImageHelper {
|
|
351 |
}
|
352 |
} else {
|
353 |
if ( !$result['absolute'] ) {
|
354 |
-
$tmp =
|
355 |
}
|
356 |
if ( 0 === strpos($tmp, $upload_dir['baseurl']) ) {
|
357 |
$result['base'] = self::BASE_UPLOADS; // upload based
|
187 |
*/
|
188 |
protected static function add_constants() {
|
189 |
if ( !defined('WP_CONTENT_SUBDIR') ) {
|
190 |
+
$wp_content_path = str_replace(site_url(), '', WP_CONTENT_URL);
|
191 |
define('WP_CONTENT_SUBDIR', $wp_content_path);
|
192 |
}
|
193 |
}
|
199 |
*/
|
200 |
static function add_filters() {
|
201 |
add_filter('upload_dir', function( $arr ) {
|
202 |
+
$arr['relative'] = str_replace(site_url(), '', $arr['baseurl']);
|
203 |
return $arr;
|
204 |
} );
|
205 |
}
|
351 |
}
|
352 |
} else {
|
353 |
if ( !$result['absolute'] ) {
|
354 |
+
$tmp = site_url().$tmp;
|
355 |
}
|
356 |
if ( 0 === strpos($tmp, $upload_dir['baseurl']) ) {
|
357 |
$result['base'] = self::BASE_UPLOADS; // upload based
|
lib/Loader.php
CHANGED
@@ -23,7 +23,7 @@ class Loader {
|
|
23 |
|
24 |
protected $cache_mode = self::CACHE_TRANSIENT;
|
25 |
|
26 |
-
|
27 |
|
28 |
/**
|
29 |
* @param bool|string $caller the calling directory or false
|
@@ -37,13 +37,14 @@ class Loader {
|
|
37 |
/**
|
38 |
* @param string $file
|
39 |
* @param array $data
|
40 |
-
* @param bool
|
41 |
* @param string $cache_mode
|
42 |
* @return bool|string
|
43 |
*/
|
44 |
public function render( $file, $data = null, $expires = false, $cache_mode = self::CACHE_USE_DEFAULT ) {
|
45 |
// Different $expires if user is anonymous or logged in
|
46 |
if ( is_array($expires) ) {
|
|
|
47 |
if ( is_user_logged_in() && isset($expires[1]) ) {
|
48 |
$expires = $expires[1];
|
49 |
} else {
|
@@ -67,7 +68,7 @@ class Loader {
|
|
67 |
do_action('timber_loader_render_file', $result);
|
68 |
}
|
69 |
$data = apply_filters('timber_loader_render_data', $data);
|
70 |
-
$data = apply_filters('timber/loader/render_data', $data);
|
71 |
$output = $twig->render($file, $data);
|
72 |
}
|
73 |
|
@@ -75,7 +76,7 @@ class Loader {
|
|
75 |
$this->set_cache($key, $output, self::CACHEGROUP, $expires, $cache_mode);
|
76 |
}
|
77 |
$output = apply_filters('timber_output', $output);
|
78 |
-
return apply_filters('timber/output', $output);
|
79 |
}
|
80 |
|
81 |
/**
|
@@ -101,7 +102,7 @@ class Loader {
|
|
101 |
*/
|
102 |
protected function template_exists( $file ) {
|
103 |
foreach ( $this->locations as $dir ) {
|
104 |
-
$look_for =
|
105 |
if ( file_exists($look_for) ) {
|
106 |
return true;
|
107 |
}
|
@@ -112,26 +113,26 @@ class Loader {
|
|
112 |
/**
|
113 |
* @return array
|
114 |
*/
|
115 |
-
|
116 |
$theme_locs = array();
|
117 |
-
$
|
118 |
-
$
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
$theme_locs[] =
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
}
|
132 |
}
|
133 |
-
|
134 |
-
$theme_locs = array_map('trailingslashit', $theme_locs);
|
135 |
return $theme_locs;
|
136 |
}
|
137 |
|
@@ -139,7 +140,7 @@ class Loader {
|
|
139 |
* returns an array of the directory inside themes that holds twig files
|
140 |
* @return string[] the names of directores, ie: array('templats', 'views');
|
141 |
*/
|
142 |
-
|
143 |
if ( is_string(Timber::$dirname) ) {
|
144 |
return array(Timber::$dirname);
|
145 |
}
|
@@ -150,7 +151,7 @@ class Loader {
|
|
150 |
*
|
151 |
* @return array
|
152 |
*/
|
153 |
-
|
154 |
$locs = array();
|
155 |
if ( isset(Timber::$locations) ) {
|
156 |
if ( is_string(Timber::$locations) ) {
|
@@ -170,15 +171,16 @@ class Loader {
|
|
170 |
* @param bool|string $caller the calling directory
|
171 |
* @return array
|
172 |
*/
|
173 |
-
|
174 |
$locs = array();
|
175 |
if ( $caller && is_string($caller) ) {
|
176 |
-
$caller =
|
177 |
if ( is_dir($caller) ) {
|
178 |
$locs[] = $caller;
|
179 |
}
|
|
|
180 |
foreach ( $this->get_locations_theme_dir() as $dirname ) {
|
181 |
-
$caller_sub = $caller
|
182 |
if ( is_dir($caller_sub) ) {
|
183 |
$locs[] = $caller_sub;
|
184 |
}
|
@@ -201,6 +203,8 @@ class Loader {
|
|
201 |
$locs = array_merge($locs, $this->get_locations_theme());
|
202 |
$locs = array_merge($locs, $this->get_locations_caller($caller));
|
203 |
$locs = array_unique($locs);
|
|
|
|
|
204 |
$locs = apply_filters('timber_locations', $locs);
|
205 |
$locs = apply_filters('timber/locations', $locs);
|
206 |
return $locs;
|
@@ -210,28 +214,13 @@ class Loader {
|
|
210 |
* @return \Twig_Loader_Filesystem
|
211 |
*/
|
212 |
public function get_loader() {
|
213 |
-
$paths = array();
|
214 |
-
foreach ( $this->locations as $loc ) {
|
215 |
-
$loc = realpath($loc);
|
216 |
-
if ( is_dir($loc) ) {
|
217 |
-
$loc = realpath($loc);
|
218 |
-
$paths[] = $loc;
|
219 |
-
} else {
|
220 |
-
//error_log($loc.' is not a directory');
|
221 |
-
}
|
222 |
-
}
|
223 |
-
if ( !ini_get('open_basedir') ) {
|
224 |
-
$paths[] = '/';
|
225 |
-
} else {
|
226 |
-
$paths[] = ABSPATH;
|
227 |
-
}
|
228 |
$paths = apply_filters('timber/loader/paths', $paths);
|
229 |
-
|
230 |
-
return $loader;
|
231 |
}
|
232 |
|
233 |
/**
|
234 |
-
* @return Twig_Environment
|
235 |
*/
|
236 |
public function get_twig() {
|
237 |
$loader = $this->get_loader();
|
23 |
|
24 |
protected $cache_mode = self::CACHE_TRANSIENT;
|
25 |
|
26 |
+
protected $locations;
|
27 |
|
28 |
/**
|
29 |
* @param bool|string $caller the calling directory or false
|
37 |
/**
|
38 |
* @param string $file
|
39 |
* @param array $data
|
40 |
+
* @param array|bool $expires
|
41 |
* @param string $cache_mode
|
42 |
* @return bool|string
|
43 |
*/
|
44 |
public function render( $file, $data = null, $expires = false, $cache_mode = self::CACHE_USE_DEFAULT ) {
|
45 |
// Different $expires if user is anonymous or logged in
|
46 |
if ( is_array($expires) ) {
|
47 |
+
/** @var array $expires */
|
48 |
if ( is_user_logged_in() && isset($expires[1]) ) {
|
49 |
$expires = $expires[1];
|
50 |
} else {
|
68 |
do_action('timber_loader_render_file', $result);
|
69 |
}
|
70 |
$data = apply_filters('timber_loader_render_data', $data);
|
71 |
+
$data = apply_filters( 'timber/loader/render_data', $data, $file );
|
72 |
$output = $twig->render($file, $data);
|
73 |
}
|
74 |
|
76 |
$this->set_cache($key, $output, self::CACHEGROUP, $expires, $cache_mode);
|
77 |
}
|
78 |
$output = apply_filters('timber_output', $output);
|
79 |
+
return apply_filters( 'timber/output', $output, $data, $file );
|
80 |
}
|
81 |
|
82 |
/**
|
102 |
*/
|
103 |
protected function template_exists( $file ) {
|
104 |
foreach ( $this->locations as $dir ) {
|
105 |
+
$look_for = $dir.$file;
|
106 |
if ( file_exists($look_for) ) {
|
107 |
return true;
|
108 |
}
|
113 |
/**
|
114 |
* @return array
|
115 |
*/
|
116 |
+
protected function get_locations_theme() {
|
117 |
$theme_locs = array();
|
118 |
+
$theme_dirs = $this->get_locations_theme_dir();
|
119 |
+
$roots = array(get_stylesheet_directory(), get_template_directory());
|
120 |
+
$roots = array_map('realpath', $roots);
|
121 |
+
$roots = array_unique($roots);
|
122 |
+
foreach ( $roots as $root ) {
|
123 |
+
if ( !is_dir($root) ) {
|
124 |
+
continue;
|
125 |
+
}
|
126 |
+
$theme_locs[] = $root;
|
127 |
+
$root = trailingslashit($root);
|
128 |
+
foreach ( $theme_dirs as $dirname ) {
|
129 |
+
$tloc = realpath($root.$dirname);
|
130 |
+
if ( is_dir($tloc) ) {
|
131 |
+
$theme_locs[] = $tloc;
|
132 |
+
}
|
133 |
}
|
134 |
}
|
135 |
+
|
|
|
136 |
return $theme_locs;
|
137 |
}
|
138 |
|
140 |
* returns an array of the directory inside themes that holds twig files
|
141 |
* @return string[] the names of directores, ie: array('templats', 'views');
|
142 |
*/
|
143 |
+
protected function get_locations_theme_dir() {
|
144 |
if ( is_string(Timber::$dirname) ) {
|
145 |
return array(Timber::$dirname);
|
146 |
}
|
151 |
*
|
152 |
* @return array
|
153 |
*/
|
154 |
+
protected function get_locations_user() {
|
155 |
$locs = array();
|
156 |
if ( isset(Timber::$locations) ) {
|
157 |
if ( is_string(Timber::$locations) ) {
|
171 |
* @param bool|string $caller the calling directory
|
172 |
* @return array
|
173 |
*/
|
174 |
+
protected function get_locations_caller( $caller = false ) {
|
175 |
$locs = array();
|
176 |
if ( $caller && is_string($caller) ) {
|
177 |
+
$caller = realpath($caller);
|
178 |
if ( is_dir($caller) ) {
|
179 |
$locs[] = $caller;
|
180 |
}
|
181 |
+
$caller = trailingslashit($caller);
|
182 |
foreach ( $this->get_locations_theme_dir() as $dirname ) {
|
183 |
+
$caller_sub = realpath($caller.$dirname);
|
184 |
if ( is_dir($caller_sub) ) {
|
185 |
$locs[] = $caller_sub;
|
186 |
}
|
203 |
$locs = array_merge($locs, $this->get_locations_theme());
|
204 |
$locs = array_merge($locs, $this->get_locations_caller($caller));
|
205 |
$locs = array_unique($locs);
|
206 |
+
//now make sure theres a trailing slash on everything
|
207 |
+
$locs = array_map('trailingslashit', $locs);
|
208 |
$locs = apply_filters('timber_locations', $locs);
|
209 |
$locs = apply_filters('timber/locations', $locs);
|
210 |
return $locs;
|
214 |
* @return \Twig_Loader_Filesystem
|
215 |
*/
|
216 |
public function get_loader() {
|
217 |
+
$paths = array_merge($this->locations, array(ini_get('open_basedir') ? ABSPATH : '/'));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
$paths = apply_filters('timber/loader/paths', $paths);
|
219 |
+
return new \Twig_Loader_Filesystem($paths);
|
|
|
220 |
}
|
221 |
|
222 |
/**
|
223 |
+
* @return \Twig_Environment
|
224 |
*/
|
225 |
public function get_twig() {
|
226 |
$loader = $this->get_loader();
|
lib/Menu.php
CHANGED
@@ -9,7 +9,6 @@ use Timber\Post;
|
|
9 |
* In Timber, you can use TimberMenu() to make a standard Wordpress menu available to the Twig template as an object you can loop through. And once the menu becomes available to the context, you can get items from it in a way that is a little smoother and more versatile than Wordpress's wp_nav_menu. (You need never again rely on a crazy "Walker Function!"). The first thing to do is to initialize the menu using TimberMenu(). This will make the menu available as an object to work with in the context. (TimberMenu can include a Wordpress menu slug or ID, or it can be sent with no parameter--and guess the right menu.)
|
10 |
* @example
|
11 |
* ```php
|
12 |
-
* <?php
|
13 |
* # functions.php
|
14 |
* add_filter('timber/context', 'add_to_context');
|
15 |
* function add_to_context($data){
|
@@ -238,4 +237,4 @@ class Menu extends Core {
|
|
238 |
}
|
239 |
return array();
|
240 |
}
|
241 |
-
}
|
9 |
* In Timber, you can use TimberMenu() to make a standard Wordpress menu available to the Twig template as an object you can loop through. And once the menu becomes available to the context, you can get items from it in a way that is a little smoother and more versatile than Wordpress's wp_nav_menu. (You need never again rely on a crazy "Walker Function!"). The first thing to do is to initialize the menu using TimberMenu(). This will make the menu available as an object to work with in the context. (TimberMenu can include a Wordpress menu slug or ID, or it can be sent with no parameter--and guess the right menu.)
|
10 |
* @example
|
11 |
* ```php
|
|
|
12 |
* # functions.php
|
13 |
* add_filter('timber/context', 'add_to_context');
|
14 |
* function add_to_context($data){
|
237 |
}
|
238 |
return array();
|
239 |
}
|
240 |
+
}
|
lib/Post.php
CHANGED
@@ -19,7 +19,6 @@ use WP_Post;
|
|
19 |
* This is the object you use to access or extend WordPress posts. Think of it as Timber's (more accessible) version of WP_Post. This is used throughout Timber to represent posts retrieved from WordPress making them available to Twig templates. See the PHP and Twig examples for an example of what it's like to work with this object in your code.
|
20 |
* @example
|
21 |
* ```php
|
22 |
-
* <?php
|
23 |
* // single.php, see connected twig example
|
24 |
* $context = Timber::get_context();
|
25 |
* $context['post'] = new Timber\Post(); // It's a new Timber\Post object, but an existing post from WordPress.
|
@@ -48,7 +47,7 @@ use WP_Post;
|
|
48 |
* @package Timber
|
49 |
*/
|
50 |
class Post extends Core implements CoreInterface {
|
51 |
-
|
52 |
/**
|
53 |
* @var string $ImageClass the name of the class to handle images by default
|
54 |
*/
|
@@ -369,7 +368,7 @@ class Post extends Core implements CoreInterface {
|
|
369 |
* @return PostPreview
|
370 |
*/
|
371 |
public function preview() {
|
372 |
-
return new PostPreview(
|
373 |
}
|
374 |
|
375 |
/**
|
@@ -509,7 +508,7 @@ class Post extends Core implements CoreInterface {
|
|
509 |
return null;
|
510 |
}
|
511 |
|
512 |
-
do_action_ref_array(
|
513 |
|
514 |
$post->status = $post->post_status;
|
515 |
$post->id = $post->ID;
|
@@ -527,7 +526,7 @@ class Post extends Core implements CoreInterface {
|
|
527 |
* @return string of HTML for the form
|
528 |
*/
|
529 |
public function comment_form( $args = array() ) {
|
530 |
-
return Helper::get_comment_form(
|
531 |
}
|
532 |
|
533 |
|
@@ -622,10 +621,10 @@ class Post extends Core implements CoreInterface {
|
|
622 |
|
623 |
/**
|
624 |
* Returns the post_type object with labels and other info
|
625 |
-
*
|
626 |
* @deprecated since 1.0.4
|
627 |
* @example
|
628 |
-
*
|
629 |
* ```twig
|
630 |
* This post is from <span>{{ post.get_post_type.labels.plural }}</span>
|
631 |
* ```
|
@@ -655,7 +654,7 @@ class Post extends Core implements CoreInterface {
|
|
655 |
public function has_field( $field_name ) {
|
656 |
return (!$this->get_field( $field_name )) ? false : true;
|
657 |
}
|
658 |
-
|
659 |
|
660 |
/**
|
661 |
* @param string $field_name
|
@@ -900,7 +899,7 @@ class Post extends Core implements CoreInterface {
|
|
900 |
// Add child comments to the relative "super parents"
|
901 |
foreach ( $comments_tree as $comment_parent => $comment_children ) {
|
902 |
foreach ( $comment_children as $comment_child ) {
|
903 |
-
$timber_comments[$comment_parent]->add_child(
|
904 |
unset($timber_comments[$comment_child]);
|
905 |
}
|
906 |
}
|
@@ -1004,10 +1003,10 @@ class Post extends Core implements CoreInterface {
|
|
1004 |
|
1005 |
/**
|
1006 |
* Returns the post_type object with labels and other info
|
1007 |
-
*
|
1008 |
* @since 1.0.4
|
1009 |
* @example
|
1010 |
-
*
|
1011 |
* ```twig
|
1012 |
* This post is from <span>{{ post.type.labels.name }}</span>
|
1013 |
* ```
|
@@ -1029,7 +1028,7 @@ class Post extends Core implements CoreInterface {
|
|
1029 |
|
1030 |
/**
|
1031 |
* Returns the edit URL of a post if the user has access to it
|
1032 |
-
* @return bool|string the edit URL of a post in the WordPress admin
|
1033 |
*/
|
1034 |
public function edit_link() {
|
1035 |
if ( $this->can_edit() ) {
|
@@ -1286,12 +1285,12 @@ class Post extends Core implements CoreInterface {
|
|
1286 |
}
|
1287 |
|
1288 |
|
1289 |
-
/**
|
1290 |
*
|
1291 |
* ===================================
|
1292 |
* DEPRECATED FUNCTIONS LIVE DOWN HERE
|
1293 |
* ===================================
|
1294 |
-
*
|
1295 |
*/
|
1296 |
|
1297 |
/**
|
19 |
* This is the object you use to access or extend WordPress posts. Think of it as Timber's (more accessible) version of WP_Post. This is used throughout Timber to represent posts retrieved from WordPress making them available to Twig templates. See the PHP and Twig examples for an example of what it's like to work with this object in your code.
|
20 |
* @example
|
21 |
* ```php
|
|
|
22 |
* // single.php, see connected twig example
|
23 |
* $context = Timber::get_context();
|
24 |
* $context['post'] = new Timber\Post(); // It's a new Timber\Post object, but an existing post from WordPress.
|
47 |
* @package Timber
|
48 |
*/
|
49 |
class Post extends Core implements CoreInterface {
|
50 |
+
|
51 |
/**
|
52 |
* @var string $ImageClass the name of the class to handle images by default
|
53 |
*/
|
368 |
* @return PostPreview
|
369 |
*/
|
370 |
public function preview() {
|
371 |
+
return new PostPreview($this);
|
372 |
}
|
373 |
|
374 |
/**
|
508 |
return null;
|
509 |
}
|
510 |
|
511 |
+
do_action_ref_array('the_post', array(&$post, &$GLOBALS['wp_query']));
|
512 |
|
513 |
$post->status = $post->post_status;
|
514 |
$post->id = $post->ID;
|
526 |
* @return string of HTML for the form
|
527 |
*/
|
528 |
public function comment_form( $args = array() ) {
|
529 |
+
return Helper::get_comment_form($this->ID, $args);
|
530 |
}
|
531 |
|
532 |
|
621 |
|
622 |
/**
|
623 |
* Returns the post_type object with labels and other info
|
624 |
+
*
|
625 |
* @deprecated since 1.0.4
|
626 |
* @example
|
627 |
+
*
|
628 |
* ```twig
|
629 |
* This post is from <span>{{ post.get_post_type.labels.plural }}</span>
|
630 |
* ```
|
654 |
public function has_field( $field_name ) {
|
655 |
return (!$this->get_field( $field_name )) ? false : true;
|
656 |
}
|
657 |
+
|
658 |
|
659 |
/**
|
660 |
* @param string $field_name
|
899 |
// Add child comments to the relative "super parents"
|
900 |
foreach ( $comments_tree as $comment_parent => $comment_children ) {
|
901 |
foreach ( $comment_children as $comment_child ) {
|
902 |
+
$timber_comments[$comment_parent]->add_child($timber_comments[$comment_child]);
|
903 |
unset($timber_comments[$comment_child]);
|
904 |
}
|
905 |
}
|
1003 |
|
1004 |
/**
|
1005 |
* Returns the post_type object with labels and other info
|
1006 |
+
*
|
1007 |
* @since 1.0.4
|
1008 |
* @example
|
1009 |
+
*
|
1010 |
* ```twig
|
1011 |
* This post is from <span>{{ post.type.labels.name }}</span>
|
1012 |
* ```
|
1028 |
|
1029 |
/**
|
1030 |
* Returns the edit URL of a post if the user has access to it
|
1031 |
+
* @return bool|string the edit URL of a post in the WordPress admin
|
1032 |
*/
|
1033 |
public function edit_link() {
|
1034 |
if ( $this->can_edit() ) {
|
1285 |
}
|
1286 |
|
1287 |
|
1288 |
+
/**
|
1289 |
*
|
1290 |
* ===================================
|
1291 |
* DEPRECATED FUNCTIONS LIVE DOWN HERE
|
1292 |
* ===================================
|
1293 |
+
*
|
1294 |
*/
|
1295 |
|
1296 |
/**
|
lib/PostType.php
CHANGED
@@ -10,7 +10,7 @@ class PostType {
|
|
10 |
|
11 |
public function __construct( $post_type ) {
|
12 |
$this->slug = $post_type;
|
13 |
-
$this->init(
|
14 |
}
|
15 |
|
16 |
public function __toString() {
|
@@ -19,8 +19,8 @@ class PostType {
|
|
19 |
|
20 |
protected function init( $post_type ) {
|
21 |
$obj = get_post_type_object($post_type);
|
22 |
-
foreach (get_object_vars($obj) as $key => $value) {
|
23 |
-
if ( $key === '' || ord(
|
24 |
continue;
|
25 |
}
|
26 |
$this->$key = $value;
|
10 |
|
11 |
public function __construct( $post_type ) {
|
12 |
$this->slug = $post_type;
|
13 |
+
$this->init($post_type);
|
14 |
}
|
15 |
|
16 |
public function __toString() {
|
19 |
|
20 |
protected function init( $post_type ) {
|
21 |
$obj = get_post_type_object($post_type);
|
22 |
+
foreach ( get_object_vars($obj) as $key => $value ) {
|
23 |
+
if ( $key === '' || ord($key[0]) === 0 ) {
|
24 |
continue;
|
25 |
}
|
26 |
$this->$key = $value;
|
lib/Site.php
CHANGED
@@ -110,19 +110,22 @@ class Site extends Core implements CoreInterface {
|
|
110 |
* @param string|int $site_name_or_id
|
111 |
*/
|
112 |
public function __construct( $site_name_or_id = null ) {
|
113 |
-
$this->init();
|
114 |
if ( is_multisite() ) {
|
115 |
-
$
|
116 |
-
|
117 |
-
$this->
|
118 |
-
|
|
|
|
|
|
|
119 |
}
|
120 |
|
121 |
/**
|
122 |
-
*
|
123 |
-
* @param string|
|
|
|
124 |
*/
|
125 |
-
protected function
|
126 |
if ( $site_name_or_id === null ) {
|
127 |
//this is necessary for some reason, otherwise returns 1 all the time
|
128 |
if ( is_multisite() ) {
|
@@ -134,21 +137,25 @@ class Site extends Core implements CoreInterface {
|
|
134 |
$old_id = get_current_blog_id();
|
135 |
$info = get_blog_details($site_name_or_id);
|
136 |
switch_to_blog($info->blog_id);
|
|
|
|
|
137 |
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
$this->import($info);
|
139 |
$this->ID = $info->blog_id;
|
140 |
$this->id = $this->ID;
|
141 |
$this->name = $this->blogname;
|
142 |
$this->title = $this->blogname;
|
143 |
-
$this->url = get_bloginfo('url');
|
144 |
$theme_slug = get_blog_option($info->blog_id, 'stylesheet');
|
145 |
$this->theme = new Theme($theme_slug);
|
146 |
$this->description = get_blog_option($info->blog_id, 'blogdescription');
|
147 |
$this->admin_email = get_blog_option($info->blog_id, 'admin_email');
|
148 |
$this->multisite = true;
|
149 |
-
|
150 |
-
//switch back to the before time
|
151 |
-
switch_to_blog($old_id);
|
152 |
}
|
153 |
|
154 |
/**
|
@@ -160,7 +167,6 @@ class Site extends Core implements CoreInterface {
|
|
160 |
$this->name = get_bloginfo('name');
|
161 |
$this->title = $this->name;
|
162 |
$this->description = get_bloginfo('description');
|
163 |
-
$this->url = get_bloginfo('url');
|
164 |
$this->theme = new Theme();
|
165 |
$this->language_attributes = Helper::function_wrapper('language_attributes');
|
166 |
$this->multisite = false;
|
@@ -171,6 +177,7 @@ class Site extends Core implements CoreInterface {
|
|
171 |
* @internal
|
172 |
*/
|
173 |
protected function init() {
|
|
|
174 |
$this->rdf = get_bloginfo('rdf_url');
|
175 |
$this->rss = get_bloginfo('rss_url');
|
176 |
$this->rss2 = get_bloginfo('rss2_url');
|
110 |
* @param string|int $site_name_or_id
|
111 |
*/
|
112 |
public function __construct( $site_name_or_id = null ) {
|
|
|
113 |
if ( is_multisite() ) {
|
114 |
+
$blog_ids = self::switch_to_blog($site_name_or_id);
|
115 |
+
$this->init();
|
116 |
+
$this->init_as_multisite($blog_ids['new']);
|
117 |
+
return switch_to_blog($blog_ids['old']);
|
118 |
+
}
|
119 |
+
$this->init();
|
120 |
+
$this->init_as_singlesite();
|
121 |
}
|
122 |
|
123 |
/**
|
124 |
+
* Switches to the blog requested in the request
|
125 |
+
* @param string|integer|null $site_name_or_id
|
126 |
+
* @return array with the ID of the old and new blogs
|
127 |
*/
|
128 |
+
protected static function switch_to_blog( $site_name_or_id ) {
|
129 |
if ( $site_name_or_id === null ) {
|
130 |
//this is necessary for some reason, otherwise returns 1 all the time
|
131 |
if ( is_multisite() ) {
|
137 |
$old_id = get_current_blog_id();
|
138 |
$info = get_blog_details($site_name_or_id);
|
139 |
switch_to_blog($info->blog_id);
|
140 |
+
return array('old' => $old_id, 'new' => $info->blog_id);
|
141 |
+
}
|
142 |
|
143 |
+
/**
|
144 |
+
* @internal
|
145 |
+
* @param integer $site_id
|
146 |
+
*/
|
147 |
+
protected function init_as_multisite( $site_id ) {
|
148 |
+
$info = get_blog_details($site_id);
|
149 |
$this->import($info);
|
150 |
$this->ID = $info->blog_id;
|
151 |
$this->id = $this->ID;
|
152 |
$this->name = $this->blogname;
|
153 |
$this->title = $this->blogname;
|
|
|
154 |
$theme_slug = get_blog_option($info->blog_id, 'stylesheet');
|
155 |
$this->theme = new Theme($theme_slug);
|
156 |
$this->description = get_blog_option($info->blog_id, 'blogdescription');
|
157 |
$this->admin_email = get_blog_option($info->blog_id, 'admin_email');
|
158 |
$this->multisite = true;
|
|
|
|
|
|
|
159 |
}
|
160 |
|
161 |
/**
|
167 |
$this->name = get_bloginfo('name');
|
168 |
$this->title = $this->name;
|
169 |
$this->description = get_bloginfo('description');
|
|
|
170 |
$this->theme = new Theme();
|
171 |
$this->language_attributes = Helper::function_wrapper('language_attributes');
|
172 |
$this->multisite = false;
|
177 |
* @internal
|
178 |
*/
|
179 |
protected function init() {
|
180 |
+
$this->url = home_url();
|
181 |
$this->rdf = get_bloginfo('rdf_url');
|
182 |
$this->rss = get_bloginfo('rss_url');
|
183 |
$this->rss2 = get_bloginfo('rss2_url');
|
lib/TermGetter.php
CHANGED
@@ -12,8 +12,8 @@ class TermGetter {
|
|
12 |
* @return Timber\Term|WP_Error|null
|
13 |
*/
|
14 |
public static function get_term( $term, $taxonomy, $TermClass = 'Term' ) {
|
15 |
-
$term = get_term(
|
16 |
-
return new $TermClass(
|
17 |
}
|
18 |
|
19 |
/**
|
12 |
* @return Timber\Term|WP_Error|null
|
13 |
*/
|
14 |
public static function get_term( $term, $taxonomy, $TermClass = 'Term' ) {
|
15 |
+
$term = get_term($term, $taxonomy);
|
16 |
+
return new $TermClass($term->term_id, $term->taxonomy);
|
17 |
}
|
18 |
|
19 |
/**
|
lib/Timber.php
CHANGED
@@ -20,7 +20,8 @@ use Timber\Loader;
|
|
20 |
*
|
21 |
* Main class called Timber for this plugin.
|
22 |
*
|
23 |
-
*
|
|
|
24 |
* $posts = Timber::get_posts();
|
25 |
* $posts = Timber::get_posts('post_type = article')
|
26 |
* $posts = Timber::get_posts(array('post_type' => 'article', 'category_name' => 'sports')); // uses wp_query format.
|
@@ -29,12 +30,13 @@ use Timber\Loader;
|
|
29 |
* $context = Timber::get_context(); // returns wp favorites!
|
30 |
* $context['posts'] = $posts;
|
31 |
* Timber::render('index.twig', $context);
|
|
|
32 |
*/
|
33 |
class Timber {
|
34 |
|
35 |
public static $version = '1.0.3';
|
36 |
public static $locations;
|
37 |
-
public static $dirname;
|
38 |
public static $twig_cache = false;
|
39 |
public static $cache = false;
|
40 |
public static $auto_meta = true;
|
@@ -115,7 +117,7 @@ class Timber {
|
|
115 |
|
116 |
/**
|
117 |
* Get post.
|
118 |
-
*
|
119 |
* @param mixed $query
|
120 |
* @param string $PostClass
|
121 |
* @return array|bool|null
|
@@ -126,6 +128,7 @@ class Timber {
|
|
126 |
|
127 |
/**
|
128 |
* Get posts.
|
|
|
129 |
* @example
|
130 |
* ```php
|
131 |
* $posts = Timber::get_posts();
|
@@ -143,7 +146,7 @@ class Timber {
|
|
143 |
|
144 |
/**
|
145 |
* Query post.
|
146 |
-
*
|
147 |
* @param mixed $query
|
148 |
* @param string $PostClass
|
149 |
* @return array|bool|null
|
@@ -154,7 +157,7 @@ class Timber {
|
|
154 |
|
155 |
/**
|
156 |
* Query posts.
|
157 |
-
*
|
158 |
* @param mixed $query
|
159 |
* @param string $PostClass
|
160 |
* @return array|bool|null
|
@@ -168,7 +171,7 @@ class Timber {
|
|
168 |
|
169 |
/**
|
170 |
* Get terms.
|
171 |
-
*
|
172 |
* @param string|array $args
|
173 |
* @param array $maybe_args
|
174 |
* @param string $TermClass
|
@@ -180,13 +183,13 @@ class Timber {
|
|
180 |
|
181 |
/**
|
182 |
* Get term.
|
183 |
-
*
|
184 |
* @param int|WP_Term|object $term
|
185 |
* @param string $taxonomy
|
186 |
* @return Timber\Term|WP_Error|null
|
187 |
*/
|
188 |
public static function get_term( $term, $taxonomy = 'post_tag', $TermClass = 'Timber\Term' ) {
|
189 |
-
return TermGetter::get_term(
|
190 |
}
|
191 |
|
192 |
/* Site Retrieval
|
@@ -194,7 +197,7 @@ class Timber {
|
|
194 |
|
195 |
/**
|
196 |
* Get sites.
|
197 |
-
*
|
198 |
* @param array|bool $blog_ids
|
199 |
* @return array
|
200 |
*/
|
@@ -216,7 +219,7 @@ class Timber {
|
|
216 |
|
217 |
/**
|
218 |
* Get context.
|
219 |
-
*
|
220 |
* @return array
|
221 |
*/
|
222 |
public static function get_context() {
|
@@ -245,7 +248,7 @@ class Timber {
|
|
245 |
|
246 |
/**
|
247 |
* Compile function.
|
248 |
-
*
|
249 |
* @param array $filenames
|
250 |
* @param array $data
|
251 |
* @param bool $expires
|
@@ -280,7 +283,7 @@ class Timber {
|
|
280 |
|
281 |
/**
|
282 |
* Compile string.
|
283 |
-
*
|
284 |
* @param string $string a string with twig variables.
|
285 |
* @param array $data an array with data in it.
|
286 |
* @return bool|string
|
@@ -294,7 +297,7 @@ class Timber {
|
|
294 |
|
295 |
/**
|
296 |
* Fetch function.
|
297 |
-
*
|
298 |
* @param array $filenames
|
299 |
* @param array $data
|
300 |
* @param bool $expires
|
@@ -315,7 +318,7 @@ class Timber {
|
|
315 |
|
316 |
/**
|
317 |
* Render function.
|
318 |
-
*
|
319 |
* @param array $filenames
|
320 |
* @param array $data
|
321 |
* @param bool $expires
|
@@ -330,7 +333,7 @@ class Timber {
|
|
330 |
|
331 |
/**
|
332 |
* Render string.
|
333 |
-
*
|
334 |
* @param string $string a string with twig variables.
|
335 |
* @param array $data an array with data in it.
|
336 |
* @return bool|string
|
@@ -347,7 +350,7 @@ class Timber {
|
|
347 |
|
348 |
/**
|
349 |
* Get sidebar.
|
350 |
-
*
|
351 |
* @param string $sidebar
|
352 |
* @param array $data
|
353 |
* @return bool|string
|
@@ -364,7 +367,7 @@ class Timber {
|
|
364 |
|
365 |
/**
|
366 |
* Get sidebar from PHP
|
367 |
-
*
|
368 |
* @param string $sidebar
|
369 |
* @param array $data
|
370 |
* @return string
|
@@ -395,7 +398,7 @@ class Timber {
|
|
395 |
|
396 |
/**
|
397 |
* Get widgets.
|
398 |
-
*
|
399 |
* @param int $widget_id
|
400 |
* @return TimberFunctionWrapper
|
401 |
*/
|
@@ -408,7 +411,7 @@ class Timber {
|
|
408 |
|
409 |
/**
|
410 |
* Get pagination.
|
411 |
-
*
|
412 |
* @param array $prefs
|
413 |
* @return array mixed
|
414 |
*/
|
@@ -442,14 +445,27 @@ class Timber {
|
|
442 |
$data['current'] = $args['current'];
|
443 |
$data['total'] = $args['total'];
|
444 |
$data['pages'] = Helper::paginate_links($args);
|
445 |
-
|
446 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
447 |
// set next and prev using pages array generated by paginate links
|
448 |
-
if ( isset(
|
449 |
-
$data['next'] = array('link' => untrailingslashit(
|
450 |
}
|
451 |
-
if ( isset(
|
452 |
-
$data['prev'] = array('link' => untrailingslashit(
|
453 |
}
|
454 |
if ( $paged < 2 ) {
|
455 |
$data['prev'] = '';
|
@@ -465,7 +481,7 @@ class Timber {
|
|
465 |
|
466 |
/**
|
467 |
* Get calling script dir.
|
468 |
-
*
|
469 |
* @return string
|
470 |
*/
|
471 |
public static function get_calling_script_dir( $offset = 0 ) {
|
@@ -493,7 +509,7 @@ class Timber {
|
|
493 |
|
494 |
/**
|
495 |
* Get calling script file.
|
496 |
-
*
|
497 |
* @param int $offset
|
498 |
* @return string|null
|
499 |
* @deprecated since 0.20.0
|
20 |
*
|
21 |
* Main class called Timber for this plugin.
|
22 |
*
|
23 |
+
* @example
|
24 |
+
* ```php
|
25 |
* $posts = Timber::get_posts();
|
26 |
* $posts = Timber::get_posts('post_type = article')
|
27 |
* $posts = Timber::get_posts(array('post_type' => 'article', 'category_name' => 'sports')); // uses wp_query format.
|
30 |
* $context = Timber::get_context(); // returns wp favorites!
|
31 |
* $context['posts'] = $posts;
|
32 |
* Timber::render('index.twig', $context);
|
33 |
+
* ```
|
34 |
*/
|
35 |
class Timber {
|
36 |
|
37 |
public static $version = '1.0.3';
|
38 |
public static $locations;
|
39 |
+
public static $dirname = 'views';
|
40 |
public static $twig_cache = false;
|
41 |
public static $cache = false;
|
42 |
public static $auto_meta = true;
|
117 |
|
118 |
/**
|
119 |
* Get post.
|
120 |
+
* @api
|
121 |
* @param mixed $query
|
122 |
* @param string $PostClass
|
123 |
* @return array|bool|null
|
128 |
|
129 |
/**
|
130 |
* Get posts.
|
131 |
+
* @api
|
132 |
* @example
|
133 |
* ```php
|
134 |
* $posts = Timber::get_posts();
|
146 |
|
147 |
/**
|
148 |
* Query post.
|
149 |
+
* @api
|
150 |
* @param mixed $query
|
151 |
* @param string $PostClass
|
152 |
* @return array|bool|null
|
157 |
|
158 |
/**
|
159 |
* Query posts.
|
160 |
+
* @api
|
161 |
* @param mixed $query
|
162 |
* @param string $PostClass
|
163 |
* @return array|bool|null
|
171 |
|
172 |
/**
|
173 |
* Get terms.
|
174 |
+
* @api
|
175 |
* @param string|array $args
|
176 |
* @param array $maybe_args
|
177 |
* @param string $TermClass
|
183 |
|
184 |
/**
|
185 |
* Get term.
|
186 |
+
* @api
|
187 |
* @param int|WP_Term|object $term
|
188 |
* @param string $taxonomy
|
189 |
* @return Timber\Term|WP_Error|null
|
190 |
*/
|
191 |
public static function get_term( $term, $taxonomy = 'post_tag', $TermClass = 'Timber\Term' ) {
|
192 |
+
return TermGetter::get_term($term, $taxonomy, $TermClass);
|
193 |
}
|
194 |
|
195 |
/* Site Retrieval
|
197 |
|
198 |
/**
|
199 |
* Get sites.
|
200 |
+
* @api
|
201 |
* @param array|bool $blog_ids
|
202 |
* @return array
|
203 |
*/
|
219 |
|
220 |
/**
|
221 |
* Get context.
|
222 |
+
* @api
|
223 |
* @return array
|
224 |
*/
|
225 |
public static function get_context() {
|
248 |
|
249 |
/**
|
250 |
* Compile function.
|
251 |
+
* @api
|
252 |
* @param array $filenames
|
253 |
* @param array $data
|
254 |
* @param bool $expires
|
283 |
|
284 |
/**
|
285 |
* Compile string.
|
286 |
+
* @api
|
287 |
* @param string $string a string with twig variables.
|
288 |
* @param array $data an array with data in it.
|
289 |
* @return bool|string
|
297 |
|
298 |
/**
|
299 |
* Fetch function.
|
300 |
+
* @api
|
301 |
* @param array $filenames
|
302 |
* @param array $data
|
303 |
* @param bool $expires
|
318 |
|
319 |
/**
|
320 |
* Render function.
|
321 |
+
* @api
|
322 |
* @param array $filenames
|
323 |
* @param array $data
|
324 |
* @param bool $expires
|
333 |
|
334 |
/**
|
335 |
* Render string.
|
336 |
+
* @api
|
337 |
* @param string $string a string with twig variables.
|
338 |
* @param array $data an array with data in it.
|
339 |
* @return bool|string
|
350 |
|
351 |
/**
|
352 |
* Get sidebar.
|
353 |
+
* @api
|
354 |
* @param string $sidebar
|
355 |
* @param array $data
|
356 |
* @return bool|string
|
367 |
|
368 |
/**
|
369 |
* Get sidebar from PHP
|
370 |
+
* @api
|
371 |
* @param string $sidebar
|
372 |
* @param array $data
|
373 |
* @return string
|
398 |
|
399 |
/**
|
400 |
* Get widgets.
|
401 |
+
* @api
|
402 |
* @param int $widget_id
|
403 |
* @return TimberFunctionWrapper
|
404 |
*/
|
411 |
|
412 |
/**
|
413 |
* Get pagination.
|
414 |
+
* @api
|
415 |
* @param array $prefs
|
416 |
* @return array mixed
|
417 |
*/
|
445 |
$data['current'] = $args['current'];
|
446 |
$data['total'] = $args['total'];
|
447 |
$data['pages'] = Helper::paginate_links($args);
|
448 |
+
|
449 |
+
if ( $data['total'] <= count($data['pages']) ) {
|
450 |
+
// decrement current so that it matches up with the 0 based index used by the pages array
|
451 |
+
$current = $data['current'] - 1;
|
452 |
+
}
|
453 |
+
// $data['current'] can't be used b/c there are more than 10 pages and we are condensing with dots
|
454 |
+
else {
|
455 |
+
foreach ( $data['pages'] as $key => $page ) {
|
456 |
+
if ( !empty($page['current']) ) {
|
457 |
+
$current = $key;
|
458 |
+
break;
|
459 |
+
}
|
460 |
+
}
|
461 |
+
}
|
462 |
+
|
463 |
// set next and prev using pages array generated by paginate links
|
464 |
+
if ( isset($data['pages'][$current + 1]) ) {
|
465 |
+
$data['next'] = array('link' => untrailingslashit($data['pages'][$current + 1]['link']), 'class' => 'page-numbers next');
|
466 |
}
|
467 |
+
if ( isset($data['pages'][$current - 1]) ) {
|
468 |
+
$data['prev'] = array('link' => untrailingslashit($data['pages'][$current - 1]['link']), 'class' => 'page-numbers prev');
|
469 |
}
|
470 |
if ( $paged < 2 ) {
|
471 |
$data['prev'] = '';
|
481 |
|
482 |
/**
|
483 |
* Get calling script dir.
|
484 |
+
* @api
|
485 |
* @return string
|
486 |
*/
|
487 |
public static function get_calling_script_dir( $offset = 0 ) {
|
509 |
|
510 |
/**
|
511 |
* Get calling script file.
|
512 |
+
* @api
|
513 |
* @param int $offset
|
514 |
* @return string|null
|
515 |
* @deprecated since 0.20.0
|
lib/Twig.php
CHANGED
@@ -271,7 +271,7 @@ class Twig {
|
|
271 |
|
272 |
if ( $date instanceof \DateTime ) {
|
273 |
$timestamp = $date->getTimestamp() + $date->getOffset();
|
274 |
-
} else if ( is_numeric($date) && strtotime($date) === false ) {
|
275 |
$timestamp = intval($date);
|
276 |
} else {
|
277 |
$timestamp = strtotime($date);
|
271 |
|
272 |
if ( $date instanceof \DateTime ) {
|
273 |
$timestamp = $date->getTimestamp() + $date->getOffset();
|
274 |
+
} else if ( is_numeric($date) && (strtotime($date) === false || strlen($date) !== 8) ) {
|
275 |
$timestamp = intval($date);
|
276 |
} else {
|
277 |
$timestamp = strtotime($date);
|
lib/User.php
CHANGED
@@ -142,6 +142,7 @@ class User extends Core implements CoreInterface {
|
|
142 |
$this->import($data);
|
143 |
}
|
144 |
}
|
|
|
145 |
$this->id = $this->ID;
|
146 |
$this->name = $this->name();
|
147 |
$this->avatar = new Image(get_avatar_url($this->id));
|
@@ -228,4 +229,4 @@ class User extends Core implements CoreInterface {
|
|
228 |
public function slug() {
|
229 |
return $this->user_nicename;
|
230 |
}
|
231 |
-
}
|
142 |
$this->import($data);
|
143 |
}
|
144 |
}
|
145 |
+
unset($this->user_pass);
|
146 |
$this->id = $this->ID;
|
147 |
$this->name = $this->name();
|
148 |
$this->avatar = new Image(get_avatar_url($this->id));
|
229 |
public function slug() {
|
230 |
return $this->user_nicename;
|
231 |
}
|
232 |
+
}
|
readme.txt
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
Contributors: jarednova, connorjburton, lggorman
|
3 |
Tags: template engine, templates, twig
|
4 |
Requires at least: 3.7
|
5 |
-
Stable tag: 1.0
|
6 |
Tested up to: 4.5.1
|
7 |
PHP version: 5.3.0 or greater
|
8 |
License: GPLv2 or later
|
@@ -41,6 +41,14 @@ Timber is great for any WordPress developer who cares about writing good, mainta
|
|
41 |
|
42 |
== Changelog ==
|
43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
= 1.0.5 =
|
45 |
* Restored prior `{{ post.type }}` behavior for existing custom fields (@jarednova) 6c9574912e526b8589eb134b79820c7e239a1dda
|
46 |
* Fixed errors in PHP 7 (@FlyingDR) 48ba0fc125c2d19eeb0de0a895a83a9d3bb5a398
|
2 |
Contributors: jarednova, connorjburton, lggorman
|
3 |
Tags: template engine, templates, twig
|
4 |
Requires at least: 3.7
|
5 |
+
Stable tag: 1.1.0
|
6 |
Tested up to: 4.5.1
|
7 |
PHP version: 5.3.0 or greater
|
8 |
License: GPLv2 or later
|
41 |
|
42 |
== Changelog ==
|
43 |
|
44 |
+
= 1.1.0 =
|
45 |
+
* Fixed how Timber loads with Composer (thanks @connorjburton and @mrgrain)
|
46 |
+
* Updated docs! (thanks @lggorman and @kateboudreau)
|
47 |
+
* Fixed ImageHelper paths (thanks @TuureKaunisto)
|
48 |
+
* Added new filters for render (thanks @johnbillion)
|
49 |
+
* Fixed issue with timestamp conversion (thanks @thedamon)
|
50 |
+
* Fixed localization bugs (thanks @FlyingDR)
|
51 |
+
|
52 |
= 1.0.5 =
|
53 |
* Restored prior `{{ post.type }}` behavior for existing custom fields (@jarednova) 6c9574912e526b8589eb134b79820c7e239a1dda
|
54 |
* Fixed errors in PHP 7 (@FlyingDR) 48ba0fc125c2d19eeb0de0a895a83a9d3bb5a398
|
timber-starter-theme/templates/menu.twig
CHANGED
@@ -1,8 +1,10 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
<
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
|
|
|
1 |
+
{% if menu %}
|
2 |
+
<ul>
|
3 |
+
{% for item in menu %}
|
4 |
+
<li class="{{item.classes | join(' ')}}">
|
5 |
+
<a href="{{item.get_link}}">{{item.title}}</a>
|
6 |
+
{% include "menu.twig" with {'menu': item.get_children} %}
|
7 |
+
</li>
|
8 |
+
{% endfor %}
|
9 |
+
</ul>
|
10 |
+
{% endif %}
|
timber.php
CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Timber
|
|
4 |
Description: The WordPress Timber Library allows you to write themes using the power Twig templates.
|
5 |
Plugin URI: http://timber.upstatement.com
|
6 |
Author: Jared Novack + Upstatement
|
7 |
-
Version: 1.0
|
8 |
Author URI: http://upstatement.com/
|
9 |
*/
|
10 |
// we look for Composer files first in the plugins dir.
|
@@ -18,3 +18,4 @@ if ( file_exists( $composer_autoload = __DIR__ . '/vendor/autoload.php' ) /* che
|
|
18 |
) {
|
19 |
require_once $composer_autoload;
|
20 |
}
|
|
4 |
Description: The WordPress Timber Library allows you to write themes using the power Twig templates.
|
5 |
Plugin URI: http://timber.upstatement.com
|
6 |
Author: Jared Novack + Upstatement
|
7 |
+
Version: 1.1.0
|
8 |
Author URI: http://upstatement.com/
|
9 |
*/
|
10 |
// we look for Composer files first in the plugins dir.
|
18 |
) {
|
19 |
require_once $composer_autoload;
|
20 |
}
|
21 |
+
new \Timber\Timber;
|
vendor/autoload.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInita33a0f094141597796f7eb9432c529a9::getLoader();
|
vendor/composer/autoload_files.php
DELETED
@@ -1,10 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
// autoload_files.php @generated by Composer
|
4 |
-
|
5 |
-
$vendorDir = dirname(dirname(__FILE__));
|
6 |
-
$baseDir = dirname($vendorDir);
|
7 |
-
|
8 |
-
return array(
|
9 |
-
'cb78221880aa21d756cc44a8539bb425' => $baseDir . '/init.php',
|
10 |
-
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/composer/autoload_real.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
-
class
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
@@ -19,9 +19,9 @@ class ComposerAutoloaderInitcb7cd3f591a5a00a4b4ac0d8e060a51d
|
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
-
spl_autoload_register(array('
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
-
spl_autoload_unregister(array('
|
25 |
|
26 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
27 |
foreach ($map as $namespace => $path) {
|
@@ -40,20 +40,6 @@ class ComposerAutoloaderInitcb7cd3f591a5a00a4b4ac0d8e060a51d
|
|
40 |
|
41 |
$loader->register(true);
|
42 |
|
43 |
-
$includeFiles = require __DIR__ . '/autoload_files.php';
|
44 |
-
foreach ($includeFiles as $fileIdentifier => $file) {
|
45 |
-
composerRequirecb7cd3f591a5a00a4b4ac0d8e060a51d($fileIdentifier, $file);
|
46 |
-
}
|
47 |
-
|
48 |
return $loader;
|
49 |
}
|
50 |
}
|
51 |
-
|
52 |
-
function composerRequirecb7cd3f591a5a00a4b4ac0d8e060a51d($fileIdentifier, $file)
|
53 |
-
{
|
54 |
-
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
55 |
-
require $file;
|
56 |
-
|
57 |
-
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
58 |
-
}
|
59 |
-
}
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInita33a0f094141597796f7eb9432c529a9
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
+
spl_autoload_register(array('ComposerAutoloaderInita33a0f094141597796f7eb9432c529a9', 'loadClassLoader'), true, true);
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
+
spl_autoload_unregister(array('ComposerAutoloaderInita33a0f094141597796f7eb9432c529a9', 'loadClassLoader'));
|
25 |
|
26 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
27 |
foreach ($map as $namespace => $path) {
|
40 |
|
41 |
$loader->register(true);
|
42 |
|
|
|
|
|
|
|
|
|
|
|
43 |
return $loader;
|
44 |
}
|
45 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/composer/installed.json
CHANGED
@@ -103,17 +103,17 @@
|
|
103 |
},
|
104 |
{
|
105 |
"name": "twig/twig",
|
106 |
-
"version": "v1.24.
|
107 |
-
"version_normalized": "1.24.
|
108 |
"source": {
|
109 |
"type": "git",
|
110 |
"url": "https://github.com/twigphp/Twig.git",
|
111 |
-
"reference": "
|
112 |
},
|
113 |
"dist": {
|
114 |
"type": "zip",
|
115 |
-
"url": "https://api.github.com/repos/twigphp/Twig/zipball/
|
116 |
-
"reference": "
|
117 |
"shasum": ""
|
118 |
},
|
119 |
"require": {
|
@@ -123,7 +123,7 @@
|
|
123 |
"symfony/debug": "~2.7",
|
124 |
"symfony/phpunit-bridge": "~2.7"
|
125 |
},
|
126 |
-
"time": "2016-
|
127 |
"type": "library",
|
128 |
"extra": {
|
129 |
"branch-alias": {
|
103 |
},
|
104 |
{
|
105 |
"name": "twig/twig",
|
106 |
+
"version": "v1.24.1",
|
107 |
+
"version_normalized": "1.24.1.0",
|
108 |
"source": {
|
109 |
"type": "git",
|
110 |
"url": "https://github.com/twigphp/Twig.git",
|
111 |
+
"reference": "3566d311a92aae4deec6e48682dc5a4528c4a512"
|
112 |
},
|
113 |
"dist": {
|
114 |
"type": "zip",
|
115 |
+
"url": "https://api.github.com/repos/twigphp/Twig/zipball/3566d311a92aae4deec6e48682dc5a4528c4a512",
|
116 |
+
"reference": "3566d311a92aae4deec6e48682dc5a4528c4a512",
|
117 |
"shasum": ""
|
118 |
},
|
119 |
"require": {
|
123 |
"symfony/debug": "~2.7",
|
124 |
"symfony/phpunit-bridge": "~2.7"
|
125 |
},
|
126 |
+
"time": "2016-05-30 09:11:59",
|
127 |
"type": "library",
|
128 |
"extra": {
|
129 |
"branch-alias": {
|
vendor/twig/twig/CHANGELOG
CHANGED
@@ -1,3 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
* 1.24.0 (2016-01-25)
|
2 |
|
3 |
* adding support for the ?? operator
|
1 |
+
* 1.24.1 (2016-05-30)
|
2 |
+
|
3 |
+
* fixed reserved keywords (forbids true, false, null and none keywords for variables names)
|
4 |
+
* fixed support for PHP7 (Throwable support)
|
5 |
+
* marked the following methods as being internals on Twig_Environment:
|
6 |
+
getFunctions(), getFilters(), getTests(), getFunction(), getFilter(), getTest(),
|
7 |
+
getTokenParsers(), getTags(), getNodeVisitors(), getUnaryOperators(), getBinaryOperators(),
|
8 |
+
getFunctions(), getFilters(), getGlobals(), initGlobals(), initExtensions(), and initExtension()
|
9 |
+
|
10 |
* 1.24.0 (2016-01-25)
|
11 |
|
12 |
* adding support for the ?? operator
|
vendor/twig/twig/doc/advanced.rst
CHANGED
@@ -659,7 +659,7 @@ Globals
|
|
659 |
Global variables can be registered in an extension via the ``getGlobals()``
|
660 |
method::
|
661 |
|
662 |
-
class Project_Twig_Extension extends Twig_Extension
|
663 |
{
|
664 |
public function getGlobals()
|
665 |
{
|
659 |
Global variables can be registered in an extension via the ``getGlobals()``
|
660 |
method::
|
661 |
|
662 |
+
class Project_Twig_Extension extends Twig_Extension implements Twig_Extension_GlobalsInterface
|
663 |
{
|
664 |
public function getGlobals()
|
665 |
{
|
vendor/twig/twig/doc/intro.rst
CHANGED
@@ -19,11 +19,11 @@ The key-features are...
|
|
19 |
may modify the template design.
|
20 |
|
21 |
* *Flexible*: Twig is powered by a flexible lexer and parser. This allows the
|
22 |
-
developer to define
|
23 |
|
24 |
Twig is used by many Open-Source projects like Symfony, Drupal8, eZPublish,
|
25 |
-
phpBB, Piwik, OroCRM
|
26 |
-
Slim, Yii, Laravel, Codeigniter
|
27 |
|
28 |
Prerequisites
|
29 |
-------------
|
19 |
may modify the template design.
|
20 |
|
21 |
* *Flexible*: Twig is powered by a flexible lexer and parser. This allows the
|
22 |
+
developer to define their own custom tags and filters, and to create their own DSL.
|
23 |
|
24 |
Twig is used by many Open-Source projects like Symfony, Drupal8, eZPublish,
|
25 |
+
phpBB, Piwik, OroCRM; and many frameworks have support for it as well like
|
26 |
+
Slim, Yii, Laravel, Codeigniter and Kohana — just to name a few.
|
27 |
|
28 |
Prerequisites
|
29 |
-------------
|
vendor/twig/twig/doc/recipes.rst
CHANGED
@@ -280,7 +280,7 @@ For functions, use ``registerUndefinedFunctionCallback()``::
|
|
280 |
// don't try this at home as it's not secure at all!
|
281 |
$twig->registerUndefinedFunctionCallback(function ($name) {
|
282 |
if (function_exists($name)) {
|
283 |
-
return new
|
284 |
}
|
285 |
|
286 |
return false;
|
@@ -499,7 +499,7 @@ Loading a Template from a String
|
|
499 |
|
500 |
From a template, you can easily load a template stored in a string via the
|
501 |
``template_from_string`` function (available as of Twig 1.11 via the
|
502 |
-
``Twig_Extension_StringLoader`` extension)
|
503 |
|
504 |
.. code-block:: jinja
|
505 |
|
280 |
// don't try this at home as it's not secure at all!
|
281 |
$twig->registerUndefinedFunctionCallback(function ($name) {
|
282 |
if (function_exists($name)) {
|
283 |
+
return new Twig_SimpleFunction($name, $name);
|
284 |
}
|
285 |
|
286 |
return false;
|
499 |
|
500 |
From a template, you can easily load a template stored in a string via the
|
501 |
``template_from_string`` function (available as of Twig 1.11 via the
|
502 |
+
``Twig_Extension_StringLoader`` extension):
|
503 |
|
504 |
.. code-block:: jinja
|
505 |
|
vendor/twig/twig/doc/tags/extends.rst
CHANGED
@@ -131,8 +131,8 @@ to variables from outer scopes:
|
|
131 |
Block Shortcuts
|
132 |
---------------
|
133 |
|
134 |
-
For blocks with
|
135 |
-
following constructs do the same:
|
136 |
|
137 |
.. code-block:: jinja
|
138 |
|
131 |
Block Shortcuts
|
132 |
---------------
|
133 |
|
134 |
+
For blocks with little content, it's possible to use a shortcut syntax. The
|
135 |
+
following constructs do the same thing:
|
136 |
|
137 |
.. code-block:: jinja
|
138 |
|
vendor/twig/twig/doc/templates.rst
CHANGED
@@ -293,25 +293,24 @@ designers or yourself:
|
|
293 |
Including other Templates
|
294 |
-------------------------
|
295 |
|
296 |
-
The :doc:`include<
|
297 |
-
return the rendered content of that template into the current one:
|
298 |
|
299 |
.. code-block:: jinja
|
300 |
|
301 |
-
{
|
302 |
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
in the template:
|
307 |
|
308 |
.. code-block:: jinja
|
309 |
|
310 |
{% for box in boxes %}
|
311 |
-
{
|
312 |
{% endfor %}
|
313 |
|
314 |
-
The included template ``render_box.html`` is able to access ``box
|
315 |
|
316 |
The filename of the template depends on the template loader. For instance, the
|
317 |
``Twig_Loader_Filesystem`` allows you to access other templates by giving the
|
@@ -319,7 +318,7 @@ filename. You can access templates in subdirectories with a slash:
|
|
319 |
|
320 |
.. code-block:: jinja
|
321 |
|
322 |
-
{
|
323 |
|
324 |
This behavior depends on the application embedding Twig.
|
325 |
|
@@ -587,7 +586,9 @@ exist:
|
|
587 |
string. They are useful whenever you need a string in the template (for
|
588 |
example as arguments to function calls, filters or just to extend or include
|
589 |
a template). A string can contain a delimiter if it is preceded by a
|
590 |
-
backslash (``\``) -- like in ``'It\'s good'``.
|
|
|
|
|
591 |
|
592 |
* ``42`` / ``42.23``: Integers and floating point numbers are created by just
|
593 |
writing the number down. If a dot is present the number is a float,
|
@@ -821,7 +822,7 @@ String Interpolation
|
|
821 |
.. versionadded:: 1.5
|
822 |
String interpolation was added in Twig 1.5.
|
823 |
|
824 |
-
String interpolation (
|
825 |
within a *double-quoted string*. The result of evaluating that expression is
|
826 |
inserted into the string:
|
827 |
|
@@ -869,7 +870,7 @@ leading and or trailing whitespace:
|
|
869 |
{# output 'no spaces' #}
|
870 |
|
871 |
The above sample shows the default whitespace control modifier, and how you can
|
872 |
-
use it to remove whitespace around tags.
|
873 |
for that side of the tag. It is possible to use whitespace trimming on one side
|
874 |
of a tag:
|
875 |
|
293 |
Including other Templates
|
294 |
-------------------------
|
295 |
|
296 |
+
The :doc:`include<functions/include>` function is useful to include a template
|
297 |
+
and return the rendered content of that template into the current one:
|
298 |
|
299 |
.. code-block:: jinja
|
300 |
|
301 |
+
{{ include('sidebar.html') }}
|
302 |
|
303 |
+
By default, included templates have access to the same context as the template
|
304 |
+
which includes them. This means that any variable defined in the main template
|
305 |
+
will be available in the included template too:
|
|
|
306 |
|
307 |
.. code-block:: jinja
|
308 |
|
309 |
{% for box in boxes %}
|
310 |
+
{{ include('render_box.html') }}
|
311 |
{% endfor %}
|
312 |
|
313 |
+
The included template ``render_box.html`` is able to access the ``box`` variable.
|
314 |
|
315 |
The filename of the template depends on the template loader. For instance, the
|
316 |
``Twig_Loader_Filesystem`` allows you to access other templates by giving the
|
318 |
|
319 |
.. code-block:: jinja
|
320 |
|
321 |
+
{{ include('sections/articles/sidebar.html') }}
|
322 |
|
323 |
This behavior depends on the application embedding Twig.
|
324 |
|
586 |
string. They are useful whenever you need a string in the template (for
|
587 |
example as arguments to function calls, filters or just to extend or include
|
588 |
a template). A string can contain a delimiter if it is preceded by a
|
589 |
+
backslash (``\``) -- like in ``'It\'s good'``. If the string contains a
|
590 |
+
backslash (e.g. ``'c:\Program Files'``) escape it by doubling it
|
591 |
+
(e.g. ``'c:\\Program Files'``).
|
592 |
|
593 |
* ``42`` / ``42.23``: Integers and floating point numbers are created by just
|
594 |
writing the number down. If a dot is present the number is a float,
|
822 |
.. versionadded:: 1.5
|
823 |
String interpolation was added in Twig 1.5.
|
824 |
|
825 |
+
String interpolation (``#{expression}``) allows any valid expression to appear
|
826 |
within a *double-quoted string*. The result of evaluating that expression is
|
827 |
inserted into the string:
|
828 |
|
870 |
{# output 'no spaces' #}
|
871 |
|
872 |
The above sample shows the default whitespace control modifier, and how you can
|
873 |
+
use it to remove whitespace around tags. Trimming space will consume all whitespace
|
874 |
for that side of the tag. It is possible to use whitespace trimming on one side
|
875 |
of a tag:
|
876 |
|
vendor/twig/twig/ext/twig/php_twig.h
CHANGED
@@ -15,7 +15,7 @@
|
|
15 |
#ifndef PHP_TWIG_H
|
16 |
#define PHP_TWIG_H
|
17 |
|
18 |
-
#define PHP_TWIG_VERSION "1.24.
|
19 |
|
20 |
#include "php.h"
|
21 |
|
15 |
#ifndef PHP_TWIG_H
|
16 |
#define PHP_TWIG_H
|
17 |
|
18 |
+
#define PHP_TWIG_VERSION "1.24.1"
|
19 |
|
20 |
#include "php.h"
|
21 |
|
vendor/twig/twig/ext/twig/twig.c
CHANGED
@@ -1040,7 +1040,7 @@ PHP_FUNCTION(twig_template_get_attributes)
|
|
1040 |
efree(item);
|
1041 |
return;
|
1042 |
}
|
1043 |
-
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "
|
1044 |
efree(item);
|
1045 |
return;
|
1046 |
}
|
1040 |
efree(item);
|
1041 |
return;
|
1042 |
}
|
1043 |
+
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Neither the property \"%s\" nor one of the methods \"%s()\", \"get%s()\"/\"is%s()\" or \"__call()\" exist and have public access in class \"%s\"", item, item, item, item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
|
1044 |
efree(item);
|
1045 |
return;
|
1046 |
}
|
vendor/twig/twig/lib/Twig/Environment.php
CHANGED
@@ -16,7 +16,7 @@
|
|
16 |
*/
|
17 |
class Twig_Environment
|
18 |
{
|
19 |
-
const VERSION = '1.24.
|
20 |
|
21 |
protected $charset;
|
22 |
protected $loader;
|
@@ -438,6 +438,10 @@ class Twig_Environment
|
|
438 |
} catch (Exception $e) {
|
439 |
$this->setLoader($current);
|
440 |
|
|
|
|
|
|
|
|
|
441 |
throw $e;
|
442 |
}
|
443 |
$this->setLoader($current);
|
@@ -855,6 +859,8 @@ class Twig_Environment
|
|
855 |
* Gets the registered Token Parsers.
|
856 |
*
|
857 |
* @return Twig_TokenParserBrokerInterface A broker containing token parsers
|
|
|
|
|
858 |
*/
|
859 |
public function getTokenParsers()
|
860 |
{
|
@@ -871,6 +877,8 @@ class Twig_Environment
|
|
871 |
* Be warned that this method cannot return tags defined by Twig_TokenParserBrokerInterface classes.
|
872 |
*
|
873 |
* @return Twig_TokenParserInterface[] An array of Twig_TokenParserInterface instances
|
|
|
|
|
874 |
*/
|
875 |
public function getTags()
|
876 |
{
|
@@ -902,6 +910,8 @@ class Twig_Environment
|
|
902 |
* Gets the registered Node Visitors.
|
903 |
*
|
904 |
* @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
|
|
|
|
|
905 |
*/
|
906 |
public function getNodeVisitors()
|
907 |
{
|
@@ -947,6 +957,8 @@ class Twig_Environment
|
|
947 |
* @param string $name The filter name
|
948 |
*
|
949 |
* @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exist
|
|
|
|
|
950 |
*/
|
951 |
public function getFilter($name)
|
952 |
{
|
@@ -993,6 +1005,8 @@ class Twig_Environment
|
|
993 |
* @return Twig_FilterInterface[] An array of Twig_FilterInterface instances
|
994 |
*
|
995 |
* @see registerUndefinedFilterCallback
|
|
|
|
|
996 |
*/
|
997 |
public function getFilters()
|
998 |
{
|
@@ -1033,6 +1047,8 @@ class Twig_Environment
|
|
1033 |
* Gets the registered Tests.
|
1034 |
*
|
1035 |
* @return Twig_TestInterface[] An array of Twig_TestInterface instances
|
|
|
|
|
1036 |
*/
|
1037 |
public function getTests()
|
1038 |
{
|
@@ -1049,6 +1065,8 @@ class Twig_Environment
|
|
1049 |
* @param string $name The test name
|
1050 |
*
|
1051 |
* @return Twig_Test|false A Twig_Test instance or false if the test does not exist
|
|
|
|
|
1052 |
*/
|
1053 |
public function getTest($name)
|
1054 |
{
|
@@ -1098,6 +1116,8 @@ class Twig_Environment
|
|
1098 |
* @param string $name function name
|
1099 |
*
|
1100 |
* @return Twig_Function|false A Twig_Function instance or false if the function does not exist
|
|
|
|
|
1101 |
*/
|
1102 |
public function getFunction($name)
|
1103 |
{
|
@@ -1144,6 +1164,8 @@ class Twig_Environment
|
|
1144 |
* @return Twig_FunctionInterface[] An array of Twig_FunctionInterface instances
|
1145 |
*
|
1146 |
* @see registerUndefinedFunctionCallback
|
|
|
|
|
1147 |
*/
|
1148 |
public function getFunctions()
|
1149 |
{
|
@@ -1189,6 +1211,8 @@ class Twig_Environment
|
|
1189 |
* Gets the registered Globals.
|
1190 |
*
|
1191 |
* @return array An array of globals
|
|
|
|
|
1192 |
*/
|
1193 |
public function getGlobals()
|
1194 |
{
|
@@ -1227,6 +1251,8 @@ class Twig_Environment
|
|
1227 |
* Gets the registered unary Operators.
|
1228 |
*
|
1229 |
* @return array An array of unary operators
|
|
|
|
|
1230 |
*/
|
1231 |
public function getUnaryOperators()
|
1232 |
{
|
@@ -1241,6 +1267,8 @@ class Twig_Environment
|
|
1241 |
* Gets the registered binary Operators.
|
1242 |
*
|
1243 |
* @return array An array of binary operators
|
|
|
|
|
1244 |
*/
|
1245 |
public function getBinaryOperators()
|
1246 |
{
|
@@ -1261,6 +1289,9 @@ class Twig_Environment
|
|
1261 |
return Twig_Error_Syntax::computeAlternatives($name, $items);
|
1262 |
}
|
1263 |
|
|
|
|
|
|
|
1264 |
protected function initGlobals()
|
1265 |
{
|
1266 |
$globals = array();
|
@@ -1286,6 +1317,9 @@ class Twig_Environment
|
|
1286 |
return call_user_func_array('array_merge', $globals);
|
1287 |
}
|
1288 |
|
|
|
|
|
|
|
1289 |
protected function initExtensions()
|
1290 |
{
|
1291 |
if ($this->extensionInitialized) {
|
@@ -1307,6 +1341,9 @@ class Twig_Environment
|
|
1307 |
$this->initExtension($this->staging);
|
1308 |
}
|
1309 |
|
|
|
|
|
|
|
1310 |
protected function initExtension(Twig_ExtensionInterface $extension)
|
1311 |
{
|
1312 |
// filters
|
16 |
*/
|
17 |
class Twig_Environment
|
18 |
{
|
19 |
+
const VERSION = '1.24.1';
|
20 |
|
21 |
protected $charset;
|
22 |
protected $loader;
|
438 |
} catch (Exception $e) {
|
439 |
$this->setLoader($current);
|
440 |
|
441 |
+
throw $e;
|
442 |
+
} catch (Throwable $e) {
|
443 |
+
$this->setLoader($current);
|
444 |
+
|
445 |
throw $e;
|
446 |
}
|
447 |
$this->setLoader($current);
|
859 |
* Gets the registered Token Parsers.
|
860 |
*
|
861 |
* @return Twig_TokenParserBrokerInterface A broker containing token parsers
|
862 |
+
*
|
863 |
+
* @internal
|
864 |
*/
|
865 |
public function getTokenParsers()
|
866 |
{
|
877 |
* Be warned that this method cannot return tags defined by Twig_TokenParserBrokerInterface classes.
|
878 |
*
|
879 |
* @return Twig_TokenParserInterface[] An array of Twig_TokenParserInterface instances
|
880 |
+
*
|
881 |
+
* @internal
|
882 |
*/
|
883 |
public function getTags()
|
884 |
{
|
910 |
* Gets the registered Node Visitors.
|
911 |
*
|
912 |
* @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
|
913 |
+
*
|
914 |
+
* @internal
|
915 |
*/
|
916 |
public function getNodeVisitors()
|
917 |
{
|
957 |
* @param string $name The filter name
|
958 |
*
|
959 |
* @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exist
|
960 |
+
*
|
961 |
+
* @internal
|
962 |
*/
|
963 |
public function getFilter($name)
|
964 |
{
|
1005 |
* @return Twig_FilterInterface[] An array of Twig_FilterInterface instances
|
1006 |
*
|
1007 |
* @see registerUndefinedFilterCallback
|
1008 |
+
*
|
1009 |
+
* @internal
|
1010 |
*/
|
1011 |
public function getFilters()
|
1012 |
{
|
1047 |
* Gets the registered Tests.
|
1048 |
*
|
1049 |
* @return Twig_TestInterface[] An array of Twig_TestInterface instances
|
1050 |
+
*
|
1051 |
+
* @internal
|
1052 |
*/
|
1053 |
public function getTests()
|
1054 |
{
|
1065 |
* @param string $name The test name
|
1066 |
*
|
1067 |
* @return Twig_Test|false A Twig_Test instance or false if the test does not exist
|
1068 |
+
*
|
1069 |
+
* @internal
|
1070 |
*/
|
1071 |
public function getTest($name)
|
1072 |
{
|
1116 |
* @param string $name function name
|
1117 |
*
|
1118 |
* @return Twig_Function|false A Twig_Function instance or false if the function does not exist
|
1119 |
+
*
|
1120 |
+
* @internal
|
1121 |
*/
|
1122 |
public function getFunction($name)
|
1123 |
{
|
1164 |
* @return Twig_FunctionInterface[] An array of Twig_FunctionInterface instances
|
1165 |
*
|
1166 |
* @see registerUndefinedFunctionCallback
|
1167 |
+
*
|
1168 |
+
* @internal
|
1169 |
*/
|
1170 |
public function getFunctions()
|
1171 |
{
|
1211 |
* Gets the registered Globals.
|
1212 |
*
|
1213 |
* @return array An array of globals
|
1214 |
+
*
|
1215 |
+
* @internal
|
1216 |
*/
|
1217 |
public function getGlobals()
|
1218 |
{
|
1251 |
* Gets the registered unary Operators.
|
1252 |
*
|
1253 |
* @return array An array of unary operators
|
1254 |
+
*
|
1255 |
+
* @internal
|
1256 |
*/
|
1257 |
public function getUnaryOperators()
|
1258 |
{
|
1267 |
* Gets the registered binary Operators.
|
1268 |
*
|
1269 |
* @return array An array of binary operators
|
1270 |
+
*
|
1271 |
+
* @internal
|
1272 |
*/
|
1273 |
public function getBinaryOperators()
|
1274 |
{
|
1289 |
return Twig_Error_Syntax::computeAlternatives($name, $items);
|
1290 |
}
|
1291 |
|
1292 |
+
/**
|
1293 |
+
* @internal
|
1294 |
+
*/
|
1295 |
protected function initGlobals()
|
1296 |
{
|
1297 |
$globals = array();
|
1317 |
return call_user_func_array('array_merge', $globals);
|
1318 |
}
|
1319 |
|
1320 |
+
/**
|
1321 |
+
* @internal
|
1322 |
+
*/
|
1323 |
protected function initExtensions()
|
1324 |
{
|
1325 |
if ($this->extensionInitialized) {
|
1341 |
$this->initExtension($this->staging);
|
1342 |
}
|
1343 |
|
1344 |
+
/**
|
1345 |
+
* @internal
|
1346 |
+
*/
|
1347 |
protected function initExtension(Twig_ExtensionInterface $extension)
|
1348 |
{
|
1349 |
// filters
|
vendor/twig/twig/lib/Twig/ExpressionParser.php
CHANGED
@@ -539,10 +539,11 @@ class Twig_ExpressionParser
|
|
539 |
$targets = array();
|
540 |
while (true) {
|
541 |
$token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to');
|
542 |
-
|
543 |
-
|
|
|
544 |
}
|
545 |
-
$targets[] = new Twig_Node_Expression_AssignName($
|
546 |
|
547 |
if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
|
548 |
break;
|
539 |
$targets = array();
|
540 |
while (true) {
|
541 |
$token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to');
|
542 |
+
$value = $token->getValue();
|
543 |
+
if (in_array(strtolower($value), array('true', 'false', 'none', 'null'))) {
|
544 |
+
throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s"', $value), $token->getLine(), $this->parser->getFilename());
|
545 |
}
|
546 |
+
$targets[] = new Twig_Node_Expression_AssignName($value, $token->getLine());
|
547 |
|
548 |
if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
|
549 |
break;
|
vendor/twig/twig/lib/Twig/Node/Macro.php
CHANGED
@@ -109,6 +109,11 @@ class Twig_Node_Macro extends Twig_Node
|
|
109 |
->write("ob_end_clean();\n\n")
|
110 |
->write("throw \$e;\n")
|
111 |
->outdent()
|
|
|
|
|
|
|
|
|
|
|
112 |
->write("}\n\n")
|
113 |
->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset());\n")
|
114 |
->outdent()
|
109 |
->write("ob_end_clean();\n\n")
|
110 |
->write("throw \$e;\n")
|
111 |
->outdent()
|
112 |
+
->write("} catch (Throwable \$e) {\n")
|
113 |
+
->indent()
|
114 |
+
->write("ob_end_clean();\n\n")
|
115 |
+
->write("throw \$e;\n")
|
116 |
+
->outdent()
|
117 |
->write("}\n\n")
|
118 |
->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset());\n")
|
119 |
->outdent()
|
vendor/twig/twig/lib/Twig/Template.php
CHANGED
@@ -369,6 +369,12 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|
369 |
ob_end_clean();
|
370 |
}
|
371 |
|
|
|
|
|
|
|
|
|
|
|
|
|
372 |
throw $e;
|
373 |
}
|
374 |
|
@@ -581,7 +587,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|
581 |
return;
|
582 |
}
|
583 |
|
584 |
-
throw new Twig_Error_Runtime(sprintf('
|
585 |
}
|
586 |
|
587 |
if ($isDefinedTest) {
|
369 |
ob_end_clean();
|
370 |
}
|
371 |
|
372 |
+
throw $e;
|
373 |
+
} catch (Throwable $e) {
|
374 |
+
while (ob_get_level() > $level) {
|
375 |
+
ob_end_clean();
|
376 |
+
}
|
377 |
+
|
378 |
throw $e;
|
379 |
}
|
380 |
|
587 |
return;
|
588 |
}
|
589 |
|
590 |
+
throw new Twig_Error_Runtime(sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()" or "__call()" exist and have public access in class "%2$s"', $item, get_class($object)), -1, $this->getTemplateName());
|
591 |
}
|
592 |
|
593 |
if ($isDefinedTest) {
|
vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php
CHANGED
@@ -27,8 +27,13 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
27 |
{
|
28 |
return array(
|
29 |
array('{% set false = "foo" %}'),
|
|
|
30 |
array('{% set true = "foo" %}'),
|
|
|
31 |
array('{% set none = "foo" %}'),
|
|
|
|
|
|
|
32 |
array('{% set 3 = "foo" %}'),
|
33 |
array('{% set 1 + 2 = "foo" %}'),
|
34 |
array('{% set "bar" = "foo" %}'),
|
27 |
{
|
28 |
return array(
|
29 |
array('{% set false = "foo" %}'),
|
30 |
+
array('{% set FALSE = "foo" %}'),
|
31 |
array('{% set true = "foo" %}'),
|
32 |
+
array('{% set TRUE = "foo" %}'),
|
33 |
array('{% set none = "foo" %}'),
|
34 |
+
array('{% set NONE = "foo" %}'),
|
35 |
+
array('{% set null = "foo" %}'),
|
36 |
+
array('{% set NULL = "foo" %}'),
|
37 |
array('{% set 3 = "foo" %}'),
|
38 |
array('{% set 1 + 2 = "foo" %}'),
|
39 |
array('{% set "bar" = "foo" %}'),
|
vendor/twig/twig/test/Twig/Tests/Node/MacroTest.php
CHANGED
@@ -58,6 +58,10 @@ public function getfoo(\$__foo__ = null, \$__bar__ = "Foo"$declaration)
|
|
58 |
} catch (Exception \$e) {
|
59 |
ob_end_clean();
|
60 |
|
|
|
|
|
|
|
|
|
61 |
throw \$e;
|
62 |
}
|
63 |
|
58 |
} catch (Exception \$e) {
|
59 |
ob_end_clean();
|
60 |
|
61 |
+
throw \$e;
|
62 |
+
} catch (Throwable \$e) {
|
63 |
+
ob_end_clean();
|
64 |
+
|
65 |
throw \$e;
|
66 |
}
|
67 |
|
vendor/twig/twig/test/Twig/Tests/TemplateTest.php
CHANGED
@@ -68,8 +68,8 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
|
|
68 |
array('{{ empty_array.a }}', 'Key "a" does not exist as the array is empty in "%s" at line 1', false),
|
69 |
array('{{ array.a }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1', false),
|
70 |
array('{{ attribute(array, -10) }}', 'Key "-10" for array with keys "foo" does not exist in "%s" at line 1', false),
|
71 |
-
array('{{ array_access.a }}', '
|
72 |
-
array('{% from _self import foo %}{% macro foo(obj) %}{{ obj.missing_method() }}{% endmacro %}{{ foo(array_access) }}', '
|
73 |
array('{{ magic_exception.test }}', 'An exception has been thrown during the rendering of a template ("Hey! Don\'t try to isset me!") in "%s" at line 1.', false),
|
74 |
array('{{ object["a"] }}', 'Impossible to access a key "a" on an object of class "stdClass" that does not implement ArrayAccess interface in "%s" at line 1', false),
|
75 |
);
|
68 |
array('{{ empty_array.a }}', 'Key "a" does not exist as the array is empty in "%s" at line 1', false),
|
69 |
array('{{ array.a }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1', false),
|
70 |
array('{{ attribute(array, -10) }}', 'Key "-10" for array with keys "foo" does not exist in "%s" at line 1', false),
|
71 |
+
array('{{ array_access.a }}', 'Neither the property "a" nor one of the methods "a()", "geta()"/"isa()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1', false),
|
72 |
+
array('{% from _self import foo %}{% macro foo(obj) %}{{ obj.missing_method() }}{% endmacro %}{{ foo(array_access) }}', 'Neither the property "missing_method" nor one of the methods "missing_method()", "getmissing_method()"/"ismissing_method()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1', false),
|
73 |
array('{{ magic_exception.test }}', 'An exception has been thrown during the rendering of a template ("Hey! Don\'t try to isset me!") in "%s" at line 1.', false),
|
74 |
array('{{ object["a"] }}', 'Impossible to access a key "a" on an object of class "stdClass" that does not implement ArrayAccess interface in "%s" at line 1', false),
|
75 |
);
|