Skip to content

Instantly share code, notes, and snippets.

@daun
Last active January 27, 2024 09:17
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save daun/49c2eefcf233341b78277283ae2760b2 to your computer and use it in GitHub Desktop.
Save daun/49c2eefcf233341b78277283ae2760b2 to your computer and use it in GitHub Desktop.
Integrate Latte into Laravel directly without using a package
<?php
return [
'providers' => [
App\Providers\LatteProvider::class
]
];
{
"require": {
"latte/latte": "^2.0"
}
}
<?php
namespace App\Providers;
use Illuminate\Contracts\View\Factory;
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
use Latte\Engine;
use Latte\Macros\MacroSet;
class LatteProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton('latte.engine', function ($app) {
$latte = $this->createEngine($app);
$this->installMacros($latte);
$this->installFilters($latte);
return $latte;
});
$this->app->resolving('view', function (Factory $viewFactory, Application $app) {
return $this->resolveView($viewFactory, $app);
});
}
protected function createEngine(Application $app): Engine
{
$isDebug = $app['config']['app.debug'];
$compiledViewsDir = $app['config']['view.compiled'];
$mainViewDir = $app['config']['view.paths.0'];
$latte = new Engine;
$latte->setAutoRefresh($isDebug);
$latte->setTempDirectory($compiledViewsDir);
$latte->setLoader(new LatteProviderFileLoader($mainViewDir));
return $latte;
}
protected function resolveView(Factory $viewFactory, Application $app): void
{
if (! ($viewFactory instanceof \Illuminate\View\Factory)) {
$class = get_class($viewFactory);
throw new \InvalidArgumentException("Can't register Latte\Engine: {$class} is not supported.");
}
$resolver = fn() => new LatteProviderEngineBridge($app['latte.engine']);
$viewFactory->addExtension('latte', 'latte', $resolver);
}
protected function installMacros(Engine $latte): void
{
$macros = new MacroSet($latte->getCompiler());
// Allow injecting sections à la Blade
$macros->addMacro('yield', 'echo $__env->yieldContent(%node.word);');
}
protected function installFilters(Engine $latte): void
{
// Slug filter
$latte->addFilter('slug', fn($string) => Str::slug($string));
// Retrieve translation string
$latte->addFilter('translate', function ($key, $replace = [], $locale = null) {
if (is_string($replace) && ! $locale) {
$locale = $replace;
$replace = [];
}
return __($key, $replace, $locale);
});
}
}
<?php
namespace App\Providers;
use Illuminate\Contracts\View\Engine as EngineInterface;
use Latte\Engine;
class LatteProviderEngineBridge implements EngineInterface
{
private $latte;
public function __construct(Engine $latte)
{
$this->latte = $latte;
}
public function get($path, array $data = []): string
{
return $this->latte->renderToString($path, $data);
}
}
<?php
namespace App\Providers;
use Illuminate\Support\Str;
use Latte\Loaders\FileLoader;
class LatteProviderFileLoader extends FileLoader
{
public function getContent($fileName): string
{
// Remove base dir from beginning
if ($this->baseDir) {
$fileName = Str::after($fileName, $this->baseDir);
}
// Allow dot syntax for folders
$fileName = Str::before($fileName, '.latte');
$fileName = str_replace('.', '/', $fileName);
$fileName = "{$fileName}.latte";
return parent::getContent($fileName);
}
public function getReferredName($file, $referringFile): string
{
return $file;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment