Skip to content

Commit bb60599

Browse files
committed
LatteEngine update
1 parent 3c659eb commit bb60599

4 files changed

Lines changed: 97 additions & 44 deletions

File tree

src/Shared/Core/App.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,10 @@ public function run(): void
138138
LanguageManager::init();
139139

140140
$engine = match ($_ENV['VIEW_ENGINE'] ?? 'latte') {
141-
'blade' => new BladeEngine(),
142-
default => new LatteEngine(),
141+
'blade' => new BladeEngine($auth, $request),
142+
default => new LatteEngine($auth, $request),
143143
};
144144

145-
$engine->setAuth($auth);
146-
147145
View::setEngine($engine);
148146

149147
$this->initPlugins($auth);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace Ivy\Template\Infrastructure\Renderer;
4+
5+
use Latte\Engine;
6+
use Ivy\Template\Infrastructure\Manager\TemplateManager;
7+
8+
final class ButtonRenderer
9+
{
10+
private array $templateCache = [];
11+
12+
public function __construct(
13+
private Engine $latte,
14+
private TemplateManager $templates
15+
) {}
16+
17+
public function render(array $args): string
18+
{
19+
$type = $args['type'] ?? null;
20+
21+
if (!$type) {
22+
throw new \InvalidArgumentException('Button type missing');
23+
}
24+
25+
$file = $this->templateCache[$type]
26+
??= $this->templates->file("buttons/button.$type.latte");
27+
28+
if (!$file) {
29+
throw new \RuntimeException("Button '{$type}' not found");
30+
}
31+
32+
return $this->latte->renderToString($file, $args);
33+
}
34+
}

src/Template/Presentation/Tag/ButtonNode.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,17 @@ public static function create(Tag $tag): self
2222
public function print(PrintContext $context): string
2323
{
2424
return $context->format(
25-
'echo ($this->global->customButtonRender)(%node);',
25+
<<<'PHP'
26+
$args = %node;
27+
28+
$file = \Ivy\Template\Infrastructure\Manager\TemplateManager::file(
29+
'buttons/button.' . ($args['type'] ?? 'default') . '.latte'
30+
);
31+
32+
if ($file) {
33+
$this->createTemplate($file, $args, 'include')->render();
34+
}
35+
PHP,
2636
$this->args
2737
);
2838
}

src/Template/Presentation/View/Engine/LatteEngine.php

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,19 @@
2121
use Ivy\Shared\Core\Path;
2222
use Ivy\Plugin\Infrastructure\Registry\PluginRegistry;
2323
use Ivy\Template\Presentation\Tag\ButtonTag;
24+
use Symfony\Component\HttpFoundation\Request;
2425

2526
class LatteEngine implements ViewEngineInterface
2627
{
2728
private Engine $latte;
2829
private AuthService $auth;
30+
private Request $request;
2931

30-
31-
public function __construct()
32+
public function __construct(AuthService $auth, Request $request)
3233
{
3334
$this->latte = new Engine();
34-
}
35-
36-
public function setAuth(AuthService $auth): void
37-
{
3835
$this->auth = $auth;
36+
$this->request = $request;
3937
}
4038

4139
public function boot(): void
@@ -71,7 +69,7 @@ public function getEngine(): Engine
7169
private function registerFunctions(): void
7270
{
7371
$this->latte->addFunction('icon', fn ($icon) =>
74-
file_get_contents(Path::get('MEDIA_PATH') . 'icons/' . $icon)
72+
file_get_contents(Path::get('MEDIA_PATH') . 'icons/' . $icon)
7573
);
7674

7775
$this->latte->addFunction('text', fn ($key, $vars = null) =>
@@ -89,11 +87,7 @@ private function registerFunctions(): void
8987
);
9088

9189
$this->latte->addFunction('file', fn ($key) =>
92-
TemplateManager::file($key)
93-
);
94-
95-
$this->latte->addFunction('render', fn ($key, $vars = []) =>
96-
View::render($key, $vars)
90+
TemplateManager::file($key)
9791
);
9892

9993
$this->latte->addFunction('info', fn ($key) =>
@@ -109,75 +103,99 @@ private function registerFunctions(): void
109103
);
110104

111105
$this->latte->addFunction('isPluginActive', fn (string $key): bool =>
112-
PluginRegistry::isActive($key)
106+
PluginRegistry::isActive($key)
113107
);
114108

115109
$this->latte->addFunction('csrf', fn () =>
116-
new Html('<input type="hidden" name="csrf_token" value="' . CsrfManager::token() . '">')
110+
new Html('<input type="hidden" name="csrf_token" value="' . CsrfManager::token() . '">')
117111
);
118112

119113
$this->latte->addFunction('canEditAsEditor', fn () =>
120-
$this->auth->canEditAsEditor()
114+
$this->auth->canEditAsEditor()
121115
);
122116

123117
$this->latte->addFunction('canEditAsAdmin', fn () =>
124-
$this->auth->canEditAsAdmin()
118+
$this->auth->canEditAsAdmin()
125119
);
126120

127121
$this->latte->addFunction('canEditAsSuperAdmin', fn () =>
128-
$this->auth->canEditAsSuperAdmin()
122+
$this->auth->canEditAsSuperAdmin()
129123
);
130124

131125
$this->latte->addFunction('doesUserHaveRole', fn ($user, $role) =>
132-
$this->auth->auth()->admin()->doesUserHaveRole($user, $role)
126+
$this->auth->auth()->admin()->doesUserHaveRole($user, $role)
133127
);
134128

135129
$this->latte->addFunction('authRoles', fn () =>
136-
$this->auth->auth()->getRoles()
130+
$this->auth->auth()->getRoles()
137131
);
138132

139133
$this->latte->addFunction('authUser', fn () =>
140-
$this->auth->authUser()
134+
$this->auth->authUser()
141135
);
142136

143137
$this->latte->addFunction('authProfile', fn () =>
144-
$this->auth->authProfile()
138+
$this->auth->authProfile()
145139
);
146140

147141
$this->latte->addFunction('isLoggedIn', fn () =>
148-
$this->auth->isLoggedIn()
142+
$this->auth->isLoggedIn()
149143
);
150144

151145
$this->latte->addFunction('can', fn ($action, $model) =>
152-
(bool) $this->auth->can($action, $model)
146+
(bool) $this->auth->can($action, $model)
153147
);
154148

155149
$this->latte->addFunction('hook', fn ($key) =>
156-
HookManager::do($key)
150+
HookManager::do($key)
157151
);
158152

159153
$this->latte->addFunction('csp', fn () =>
160-
SecurityManager::getNonce()
154+
SecurityManager::getNonce()
161155
);
162156

163157
$this->latte->addFunction('cssFiles', fn () =>
164-
AssetManager::getCSS()
158+
AssetManager::getCSS()
165159
);
166160

167161
$this->latte->addFunction('jsFiles', fn () =>
168-
AssetManager::getJS()
162+
AssetManager::getJS()
169163
);
170164

171165
$this->latte->addFunction('moduleFiles', fn () =>
172-
AssetManager::getModules()
166+
AssetManager::getModules()
173167
);
174168

175-
$this->latte->addFunction('datetime', fn () =>
176-
Carbon::class
169+
$this->latte->addFunction('now', fn () => Carbon::now());
170+
171+
$this->latte->addFunction('parseDate', fn ($v) => Carbon::parse($v));
172+
173+
$this->latte->addFunction('monthName', fn ($i) =>
174+
Carbon::create()->month($i)->format('F')
177175
);
178176

179-
$this->latte->addFunction('value', fn ($key, $default = null) => $key ?? $default
177+
$this->latte->addFunction('value', fn ($key, $default = null) =>
178+
$key ?? $default
180179
);
180+
181+
$this->latte->addFunction('sortUrl', function (string $column) {
182+
183+
$query = $this->request->query->all();
184+
185+
$currentSort = $query['sort'] ?? null;
186+
$currentDirection = $query['direction'] ?? 'asc';
187+
188+
$query['sort'] = $column;
189+
190+
$query['direction'] =
191+
($currentSort === $column && $currentDirection === 'asc')
192+
? 'desc'
193+
: 'asc';
194+
195+
unset($query['page']);
196+
197+
return '?' . http_build_query($query);
198+
});
181199
}
182200

183201
private function registerExtensions(): void
@@ -187,13 +205,6 @@ private function registerExtensions(): void
187205

188206
private function registerProviders(): void
189207
{
190-
$this->latte->addProvider('customButtonRender', function ($args) {
191-
if ($file = TemplateManager::file('buttons/button.' . $args['type'] . '.latte')) {
192-
$this->latte->render($file, $args);
193-
return;
194-
}
195-
196-
throw new \Exception("Button template for type '{$args['type']}' not found.");
197-
});
208+
198209
}
199210
}

0 commit comments

Comments
 (0)