custom-post-types – Desarrollo de un complemento de búsqueda de WordPress – Mejores prácticas

Pregunta:

Buscando alrededor de dos días para encontrar una respuesta a mi pregunta, finalmente me registré para este StackExchange. 🙂

Mi pregunta no es simple, por lo que debo comenzar desde el principio. Pero para darte una idea de lo que trata esta publicación: Mientras tanto, mi complemento está funcionando, pero no me gusta el código. Creo que hay mejores formas de resolver esto y por eso estoy buscando ninjas de wordpress que puedan ayudarme con buenos consejos y mejores prácticas. Realmente trato de adentrarme en las profundidades de wordpress, pero es un poco difícil. ¡Gracias de antemano!


Qué debería hacer mi complemento

El usuario de este complemento debería poder usar un código corto para mostrar un formulario de búsqueda para tipos de publicaciones específicas. El complemento solo es necesario en las páginas que contienen este código corto.

Los tipos de publicaciones se crean a través de la página de configuración del complemento. Cada publicación de este tipo tiene un título, contenido y varios campos personalizados del complemento acf. Hay un código abreviado para cada tipo de publicación. El formulario de búsqueda tiene un campo para buscar todos los campos de publicación del tipo de publicación especificado. Los otros dos se pueden utilizar para limitar los resultados mediante dos palabras clave (por ejemplo, la ubicación, que es un campo acf).

Los resultados se cargan a través de ajax y se muestran debajo del formulario de búsqueda.


Lo que hice ya

Intento que esta pregunta no sea demasiado grande. Así que no especifico todos y cada uno de los aspectos. Lo siguiente debería funcionar bien:

  • Crear en el tipo de publicación en el archivo php del complemento. Por el momento, se ha aprobado un tipo de publicación estática.
  • Cree un código corto que imprima el formulario de búsqueda y un contenedor vacío para los resultados.
  • La solicitud Ajax está funcionando a través de javascript y da los resultados esperados.

Buscar campos personalizados

Esto fue bastante difícil, pero encontré un fragmento de código que funciona y entiendo lo que está haciendo. El problema aquí es que solo quiero buscar campos acf con mi formulario de búsqueda específico. No quiero tocar la búsqueda del sitio existente.

Primero intenté verificar en qué sitio se encuentra el usuario y usar una declaración if con is_page () antes de modificar la consulta de búsqueda. Pero como uso ajax, esto parece no funcionar para mí aquí …

Mi solución es establecer una variable global al comienzo de cada consulta de búsqueda ajax. Ahora verifico si esta variable está configurada antes de modificar la consulta de búsqueda. Al final de mi función ajax, configuro esta variable de nuevo en falso. Sí, creo que hay una forma mejor de solucionar esto, pero no sé cómo …

Las funciones que modifican mi consulta de búsqueda son las siguientes:

/**
 * 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' );

Limita los resultados por campos personalizados

Todos los campos del formulario son opcionales. Un formulario vacío devolverá todas las publicaciones de este tipo de publicación. El primer campo debe buscar la palabra clave en todos los campos de las publicaciones. El segundo y tercer campo deben limitar los resultados al que contiene esta palabra clave. Resolví esto con declaraciones if y sé que debe haber una solución mejor.

/**
* 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' );

Depuración de WP

Cuando activo el complemento, aparecen muchas líneas como las siguientes en la página principal:

Aviso: tratando de obtener la propiedad de un no objeto en C: \ Users \ CWalt \ Documents \ gitlab \ steuerazubi \ wordpress \ wp-includes \ query.php en la línea 4520 Aviso: tratando de obtener una propiedad de un no objeto en C: \ Users \ CWalt \ Documents \ gitlab \ steuerazubi \ wordpress \ wp-includes \ query.php en la línea 4522 Aviso: Intentando obtener la propiedad de un no objeto en C: \ Users \ CWalt \ Documents \ gitlab \ steuerazubi \ wordpress \ wp- incluye \ query.php en la línea 4524 …

Activé la depuración para crear un buen complemento. ¿Qué podría haber hecho mal?


Más tipos de publicaciones

¿Conoce un buen enfoque para permitir que el usuario especifique más tipos de publicaciones a través del backend de wordpress? El usuario debería poder crear diferentes páginas de búsqueda para diferentes tipos de publicaciones a través de códigos cortos.


Muchas gracias por leer Estoy agradecido por cada pequeña pista.

Respuesta:

He leído tu publicación en su totalidad, ciertamente no veo nada particularmente malo en ella, pero me parece que estás más frustrado con la forma en que se ha presentado.

Personalmente, tengo una gran experiencia en programación orientada a objeciones, me permite establecer una estructura y hace que mi código sea mucho más reutilizable. Mi sugerencia para usted sería intentar un enfoque orientado a objetos para su próximo complemento, o la reestructuración de este complemento sobre el que escribió en la pregunta original.

WordPress Plugin Boiler Plate es lo que recomiendo de todo corazón. Por lo general, comienzo dirigiéndome a wwpb.me para generar un esqueleto de complementos para mí que sea funcional desde el principio, simplemente complete el formulario, descargue y extraiga en el directorio de complementos de su instalación de wordpress.

Una vez que tenga su esqueleto para correr en su lugar, le sugiero que lea este tutorial, es una excelente introducción sobre cómo construir el esqueleto para caminar que acaba de descargar:

Acelere el desarrollo utilizando el complemento de WordPress Boilerplate pt1

El complemento de WordPress Boilerplate Parte 2: Desarrollo de un complemento

The WordPress Plugin Boilerplate Parte 3: Los últimos pasos

Después de leerlo rápidamente, generalmente me gusta crear una clase de datos que almacene todas mis consultas de base de datos personalizadas, como:

<?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;
  }

Luego, para usar esto dentro de su administrador / controladores de cara al público, es tan simple como hacer:

    <?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();

}

También me gusta crearme una clase de utilidad que contenga funciones muy comunes en todo mi complemento, como reglas de validación de formularios, implementadas y utilizadas exactamente de la misma manera.

Simplemente inclúyalos en su archivo de complemento principal con require_once y cree una instancia donde sea necesario.

El uso de la clase de datos me permite centralizar todas mis llamadas de datos en un solo lugar y usarlas durante el desarrollo del complemento.

El uso de estas prácticas ha reducido significativamente mi tiempo de desarrollo y ha hecho que mis complementos sean mucho más fáciles de mantener.

¡Espero que encuentre útil esta respuesta!

Leave a Comment

Your email address will not be published.

Scroll to Top

istanbul avukat

-

web tasarım