perfectneeds/seo-multi-lang-bundle

多语言网站Seo Bundle

2.0.20 2023-07-27 09:05 UTC

README

先决条件

  1. Symfony 3.4
  2. PNLocaleBundle
  3. PNServiceBundle

翻译

如果您想使用此Bundle中提供的默认文本,请确保您已在配置中启用了翻译器。

    # app/config/config.yml

parameters:
    # default locale 
    locale: en 
    # all locales separated by |
    app.locales: en|ar| 
    
framework:
    translator: ~
    default_locale: '%locale%'

安装

安装是一个快速(我保证!)的7步过程

  1. 使用composer下载PNSeoBundle
  2. 在AppKernel中启用Bundle
  3. 创建您的Seo类
  4. 创建您的SeoRepository类
  5. 配置PNSeoBundle
  6. 导入PNSeoBundle路由
  7. 更新您的数据库模式

步骤1:使用composer下载PNSeoBundle

使用composer要求此Bundle

$ composer require perfectneeds/seo-multi-lang-bundle "~1.0"

步骤2:在AppKernel中启用Bundle

使用composer要求此Bundle

<?php
// app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        // ...
        new VM5\EntityTranslationsBundle\VM5EntityTranslationsBundle(),
        new PN\SeoBundle\PNSeoBundle(),
        new \PN\LocaleBundle\PNLocaleBundle(),
        new \PN\ServiceBundle\PNServiceBundle(),
        // ...
    );
}

步骤3:创建您的Seo类

此Bundle的目标是将一些Seo类持久化到数据库。那么,您的第一个任务就是为您的应用程序创建一个Seo类。这个类可以看起来和表现得像您想要的样子:添加任何您认为有用的属性或方法。这是您的 Seo类。

此Bundle提供了基类,这些基类已经映射到大多数字段,以便更轻松地创建您的实体。以下是您如何使用它的示例

  1. 扩展基Seo类(如果您使用的是任何Doctrine变体,则来自Entity文件夹)
  2. 映射id字段。它必须是受保护的,因为它是从父类继承的。

注意!

当您从Bundle提供的映射超类扩展时,不要重新定义其他字段的映射,因为它们是由Bundle提供的。

在以下部分中,您将看到根据您如何存储您的Seos(Doctrine ORM)的示例,您的Seo类应该如何看起来。

注意

此文档使用名为SeoBundle的Bundle。然而,当然您可以将您的SEO类放置在您想要的任何Bundle中。

注意!

如果您在Seo类中重写了__construct()方法,请务必调用parent::__construct(),因为基础Seo类依赖于它来初始化一些字段。

Doctrine ORM Seo类

如果您通过Doctrine ORM持久化SEO,则您的Seo类应位于您的Bundle的Entity命名空间中,并如下开始

您可以在此类中添加所有其他实体之间的关系

<?php
// src/PN/Bundle/SeoBundle/Entity/Seo.php

namespace PN\Bundle\SeoBundle\Entity;

use Doctrine\ORM\Mapping\UniqueConstraint;
use Doctrine\ORM\Mapping as ORM;

// DON'T forget the following use statement!!!
use PN\SeoBundle\Entity\Seo as BaseSeo;
use PN\SeoBundle\Model\SeoTrait;

/**
 * Seo
 * @ORM\HasLifecycleCallbacks
 * @ORM\Table("seo", uniqueConstraints={@UniqueConstraint(name="slug_unique", columns={"slug", "seo_base_route_id", "deleted"})})
 * @ORM\Entity(repositoryClass="PN\Bundle\SeoBundle\Repository\SeoRepository")
 */
class Seo extends BaseSeo {

    use SeoTrait;
    /**
     * @ORM\OneToMany(targetEntity="PN\Bundle\SeoBundle\Entity\Translation\SeoTranslation", mappedBy="translatable", cascade={"ALL"}, orphanRemoval=true)
     */
    protected $translations;
    
    public function __construct()
    {
        parent::__construct();
        // your own logic
    }
<?php
// src/PN/Bundle/SeoBundle/Entity/Translation/SeoTranslation.php

namespace PN\Bundle\SeoBundle\Entity\Translation;

use Doctrine\ORM\Mapping as ORM;

// DON'T forget the following use statement!!!
use PN\SeoBundle\Entity\Translation\SeoTranslation as BaseSeoTranslation;

/**
 * @ORM\Entity
 * @ORM\Table(name="seo_translations")
 */
class SeoTranslation extends BaseSeoTranslation {

    /**
     * @var
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="PN\Bundle\SeoBundle\Entity\Seo", inversedBy="translations")
     * @ORM\JoinColumn(name="translatable_id", referencedColumnName="id")
     */
    protected $translatable;

}

步骤4:创建您的SeoRepository类

您可以使用此Repository添加任何自定义方法

<?php
// src/PN/Bundle/SeoBundle/Repository/SeoRepository.php


namespace PN\Bundle\SeoBundle\Repository;

use PN\SeoBundle\Repository\SeoRepository as BaseSeoRepository;

class SeoRepository extends BaseSeoRepository {

}

步骤5:配置PNSeoBundle

根据您使用的存储数据类型,将以下配置添加到您的config.yml文件中。

# app/config/config.yml 

doctrine:
   orm:
        # search for the "ResolveTargetEntityListener" class for an article about this
        resolve_target_entities: 
            VM5\EntityTranslationsBundle\Model\Language: PN\LocaleBundle\Entity\Language
            PN\SeoBundle\Entity\Seo: PN\Bundle\SeoBundle\Entity\Seo

pn_seo:
    # The fully qualified class name (FQCN) of the Seo class which you created in Step 3.
    seo_class: PN\Bundle\SeoBundle\Entity\Seo
    # The fully qualified class name (FQCN) of the SeoTranslation class which you created in Step 3.
    seo_translation_class: PN\Bundle\SeoBundle\Entity\Translation\SeoTranslation

步骤6:导入PNSeoBundle路由文件

# app/config/routing.yml 

pn_seo:
    resource: "@PNSeoBundle/Resources/config/routing.yml"

pn_locale:
    resource: "@PNLocaleBundle/Resources/config/routing.yml"

步骤7:更新您的数据库模式

现在Bundle已配置,最后您需要更新数据库模式,因为您已添加了一个新实体,即您在步骤3中创建的Seo类。

$ php bin/console doctrine:schema:update --force

如何使用PNSeoBundle

  1. 使用Doctrine ORM在Entity中使用Seo
  2. 在Form Type中使用Seo
  3. 在控制器中使用Seo
  4. 在详情页面(如show.html.twig)中使用Seo

1. 使用Doctrine ORM在Entity中使用Seo

首先,您需要在 src/PN/Bundle/SeoBundle/Entity/Seo.php 文件中使用 Seo 类添加需要使用 SEO 的实体之间的关联 例如:博客作者、产品等... 示例实体
Seo.php

<?php
// src/PN/Bundle/SeoBundle/Entity/Seo.php

namespace PN\Bundle\SeoBundle\Entity;

use Doctrine\ORM\Mapping\UniqueConstraint;
use Doctrine\ORM\Mapping as ORM;
use PN\SeoBundle\Entity\Seo as BaseSeo;
use PN\SeoBundle\Model\SeoTrait;

/**
 * Seo
 * @ORM\HasLifecycleCallbacks
 * @ORM\Table("seo", uniqueConstraints={@UniqueConstraint(name="slug_unique", columns={"slug", "seo_base_route_id"})})
 * @ORM\Entity(repositoryClass="PN\Bundle\SeoBundle\Repository\SeoRepository")
 */
class Seo extends BaseSeo {

    use SeoTrait;
    
    /**
     * @ORM\OneToOne(targetEntity="\PN\Bundle\CMSBundle\Entity\DynamicPage", mappedBy="seo")
     */
    protected $dynamicPage;
    
    // Add here your own relations
    
    public function __construct()
    {
        parent::__construct();
        // your own logic
    }

DynamicPage.php

<?php

namespace PN\Bundle\CMSBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use PN\ServiceBundle\Model\DateTimeTrait;
use VM5\EntityTranslationsBundle\Model\Translatable;
use PN\LocaleBundle\Model\LocaleTrait;

/**
 * DynamicPage
 *
 * @ORM\HasLifecycleCallbacks
 * @ORM\Table(name="dynamic_page")
 * @ORM\Entity(repositoryClass="PN\Bundle\CMSBundle\Repository\DynamicPageRepository")
 */
class DynamicPage implements Translatable {

    use DateTimeTrait,
        LocaleTrait;
    ....

    /**
     * @ORM\OneToOne(targetEntity="\PN\Bundle\SeoBundle\Entity\Seo", inversedBy="dynamicPage", cascade={"persist", "remove" })
     */
    protected $seo;
    
    ....
}

2. 在表单类型中使用 Seo

您需要将 Seo 类型添加到任何表单类型中,以使用这个神奇的工具

DynamicPageType.php

<?php

namespace PN\Bundle\CMSBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

// DON'T forget the following use statement!!!
use PN\SeoBundle\Form\SeoType;


class DynamicPageType extends AbstractType {

    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
                ->add('seo', SeoType::class)
                ......
                ;
    }
    .....
}

3. 在控制器中使用 Seo

您需要调用此方法以根据 slug 获取实体,此方法用于在您调用任何动作时通过 slug 获取实体

DynamicPageController.php

    /**
     * @Route("/{slug}", name="fe_dynamic_page_show", methods={"GET", "POST"})
     */
    public function showAction(Request $request, $slug) {
        $em = $this->getDoctrine()->getManager();
        $entity = $this->get("fe_seo")->getSlug($request, $slug, new DynamicPage());
        if ($entity instanceof RedirectResponse) {
            return $entity;
        }
        if (!$entity) {
            throw $this->createNotFoundException();
        }
        
        // your own logic
    }

选项

request

类型: Symfony\Component\HttpFoundation\Request 对象实例

slug

类型: string 从路由参数传递的 slug 值

entityClass

类型: Object 任何实体的实例

slueRouteParamName (可选,默认为 'slug')

类型: string 路由注解中 slug 的名称

4. 在详情页(如 show.html.twig)中使用 Seo

此代码片段用于在 base.html.twig 中添加元标签和 HTML 标题。因此,您需要在 base.html.twig 中添加 2 个空块(metaTagtitle

{% set seo = dynamicPage.seo %}
{% use '@PNSeo/FrontEnd/seo.html.twig' %}

报告问题或功能请求

问题和功能请求在 Github issue tracker 中跟踪。

在报告错误时,最好在基本项目中重现它,该项目使用 Symfony Standard Edition 构建,以便包的开发者可以通过简单地克隆它并遵循一些步骤来重现问题。