netgen/layouts-contentful
Netgen Layouts Contentful integrates Contentful CMS with Netgen Layouts, letting you use Contentful entries as dynamic content sources and render queried Contentful content within your layouts alongside existing providers.
composer require netgen/layouts-contentful pulls in netgen/layouts-core and a Contentful delivery SDK. The package ships a Symfony bundle (NetgenLayoutsContentfulBundle), which you register in config/bundles.php alongside the core Layouts bundle(s). If your project is Laravel-first, this integration is not plug-and-play — you'd need the Symfony framework components and an actual Netgen Layouts installation underneath. Treat it as a Symfony bundle you happen to consume from a Laravel-adjacent codebase (e.g., a sub-application), not a Laravel package.space_id, environment (defaults to master in Contentful, but the SDK can quietly 404 if you omit it), and an access_token. Use a delivery token in production and a preview token plus preview: true in staging/editor environments. Keep both in env vars.DependencyInjection/Configuration.php (the config tree you'll actually be editing), the collection query handler / block handler services (this is what turns a Layouts block into a Contentful API call), and any ItemView/value-converter classes (this is what maps a Contentful entry to a Twig template). Those three files tell you 80% of what the package does.netgen_layouts config that uses the Contentful collection query type, pointing at one content type (e.g. article). Render that block in a layout, then render each entry with an item view template you supply. Once that loop works end-to-end, the rest of the package is variations on it.netgen_layouts.block_definitions and let the Contentful collection query handler resolve entries at render time. Keep one block definition per content type rather than one generic "Contentful block" — it makes the admin UI understandable and the caching granular.netgen_layouts config or via a design) that map each Contentful content type to a Twig template. This is where you normalize fields, handle missing optional fields, and render assets. Resist the urge to make a single mega-template; one template per content type scales much better when marketing adds fields.Entry objects. Define a small typed DTO or resolver class per content type so templates don't do defensive isset() gymnastics. This also gives you one place to update when a content model changes.en-US, de-DE, and they must match exactly; don't assume en works.preview on and see draft/unpublished entries inside Layouts. This is the single feature that makes the integration tolerable for content teams — without it, every change is a publish-and-wait loop.publish/unpublish/delete and clears the matching tags. This is not provided out of the box — you implement the endpoint and the listener.contentful/rich-text PHP packages or a custom Twig extension) and register it as a Twig function/filter so templates can do {{ entry.richText|contentful_rich_text }}.?w=&h=&fm=webp&q=80). Add a Twig helper that builds these from an asset + a size preset; don't sprinkle raw images.ctfassets.net URLs across templates.master. If you use separate environments for staging/prod, set environment explicitly in both configs.preview: true behind an environment check, and never let a preview token end up in a cached response. Content teams will copy config between environments.include parameter controls how many levels of linked entries/assets come back hydrated. Anything deeper than the default (usually 1–2) is not resolved — you'll get stub objects. Either set include depth or build a resolver that fetches referenced entries by ID.services.yaml — override with a compiler pass or explicit decorator so upgrades stay portable.How can I help you explore Laravel packages today?