config.yml 中的 SilverStripe class 个扩展
SilverStripe class extensions in config.yml
我注意到在某些情况下,当您编写扩展现有 class 的 class 时,您需要在 config.yml 文件中声明 class 扩展.
例如,我最近写了这段代码来删除 CMS 后端中的 "help" 按钮。
mysite/code/Tweak.php
class Tweak extends LeftAndMainExtension
{
public function init()
{
parent::init();
/* Remove help link */
CMSMenu::remove_menu_item('Help');
}
}
mysite/code/Config.yml
LeftAndMain:
extensions:
- Tweak
问题 1: 为什么有些 class 扩展需要在 config.yml 中声明?为什么其他 class 扩展(例如扩展 DataObject 或 Page_Controller)不需要这个额外的步骤?
问题 2: 关于上述代码的具体问题,为什么我声明 Tweaks 作为 LeftAndMain[ 的扩展=37=] 在配置文件中,但在 php 文件中我实际上扩展了 LeftAndMainExtension?
Question 1: Why do some class extensions need to be declared in config.yml? And why is this extra step not necessary for other class extensions (eg extending DataObject or Page_Controller)?
PHP 和 SilverStripe 术语之间存在重要区别。
在 SilverStripe 中,Extension 是一个在 SilverStripe 中实现的框架功能,它允许您修改对象的行为而无需访问除 public.它在这方面类似于 Ruby。
在 PHP 中,您使用 extends
关键字定义现有 class.
的子 class
在您的示例中,您使用的是 LeftAndMainExtension
,它是 SilverStripe "Extension" - 这允许您修改 SilverStripe 管理区域中 CMS 菜单的行为,而它不会 从字面上扩展(以 PHP 术语)LeftAndMain
class.
Question 2: Specific question about above code, why am I declaring Tweaks as an extension to LeftAndMain in the config file, but in the php file I'm actually extending LeftAndMainExtension?
如上所述,这就是 SilverStripe 的扩展系统的工作原理。它基本上遵循以下过程:
- 您在继承中的某个点创建了一个 class
extends
(PHP 关键字)Extension
(您使用 LeftAndMainExtension
,它扩展了 Extension
).对于 DataObjects,您使用 DataExtension
代替。
- 您告诉 SilverStripe 将您的扩展应用到对象,在本例中是
LeftAndMain
命名是经过深思熟虑的,因此您可以将对象及其相关扩展组合在一起easily/visually:
Convention is for extension class names to end in Extension. This isn't a requirement but makes it clearer
- SilverStripe developer documentation
请注意,我故意将 Extension 大写以表示它是 SilverStripe 扩展 class,而不是 class (class Foo extends Bar
) 的 PHP 扩展。
框架如何执行这个过程的例子,基本上是这样的:
- 对象已初始化
- 框架分析 YAML 配置(或通过
Object::add_extension()
应用的扩展)以获取扩展
- 框架循环扩展,将
$this->owner
设置为当前对象,以便扩展可以从中访问 public 方法和属性
- 框架returns最终对象
您实际上是在谈论两种基本的 OO 模式。
- 简单子classing
这几乎是许多语言的标准方式,包括 PHP 和 Java 自定义 class 从另一个 class 继承一些逻辑并能够声明自己的ala:
class MyObject extends DataObject {
}
这里没有任何特定于 SilverStripe 的东西,在这种情况下它是原生的 (PHP)。
- 装饰者
当您订阅 class Extension
或其任何一个订阅class时,例如DataExtension
、SiteTreeExtension
或 LeftAndMainExtension
根据您的示例,您是 "decorating" 现有的 class 和当前库或框架的 "Decorator" 模式。
在 SilverStripe 中,这两种方法之间的一个很大区别是,对于 subclassing,您的新 class 将在数据库中创建一个新的 table(您在其中声明一个 $db
里面是静态的)。使用装饰器(在 YML 中声明的 Extension
subclass 或通过 class 本身中的 $extension
静态声明)不会创建新的 table,你我们可以简单地将 "tack-on" 新字段和逻辑添加到现有对象及其 table 中。
后一种方法实用性的一个常见示例是 Member
class。对其进行子class修改/自定义 SilverStripe 的会员和权限系统不会有太大帮助,装饰它 会。
请参阅有关 SilverStripe 的此功能的专用页面:https://docs.silverstripe.org/en/3.3/developer_guides/extending/extensions/
我注意到在某些情况下,当您编写扩展现有 class 的 class 时,您需要在 config.yml 文件中声明 class 扩展.
例如,我最近写了这段代码来删除 CMS 后端中的 "help" 按钮。
mysite/code/Tweak.php
class Tweak extends LeftAndMainExtension
{
public function init()
{
parent::init();
/* Remove help link */
CMSMenu::remove_menu_item('Help');
}
}
mysite/code/Config.yml
LeftAndMain:
extensions:
- Tweak
问题 1: 为什么有些 class 扩展需要在 config.yml 中声明?为什么其他 class 扩展(例如扩展 DataObject 或 Page_Controller)不需要这个额外的步骤?
问题 2: 关于上述代码的具体问题,为什么我声明 Tweaks 作为 LeftAndMain[ 的扩展=37=] 在配置文件中,但在 php 文件中我实际上扩展了 LeftAndMainExtension?
Question 1: Why do some class extensions need to be declared in config.yml? And why is this extra step not necessary for other class extensions (eg extending DataObject or Page_Controller)?
PHP 和 SilverStripe 术语之间存在重要区别。
在 SilverStripe 中,Extension 是一个在 SilverStripe 中实现的框架功能,它允许您修改对象的行为而无需访问除 public.它在这方面类似于 Ruby。
在 PHP 中,您使用 extends
关键字定义现有 class.
在您的示例中,您使用的是 LeftAndMainExtension
,它是 SilverStripe "Extension" - 这允许您修改 SilverStripe 管理区域中 CMS 菜单的行为,而它不会 从字面上扩展(以 PHP 术语)LeftAndMain
class.
Question 2: Specific question about above code, why am I declaring Tweaks as an extension to LeftAndMain in the config file, but in the php file I'm actually extending LeftAndMainExtension?
如上所述,这就是 SilverStripe 的扩展系统的工作原理。它基本上遵循以下过程:
- 您在继承中的某个点创建了一个 class
extends
(PHP 关键字)Extension
(您使用LeftAndMainExtension
,它扩展了Extension
).对于 DataObjects,您使用DataExtension
代替。 - 您告诉 SilverStripe 将您的扩展应用到对象,在本例中是
LeftAndMain
命名是经过深思熟虑的,因此您可以将对象及其相关扩展组合在一起easily/visually:
Convention is for extension class names to end in Extension. This isn't a requirement but makes it clearer
- SilverStripe developer documentation
请注意,我故意将 Extension 大写以表示它是 SilverStripe 扩展 class,而不是 class (class Foo extends Bar
) 的 PHP 扩展。
框架如何执行这个过程的例子,基本上是这样的:
- 对象已初始化
- 框架分析 YAML 配置(或通过
Object::add_extension()
应用的扩展)以获取扩展 - 框架循环扩展,将
$this->owner
设置为当前对象,以便扩展可以从中访问 public 方法和属性 - 框架returns最终对象
您实际上是在谈论两种基本的 OO 模式。
- 简单子classing
这几乎是许多语言的标准方式,包括 PHP 和 Java 自定义 class 从另一个 class 继承一些逻辑并能够声明自己的ala:
class MyObject extends DataObject {
}
这里没有任何特定于 SilverStripe 的东西,在这种情况下它是原生的 (PHP)。
- 装饰者
当您订阅 class Extension
或其任何一个订阅class时,例如DataExtension
、SiteTreeExtension
或 LeftAndMainExtension
根据您的示例,您是 "decorating" 现有的 class 和当前库或框架的 "Decorator" 模式。
在 SilverStripe 中,这两种方法之间的一个很大区别是,对于 subclassing,您的新 class 将在数据库中创建一个新的 table(您在其中声明一个 $db
里面是静态的)。使用装饰器(在 YML 中声明的 Extension
subclass 或通过 class 本身中的 $extension
静态声明)不会创建新的 table,你我们可以简单地将 "tack-on" 新字段和逻辑添加到现有对象及其 table 中。
后一种方法实用性的一个常见示例是 Member
class。对其进行子class修改/自定义 SilverStripe 的会员和权限系统不会有太大帮助,装饰它 会。
请参阅有关 SilverStripe 的此功能的专用页面:https://docs.silverstripe.org/en/3.3/developer_guides/extending/extensions/