Skip to content

Commit b8fea34

Browse files
authored
Merge pull request #65 from pug-php/feature/symfony-6
Upgrade to Symfony 6
2 parents b7f7352 + 74451b1 commit b8fea34

34 files changed

+1021
-428
lines changed

.github/workflows/coverage.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
fail-fast: false
1515
matrix:
1616
os: ['ubuntu-latest']
17-
php: ['7.4']
17+
php: ['8.2']
1818

1919
name: PHP ${{ matrix.php }} - ${{ matrix.os }}
2020

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
fail-fast: false
1515
matrix:
1616
os: ['ubuntu-latest', 'windows-latest']
17-
php: ['7.2', '7.3', '7.4', '8.0', '8.1']
17+
php: ['8.1', '8.2', '8.3']
1818

1919
name: PHP ${{ matrix.php }} - ${{ matrix.os }}
2020

README.md

Lines changed: 63 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ In the root directory of your Symfony project, open a terminal and enter.
1414
```shell
1515
composer require pug-php/pug-symfony
1616
```
17-
When your are asked to install automatically needed settings, enter yes.
17+
When you are asked to install automatically needed settings, enter yes.
1818

1919
It for any reason, you do not can or want to use it, you will have to add to
2020
your **config/bundles.php** file:
@@ -26,29 +26,50 @@ Pug\PugSymfonyBundle\PugSymfonyBundle::class => ['all' => true],
2626
## Usage
2727

2828
Create Pug views by creating files with .pug extension
29-
in **app/Resources/views** such as contact.pug:
29+
in **templates** such as contact.pug:
3030
```pug
3131
h1
3232
| Contact
3333
=name
3434
```
3535

36-
Note: standard Twig functions are also available in your pug templates, for instance:
37-
```pug
38-
!=form_start(form, {method: 'GET'})
36+
Then inject `Pug\PugSymfonyEngine` to call it in your controller:
37+
```php
38+
namespace App\Controller;
39+
40+
use Pug\PugSymfonyEngine;
41+
use Symfony\Component\HttpKernel\Attribute\AsController;
42+
use Symfony\Component\Routing\Annotation\Route;
43+
44+
#[AsController]
45+
class MyController
46+
{
47+
#[Route('/contact')]
48+
public function contactAction(PugSymfonyEngine $pug)
49+
{
50+
return $pug->renderResponse('contact/contact.pug', [
51+
'name' => 'Us',
52+
]);
53+
}
54+
}
3955
```
4056

41-
Then call it in your controller:
57+
Or alternatively you can use `\Pug\Symfony\Traits\PugRenderer` to call directly `->render()` from
58+
any method of a controller (or service):
59+
4260
```php
4361
namespace App\Controller;
4462

45-
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
63+
use Pug\Symfony\Traits\PugRenderer;
64+
use Symfony\Component\HttpKernel\Attribute\AsController;
65+
use Symfony\Component\Routing\Annotation\Route;
4666

47-
class MyController extends AbstractController
67+
#[AsController]
68+
class MyController
4869
{
49-
/**
50-
* @Route("/contact")
51-
*/
70+
use PugRenderer;
71+
72+
#[Route('/contact')]
5273
public function contactAction()
5374
{
5475
return $this->render('contact/contact.pug', [
@@ -58,13 +79,38 @@ class MyController extends AbstractController
5879
}
5980
```
6081

82+
No matter if your controller extends `AbstractController` as it can also render twig views, so it will just
83+
work the same as before rather you `->render('view.html.twig')` or `->render('view.pug')`.
84+
85+
Note: standard Twig functions are also available in your pug templates, for instance:
86+
```pug
87+
!=form(form)
88+
```
89+
90+
As per https://symfony.com/doc/current/forms.html
91+
92+
Pass the FormView as usual from the controller:
93+
```php
94+
$task = new Task();
95+
// ...
96+
97+
$form = $this->createFormBuilder($task)
98+
// ...
99+
->getForm();
100+
101+
return $pug->renderResponse('home.pug', [
102+
'form' => $form->createView(),
103+
]);
104+
```
105+
61106
## Configure
62107

63108
You can inject `Pug\PugSymfonyEngine` to change options, share values, add plugins to Pug
64109
at route level:
65110

66111
```php
67112
// In a controller method
113+
#[Route('/contact')]
68114
public function contactAction(\Pug\PugSymfonyEngine $pug)
69115
{
70116
$pug->setOptions(array(
@@ -74,14 +120,16 @@ public function contactAction(\Pug\PugSymfonyEngine $pug)
74120
));
75121
$pug->share('globalVar', 'foo');
76122
$pug->getRenderer()->addKeyword('customKeyword', $bar);
77-
78-
return $this->render('contact/contact.pug', [
123+
124+
return $pug->renderResponse('contact/contact.pug', [
79125
'name' => 'Us',
80126
]);
81127
}
82128
```
83129

84-
Same can be ran globally on a given event such as `onKernelView` to apply customization before any
130+
If you use the `PugRenderer` trait, you don't need to inject the service again and can just use `$this->pug`.
131+
132+
Same can be run globally on a given event such as `onKernelView` to apply customization before any
85133
view rendering.
86134

87135
See the options in the pug-php documentation: https://phug-lang.com/#options
@@ -108,7 +156,7 @@ twig:
108156
109157
```
110158

111-
Make the translator available in every views:
159+
Make the translator available in every view:
112160
```pug
113161
p=translator.trans('Hello %name%', {'%name%': 'Jack'})
114162
```

composer.json

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,23 @@
66
"description": "Pug template engine for Symfony",
77
"type": "library",
88
"require": {
9-
"php": "^7.2.5 || ^8.0",
10-
"phug/component": "^1.1.0",
11-
"pug/installer": "^1.0.0",
12-
"pug-php/pug": "^3.4.0",
13-
"pug-php/pug-assets": "^1.0.1",
14-
"symfony/framework-bundle": "^5.0",
15-
"symfony/http-foundation": "^5.0",
16-
"symfony/http-kernel": "^5.0",
17-
"symfony/security-bundle": "^5.0",
18-
"symfony/templating": "^5.0",
19-
"symfony/twig-bridge": "^5.0",
20-
"twig/twig": "^3.0.0"
9+
"php": ">=8.1",
10+
"phug/component": "^1.1.4",
11+
"pug/installer": "^1.0.1",
12+
"pug-php/pug": "^3.5.0",
13+
"pug-php/pug-assets": "^1.1.4",
14+
"symfony/framework-bundle": "^6.0",
15+
"symfony/http-foundation": "^6.0",
16+
"symfony/http-kernel": "^6.0",
17+
"symfony/security-bundle": "^6.0",
18+
"symfony/templating": "^6.0",
19+
"symfony/twig-bridge": "^6.0",
20+
"twig/twig": "^3.5.0"
2121
},
2222
"require-dev": {
2323
"phpunit/phpunit": "^8.5",
24-
"symfony/symfony": "^5.0"
24+
"symfony/symfony": "^6.0",
25+
"monolog/monolog": "^3.2"
2526
},
2627
"minimum-stability": "stable",
2728
"license": "MIT",

src/Pug/Exceptions/ReservedVariable.php

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

3+
declare(strict_types=1);
4+
35
namespace Pug\Exceptions;
46

57
use RuntimeException;

src/Pug/PugSymfonyBundle/Command/AssetsPublishCommand.php

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,29 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace Pug\PugSymfonyBundle\Command;
46

57
use Phug\Renderer;
68
use Pug\PugSymfonyEngine;
9+
use Symfony\Component\Console\Attribute\AsCommand;
710
use Symfony\Component\Console\Command\Command;
811
use Symfony\Component\Console\Input\InputInterface;
912
use Symfony\Component\Console\Output\OutputInterface;
1013
use Throwable;
1114

15+
#[AsCommand(
16+
'assets:publish',
17+
'Export your assets in the web directory.',
18+
)]
1219
class AssetsPublishCommand extends Command
1320
{
14-
protected $pugSymfonyEngine;
15-
16-
public function __construct(PugSymfonyEngine $pugSymfonyEngine)
17-
{
18-
$this->pugSymfonyEngine = $pugSymfonyEngine;
19-
parent::__construct(null);
20-
}
21-
22-
protected function configure()
21+
public function __construct(protected readonly PugSymfonyEngine $pugSymfonyEngine)
2322
{
24-
$this
25-
->setName('assets:publish')
26-
->setDescription('Export your assets in the web directory.');
23+
parent::__construct();
2724
}
2825

29-
protected function cacheTemplates(Renderer $pug)
26+
protected function cacheTemplates(Renderer $pug): array
3027
{
3128
$success = 0;
3229
$errors = 0;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Pug\PugSymfonyBundle;
6+
7+
use Symfony\Component\Config\FileLocator;
8+
use Symfony\Component\DependencyInjection\ContainerBuilder;
9+
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
10+
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
11+
12+
/**
13+
* TwigExtension.
14+
*
15+
* @author Fabien Potencier <[email protected]>
16+
* @author Jeremy Mikola <[email protected]>
17+
*/
18+
class PugExtension extends Extension
19+
{
20+
public function load(array $configs, ContainerBuilder $container)
21+
{
22+
$loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/config'));
23+
$loader->load('pug.php');
24+
}
25+
}
Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,30 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace Pug\PugSymfonyBundle;
46

57
use Pug\PugSymfonyBundle\Command\AssetsPublishCommand;
6-
use Pug\PugSymfonyEngine;
78
use Pug\Symfony\Traits\PrivatePropertyAccessor;
8-
use ReflectionException;
9-
use ReflectionMethod;
10-
use ReflectionProperty;
119
use Symfony\Component\Console\Application;
12-
use Symfony\Component\DependencyInjection\ContainerInterface;
10+
use Symfony\Component\DependencyInjection\ContainerBuilder;
1311
use Symfony\Component\HttpKernel\Bundle\Bundle;
14-
use Symfony\Component\HttpKernel\KernelInterface;
1512

1613
class PugSymfonyBundle extends Bundle
1714
{
1815
use PrivatePropertyAccessor;
1916

20-
/**
21-
* @param ContainerInterface|null $container
22-
*
23-
* @throws ReflectionException
24-
*/
25-
public function setContainer(ContainerInterface $container = null)
17+
public function build(ContainerBuilder $containerBuilder): void
2618
{
27-
$this->container = $container;
28-
29-
if ($container) {
30-
/** @var KernelInterface $kernel */
31-
$kernel = $container->get('kernel');
32-
$engine = new PugSymfonyEngine($kernel);
33-
/** @var ReflectionProperty $propertyAccessor */
34-
$services = static::getPrivateProperty($container, 'services', $propertyAccessor);
35-
$services[PugSymfonyEngine::class] = $engine;
36-
$propertyAccessor->setValue($container, $services);
37-
}
19+
$extension = new PugExtension();
20+
$containerBuilder->registerExtension($extension);
21+
$containerBuilder->loadFromExtension($extension->getAlias());
3822
}
3923

4024
public function registerCommands(Application $application)
4125
{
42-
$method = new ReflectionMethod(AssetsPublishCommand::class, '__construct');
43-
$class = $method->getNumberOfParameters() === 1 ? $method->getParameters()[0]->getClass() : null;
44-
45-
if ($class && $class->getName() === PugSymfonyEngine::class) {
46-
/** @var PugSymfonyEngine $engine */
47-
$engine = $this->container->get(PugSymfonyEngine::class);
48-
49-
$application->addCommands([
50-
new AssetsPublishCommand($engine),
51-
]);
52-
}
26+
$application->addCommands([
27+
$this->container->get(AssetsPublishCommand::class),
28+
]);
5329
}
5430
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
6+
7+
return static function (ContainerConfigurator $configurator): void {
8+
$services = $configurator->services()
9+
->defaults()
10+
->autowire()
11+
->autoconfigure();
12+
13+
$services->load('Pug\\', __DIR__.'/../../*')
14+
->exclude([
15+
__DIR__.'/../../Exceptions',
16+
__DIR__.'/../../PugSymfonyBundle',
17+
__DIR__.'/../../Symfony',
18+
__DIR__.'/../../Twig',
19+
]);
20+
21+
$services->load('Pug\\PugSymfonyBundle\\Command\\', __DIR__.'/../../PugSymfonyBundle/Command/*')
22+
->public();
23+
};

0 commit comments

Comments
 (0)