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

Remote Media Bundle Laravel Package

netgen/remote-media-bundle

Netgen Remote Media Bundle integrates remote media providers into Symfony/eZ Platform, adding a field type and browser so editors can search, preview, and embed externally hosted videos, images, and files without uploading them to the CMS.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the reality check: this is an eZ Publish / eZ Platform (Ibexa) bundle, not a Laravel package. There is no service provider, no publishable config, no Blade directives. You cannot composer require this into a Laravel app and get anything useful. If you are a Laravel dev, treat this as a reference implementation for modelling remote-media fields (provider registry + value object + render helpers) — or as work you only take on inside an Ibexa codebase. The concepts map cleanly (container, config tree, tagged services, Twig extensions), the plumbing does not.

Minimal path if you are on Ibexa/eZ:

  1. Install and enable the bundle:
    composer require netgen/remote-media-bundle
    
    Then register Netgen\Bundle\RemoteMediaBundle\NetgenRemoteMediaBundle in config/bundles.php (Symfony 4/5) or the legacy ezpublish/EzPublishKernel.php / app/AppKernel.php for eZ Publish.
  2. Configure at least one provider (Cloudinary is the reference implementation) with credentials via env vars.
  3. Add the bundle's field type to a content type — via the admin UI or a content-type definition/migration — and store a value on a content item.
  4. Render it in a template and confirm the URL resolves.

Where to look first, in this order:

  • DependencyInjection/Configuration.php — the authoritative config shape. Do not trust blog snippets; the provider config array changed across versions.
  • Provider/ProviderInterface.php (and Provider/Cloudinary/CloudinaryProvider.php) — the contract you implement for a custom backend.
  • eZ/FieldType/RemoteMedia/ (or FieldType/RemoteMedia/ in Ibexa-era versions) — the field type, Value, and Type classes. This tells you exactly what is persisted.
  • Resources/config/services.yml — the service IDs and, critically, the provider tag name.
  • Resources/views/ — the default Twig template, which is what you will override.

First real use case: a "Video" or "Image" field on an article content type where editors paste a Cloudinary public ID or a YouTube/Vimeo URL, and the front end renders a provider-transformed asset rather than a locally stored binary. This is the bundle's whole reason to exist: no binary in your DB or var storage, provider-side transforms, one field type for many sources.

Implementation Patterns

Provider registry, not hardcoded calls. Everything routes through a registry keyed by provider identifier. That means your templates and business logic ask for cloudinary or vimeo by name and never import a concrete client. Follow that discipline in your own code — never instantiate a provider directly.

Custom provider. Implement the provider interface, return the field's value object from getValue(), and tag the service. The tag name is the thing to verify in services.yml; it is roughly:

App\Media\VimeoProvider:
    tags:
        - { name: netgen.remote_media.provider, alias: vimeo }

Then register it under providers: in the bundle config so the admin UI and field type can resolve it. If your service is private (Symfony 4+ default), the registry lookup at runtime will fail — see Gotchas.

Rendering. Use the bundle's Twig helpers/extensions rather than reconstructing URLs by hand; the helper handles provider dispatch and transformation option formatting. Override the shipped field template by placing a template at the same path under your app's templates directory — this is the standard eZ/Ibexa override mechanism and is far less brittle than editing the vendor view.

Headless / API output. The stored value is small: provider identifier, resource ID, and any provider metadata (width/height, resource type, alt text depending on version). That is the right thing to serialize. Build the delivery URL in your API layer via the provider so transformations stay server-side and you never leak API secrets into JSON. If you need signed URLs, generate them per-request in the controller — never cache a signed URL beyond its expiry.

Responsive markup. Because the asset lives at the provider, do not fight the CMS's image variation system. Request srcset candidates as distinct provider transformations and emit a plain <picture>/<img srcset> block. Keep a single mapping of your breakpoints to transformation strings in one Twig macro or PHP class so it is not duplicated across templates.

Content migration / fixtures. When creating content programmatically, construct the field value through the field type's value class and let the field type's Type::toPersistenceValue() do the work. Do not write raw hashes into the attribute table. If you are importing a large set of Cloudinary assets, batch it and throttle — provider APIs rate-limit and a naive loop will burn your quota mid-import.

Testing. Write a fake provider that returns deterministic URLs, tag it, and use it in functional tests. Assert on the resolved URL and on the rendered markup, not on the provider SDK. This keeps CI free of network calls and credentials.

Gotchas and Tips

  • It is not a Laravel package. No facade, no config/remote-media.php, no Blade component. Any tutorial that implies otherwise is wrong. Porting the idea to Laravel is a rewrite, not an install.
  • Private services break provider resolution. On modern Symfony, services are private by default and the registry resolves by tag alias. If you get "provider not found" for a provider you definitely registered, check public: true / a service alias / whether the registry uses a service locator. This is the single most common integration failure.
  • Config shape drift. The bundle is at version 22.x-era maturity but only ~18 stars and few dependents — the user base is small, so Stack Overflow coverage is near zero. Read Configuration.php for your installed version rather than trusting any snippet, including ones in this write-up.
  • Verify the field type identifier. Register it in content types using the exact identifier the bundle declares (historically ngremotemedia), not the class name. A mismatch produces a silently empty field in the admin UI.
  • eZ Publish vs eZ Platform paths differ. Legacy and Platform versions ship different directory layouts (eZ/FieldType/... vs FieldType/...) and different template override conventions. Confirm which branch you installed before copying code.
  • No local fallback. If the provider is down or credentials expire, you get a broken URL with no cached copy. For anything user-facing, store a low-res poster/fallback URL in a separate field or in the value's metadata, and render it on error.
  • Credentials are load-bearing. Missing or malformed Cloudinary credentials often surface as a generic render error, not a clear config error. Validate them in a smoke test on boot or in CI rather than discovering it in production.
  • Transformation strings are provider-specific. w_600 means nothing to Vimeo. Do not try to build a provider-agnostic transformation DSL on top; expose per-provider options and let templates pass the right ones.
  • Alt text and accessibility are on you. Depending on version, the field may not carry an alt attribute. Add a companion text field on the content type and thread it through the template — retrofitting alt text across a live site is painful.
  • Extension point worth knowing: the provider interface is the intended seam. Everything else (field type, Twig extension) is thin. If the bundle does not do what you need, the right move is a provider or a template override, not a fork.
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.
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
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console