how to highlight string in a string in a laravel blade view - php

Somewhere in my template I have this:
{{ $result->someText }}
Now in this text I want to highlight all words that are in the string
{{ $searchString }}
So I thought I create a new blade directive:
{{ #highlightSearch($result->someText, $searchString) }}
Blade::directive('highlightSearch', function($input, $searchString)...
error: missing argument 2
Found out that directives do not except 2 arguments. I tried every workaround that I could find but none worked. They always return the arguments as a plain string, not even passing the actual values.
I tried adding a helper function like explained here: https://stackoverflow.com/a/32430258/928666. Did not work:
error: unknown function "highlightSearch"
So how do I do this super easy task in laravel? I don't care about the highlighting function, that's almost a one-liner.

The reality is blade directives can't do what you need them to do. Whether or not they should is not a topic I can't help with. However you can instead do this in your service provider:
use Illuminate\Support\Str;
/* ... */
Str::macro('highlightSearch', function ($input, $searchString) {
return str_replace($searchString, "<mark>$searchString</mark>", $input);
//Or whatever else you do
});
Then in blade you can just do:
{!! \Illuminate\Support\Str::highlightSearch($result->someText, $searchString) !!}

I've just tested in Laravel 5.1 it and it works without any problem:
\Blade::directive('highlightSearch', function($input) {
return "<?php echo strtoupper($input); ?>";
});
in boot method of AppServiceProvider
and in view I can use:
#highlightSearch('test')
and it returns TEST as expected.
Make sure you are using Blade from global namespace, also run
php artisan clear-compiled
to make sure everything is refreshed. If it won't help, you can try running
composer dump-autoload
just in case.
EDIT
I've also tested it with additional argument and it really seems not be working as expected, so the most reasonable would be adding helper file (if you don't have any with simple PHP function) as for example:
function highlight_search($text, $searchString)
{
// return whatever you want
}
and later use it it in Blade as any other function like so:
{{ highlight_search('Sample', 'Sam') }}
optionally using
{!! highlight_search('Sample', 'Sam') !!}
if you want highlight_search to output HTML

Related

Getting error when using {{ Str::limit }} helper class in Laravel Blade

I'm building an app using Laravel 6.5, upgraded from Laravel 5.7.
I have a field that pulls text from the DB and displays the first 50 characters, using the Blade syntax:
...
{{ Str::limit($someValue->value, 50) }} // This worked
...
{{ Str::limit($someOtherValue->value, 50) }} // This gave error message
...
and when accessing the page I get
ErrorException (E_ERROR)
Class 'Str' not found
The original code uses the helper class str_limit() which was deprecated since Laravel 5.8.
So when I took over this project and upgraded Laravel, I updated the code to the above.
From my understanding, Str::limit() is a global helper class and should work without having to declare any Facade or add aliases. The fact that the above code worked partially proves it.
I implemented a working fix:
...
{{ Str::limit($someValue->value, 50) }} // This worked
...
{{ \Illuminate\Support\Str::limit($someOtherValue->value, 50) }} // This now works
...
Although I have a working fix, the ugliness of the code hurts my eyes and it drives me nuts not know WHY only 1 of it worked?? My linter and bracket highlighting tell me there are no missing tags. I've also copied the same code and applied in every combination, it's just that second Str::limit() which is not working.
Can anyone tell me why it's behaving this way? Thank you!
I suggest you to use Mutator. It's a good way when you modify your data from your database. Don't make your blade file messy.
******* Model ********
use Illuminate\Support\Str;
public function getSomeFieldAttribute($value)
{
return str_limit($value, 50);
}
Note: someField is a column that you want to limit.
In controller you can use code like below
use Illuminate\Support\Str;
then
Example :-
$limit_string = Str::limit('This is just an example', 5);
In View file if you want to use then
{{\Illuminate\Support\Str::limit('This is just an example',5)}}
you can't extend facade to blade file . if you want to use str then you have define a path and use that helper function that is limit here .
arr and str is global function but in laravel 5.8 they deprecated this functionality so if you want to use this str or arr helpers then you have to use
Illuminate\Support\Str (str) and use Illuminate\Support\Arr (arr) to perform operation.
Ok I figured out my problem.
...
if (someCondition not fulfilled) {
{{ Str::limit($someValue->value, 50) }} // This actually didn't work but got skipped
} else {
'Some error message' // THIS worked
...
if (someCondition fulfilled) {
{{ Str::limit($someOtherValue->value, 50) }} // This gave error message
} else {
'Some error message' // Skipped
...
The Str helper function only worked after declaring an alias for Str in config/app.php and clearing the cache: php artisan view:clear & php artisan config:clear
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
...
'Str' => Illuminate\Support\Str::class
]
Much thanks to everyone who offered help here!

Extending blade with a service

I installed graham-campbell/markdown, and it works in the controller. I would like to extend it's functionality to blade so I could use #markdown($variable) but can't figure out how to accomplish that.
This is how my AppServiceProvider's boot method looks like with the added blade directive.
public function boot()
{
Schema::defaultStringLength(191);
Blade::directive('markdown', function ($expression) {
return "<?php echo Markdown::convertToHtml($expression); ?>";
});
}
And in my view
#markdown($comment->comment)
But I"m getting the following error:
Class 'Markdown' not found (View: C:\xampp\htdocs\portfolio\portfolio\resources\views\blog.blade.php)
I've added the use at the top of AppServiceProvider file:
use GrahamCampbell\Markdown\Facades\Markdown;
And still the same error. I've even tried the following directive instead of the one I have posted previously:
Blade::directive('markdown', function ($expression) {
return Markdown::convertToHtml($expression);
});
And although it's frowned upon, I've tried to inject the markdown class into the view
#inject('markdown', 'GrahamCampbell\Markdown\Facades\Markdown')
The error no longer shows, but it simply displays $comment->comment.
If I put #markdown(foo **this**) I get 'foo this' just like I would expect. How do I extract the contents of '$comment->comment' and submit it to be parsed by the markdown compiler?
Also, is it possible to do that without the Facades injection?
[EDIT]
I've solved my issue where it just prints $comment->comment. I've removed any changes to AppServiceProvider... I've removed that use statement and blade directive and just using the following in view
#inject('markdown', 'GrahamCampbell\Markdown\Facades\Markdown')
{!! $markdown::convertToHtml($comment->comment) !!}
But I'm still interesting in using the directive #markdown($variable) without the need for that injection.
The first line of code is correct except that you need to add {} instead of (), please refer to this answer.
so you need to type it like this:{$expression} instead of ($expression).
here as well a good tutorial on how to create a custom directive and you can check laracasts.

Symfony Twig {{render}} handling passed arguments

Over a template I do a render method:
{{ render(controller('AppBundle:Widgets:myCapsWidget'),{'somestring':someString}) }}
Over the controller I have the following method:
public function myCapsWidgetAction($somestring)
{
return new Response(strtoupper($somestring));
}
I also looked over theese links:
symfony twig render controller argument array
https://knpuniversity.com/screencast/symfony2-ep3/render-controller
But still cannot find any light to my path.
If I read the first link you gave us, you should use:
{{ render(controller('AppBundle:Widgets:myCapsWidget',{'somestring':someString})) }}

VueJS variable inside URL::action in Laravel

I am new to VueJS.
I have a link using Laravel Helpers:
{{ $tournament->id }}
As it will be inside a VueJS v-for, now I need to refer to Vue variables that I load with AJAX.
So, I tried to write it like that:
#{{ tournament.id }}
But I get
Parse error: syntax error, unexpected '{' (View: /home/vagrant/Code/resources/views/tournaments/index.blade.php)
Any Idea how to mix Laravel Helper and VueJS?
First of all it looks like you're missing quotes around #{{ tournament.id }}.
But after playing around with it myself it doesn't seem possible at the moment due to routes using the same brackets as placeholders.
A workaround would be to create a simple function somewhere that generates the url with a unique placeholder and afterwards you do a str_replace call on the generated url.
That's the thing I dislike in the helpers and I have completely stopped using them. IMHO the best way to go is to create a route for that (or a Route::controller) and map those urls to a controller. and then use something like:
#{{ tournament.id }}
Your routes could be something like:
Route::controller('tournament','TournamentController');
and your function inside the controller:
function getEdit($tournament_id){
// something something
}
And something like this would work

Capitalized a blade's variable in Laravel

I used to use smarty a lot and now moved on to Laravel but I'm missing something that was really useful. The modification in the template of you're variable.
Let say I have a variable assign as {{$var}}. Is there a way in Laravel to set it to upper case ? Something like: {{$var|upper}}
I sadly haven't found any documentation on it.
Only first character :
You could use UCFirst, a PHP function
{{ucfirst(trans('text.blabla'))}}
For the doc : http://php.net/manual/en/function.ucfirst.php
Whole word
Str::upper($value)
Also this page might have handy things : http://cheats.jesse-obrien.ca/
PHP Native functions can be used here
{{ strtoupper($currency) }}
{{ ucfirst($interval) }}
Tested OK
You can also create a custom Blade directive within the AppServiceProvider.php
Example:
public function boot() {
Blade::directive('lang_u', function ($s) {
return "<?php echo ucfirst(trans($s)); ?>";
});
}
Don't forget to import Blade at the top of the AppServiceProvider
use Illuminate\Support\Facades\Blade;
Then use it like this within your blade template:
#lang_u('index.section_h2')
Source:
How to capitalize first letter in Laravel Blade
For further information:
https://laravel.com/docs/5.8/blade#extending-blade
works double quoted:
{{ucfirst(trans("$var"))}}

Categories