如何将主题设置为“插件就绪”?

时间:2012-10-28 作者:Volomike

如何修改主题,以便发布我的事件挂钩,任何人都可以构建插件来轻松地向主题添加新功能?

5 个回复
SO网友:fuxia

在完成了几个如此大的项目后,我甚至不认识所有参与的人,我得出了一个结论:

Keep it simple, write great documentation.

如果代码易于阅读、学习和扩展,那么它就是简单的。

不要重新发明轮子:尽可能使用给定的挂钩,在可预测的方案中添加新的挂钩。

一个非常基本的例子:

if ( ! is_singular() && is_active_sidebar( \'t5-archive-sidebar\' ) )
{
    do_action( \'sidebar_before\' );
    print \'<ul id="sidebar">\';
    dynamic_sidebar( \'t5-archive-sidebar\' );
    print \'</ul>\';
    do_action( \'sidebar_after\' );
}
通过查看id 属性任何人都可以预测挂钩,因为它们的名称总是相同的。你已经知道<div id="header"><div id="content"> 将命名。有一个有趣的Trac ticket 您应该阅读Theme Hook Alliance @奥托在回答中建议。

在一个地方注册钩子的所有回调:开始functions.php. 如果一切都被束缚在一个你不需要的钩子上function_exists(), 因为插件或子主题可以取消注册您的函数并使用自己的函数。

示例:

add_action( \'content_before\',       \'t5_frontpage_widget\' );
add_action( \'footer_before\',        \'t5_loop_navigation\' );
add_action( \'header_before\',        \'t5_skiplink\', 1, 0 );
add_filter( \'the_title\',            \'t5_fill_empty_title\', 20, 1 );
add_action( \'wp_loaded\',            \'t5_post_format_support\' );
add_action( \'wp_loaded\',            \'t5_load_theme_language\' );
add_action( \'wp_loaded\',            \'t5_setup_custom_background\' );
add_action( \'wp_loaded\',            \'t5_setup_custom_header\' );
add_action( \'wp_loaded\',            \'t5_setup_sidebars\' );
add_filter( \'wp_title\',             \'t5_wp_title_filter\', 20, 2 );
尽可能晚地包含其他文件,以便于替换这些文件,并为每个类使用一个文件。

对所有函数和类使用PHPDoc,添加每个调用的钩子。

示例:

/**
 * Handles posts without a title. Uses the first 35 caharacters instead.
 *
 * @wp-hook the_title 20
 * @param  string $title
 * @return string
 */
function t5_fill_empty_title( $title )
{
}
The@wp-hook the_title 20 告诉读者何时调用该函数以及如何删除它。对于复杂代码,请在DocBlock中提供使用示例。

避免编写插件代码困难的代码:

切勿在文件(模板)视图中包含文件、声明函数或创建全局变量。儿童主题作者将不得不重新创建这些主题——浪费时间functions.php 被调用。将所有内容绑定到一个钩子,让插件有机会禁用代码0.require, require_onceincludeinclude_once 在您的主题中。使用locate_template() 相反在某些情况下,插件可能会将自己的目录注册为子主题的附加主题目录。locate_template() 允许这样的插件替换完整的文件anonymous objects.

SO网友:Otto

尽量使用标准化挂钩。看看主题挂钩联盟中的那些:https://github.com/zamoose/themehookalliance

SO网友:Michael Ecklund

您的问题确实没有明确的答案:How to make a theme "plugin-ready"?

尽管如此,在你的主题中有一些东西你应该加以利用。我不能把你应该做的每一件事都列得这么详细。然而,我可以提供一个简短的列表,并快速解释为什么应该使用它们。

WordPress核心功能add_theme_support(); - 添加主题支持允许插件开发人员检查是否存在特定的主题功能,并向每个主题添加额外的功能

  • register_sidebar();register_sidebars(); - 通过动态创建侧栏,插件开发人员可以通过隐藏已有内容、添加更多内容或完全删除侧栏来操纵侧栏输出
  • register_nav_menu();register_nav_menus(); - 允许插件高度操纵您的导航结构,如添加菜单项、添加新菜单项或更改CSS样式等。。。将权限设置完全添加到导航,或专门添加到特定导航菜单项
  • wp_register_sidebar_widget();wp_set_sidebars_widgets(); - 小部件与第二个项目符号中的动态侧栏非常匹配。这同样允许您的主题具有极高的灵活性。允许开发人员添加自定义小部件,并将其插入动态侧栏中,以获得进一步的功能或内容输出
  • get_header(); get_footer(); get_sidebar();get_template_part(); - 使用WordPress内置函数获取主题的各个部分,插件开发人员可以通过向主题插入额外代码、从主题中删除代码或使用钩子更改主题的效果,再次操纵主题输出,我将在下面的列表后面介绍钩子
  • wp_head(); wp_footer(); wp_title();body_class(); - 这些函数对于插件开发人员来说非常好。这允许插件开发人员将新脚本或样式排队,或将现有脚本或样式从主题的页眉和页脚中排队。使用wp_title(); 允许插件开发人员操纵主题的标题标记输出。非常适合SEO插件。body_class(); 真的可以用很多。我强烈建议您在所有主题中对此建立支持
  • 如果您不确定某个特定功能,并且知道它必须存在于某个地方,请尝试访问WordPress Developer Code Reference.

    WordPress挂钩(操作和过滤器)您应该考虑的下一件事是WordPress Hooks, 或政治正确的行动和过滤器。

    • Plugin API/Filter Reference - WordPress中所有过滤器挂钩的参考列表Plugin API/Action Reference - WordPress中所有动作挂钩的参考列表@userabuser\'有关可用WordPress挂钩的更详细列表,请考虑查看Adam R Brown\'sWordPress Hooks Database

      这些“事件”被称为挂钩,它允许插件开发人员添加、修改或删除主题中特定区域的代码。或者在主题中触发另一个事件时触发某个事件。

      这将我们带到下一个你应该考虑的领域,同时创建一个“插件就绪”的WordPress主题。

      创建自己的WordPress挂钩是明智的做法,学习如何在主题中创建自己的WordPress操作和WordPress过滤器。这将允许插件开发人员高度操纵WordPress主题。

      如果您不知道如何创建WordPress操作或WordPress筛选器,请单击此处了解有关creating WordPress actions with do_action(); 并单击此处了解有关creating WordPress filters with apply_filters();.

      只需使用WordPress core提供的更多默认功能(如本答案开头第一个编号列表中列出的功能,或者here for a full function index), 开发人员需要使用的许多挂钩已经由核心定义。

      在WordPress主题内创建自己的WordPress挂钩时,千万不要害羞。让开发人员可以利用许多钩子,而不是做不到他们需要做的事情,这总是更好的。

      只需记住对钩子名称使用唯一的引用即可。(它们必须是唯一的,以便与现有WordPress核心挂钩或其他插件开发人员创建的现有WordPress挂钩不冲突。)

      通过创建自己的挂钩,WordPress插件开发人员可以使用add_action();add_filter(); 并配置WordPress主题的输出或行为,而不实际更改主题的核心代码。

      这很好,当你为你的主题发布更新时,因为他们对你的主题的更改将是持久的,不会被主题更新写得太多或丢失。

      根据@Otto\'sanswer, 您可以尝试使用Theme Hook Alliance.

      <小时>

    SO网友:Adam

    作为你答案的另一种选择,你为什么不做类似的事情呢?

    在主题文件中放置一个钩子,

    Step 1: single.php

    <div class="post">
    
        <?php the_title(); ?>
    
        <?php the_content(); ?>
    
        <!-- your hook -->
        <?php after_post_content(); ?>
    
    </div>
    

    Step 2: functions.php

    在您的functions.php 我们想让WordPress知道这个钩子。。。

    function after_post_content(){
    
        do_action(\'after_post_content\');
    
    }
    

    Step 3: In your plugin

    顾名思义,连接到after_post_content 允许我们在the_content 如图所示single.pgp. 在这种情况下,我们只是重复一些基本的短语,但是你可以用它来注入社交媒体按钮、特殊广告、电子邮件订阅框或任何其他你能想到的创意。。。

    add_action(\'after_post_content\', \'my_callback_function\', 10);
    
    function my_callback_function(){
    
       if ( is_single(\'special-page-slug\') ) {
           echo \'how you doin?\';
       } else {
           echo \'yo!\';
       }
    
    }
    
    总体而言,上述↑ 这只是一个简化的示例,说明了如何为主题创建可挂接的操作/过滤器,但为插件甚至主题开发人员/用户提供了易于访问的方法来注入或过滤内容。这是一个更高效的流程,更易于管理。

    This is just the start of what\'s possible...

    SO网友:Volomike

    1) 将每个主题文件分开,以便顶部有PHP,底部有HTML。然后,在HTML部分,像这样插入变量:

    <?= $view->MY_VAR ?>
    
    或使用PHP Alternative Syntax 循环和if/then/else条件的填充最少。关键字--最小值。请参见,大部分PHP应该位于文件的顶部。

    你可能在挠头为什么$view->MY_VAR. 好吧,原因如下:

    $view = (object) array()
    $view->MY_VAR1 = \'<strong>Test1</strong>\';
    $view->MY_VAR2 = \'<em>Test2</em>\';
    print_r($view);
    
    看看调试有多容易?另外,因为我在变量名上使用了所有的大写字母,所以我可以在页面的HTML部分轻松找到它们。我为什么叫它$view? 因为它比打字短$template, 因为了解这种变量注入方式的人通常都知道一种叫做MVC(计算机科学术语)的东西,其中V代表视图。

    2) 将包含的任何库或类文件移动到PHP文件的顶部,例如:

    require_once(\'mailer.php\');
    require_once(\'gallery.static.class.php\');
    
    3)按照库包括的内容,设置任何常量或静态信息,或从get_option() API。

    4) 在“设置”初始化区域(步骤3)之后,执行以下操作$_GET, $_SERVER, 或$_POST 您读取这些内容并将其粘贴到变量中的设置,或者可能需要对其执行以下操作strip_tags(), stripslashes(), trim(), 基本上你应该做任何输入处理,而不是做任何真正的硬核编程。

    5) 在GET/POST变量处理(步骤4)之后,添加这段代码,注意我使用了“mytheme\\uu0”作为主题名称的前缀,但您可以将“mytheme\\u0”更改为其他名称。

    // expose our WordPress plugin event hook - pre, meaning after GET/POST processing but before actually doing anything else
    $sHook = strtolower(basename(__FILE__));
    $sHook = str_replace(\'.php\',\'\',$sHook);
    $sHook = str_replace(\'-\',\'_\',$sHook);
    $sHook = str_replace(\'.\',\'_\',$sHook);
    $sHook = preg_replace(\'/[^a-z0-9\\_]/\',\'\',$sHook);
    @ do_action(\'mytheme_pre_\' . $sHook,get_defined_vars());
    
    6)在您进行?> 在开始执行文件的HTML部分之前,请添加以下代码片段:

    // expose our plugin post event hook - post, meaning right before showing content
    @ do_action(\'mytheme_post_\' . $sHook,get_defined_vars());
    // turn on output buffering
    @ ob_start();
    
    7)在文件末尾,在所有HTML之后,添加以下代码片段:

    <?php
    try {
      $sContent = ob_get_contents();
      ob_end_clean();
      $sContent = apply_filters(\'mytheme_\' . $sHook,$sContent,get_defined_vars());
      echo $sContent;
    } catch (Exception $e) {
      echo "\\n<!-- ob_* function error -->\\n";
    }
    // no ending ?> is required here
    
    //////////////

    现在已经完成了,您可以编写一个新的插件add_filter()add_action(), 您的回调函数将获得页面的所有已定义变量(如果是add_filter()), 你几乎可以覆盖主题中的任何内容。

    您可以使用echo "<h2>$sHook</h2>\\n"; 在页面上记录所有事件挂钩的内容。

    不要忘记在你用主题创建的管理面板上这样做,而不仅仅是在主题的前端。

    注意,在上面的几行中,您可以通过几个函数(例如用于查找钩子名称的函数)稍微减少这一点。只是不要把do_action(), apply_filters(), 或get_defined_vars() 在一个函数或事物中,它们不会像您期望的那样工作。

    结束