Skip to content

Commit

Permalink
Merge pull request #51 from pug-php/feature/lazy-engine
Browse files Browse the repository at this point in the history
Postpone engine initialization
  • Loading branch information
kylekatarnls authored Feb 6, 2020
2 parents d2f2dc9 + 5c5e64a commit 8aac53f
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 78 deletions.
20 changes: 16 additions & 4 deletions src/Pug/PugSymfonyEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ protected function crawlDirectories(string $srcDir, array &$assetsDirectories, a
}

if (is_dir($viewDirectory = $srcDir.'/'.$directory.'/Resources/views')) {
if (is_null($baseDir)) {
if ($baseDir === null) {
$baseDir = $viewDirectory;
}

Expand Down Expand Up @@ -131,7 +131,15 @@ protected function getFileFromName(string $name, string $directory = null): stri
*/
public function share($variables, $value = null): self
{
$this->getRenderer()->share(...func_get_args());
if (func_num_args() === 2) {
$variables = [
$variables => $value,
];
}

$variables = array_merge($this->getOptionDefault('shared_variables', []), $variables);

$this->setOption('shared_variables', $variables);

return $this;
}
Expand All @@ -155,7 +163,11 @@ public function getCacheDir(): string
*/
public function getParameters(array $locals = []): array
{
$locals = array_merge($this->getOptionDefault('shared_variables'), $locals);
$locals = array_merge(
$this->getOptionDefault('globals', []),
$this->getOptionDefault('shared_variables', []),
$locals
);

foreach (['context', 'blocks', 'macros', 'this'] as $forbiddenKey) {
if (array_key_exists($forbiddenKey, $locals)) {
Expand Down Expand Up @@ -235,7 +247,7 @@ public function exists($name): bool
*/
public function supports($name): bool
{
foreach ($this->getOptionDefault('extensions', []) as $extension) {
foreach ($this->getOptionDefault('extensions', ['.pug', '.jade']) as $extension) {
if (substr($name, -strlen($extension)) === $extension) {
return true;
}
Expand Down
115 changes: 53 additions & 62 deletions src/Pug/Symfony/Traits/HelpersHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,23 +69,6 @@ trait HelpersHandler
*/
protected $nodeHandler;

/**
* @var array
*/
protected $templatingHelpers = [
'actions',
'assets',
'code',
'form',
'request',
'router',
'security',
'session',
'slots',
'stopwatch',
'translator',
];

/**
* Get the Pug engine.
*
Expand All @@ -94,10 +77,7 @@ trait HelpersHandler
public function getRenderer(): Pug
{
if ($this->pug === null) {
$cache = $this->getCacheDir();
(new Filesystem())->mkdir($cache);

$this->pug = $this->createEngine($this->getRendererOptions($cache));
$this->pug = $this->createEngine($this->getRendererOptions());
$this->copyTwigFunctions();
$this->initializePugPlugins();
$this->share($this->getTwig()->getGlobals());
Expand All @@ -112,51 +92,60 @@ public function onNode(callable $nodeHandler): void
$this->nodeHandler = $nodeHandler;
}

protected function getRendererOptions(string $cache): array
protected function getRendererOptions(): array
{
$environment = $this->kernel->getEnvironment();
$projectDirectory = $this->kernel->getProjectDir();
$assetsDirectories = [$projectDirectory.'/Resources/assets'];
$viewDirectories = [$projectDirectory.'/templates'];

if (($loader = $this->getTwig()->getLoader()) instanceof FilesystemLoader &&
is_array($paths = $loader->getPaths()) &&
isset($paths[0])
) {
$viewDirectories[] = $paths[0];
}
if ($this->options === null) {
$environment = $this->kernel->getEnvironment();
$projectDirectory = $this->kernel->getProjectDir();
$assetsDirectories = [$projectDirectory.'/Resources/assets'];
$viewDirectories = [$projectDirectory.'/templates'];

if (($loader = $this->getTwig()->getLoader()) instanceof FilesystemLoader &&
is_array($paths = $loader->getPaths()) &&
isset($paths[0])
) {
$viewDirectories[] = $paths[0];
}

$srcDir = $projectDirectory.'/src';
$webDir = $projectDirectory.'/public';
$baseDir = isset($this->userOptions['baseDir'])
? $this->userOptions['baseDir']
: $this->crawlDirectories($srcDir, $assetsDirectories, $viewDirectories);
$baseDir = $baseDir && file_exists($baseDir) ? realpath($baseDir) : $baseDir;
$this->defaultTemplateDirectory = $baseDir;
$srcDir = $projectDirectory.'/src';
$webDir = $projectDirectory.'/public';
$baseDir = isset($this->userOptions['baseDir'])
? $this->userOptions['baseDir']
: $this->crawlDirectories($srcDir, $assetsDirectories, $viewDirectories);
$baseDir = $baseDir && file_exists($baseDir) ? realpath($baseDir) : $baseDir;
$this->defaultTemplateDirectory = $baseDir;

if (isset($this->userOptions['paths'])) {
$viewDirectories = array_merge($viewDirectories, $this->userOptions['paths'] ?: []);
if (isset($this->userOptions['paths'])) {
$viewDirectories = array_merge($viewDirectories, $this->userOptions['paths'] ?: []);
}

$debug = $this->kernel->isDebug();
$options = array_merge([
'debug' => $debug,
'assetDirectory' => static::extractUniquePaths($assetsDirectories),
'viewDirectories' => static::extractUniquePaths($viewDirectories),
'baseDir' => $baseDir,
'cache' => $debug ? false : $this->getCacheDir(),
'environment' => $environment,
'extension' => ['.pug', '.jade'],
'outputDirectory' => $webDir,
'prettyprint' => $debug,
'on_node' => $this->nodeHandler,
], $this->userOptions);
$cache = $options['cache'] ?? $options['cache_dir'] ?? null;

if ($cache) {
(new Filesystem())->mkdir($cache);
}

$options['paths'] = array_unique(array_filter($options['viewDirectories'], function ($path) use ($baseDir) {
return $path !== $baseDir;
}));

$this->options = $options;
}

$debug = $this->kernel->isDebug();
$options = array_merge([
'debug' => $debug,
'assetDirectory' => static::extractUniquePaths($assetsDirectories),
'viewDirectories' => static::extractUniquePaths($viewDirectories),
'baseDir' => $baseDir,
'cache' => $debug ? false : $cache,
'environment' => $environment,
'extension' => ['.pug', '.jade'],
'outputDirectory' => $webDir,
'prettyprint' => $debug,
'on_node' => $this->nodeHandler,
], $this->userOptions);

$options['paths'] = array_unique(array_filter($options['viewDirectories'], function ($path) use ($baseDir) {
return $path !== $baseDir;
}));

return $options;
return $this->options;
}

protected function createEngine(array $options): Pug
Expand Down Expand Up @@ -232,9 +221,11 @@ protected function interpolateTwigFunctions(string $code): string
case ')':
if ((--$opening) !== 0) {
$argument .= ')';

break;
}

break;
break 2;

case ',':
if ($opening > 1) {
Expand Down
29 changes: 28 additions & 1 deletion src/Pug/Symfony/Traits/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,18 @@
/**
* Trait Options.
*
* @method Pug getRenderer()
* @property Pug|null $pug
*
* @method Pug getRenderer()
* @method array getRendererOptions()
*/
trait Options
{
/**
* @var array
*/
protected $options;

/**
* Get a Pug engine option or the default value passed as second parameter (null if omitted).
*
Expand All @@ -21,6 +29,12 @@ trait Options
*/
public function getOptionDefault($name, $default = null)
{
if ($this->pug === null) {
$options = $this->getRendererOptions();

return array_key_exists($name, $options) ? $options[$name] : $default;
}

$pug = $this->getRenderer();

return method_exists($pug, 'hasOption') && !$pug->hasOption($name)
Expand All @@ -36,6 +50,13 @@ public function getOptionDefault($name, $default = null)
*/
public function setOption($name, $value): void
{
if ($this->pug === null) {
$this->getRendererOptions();
$this->options[$name] = $value;

return;
}

$this->getRenderer()->setOption($name, $value);
}

Expand All @@ -46,6 +67,12 @@ public function setOption($name, $value): void
*/
public function setOptions(array $options): void
{
if ($this->pug === null) {
$this->options = array_merge($this->getRendererOptions(), $options);

return;
}

$this->getRenderer()->setOptions($options);
}

Expand Down
14 changes: 5 additions & 9 deletions src/Pug/Twig/Environment.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ public function setContainer(ContainerInterface $container): void
$this->container = $container;
}

public function compileSourceBase(Source $source)
public function compileSource(Source $source): string
{
$path = $source->getPath();

if ($this->pugSymfonyEngine->supports($path)) {
$pug = $this->pugSymfonyEngine->getRenderer();
$pug = $this->getRenderer();
$code = $source->getCode();
$php = $pug->compile($code, $path);
$codeFirstLine = $this->isDebug() ? 31 : 25;
Expand Down Expand Up @@ -170,11 +170,6 @@ public function compileSourceBase(Source $source)
return $html;
}

public function compileSource(Source $source): string
{
return $this->compileSourceBase($source);
}

public function loadTemplate(string $cls, string $name, int $index = null): Template
{
if ($index !== null) {
Expand Down Expand Up @@ -211,12 +206,13 @@ public function compileCode(TwigFunction $function, string $code)
$parser = new Parser($this);
$path = '__twig_function_'.$name.'_'.sha1($code).'.html.twig';
$stream = $this->tokenize(new Source($code, $path, $path));
$output = $this->compile($parser->parse($stream));

if (!preg_match('/^\s*echo\s(.*);\s*$/m', $this->compile($parser->parse($stream)), $match)) {
if (!preg_match('/^\s*echo\s(.*);\s*$/m', $output, $match)) {
throw new RuntimeException('Unable to compile '.$name.' function.');
}

return trim($match[1]);
return '('.trim($match[1]).')'."\n";
}

protected static function getPrivateExtensionProperty(TwigEnvironment $twig, string $extension, string $property)
Expand Down
5 changes: 5 additions & 0 deletions tests/Pug/PugSymfonyEngineTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ public function testExists()

self::assertTrue($pugSymfony->exists('logout.pug'));
self::assertFalse($pugSymfony->exists('login.pug'));
self::assertTrue($pugSymfony->exists('bundle.pug'));
}

public function testSupports()
Expand Down Expand Up @@ -613,6 +614,10 @@ public function testDefaultOption()
$pugSymfony = new PugSymfonyEngine(self::$kernel);

self::assertSame(42, $pugSymfony->getOptionDefault('does-not-exist', 42));

$pugSymfony->getRenderer();

self::assertSame(42, $pugSymfony->getOptionDefault('does-not-exist', 42));
}

public function testGetSharedVariables()
Expand Down
4 changes: 2 additions & 2 deletions tests/project-s5/templates/style-php.pug
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
.foo(style='background-position: 50% -402px; background-image: ' + css_url('assets/img/patterns/5.png') + ';')
.foo(style={'background-position': "50% -402px", 'background-image': css_url('assets/img/patterns/5.png')})
.foo(style='background-position: 50% -402px; background-image: ' . css_url('assets/img/patterns/5.png') . ';')
.foo(style=array('background-position' => "50% -402px", 'background-image' => css_url('assets/img/patterns/5.png')))

0 comments on commit 8aac53f

Please sign in to comment.