dimanche 27 janvier 2019

How to define and pass Variables in a Blade Directive?

Here's my problem; I'm trying to pass a variable, defined in the blade template, to two diffirent directives that receive data the same way. One nicely parses my data, the other doesn't.

I'm quite new to Laravel and Blade, but I've had a very pleasant experience working with a component-based workflow with Twig in the past. Leaping into Laravel on my spare time, I tried replicating this approach, but it's been proven to be difficult. Not only that, but I've been getting diffirent results in diffirent places. Allow me to explain...

@define $name = 'motor-loader'

<div class=@bemclass('')>
    <div class=@bemclass('', 'coils')>@svg('components/motor-loader/images/motor-coils.svg', '', 'svg')</div>
</div>

I define a variable here. While I know Blade detests having variables, I am quite certain this is the correct place. This is the template, this place responsible for it's own variables. If I have a complicated template whose name changes, I don't want to go through the template a ton of times; I want to be able to just have to change that variable. The variable is defined using the following function from this question

Blade::extend(function($value) {
    return $this->createBladeVariable($value);
});

and the function:

private function createBladeVariable(string $value) {
    return preg_replace('/\@define(.+)/', '<?php ${1}; ?>', $value);
}

At this point, things start getting a little bit funky. If you saw the @bemclass directive, I added quotes around the parsed variable. This was needed in order to pass the value as a string; my @bemclass directive actually works perfectly. This is what it looks like:

Blade::directive('bemclass', function ($expression) {
    $data = explode(', ', $expression, 3);
    $block = $this->stripBladeParameterString($data[0]);
    isset($data[1]) ? $element = $this->stripBladeParameterString($data[1]) : $element = null;
    isset($data[2]) ? $modifiers = $this->stripBladeParameterStringArray($data[2]) : $modifiers = null;

    return $this->renderBladeClasses($block, $element, $modifiers);
});

What happens here is that, if I pass the value is not recognized as a string and the directive fails. If I pass it as '', then it's passed as a string with quotes and I need to strip the quotes from around the input, this is what the stripBladeParameterString function does. It's not the prettiest; but this function actually does what's intended, and returns a nicely formatted .motor-loader and .motor-loader__coils classes.

Now, moving on to the @svg directive...

Blade::directive('svg', function ($expression) {
    $data = explode(', ', $expression, 4);
    $path = $this->stripBladeParameterString($data[0]);
    isset($data[1]) ? $block = $this->stripBladeParameterString($data[1]) : $class = null;
    isset($data[2]) ? $element = $this->stripBladeParameterString($data[2]) : $element = null;
    isset($data[3]) ? $modifiers = $this->stripBladeParameterStringArray($data[3]) : $modifiers = null;

    return $this->fetchSvg($path);
});

Now, whenever I var_dump($data), I get my parameters back; They split perfectly, however, this time around, it doesn't parse , all I get is the string "''" in $data's second member. I take away the quotes? I get the string . It's strange, because while it parses perfectly in my @bemclass directive, it doesn't in my @svg directive.

Now, I would expect to to either always parse, or I'm going at this completely the wrong way and it should never pass, but in reality, it does parse in the @bemclass directive and it doesn't in the @svg directive.



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire