Replies: 1 comment
-
The <?php
use Illuminate\Support\Facades\Blade;
Blade::prepareStringsForCompilationUsing(function ($content) {
// Modify $content as needed.
return $content;
}); |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Laravel Version
11.x
PHP Version
8.3.11
Database Driver & Version
MySQL-8.0.30-winx64
Description
Hey guys, I want to add some custom syntax to blade, in particular to component tags
<x-my.custom.component />
, and use a precompiler to compile to something that theBladeCompiler
or php could work with. But my precompiler didn't seem to work as I expected.The issue
After some digging around in the framework, I found out that custom precompilers are called after component tags are already compiled to
@component
tags. I would've expected that precompilers are ran before any other compiler, hence the name precompiler. But this is not the case. This makes it unintuitive and harder to work with, because you'd expect that the exact content of the blade file are passed into the precompiler, but instead it's already half processed. This is unexpected behaviour and makes me unable to add custom syntax to blade component tags, because the tags won't compile.In my opinion, it would be much better to run precompilers before any compiling happens at all, this would be more in line with the name 'precompiler' and would open up more possibilities, and make the precompiler more flexible, all without (to my knowledge) any downsides.
This has already been mentioned by @ph7jack in This discussion. He also made a pull request over 2 years ago, but this (inconvenient) issue still persists.
The fix
The issue is very easy to fix fortunately. @ph7jack added some code to correct this inconvenient issue, but I don't think this is necessary at all. The precompilers goal is already to run before the BladeCompiler. The only thing that has to be done is shift 3 lines of code a bit higher up, to the beginning of the function that compiles a blade view. This will fix the issue I'm facing and make the BladeCompiler more flexible, and make the precompiler behave as expected:
In https://github.com/laravel/framework/blob/f405bf0a56e9ad4407ed7bcd2e8a3fbcd62479b6/src/Illuminate/View/Compilers/BladeCompiler.php
framework/src/Illuminate/View/Compilers/BladeCompiler.php
Lines 257 to 304 in f405bf0
Move these 3 lines to the very top of the function:
framework/src/Illuminate/View/Compilers/BladeCompiler.php
Lines 274 to 276 in f405bf0
Like this:
Temporary workaround
For people facing the same issue but wanting to implement the precompiler in the same way I want to, there is a workaround. What I'm doing now is replace the default
ViewServiceProvider
with my own custom ViewServiceProvider, which extends the original one. This custom ViewServiceProvider overwrites the registerBladeCompiler method, in which I register my own custom BladeCompiler, which also extends the original one. And in the custom BladeCompiler overwrite the compileString method to move these 3 lines of code up to the beginning of the function. This does the trick, but this wouldn't all be necessary if this was the default.Thank you guys in advance for taking the time to read into this issue. I can create a pull request if you guys want to, but this is a very easy fix, so I guess it's better if I leave this up to you guys.
If for some reason this can't or won't be implemented, could you explain why, especially for the people in the future that would maybe face this issue.
PS: Much love to laravel and it's team and community, you guys have done amazing work
Steps To Reproduce
I was implementing something very simple and not worth mentioning that much actually. but I wanted to add a way so that php variables were directly accessible as css variables or as data for javascript to retrieve and use, instead of being passed to the component as php variables.
so what I wanted is to turn something like this:
<x-my.custom.component css:$cssVar data:$dataVar />
Into this:
<x-my.custom.component style="--css-var: {{ $cssVar }}" data-data-var="{{ $dataVar }}" />
So all this to save me from typing a few more characters, just because I'm lazy and I think it looks nice.
Beta Was this translation helpful? Give feedback.
All reactions