Skip to content

Commit

Permalink
Merge pull request #65 from pug-php/feature/symfony-6
Browse files Browse the repository at this point in the history
Upgrade to Symfony 6
  • Loading branch information
kylekatarnls authored Mar 5, 2023
2 parents b7f7352 + 74451b1 commit b8fea34
Show file tree
Hide file tree
Showing 34 changed files with 1,021 additions and 428 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
fail-fast: false
matrix:
os: ['ubuntu-latest']
php: ['7.4']
php: ['8.2']

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

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
fail-fast: false
matrix:
os: ['ubuntu-latest', 'windows-latest']
php: ['7.2', '7.3', '7.4', '8.0', '8.1']
php: ['8.1', '8.2', '8.3']

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

Expand Down
78 changes: 63 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ In the root directory of your Symfony project, open a terminal and enter.
```shell
composer require pug-php/pug-symfony
```
When your are asked to install automatically needed settings, enter yes.
When you are asked to install automatically needed settings, enter yes.

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

Create Pug views by creating files with .pug extension
in **app/Resources/views** such as contact.pug:
in **templates** such as contact.pug:
```pug
h1
| Contact
=name
```

Note: standard Twig functions are also available in your pug templates, for instance:
```pug
!=form_start(form, {method: 'GET'})
Then inject `Pug\PugSymfonyEngine` to call it in your controller:
```php
namespace App\Controller;

use Pug\PugSymfonyEngine;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Routing\Annotation\Route;

#[AsController]
class MyController
{
#[Route('/contact')]
public function contactAction(PugSymfonyEngine $pug)
{
return $pug->renderResponse('contact/contact.pug', [
'name' => 'Us',
]);
}
}
```

Then call it in your controller:
Or alternatively you can use `\Pug\Symfony\Traits\PugRenderer` to call directly `->render()` from
any method of a controller (or service):

```php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Pug\Symfony\Traits\PugRenderer;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Routing\Annotation\Route;

class MyController extends AbstractController
#[AsController]
class MyController
{
/**
* @Route("/contact")
*/
use PugRenderer;

#[Route('/contact')]
public function contactAction()
{
return $this->render('contact/contact.pug', [
Expand All @@ -58,13 +79,38 @@ class MyController extends AbstractController
}
```

No matter if your controller extends `AbstractController` as it can also render twig views, so it will just
work the same as before rather you `->render('view.html.twig')` or `->render('view.pug')`.

Note: standard Twig functions are also available in your pug templates, for instance:
```pug
!=form(form)
```

As per https://symfony.com/doc/current/forms.html

Pass the FormView as usual from the controller:
```php
$task = new Task();
// ...

$form = $this->createFormBuilder($task)
// ...
->getForm();

return $pug->renderResponse('home.pug', [
'form' => $form->createView(),
]);
```

## Configure

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

```php
// In a controller method
#[Route('/contact')]
public function contactAction(\Pug\PugSymfonyEngine $pug)
{
$pug->setOptions(array(
Expand All @@ -74,14 +120,16 @@ public function contactAction(\Pug\PugSymfonyEngine $pug)
));
$pug->share('globalVar', 'foo');
$pug->getRenderer()->addKeyword('customKeyword', $bar);
return $this->render('contact/contact.pug', [

return $pug->renderResponse('contact/contact.pug', [
'name' => 'Us',
]);
}
```

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

Same can be run globally on a given event such as `onKernelView` to apply customization before any
view rendering.

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

Make the translator available in every views:
Make the translator available in every view:
```pug
p=translator.trans('Hello %name%', {'%name%': 'Jack'})
```
Expand Down
27 changes: 14 additions & 13 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,23 @@
"description": "Pug template engine for Symfony",
"type": "library",
"require": {
"php": "^7.2.5 || ^8.0",
"phug/component": "^1.1.0",
"pug/installer": "^1.0.0",
"pug-php/pug": "^3.4.0",
"pug-php/pug-assets": "^1.0.1",
"symfony/framework-bundle": "^5.0",
"symfony/http-foundation": "^5.0",
"symfony/http-kernel": "^5.0",
"symfony/security-bundle": "^5.0",
"symfony/templating": "^5.0",
"symfony/twig-bridge": "^5.0",
"twig/twig": "^3.0.0"
"php": ">=8.1",
"phug/component": "^1.1.4",
"pug/installer": "^1.0.1",
"pug-php/pug": "^3.5.0",
"pug-php/pug-assets": "^1.1.4",
"symfony/framework-bundle": "^6.0",
"symfony/http-foundation": "^6.0",
"symfony/http-kernel": "^6.0",
"symfony/security-bundle": "^6.0",
"symfony/templating": "^6.0",
"symfony/twig-bridge": "^6.0",
"twig/twig": "^3.5.0"
},
"require-dev": {
"phpunit/phpunit": "^8.5",
"symfony/symfony": "^5.0"
"symfony/symfony": "^6.0",
"monolog/monolog": "^3.2"
},
"minimum-stability": "stable",
"license": "MIT",
Expand Down
2 changes: 2 additions & 0 deletions src/Pug/Exceptions/ReservedVariable.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace Pug\Exceptions;

use RuntimeException;
Expand Down
23 changes: 10 additions & 13 deletions src/Pug/PugSymfonyBundle/Command/AssetsPublishCommand.php
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
<?php

declare(strict_types=1);

namespace Pug\PugSymfonyBundle\Command;

use Phug\Renderer;
use Pug\PugSymfonyEngine;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Throwable;

#[AsCommand(
'assets:publish',
'Export your assets in the web directory.',
)]
class AssetsPublishCommand extends Command
{
protected $pugSymfonyEngine;

public function __construct(PugSymfonyEngine $pugSymfonyEngine)
{
$this->pugSymfonyEngine = $pugSymfonyEngine;
parent::__construct(null);
}

protected function configure()
public function __construct(protected readonly PugSymfonyEngine $pugSymfonyEngine)
{
$this
->setName('assets:publish')
->setDescription('Export your assets in the web directory.');
parent::__construct();
}

protected function cacheTemplates(Renderer $pug)
protected function cacheTemplates(Renderer $pug): array
{
$success = 0;
$errors = 0;
Expand Down
25 changes: 25 additions & 0 deletions src/Pug/PugSymfonyBundle/PugExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Pug\PugSymfonyBundle;

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

/**
* TwigExtension.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jeremy Mikola <jmikola@gmail.com>
*/
class PugExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/config'));
$loader->load('pug.php');
}
}
44 changes: 10 additions & 34 deletions src/Pug/PugSymfonyBundle/PugSymfonyBundle.php
Original file line number Diff line number Diff line change
@@ -1,54 +1,30 @@
<?php

declare(strict_types=1);

namespace Pug\PugSymfonyBundle;

use Pug\PugSymfonyBundle\Command\AssetsPublishCommand;
use Pug\PugSymfonyEngine;
use Pug\Symfony\Traits\PrivatePropertyAccessor;
use ReflectionException;
use ReflectionMethod;
use ReflectionProperty;
use Symfony\Component\Console\Application;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\HttpKernel\KernelInterface;

class PugSymfonyBundle extends Bundle
{
use PrivatePropertyAccessor;

/**
* @param ContainerInterface|null $container
*
* @throws ReflectionException
*/
public function setContainer(ContainerInterface $container = null)
public function build(ContainerBuilder $containerBuilder): void
{
$this->container = $container;

if ($container) {
/** @var KernelInterface $kernel */
$kernel = $container->get('kernel');
$engine = new PugSymfonyEngine($kernel);
/** @var ReflectionProperty $propertyAccessor */
$services = static::getPrivateProperty($container, 'services', $propertyAccessor);
$services[PugSymfonyEngine::class] = $engine;
$propertyAccessor->setValue($container, $services);
}
$extension = new PugExtension();
$containerBuilder->registerExtension($extension);
$containerBuilder->loadFromExtension($extension->getAlias());
}

public function registerCommands(Application $application)
{
$method = new ReflectionMethod(AssetsPublishCommand::class, '__construct');
$class = $method->getNumberOfParameters() === 1 ? $method->getParameters()[0]->getClass() : null;

if ($class && $class->getName() === PugSymfonyEngine::class) {
/** @var PugSymfonyEngine $engine */
$engine = $this->container->get(PugSymfonyEngine::class);

$application->addCommands([
new AssetsPublishCommand($engine),
]);
}
$application->addCommands([
$this->container->get(AssetsPublishCommand::class),
]);
}
}
23 changes: 23 additions & 0 deletions src/Pug/PugSymfonyBundle/config/pug.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

return static function (ContainerConfigurator $configurator): void {
$services = $configurator->services()
->defaults()
->autowire()
->autoconfigure();

$services->load('Pug\\', __DIR__.'/../../*')
->exclude([
__DIR__.'/../../Exceptions',
__DIR__.'/../../PugSymfonyBundle',
__DIR__.'/../../Symfony',
__DIR__.'/../../Twig',
]);

$services->load('Pug\\PugSymfonyBundle\\Command\\', __DIR__.'/../../PugSymfonyBundle/Command/*')
->public();
};
Loading

0 comments on commit b8fea34

Please sign in to comment.