Laravel 4: include template with parameters in single line - laravel

I'm trying to save a blade template into a javascript variable but I can't figure out how to remove the line breaks from the template.
I looked at extending blade and created the following code based on BladeCompiler:compileInclude() which removes all line breaks, but only for templates without parameters.
Blade::extend(function($view, $compiler)
{
$pattern = $compiler->createMatcher('include_string');
return preg_replace($pattern, '$1<?php echo str_replace(array("\r","\n"), "", $__env->make($2, array_except(get_defined_vars(), array(\'__data\', \'__path\')))->render()); ?>', $view);
});
I know I could simply remove all line breaks from the template manually but I'm hoping there's a better way.
Has anyone done this before? Any help is appreciated.

I haven't found a way to create your own blade functions that can receive multiple values (or an array) and I don't think it is even possible by using "only" Blade::extend. Of course you could extend Laravel's BladeCompiler class and write much more powerful macros.
But instead I suggest you create a macro for removing the line breaks only.
Blade::extend(function($view, $compiler)
{
$pattern = $compiler->createMatcher('singleline');
return preg_replace($pattern, '$1<?php echo str_replace(array("\r","\n"), "", $2); ?>', $view);
});
And the use it either like this:
#singleline(View::make('view-name', array('foo' => 'bar')))
Or if you prefer the $__env syntax:
#singleline($__env->make('view-name', array('foo' => 'bar')))

Related

How to get translate message in controller Laravel?

I have file excel.php by the path /resources/lang/en/excel.php
Then in controller I tried to fetch word by key:
use Lang;
echo Lang::get('excel.idEvent');
Also I tried:
dd(echo __('excel.idEvent'));
Whats is right way to do that?
First, your excel.php file must be in the right format:
<?php
return [
'welcome' => 'Welcome to our application'
];
The right way to get it on your blade template in fact it is:
echo __('excel.welcome');
or
echo __('Welcome to our application');
The way to do it on your controller is:
use Lang;
Lang::get('excel.welcome');
If you are not using Facades: use \Illuminate\Support\Facades\Lang;
You can also use the trans() function, ex:
Route::get('/', function () {
echo trans('messages.welcome');
});
If you use JSON translation files, you might have to use __().
Here are all the ways to use:
#lang('...') // only in blade files
__('...')
Lang::get('...')
trans('...')
app('translator')->get('...')
Lang::trans('...')
They all defer to \Illuminate\Translation\Translator::get() eventually.

Laravel blade #include into a Javascript variable?

In a Laravel 5 blade template I have a <script> section.
In this section I need to set a variable to a string that is coming from another blade template.
I tried something like :
<script>
var a = "#include 'sometext.blade.php' ";
</script>
but this obviously doesn't work.
Also, the included blade can contain both single and double quotes, so these need to be escaped somehow, or the Javascript will not be valid.
Any ideas?
Ended up needing similar functionality when working with DataTables, and the additional actions HTML needs to be injected after the fact via jQuery.
First I created a helper function with this (from Pass a PHP string to a JavaScript variable (and escape newlines)):
function includeAsJsString($template)
{
$string = view($template);
return str_replace("\n", '\n', str_replace('"', '\"', addcslashes(str_replace("\r", '', (string)$string), "\0..\37'\\")));
}
Then in your template you could do something like:
$('div.datatable-toolbar').html("{!! includeAsJsString('sometext') !!}");
to include the sometext.blade.php blade template with escaping of quotes and removal of newlines.

Using Blade directives outside of templates

Laravel 5.1: I defined a few custom directives inside a BladeServiceProvider (example below). Now I would like to use them outside of a view template to format strings (I am writing an EXCEL file with PHPExcel in a custom ExportService class). Is it possible to reuse my directives?
Blade::directive('appFormatDate', function($expression) {
return "<?php
if (!is_null($expression)) {
echo date(\Config::get('custom.dateformat'), strtotime($expression));
}
else {
echo '-';
}
?>";
});
The BladeCompiler has a compileString method, which allows you to use the Blade directives outside the views. :)
So, you can do things like this:
$timestamp = '2015-11-10 17:41:53';
$result = Blade::compileString('#appFormatDate($timestamp)');
You can use this:
use Illuminate\Support\Facades\Blade;
$timestamp = '2023-01-28 12:41:53';
Blade::render("#appFormatDate({$timestamp})");

Extending blade template for opening and closing tags

I'm trying to wrap my head around extending blade templates in Laravel 4.2, the example in the docs states:
Blade::extend(function($view, $compiler)
{
$pattern = $compiler->createMatcher('datetime');
return preg_replace($pattern, '$1<?php echo $2->format(\'m/d/Y H:i\'); ?>', $view);
});
This works for single blade tags such #datetime(...).
I'm trying to extend (more like alias) something such as
#if($var == 'foo')
bar
#endif
to
#foo
bar
#endfoo
I'm unsure how to handle "opening" and "closing" tags. Can someone show me an example?
Create a new file blade_extensions.php in your app/ folder. Then inside that file put the following:
<?php
Blade::extend(function($view, $compiler)
{
$pattern = $compiler->createMatcher('foo');
return preg_replace($pattern, '$1<?php if ($2 == "foo") : ?>', $view);
});
Blade::extend(function($view, $compiler)
{
$pattern = $compiler->createPlainMatcher('endfoo');
return preg_replace($pattern, '$1<?php endif; ?>', $view);
});
Then in your app/start/global.php at the bottom after require app_path().'/filters.php'; add:
require app_path().'/blade_extensions.php';
Then in your view you can write the following:
#foo ($var)
bar
#endfoo
I don't know if that's exactly the control structure you're looking for, but that matches the check for $var == 'foo'

Passing objects to Custom Control Structures in Laravel Blade

I can't call member functions on objects that I pass to custom control structures in Laravel 4.1.23.
My custom control structure:
Blade::extend(function($view, $compiler){
$pattern = $compiler->createMatcher('paginatePretty');
$code =
'$1<?php
echo $2->getCurrentPage();
?>';
return preg_replace($pattern, $code, $view);
});
My blade view code that instantiates paginatePretty:
// $articles = Articles::orderBy('created_at', 'desc')->paginate($per_page);
#paginatePretty($articles)
At compile time, I get this error:
syntax error, unexpected '->' (T_OBJECT_OPERATOR), expecting ',' or ';'
And the custom control structure was compiled like this:
echo ($articles)->getCurrentPage();
How can I pass an object to the custom control structure?
Use list() and array to solve:
Blade::extend(function($view, $compiler){
$pattern = $compiler->createMatcher('paginatePretty');
$code =
'$1<?php
#echo $2->getCurrentPage(); --> the bad code
list($_paginator) = array$2;
echo $_paginator->getCurrentPage();
?>';
return preg_replace($pattern, $code, $view);
});
I prefix variables declared inside of custom control structures with an underscore to avoid collisions in the view.

Resources