Stillat / blade-parser-typescript

A Laravel Blade parser, compiler, and static analyzer written in TypeScript.
https://stillat.com
MIT License
82 stars 2 forks source link

foreach loop variables becomes broken #94

Closed cyppe closed 6 months ago

cyppe commented 6 months ago

I am using this package through prettier/pint based on this instruction:

https://helgesver.re/articles/laravel-blade-formatter-prettier

It seems to work pretty good, but I notice it breaks foreach loops.

@foreach($closeOutProducts as $closeProduct)

becomes

@foreach (OutProducts as $closeProduct)

Diff before vs. after running: npm run format

image image image

Am I doing something wrong? Seems like too obvious issue to be common.

JohnathonKoster commented 6 months ago

That's definitely odd... i couldn't reproduce with a quick test. Would you be able to share the full original template and any custom Pint settings you may have? Something might be confusing it and causing that.

cyppe commented 6 months ago

Of course!

Here is one full blade template as example. It's not pretty, but that's why I started to look into ways to improve them. :-)

@section('script')
    @parent

    <script>

        $(function() {
            $('#ma-closeOutBtn').click(function(e){
                e.stopPropagation();
                e.preventDefault();

                if($('input[name="property_clouseout"]').length){
                    //if(!$('input[name="property_clouseout"]').is(':checked')){
                        @if(isset($browser_detect) && $browser_detect)
                            $('input[name="property_clouseout"]').next().click();
                        @else
                            $('input[name="property_clouseout"]').parent().click();
                        @endif

                    setTimeout(function(){
                            $('html, body').animate({ scrollTop: $('.sort-placer').offset().top -80 }, 'slow');
                    }, 1000);

                    //}
                }

            });
        });

    </script>

@stop

<div class="col-12 col-lg-12 d-md-none" style="margin-bottom:25px;">
        <div class="ma-productlist-closeout">
        <img loading="lazy" src="/images/ma-mobile-productlist-closeout-bg.jpg" class="ma-productlist-closeout-mobile_bg img-fluid">
        <img loading="lazy" src="/images/ma-tablet-productlist-closeout-bg.jpg" class="ma-productlist-closeout-tablet_bg img-fluid">

        <div class="ma-closeout-prod-container">
            @foreach($closeOutProducts as $closeProduct)

                <?php $check_vehicle_item = false; ?>

                @if( (isset($vid_selected_bike) && $vid_selected_bike != '') && (isset($closeProduct['check_variant_fit_vehicle']) && $closeProduct['check_variant_fit_vehicle'] != '') )
                    <?php $check_vehicle_item = true; ?>
                @endif

                <?php $product_price = $closeProduct['price']; ?>

                @if(isset($closeProduct['variants'][0]['price']) && $closeProduct['variants'][0]['price'] > 0)
                    <?php $product_price = $closeProduct['variants'][0]['price']; ?>
                @endif

                @if(!$check_vehicle_item && isset($closeProduct['smallest_price']) && $closeProduct['smallest_price'] < $product_price && $closeProduct['smallest_price'] > 0)
                    <?php $product_price = $closeProduct['smallest_price']; ?>
                @endif

                @if(isset($closeProduct['is_package']) && $closeProduct['is_package'])
                    <?php $product_price = $closeProduct['total_package_price']; ?>
                @endif

                @if($closeProduct['rek_price'] > 0)
                    <?php $product_rek_price = $closeProduct['rek_price']; ?>

                    @if(isset($closeProduct['variants'][0]['rek_price']) && $closeProduct['variants'][0]['rek_price'] > 0 && $closeProduct['variants'][0]['rek_price'] > $product_price)
                        <?php $product_rek_price = $closeProduct['variants'][0]['rek_price']; ?>
                    @endif

                    @if(!$check_vehicle_item && isset($closeProduct['smallest_rek_price']) && $closeProduct['smallest_rek_price'] < $product_rek_price && (int)$closeProduct['smallest_rek_price'] > 0 &&  $closeProduct['smallest_rek_price'] > $product_price)
                        <?php $product_rek_price = $closeProduct['smallest_rek_price']; ?>
                    @endif

                    @if(isset($closeProduct['is_package']) && $closeProduct['is_package'] == 1 && isset($closeProduct['total_package_rek_price']) && $closeProduct['total_package_rek_price'] > 0 )
                        <?php $product_rek_price = $closeProduct['total_package_rek_price']; ?>
                    @endif

                    <?php $rabatt = (1 - ((float)$product_price/(float)$product_rek_price))*100 ?>

                    <div class="ma-closeout-prod-container-item">
                        <a href="{{$closeProduct['url']}}">
                            @if(isset($closeProduct['images']))
                                <img loading="lazy" alt="{{$closeProduct['name']}}" src="{{$closeProduct['images'][0]['images'][8]}}" class="img-fluid" />
                            @else
                                <img loading="lazy" alt="{{$closeProduct['name']}}" src="{{config('configuration.CDN_ADDRESS')}}image.php?src=empty.jpg&w=256&h=256&q=80&version=100" class="img-fluid" />
                            @endif
                            <p>- {{round($rabatt)}} %</p>
                        </a>
                    </div>

                @endif

            @endforeach
        </div>

        <div id="ma-closeOutBtn">
            <div class="col-12 d-block d-sm-none">
                <button type="button" class="btn btn-outline-danger" style="margin-top: 40px;">VISA ALLA</button>
            </div>
            <img loading="lazy" src="{{config('configuration.CDN_ADDRESS')}}closeout_2019_badge_desktop.png" class="ma-closeOutBtnBadge d-none d-sm-block">
        </div>

    </div>
</div>

I have quite a lot of settings in my pint.json might be it?

I actually don't fullt understand how pint comes into play based on the article. I don't mind if it's being integrated with pine but don't understand how it's being used. Calling pint on whole project right now does not touch any blade templates so at least it does not seem to be integrated in that direction. Can you explain how it's supposed to use pint or point me to some document if it exists.

Anyway...

My pint.json

{
  "preset": "per",
  "rules": {
    "align_multiline_comment": true,
    "array_indentation": true,
    "array_syntax": true,
    "blank_line_after_namespace": true,
    "blank_line_after_opening_tag": true,
    "combine_consecutive_issets": true,
    "combine_consecutive_unsets": true,
    "concat_space": {
      "spacing": "one"
    },
    "binary_operator_spaces": {
      "operators": {
        "=>": "align_single_space_minimal",
        "=": "align_single_space_minimal"
      }
    },
    "braces_position": {
      "allow_single_line_anonymous_functions": true,
      "allow_single_line_empty_anonymous_classes": true,
      "anonymous_classes_opening_brace": "same_line",
      "anonymous_functions_opening_brace": "same_line",
      "classes_opening_brace": "next_line_unless_newline_at_signature_end",
      "control_structures_opening_brace": "same_line",
      "functions_opening_brace": "next_line_unless_newline_at_signature_end"
    },
    "no_extra_blank_lines": {
      "tokens": [
        "extra",
        "throw",
        "use",
        "return",
        "parenthesis_brace_block",
        "square_brace_block",
        "curly_brace_block"
      ]
    },
    "blank_line_before_statement": {
      "statements": [
        "return",
        "try"
      ]
    },
    "declare_parentheses": true,
    "global_namespace_import": {
      "import_classes": true,
      "import_constants": true,
      "import_functions": true
    },
    "is_null": true,
    "lambda_not_used_import": true,
    "logical_operators": true,
    "mb_str_functions": true,
    "method_chaining_indentation": true,
    "modernize_strpos": true,
    "new_with_braces": true,
    "no_empty_comment": false,
    "not_operator_with_space": true,
    "ordered_traits": true,
    "simplified_if_return": true,
    "ternary_to_null_coalescing": true,
    "trim_array_spaces": true,
    "use_arrow_functions": false,
    "void_return": false,
    "yoda_style": true,
    "array_push": true,
    "assign_null_coalescing_to_coalesce_equal": true,
    "explicit_indirect_variable": true,
    "method_argument_space": {
      "on_multiline": "ensure_fully_multiline"
    },
    "modernize_types_casting": true,
    "no_superfluous_elseif": true,
    "no_useless_else": true,
    "nullable_type_declaration_for_default_null_value": true,
    "ordered_imports": {
      "sort_algorithm": "alpha"
    },
    "ordered_class_elements": {
      "order": [
        "use_trait",
        "case",
        "constant",
        "constant_public",
        "constant_protected",
        "constant_private",
        "property_public",
        "property_protected",
        "property_private",
        "construct",
        "destruct",
        "magic",
        "phpunit",
        "method_abstract",
        "method_public_static",
        "method_public",
        "method_protected_static",
        "method_protected",
        "method_private_static",
        "method_private"
      ],
      "sort_algorithm": "none"
    }
  }
}
cyppe commented 6 months ago

Fyi - I tried now to change .blade.format.json into

{
  "useLaravelPint": false
}

And without having much time to review the result, at least I can see that it did not break the foreach loops. So somehow pint is involved.

JohnathonKoster commented 6 months ago

The Blade formatter will do some extra processing to extract directive parameters/PHP blocks and run them through Laravel Pint in the background for you (to have consistent PHP formatting, even in Blade files). I have some docs about this feature here: https://stillat.com/blade-parser/v1/formatting-configuration#content-configuring-laravel-pint

I'll take a look at your Pint configuration this evening to see if I can track down the root cause and get a fix rolling. Thanks for all the extra info!

JohnathonKoster commented 6 months ago

Issue was tracked down to the selected preset adjusting the spacing between foreach ( and its content. Fix is available in v2.1.5