承接 daddl3/seo-tool-bundle 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

daddl3/seo-tool-bundle

Composer 安装命令:

composer require daddl3/seo-tool-bundle

包简介

All in One Symfony Seo Bundle

README 文档

README

All-in-One Symfony SEO Bundle — Meta Tags, Open Graph, Schema.org, Breadcrumbs, Google Tag Manager, Meta Pixel, and full Profiler support.

Requirements: PHP 8.5+, Symfony 8.x

Installation

composer require daddl3/seo-tool-bundle

Symfony Flex registers the bundle automatically. If not:

// config/bundles.php
return [
    Daddl3\SeoToolBundle\SeoBundle::class => ['all' => true],
];

Configuration

All options in config/packages/seo.yaml:

seo:

    # Schema.org — inject JSON-LD into <head>
    schema:
        enabled: true
        cache_ttl: 604800   # Cache in seconds (default: 1 week)

    # Meta Tags — global default values
    meta_tags:
        title: 'My Website'
        description: 'Default description'
        keywords: ['symfony', 'seo']

    # Open Graph — global default values
    open_graph:
        title: 'My Website'
        description: 'Default description'
        sitename: 'My Website'
        url: 'https://example.com'
        type: 'website'

    # Google Tag Manager
    google_tag_manager:
        enabled: true
        tag_manager_id: 'GTM-XXXXXX'

    # Meta Pixel (Facebook)
    meta_pixel:
        enabled: true
        pixel_id: '1234567890'

Features

Meta Tags

In the Controller

use Daddl3\SeoToolBundle\Metas\MetaTagsManagerInterface;

class ProductController extends AbstractController
{
    public function show(MetaTagsManagerInterface $meta): Response
    {
        $meta
            ->setTitle('Product Name')
            ->setDescription('Short product description')
            ->setKeywords(['product', 'shop', 'symfony'])
            ->setCanonical('https://example.com/product')
            ->setRobots(['index', 'follow'])
            ->setAuthor('John Doe')
            ->setViewPort('width=device-width, initial-scale=1')
            ->setCharacterEncoding('UTF-8')
            ->setCopyright('2025 Example Inc.')
            ->setContentType('text/html; charset=UTF-8')
            ->setContentSecurityPolicy("default-src 'self'")
            ->setSubject('E-Commerce')
            ->setXUACompatible()
            ->setCustomMetaTag('theme-color', '#ffffff')
        ;

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

In a Twig Template

{{ meta_tags(
    title: 'Product Name',
    description: 'Short description',
    keywords: ['product', 'shop'],
    canonical: 'https://example.com/product',
    robots: ['index', 'follow']
) }}

Values from the controller and the template are merged. Template values override controller values.

Include in the Base Template

<head>
    {{ meta_tags() }}
</head>

Output

<meta charset="UTF-8" />
<title>Product Name</title>
<meta name="description" content="Short product description" />
<meta name="keywords" content="product, shop, symfony" />
<meta name="robots" content="index, follow" />
<link rel="canonical" href="https://example.com/product" />
<meta name="author" content="John Doe" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

All Available Methods

MethodDescription
setTitle(string)Page title (<title>)
setDescription(string)Meta description
setKeywords(array)Meta keywords
setCanonical(string)Canonical URL
setRobots(array)Robots directives (index, follow, noindex, …)
setAuthor(string)Author
setViewPort(string)Viewport
setCharacterEncoding(string)Character encoding (default: UTF-8)
setCopyright(string)Copyright notice
setSubject(string)Page subject
setContentType(string)Content type
setContentSecurityPolicy(string)CSP header
setAlternate(string, string)Alternate link (href, media)
setXUACompatible()IE compatibility mode (IE=edge)
setDefaultStyle(string)Default stylesheet
setCustomMetaTag(string, string)Custom meta tag (name, content)

Open Graph

In the Controller

use Daddl3\SeoToolBundle\OpenGraph\OpenGraphManagerInterface;

class ArticleController extends AbstractController
{
    public function show(OpenGraphManagerInterface $og): Response
    {
        $og
            ->setTitle('Article Title')
            ->setDescription('Description for social media')
            ->setImage('https://example.com/image.jpg')
            ->setImageAltText('Image description')
            ->setUrl('https://example.com/article')
            ->setType('article')
            ->setLocale('en_US')
            ->setAlternateLocale('de_DE')
            ->setSiteName('My Website')
        ;

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

In a Twig Template

{{ open_graph(
    title: 'Article Title',
    description: 'Description for social media',
    imageUrl: 'https://example.com/image.jpg',
    url: 'https://example.com/article',
    type: 'article'
) }}

Include in the Base Template

<head>
    {{ open_graph() }}
</head>

Output

<meta property="og:title" content="Article Title" />
<meta property="og:description" content="Description for social media" />
<meta property="og:image" content="https://example.com/image.jpg" />
<meta property="og:url" content="https://example.com/article" />
<meta property="og:type" content="article" />
<meta property="og:site_name" content="My Website" />

OG Image

Extended image metadata with og:image:* tags.

Controller:

use Daddl3\SeoToolBundle\OpenGraph\OGImageManagerInterface;

public function show(OGImageManagerInterface $ogImage): Response
{
    $ogImage
        ->setUrl('https://example.com/og.jpg')
        ->setSecureUrl('https://example.com/og.jpg')
        ->setType('image/jpeg')
        ->setWidth('1200')
        ->setHeight('630')
        ->setAlt('Image description')
    ;
}

Twig:

{{ og_image(
    url: 'https://example.com/og.jpg',
    type: 'image/jpeg',
    width: '1200',
    height: '630',
    alt: 'Image description'
) }}

Output:

<meta property="og:image" content="https://example.com/og.jpg" />
<meta property="og:image:secure_url" content="https://example.com/og.jpg" />
<meta property="og:image:type" content="image/jpeg" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="Image description" />

OG Video

Controller:

use Daddl3\SeoToolBundle\OpenGraph\OGVideoManagerInterface;

public function show(OGVideoManagerInterface $ogVideo): Response
{
    $ogVideo
        ->setUrl('https://example.com/video.mp4')
        ->setSecureUrl('https://example.com/video.mp4')
        ->setType('video/mp4')
        ->setWidth('1280')
        ->setHeight('720')
    ;
}

Twig:

{{ og_video(url: 'https://example.com/video.mp4', type: 'video/mp4', width: '1280', height: '720') }}

Output:

<meta property="og:video" content="https://example.com/video.mp4" />
<meta property="og:video:secure_url" content="https://example.com/video.mp4" />
<meta property="og:video:type" content="video/mp4" />
<meta property="og:video:width" content="1280" />
<meta property="og:video:height" content="720" />

OG Audio

Controller:

use Daddl3\SeoToolBundle\OpenGraph\OGAudioManagerInterface;

public function show(OGAudioManagerInterface $ogAudio): Response
{
    $ogAudio
        ->setUrl('https://example.com/audio.mp3')
        ->setSecureUrl('https://example.com/audio.mp3')
        ->setType('audio/mpeg')
    ;
}

Twig:

{{ og_audio(url: 'https://example.com/audio.mp3', type: 'audio/mpeg') }}

Output:

<meta property="og:audio" content="https://example.com/audio.mp3" />
<meta property="og:audio:secure_url" content="https://example.com/audio.mp3" />
<meta property="og:audio:type" content="audio/mpeg" />

OG Article

Controller:

use Daddl3\SeoToolBundle\OpenGraph\OGArticleManagerInterface;

public function show(OGArticleManagerInterface $ogArticle): Response
{
    $ogArticle
        ->setPublishedTime(new \DateTime('2025-01-15'))
        ->setModifiedTime(new \DateTime('2025-06-01'))
        ->setAuthor('John Doe')
        ->setSection('Technology')
        ->setTags(['symfony', 'php', 'seo'])
    ;
}

Twig:

{{ og_article(
    author: 'John Doe',
    section: 'Technology',
    tags: ['symfony', 'php', 'seo']
) }}

Output:

<meta property="article:published_time" content="..." />
<meta property="article:modified_time" content="..." />
<meta property="article:author" content="John Doe" />
<meta property="article:section" content="Technology" />
<meta property="article:tag" content="symfony" />
<meta property="article:tag" content="php" />
<meta property="article:tag" content="seo" />

Twitter Cards

Twitter Cards are added via the OpenGraphManager:

$og->addTwitterCardProperty('card', 'summary_large_image');
$og->addTwitterCardProperty('site', '@myWebsite');
$og->addTwitterCardProperty('creator', '@author');
$og->addTwitterCardProperty('title', 'Article Title');
$og->addTwitterCardProperty('description', 'Description for Twitter');

Output:

<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:site" content="@myWebsite" />
<meta property="twitter:creator" content="@author" />

Structured Properties

For og:video:*, og:audio:*, and og:image:* inline in the OG block:

$og->addStructuredProperty('video', 'secure_url', 'https://example.com/video.mp4');
$og->addStructuredProperty('image', 'width', '1200');

Output:

<meta property="og:video:secure_url" content="https://example.com/video.mp4" />
<meta property="og:image:width" content="1200" />

For music:

$og->addMusicProperty('musician', 'https://example.com/artist');

Schema.org (Rich Results)

First enable it in the configuration:

seo:
    schema:
        enabled: true
        cache_ttl: 604800

The schema is automatically injected as <script type="application/ld+json"> into the <head>.

In the Controller

use Daddl3\SeoToolBundle\Schema\SchemaInterface;

class ArticleController extends AbstractController
{
    public function show(SchemaInterface $schema): Response
    {
        $article = $schema->article()
            ->name('My Article')
            ->setDescription('Article description')
            ->url('https://example.com/article')
        ;

        $schema->render($article);

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

Output

<script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@type": "Article",
    "name": "My Article",
    "description": "Article description",
    "url": "https://example.com/article"
}
</script>

Nested Objects

$person = $schema->person()
    ->name('John Doe')
    ->url('https://example.com/john')
;

$org = $schema->organization()
    ->name('Example Inc.')
    ->url('https://example.com')
;

$schema->render(
    $schema->article()
        ->name('My Article')
        ->setDescription('...')
);

Supported Schema Types

CategoryTypes
Thingthing(), person(), organization(), place(), event(), action()
CreativeWorkcreativeWork(), article(), blogPosting(), socialMediaPosting(), blog(), course(), thesis(), website(), mediaObject(), imageObject(), textObject()
WebPagewebPage(), aboutPage(), contactPage(), faqPage(), itemPage(), checkoutPage(), profilePage(), searchResultPage(), collectionPage(), mediaGallery(), imageGallery(), webPageElement()
Organizationorganization(), localBusiness(), library(), radioStation(), travelAgency()
Placeplace(), administrativeArea(), country()
IntangiblejobPosting(), occupation(), breadcrumbList(), listItem(), itemList(), definedTerm(), specialty(), speakableSpecification(), monetaryAmount(), propertyValue(), offer()
Otherservice(), audience(), postalAddress(), educationOccupationalCredential()

Breadcrumb

In the Controller

use Daddl3\SeoToolBundle\Breadcrumb\BreadcrumbManagerInterface;

class BlogController extends AbstractController
{
    public function show(BreadcrumbManagerInterface $breadcrumb): Response
    {
        $breadcrumb
            ->addItem('Home', 'https://example.com')
            ->addItem('Blog', 'https://example.com/blog')
            ->addItem('My Article')   // last item without URL = active
        ;

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

Render in the Template

{{ seo_breadcrumb() }}

Output (Bootstrap)

<ol class="breadcrumb">
    <li class="breadcrumb-item"><a href="https://example.com">Home</a></li>
    <li class="breadcrumb-item"><a href="https://example.com/blog">Blog</a></li>
    <li class="breadcrumb-item active">My Article</li>
</ol>

Customize CSS Classes

$breadcrumb->setOptions([
    'list_class'      => 'breadcrumb',
    'list_item_class' => 'breadcrumb-item',
    'active_item'     => 'active',
]);

Google Tag Manager

Configuration (automatically on all pages)

seo:
    google_tag_manager:
        enabled: true
        tag_manager_id: 'GTM-XXXXXX'

Automatically injects the GTM code into <head> and <body>.

Programmatically per Request

use Daddl3\SeoToolBundle\Seo\GoogleTagManager\TagManagerInterface;

public function index(TagManagerInterface $tagManager): Response
{
    $tagManager->enableGoogleTagManager('GTM-XXXXXX');

    return $this->render('index.html.twig');
}

Meta Pixel (Facebook)

Configuration (automatically on all pages)

seo:
    meta_pixel:
        enabled: true
        pixel_id: '1234567890'

Programmatically per Request

use Daddl3\SeoToolBundle\Seo\MetaPixel\MetaPixelInterface;

public function index(MetaPixelInterface $metaPixel): Response
{
    $metaPixel->enableMetaPixel('1234567890');

    return $this->render('index.html.twig');
}

Symfony Profiler

A full SEO profiler is available in dev mode.

Toolbar shows the status of all features at a glance:

FeatureGreenYellowRed
Meta Tagssetnot set
Open Graphsetnot set
Twitter Cardssetnot set
OG Image / Video / Audio / Articlesetnot set
Schema.orgtype namenot set
Breadcrumbnumber of items0 items
Google GTMGTM IDnot configured
Meta PixelPixel IDnot configured

Profiler panel shows for each page:

  • Overview of all features with status
  • All set meta tags in detail
  • Open Graph tags (base, Twitter Cards, Structured Properties, Music)
  • Separate panels for OG Image, Video, Audio, Article Manager
  • Schema.org JSON-LD preview
  • Breadcrumb items as a table
  • Google Tag Manager ID
  • Meta Pixel ID

daddl3/seo-tool-bundle 适用场景与选型建议

daddl3/seo-tool-bundle 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 100 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 03 月 31 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「seo」 「Symfony Bundle」 「symfony seo」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 daddl3/seo-tool-bundle 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 daddl3/seo-tool-bundle 我们能提供哪些服务?
定制开发 / 二次开发

基于 daddl3/seo-tool-bundle 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 100
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 10
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-03-31