Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
syncEnrollments
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Yeray Santana Hualde
syncEnrollments
Commits
8e8b0b8c
Commit
8e8b0b8c
authored
Mar 23, 2012
by
Taylor Otwell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More Blade improvements… adds template inheritance.
Signed-off-by:
Taylor Otwell
<
taylorotwell@gmail.com
>
parent
b07ee31f
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
261 additions
and
38 deletions
+261
-38
changes.txt
changes.txt
+4
-1
blade.php
laravel/blade.php
+224
-34
helpers.php
laravel/helpers.php
+11
-0
view.php
laravel/view.php
+22
-3
No files found.
changes.txt
View file @
8e8b0b8c
...
...
@@ -27,4 +27,7 @@ Changes for 3.1:
- Added Route::forward method.
- Prepend table name to default index names in schema.
- Added for/else to Blade.
- Added View::render_each
\ No newline at end of file
- Added View::render_each
- Able to specify full path to view (path: ).
- Blade extended views.
- Yield is now done via blade through {{ yield("content") }}
\ No newline at end of file
laravel/blade.php
View file @
8e8b0b8c
<?php
namespace
Laravel
;
<?php
namespace
Laravel
;
use
FilesystemIterator
as
fIterator
;
class
Blade
{
/**
* The cache key for the extension tree.
*
* @var string
*/
const
cache
=
'laravel.blade.extensions'
;
/**
* An array containing the template extension tree.
*
* @var array
*/
public
static
$extensions
;
/**
* The original extension tree loaded from the cache.
*
* @var array
*/
public
static
$original
;
/**
* All of the compiler functions used by Blade.
*
* @var array
*/
protected
static
$compilers
=
array
(
'extends'
,
'includes'
,
'echos'
,
'forelse'
,
...
...
@@ -16,7 +38,6 @@ class Blade {
'structure_openings'
,
'structure_closings'
,
'else'
,
'yields'
,
'section_start'
,
'section_end'
,
);
...
...
@@ -28,6 +49,8 @@ class Blade {
*/
public
static
function
sharpen
()
{
static
::
extensions
();
Event
::
listen
(
View
::
engine
,
function
(
$view
)
{
// The Blade view engine should only handle the rendering of views which
...
...
@@ -43,9 +66,9 @@ class Blade {
// If the view doesn't exist or has been modified since the last time it
// was compiled, we will recompile the view into pure PHP from it's
// Blade representation, writing it to cached storage.
if
(
!
file_exists
(
$compiled
)
or
(
filemtime
(
$view
->
path
)
>
filemtime
(
$compiled
)
))
if
(
!
file_exists
(
$compiled
)
or
Blade
::
expired
(
$view
->
view
,
$view
->
path
))
{
file_put_contents
(
$compiled
,
Blade
::
compile
(
$view
->
path
));
file_put_contents
(
$compiled
,
Blade
::
compile
(
$view
));
}
$view
->
path
=
$compiled
;
...
...
@@ -57,35 +80,201 @@ class Blade {
});
}
/**
* Load the extension tree so we can correctly invalidate caches.
*
* @return void
*/
protected
static
function
extensions
()
{
// The entire view extension tree is cached so we can check for expired
// views anywhere in the tree. This allows us to recompile a child
// view if any of its parent views change throughout the tree.
static
::
$extensions
=
Cache
::
get
(
Blade
::
cache
);
static
::
$original
=
static
::
$extensions
;
// If no extension tree was present, we need to invalidate every cache
// since we have no way of knowing which views needs to be compiled
// since we don't know any of their parent views.
if
(
is_null
(
static
::
$extensions
))
{
static
::
flush
();
static
::
$extensions
=
array
();
}
// We'll hook into the "done" event of Laravel and write out the tree
// of extensions if it was changed during the course of the request.
// The tree would change if new templates were rendered, etc.
Event
::
listen
(
'laravel.done'
,
function
()
{
if
(
Blade
::
$extensions
!==
Blade
::
$original
)
{
Cache
::
forever
(
Blade
::
cache
,
Blade
::
$extensions
);
}
});
}
/**
* Determine if a view is "expired" and needs to be re-compiled.
*
* @param string $view
* @param string $path
* @param string $compiled
* @return bool
*/
public
static
function
expired
(
$view
,
$path
)
{
$compiled
=
static
::
compiled
(
$path
);
return
filemtime
(
$path
)
>
filemtime
(
$compiled
)
or
static
::
expired_parent
(
$view
);
}
/**
* Determine if the given view has an expired parent view.
*
* @param string $view
* @return bool
*/
protected
static
function
expired_parent
(
$view
)
{
// If the view is extending another view, we need to recursively check
// whether any of the extended views have expired, all the way up to
// the top most parent view of the extension chain.
if
(
isset
(
static
::
$extensions
[
$view
]))
{
$e
=
static
::
$extensions
[
$view
];
return
static
::
expired
(
$e
[
'view'
],
$e
[
'path'
]);
}
return
false
;
}
/**
* Get the fully qualified path for a compiled view.
*
* @param string $view
* @return string
*/
public
static
function
compiled
(
$path
)
{
return
path
(
'storage'
)
.
'views/'
.
md5
(
$path
);
}
/**
* Compiles the specified file containing Blade pseudo-code into valid PHP.
*
* @param string $path
* @return string
*/
public
static
function
compile
(
$
path
)
public
static
function
compile
(
$
view
)
{
return
static
::
compile_string
(
file_get_contents
(
$
path
)
);
return
static
::
compile_string
(
file_get_contents
(
$
view
->
path
),
$view
);
}
/**
* Compiles the given string containing Blade pseudo-code into valid PHP.
*
* @param string $value
* @param View $view
* @return string
*/
public
static
function
compile_string
(
$value
)
public
static
function
compile_string
(
$value
,
$view
=
null
)
{
foreach
(
static
::
$compilers
as
$compiler
)
{
$method
=
"compile_
{
$compiler
}
"
;
$value
=
static
::
$method
(
$value
);
$value
=
static
::
$method
(
$value
,
$view
);
}
return
$value
;
}
/**
* Rewrites Blade extended templates into valid PHP.
*
* @param string $value
* @param View $view
* @return string
*/
protected
static
function
compile_extends
(
$value
,
$view
)
{
// If the view doesn't begin with @extends, we don't need to do anything
// and can simply return the view to be parsed by the rest of Blade's
// compilers like any other normal Blade view would be compiled.
if
(
is_null
(
$view
)
or
!
starts_with
(
$value
,
'@extends'
))
{
return
$value
;
}
// First we need to parse the parent template from the extends keyword
// so we know which parent to render. We will remove the extends
// from the template after we have extracted the parent.
$template
=
static
::
extract_template
(
$value
);
$path
=
static
::
store_extended
(
$value
,
$view
);
// Once we have stored a copy of the view without the "extends" clause
// we can load up that stored view and render it. The extending view
// should only be using "sections", so we don't need the output.
View
::
make
(
"path:
{
$path
}
"
,
$view
->
data
())
->
render
();
$parent
=
View
::
make
(
$template
);
// Finally we will make and return the parent view as the output of
// the compilation. We'll touch the parent to force it to compile
// when it is rendered so we can make sure we're all fresh.
touch
(
$parent
->
path
);
static
::
log_extension
(
$view
,
$parent
);
return
$parent
->
render
();
}
/**
* Extract the parent template name from an extending view.
*
* @param string $value
* @return string
*/
protected
static
function
extract_template
(
$value
)
{
preg_match
(
'/@extends(\s*\(.*\))(\s*)/'
,
$value
,
$matches
);
return
str_replace
(
array
(
"('"
,
"')"
),
''
,
$matches
[
1
]);
}
/**
* Store an extended view in the view storage.
*
* @param string $value
* @param View $view
* @return array
*/
protected
static
function
store_extended
(
$value
,
$view
)
{
$value
=
preg_replace
(
'/@extends(\s*\(.*\))(\s*)/'
,
''
,
$value
);
file_put_contents
(
$path
=
static
::
compiled
(
$view
->
path
.
'_extended'
)
.
BLADE_EXT
,
$value
);
return
$path
;
}
/**
* Log a view extension for a given view in the extension tree.
*
* @param View $view
* @param View $parent
* @return void
*/
protected
static
function
log_extension
(
$view
,
$parent
)
{
static
::
$extensions
[
$view
->
view
]
=
array
(
'view'
=>
$parent
->
view
,
'path'
=>
$parent
->
path
);
}
/**
* Rewrites Blade "include" statements to valid PHP.
*
...
...
@@ -96,9 +285,7 @@ class Blade {
{
$pattern
=
'/\{\{(\s*)include(\s*\(.*\))(\s*)\}\}/'
;
$value
=
preg_replace
(
$pattern
,
'<?php echo render$2'
,
$value
);
return
rtrim
(
$value
,
')'
)
.
', get_defined_vars()); ?>'
;
return
preg_replace
(
$pattern
,
'<?php echo render$2->with(get_defined_vars()); ?>'
,
$value
);
}
/**
...
...
@@ -123,17 +310,17 @@ class Blade {
preg_match_all
(
'/(\s*)@forelse(\s*\(.*\))(\s*)/'
,
$value
,
$matches
);
// First we'll loop through all of the "@forelse" lines. We need to
// wrap each loop in an
"if/else"
statement that checks the count
// of the variable
being iterated against
.
// wrap each loop in an
if/else
statement that checks the count
// of the variable
that is being iterated by the loop
.
if
(
isset
(
$matches
[
0
]))
{
foreach
(
$matches
[
0
]
as
$forelse
)
{
preg_match
(
'/\$[^\s]*/'
,
$forelse
,
$variable
);
// Once we have extracted the variable being looped against, we can
prepend
//
an "if" statmeent to the start of the loop that checks that the count
//
of the variable is greater than zero before looping the data
.
// Once we have extracted the variable being looped against, we can
//
prepend an "if" statmeent to the start of the loop that checks
//
that the count of the variable is greater than zero
.
$if
=
"<?php if (count(
{
$variable
[
0
]
}
) > 0): ?>"
;
$search
=
'/(\s*)@forelse(\s*\(.*\))/'
;
...
...
@@ -142,9 +329,9 @@ class Blade {
$blade
=
preg_replace
(
$search
,
$replace
,
$forelse
);
// Finally, once we have the check prepended to the loop, we will
replace
//
all instances of this "forelse" structure in the content of
the view
//
being compiled to Blade syntax using a simple str_replace
.
// Finally, once we have the check prepended to the loop, we will
//
replace all instances of this "forelse" syntax in
the view
//
content of the view being compiled to Blade syntax
.
$value
=
str_replace
(
$forelse
,
$blade
,
$value
);
}
}
...
...
@@ -211,21 +398,6 @@ class Blade {
return
preg_replace
(
'/(\s*)@(else)(\s*)/'
,
'$1<?php $2: ?>$3'
,
$value
);
}
/**
* Rewrites Blade @yield statements into Section statements.
*
* The Blade @yield statement is a shortcut to the Section::yield method.
*
* @param string $value
* @return string
*/
protected
static
function
compile_yields
(
$value
)
{
$pattern
=
static
::
matcher
(
'yield'
);
return
preg_replace
(
$pattern
,
'$1<?php echo \\Laravel\\Section::yield$2; ?>'
,
$value
);
}
/**
* Rewrites Blade @section statements into Section statements.
*
...
...
@@ -265,4 +437,22 @@ class Blade {
return
'/(\s*)@'
.
$function
.
'(\s*\(.*\))/'
;
}
/**
* Remove all of the cached views from storage.
*
* @return void
*/
protected
static
function
flush
()
{
$items
=
new
fIterator
(
path
(
'storage'
)
.
'views'
);
foreach
(
$items
as
$item
)
{
if
(
$item
->
isFile
()
and
$item
->
getBasename
()
!==
'.gitignore'
)
{
@
unlink
(
$item
->
getRealPath
());
}
}
}
}
\ No newline at end of file
laravel/helpers.php
View file @
8e8b0b8c
...
...
@@ -450,4 +450,15 @@ function render($view, $data = array())
function
render_each
(
$partial
,
array
$data
,
$iterator
,
$empty
=
'raw|'
)
{
return
Laravel\View
::
render_each
(
$partial
,
$data
,
$iterator
,
$empty
);
}
/**
* Get the string contents of a section.
*
* @param string $section
* @return string
*/
function
yield
(
$section
)
{
return
Laravel\Section
::
yield
(
$section
);
}
\ No newline at end of file
laravel/view.php
View file @
8e8b0b8c
...
...
@@ -73,7 +73,18 @@ class View implements ArrayAccess {
{
$this
->
view
=
$view
;
$this
->
data
=
$data
;
$this
->
path
=
$this
->
path
(
$view
);
// In order to allow developers to load views outside of the normal loading
// conventions, we'll allow for a raw path to be given in place of the
// typical view name, giving total freedom on view loading.
if
(
starts_with
(
$view
,
'path: '
))
{
$this
->
path
=
substr
(
$view
,
6
);
}
else
{
$this
->
path
=
$this
->
path
(
$view
);
}
// If a session driver has been specified, we will bind an instance of the
// validation error message container to every view. If an error instance
...
...
@@ -327,7 +338,7 @@ class View implements ArrayAccess {
/**
* Get the array of view data for the view instance.
*
* The shared view data will be combined with the view data
for the instance
.
* The shared view data will be combined with the view data.
*
* @return array
*/
...
...
@@ -381,7 +392,15 @@ class View implements ArrayAccess {
*/
public
function
with
(
$key
,
$value
)
{
$this
->
data
[
$key
]
=
$value
;
if
(
is_array
(
$key
))
{
$this
->
data
=
array_merge
(
$this
->
data
,
$key
);
}
else
{
$this
->
data
[
$key
]
=
$value
;
}
return
$this
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment