Skip to main content

Code blocks

Code blocks start with three backticks and the language. Each block has a copy button in the top right corner.

Languages​

<?php declare(strict_types=1);

namespace Gambit24\DarstellungsBeispiel\Subscriber;

use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

final class ProductPageSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [ProductPageLoadedEvent::class => 'onProductPageLoaded'];
}

public function onProductPageLoaded(ProductPageLoadedEvent $event): void
{
// Load the notice and attach it to the page
}
}
// Administration: override a component
Shopware.Component.override('sw-product-detail-base', {
template,
computed: {
noticeRepository() {
return this.repositoryFactory.create('gb_notice');
},
},
});
export interface Notice {
id: string;
text: string;
validFrom: string | null;
validUntil: string | null;
}
{% sw_extends '@Storefront/storefront/page/product-detail/buy-widget.html.twig' %}

{% block page_product_detail_buy_container %}
{{ parent() }}
{% block gb_notice %}
<div class="gb-notice">{{ page.extensions.gbNotice.text }}</div>
{% endblock %}
{% endblock %}
.gb-notice {
padding: $spacer-sm;
border-left: 4px solid $sw-color-brand-primary;
}
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services">
<services>
<service id="Gambit24\DarstellungsBeispiel\Subscriber\ProductPageSubscriber">
<tag name="kernel.event_subscriber"/>
</service>
</services>
</container>
{
"id": "0190a1b2c3d4e5f6a7b8c9d0e1f2a3b4",
"text": "Versand nur innerhalb Deutschlands.",
"validFrom": null
}
gb_notice:
default_position: below_price
cache_ttl: 3600
SELECT LOWER(HEX(id)) AS id, text
FROM gb_notice
WHERE valid_from IS NULL OR valid_from <= NOW();
bin/console plugin:install --activate GbmsDarstellungsBeispiel
bin/console cache:clear
- $notice = $this->repository->search($criteria, $context)->first();
+ $notice = $this->noticeLoader->load($productId, $context);
Plain text without highlighting, e.g. for log output:
[2026-10-24 12:00:00] app.ERROR: Notice not found {"productId":"..."}

Twig is currently shown without colours, but the code stays readable and copyable.

Title​

src/Resources/config/services.php
return static function (ContainerConfigurator $container): void {
$container->services()->defaults()->autowire()->autoconfigure();
};

Highlighting lines​

Using line numbers in curly brackets:

public function onProductPageLoaded(ProductPageLoadedEvent $event): void
{
$notice = $this->noticeLoader->load($event->getPage()->getProduct()->getId(), $event->getSalesChannelContext());
$event->getPage()->addExtension('gbNotice', $notice);
}

Or with comments directly in the code:

const position = config.position ?? 'below_price';
const notice = await loadNotice(productId);
if (!notice) {
return null;
}
render(notice, position);

Line numbers​

public function load(string $productId, SalesChannelContext $context): ?NoticeStruct
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('productId', $productId));

return $this->repository->search($criteria, $context->getContext())->first();
}

Title, highlighting and line numbers can be combined:

NoticeLoader.php
public function load(string $productId): ?NoticeStruct
{
return $this->cache->get($productId);
}

Inline-Code​

The NoticeLoader service is available under the ID Gambit24\DarstellungsBeispiel\Service\NoticeLoader. Configuration values live under GbmsDarstellungsBeispiel.config.position.

Long lines​

Long lines are not wrapped but scroll horizontally:

$criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_OR, [new EqualsFilter('validFrom', null), new RangeFilter('validFrom', [RangeFilter::LTE => (new \DateTimeImmutable())->format(Defaults::STORAGE_DATE_TIME_FORMAT)])]));