Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Layouts Remote Media Laravel Package

netgen/layouts-remote-media

Netgen Layouts Remote Media adds remote media support to Netgen Layouts, letting editors fetch, manage, and render externally hosted media within layout blocks. A PHP package for flexible, reusable media content in Layouts-powered sites.

View on GitHub
Deep Wiki
Context7

Getting Started

What it is. netgen/layouts-remote-media is a thin bridge bundle that plugs a remote media source into Netgen Layouts. In practice that means one or both of:

  • a block definition (e.g. remote_media) you can drop onto a layout zone in the Layouts admin UI, whose parameter is an asset picked from the remote library;
  • an item provider / item type that turns a remote asset into a Layouts ItemInterface object so it can be stored as a block item, a collection query result, or a target of a custom block parameter.

Before writing any code, read three things in vendor/netgen/layouts-remote-media/:

  1. src/ — the Item/, Block/BlockDefinition/Handler/ and Item/ValueType/ namespaces tell you exactly what the package exposes.
  2. src/Resources/config/ — services.yaml (tags like netgen_layouts.block_definition.handler, netgen_layouts.item.value_type) and any layouts.yaml with default block definition config.
  3. composer.json — the netgen/layouts-* version constraint. This is the single most important compatibility signal (see Gotchas).

Minimal setup.

composer require netgen/layouts-remote-media
// config/bundles.php
return [
    // ...
    Netgen\Layouts\Bundle\NetgenLayoutsBundle::class => ['all' => true],
    Netgen\Layouts\RemoteMedia\NetgenLayoutsRemoteMediaBundle::class => ['all' => true],
];
# .env.local — whatever the package's Configuration.php expects
REMOTE_MEDIA_BASE_URI=https://media.example.com
REMOTE_MEDIA_TOKEN=xxxxxxxx
# config/packages/netgen_layouts_remote_media.yaml
# Check the bundle's Configuration.php for the real key; it is usually
# a single-node root config, not nested under netgen_layouts.

Then clear cache and check the wiring rather than guessing:

bin/console cache:clear
bin/console debug:container --tag=netgen_layouts.block_definition.handler | grep -i media
bin/console debug:config netgen_layouts_remote_media

First use case to prove it works. Open a layout in the Layouts admin UI, add the "Remote media" block to a zone, pick one asset from the remote library, publish the layout, and confirm the front end renders it. If that round-trip works, the HTTP client, credentials, item provider and template override path are all correct — and everything else is variation on that.

Implementation Patterns

Render through theme templates, not the vendor template. Layouts resolves block templates per theme and view type. Override rather than edit vendor files:

templates/themes/<theme>/blocks/remote_media/<view_type>.html.twig

Typical render — item values are exposed as block.item.<valueIdentifier>:

{% if block.item is not null %}
    <figure>
        <img
            src="{{ netgen_layouts_image(block.item, 'large') }}"
            alt="{{ block.item.value('alt_text') }}"
            loading="lazy"
        >
        <figcaption>{{ block.item.name }}</figcaption>
    </figure>
{% endif %}

Reuse the item in your own blocks. The highest-value pattern is not the shipped block but using the remote item as a parameter on a block you already own. Register a value type and a parameter definition in your bundle's config/services.yaml:

App\Layouts\Block\Parameter\RemoteMediaParameter:
    tags:
        - { name: netgen_layouts.block_definition.parameter_type, alias: remote_media }

You then get the remote media picker UI for free on existing blocks (hero, teaser, gallery) instead of forcing editors into a dedicated block.

Custom block definitions that only borrow rendering. Keep netgen_layouts.block_definitions declarative where you can, and fall back to a PHP BlockDefinition + Handler\Plugin when you need extra parameters (crop, aspect ratio, focal point):

final class RemoteMediaPlugin implements PluginInterface
{
    public static function getDefaultConfig(): array
    {
        return [
            'aspect_ratio' => ['type' => 'string', 'default' => '16:9'],
            'crop' => ['type' => 'string', 'default' => 'fill'],
        ];
    }
}

Batch the HTTP calls. If the remote item is fetched lazily when the item is hydrated, a grid of twelve blocks means twelve round-trips. Two mitigations:

  • Warm the item into the Layouts item cache (the item loader) on publish, not on render.
  • Or resolve the remote payload once per request in a small Item\ItemResolver-style service keyed by remote identifier, and have the value types read from that per-request map.
final class PerRequestRemoteCache
{
    /** @var array<string, array> */
    private array $resolved = [];

    public function get(string $id, callable $fetch): array
    {
        return $this->resolved[$id] ??= $fetch($id);
    }
}

Make values cacheable and siteaccess-aware. Remote assets rarely change, so tag your items and blocks with a TTL and, if available, the remote identifier. Configure per-siteaccess where the block is available:

netgen_layouts:
    system:
        default:
            block_definitions:
                remote_media:
                    enabled: true
            block_types:
                remote_media:
                    name: 'Remote media'

Test without the network. Symfony HttpClient's MockHttpClient plus KernelBrowser is enough to cover the item provider end to end; assert on the rendered block HTML rather than on internal service calls, since the package's internals are not a stable contract.

Gotchas and Tips

  • Version alignment is the whole ballgame. Netgen ships netgen/layouts-* packages in lockstep with the core. A ~1.x remote-media bundle against netgen/layouts-core ^2.0 will autoload and then explode on moved classes. Always check with composer why-not netgen/layouts-core before debugging anything else.
  • Bundle order matters. Register the remote-media bundle after NetgenLayoutsBundle; a few CompilerPass decorators assume the core services are already registered.
  • The config key is not necessarily netgen_layouts. Read DependencyInjection/Configuration.php and use debug:config <root_key> — guessing the node name costs more time than reading twenty lines of PHP.
  • Cache invalidation is the real hazard. Layouts' cache has no idea that an asset changed upstream. If editors replace an image in the remote library, the layout will keep serving the old one. Options: short TTL on the item, a remote updated_at folded into the item's cache key, or an explicit admin "clear layout cache" workflow after remote edits.
  • Signed / expiring URLs break persistence. If your value type stores a full URL rather than an identifier, the block degrades into a dead link the moment the remote token rotates. Prefer storing the identifier and generating the URL at render time.
  • Null items render silently blank. The provider returns null for a missing/403 asset and Twig prints nothing. Wrap output in {% if block.item %} and log misses at the provider level; otherwise "the page is broken" tickets are hard to trace.
  • N+1 on collection pages. Blocks inside a collection are rendered per item. Prefetch or memoise the remote payload per request (see above) before you blame Layouts' performance.
  • Admin UI picker needs the identifier, not just the URL. If the picker is empty while the front end works, the problem is usually the search/list endpoint or the admin asset registration — check Resources/config/ for the admin-side service tag and confirm the bundle's JS/CSS is published (assets:install / webpack copy step).
  • Debugging entry points. debug:container --tag=netgen_layouts.block_definition.handler, debug:config, and the Layouts admin "Preview" mode will resolve 90% of "block doesn't appear" issues faster than reading the bundle source.
  • Extension points before forking. BlockDefinition\Handler\Plugin for extra parameters, a custom ValueType for fields the package doesn't map, and a decorated item provider for different remote endpoints. Only patch vendor code as a last resort.
  • Adoption risk. Zero stars and zero dependents means no community docs and no upstream bug reports. Pin the exact version (or a commit hash) in composer.json, budget for maintaining a fork, and put a one-page internal README next to your integration describing the credentials, endpoints, and template overrides — future-you will not remember which theme template is load-bearing.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource