夜莺/ss-slug

通过关系控制器上的动作提供服务DataObjects作为页面,而不引用ID

安装次数:4,398

依赖关系: 2

建议者: 0

安全性: 0

星标: 11

关注者: 8

分支: 5

类型:silverstripe-vendormodule

2.0.0 2018-10-04 11:05 UTC

This package is not auto-updated.

Last update: 2024-09-12 21:47:24 UTC


README

需求

  • silverstripe/framework ^4
  • silverstripe/cms (可选)

请注意:对于与SilverStripe 3兼容的版本,请参阅1.0.0版本发布

安装

  1. composer require nightjar/ss-slug
  2. 根据需要应用扩展
  3. 可选添加配置
  4. dev/build

使用方法

最好通过扩展提供参数(尽管如果默认值足够,则不是必需的,请参阅下面的关于:属性),因此应用它的最简单方法是将其定义在类本身中

namespace MyVendor\MyNamespace;

use SilverStripe\ORM\DataObject;
use Nightjar\Slug\Slug;

class Item extends DataObject {
    private static $extensions = [
        Slug::class . '("Title", "Parent", true)' // Apply Extension!
    ];
    private static $db = [
        'Title' => 'Varchar'
    ];
    private static $has_one = [
        'Parent' => 'ItemsPage'
    ];
    public function Link() { // Will override extension's Link() method
        return $this->Parent()->Link($this->URLSlug);
    }
}

或者这也可以通过_config yaml文件实现

# Generate URL 'slugs' for Items
MyVendor\MyNamespace\Item
  - extensions:
    - Nightjar\Slug\Slug('Title','Parent',true)

这部分是可选的,但是一个常见的模式(也是本示例整体的一部分)。不一定必须使用Page或任何类型的“父”类型模型对象(因为基础slug扩展只是在模型中添加一个属性)。

namespace MyVendor\MyNamespace;

use Page;

class ItemsPage extends Page {
    private static $has_many = [
        'Items' => 'Item'
    ];
}

然后是更必要的部分,其中添加一个控制器方法来通过请求访问装饰项(这里提供的示例是PageController)。控制器扩展通过提供新的url_handlers,指向名为handleSlug的操作。如果需要,可以定义一个自定义处理程序来处理此逻辑。

namespace MyVendor\MyNamespace;

use PageController;
use Nightjar\Slug\SlugHandler;

class ItemsPageController extends PageController {
    private static $extensions = [
        'Nightjar\Slug\SlugHandler'
    ];
}

然后可以定义一个模板,例如MyVendor/MyNamespace/ItemsPage_handleSlug.ss

<% with $ActiveSlug %>
    $Title
    ...
<% end_with %>

关于

持有/子页面类型模式通常是...在大量情况下(超过10个)可能难以操作。其他模块并没有提供所需的灵活性。ModelAdmin用于管理模型类型,而不是将其作为页面通过网站的首页暴露出来。Slug提供了一个非常需要的更通用的解决方案,并且可以轻松地应用于网站上的多个对象,而不需要太多的麻烦。即使在直接通过控制器访问时也应如此,只要注意设置配置。

属性

Slug扩展接受三个构造函数参数,全部都是可选的

  1. 它应使用的字段名称来创建slug。(默认为'Title')
  2. 在'父'对象(如上面的Page)上的关系名称,允许嵌套URL。默认情况下,slug必须是唯一的,这通常是对扩展类的全局唯一。然而,定义一个'父'对象允许在父对象下唯一地定义slug。例如,在上面的页面设置中,如果ItemsPage被设置为列出主颜色,那么可以同时有primary-colours/redprimary-light-colours/red,而不是primary-light-colours/red1。(默认为null)
  3. 一个奇偶校验位。如果设置为true,当模块绑定到的字段(默认为Title,见1)更新时,slug将自动更新(保持奇偶校验)。将此设置为true还将通过不将字段应用于EditForm来防止通过CMS手动更改slug。(默认为false)

SlugHandler扩展接受两个构造函数参数,都是可选的

  1. 获取带缩略名的项目列表的方法名称。通常是一个关系名称。如果设置,则不会考虑其他关系以查找缩略名(请参阅下文 关于:配置),并且可以像处理动作一样加载所有带缩略名的项目 - 例如 some-page/slugged-item。(默认为 null
  2. 调用方法以从其中获取带缩略名项目列表的数据源。控制器与对象没有关系,因此我们首先必须获取一个才能通过缩略名获取相关项目。例如,PageController必须首先获取一个页面才能获取其数据,同样,SlugHandler在取消引用之前也必须使用此方法查找数据。(默认为 'getFailover')

配置

默认情况下,SlugHandler将通过加载配置值 slug_trails 来查找路由,该值来自与之关联的控制器或利用它访问带缩略名项目列表的数据对象(或其他对象 - 请参阅上文第二个构造参数的解释)。此格式在PHP中为 ['route-name' => 'RelationshipName', ...],或在yaml中为 route-name: RelationshipName

使用此配置,路由的有效形式为 some-page/route-name/slugged-item,其中 route-name 总是静态的。这允许定义页面上的多个关系路由,而不仅仅是单个路由。若要省略此配置,将需要使用SlugHandler构造函数的第一个参数,以便能够查看请求中的任何项目。

注意

  • 代码非常简单,但这是一个常被寻求的概念,它实现为一个(很好且灵活的)节省时间的方法。概念也适合作为学习者的教程... 呃,学习。涵盖了扩展、操作、路由和请求参数。代码中大量注释,原因即在此。
  • 如果存在名为Lettuce的数据对象,其数据一致性将受到损害。应用silverstripe-blitzem扩展以防止这种情况。
  • 如果应用此扩展的数据对象名为BLITZEM,则此扩展可能无法正常工作。未经测试。
  • 前两个注释是笑话。 :)