Foil
Foil copied to clipboard
Duplicate code with nested sections
I have the following setup: The layout defines sections:
<!DOCTYPE html>
<html>
<head>
<title><?= $this->e('title') ?></title>
<?php $this->section('head'); $this->stop(); ?>
</head>
<body>
<?php $this->section('content');$this->stop(); ?>
<?php $this->section('end-body');$this->stop(); ?>
</body>
</html>
Then there is the template appending some content to the content section of the layout. Some of the content is loaded by including a partial:
<?php $this->layout('layout::page', ['title' => 'Page title']) ?>
<?php $this->section('content') ?>
<h1>Test</h1>
<?= $this->insert('partials::date-input'); ?>
<?php $this->append() ?>
The partial references a JS file (which should be appended to the "end-body" section of the layout) and some HTML which should be inserted whereever $this->insert('partial-name') is called.
<?php $this->section('end-body') ?>
<script src="/jquery.min.js"></script>
<script src="/intercooler.js"></script>
<?php $this->append() ?>
<div ic-get-from="<url>" ic-trigger-on="scrolled-into-view"></div>
The result is:
<!DOCTYPE html>
<html>
<head>
<title>Page title</title>
</head>
<body>
<h1>Test</h1>
<script src="/jquery.min.js"></script>
<script src="/intercooler.js"></script>
<div ic-get-from="<url>" ic-trigger-on="scrolled-into-view"></div>
<script src="/jquery.min.js"></script>
<script src="/intercooler.js"></script>
</body>
</html>
So the JS files get embedded twice. I am quite sure that I did something wrong but perhaps this really is a bug.
Hi @janwalther thanks for your interest in Foil and the detailed issue.
And sorry for the trouble.
I think this is a regression bug that has been introduced with a section handling change I did in a previous release to fix a another bug. And it was not catched because missing test...
Can you please test if the bus is still there if you use stop()
/ replace()
instead of append()
?
An unrelated thing:
you could replace your:
<?php $this->section('content'); $this->stop(); ?>
with
<?php $this->supply('content') ?>
The reason to be of supply()
is just that: render section content if it exists, or do nothing if not.
Same result with the following partial code (JS files get included twice):
<?php $this->section('end-body') ?>
<script src="/jquery.min.js"></script>
<script src="/intercooler.js"></script>
<?php $this->stop() ?>
<div ic-get-from="<url>" ic-trigger-on="scrolled-into-view"></div>
And also with $this->replace(). And in the end I would have to use append because there could be multiple partials which all want to append JS file embedding to "end-body" section.
Thanks for mentioning $this->supply(). I replaced all $this->section('name');$this->stop() with $this->supply('name'); but as said the JS files get included twice.
Thank.
And yes, supply('name')
is just a shorcut for $this->section('name'); $this->stop()
won't solve the issue.
It definetively worked before, so it is a regression bug, I'll try to fix as soon as possible.