Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a webpack encore helper to Twig #446

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -43,6 +43,13 @@ public function getConfigTreeBuilder(): TreeBuilder
->defaultValue(['', 'twig', 'html', 'html.twig', 'twig.html'])
->prototype('scalar')->end()
->end()
->scalarNode('webpack_manifest')
->info(
'Optional relative path to the Webpack Encore manifest file within source/ '
. '(e.g., "build/manifest.json")'
)
->defaultNull()
->end()
->end();

return $treeBuilder;
Expand Down
Expand Up @@ -37,6 +37,7 @@ public function load(array $configs, ContainerBuilder $container): void
$container->setParameter('sculpin_twig.source_view_paths', $config['source_view_paths']);
$container->setParameter('sculpin_twig.view_paths', $config['view_paths']);
$container->setParameter('sculpin_twig.extensions', $config['extensions']);
$container->setParameter('sculpin_twig.webpack_manifest', $config['webpack_manifest']);

if (! extension_loaded('intl')) {
// Do not enable the intl Twig extension if the intl PHP extension is not installed.
Expand Down
6 changes: 6 additions & 0 deletions src/Sculpin/Bundle/TwigBundle/Resources/config/services.xml
Expand Up @@ -52,6 +52,12 @@
<tag name="twig.extension" />
</service>

<service id="sculpin_twig.helpers.webpack_encore_helper" class="Sculpin\Bundle\TwigBundle\WebpackEncoreHelper">
<argument>%sculpin.source_dir%</argument>
<argument>%sculpin_twig.webpack_manifest%</argument>
<tag name="twig.extension" />
</service>

</services>

</container>
54 changes: 54 additions & 0 deletions src/Sculpin/Bundle/TwigBundle/WebpackEncoreHelper.php
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace Sculpin\Bundle\TwigBundle;

use Twig\Extension\AbstractExtension;
use Twig\Extension\GlobalsInterface;

class WebpackEncoreHelper extends AbstractExtension implements GlobalsInterface
{
protected $sourceDir;
protected $manifest;

public function __construct(string $sourceDir, ?string $manifest)
{
$this->sourceDir = $sourceDir;
$this->manifest = $manifest;
}

public function getGlobals(): array
{
$manifestContents = $this->getManifestContents();

if (!$manifestContents) {
return [
'webpack_manifest' =>
[
'error' => 'Please configure the `sculpin_twig.webpack_manifest` variable '
. 'in your app/config/sculpin_kernel.yml file. For example:' . "\n\n"
. 'sculpin_twig:' . "\n"
. ' webpack_manifest: build/manifest.json'
]
];
}

$manifest = json_decode($manifestContents, true);

return [
'webpack_manifest' => $manifest,
];
}

private function getManifestContents(): string
{
$path = $this->sourceDir . DIRECTORY_SEPARATOR . $this->manifest;

if (!file_exists($path) || !is_readable($path)) {
return '';
}

return file_get_contents($path);
}
}
@@ -0,0 +1,4 @@
{
"build/css/app.css": "/build/css/app.9141cd43.css",
"build/js/app.js": "/build/js/app.43dcc737.js"
}
@@ -0,0 +1,7 @@
---
title: testing webpack manifest
---

Testing CSS {{ webpack_manifest['build/css/app.css']|default('/build/css/app.css') }}
Testing JS {{ webpack_manifest['build/js/app.js']|default('/build/js/app.js') }}

4 changes: 2 additions & 2 deletions src/Sculpin/Tests/Functional/FunctionalTestCase.php
Expand Up @@ -42,8 +42,8 @@ protected function setUpTestProject(): void
$this->tearDownTestProject();

$projectFiles = [
'/config/sculpin_kernel.yml',
'/config/sculpin_site.yml',
'/app/config/sculpin_kernel.yml',
'/app/config/sculpin_site.yml',
'/source/_layouts/default.html.twig',
'/source/_layouts/raw.html.twig',
];
Expand Down
37 changes: 37 additions & 0 deletions src/Sculpin/Tests/Functional/GenerateCommandTest.php
Expand Up @@ -6,6 +6,17 @@

class GenerateCommandTest extends FunctionalTestCase
{
public const CONFIG_FILE = DIRECTORY_SEPARATOR . 'app'
. DIRECTORY_SEPARATOR . 'config'
. DIRECTORY_SEPARATOR . 'sculpin_kernel.yml';

public function tearDown()
{
parent::tearDown();

$this->writeToProjectFile(self::CONFIG_FILE, '');
}

/** @test */
public function shouldGenerateInSpecifiedOutputDir(): void
{
Expand Down Expand Up @@ -43,4 +54,30 @@ public function shouldGenerateUsingSpecifiedSourceDir(): void
// check that it worked
$this->assertProjectHasFile($filePath, "Expected project to have generated file at path $filePath.");
}

/** @test */
public function shouldExposeWebpackManifestInTwig(): void
{
$this->configureForWebpack();
$this->copyFixtureToProject(__DIR__ . '/Fixture/webpack_manifest/manifest_test.md', '/source/test.md');
$this->copyFixtureToProject(__DIR__ . '/Fixture/webpack_manifest/manifest.json', '/source/build/manifest.json');

$this->executeSculpin('generate');

$filePath = '/test/index.html';
$msg = "Expected project to have generated file at path $filePath.";

$this->assertProjectHasFile('/output_test' . $filePath, $msg);
$this->assertGeneratedFileHasContent($filePath, 'Testing CSS /build/css/app.9141cd43.css');
$this->assertGeneratedFileHasContent($filePath, 'Testing JS /build/js/app.43dcc737.js');
}

protected function configureForWebpack(): void
{
$this->writeToProjectFile(
self::CONFIG_FILE,
'sculpin_twig:' . "\n"
. ' webpack_manifest: build/manifest.json' . "\n"
);
}
}