WordPress搜索插件的开发--最佳实践

时间:2016-05-05 作者:Christoph

我花了大约两天的时间来寻找问题的答案,最终注册了这个StackExchange.:)

我的问题并不简单,所以我需要从头开始。但让你了解一下这篇文章的内容:与此同时,我的插件正在工作,但我不喜欢代码。我认为有更好的方法来解决这个问题,所以我正在寻找wordpress忍者,他们可以帮助我提供好的提示和最佳实践。我真的很想深入wordpress,但这有点难。提前感谢您!

我的插件应该做什么这个插件的用户应该能够使用一个短代码来显示特定帖子类型的搜索表单。只有包含此短代码的页面才需要该插件。

帖子类型是通过插件设置页面创建的。这种类型的每篇文章都有一个标题、内容和来自acf插件的几个自定义字段。每种帖子类型都有一个短代码。搜索表单有一个字段,用于搜索指定帖子类型的所有帖子字段。另外两个可用于通过两个关键字限制结果(例如位置,它是一个acf字段)。

结果通过ajax加载,并显示在搜索表单下方。

我已经做了些什么,我尽量让这个问题不要太大。所以我并没有具体说明每一个方面。以下各项应能正常工作:

在插件的php文件中创建on-post类型。目前,一种静态立柱类型是enaugh


Search Custom fields

这相当困难,但我找到了一个可以工作的代码片段,我理解它在做什么。这里的问题是,我只想用我的特定搜索表单搜索acf字段。我不想触碰现有网站的搜索。

首先,在修改搜索查询之前,我尝试检查用户所在的站点,并将if语句与is\\u page()一起使用。但当我使用ajax时,这似乎对我不起作用。。。

我的解决方法是在每个ajax搜索查询的开头设置一个全局变量。现在,在修改搜索查询之前,检查是否设置了此变量。在ajax函数的末尾,我将此变量设置回false。是的,我认为有更好的方法来解决这个问题,但我不知道如何。。。

修改我的搜索查询的功能如下:

/**
 * Extend WordPress search to include custom fields
 *
 * http://adambalee.com
 */

/**
 * Join posts and postmeta tables
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_join
 */
function cf_search_join( $join ) {
    global $wpdb;
    //$cwlistpage=(is_page(\'list\'));

    global $testcheck;
    $cwlistpage=$testcheck;

    if ( $cwlistpage ) {    
        $join .=\' LEFT JOIN \'.$wpdb->postmeta. \' ON \'. $wpdb->posts . \'.ID = \' . $wpdb->postmeta . \'.post_id \';
    }

    return $join;
}
add_filter(\'posts_join\', \'cf_search_join\' );

/**
 * Modify the search query with posts_where
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_where
 */
function cf_search_where( $where ) {
    global $pagenow, $wpdb;
    //$cwlistpage=(is_page(\'list\'));

    global $testcheck;
    $cwlistpage=$testcheck;

    if ( $cwlistpage ) {
        $where = preg_replace(
            "/\\(\\s*".$wpdb->posts.".post_title\\s+LIKE\\s*(\\\'[^\\\']+\\\')\\s*\\)/",
            "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
    }

    return $where;
}
add_filter( \'posts_where\', \'cf_search_where\' );

/**
 * Prevent duplicates
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_distinct
 */
function cf_search_distinct( $where ) {
    global $wpdb;
    //$cwlistpage=(is_page(\'list\'));

    global $testcheck;
    $cwlistpage=$testcheck;

    if ( $cwlistpage ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( \'posts_distinct\', \'cf_search_distinct\' );
<人力资源>

Limit the results by custom fields

表单的所有字段都是可选的。空表单将返回此帖子类型的所有帖子。第一个字段应该在帖子的每个字段中搜索关键字。第二个和第三个字段应将结果限制为包含此关键字的结果。我用if语句解决了这个问题,我知道一定有更好的解决方案。

/**
* Search with AJAX
*/
function cwlist_click_search() {
global $testcheck;
$testcheck = true;

$searchterm = $_POST[\'query\'];
$searchlocation = $_POST[\'location\'];
$searchdegree = $_POST[\'degree\'];

// WP_Query arguments
$args = array (
    \'post_type\' => \'offers\',
    \'post_status\' => \'publish\',
    \'s\' => $searchterm
);

$query = new WP_Query( $args );

ob_start();

// The Loop
if ( $query->have_posts() ) : ?>
  <br><br><p>
   <?php while ( $query->have_posts() ) : $query->the_post();
        if( ($searchlocation == NULL) || in_array(trim(strtolower($searchlocation)), array_map(\'strtolower\', get_field(\'offer_location\')))):
            if( ($searchdegree == NULL) || (trim(strtolower($searchdegree)) === strtolower(get_field(\'offer_degree\')))):?>

     Titel: <?php the_title(); ?> <br>
     Abschluss: <?php the_field(\'offer_degree\'); ?> <br>
     Ort: <?php the_field(\'offer_location\'); ?> <br>
     Anbieter: <?php the_field(\'offer_provider\'); ?> <br>
     <?php if(get_field(\'offer_subtitle\')): ?>
     - <?php the_field(\'offer_subtitle\'); ?> <br>
     <?php endif; ?>
     <br>

    <?php endif; endif; endwhile; ?>
    </p>
<?php else: ?>
    <!-- no posts found -->
    Keine Angebote gefunden
<?php endif;

// Restore original Post Data
wp_reset_postdata();

$content = ob_get_clean();

echo $content;
die();

$testcheck = false;
}
add_action( \'wp_ajax_nopriv_cwlist_click_search\', \'cwlist_click_search\' );
add_action( \'wp_ajax_cwlist_click_search\', \'cwlist_click_search\' );
<小时>

WP Debug

当我激活插件时,首页上会出现许多类似以下的行:

注意:正在尝试获取C:\\Users\\CWalt\\Documents\\gitlab\\steuerazubi\\wordpress\\wp includes\\query中非对象的属性。php第4520行注意:正在尝试获取C:\\Users\\CWalt\\Documents\\gitlab\\steuerazubi\\wordpress\\wp includes\\query中非对象的属性。php第4522行注意:正在尝试获取C:\\Users\\CWalt\\Documents\\gitlab\\steuerazubi\\wordpress\\wp includes\\query中非对象的属性。php在线4524。。。

我激活了调试来创建一个好的插件。我可能做错了什么?

<小时>

More Post Types

你知道一种让用户通过wordpress后端指定更多帖子类型的好方法吗?用户应该能够通过短代码为不同的帖子类型创建不同的搜索页面。

非常感谢您的阅读。我感谢每一个小小的暗示。

1 个回复
最合适的回答,由SO网友:Nebri 整理而成

我已经通读了你的文章的全部内容,我当然不认为它有什么特别的问题,但在我看来,你对它的布局更感到沮丧。

我个人有很大的面向对象编程背景,它允许我建立一个结构,并使我的代码更加可重用。我给你的建议是,为你的下一个插件尝试一种面向对象的方法,或者重新构造你在原始问题中提到的这个插件。

Wordpress插件锅炉板是我衷心推荐的。我通常先去wwpb.me 要为我自己生成一个功能强大的插件框架,只需填写表单,下载并解压缩到wordpress安装的插件目录中。

一旦你有了跑步骨架,我建议你阅读一下本教程,这是一本关于如何构建你刚刚下载的行走骨架的很好的入门读物:

Speed up Development Using the WordPress Plugin Boilerplate pt1

The WordPress Plugin Boilerplate Part 2: Developing a Plugin

The WordPress Plugin Boilerplate Part 3: The Last Steps

在快速阅读之后,我通常会创建一个数据类来存储所有自定义数据库查询,例如:

<?php 

class example_Events_Data {
  private $wpdb;

  public function __construct() {
    global $wpdb;
    $this->wpdb = $wpdb;
  }

  public function get_events($start_date = null, $end_date = null) {
    $query = "SELECT wp_example_event.id, wp_example_event.name, wp_example_event.description, wp_example_event.date, wp_example_event.end_date, wp_example_event_type.id as event_type_id, wp_example_event_type.type as event_type
              FROM wp_example_event
              JOIN wp_example_event_type on wp_example_event.type_id = wp_example_event_type.id
              ORDER BY wp_example_event.name ASC";
    $events = $this->wpdb->get_results($query, ARRAY_A);
    return $events;
  }
然后,要在面向管理/公共的控制器中使用此功能,只需执行以下操作:

    <?php

class Example_Events_Admin {

/**
 * The ID of this plugin.
 *
 * @since    1.0.0
 * @access   private
 * @var      string    $plugin_name    The ID of this plugin.
 */
private $plugin_name;

/**
 * The version of this plugin.
 *
 * @since    1.0.0
 * @access   private
 * @var      string    $version    The current version of this plugin.
 */
private $version;

private $data;
private $utils;

/**
 * Initialize the class and set its properties.
 *
 * @since    1.0.0
 * @param      string    $plugin_name       The name of this plugin.
 * @param      string    $version    The version of this plugin.
 */
public function __construct( $plugin_name, $version ) {

    $this->plugin_name = $plugin_name;
    $this->version = $version;
    $this->data = new example_Events_Data();

}
我还喜欢自己创建一个实用程序类,该类包含整个插件中非常常见的函数,例如表单验证规则,它们的实现和使用方式完全相同。

您只需使用require\\u将它们包含在主插件文件中一次,并在需要的地方进行实例化。

使用数据类可以将所有数据调用集中在一个地方,并在整个插件开发过程中使用它们。

使用这些实践大大缩短了我的开发时间,并使插件更易于维护。

我希望你觉得这个答案有用!

相关推荐

尝试在WordPress中实现AJAX注释,遇到WP错误

我试图在WordPress中为我的评论实现Ajax,使用this tutorial. 但我在将教程中的代码集成到自己的预构建主题时遇到了问题。问题是,我要么得到一个WP错误“检测到重复注释;看来你已经说过了!”或标准500错误。以下是我得到的:下面是我对ajax的评论。js文件如下所示: * Let\'s begin with validation functions */ jQuery.extend(jQuery.fn, { /* * check i