Skip to content

Instantly share code, notes, and snippets.

@fzldn
Last active July 28, 2023 18:28
Show Gist options
  • Save fzldn/a27973ff7e4c8e3738b0e06e525f7403 to your computer and use it in GitHub Desktop.
Save fzldn/a27973ff7e4c8e3738b0e06e525f7403 to your computer and use it in GitHub Desktop.
VS Code Laravel Blade formatter using extension Beautify 1.5.0 by HookyQR with js-beautify hacks
...
Beautifier.prototype.beautify = function() {
...
var source_text = this._source_text;
// BEGIN
source_text = source_text.replace(/\{\{(--)?((?:(?!(--)?\}\}).)+)(--)?\}\}/g, function(m, ds, c, dh, de) {
if (c) {
c = c.replace(/(^[ \t]*|[ \t]*$)/g, '');
c = c.replace(/'/g, ''');
c = c.replace(/"/g, '"');
c = encodeURIComponent(c);
}
return "{{" + (ds ? ds : "") + c + (de ? de : "") + "}}";
});
source_text = source_text.replace(/^[ \t]*@([a-z]+)([^\n]*)$/gim, function(m, d, c) {
if (c) {
c = c.replace(/'/g, ''');
c = c.replace(/"/g, '"');
c = "|" + encodeURIComponent(c);
}
switch (d) {
case 'break':
case 'case':
case 'continue':
case 'default':
case 'empty':
case 'endsection':
case 'else':
case 'elseif':
case 'extends':
case 'csrf':
case 'include':
case 'json':
case 'method':
case 'parent':
case 'section':
case 'stack':
case 'yield':
return "<blade " + d + c + "/>";
default:
if (d.startsWith('end')) {
return "</blade " + d + c + ">";
} else {
return "<blade " + d + c + ">";
}
}
});
// END
...
var sweet_code = printer._output.get_code(eol);
// BEGIN
sweet_code = sweet_code.replace(/^([ \t]*)<\/?blade ([a-z]+)\|?([^>\/]+)?\/?>$/gim, function toDirective(m, s, d, c) {
if (c) {
c = decodeURIComponent(c);
c = c.replace(/&#39;/g, "'");
c = c.replace(/&#34;/g, '"');
c = c.replace(/^[ \t]*/g, '');
} else {
c = "";
}
if (!s) {
s = "";
}
switch (d) {
case 'else':
case 'elseif':
case 'empty':
s = s.replace(printer._output.__indent_cache.__indent_string, '');
break;
}
return s + "@" + d + c.trim();
});
sweet_code = sweet_code.replace(/@(case|default)((?:(?!@break).|\n)+)@break/gim, function addMoreIndent(m, t, c) {
var indent = printer._output.__indent_cache.__base_string;
c = c.replace(/\n/g, "\n" + indent + printer._output.__indent_cache.__indent_string);
c = c.replace(new RegExp(indent + '@' + t, 'gi'), '@' + t);
return "@" + t + c + "@break";
});
sweet_code = sweet_code.replace(/\{\{(--)?((?:(?!(--)?\}\}).)+)(--)?\}\}/g, function (m, ds, c, dh, de) {
if (c) {
c = decodeURIComponent(c);
c = c.replace(/&#39;/g, "'");
c = c.replace(/&#34;/g, '"');
c = c.replace(/(^[ \t]*|[ \t]*$)/g, ' ');
}
return "{{" + (ds ? ds : "") + c + (de ? de : "") + "}}";
});
// END
return sweet_code;
};
...
@fzldn
Copy link
Author

fzldn commented Jul 16, 2019

@Zontir gist updated with @empty no need extra indentation

@mreduar
Copy link

mreduar commented Jul 16, 2019

Thanks! :)

@brandonfredericksen
Copy link

much appreciated 👍

@brandonfredericksen
Copy link

@mohamedsabil83 @aeadedoyin created new fix for 1.5.0, please re-apply the patch

Hi, just tested its still the same.
Nested @if don't display normally.

This:

@if ($user->isApplicant())
@if ($user->applicant->isAttempted($course->id, $module_item->id))
@if ($user->applicant->isChosenAnswer($course->id, $module_item->id, 'question'.$qkey, $okey))

Returns:

@if($user->isApplicant())
    <blade
        if|%20(%24user-%3Eapplicant-%3EisAttempted(%24course-%3Eid%2C%20%24module_item-%3Eid))%0D>
            <blade
                if|%20(%24user-%3Eapplicant-%3EisChosenAnswer(%24course-%3Eid%2C%20%24module_item%3Eid%2C%20%26%2339%3Bquestion%26%2339%3B.%24qkey%2C%20%24okey))%0D>

Ah, having this issue too.. darn.

@mreduar
Copy link

mreduar commented Jul 24, 2019

I found a new problem formatting files with the @show directive

Expected

@section('sidebar')
     This is the master sidebar.
@show

<div class="container">
     @yield('content')
</div>

Obtained

@section('sidebar')
     This is the master sidebar.
@show

     <div class="container">
          @yield('content')
     </div>

I have also noticed that with the @parent directive this happens

Expected

@section('sidebar')
    @parent

    <p>This is appended to the master sidebar.</p>
@endsection

Obtained

@section('sidebar')
@parent

<p>This is appended to the master sidebar.</p>
@endsection

@mohamedsabil83
Copy link

@Zontir, note that any directive listed in source_text switch wouldn't add any append in the next lines. You can add what you need.

switch (d) {
            case 'break':
            case 'case':
            case 'continue':
            case 'default':
            case 'empty':
            case 'endsection':
            case 'else':
            case 'elseif':
            case 'extends':
            case 'csrf':
            case 'include':
            case 'json':
            case 'method':
            case 'parent':
            case 'section':
            case 'stack':
            case 'yield':
            case 'show': // You can add it here

@mreduar
Copy link

mreduar commented Jul 24, 2019

@mohamedsabil83 Thanks for the help. I've tried it and it works well, however I couldn't locate the part of the code to fix the @parent directive.

@mohamedsabil83
Copy link

You're welcome @Zontir. I'll try to figure it and may @fzldn help us with it

@mohamedsabil83
Copy link

Any idea to keep array indent in blade file e.g.:

{!! Form::text('name', old('name'), [
    'class' => [
        ''
    ]
]) !!}

instead of:

{!! Form::text('name', old('name'), [
'class' => [
''
]
]) !!}

CC: @fzldn

@fzldn
Copy link
Author

fzldn commented Aug 16, 2019

@mohamedsabil83 sorry I can't help much on that part, because that is a part of php formatter not in jsbeautify

@mreduar
Copy link

mreduar commented Aug 16, 2019

@mohamedsabil83 I think you simply shouldn't use LaravelCollective packages, these forms were taken from previous versions of Laravel.

@mohamedsabil83
Copy link

@fzldn I thought that just to be sure.

@Zontir It's an old project. Guess I will remove it when upgrading project to v6.

@lrpinto
Copy link

lrpinto commented Sep 16, 2019

Thank you for the fantastic work.

I was wondering if anyone found a work around to keep array indentation:

// Before

  @component('components.form.form', [
    'classlist' => 'p-4',
    'attributes' => [
      'attribute' => [
        'something' => true
      ]
    ]
  ])

// After

  @component('components.form.form', [
    'classlist' => 'p-4',
    'attributes' => [
    'attribute' => [
    'something' => true
    ]
    ]
    ])

@rashidhussainshah
Copy link

rashidhussainshah commented Oct 7, 2019

not working in beautify 1.5.0

@tech-mik
Copy link

Nice! Working just fine here. Isn't there any way to make beautify indent on section also, only if there is a endsection following?

@tech-mik
Copy link

Ah, I found a bug:
// before
@section('title', 'Edit details for ' . $customer->name)

// After
<blade section|(%26%2339%3Btitle%26%2339%3B%2C%20%26%2339%3BEdit%20details%20for%20%26%2339%3B%20.%20%24customer-%3Ename) />

@lrpinto
Copy link

lrpinto commented Nov 1, 2019 via email

@tech-mik
Copy link

tech-mik commented Nov 1, 2019

I have no clue, not that far with php ;P @fzldn maybe?? 💯

Edit:
It seems it has to do something with the length of the blade syntax. If you shorten it to:
@section("title", "Edit details for ".$customer->name)
Nothing happens. Add 2 more characters and it's all messed up again.

EDIT EDIT:
Here is a short, simpel but awkward solution for longer blade syntaxes, until it's fixed:

@php
$title = 'Details for ' . $customer->name
@endphp
@section('title', $title)

@tech-mik
Copy link

tech-mik commented Nov 2, 2019

SOLVED!

Add this to your user settings, and the bug is gone:
"html.format.wrapLineLength": 0,

@slovenianGooner
Copy link

slovenianGooner commented Nov 20, 2019

There's a problem when using blade tags inside a <script> tag.

Screenshot 2019-11-20 at 21 04 06

Should be like this.

@if (isset($currentPage))
...
@else
...
@endif

@fzldn
Copy link
Author

fzldn commented Dec 19, 2019

@slovenianGooner sorry I can't handle php script inside inline js

@PhamBaTrungThanh
Copy link

PhamBaTrungThanh commented Feb 18, 2020

Much appreciated it.

But can you tell me how to use this alongside Laravel blade snippet though?


Nvm, I figured it out.

@Slivicon
Copy link

Slivicon commented Mar 16, 2020

This is the only solution I've found that actually attempts to indent blade directives, so thank you :) I did notice that {!! !!} syntax seems to get formatted unexpectedly now, not the same as {{ }}. Edit: Only when inside an html <script> tag, though, it seems. Inside that, a blade directive {!! !!} gets split to multiple lines, perhaps beautify trying to format it as JS, I'm not sure.

@sdebacker
Copy link

sdebacker commented Mar 19, 2020

Hello, thank for this. I had to add case 'show': in the list, to allow to support @show for a section like this:

@section('main')
    <p>Content of section</p>
@show

@maliouris
Copy link

maliouris commented Mar 31, 2020

I still get the error <blade section|(%26%2339%3Btitle%26%2339%3B%2C%20%26%2339%3BEdit%20details%20for%20%26%2339%3B%20.%20%24customer-%3Ename) /> when an if statement exceeds a line length and I dont think "html.format.wrapLineLength": 0 cause all in one line isn't a proper formating, is the solution. Has anyone come up with anything else ?

@maliouris
Copy link

I just solved it and you can watch how here https://gist.github.com/maliouris/f84b7f3dcb2a71455e693716e76ce302

@khaled-sadek
Copy link

I worked on a different solution.
I forked js-beautify and published a new package to format Blade files as HTML
you can find it from here: https://github.com/ThePlanet-Tech/js-beautify
I still need more contributors & testers to make sure everything is smooth and working fine.
you can install the package by npm install js-beautify-with-blade
then use it html-beautify -r resources/views/**/*.blade.php
you can also configure all the rules you want on .jsbeautifyrc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment