Cách tải động các bài đăng khi nhấp chuột bằng Ajax trong Genesis

Hướng dẫn chỉ dành cho thành viên này cung cấp các bước để hiển thị liên kết tiêu đề bài đăng trong thanh bên và sử dụng Ajax để tìm nạp và tải mục nhập tương ứng khi một tiêu đề được nhấp vào dựa trên bài viết tuyệt vời này từ wpmudev.

Mặc dù hướng dẫn đã được viết cho Genesis Sample, nhưng nó sẽ hoạt động với một số điều chỉnh trong bất kỳ chủ đề Genesis hoặc WordPress nào.

Quy trình thực hiện cuộc gọi Ajax trong WordPress có thể được tóm tắt như sau:

Bước 1: PHP

Hãy tạo một mẫu Trang tùy chỉnh có mã để

  • buộc bố cục nội dung-thanh bên.
  • đặt lại tiêu đề mục nhập từ vị trí mặc định của nó đến trước phần bao bọc của thanh bên nội dung.
  • xóa thanh bên chính khỏi khu vực thanh bên chính.
  • sử dụng WP_Query tùy chỉnh để xuất tiêu đề được liên kết của tất cả các bài đăng trong khu vực thanh bên chính.
  • chuyển URL của admin-ajax.php và URL tải hình ảnh vào load-post.js và tải nó ở chân trang.

Tạo một tệp có tên say, template-ajax-load.php trong thư mục chủ đề con có như sau:

/* Template Name: AJAX Load */

// Forces sidebar-content layout setting.
add_filter( 'genesis_pre_get_option_site_layout', '__genesis_return_sidebar_content' );

/* Relocates entry header */
remove_action( 'genesis_entry_header', 'genesis_entry_header_markup_open', 5 );
remove_action( 'genesis_entry_header', 'genesis_do_post_title' );
remove_action( 'genesis_entry_header', 'genesis_entry_header_markup_close', 15 );

add_action( 'genesis_before_content_sidebar_wrap', 'genesis_entry_header_markup_open' );
add_action( 'genesis_before_content_sidebar_wrap', 'genesis_do_post_title' );
add_action( 'genesis_before_content_sidebar_wrap', 'genesis_entry_header_markup_close' );

// Removes Primary Sidebar from the Primary Sidebar area.
remove_action( 'genesis_sidebar', 'genesis_do_sidebar' );

add_action( 'genesis_sidebar', 'sk_show_post_links' );
/**
 * Outputs links to all the posts in the Primary Sidebar area.
 */
function sk_show_post_links() {

    // WP_Query arguments.
    $args = array(
        'posts_per_page' => '-1',
        // 'post_type' => 'gs_faq',
    );

    // The Query.
    $query = new WP_Query( $args );

    // The Loop.
    if ( $query->have_posts() ) {
        echo '<ul>';
        while ( $query->have_posts() ) {
            $query->the_post();
            printf( '<li><a href="%s" class="post-link" data-id="%s">%s</a></li>',
                esc_url( get_the_permalink() ),
                get_the_ID(),
                esc_html( get_the_title() )
            );
        }
        echo '</ul>';
    } else {
        // no posts found.
    }

    // Restore original Post Data.
    wp_reset_postdata();

}

add_action( 'wp_enqueue_scripts', 'sk_load_post_script' );
/**
 * Passes WP AJAX URL and loading image URL to `load-post.js` and loads it in the footer.
 */
function sk_load_post_script() {

    wp_enqueue_script(
        'sk-loadpost',
        get_stylesheet_directory_uri() . '/js/load-post.js',
        array( 'jquery' ),
        CHILD_THEME_VERSION,
        true
    );

    wp_localize_script(
        'sk-loadpost',
        'sk_ajaxobject',
        array(
            'ajaxurl'       => admin_url( 'admin-ajax.php' ),
            'loadingimage'  => get_stylesheet_directory_uri() . '/images/loading.gif',
        )
    );

}

genesis();

Ghi chú:

a) Nếu bạn muốn giải pháp hoạt động với các mục nhập của Loại bài đăng tùy chỉnh thay vì các bài đăng tiêu chuẩn, hãy bỏ ghi chú

'post_type' => 'gs_faq',

và chỉ định loại bài đăng của bạn.

b) Chúng tôi đang đặt một lớp post-link cho mỗi liên kết tiêu đề và thêm ID của mục nhập đó làm giá trị của data-id thuộc tính. Sau đó trong tệp JS, chúng tôi sẽ truy xuất ID này và chuyển nó cùng với yêu cầu Ajax của chúng tôi tới máy chủ.

c) Trong hàm sk_load_post_script (), chúng tôi đang gửi URL của trình xử lý Ajax chính của WordPress, wp-admin / admin-ajax.php và của một hình ảnh chỉ báo đang tải lên load-post.js (chúng tôi sẽ tạo Kế tiếp).

d) Tải hình ảnh loading.gif (tải xuống từ đây) vào thư mục hình ảnh của chủ đề con .

Bước 2: Javascript

Tạo một tệp có tên load-post.js trong js thư mục của chủ đề con có như sau:

(function ($) {

    $(document).on('click', 'a.post-link', function (event) {
        event.preventDefault();

        $.ajax({
            // URL to which request is sent.
            url: sk_ajaxobject.ajaxurl,

            // specifies how contents of data option are sent to the server.
            // `post` indicates that we are submitting the data.
            type: 'post',

            // data to be sent to the server.
            data: {
                // a function defined in functions.php hooked to this action (with `wp_ajax_nopriv_` and/or `wp_ajax_` prefixed) will run.
                action: 'sk_load_post',

                // stores the value of `data-id` attribute of the clicked link in a variable.
                post_id: $(this).data('id')
            },

            // pre-reqeust callback function.
            beforeSend: function () {
                $('.content > .entry .entry-content').html('<img src="' + sk_ajaxobject.loadingimage + '" />');
            },

            // function to be called if the request succeeds.
            // `response` is data returned from the server.
            success: function (response) {
                $('.content > .entry .entry-content').hide().html(response).fadeIn('slow');
            }
        })
    })

})(jQuery);

Lệnh gọi Ajax được kích hoạt bởi sự kiện nhấp chuột mỗi khi bất kỳ liên kết tiêu đề bài đăng nào được nhấp vào.

Lưu ý tên của hành động , sk_load_post . Trong bước tiếp theo, chúng ta sẽ xác định mã sẽ được xuất ra trên giao diện người dùng trong một hàm được nối với hành động này. Đầu ra của hàm này là response dữ liệu được gửi trở lại tệp .js .

Bước 3 và 4: functions.php

Thêm phần sau vào functions.php của chủ đề con :

add_action( 'wp_ajax_nopriv_sk_load_post', 'sk_load_post' );
add_action( 'wp_ajax_sk_load_post', 'sk_load_post' );
/**
 * Outputs entry header, entry content and entry footer for the specified post.
 */
function sk_load_post() {

    $args = array(
        'posts_per_page' => '1',
        'no_found_rows' => true,
        // set post id to the ID of the post whose title has been clicked via `load-post.js`.
        'p' => intval( $_POST['post_id'] ),
        'post_type' => get_post_type( $_POST['post_id'] ),
    );

    $loop = new WP_Query( $args );

    // sets up the post, sets the ‘in the loop’ property to true.
    $loop->the_post();

    /* entry header */
    do_action( 'genesis_entry_header' );

    /* entry content */
    do_action( 'genesis_before_entry_content' );

    printf( '<div %s>', genesis_attr( 'entry-content' ) );
    do_action( 'genesis_entry_content' );
    echo '</div>';

    do_action( 'genesis_after_entry_content' );

    /* entry footer */
    do_action( 'genesis_entry_footer' );

    // restores original post data.
    wp_reset_postdata();

    // prevents echoing out `0` via the die function in admin-ajax.php, in addition to the above output.
    die();

}

Ghi chú:

a) Các chức năng được nối để wp_ajax_nopriv_{action_name} chạy trên giao diện người dùng chưa đăng nhập và các chức năng được nối để wp_ajax_{action_name} chạy trên giao diện người dùng đã đăng nhập.

b) Nếu bạn muốn hiển thị toàn bộ bài đăng bao gồm. phần nhận xét, hộp tác giả (nếu được bật), v.v., thay thế

// sets up the post, sets the ‘in the loop’ property to true.
$loop->the_post();

/* entry header */
do_action( 'genesis_entry_header' );

/* entry content */
do_action( 'genesis_before_entry_content' );

printf( '<div %s>', genesis_attr( 'entry-content' ) );
do_action( 'genesis_entry_content' );
echo '</div>';

do_action( 'genesis_after_entry_content' );

/* entry footer */
do_action( 'genesis_entry_footer' );

// restores original post data.
wp_reset_postdata();

với

genesis_custom_loop( $args );

Bước 5: CSS

Hãy thêm CSS để đảm bảo rằng các liên kết xuất hiện phía trên nội dung được tải từ 959px trở xuống.

.page-template-template-ajax-load .entry-header {
    margin-bottom: 40px;
}

.sidebar-content .content-sidebar-wrap {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
        -ms-flex-direction: column;
            flex-direction: column;
}

.sidebar-content .sidebar {
    -webkit-box-ordinal-group: 1;
        -ms-flex-order: 0;
            order: 0;
    margin-bottom: 60px;
}

.sidebar-content .content {
    -webkit-box-ordinal-group: 2;
        -ms-flex-order: 1;
            order: 1;
}

Để đảm bảo điều này trông ổn từ 960px trở lên, trong truy vấn phương tiện chiều rộng tối thiểu 960px, hãy thêm

.content-sidebar-wrap {
    overflow: hidden;
}

.sidebar-content .content-sidebar-wrap {
    -webkit-box-orient: horizontal;
    -webkit-box-direction: normal;
        -ms-flex-direction: row;
            flex-direction: row;
}

.page-template-template-ajax-load .content-sidebar-wrap {
    margin-bottom: 60px;
    min-height: 70vh;
}

Cuối cùng, tạo / chỉnh sửa một Trang tĩnh, chọn AJAX Load Mẫu Trang và xuất bản / cập nhật.

// This gist is now maintained on github at https://github.com/luetkemj/wp-query-ref

 Quicktag in the post content.
    'nopaging' => false, // (boolean) - show all posts or use pagination. Default value is 'false', use paging.
    'posts_per_archive_page' => 10, // (int) - number of posts to show per page - on archive pages only. Over-rides posts_per_page and showposts on pages where is_archive() or is_search() would be true.
    'offset' => 3, // (int) - number of post to displace or pass over.
                   // Warning: Setting the offset parameter overrides/ignores the paged parameter and breaks pagination. for a workaround see: http://codex.wordpress.org/Making_Custom_Queries_using_Offset_and_Pagination
                   // The 'offset' parameter is ignored when 'posts_per_page'=>-1 (show all posts) is used.
    'paged' => get_query_var('paged'), // (int) - number of page. Show the posts that would normally show up just on page X when usinthe "Older Entries" link.
                                       // NOTE: This whole paging thing gets tricky. Some links to help you out:
                                       // http://codex.wordpress.org/Function_Reference/next_posts_link#Usage_when_querying_the_loop_with_WP_Query
                                       // http://codex.wordpress.org/Pagination#Troubleshooting_Broken_Pagination
    'page' => get_query_var('page'), // (int) - number of page for a static front page. Show the posts that would normally show up just on page X of a Static Front Page.
                                     // NOTE: The query variable 'page' holds the pagenumber for a single paginated Post or Page that includes the  Quicktag in the post content.
    'ignore_sticky_posts' => false, // (boolean) - ignore sticky posts or not (available with Version 3.1, replaced caller_get_posts parameter). Default value is 0 - don't ignore sticky posts. Note: ignore/exclude sticky posts being included at the beginning of posts returned, but the sticky post will still be returned in the natural order of that list of posts returned.

// Order & Orderby Parameters - Sort retrieved posts.
// http://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters
    'order' => 'DESC', // (string) - Designates the ascending or descending order of the 'orderby' parameter. Default to 'DESC'.
                       //Possible Values:
                       //'ASC' - ascending order from lowest to highest values (1, 2, 3; a, b, c).
                       //'DESC' - descending order from highest to lowest values (3, 2, 1; c, b, a).
    'orderby' => 'date', // (string) - Sort retrieved posts by parameter. Defaults to 'date'. One or more options can be passed. EX: 'orderby' => 'menu_order title'
                         //Possible Values:
                         // 'none' - No order (available since Version 2.8).
                         // 'ID' - Order by post id. Note the capitalization.
                         // 'author' - Order by author. ('post_author' is also accepted.)
                         // 'title' - Order by title. ('post_title' is also accepted.)
                         // 'name' - Order by post name (post slug). ('post_name' is also accepted.)
                         // 'type' - Order by post type (available since Version 4.0). ('post_type' is also accepted.)
                         // 'date' - Order by date. ('post_date' is also accepted.)
                         // 'modified' - Order by last modified date. ('post_modified' is also accepted.)
                         // 'parent' - Order by post/page parent id. ('post_parent' is also accepted.)
                         // 'rand' - Random order. You can also use 'RAND(x)' where 'x' is an integer seed value.
                         // 'comment_count' - Order by number of comments (available since Version 2.9).
                         // 'relevance' - Order by search terms in the following order: First, whether the entire sentence is matched. Second, if all the search terms are within the titles. Third, if any of the search terms appear in the titles. And, fourth, if the full sentence appears in the contents.
                         // 'menu_order' - Order by Page Order. Used most often for Pages (Order field in the Edit Page Attributes box) and for Attachments (the integer fields in the Insert / Upload Media Gallery dialog), but could be used for any post type with distinct 'menu_order' values (they all default to 0).
                         // 'meta_value' - Note that a 'meta_key=keyname' must also be present in the query. Note also that the sorting will be alphabetical which is fine for strings (i.e. words), but can be unexpected for numbers (e.g. 1, 3, 34, 4, 56, 6, etc, rather than 1, 3, 4, 6, 34, 56 as you might naturally expect). Use 'meta_value_num' instead for numeric values.
                         // 'meta_type' if you want to cast the meta value as a specific type. Possible values are 'NUMERIC', 'BINARY',  'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED', same as in '$meta_query'. When using 'meta_type' you can also use 'meta_value_*' accordingly. For example, when using DATETIME as 'meta_type' you can use 'meta_value_datetime' to define order structure.
                         // 'meta_value_num' - Order by numeric meta value (available since Version 2.8). Also note that a 'meta_key=keyname' must also be present in the query. This value allows for numerical sorting as noted above in 'meta_value'.
                         // 'post__in' - Preserve post ID order given in the 'post__in' array (available since Version 3.5). Note - the value of the order parameter does not change the resulting sort order.
                         // 'post_name__in' - Preserve post slug order given in the 'post_name__in' array (available since Version 4.6). Note - the value of the order parameter does not change the resulting sort order.
                         // 'post_parent__in' - Preserve post parent order given in the 'post_parent__in' array (available since Version 4.6). Note - the value of the order parameter does not change the resulting sort order.

// Date Parameters - Show posts associated with a certain time and date period.
// http://codex.wordpress.org/Class_Reference/WP_Query#Date_Parameters
    'year' => 2014, // (int) - 4 digit year (e.g. 2011).
    'monthnum' => 4, // (int) - Month number (from 1 to 12).
    'w' =>  25, // (int) - Week of the year (from 0 to 53). Uses the MySQL WEEK command. The mode is dependenon the "start_of_week" option.
    'day' => 17, // (int) - Day of the month (from 1 to 31).
    'hour' => 13, // (int) - Hour (from 0 to 23).
    'minute' => 19, // (int) - Minute (from 0 to 60).
    'second' => 30, // (int) - Second (0 to 60).
    'm' => 201404, // (int) - YearMonth (For e.g.: 201307).
    'date_query' => array( // (array) - Date parameters (available with Version 3.7).
                           // these are super powerful. check out the codex for more comprehensive code examples http://codex.wordpress.org/Class_Reference/WP_Query#Date_Parameters
      array(
        'year' => 2014, // (int) - 4 digit year (e.g. 2011).
        'month' => 4, // (int) - Month number (from 1 to 12).
        'week' => 31, // (int) - Week of the year (from 0 to 53).
        'day' => 5, // (int) - Day of the month (from 1 to 31).
        'hour' => 2, // (int) - Hour (from 0 to 23).
        'minute' => 3, // (int) - Minute (from 0 to 59).
        'second' => 36, // (int) - Second (0 to 59).
        'after' => 'January 1st, 2013', // (string/array) - Date to retrieve posts after. Accepts strtotime()-compatible string, or array of 'year', 'month', 'day'
        'before' => array( // (string/array) - Date to retrieve posts after. Accepts strtotime()-compatible string, or array of 'year', 'month', 'day'
          'year' => 2013, // (string) Accepts any four-digit year. Default is empty.
          'month' => 2, // (string) The month of the year. Accepts numbers 1-12. Default: 12.
          'day' => 28, // (string) The day of the month. Accepts numbers 1-31. Default: last day of month.
        ),
        'inclusive' => true, // (boolean) - For after/before, whether exact value should be matched or not'.
        'compare' =>  '=', // (string) - Possible values are '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'EXISTS' (only in WP >= 3.5), and 'NOT EXISTS' (also only in WP >= 3.5). Default value is '='
        'column' => 'post_date', // (string) - Column to query against. Default: 'post_date'.
        'relation' => 'AND', // (string) - OR or AND, how the sub-arrays should be compared. Default: AND.
      ),
    ),

// Custom Field Parameters - Show posts associated with a certain custom field.
// http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters
    'meta_key' => 'key', // (string) - Custom field key.
    'meta_value' => 'value', // (string) - Custom field value.
    'meta_value_num' => 10, // (number) - Custom field value.
    'meta_compare' => '=', // (string) - Operator to test the 'meta_value'. Possible values are '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'NOT EXISTS', 'REGEXP', 'NOT REGEXP' or 'RLIKE'. Default value is '='. 'meta_query' => array( // (array) - Custom field parameters (available with Version 3.1).
      'relation' => 'AND', // (string) - Possible values are 'AND', 'OR'. The logical relationship between each inner meta_query array when there is more than one. Do not use with a single inner meta_query array.
       array(
         'key' => 'color', // (string) - Custom field key.
         'value' => 'blue', // (string/array) - Custom field value (Note: Array support is limited to a compare value of 'IN', 'NOT IN', 'BETWEEN', or 'NOT BETWEEN') Using WP < 3.9? Check out this page for details: http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters 'type' => 'CHAR', // (string) - Custom field type. Possible values are 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'. Default value is 'CHAR'. The 'type' DATE works with the 'compare' value BETWEEN only if the date is stored at the format YYYYMMDD and tested with this format.
                           //NOTE: The 'type' DATE works with the 'compare' value BETWEEN only if the date is stored at the format YYYYMMDD and tested with this format.
         'compare' => '=', // (string) - Operator to test. Possible values are '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'EXISTS' (only in WP >= 3.5), and 'NOT EXISTS' (also only in WP >= 3.5). Default value is '='.
       ),
       array(
         'key' => 'price',
         'value' => array( 1,200 ),
         'compare' => 'NOT LIKE',
       )
    ),

// Permission Parameters - Display published posts, as well as private posts, if the user has the appropriate capability:
// http://codex.wordpress.org/Class_Reference/WP_Query#Permission_Parameters
    'perm' => 'readable', // (string) Possible values are 'readable', 'editable'

// Mime Type Parameters - Used with the attachments post type.
// https://codex.wordpress.org/Class_Reference/WP_Query#Mime_Type_Parameters
    'post_mime_type' => 'image/gif', // (string/array) - Allowed mime types.


// Caching Parameters
// http://codex.wordpress.org/Class_Reference/WP_Query#Caching_Parameters
// NOTE Caching is a good thing. Setting these to false is generally not advised.
    'cache_results' => true, // (bool) Default is true - Post information cache.
    'update_post_term_cache' => true, // (bool) Default is true - Post meta information cache.
    'update_post_meta_cache' => true, // (bool) Default is true - Post term information cache.
    'no_found_rows' => false, // (bool) Default is false. WordPress uses SQL_CALC_FOUND_ROWS in most queries in order to implement pagination. Even when you don’t need pagination at all. By Setting this parameter to true you are telling wordPress not to count the total rows and reducing load on the DB. Pagination will NOT WORK when this parameter is set to true. For more information see: http://flavio.tordini.org/speed-up-wordpress-get_posts-and-query_posts-functions


// Search Parameter
// http://codex.wordpress.org/Class_Reference/WP_Query#Search_Parameter
    's' => $s, // (string) - Passes along the query string variable from a search. For example usage see: http://www.wprecipes.com/how-to-display-the-number-of-results-in-wordpress-search
    'exact' => true, // (bool) - flag to make it only match whole titles/posts - Default value is false. For more information see: https://gist.github.com/2023628#gistcomment-285118
    'sentence' => true, // (bool) - flag to make it do a phrase search - Default value is false. For more information see: https://gist.github.com/2023628#gistcomment-285118

// Post Field Parameters
// For more info see: http://codex.wordpress.org/Class_Reference/WP_Query#Return_Fields_Parameter
// also https://gist.github.com/luetkemj/2023628/#comment-1003542
    'fields' => 'ids', // (string) - Which fields to return. All fields are returned by default.
                       // Possible values:
                       // 'ids'        - Return an array of post IDs.
                       // 'id=>parent' - Return an associative array [ parent => ID, … ].
                       // Passing anything else will return all fields (default) - an array of post objects.

// Filters
// For more information on available Filters see: http://codex.wordpress.org/Class_Reference/WP_Query#Filters

);

$the_query = new WP_Query( $args );

// The Loop
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
  // Do Stuff
endwhile;
endif;

// Reset Post Data
wp_reset_postdata();

?>