Extending blade with a service - php

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.

Related

Can I define any route without callback function in laravel?

To register a route, I specify the route in web.php in following way,
Route::get($uri, $callback)->name($name);
Is there any way to do this without any specific callback function?
I am building a laravel website but some portion are made with perl. I need to submit a form to a url where the perl code takes over. However, as the form is used in many places I want to use the $name part as form action inside my front end codes.
Essentially what I want is something like this,
Route::get('cgi-bin/route_to_perl_program.cgi', "DO NOTHING. LET PERL DO IT JOB")->name($url_name);
If you not to define any $callback function,there is no need to define a route in web.php. As you want to use route('name') to produce that url in all your blade file,there is an alternative. You need to add this line of code in your config/app.php as follows:
perl_url => 'cgi-bin/route_to_perl_program.cgi',
And use them in your blade like as
link text
This is not your answer,this might be a solution of your specific
need.
In your $callback function to run a command to execute your perl file and get back the output and return that output as a response.,e.g:
.....
$yourPerlOutPut = exec('perl ~/your/path/yourfile.pl');
return response($yourPerlOutPut);
exec() executes the given command.
You can put your route_to_perl_program.cgi file in public folder and access yourdomain.com/route_to_perl_program.cgi. It will run. You need not put it the route.
Or try something like the following
Route::get('cgi-bin/route_to_perl_program.cgi', function(){
exec('cgi-bin/route_to_perl_program.cgi');
})->name($url_name);

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

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

Lumen/Dingo API Dynamic Versioning

I'm using Lumen for my project, currently the way I version my API is through prefixing and using a specific corresponding controller like so:
$api->get('/v1/users', 'App\Api\V1\Controllers\UserController#show');
$api->get('/v2/users', 'App\Api\V2\Controllers\UserController#show');
I want to change this, such that I take an argument from the user and use a controller based on that parameter.
This Route:
$api->get('/v{api_version}/users'...
Should use this controller:
'App\Api\V{api_version}\Controllers\UserController#show'
I'm currently using Dingo along side Lumen, is there anyway to do this with either Lumen or Dingo?
Yes, you can. But it's a little bit more complicated than in your example, but it's still a one-liner. Just define a closure and invoke your controller within it instead of passing the FQCN controller name directly.
routes/web.php
$app->get("api/v{version}/users", function ($version) use ($app) {
return $app->make("App\Api\V{$version}\Controllers\UserController")->show();
});
If someone else is interested (as I was) how to achieve the same in an laravel installation: Just use the method Controller::callAction() after the controller was resolved
Route::get("api/v{version}/test", function ($version) {
return app()->make('App\Api\V{$version}\Controllers\UserController')->callAction("show", [/* arguments */]);
});

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"))}}

HTMLHelper addCrumb method not available

I would like to use the addCrumb method in my Layout to automatically add controller links. I tried this but the Html-Helper-Object in the Layout didn't contain the addCrumb Function. Then I tried to use the function in the beforeFilter in my AppController to set the Link but this wont work too (no error given). At last I tried to use an element to make this happen, but this didnt the job (error method not found).
I am using CakePHP 2.0 - has anybody an idea to solve my problem (without changing the *.ctp files by hand)?
PS: Using $this->html->addCrumb() in my specific .ctp-file works great.
To have access to HTML helper methods such as addCrumb, you must make sure the helper is loaded for whatever action you want to use it in. Simply do $this->helpers[] = 'Html'; in your controller (in an action or in your AppController to add it universally).

Categories