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

Open Graph Protocol Bundle Laravel Package

beyerz/open-graph-protocol-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require beyerz/open-graph-protocol-bundle
    

    Add the bundle to config/bundles.php (Symfony 3.4+):

    return [
        // ...
        Beyerz\OpenGraphProtocolBundle\OpenGraphProtocolBundle::class => ['all' => true],
    ];
    
  2. Basic Configuration (config/packages/open_graph_protocol.yaml):

    open_graph_protocol:
        libraries:
            base:
                default: true
                title: "Default Title"
                description: "Default Description"
                image: "%kernel.project_dir%/public/images/default-ogp.jpg"
    
  3. First Use Case: Inject the OpenGraphProtocolService in a controller and set metadata:

    use Beyerz\OpenGraphProtocolBundle\Service\OpenGraphProtocolService;
    
    class MyController extends AbstractController
    {
        public function show(OpenGraphProtocolService $ogpService)
        {
            $ogpService->setTitle('My Page Title');
            $ogpService->setDescription('My page description');
            $ogpService->setImage('/images/my-image.jpg');
    
            return $this->render('my_template.html.twig');
        }
    }
    
  4. Twig Integration: Use the ogp Twig extension to render metadata in your layout:

    <head>
        {{ ogp('base') }}
    </head>
    

Implementation Patterns

Controller Integration

Dynamic Metadata:

public function showPost(Post $post, OpenGraphProtocolService $ogpService)
{
    $ogpService->setTitle($post->getTitle());
    $ogpService->setDescription($post->getExcerpt());
    $ogpService->setImage($post->getFeaturedImageUrl());
    $ogpService->setUrl($this->generateUrl('post_show', ['id' => $post->getId()]));

    // Add Twitter Card metadata
    $ogpService->setTwitterCard('summary_large_image');
    $ogpService->setTwitterSite('@your_handle');
    $ogpService->setTwitterCreator('@author_handle');

    return $this->render('post/show.html.twig');
}

Reusable Metadata: Create a base controller to handle common OGP logic:

abstract class BaseController extends AbstractController
{
    protected function configureOgp(OpenGraphProtocolService $ogpService, $routeParams)
    {
        $ogpService->setSiteName('My Site');
        $ogpService->setLocale('en_US');
        $ogpService->setUrl($this->generateUrl('homepage'));

        // Route-specific logic
        if (isset($routeParams['id'])) {
            $ogpService->setTitle("Item #{$routeParams['id']}");
        }
    }
}

Twig Integration

Conditional Rendering:

<head>
    {% if app.request.get('_route') == 'post_show' %}
        {{ ogp('base', {'title': post.title, 'image': post.imageUrl}) }}
    {% else %}
        {{ ogp('base') }}
    {% endif %}
</head>

Multiple Libraries:

<head>
    {{ ogp('base') }}
    {{ ogp('facebook', {'app_id': '123456'}) }}
    {{ ogp('twitter') }}
</head>

Event-Driven Approach

Listen to kernel events to set OGP metadata globally:

use Symfony\Component\HttpKernel\Event\FilterResponseEvent;

class OgpSubscriber implements EventSubscriber
{
    public function onKernelResponse(FilterResponseEvent $event)
    {
        $request = $event->getRequest();
        $ogpService = $event->getContainer()->get('open_graph_protocol.service');

        if ($request->attributes->get('_route') === 'post_show') {
            $post = $request->attributes->get('post');
            $ogpService->setTitle($post->getTitle());
            // ... other metadata
        }
    }

    public static function getSubscribedEvents()
    {
        return [
            'kernel.response' => 'onKernelResponse',
        ];
    }
}

API-Driven Metadata

For SPAs or API-first apps, expose OGP metadata via an endpoint:

public function getOgpData(OpenGraphProtocolService $ogpService, Request $request)
{
    $ogpService->setTitle('API Data - ' . $request->query->get('query'));
    $ogpService->setDescription('Search results for: ' . $request->query->get('query'));

    return new JsonResponse($ogpService->getMetadata());
}

Gotchas and Tips

Configuration Quirks

  1. Symfony Version Compatibility:

    • For Symfony < 2.8, use v1.0 of the bundle (traits for container awareness).
    • For Symfony 3.4+, use the latest version (supports modern DI).
  2. Default Values Override:

    • Library defaults in config.yml are merged with runtime values. Runtime values take precedence.
    • Example: If default: true is set for base, but you call setTitle() in code, the code value wins.
  3. Image Paths:

    • Use absolute URLs (e.g., https://example.com/image.jpg) or paths relative to the public directory (e.g., /images/image.jpg).
    • Avoid hardcoding kernel.project_dir in runtime calls; use the service's setImage() with relative paths.

Debugging

  1. Metadata Inspection:

    • Use $ogpService->getMetadata() to debug current metadata before rendering:
      dump($ogpService->getMetadata());
      
  2. Twig Debugging:

    • Check if the Twig extension is loaded by calling {{ dump(ogp('base')) }} in a template.
  3. Missing Metadata:

    • If metadata doesn’t render, verify:
      • The bundle is registered in config/bundles.php.
      • The library is enabled in config/packages/open_graph_protocol.yaml (e.g., default: true).
      • No PHP errors in logs (check var/log/dev.log).

Extension Points

  1. Custom Libraries: Add new libraries in config.yml:

    open_graph_protocol:
        libraries:
            linkedin:
                default: false
                title: "LinkedIn Title"
                description: "LinkedIn Description"
                image: "/images/linkedin-share.jpg"
                url: "https://www.linkedin.com/sharing/"
    

    Then render with {{ ogp('linkedin') }}.

  2. Custom Metadata: Extend the service to add custom tags:

    $ogpService->addCustomTag('<meta property="article:published_time" content="2023-01-01T00:00:00+00:00">');
    
  3. Override Service: Create a custom service class extending OpenGraphProtocolService to add methods like:

    public function setArticleMetadata($publishedTime, $author, $section)
    {
        $this->addCustomTag(sprintf(
            '<meta property="article:published_time" content="%s">',
            $publishedTime
        ));
        $this->addCustomTag(sprintf(
            '<meta property="article:author" content="%s">',
            $author
        ));
        // ... other article-specific tags
    }
    

    Then bind your custom service in services.yaml:

    services:
        App\Service\CustomOpenGraphService:
            decorates: 'open_graph_protocol.service'
            arguments: ['@.inner']
    

Performance Tips

  1. Cache Metadata: For static pages, cache the rendered OGP HTML:

    $cacheKey = 'ogp_' . md5($request->getUri());
    $ogpHtml = $cache->get($cacheKey);
    if (!$ogpHtml) {
        $ogpHtml = $ogpService->render('base');
        $cache->set($cacheKey, $ogpHtml, 3600); // Cache for 1 hour
    }
    
  2. Avoid Runtime Overhead: Set metadata as early as possible in the request lifecycle (e.g., in a subscriber) to minimize runtime processing.

Common Pitfalls

  1. Relative vs. Absolute URLs:

    • If setImage() uses a relative path (e.g., /images/ogp.jpg), ensure the base URL is correctly set in the rendered output.
    • For absolute paths, use full URLs (e.g., https://example.com/images/ogp.jpg).
  2. Missing ogp Twig Function:

    • If {{ ogp('base') }} fails, ensure the Twig extension is registered. Check for errors in var/log/dev.log.
  3. Facebook Debugger Issues:

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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours