-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
708 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
--- | ||
description: >- | ||
Twig Extra is a set of Twig extensions to bring more Twig helpers. | ||
--- | ||
|
||
# Getting started | ||
|
||
## Installation | ||
|
||
Install the package using Composer and Symfony Flex: | ||
|
||
```bash | ||
composer require sylius/twig-extra | ||
``` | ||
|
||
## Features | ||
|
||
### Sort by | ||
|
||
This sort by extension allows to sort an array of objects by a specific property. | ||
|
||
```php | ||
class Book { | ||
public function __construct() { | ||
public string $name, | ||
} | ||
} | ||
|
||
$books = [new Book('Shinning'), new Book('A Lord Of The Rings')]; | ||
``` | ||
|
||
```twig | ||
<ul> | ||
{% for book in books|sort_by('name') %} | ||
<li>{{ book.name }}</li> | ||
{% endif %} | ||
</ul> | ||
``` | ||
|
||
```text | ||
. A Lord Of The Rings | ||
. Shinning | ||
``` | ||
|
||
You can also sort array of arrays. | ||
|
||
```php | ||
|
||
$books = [['name' => 'Shinning'], ['name' => 'A Lord Of The Rings']]; | ||
``` | ||
|
||
You just need to encapsulate the key with `[]`. | ||
|
||
```twig | ||
<ul> | ||
{% for book in books|sort_by('[name]') %} | ||
<li>{{ book.name }}</li> | ||
{% endif %} | ||
</ul> | ||
``` | ||
|
||
### Test HTML attribute | ||
|
||
This Twig extension allows you to add some data attributes in test environment | ||
This allows to identify your data easily in E2E tests without being too much dependant of your HTML changes. | ||
|
||
```twig | ||
<h1 {{ sylius_test_html_attribute('title')>Shinning</h1> | ||
``` | ||
|
||
```html | ||
<h1 data-test-title>Shinning</h1> | ||
``` | ||
|
||
### Test Form HTML attribute | ||
|
||
This is slightly the same behaviour as `sylius_test_html_attribute` Twig function. | ||
|
||
```twig | ||
{{ form_row(form.title, sylius_test_form_attribute('title')) }} | ||
``` | ||
|
||
```html | ||
<!-- The real results depend on your form theme. --> | ||
<label for="book_title">Title</label> | ||
<input | ||
type="text" | ||
id="book_title" | ||
name="title" | ||
data-test-title <!-- This is the added data attribute --> | ||
/> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"name": "sylius/twig-extra", | ||
"type": "library", | ||
"license": "MIT", | ||
"authors": [ | ||
{ | ||
"name": "Sylius project", | ||
"homepage": "https://sylius.com" | ||
}, | ||
{ | ||
"name": "Community contributions", | ||
"homepage": "https://github.com/Sylius/Stack/contributors" | ||
} | ||
], | ||
"require": { | ||
"php": "^8.1", | ||
"symfony/http-kernel": "^5.4 || ^6.0", | ||
"symfony/twig-bundle": "^5.4 || ^6.0" | ||
}, | ||
"conflict": { | ||
"sylius/ui-bundle": "<2.0" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"Sylius\\TwigExtra\\": "src/" | ||
} | ||
}, | ||
"autoload-dev": { | ||
"psr-4": { | ||
"Tests\\Sylius\\TwigExtra\\": "tests/" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator; | ||
|
||
use Sylius\TwigExtra\Twig\SortByExtension; | ||
use Sylius\TwigExtra\Twig\TestFormAttributeExtension; | ||
use Sylius\TwigExtra\Twig\TestHtmlAttributeExtension; | ||
|
||
return function (ContainerConfigurator $configurator): void { | ||
$services = $configurator->services(); | ||
|
||
$services->set('twig_extra.twig.extension.test_form_attribute', TestFormAttributeExtension::class) | ||
->args([ | ||
param('kernel.environment'), | ||
param('kernel.debug'), | ||
]) | ||
->tag(name: 'twig.extension') | ||
; | ||
|
||
$services->set('twig_extra.twig.extension.test_html_attribute', TestHtmlAttributeExtension::class) | ||
->args([ | ||
param('kernel.environment'), | ||
param('kernel.debug'), | ||
]) | ||
->tag(name: 'twig.extension') | ||
; | ||
|
||
$services->set('twig_extra.twig.extension.sort_by', SortByExtension::class) | ||
->tag(name: 'twig.extension') | ||
; | ||
}; |
23 changes: 23 additions & 0 deletions
23
src/TwigExtra/src/Symfony/DependencyInjection/TwigExtraExtension.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Sylius\TwigExtra\Symfony\DependencyInjection; | ||
|
||
use Symfony\Component\Config\FileLocator; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\DependencyInjection\Extension\Extension; | ||
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; | ||
|
||
final class TwigExtraExtension extends Extension | ||
{ | ||
public function load(array $configs, ContainerBuilder $container): void | ||
{ | ||
$loader = new PhpFileLoader( | ||
$container, | ||
new FileLocator(dirname(__DIR__, 3) . '/config'), | ||
); | ||
|
||
$loader->load('services.php'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Sylius\TwigExtra\Symfony; | ||
|
||
use Symfony\Component\HttpKernel\Bundle\Bundle; | ||
|
||
final class TwigExtraBundle extends Bundle | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Sylius\TwigExtra\Twig; | ||
|
||
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException; | ||
use Symfony\Component\PropertyAccess\PropertyAccess; | ||
use Twig\Extension\AbstractExtension; | ||
use Twig\TwigFilter; | ||
|
||
class SortByExtension extends AbstractExtension | ||
{ | ||
public function getFilters(): array | ||
{ | ||
return [ | ||
new TwigFilter('sort_by', [$this, 'sortBy']), | ||
]; | ||
} | ||
|
||
/** | ||
* @throws NoSuchPropertyException | ||
*/ | ||
public function sortBy(iterable $iterable, string $field, string $order = 'ASC'): array | ||
{ | ||
$array = $this->transformIterableToArray($iterable); | ||
|
||
usort( | ||
$array, | ||
function (array|object $firstElement, array|object $secondElement) use ($field, $order) { | ||
$accessor = PropertyAccess::createPropertyAccessor(); | ||
|
||
$firstProperty = (string) $accessor->getValue($firstElement, $field); | ||
$secondProperty = (string) $accessor->getValue($secondElement, $field); | ||
|
||
$result = strnatcasecmp($firstProperty, $secondProperty); | ||
if ('DESC' === $order) { | ||
$result *= -1; | ||
} | ||
|
||
return $result; | ||
}, | ||
); | ||
|
||
return $array; | ||
} | ||
|
||
private function transformIterableToArray(iterable $iterable): array | ||
{ | ||
if (is_array($iterable)) { | ||
return $iterable; | ||
} | ||
|
||
return iterator_to_array($iterable); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Sylius\TwigExtra\Twig; | ||
|
||
use Twig\Extension\AbstractExtension; | ||
use Twig\TwigFunction; | ||
|
||
final class TestFormAttributeExtension extends AbstractExtension | ||
{ | ||
public function __construct(private string $environment) | ||
{ | ||
} | ||
|
||
/** | ||
* @return TwigFunction[] | ||
*/ | ||
public function getFunctions(): array | ||
{ | ||
return [ | ||
new TwigFunction( | ||
'sylius_test_form_attribute', | ||
function (string $name, ?string $value = null): array { | ||
if (str_starts_with($this->environment, 'test')) { | ||
return ['attr' => ['data-test-' . $name => (string) $value]]; | ||
} | ||
|
||
return []; | ||
}, | ||
['is_safe' => ['html']], | ||
), | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Sylius\TwigExtra\Twig; | ||
|
||
use Twig\Extension\AbstractExtension; | ||
use Twig\TwigFunction; | ||
|
||
final class TestHtmlAttributeExtension extends AbstractExtension | ||
{ | ||
public function __construct(private readonly string $environment, private readonly bool $isDebugEnabled) | ||
{ | ||
} | ||
|
||
/** | ||
* @return TwigFunction[] | ||
*/ | ||
public function getFunctions(): array | ||
{ | ||
return [ | ||
new TwigFunction( | ||
'sylius_test_html_attribute', | ||
function (string $name, ?string $value = null): string { | ||
if (str_starts_with($this->environment, 'test') || $this->isDebugEnabled) { | ||
return sprintf('data-test-%s="%s"', $name, (string) $value); | ||
} | ||
|
||
return ''; | ||
}, | ||
['is_safe' => ['html']], | ||
), | ||
]; | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/TwigExtra/tests/Functional/Twig/Extension/SortByExtensionTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Tests\Sylius\TwigExtra\Functional\Twig\Extension; | ||
|
||
use Sylius\TwigExtra\Twig\SortByExtension; | ||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; | ||
|
||
final class SortByExtensionTest extends KernelTestCase | ||
{ | ||
public function testTheContainerContainsTheService(): void | ||
{ | ||
$this->bootKernel(); | ||
|
||
$container = $this->getContainer(); | ||
|
||
$this->assertTrue($container->has('twig_extra.twig.extension.sort_by')); | ||
$this->assertInstanceOf(SortByExtension::class, $container->get('twig_extra.twig.extension.sort_by')); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/TwigExtra/tests/Functional/Twig/Extension/TestFormAttributeExtensionTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Tests\Sylius\TwigExtra\Functional\Twig\Extension; | ||
|
||
use Sylius\TwigExtra\Twig\TestFormAttributeExtension; | ||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; | ||
|
||
final class TestFormAttributeExtensionTest extends KernelTestCase | ||
{ | ||
public function testTheContainerContainsTheService(): void | ||
{ | ||
$this->bootKernel(); | ||
|
||
$container = $this->getContainer(); | ||
|
||
$this->assertTrue($container->has('twig_extra.twig.extension.test_form_attribute')); | ||
$this->assertInstanceOf(TestFormAttributeExtension::class, $container->get('twig_extra.twig.extension.test_form_attribute')); | ||
} | ||
} |
Oops, something went wrong.