Skip to content

Commit a37a9cf

Browse files
committed
fix: shared template context injection
1 parent 35ca55a commit a37a9cf

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Liquid\Tags;
6+
7+
use Keepsuit\Liquid\Render\RenderContext;
8+
use Keepsuit\Liquid\Support\MissingValue;
9+
use Keepsuit\Liquid\Tags\RenderTag;
10+
11+
/**
12+
* Render tag that injects plugin context (trmnl, size, data, config) into partials
13+
* so shared templates can use variables like trmnl.user.name without passing them explicitly.
14+
*/
15+
class PluginRenderTag extends RenderTag
16+
{
17+
/**
18+
* Root-level keys from the plugin render context that should be available in partials.
19+
*
20+
* @var list<string>
21+
*/
22+
private const PARENT_CONTEXT_KEYS = ['trmnl', 'size', 'data', 'config'];
23+
24+
protected function buildPartialContext(RenderContext $rootContext, string $templateName, array $variables = []): RenderContext
25+
{
26+
$partialContext = $rootContext->newIsolatedSubContext($templateName);
27+
28+
foreach (self::PARENT_CONTEXT_KEYS as $key) {
29+
$value = $rootContext->get($key);
30+
if ($value !== null && ! $value instanceof MissingValue) {
31+
$partialContext->set($key, $value);
32+
}
33+
}
34+
35+
foreach ($variables as $key => $value) {
36+
$partialContext->set($key, $value);
37+
}
38+
39+
foreach ($this->attributes as $key => $value) {
40+
$partialContext->set($key, $rootContext->evaluate($value));
41+
}
42+
43+
return $partialContext;
44+
}
45+
}

app/Models/Plugin.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use App\Liquid\Filters\StandardFilters;
1111
use App\Liquid\Filters\StringMarkup;
1212
use App\Liquid\Filters\Uniqueness;
13+
use App\Liquid\Tags\PluginRenderTag;
1314
use App\Liquid\Tags\TemplateTag;
1415
use App\Services\Plugin\Parsers\ResponseParserRegistry;
1516
use App\Services\PluginImportService;
@@ -499,6 +500,8 @@ public function render(string $size = 'full', bool $standalone = true, ?Device $
499500

500501
// Register the template tag for inline templates
501502
$environment->tagRegistry->register(TemplateTag::class);
503+
// Use plugin render tag so partials receive trmnl, size, data, config
504+
$environment->tagRegistry->register(PluginRenderTag::class);
502505

503506
// Apply Liquid replacements (including 'with' syntax conversion)
504507
$processedMarkup = $this->applyLiquidReplacements($markup);

tests/Feature/PluginInlineTemplatesTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

33
use App\Models\Plugin;
4+
use App\Models\User;
45
use Illuminate\Foundation\Testing\RefreshDatabase;
56

67
uses(RefreshDatabase::class);
@@ -238,3 +239,34 @@
238239
$this->assertStringContainsString('"35":[{"name":"Ryan","age":35}]', $result);
239240
$this->assertStringContainsString('"29":[{"name":"Sara","age":29},{"name":"Jimbob","age":29}]', $result);
240241
});
242+
243+
test('shared template receives trmnl context when', function (): void {
244+
$user = User::factory()->create(['name' => 'Jane Smith']);
245+
246+
$plugin = Plugin::factory()->create([
247+
'user_id' => $user->id,
248+
'name' => 'Departures',
249+
'markup_language' => 'liquid',
250+
'render_markup_shared' => <<<'LIQUID'
251+
{% template departures_view %}
252+
<div class="title_bar">
253+
<span class="title">Departures</span>
254+
<span class="instance">{{ trmnl.user.name }}</span>
255+
</div>
256+
{% endtemplate %}
257+
LIQUID
258+
,
259+
'render_markup' => <<<'LIQUID'
260+
<div class="view">
261+
{% render "departures_view", station: "Hauptbahnhof" %}
262+
</div>
263+
LIQUID
264+
,
265+
'data_payload' => [],
266+
]);
267+
268+
$result = $plugin->render('full');
269+
270+
$this->assertStringContainsString('Jane Smith', $result);
271+
$this->assertStringContainsString('class="instance"', $result);
272+
});

0 commit comments

Comments
 (0)