Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link
Owner Author

@fzldn fzldn commented Aug 30, 2018

  1. install extension Beautify.

  2. add vscode settings:

    "beautify.language": {
        "js": {
            "type": [
                "javascript",
                "json",
                "jsonc"
            ],
            "filename": [
                ".jshintrc",
                ".jsbeautifyrc"
            ]
        },
        "css": [
            "css",
            "scss"
        ],
        "html": [
            "htm",
            "html",
            "blade"
        ]
    }
  3. edit ~/.vscode/extensions/hookyqr.beautify-1.5.0/node_modules/js-beautify/js/src/html/beautifier.js (Linux/MacOS) %USERPROFILE%\.vscode\extensions\hookyqr.beautify-1.5.0\node_modules\js-beautify\js\src\html\beautifier.js (Windows) and add the code from the gist.

  4. Restart VS Code.

  5. IMPORTANT: Every time when HookyQR.beautify is updated, check whether the fix is still in place and re-apply if needed.

@WeeHong

This comment has been minimized.

Copy link

@WeeHong WeeHong commented Sep 4, 2018

For Windows User: %USERPROFILE%\.vscode\extensions\hookyqr.beautify-1.4.2\node_modules\js-beautify\js\src\html\beautifier.js

@fzldn

This comment has been minimized.

Copy link
Owner Author

@fzldn fzldn commented Sep 7, 2018

thanks for feedback, have you test on Windows @WeeHong? I worried about \n char on windows.

@HectorBritoDev

This comment has been minimized.

Copy link

@HectorBritoDev HectorBritoDev commented Sep 16, 2018

@fzldn Thanks for the great job, i appreciate a lot. Just a little "bug" with @else

// Before

@section('content')
@if($page == 1)
{!! $page1 !!}
@else
{!! $page2 !!}
@endif
@endsection 

//After

@section('content')
    @if($page == 1)
          {!! $page1 !!}
@else
          {!! $page2 !!}
    @endif
@endsection 

@fzldn

This comment has been minimized.

Copy link
Owner Author

@fzldn fzldn commented Sep 20, 2018

@HectorBritoDev thanks for report, but I tested on Beautifier 1.4.3 seems works fine.
// Before

@section('content')
@if($page == 1)
{!! $page1 !!}
@else
{!! $page2 !!}
@endif
@endsection

// After

@section('content')
@if($page == 1)
    {!! $page1 !!}
@else
    {!! $page2 !!}
@endif
@endsection

I don't put extra indent inside section, because section not always ending by endsection

@karlrmitchell

This comment has been minimized.

Copy link

@karlrmitchell karlrmitchell commented Oct 9, 2018

The changes don't appear to work with hookyqr.beautify-1.4.4? The changes appear valid but don't appear to format blade documents at all.

@fzldn

This comment has been minimized.

Copy link
Owner Author

@fzldn fzldn commented Oct 10, 2018

The changes don't appear to work with hookyqr.beautify-1.4.4? The changes appear valid but don't appear to format blade documents at all.

@karlrmitchell I updated the gist, please re-apply for hookyqr.beautify-1.4.4

@fzldn

This comment has been minimized.

Copy link
Owner Author

@fzldn fzldn commented Oct 10, 2018

This adds new lines everywhere thereby expanding the file.
After every @(...) it adds a new line even when one already exists.

@Onyekaljeh can you give an example?

@OnyekaIjeh

This comment has been minimized.

Copy link

@OnyekaIjeh OnyekaIjeh commented Nov 10, 2018

This adds new lines everywhere thereby expanding the file.
After every @(...) it adds a new line even when one already exists.

@Onyekaljeh can you give an example?

Working fine now. Thanks @fldn

@mohamedsabil83

This comment has been minimized.

Copy link

@mohamedsabil83 mohamedsabil83 commented Dec 14, 2018

Work like a charm. Thank you v.much.

@shamilovtim

This comment has been minimized.

Copy link

@shamilovtim shamilovtim commented Dec 14, 2018

Hello, excellent gist. The following breaks the code:

Execute command: beautify
Input:

@if ( (auth::user() && auth::user()->isAdmin() && (isset($vote)) && isset($content)))

Result:

<blade
if|%20(isset(%24campaign-%3Ecampaignwrapup-%3Etotal_impressions)%20%20%26%26%20%24campaign-%3Ecampaignwrapup-%3Etotal_impressions%20)>

Also all blade within script tags is broken:

Execute command: beautify
Input:

@if (isset($campaign))

Result:

<
blade
if | % 20(isset( % 24 campaign)) >

@fzldn

This comment has been minimized.

Copy link
Owner Author

@fzldn fzldn commented Jan 18, 2019

Hello, excellent gist. The following breaks the code:

Execute command: beautify
Input:

@if ( (auth::user() && auth::user()->isAdmin() && (isset($vote)) && isset($content)))

Result:

<blade
if|%20(isset(%24campaign-%3Ecampaignwrapup-%3Etotal_impressions)%20%20%26%26%20%24campaign-%3Ecampaignwrapup-%3Etotal_impressions%20)>

Also all blade within script tags is broken:

Execute command: beautify
Input:

@if (isset($campaign))

Result:

<
blade
if | % 20(isset( % 24 campaign)) >

seem to work fine in hookyqr.beautify-1.4.7

@mreduar

This comment has been minimized.

Copy link

@mreduar mreduar commented Feb 3, 2019

Excelent! Thanks for this!! <3

@mohamedsabil83

This comment has been minimized.

Copy link

@mohamedsabil83 mohamedsabil83 commented Apr 8, 2019

Thank you for this workaround. but I face this situation:

@for ($i = 0; $i < $count; $i++)
    
@endfor

become:

@for ($i = 0; $i <
    $count;
    $i++)
    @endfor

Any idea how to solve it?

@fzldn

This comment has been minimized.

Copy link
Owner Author

@fzldn fzldn commented Apr 10, 2019

@mohamedsabil83 tested on Beautify 1.4.11 and seems work well

@mohamedsabil83

This comment has been minimized.

Copy link

@mohamedsabil83 mohamedsabil83 commented Apr 10, 2019

I just updated to 1.4.11 and just become:

@for ($i = 0; $i < $count;
  $i++)
  @endfor

can you share your beautify-html.js with me to confirm if I missed something in mine?
Edit: Also, try to put the hack in beautifier.js instead of beautify-html.js and same result.

@aeadedoyin

This comment has been minimized.

Copy link

@aeadedoyin aeadedoyin commented Jul 2, 2019

Hello, excellent gist. The following breaks the code:
Execute command: beautify
Input:

@if ( (auth::user() && auth::user()->isAdmin() && (isset($vote)) && isset($content)))

Result:

<blade
if|%20(isset(%24campaign-%3Ecampaignwrapup-%3Etotal_impressions)%20%20%26%26%20%24campaign-%3Ecampaignwrapup-%3Etotal_impressions%20)>

Also all blade within script tags is broken:
Execute command: beautify
Input:

@if (isset($campaign))

Result:

<
blade
if | % 20(isset( % 24 campaign)) >

seem to work fine in hookyqr.beautify-1.4.7

Gives the same error in 1.5.0 any fix for this?

@fzldn

This comment has been minimized.

Copy link
Owner Author

@fzldn fzldn commented Jul 2, 2019

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

@aeadedoyin

This comment has been minimized.

Copy link

@aeadedoyin aeadedoyin commented Jul 2, 2019

@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>
@fzldn

This comment has been minimized.

Copy link
Owner Author

@fzldn fzldn commented Jul 2, 2019

@aeadedoyin hmmm, weird. I tested in my local machine it works fine

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

This comment has been minimized.

Copy link

@mohamedsabil83 mohamedsabil83 commented Jul 2, 2019

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

Yes, @fzldn, the @for directive formatted as expected now. Thank you for fixing patch.

@aeadedoyin

This comment has been minimized.

Copy link

@aeadedoyin aeadedoyin commented Jul 2, 2019

@aeadedoyin hmmm, weird. I tested in my local machine it works fine

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

Okay, I will send the full code so try that too.

@fzldn

This comment has been minimized.

Copy link
Owner Author

@fzldn fzldn commented Jul 2, 2019

@aeadedoyin seems works fine

@aeadedoyin

This comment has been minimized.

Copy link

@aeadedoyin aeadedoyin commented Jul 2, 2019

@fzldn
I really do not know what's wrong.
Maybe I am not getting the beautifier.js editing right.
Please, can you just share the full thing so I am sure I am not misplacing anything.

@fzldn

This comment has been minimized.

Copy link
Owner Author

@fzldn fzldn commented Jul 2, 2019

@aeadedoyin make sure you follow the instructions as well

@aeadedoyin

This comment has been minimized.

Copy link

@aeadedoyin aeadedoyin commented Jul 2, 2019

@fzldn
I sure did, step by step. I didn't miss out on anything.

@mohamedsabil83

This comment has been minimized.

Copy link

@mohamedsabil83 mohamedsabil83 commented Jul 2, 2019

@aeadedoyin check your version. Be sure it's 1.5.0. Also, if you want, I can send you a copy of the file to replace it with yours and test if that's work

@aeadedoyin

This comment has been minimized.

Copy link

@aeadedoyin aeadedoyin commented Jul 2, 2019

@aeadedoyin check your version. Be sure it's 1.5.0. Also, if you want, I can send you a copy of the file to replace it with yours and test if that's work

I would appreciate thanks!

@mohamedsabil83

This comment has been minimized.

Copy link

@mohamedsabil83 mohamedsabil83 commented Jul 2, 2019

I pastebin it. This is the URL: https://pastebin.com/nWaxkTaq

@mohamedsabil83

This comment has been minimized.

Copy link

@mohamedsabil83 mohamedsabil83 commented Jul 3, 2019

@fzldn, I notice something after applying your patch. When using custom directive from other packages, eg. @javascript in spatie/laravel-blade-javascript, the following lines got an extra indentation.
wrong-indentation

@mohamedsabil83

This comment has been minimized.

Copy link

@mohamedsabil83 mohamedsabil83 commented Jul 6, 2019

According to my previous comment, I want to correct a point, the extra indentation affected after using any single directive, I mean by that any directive doesn't need @enddirective like @dump

@mreduar

This comment has been minimized.

Copy link

@mreduar mreduar commented Jul 13, 2019

I got a little problem formatting with the forelse sentence.

Expected:

@forelse ($users as $user)
    <li>{{ $user->name }}</li>
@empty
    <p>No users</p>
@endforelse

Obtained

@forelse($users as $user)
    <li>{{ $user->name }}</li>
    @empty
    <p>No users</p>
@endforelse

Which would be practically the same problem as the previous comment.

@fzldn

This comment has been minimized.

Copy link
Owner Author

@fzldn fzldn commented Jul 16, 2019

@Zontir gist updated with @empty no need extra indentation

@mreduar

This comment has been minimized.

Copy link

@mreduar mreduar commented Jul 16, 2019

Thanks! :)

@brandonfredericksen

This comment has been minimized.

Copy link

@brandonfredericksen brandonfredericksen commented Jul 18, 2019

much appreciated 👍

@brandonfredericksen

This comment has been minimized.

Copy link

@brandonfredericksen brandonfredericksen commented Jul 18, 2019

@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

This comment has been minimized.

Copy link

@mreduar 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

This comment has been minimized.

Copy link

@mohamedsabil83 mohamedsabil83 commented Jul 24, 2019

@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

This comment has been minimized.

Copy link

@mreduar 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

This comment has been minimized.

Copy link

@mohamedsabil83 mohamedsabil83 commented Jul 25, 2019

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

@mohamedsabil83

This comment has been minimized.

Copy link

@mohamedsabil83 mohamedsabil83 commented Aug 15, 2019

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

This comment has been minimized.

Copy link
Owner Author

@fzldn 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

This comment has been minimized.

Copy link

@mreduar 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

This comment has been minimized.

Copy link

@mohamedsabil83 mohamedsabil83 commented Aug 16, 2019

@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

This comment has been minimized.

Copy link

@lrpinto 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
    ]
    ]
    ])
@rashid786786

This comment has been minimized.

Copy link

@rashid786786 rashid786786 commented Oct 7, 2019

not working in beautify 1.5.0

@mikkert

This comment has been minimized.

Copy link

@mikkert mikkert commented Oct 30, 2019

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

@mikkert

This comment has been minimized.

Copy link

@mikkert mikkert commented Oct 31, 2019

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

This comment has been minimized.

Copy link

@lrpinto lrpinto commented Nov 1, 2019

@mikkert

This comment has been minimized.

Copy link

@mikkert mikkert 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)

@mikkert

This comment has been minimized.

Copy link

@mikkert mikkert commented Nov 2, 2019

SOLVED!

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

@slovenianGooner

This comment has been minimized.

Copy link

@slovenianGooner 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

This comment has been minimized.

Copy link
Owner Author

@fzldn fzldn commented Dec 19, 2019

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

@PhamBaTrungThanh

This comment has been minimized.

Copy link

@PhamBaTrungThanh 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

This comment has been minimized.

Copy link

@Slivicon 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

This comment has been minimized.

Copy link

@sdebacker 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

This comment has been minimized.

Copy link

@maliouris 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

This comment has been minimized.

Copy link

@maliouris maliouris commented Mar 31, 2020

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

@khaled-sadek

This comment has been minimized.

Copy link

@khaled-sadek khaled-sadek commented Jun 6, 2021

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