umanit/seo-bundle

在 Doctrine 实体上提供 SEO 功能。

安装次数: 9,297

依赖项: 0

建议者: 0

安全性: 0

星标: 5

关注者: 6

分支: 2

开放问题: 3

类型:symfony-bundle

3.0.4 2024-07-10 13:48 UTC

README

此包为任何模型实体添加 SEO 功能。

功能

  • 访问旧 URL 时的 301 重定向
  • SEO 元数据(标题和描述)
  • 规范 URL
  • Schema.org
  • 面包屑导航
  • 网站地图

安装

$ composer require umanit/seo-bundle

配置

需要在您的 Twig 配置中声明模板,其他模板之前。您必须在这两个选项中选择一个

twig:
    # ...
    form_themes:
        - '@UmanitSeo/sylius/form/fields.html.twig'
        # OR
        - '@UmanitSeo/sonata/form/fields.html.twig'
        - ...

您可以通过创建 umanit_seo.yaml 配置文件来进一步配置您的包。以下是包提供的默认配置

# Default configuration for extension with alias: "umanit_seo"
umanit_seo:

    # Historize URLs of entities which implements HistorizableUrlModelInterface
    url_historization:
        enabled: true

        # Redirect code used by UrlRedirectorSubscriber
        redirect_code: 301

        # Cache service used to store entities dependencies. **MUST** implements \Symfony\Contracts\Cache\CacheInterface
        cache_service: cache.app

    # Defines the default templates used to render breadcrumbs
    templates:
        breadcrumb_json_ld: '@UmanitSeo/breadcrumb/breadcrumb.json-ld.html.twig'
        breadcrumb_microdata: '@UmanitSeo/breadcrumb/breadcrumb.microdata.html.twig'
        breadcrumb_rdfa: '@UmanitSeo/breadcrumb/breadcrumb.rdfa.html.twig'
    metadata:
        form_type:

            # Automaticaly add a SeoMetadataType on FormType which handled an entity which implements HasSeoMetadataInterface
            add_seo_metadata_type: true

            # FQCN of the FormType used to renders SEO Metadata fields
            class_fqcn: Umanit\SeoBundle\Form\Type\SeoMetadataType

            # Injects Google Code Prettify when rendering breadcrumb and schema.org in FormType.
            inject_code_prettify: true
        default_title: 'Umanit Seo - Customize this default title to your needs.'
        title_prefix: ''
        title_suffix: ''
        default_description: 'Umanit Seo - Customize this default description to your needs.'

用法

  1. 基本用法
  2. SEO 元数据
  3. Schema.org
  4. 面包屑导航
  5. 启用 301 重定向
  6. Twig 函数参考
  7. 技巧

基本用法

为了正常工作,SeoBundle 必须能够为给定实体生成 URL。为此,umanit_seo.routable 服务使用处理器来处理实体。

处理器是一个实现 Umanit\SeoBundle\Handler\Routable\RoutableHandlerInterface 的服务。一个 supports 方法表示服务是否可以处理给定的实体,一个 process 方法通过返回一个 Umanit\SeoBundle\Model\Route 对象来完成工作。

Umanit\SeoBundle\Model\Route 对象有一个 name 属性,这是访问实体的路由名称,还有一个 parameters 属性,用于构建路由。

您必须在您的实体上实现 Umanit\SeoBundle\Model\RoutableModelInterface 接口,并创建一个处理器来处理它。

<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Umanit\SeoBundle\Model\RoutableModelInterface;

 #[ORM\Entity]
class Page implements RoutableModelInterface
{
    // ...
}
<?php

declare(strict_types=1);

namespace App\Seo\Routable;

use App\Entity\Page;
use Umanit\SeoBundle\Handler\Routable\RoutableHandlerInterface;
use Umanit\SeoBundle\Model\RoutableModelInterface;
use Umanit\SeoBundle\Model\Route;

class PageHandler implements RoutableHandlerInterface
{
    public function supports(RoutableModelInterface $entity): bool
    {
        return $entity instanceof Page;
    }

    public function process(RoutableModelInterface $entity): Route
    {
        return new Route('app_page_show', ['slug' => $entity->getSlug()]);
    }
}

SeoBundle 现在将能够从实体生成 URL。如果您更改了页面的 slug,旧 URL 将重定向到新 URL。

如果您想自己生成 URL,可以像以下示例那样操作

{{ path('app_page_show', { 'slug': my_page.slug }) }}"

现在您可以这样做

{{ path(my_page) }}

注意: 您可以使用 canonical() 函数而不传递任何实体,SeoBundle 将自动解析与当前访问路由关联的实体并从中生成 URL。

通常,您希望直接在主布局中使用 canonical() 函数。

SEO 元数据

在您的模板中使用 seo_metadata(your_entity) twig 函数。

SeoBundle 将自动找到实体中最相关的字段来推断标题和描述。

同样,seo_metadata() 可以不传递任何实体使用。

管理元数据

为了管理 SEO 元数据,您需要再次调整您的实体。

使您的实体实现 HasSeoMetadataInterface 并使用 SeoMetadataTrait

<?php

declare(strict_types=1);

namespace App\Entity;

use Umanit\SeoBundle\Doctrine\Model\SeoMetadataTrait;
use Umanit\SeoBundle\Model\HasSeoMetadataInterface;
use Umanit\SeoBundle\Model\RoutableModelInterface;

class Page implements RoutableModelInterface, HasSeoMetadataInterface
{
    use SeoMetadataTrait;

    // ...
}

如果配置 umanit_seo.metadata.form_type.add_seo_metadata_type 未禁用,则处理您的实体的所有表单将自动具有一个新的 SeoMetadataType 表单类型。

这将添加一个包含两个字段(titledescription)的子表单。

注意: 可以使用 umanit_seo.metadata.form_type.class_fqcn 定制表单类型类。

Schema.org 实现

为了生成有效的 schema.org json 微数据,SeoBundle 必须能够处理给定的实体。为此,umanit_seo.schemable 服务使用处理器来处理实体。

处理器是一个实现 Umanit\SeoBundle\Handler\Schemable\SchemableHandlerInterface 的服务。一个 supports 方法表示服务是否可以处理给定的实体,一个 process 方法通过返回一个 Spatie\SchemaOrg\BaseType 对象来完成工作。

由库 spatie/schema-org 提供的 Spatie\SchemaOrg\BaseType 对象。

您必须在您的实体上实现接口 Umanit\SeoBundle\Model\SchemableModelInterface 并创建一个处理程序来处理它。

<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Umanit\SeoBundle\Model\SchemableModelInterface;

 #[ORM\Entity]
class Page implements SchemableModelInterface
{
    // ...
}
<?php

declare(strict_types=1);

namespace App\Seo\Schemable;

use App\Entity\Page;
use Spatie\SchemaOrg\BaseType;
use Spatie\SchemaOrg\Schema;
use Umanit\SeoBundle\Handler\Schemable\SchemableHandlerInterface;
use Umanit\SeoBundle\Model\SchemableModelInterface;

class PageHandler implements SchemableHandlerInterface
{
    public function supports(SchemableModelInterface $entity): bool
    {
        return $entity instanceof Page;
    }

    /**
     * @param Page $entity
    */
    public function process(SchemableModelInterface $entity): BaseType
    {
        return Schema::mensClothingStore()
                     ->name($entity->getName())
                     ->url($entity->getSlug())
                     ->contactPoint(Schema::contactPoint()->areaServed('Worldwide'))
            ;
    }
}

接下来,在您的布局底部添加 twig 函数 seo_schema_org()

该函数将格式化并显示当前实体根据您的定义的 JSON 模式。

<script type="application/ld+json">
    {
        "@context": "https:\/\/schema.org",
        "@type": "MensClothingStore",
        "name": "Test",
        "email": "test@umanit.fr",
        "contactPoint": {
            "@type": "ContactPoint",
            "areaServed": "Worldwide"
        }
    }

</script>

面包屑导航

您可以轻松地以 3 种不同的格式生成面包屑;MicrodataRDFaJSON-LD,如 规范 所述。为此,umanit_seo.breadcrumbable 服务使用处理程序来处理实体。

处理程序是一个实现了 Umanit\SeoBundle\Handler\Breadcrumbable\BreadcrumbableHandlerInterface 的服务。一个 supports 方法表示服务是否可以处理给定的实体,一个 process 方法通过返回一个 Umanit\SeoBundle\Model\Breadcrumb 对象来完成工作。

Umanit\SeoBundle\Model\Breadcrumb 对象有一个 format 属性,它是前面提到的一个,以及一个 items 属性,它是一个包含 Umanit\SeoBundle\Model\BreadcrumbItem 的数组。每个 BreadcrumbItem 都有一个 label 属性和一个可选的 url 属性。

您必须在您的实体上实现接口 Umanit\SeoBundle\Model\BreadcrumbableModelInterface 并创建一个处理程序来处理它。

<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Umanit\SeoBundle\Model\BreadcrumbableModelInterface;

 #[ORM\Entity]
class Page implements BreadcrumbableModelInterface
{
    // ...
}
<?php

declare(strict_types=1);

namespace App\Seo\Breadcrumbable;

use App\Entity\Page;
use Umanit\SeoBundle\Handler\Breadcrumbable\BreadcrumbableHandlerInterface;
use Umanit\SeoBundle\Model\Breadcrumb;
use Umanit\SeoBundle\Model\BreadcrumbableModelInterface;
use Umanit\SeoBundle\Model\BreadcrumbItem;

class PageHandler implements BreadcrumbableHandlerInterface
{
    public function supports(BreadcrumbableModelInterface $entity): bool
    {
        return $entity instanceof Page;
    }

    /**
     * @param Page $entity
     */
    public function process(BreadcrumbableModelInterface $entity): Breadcrumb
    {
        $breadcrumb = new Breadcrumb();

        $breadcrumb->setItems([
            new BreadcrumbItem('Homepage', '/'),
            new BreadcrumbItem(
                $entity->getCategory()->getName(),
                $this->router->generate('app_page_category_show', ['slug' => $entity->getCategory()->getSlug()])
            ),
            new BreadcrumbItem($entity->getName()),
        ]);

        return $breadcrumb;
    }
}

注意:如果处理的实体实现了 RoutableModelInterface,您可以省略 url 属性,让服务 umanit_seo.routable 为您生成它。

现在,您可以像以下示例一样使用 twig 函数 seo_breadcrumb()

{{ seo_breadcrumb() }} {# Will generate the breadcrumb from the current entity using microdata format #}
{{ seo_breadcrumb(entity=my_entity, format='json-ld') }} {# Will generate the breadcrumb from my_entity using json-ld format #}
{{ seo_breadcrumb(format='rdfa') }} {# Will generate the breadcrumb from the current entity using rdfa format #}

启用 301 重定向

为了在实体上启用 URL 历史记录和 301 重定向,请确保配置 umanit_seo.url_historization.enabled 是激活的(默认为 yes),然后实现接口 Umanit\SeoBundle\Model\HistorizableUrlModelInterface 并使用特质 Umanit\SeoBundle\Doctrine\Model\HistorizableUrlTrait

<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Umanit\SeoBundle\Doctrine\Model\HistorizableUrlTrait;
use Umanit\SeoBundle\Model\HistorizableUrlModelInterface;

 #[ORM\Entity]
class Page implements HistorizableUrlModelInterface
{
    use HistorizableUrlTrait;

    // ...
}

Twig 函数参考

{{ path(entity, parameters = []) }}                 # Path to an Seo entity
{{ url(entity, parameters = []) }}                  # Url to an Seo entity
{{ seo_canonical(entity = null, parameters = []) }} # Canonical link of an Seo entity
{{ seo_title(entity = null) }}                      # Title (without markup) of an Seo entity
{{ seo_metadata(entity = null) }}                   # Metadata of an entity (title and description, with markup)
{{ seo_schema_org(entity = null) }}                 # Json schema of an entity (with markup)
{{ seo_breadcrumb(entity = null, format = null) }}  # Breadcrumb from an entity (default format to 'microdata')

技巧

  • HistorizableUrlModelInterface 扩展了 RoutableModelInterface,因此您不需要实现两个接口,
  • 您可以通过覆盖 umanit_seo.url_historization.redirect_code 来使用自定义 HTTP 状态码进行重定向,
  • 您可以通过覆盖 umanit_seo.url_historization.cache_service 来使用自定义缓存服务为 Umanit\SeoBundle\Doctrine\EventSubscriber\UrlHistoryWriter
  • 如果您的服务需要 @router,您可以实现 Umanit\SeoBundle\Service\RouterAwareInterface 并使用特质 Umanit\SeoBundle\Service\RouterAwareTrait(对面包屑处理程序很有用!)。