FoilPHP/Foil

0.6.4 is now repeating content sections within a loop

Closed this issue · 8 comments

0.6.3 was running perfectly for my code. The item in the loop were iterated properly.
0.6.4 is now just dumping the same first item for every iteration.
all my code stayed the same. I just updated composer.

File: project_item.foil

<?php $this->section('itemsection')?>
<div class="job clearfix pitem" style="page-break-inside: avoid" id="<?=$this->v('project.htmlid','')?>">
    <div class="<?=$this->col1_css ?>">
            <?= $this->insert($this->v('itemlogosectionview','partials/itemlogo_psup')); ?>

           <?php $this->section('projectyearsection')?>
                <div class="year">
                <?=$this->v('project.year','')?>
                </div>
            <?php $this->replace()?>

            <?php $this->section('projectfeessection')?>
                <div class="year">
                <?=$this->v('project.fees')?>
                </div>
            <?php $this->replace()?>
        </div>
    </div>
<?php $this->replace() ?>

The foil above was called from File: body.foil

<?php foreach($this->majorProjects as $project):?>
    <?=$this->insert('partials/project_item',['project' => $project]) ?>
<?php endforeach; ?>

I suspect this change could be the reason, src/Section/Section.php
[https://github.com/FoilPHP/Foil/compare/0.6.3...0.6.4]

if (empty($this->mode)) {
             $this->mode = self::MODE_REPLACE;
         }
-        $this->content = ob_get_clean();
+        $buffer = ob_get_clean();
+        $this->content or $this->content = $buffer;
+        $this->content = ($this->mode & self::MODE_APPEND) ? $buffer.$this->content : $this->content;
         if ($this->mode & self::MODE_OUTPUT) {
             echo $this->content();
         }

Please suggest. Thanks.

Hi @thevikas sorry to year that. I'll look at this as soon as I can, but will not be before next week.

I hope thta for now you can require 0.6.3 to avoid the issue.

Thanks for reporting.

Already changed back to prev version. :)

@thevikas your code is quite complex... and I can't understand where all these sections are defined.

You are requiring project_item.foil in loop, and inside it replacing a section itemsection that I don't see defined anywhere.

Can you provide a Gist with (a semplified version of) the code you are suing so that I can easily reproduce the issue? Thanks.

@thevikas It seems I figured it out myself... and it was a simple fix.

I pushed to dev branch the fix. Can you please give it a try requiring Foil from dev-dev?

If it works for you this fix will be merged in v0.6.5.

Thanks.

just saw your messages. checked and your changes are keeping my views same. you can merge it. thanks a lot.

Happy to hear that, @thevikas

I am waiting for feedback on another open issue before releasing new version, so both fixes will be included.

Thanks for your interest and for reporting.

You are requiring project_item.foil in loop, and inside it replacing a section itemsection that I don't see defined anywhere.

how do you define sections?
i have refactored my complex views into many files with most sections in separate foil files.
that design is working for me except when sections are within loops. for that i have to work around.
then there are few other workarounds like overwritten sections are still called even though the last one is used. this can be fixed too.

@thevikas Well, normally, sections are not intented to be used like that.

The point of sections is to be able to be replaced / extended in a child template. If you have no child template, there's no reason to use sections at all.

Moreover, if you use the section in a loop, the ipotetical child template, which one should replace?

In short, you should not use sections in a loop. I don't see which is the benefit you want to gain from using sections there...

For example, imagine you gave a tample named projects.php, like this:

<div><h1>Projects</h1></div>

<?php $this->section('projects') ?>

<?php
foreach($this->v('projects ') as $project) {
  $this->insert( 'project', [ 'project' => $project ] );
}

<?php $this->stop() ?>

it requires in loop a partial named project.php that could be something like this:

<div id="<?= $this-v('project.id') ?>">
   <h3><?= $this-v('project.title') ?></h3>
   <p><?= $this-v('project.description') ?></p>
</div>

This works just fine without using sections.

If you use section inside the project.php template, those sections can't be replaced / extended anywhere, nor can replace / extend an already defined section, because parent template is not defining any section... so, which is the benefit to use section at all inside the partial?

On the contray, a child template can use projects.php (the one that contains the foreach) as layout by calling $this->layout('projects') and then edit projects section by adding more projects (extending the section with $this->append()) or completely replace projects by using $this->append().

This make sense, because adds flexibility to the template, but having sections in a loop, honestly is something that I can't find useful in any way.