Change variable value in partials

Hi,

I didn’t find how to this simple thing and I don’t know what’s the best approach.

This is my front-page.blade.php:

@extends('layouts.app')

@section('content')
  @while(have_posts()) @php the_post() @endphp
    @include('partials.page-header')
    @php $simple_boolean = true @endphp
    @include('partials.content-front-page')
    {{ $simple_boolean }}
  @endwhile
@endsection

This is my content-front-page.blade.php:

@php $simple_boolean = false @endphp

If I print $simple_boolean variable I get the value true even if I have changed its value to false in the content-front-page.blade.php.

I’ve to do this with a controller? If yes, how?

Thank you so much for the help and sorry for the stupid question. :disappointed:

Can you explain what you need the conditional boolean for? It seems like the conditional will always be true.

You seem to be making the assuming that Blade’s @include is equivalent to PHP’s include() which is not the case. Blades receive variables from two places (AFAIK):

  • The controller (or controller-like structure)
  • Variables which are directly passed to them

The second is done as follows: @include('partials.some-blade', array('variable_name' => $variable_data).

IMO your problem is because you are treating Blade as if it is just PHP, not a templating language. Setting variables in your Blades will not always work the way you want for this reason. To allow for some of Blade’s features, your Blade is not simply executed top to bottom, pulling in all partials, as you might see in a plain PHP script. Your variable, whatever it is, should be set at the controller level (either with Controller, or with Sage’s filters). I don’t understand what it is your code is meant to accomplish, so it’s difficult for me to suggest how you might accomplish it. I lean toward processing my own data at the controller level, and sending on the data I need (instead of relying on WordPress’s loops). Here is a post I made about that technique.

Sorry, to make it simple I’ve cut out some code. I’m trying to do a dynamic flexbox structure for the front page. Every box is a relation selected via a custom field in the front page backend.

This is the front-page.php controller:

public function boxes()
    {
        $boxes = [];

        if (have_rows('boxes')) {
            while (have_rows('boxes')) {
                the_row();
                $box = get_sub_field('relation')[0];
                $box->box_size = get_sub_field('size'); // size is 'full' or 'half'
                $boxes[] = $box;
            }
        }
        return $boxes;
    }

This is the front-page.blade.php:

@extends('layouts.app')

@section('content')
  @while(have_posts()) @php the_post() @endphp
    @include('partials.page-header')
    <div class="d-lg-flex flex-row flex-wrap mt-3 w-100">
      @php $first_half = true @endphp
      @foreach ($boxes as $box)
        @include('partials.content-front-page')
      @endforeach
    </div>
  @endwhile
@endsection

This is the content-front-page.blade.php:

@if ($box->post_box_size === 'full')
  <div class="bg-dark d-flex justify-content-center align-items-center p-3 box mb-3 w-100 box-full">
    <div class="text-white text-center box-text col-md-5">
      <h2 class="h1">{{ $box->post_title }}</h2>
      <p class="lead">{{ $box->post_excerpt }}</p>
    </div>
  </div>
@elseif ($box->post_box_size === 'half')
  @if ($first_half) 
    @php $first_half = false @endphp
    <div class="bg-dark d-flex justify-content-center align-items-center p-3 box mb-3 mr-lg-3 box-half">
      <div class="text-white text-center box-text col-md-8">
        <h2 class="h1">{{ $box->post_title }}</h2>
        <p class="lead">{{ $box->post_excerpt }}</p>
      </div>
    </div>
  @else
    @php $first_half = true @endphp
    <div class="bg-dark d-flex justify-content-center align-items-center p-3 box mb-3 box-half">
      <div class="text-white text-center box-text col-md-8">
        <h2 class="h1">{{ $box->post_title }}</h2>
        <p class="lead">{{ $box->post_excerpt }}</p>
      </div>
    </div>
  @endif
@endif

This code conditionally checks if the size of the box has to be full or half and if it’s half, based on the boolean variable, prints different classes for the first half and for the second half.

The problem is not related to the WordPress loop, because in the front page runs only once.

Now I’ve managed to do this in a different way and I’ve improved the code to avoid repeating the same HTML structure 3 times. But I would like to understand how I could solve this problem, to understand how to do it in the future.

I’ve understood what @alwaysblank said, but I’ve not figured out well how to solve this with his advice. If I pass a variable to the partial like suggested, can I change its value inside the partial and see it updated in the main template?

I know that’s not a well-written code, but I’m working on this. I still have to learn how to properly use Blade. :sweat_smile:

There’s no reason to do this, and it’s bad practice. Avoid logic in your Blades as much as possible.

front-page.blade.php doesn’t need to “know” the value of that variable: only content-front-page.blade.php does, and the value of the variable is not dependent on the Blade, it’s dependent on your data, so you should be setting it at the controller level. i.e., something like this:

// front-page.php

$first_half = false;
while (have_rows('boxes')) {
   the_row();
   $box = get_sub_field('relation')[0];
   $box->box_size = get_sub_field('size'); // size is 'full' or 'half'
   if ('half' === $box->box_size) {
      $first_half = !$first_half;
      $box->first_half = $first_half;
   } else {
      $box->first_half = null; // In case you accidentally check this prop on a full box
   }   
   $boxes[] = $box;
}

Then in your partial just needs to check $box->first_half and you don’t need to set any variables in your Blade.

3 Likes

Thank you so much! Now it’s all clear, I’ve to do all the logic operations in the controller that serves the array of data to print in the view. :slight_smile: