-
Notifications
You must be signed in to change notification settings - Fork 11.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[5.7] Add Blade::helper(...) directive #24923
Conversation
Maybe those examples aren't too good but is there a big difference between doing... {{ strtoupper('blah') }} vs @upper('blah') I personally don't think we should be encouraging adding a "wrapper" around every php function and turning it into a directive. If folks really want such functionality, why not just use a package that adds some php directives To me directives are more to do with "code structure" and not presentation (though admittedly some directives are helpful if you use them frequently e.g |
In hindsight, I see that I definitely could have emphasized what I imagine would be the main feature of this PR more. I agree that we shouldn't be encouraging people to wrap individual functions one-for-one since there's no real benefit in doing that, but from my experience, it just seems to be the most common thing people do because it's not obvious to most people how to use that So, the main thing here I imagine would be the closure that can be passed in, where the developer writing the directive doesn't have to care about the context of the expression or its contents, and can just treat it like they're writing a regular function. Admittedly, these helper directives wouldn't really have any advantage in "code structure" and would only be really useful for wrapping presentation stuff, but I think there's still enough usage people would get out of that to justify it in core. Take this as a mundane example, as a wrapper for the logic around a FontAwesome 4 icon. There's a bit of boilerplate around it you probably don't want to remember to write every time, and you wouldn't want to Blade::helper('fa', function(string $iconName, string $text = null, $classes = '') {
if (is_array($classes)) {
$classes = join(' ', $classes);
}
$text = $text ?? $iconName;
return "<i class='fa fa-{$iconName} {$classes}' aria-hidden='true' title='{$text}'></i><span class='sr-only'>{$text}</span>";
}); |
@imliam Small correction for your latest example. You want: $text = $text ?: $iconName; and not: $text = $text ?? $iconName; 😀 Also, your PR seems to be failing some style checks. |
@shalvah They do almost the same |
I'm still strongly opposed to having this merged in core. The word "helper" is templating languages generally means adding a function of some kind so you can use it to output/echo stuff into the view. That's fine, this is exactly what this PR is doing. Except in all the templating languages that implement such functionality it's because they are sandboxed. For example, in Twig, you cannot simply do: {{ some_helper() }} Even if This PR has piggy-backed echo helpers onto blade directives which is simply not needed, and goes against the general convention of using directives as code structure and not echoing (minus a few exceptions). As I said, this can easily be added as a package. I'm yet to be convinced it would even be widely used. |
No plans on adding this right now. |
tl;dr makes it easier to work with custom Blade directives
When creating new custom Blade directives using the
Blade::directive(...)
method, it seems to be rare that people actually parse the contents of the expression itself within the directive, opting instead to pass the entire expression as arguments to a helper function or method on another class.Since from what I've seen, this seems to be the most common use case, I wanted to help make these functions that little bit easier to define without the boilerplate of returning the string or having to consider what an expression may be when creating a directive.
To help with this, this PR introduces a
helper
method on theBladeCompiler
class. This method accepts two arguments; the first is the name of the directive, and the second is the function that the directive should call.If no second argument is supplied, the directive name will attempt to call a function of the same name.
The second argument can also take a callback. The advantage of a callback here over the
Blade::directive(...)
method is that the closure defined can have specific parameters defined instead of just the raw expression passed through. This has several good things that solve a previous idea I brought up:By default, all of the helper directives will echo out their contents to the view when used. This can be disabled by passing
false
as the third argument.