it-swarm.com.de

sortieren Sie Suchergebnisse nach benutzerdefinierten Feldern mithilfe der Dropdown-Liste

Auf meiner search.php-Seite habe ich eine Dropdown-Liste "Sortieren nach", die fast genau so funktioniert, wie ich es möchte -

<select class="dropdown-class" name="sort-posts" id="sortbox" onchange="document.location.href=location.href+this.options[this.selectedIndex].value;">
<option disabled>Sort by</option>
<option value="&orderby=date&order=dsc">Newest</option>
<option value="&orderby=date&order=asc">Oldest</option>
</select>

<script type="text/javascript">

    <?php if (( $_GET['orderby'] == 'date') && ( $_GET['order'] == 'dsc')) { ?>
        document.getElementById('sortbox').value='orderby=date&order=dsc';

    <?php } elseif (( $_GET['orderby'] == 'date') && ( $_GET['order'] == 'asc')) { ?>
        document.getElementById('sortbox').value='orderby=date&order=asc';

    <?php } else { ?>
        document.getElementById('sortbox').value='orderby=date&order=desc';

    <?php } ?>

</script>

Wenn ich auf der Suchergebnisseite bin, sortiert das Dropdown-Menü "Sortieren" die aktuellen Ergebnisse nach Datum, indem Sie die URL abrufen und an diese anhängen und dann die Seite mit den Ergebnissen neu laden ---

// Before
mydomain.com/?s=Search&property_city=new-york-city&beds=Any 

// After
mydomain.com/?s=Search&property_city=new-york-city&beds=Any&orderby=date&order=dsc

Ich versuche jetzt jedoch, den Code weiter zu verbessern, indem ich ihn zum Sortieren nach numerischen benutzerdefinierten Feldern (hoch nach niedrig und niedrig nach hoch) verwende.

Es scheint, dass alle Informationen, die ich zu diesem Thema finden kann, viel komplizierter sind. Geht das überhaupt mit dem Code, mit dem ich bereits angefangen habe?

UPDATE

Ich scheine näher zu kommen -

Auf meiner search.php Seite habe ich dies vor meiner Schleife ----

<select class="dropdown-class" name="sort-posts" id="sortbox" onchange="document.location.href=location.href+this.options[this.selectedIndex].value;">
<option disabled>Sort by</option>
<option value="&orderby=date&order=dsc">Newest</option>
<option value="&orderby=date&order=asc">Oldest</option>
<option value="&orderby=property_price&order=asc">Most Expensive</option>
<option value="&orderby=property_price&order=dsc">Least Expensive</option>
<option value="&orderby=property_area&order=dsc">Largest</option>
<option value="&orderby=property_area&order=asc">Smallest</option>
</select>

<script type="text/javascript">

    <?php if (( $_GET['orderby'] == 'date') && ( $_GET['order'] == 'dsc')) { ?>
        document.getElementById('sortbox').value='orderby=date&order=dsc';

    <?php } elseif (( $_GET['orderby'] == 'date') && ( $_GET['order'] == 'asc')) { ?>
        document.getElementById('sortbox').value='orderby=date&order=asc';

    <?php } elseif (( $_GET['orderby'] == 'property_price') && ( $_GET['order'] == 'asc')) { ?>
        document.getElementById('sortbox').value='orderby=property_price&order=asc';

        <?php } elseif (( $_GET['orderby'] == 'property_price') && ( $_GET['order'] == 'dsc')) { ?>
        document.getElementById('sortbox').value='orderby=property_price&order=dsc';

    <?php } elseif (( $_GET['orderby'] == 'property_area') && ( $_GET['order'] == 'asc')) { ?>
        document.getElementById('sortbox').value='orderby=property_area&order=asc';

        <?php } elseif (( $_GET['orderby'] == 'property_area') && ( $_GET['order'] == 'dsc')) { ?>
        document.getElementById('sortbox').value='orderby=property_area&order=dsc';


    <?php } else { ?>
        document.getElementById('sortbox').value='orderby=date&order=desc';

    <?php } ?>

</script>

dort steht "orderby = xxx". Ich verwende nur meine Namen für meine benutzerdefinierten Felder.

1
Rich

Ok, ich habe es mithilfe des @Nicolai-Vorschlags und einer Antwort von einer anderen Frage herausgefunden (zu der ich den Link verloren zu haben scheint).

Für den Anfang musste ich sicherstellen, dass meine Zahlen keine Kommas enthalten, was ich bereits getan hatte, indem ich meine Post-Meta ohne sie gespeichert habe.

Dann habe ich den Code, den ich in einer anderen Frage gefunden habe, benutzt und in meine functions.php Datei gestellt -

function wpse139657_orderby(){
    if( isset($_GET['orderby']) ){
        $order = $_GET['order'] or 'DESC';
        set_query_var('orderby', 'meta_value_num');
        //set_query_var('meta_type', 'numeric');
        set_query_var('meta_key', $_GET['orderby']);
        set_query_var('order', $order);
    }
}

add_filter('pre_get_posts','wpse139657_orderby');

Dann habe ich auf meiner search.php Seite den folgenden Code für das Auswahlfeld verwendet -

<select class="dropdown-class" name="sort-posts" id="sortbox" onchange="document.location.href=location.href+this.options[this.selectedIndex].value;">
<option disabled>Sort by</option>
<option value="&orderby=date&order=dsc">Newest</option>
<option value="&orderby=date&order=asc">Oldest</option>
<option value="&orderby=property_price2&order=DESC">Most Expensive</option>
<option value="&orderby=property_price2&order=ASC">Least Expensive</option>
<option value="&orderby=area2&order=DESC">Largest</option>
<option value="&orderby=area2&order=ASC">Smallest</option>
</select>

Dies scheint den Trick zu tun und funktioniert mit Paginierung, nur Probleme, die ich im Moment habe, ist -

  1. Hässliche Urls
  2. Wenn die Seite mit den sortierten Beiträgen neu geladen wird, wird die Dropdown-Auswahl auf die Standardeinstellung zurückgesetzt, dh "Neueste", wenn die vom Benutzer gewählte Option weiterhin aktiviert sein sollte.
1
Rich

orderby sollte z.B. meta_value oder meta_value_num - verschiedene spezifische meta_type sind verfügbar - zum Bestellen nach Metadaten. Zusätzlich muss ein meta_key gesetzt und in der Abfrage vorhanden sein. Um genau zu sein und Missverständnisse zu vermeiden, muss meta_key die keyname des Feldes sein, nach dem Sie sortieren. Weitere Informationen finden Sie im Abschnitt Order & Orderby Parameters und Custum Fields Parameters in der Dokumentation zu WP_Query.

1
Nicolai

Form fügt Ihren ausgewählten Wert automatisch der URL hinzu, wenn Sie das Formular absenden. Es ist nicht erforderlich, einen solchen Wert &orderby=date&order=dsc zu erstellen. Wenn Sie mehrere Informationen in einem Auswahlwert übergeben möchten, können Sie einfachere Werte und if-Anweisungen verwenden. Für die neueste Option würde ich newest als Wert verwenden und eine solche if-Anweisung hinzufügen.

// Url /?s=test&order=newest

$orderby = '';
$order = '';

// Get filtered $_GET['order'] parameter
$value = filter_input( INPUT_GET, 'order', FILTER_SANITIZE_STRING );

if( $value === 'newest' ) {
    $orderby = 'date';
    $order = 'desc';
}

// Modify query using $orderby and $order parameters

Die Verwendung von JavaScript zur Auswahl der Option ist für mich ebenfalls eine schlechte Idee. Sie sollten den aktuellen Parameter order überprüfen und das ausgewählte Attribut zu Ihrer Option hinzufügen.

// Url /?s=test&order=newest

// Get filtered $_GET['order'] parameter
$value = filter_input( INPUT_GET, 'order', FILTER_SANITIZE_STRING );
$selected = ($value === 'newest') ? 'selected': '' ;
?>

<select name="order">
    <option value="newest" <?php echo esc_attr( $selected ); ?>></option>
</select>

Ich denke, Sie sollten sich nicht die Mühe machen, eine nette URL zu erstellen. Für eine kleine Anzahl von Parametern ist es möglicherweise verlockend, eine Nice-URL zu erstellen, aber wenn Ihre App größer wird, ist es sinnlos, zusätzliche Schreib- und Logikfunktionen hinzuzufügen. Wenn Sie Ihren Chef oder Kunden überzeugen müssen, auf Nice zu verzichten, zeigen Sie ihm Amazon auf der Suchseite. Ich betrachte sie als Spezialist und sie verwenden keine Nice-URLs während der Suche.

Der folgende Code ist ein voll funktionsfähiges Beispiel zum Sortieren von Beiträgen nach date, price und size. Führen Sie die Funktion wpse_288655_display_form an der Stelle aus, an der Sie das Sortierformular anzeigen möchten.

/**
 * Display sort form
 */
function wpse_288655_display_form() {

    /**
     * Get all params from url which are not part of our sort form
     * and display it in form as hidden inputs.
     */
    $search_param = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );

    /**
     * Current order value to select proper field
     */
    $value = filter_input( INPUT_GET, 'order', FILTER_SANITIZE_STRING );
    ?>

    <form method="get">
        <?php wpse_288655_display_select('order', 'Sort by:', wpse_288655_get_order_by_options(), $value ); ?>

        <?php
            /**
             * Display all params from url which do not apply to our sort form
             */
        ?>
        <input type="hidden" name="s" value="<?php esc_attr_e( $search_param ); ?>">

        <button type="submit"><?php esc_html_e('Sort'); ?></button>
    </form>
    <?php
}

/**
 * Get sort options
 */
function wpse_288655_get_order_by_options(){

    return array(
        '' => '',
        'newest' => __('Newest'),
        'oldest' => __('Oldest'),
        'most_expensive' => __('Most Expensive'),
        'least_expensive' => __('Least Expensive'),
        'largest' => __('Largest'),
        'smallest' => __('Smallest'),
    );
}

/**
 * Display select field
 */
function wpse_288655_display_select( $name, $label, $options, $value = '' ) {
    ?>
    <label><?php esc_html_e( $label ) ?></label>
    <select name="<?php esc_attr_e( $name ) ?>">
        <?php wpse_288655_display_options( $options, $value ); ?>
    </select>
    <?php
}

/**
 * Display select options
 */
function wpse_288655_display_options( $options, $value ) {

    foreach( $options as $option_value => $option_label ):
        $selected = ( $option_value === $value ) ? ' selected' : '';
        ?>
        <option value="<?php esc_attr_e( $option_value ) ?>"<?php esc_attr_e( $selected ) ?>><?php esc_html_e( $option_label ) ?></option>
        <?php

    endforeach;
}

/**
 * Sort posts using pre_get_posts filter
 */
function wpse_288655_order_posts( $query ) {

    /**
     * Execute query only when we are on search page and this is main query
     */
    if ( $query->is_search() && $query->is_main_query() ) {

        $value = filter_input( INPUT_GET, 'order', FILTER_SANITIZE_STRING );
        $order_by_options = wpse_288655_get_order_by_options();

        if( isset( $order_by_options[ $value ] ) && !empty( $value ) ) {

            switch( $value ) {
                case 'newest':

                    $query->set( 'order', 'desc' );
                    $query->set( 'orderby', 'date' );

                    break;

                case 'oldest':

                    $query->set( 'order', 'asc' );
                    $query->set( 'orderby', 'date' );

                    break;
                case 'most_expensive':

                    $query->set( 'meta_key', 'price' ); // Your custom meta_key

                    $query->set( 'order', 'desc' );
                    $query->set( 'orderby', 'meta_value_num' );

                    break;
                case 'least_expensive':

                    $query->set( 'meta_key', 'price' ); // Your custom meta_key

                    $query->set( 'order', 'asc' );
                    $query->set( 'orderby', 'meta_value_num' );

                    break;
                case 'largest':

                    $query->set( 'meta_key', 'size' ); // Your custom meta_key

                    $query->set( 'order', 'desc' );
                    $query->set( 'orderby', 'meta_value_num' );

                    break;
                case 'smallest':

                    $query->set( 'meta_key', 'size' ); // Your custom meta_key

                    $query->set( 'order', 'asc' );
                    $query->set( 'orderby', 'meta_value_num' );

                    break;
                default:
                    break;
            }
        }
    }
}

add_filter('pre_get_posts', 'wpse_288655_order_posts');
1
kierzniak