我目前正在为Wordpress编写我的第一个OOP插件。
为了帮助我找到一点结构,a boiler plate 这为我奠定了基础。
在里面Main.php
有一种方法可以为管理员加载JS和CSS资产:
/**
* Register all of the hooks related to the admin area functionality
* of the plugin.
*
* @since 0.1.0
* @access private
*/
private function define_admin_hooks() {
$plugin_admin = new Admin\\Controller( $this->get_plugin_name(), $this->get_version(), $this->get_plugin_path() );
$this->loader->add_action( \'admin_enqueue_scripts\', $plugin_admin, \'enqueue_styles\' );
$this->loader->add_action( \'admin_enqueue_scripts\', $plugin_admin, \'enqueue_scripts\' );
}
到目前为止,一切顺利。但是,随着我的插件变得越来越复杂,感觉这种方法将变得很难使用很多挂钩。
下面是一个添加了CPT设置和设置页面的示例
/**
* Register all of the hooks related to the admin area functionality
* of the plugin.
*
* @since 0.1.0
* @access private
*/
private function define_admin_hooks() {
$plugin_admin = new Admin\\Controller( $this->get_plugin_name(), $this->get_version(), $this->get_plugin_path() );
$this->loader->add_action( \'admin_enqueue_scripts\', $plugin_admin, \'enqueue_styles\' );
$this->loader->add_action( \'admin_enqueue_scripts\', $plugin_admin, \'enqueue_scripts\' );
$interactWithVimeo = new Admin\\InteractWithVimeo();
$this->loader->add_action ( \'admin_init\', $interactWithVimeo, \'setCredentials\');
$cpt = new Admin\\CustomPostType();
// Create the custom post type
$this->loader->add_action ( \'init\', $cpt, \'create_post_type\' );
// Remove post row actions
$this->loader->add_filter ( \'post_row_actions\', $cpt, \'remove_row_actions\', 10, 2 );
$settingsPage = new Admin\\SettingsPage();
// Add the settings page to CPT menu
$this->loader->add_action ( \'admin_menu\', $settingsPage, \'add_settings_page\' );
}
此时,我想知道是否最好简单地设置不同的类来加载它们自己的钩子,以避免
Main.php
例如
/**
* Register all of the hooks related to the admin area functionality
* of the plugin.
*
* @since 0.1.0
* @access private
*/
private function define_admin_hooks() {
$myExensiveClassWithAlotOfMethods = new Admin\\MyExensiveClassWithAlotOfMethods();
$this->loader->add_action ( \'admin_init\', $myExensiveClassWithAlotOfMethods, \'init\' );
}
然后类中的init方法包含类所需的所有挂钩。
这是个坏主意吗?当然,似乎有不同的方法。我只是好奇哪种方法似乎与锅炉板一致。
SO网友:kero
Sally CJ 提出了一个很好的观点their comment 最好让每个类初始化自己的操作和过滤器。
我已经用同一个锅炉板工作了一段时间了created my own version of this boiler plate on GitHub.
在那个版本中,我有一个Back\\Hooks
和aGeneral\\Hooks
, 单身和通过Loader
. 这就是General\\Hooks
在一个项目中查找
<?php
namespace ACME\\General;
class Hooks
{
protected static $instance;
protected $loader;
public static function getInstance($loader)
{
if (self::$instance === null) {
self::$instance = new self($loader);
}
return self::$instance;
}
protected function __construct($loader)
{
$this->loader = $loader;
}
public function run()
{
$this->addActions();
$this->addFilters();
}
protected function addActions()
{
AdvancedCustomFields\\Options::add($this->loader);
$this->loader->addAction(\'init\', Shortcode\\News::class, \'init\');
$this->loader->addAction(\'init\', Shortcode\\Courses::class, \'init\');
$this->loader->addAction(\'wp_footer\', WooCommerce\\Foo::class, \'print_modal\');
// and many more
}
protected function addFilters()
{
$this->loader->addFilter(\'the_content\', Bar\\Baz::class, \'filter_the_content\', 999);
// and many more
}
}
现在的情况是
AdvancedCustomFields\\Options
我已经传递了加载程序并在该类中进行了初始化,对于所有其他情况,这样做可能会更干净。
General\\Shortcode\\News
看起来像这样
<?php
namespace ACME\\General\\Shortcode;
class News
{
public static function init()
{
add_shortcode(\'acme_news\', [__CLASS__, \'render\']);
}
public static function render($raw_atts = [], $content = null, $tag = \'\')
{
$raw_atts = array_change_key_case((array)$raw_atts, CASE_LOWER);
$atts = shortcode_atts([
\'size\' => \'large\',
\'amount\' => \'4\',
\'offset\' => \'0\',
\'exclude\' => \'\',
], $raw_atts, $tag);
/* filter $atts */
$atts[\'amount\'] = intval($atts[\'amount\']);
$atts[\'offset\'] = intval($atts[\'offset\']);
/* get result */
$result = \'\';
// actual code, doing WP_Query, etc.
// never directly outputted but only saved in $result
return $result;
}