Weave Code
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

Contentful Bundle Laravel Package

atolye15/contentful-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require atolye15/contentful-bundle
    

    Ensure your composer.json requires twig/twig (for Twig integration).

  2. Register the Bundle:

    • Symfony 4+: Add to config/bundles.php:
      return [
          // ...
          Atolye15\ContentfulBundle\ContentfulBundle::class => ['dev' => true],
      ];
      
    • Symfony 3: Add to AppKernel.php:
      new Atolye15\ContentfulBundle\ContentfulBundle(),
      
  3. Configure Contentful: Create config/packages/contentful.yaml (Symfony 4) or app/config/config.yml (Symfony 3):

    contentful:
        delivery:
            main:
                space: "YOUR_SPACE_ID"
                token: "YOUR_DELIVERY_TOKEN"
                default: true
    
  4. First Use Case: Fetch content in a controller:

    use Contentful\Delivery\ClientInterface;
    
    class PageController extends AbstractController
    {
        public function show(ClientInterface $client)
        {
            $entry = $client->getEntry('YOUR_ENTRY_ID');
            return $this->render('page.html.twig', ['entry' => $entry]);
        }
    }
    

Implementation Patterns

Dependency Injection & Autowiring

  • Type-hint ClientInterface in services/controllers to leverage autowiring:
    public function __construct(ClientInterface $client) { ... }
    
  • Named Clients: Use default: true in config to specify which client is autowired when multiple are defined.

Common Workflows

  1. Fetching Entries:

    $entry = $client->getEntry('entryId');
    $fields = $entry->getFields();
    
  2. Querying Content:

    $entries = $client->getEntries([
        'content_type' => 'blogPost',
        'limit' => 10,
    ]);
    
  3. Handling Assets:

    $asset = $client->getAsset('assetId');
    $url = $asset->getFields()->get('file')->getUrl();
    
  4. Preview Mode: Configure a separate client in config/packages/contentful.yaml:

    contentful:
        delivery:
            preview:
                space: "YOUR_SPACE_ID"
                token: "YOUR_PREVIEW_TOKEN"
                api: preview
    

    Inject the preview client where needed:

    public function __construct(ClientInterface $previewClient) { ... }
    
  5. Caching: Enable caching in config:

    contentful:
        delivery:
            main:
                cache: true
    

    Use cache:clear command to purge cached data.

Integration with Twig

Pass Contentful data to Twig templates:

return $this->render('template.html.twig', [
    'entries' => $entries,
]);

Access fields in Twig:

{% for entry in entries %}
    <h1>{{ entry.fields.title }}</h1>
    {% for field in entry.fields %}
        {{ dump(field) }}
    {% endfor %}
{% endfor %}

Command-Line Tools

  • Debug Space Info:
    php bin/console contentful:delivery:debug
    
  • Check Client Configuration:
    php bin/console contentful:delivery:info
    

Gotchas and Tips

Configuration Quirks

  1. Breaking Changes in v4:

    • The bundle now uses Contentful SDK v4. Review the upgrade guide if migrating from older versions.
    • Configuration format changed. Ensure delivery is the top-level key:
      contentful:
          delivery:  # <-- Correct
              main: ...
      
  2. Preview Mode:

    • Preview tokens require api: preview in config. Without it, the client defaults to delivery.
    • Preview content is not cached by default (unlike delivery mode).
  3. Caching:

    • Caching is disabled by default. Enable it explicitly:
      contentful:
          delivery:
              main:
                  cache: true
      
    • Cache keys are based on space, locale, and content_type. Clear cache with:
      php bin/console cache:clear
      
  4. Locale Handling:

    • Set a default_locale in config to avoid errors when fetching entries without a specified locale:
      contentful:
          delivery:
              main:
                  default_locale: "en-US"
      

Debugging

  1. Web Profiler:

    • Requests to Contentful are logged in the Symfony Profiler (enabled in dev mode).
    • View headers, response bodies, and metrics under the "Contentful" tab.
  2. Common Errors:

    • InvalidSpaceId: Verify space and token in config.
    • InvalidEntryId: Ensure the entry ID exists in Contentful.
    • AuthenticationError: Check token permissions (e.g., preview tokens can’t access delivery content).
  3. Logging:

    • Enable request logging for debugging:
      contentful:
          delivery:
              main:
                  request_logging: true
      

Extension Points

  1. Custom HTTP Client: Override the default Guzzle client:

    contentful:
        delivery:
            main:
                http_client: "@your_custom_guzzle_service"
    
  2. URI Override: Useful for testing or custom endpoints:

    contentful:
        delivery:
            main:
                uri_override: "https://api.contentful.com"
    
  3. Event Listeners: Subscribe to Contentful events (e.g., Contentful\Delivery\Event\EntryFetchedEvent) via Symfony’s event dispatcher:

    services:
        App\EventListener\ContentfulListener:
            tags:
                - { name: kernel.event_listener, event: Contentful\Delivery\Event\EntryFetchedEvent, method: onEntryFetched }
    

Performance Tips

  1. Batch Requests: Use getEntries() with limit and sys.id pagination to avoid fetching all entries at once:

    $entries = $client->getEntries(['limit' => 100, 'sys.id' => ['in' => ['entry1', 'entry2']]]);
    
  2. Selective Field Loading: Reduce payload size by specifying fields:

    $client->getEntries(['content_type' => 'blogPost', 'fields' => ['title', 'summary']]);
    
  3. Avoid Redundant Calls: Cache responses in your application layer if needed (e.g., using Symfony’s cache system):

    $cache = $this->get('cache.app');
    $cached = $cache->get('contentful_entries');
    if (!$cached) {
        $entries = $client->getEntries(...);
        $cache->set('contentful_entries', $entries, 3600);
    }
    

Migration Pitfalls

  • Symfony 3 to 4:
    • Update bundles.php from AppKernel.php.
    • Move config from app/config/config.yml to config/packages/contentful.yaml.
  • SDK Version Mismatches:
    • Ensure atolye15/contentful and contentful/contentful-bundle versions align (e.g., 4.2.* for SDK v4).

Security

  • Never expose tokens in client-side code. Use environment variables or Symfony’s %env%:
    contentful:
        delivery:
            main:
                token: "%env(CONTENTFUL_DELIVERY_TOKEN)%"
    
  • Restrict tokens in Contentful’s API keys section to only allow necessary operations (e.g., content_delivery_api or content_preview_api).
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky