Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ All notable changes to this project will be documented in this file.
- Added: support for modern twig layouts of contao 5.7 ([#34](https://github.com/heimrichhannot/contao-encore-bundle/pull/34))
- Added: EntrypointsBuilder concept for retriving current page entrypoints ([#34](https://github.com/heimrichhannot/contao-encore-bundle/pull/34))
- Added: support for symfony debug bar ([#35](https://github.com/heimrichhannot/contao-encore-bundle/pull/35))
- Added: ResponseContext bag for entries ([#36](https://github.com/heimrichhannot/contao-encore-bundle/pull/36))
- Changed: add constant for default field name ([#34](https://github.com/heimrichhannot/contao-encore-bundle/pull/34))
- Fixed: removed dead or unnecessary code and checks ([#34](https://github.com/heimrichhannot/contao-encore-bundle/pull/34))
- Deprecated: `src/Asset/PageEntrypoints.php`, `src/Asset/TemplateAsset.php` and `src/Asset/TemplateAssetGenerator.php` ([#34](https://github.com/heimrichhannot/contao-encore-bundle/pull/34))
- Deprecated: `ConfigurationHelper::isEnabledOnPage()` ([#34](https://github.com/heimrichhannot/contao-encore-bundle/pull/34))
- Deprecated: getter-Methods in `EncoreEnabledEvent` ([#34](https://github.com/heimrichhannot/contao-encore-bundle/pull/34))


## [2.1.1] - 2026-03-30
- Fixed: compatibility issue with symfony 7

Expand Down
12 changes: 6 additions & 6 deletions contao/templates/twig/data_collector/huh_encore.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,12 @@

{% for entry in collector.entries %}
<tr>
<td>{{ entry.name }}</td>
<td>{{ entry.active }}</td>
<td>{{ entry.head }}</td>
<td>{{ entry.requiresCss }}</td>
<td>{{ entry.origin }}</td>
<td>{{ entry.extension }}</td>
<td class="font-normal text-bold nowrap">{{ entry.name }}</td>
<td class="text-center">{{ entry.active ? 'yes' : '' }}</td>
<td class="text-center">{{ entry.head ? 'yes' : '' }}</td>
<td class="text-center">{{ entry.requiresCss ? 'yes' : '' }}</td>
<td class="text-small break-long-words">{{ entry.origin }}</td>
<td class="text-small">{{ entry.extension }}</td>
</tr>
{% endfor %}
</tbody>
Expand Down
15 changes: 9 additions & 6 deletions docs/developers.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,27 +69,30 @@ To collect or render assets in custom templates or abstinent from the normal pag

namespace App\CustomController;

use HeimrichHannot\EncoreBundle\Asset\FrontendAsset;
use Contao\CoreBundle\Routing\ResponseContext\ResponseContext;
use HeimrichHannot\EncoreBundle\EntryPoint\EntryPointBuilderFactory;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use HeimrichHannot\EncoreBundle\Request\ResponseContext\Entry;
use HeimrichHannot\EncoreBundle\Request\ResponseContext\EntryBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\WebpackEncoreBundle\Asset\TagRenderer;use Twig\Environment;
use Symfony\WebpackEncoreBundle\Asset\TagRenderer;
use Twig\Environment;

class CustomController
{
private readonly TagRenderer $tagRenderer;
private readonly EntryPointBuilderFactory $entrypointBuilderFactory;
private readonly Environment $twig;
private readonly FrontendAsset $frontendAsset;

public function __invoke(): Response
public function __invoke(Request $request): Response
{
// collect entry points from the different sources
$entryPoints = $this->entrypointBuilderFactory->create()
// add the sources you want:
->setPage($event->getPage())
->setLayout($event->getLayout())
->setFrontendAsset($this->frontendAsset)
->setResponseContext($request->attributes->get(ResponseContext::REQUEST_ATTRIBUTE_NAME))
->setCustomBag((new EntryBag())->addEntry(new Entry('additional_entry', __METHOD__, 'App')))
// build the collection:
Comment thread
koertho marked this conversation as resolved.
->build();

Expand Down
28 changes: 27 additions & 1 deletion docs/developers/dynamic_entries.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,33 @@ This document describes different ways to add entries from your code.

> For most usecases, you should use the [PageAssetTrait](../developers.md#add-encore-entries-to-custom-template) instead!

### FrontendAsset service

## Response context

> Since version 2.2

Use `EntryBag` of `ResponseContext` to add entries from your controller.

```php
class CustomController
{
public function __invoke(Request $request): Response
{
$responseContext = $request->attributes->get(ResponseContext::REQUEST_ATTRIBUTE_NAME);
if ($responseContext instanceof ResponseContext) {
if (!$responseContext->has(EntryBag::class)) {
$responseContext->add(new EntryBag());
}
$responseContext->get(EntryBag::class)
?->addEntry(new Entry('contao-tagsinput', __METHOD__, 'example-vendor/example-extension'));
}
}
}
```

Read more about the `ResponseContext` in the [contao docs](https://docs.contao.org/5.x/dev/framework/response-context/).

## FrontendAsset service

Encore bundle comes with a service, `FrontendAsset`, to register your entrypoints.

Expand Down
6 changes: 6 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ parameters:
count: 2
path: src/EventListener/InjectPageEntriesListener.php

-
message: '#^Call to method getTemplate\(\) on an unknown class Contao\\CoreBundle\\Event\\LayoutEvent\.$#'
identifier: class.notFound
count: 2
path: src/EventListener/InjectPageEntriesListener.php

-
message: '#^Parameter \$event of method HeimrichHannot\\EncoreBundle\\EventListener\\InjectPageEntriesListener\:\:onLayoutEvent\(\) has invalid type Contao\\CoreBundle\\Event\\LayoutEvent\.$#'
identifier: class.notFound
Expand Down
66 changes: 53 additions & 13 deletions src/Asset/FrontendAsset.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,78 @@

namespace HeimrichHannot\EncoreBundle\Asset;

use Contao\CoreBundle\Routing\ResponseContext\ResponseContextAccessor;
use HeimrichHannot\EncoreBundle\Request\ResponseContext\Entry;
use HeimrichHannot\EncoreBundle\Request\ResponseContext\EntryBag;

class FrontendAsset
{
/**
* @var array
*/
private $activeEntrypoints = [];
public function __construct(
private readonly ResponseContextAccessor $responseContextAccessor,
) {
}

/**
* Add an active entrypoint.
*/
public function addActiveEntrypoint(string $entrypoint): void
public function addActiveEntrypoint(string|Entry $entrypoint): void
{
$this->activeEntrypoints[] = $entrypoint;
$bag = $this->getBag();
if (!$bag) {
return;
}

if (is_string($entrypoint)) {
$entrypoint = new Entry($entrypoint, __METHOD__);
}

$bag->addEntry($entrypoint);
}

/**
* Return a list of all active entrypoints.
*
* @return array
* @return string[]
*/
public function getActiveEntrypoints()
public function getActiveEntrypoints(): array
{
return $this->activeEntrypoints;
$bag = $this->getBag();
if (!$bag) {
return [];
}

return array_map(
static fn (Entry $entry) => $entry->name,
$bag->all()
);
}

/**
* Check if an entrypoint is set as active entrypoint.
*
* @return bool
*/
public function isActiveEntrypoint(string $entrypoint)
public function isActiveEntrypoint(string $entrypoint): bool
{
return \in_array($entrypoint, $this->activeEntrypoints, true);
$bag = $this->getBag();
if (!$bag) {
return false;
}

return null !== $bag->getEntry($entrypoint);
}

private function getBag(): ?EntryBag
{
$context = $this->responseContextAccessor->getResponseContext();
if (!$context) {
return null;
}
if (!$context->has(EntryBag::class)) {
$context->add(new EntryBag());
}

/** @var EntryBag $bag */
$bag = $context->get(EntryBag::class);

return $bag;
}
}
43 changes: 31 additions & 12 deletions src/EntryPoint/EntryPointsBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

namespace HeimrichHannot\EncoreBundle\EntryPoint;

use Contao\CoreBundle\Routing\ResponseContext\ResponseContext;
use Contao\LayoutModel;
use Contao\PageModel;
use Contao\StringUtil;
use HeimrichHannot\EncoreBundle\Asset\FrontendAsset;
use HeimrichHannot\EncoreBundle\Collection\EntryCollection;
use HeimrichHannot\EncoreBundle\Dca\EncoreEntriesSelectField;
use HeimrichHannot\EncoreBundle\Request\ResponseContext\EntryBag;
use HeimrichHannot\UtilsBundle\Util\Utils;

class EntryPointsBuilder
Expand All @@ -16,9 +17,10 @@ class EntryPointsBuilder
private string $pageField = '';
private ?LayoutModel $layout = null;
private string $layoutField = '';
private ?FrontendAsset $frontendAsset = null;

private array $available = [];
private ?ResponseContext $responseContext = null;
private ?EntryBag $entryBag = null;

public function __construct(
private readonly Utils $utils,
Expand All @@ -42,9 +44,16 @@ public function setLayout(?LayoutModel $layout, string $field = EncoreEntriesSel
return $this;
}

public function setFrontendAsset(?FrontendAsset $frontendAsset): self
public function setResponseContext(?ResponseContext $responseContext): self
{
$this->frontendAsset = $frontendAsset;
$this->responseContext = $responseContext;

return $this;
}

public function setCustomBag(?EntryBag $entryBag): self
{
$this->entryBag = $entryBag;

return $this;
}
Expand All @@ -58,14 +67,8 @@ public function build(): EntryPoints
}
$this->available = $available;

if ($this->frontendAsset) {
foreach ($this->frontendAsset->getActiveEntrypoints() as $entryPoint) {
$this->addEntryPoint(
entryPoints: $entryPoints,
name: $entryPoint,
origin: FrontendAsset::class,
);
}
if ($this->responseContext && $this->responseContext->has(EntryBag::class)) {
$this->addFromBag($entryPoints, $this->responseContext->get(EntryBag::class));
}

if ($this->pageModel && !$this->layout) {
Expand Down Expand Up @@ -105,9 +108,25 @@ public function build(): EntryPoints
}
}

if (null !== $this->entryBag) {
$this->addFromBag($entryPoints, $this->entryBag);
}

return $entryPoints;
}

private function addFromBag(EntryPoints $entryPoints, EntryBag $bag): void
{
foreach ($bag->all() as $entry) {
Comment thread
koertho marked this conversation as resolved.
$this->addEntryPoint(
entryPoints: $entryPoints,
name: $entry->name,
origin: $entry->origin,
extension: $entry->extension,
);
}
}

private function addEntryPoint(EntryPoints $entryPoints, string $name, bool $active = true, string $origin = '', string $extension = ''): void
{
if ('' === $name) {
Expand Down
6 changes: 3 additions & 3 deletions src/EventListener/Contao/ReplaceDynamicScriptTagsListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

use Contao\CoreBundle\DependencyInjection\Attribute\AsHook;
use Contao\CoreBundle\Framework\ContaoFramework;
use HeimrichHannot\EncoreBundle\Asset\FrontendAsset;
use Contao\CoreBundle\Routing\ResponseContext\ResponseContextAccessor;
use HeimrichHannot\EncoreBundle\Asset\GlobalContaoAsset;
use HeimrichHannot\EncoreBundle\EntryPoint\EntryPointBuilderFactory;
use HeimrichHannot\EncoreBundle\Helper\ConfigurationHelper;
Expand All @@ -26,9 +26,9 @@ public function __construct(
protected ConfigurationHelper $configurationHelper,
private readonly GlobalContaoAsset $globalContaoAsset,
private readonly EntryPointBuilderFactory $entryPointBuilderFactory,
private readonly FrontendAsset $frontendAsset,
private readonly TagRenderer $tagRenderer,
private readonly RequestStack $requestStack,
private readonly ResponseContextAccessor $responseContextAccessor,
) {
}

Expand All @@ -45,7 +45,7 @@ public function __invoke(string $buffer): string
}

$entryPoints = $this->entryPointBuilderFactory->create()
->setFrontendAsset($this->frontendAsset)
->setResponseContext($this->responseContextAccessor->getResponseContext())
->setPage($pageModel)
->build();

Expand Down
Loading
Loading