簡體   English   中英

更改內容 <div> 來自“按類別排序”菜單,沒有頁面加載

[英]Change content inside <div> from “sort posts by category” menu without page load

我在這個網站上的第一篇文章,我正在為我的第一個自定義wordpress主題尋求一些指導。 我對jQuery / AJAX非常陌生,此時它對我的大腦造成了傷害,因為整個過程在下一個過程之后就是一個學習曲線。 所以請原諒我無法在線條之間看到並理解已經或可能已經存在的內容。 當我搜索時,這個主題有一些結果但是我無法將這些例子轉化為我的情況的工作結果......

我希望按類別在“新聞”部分對我顯示的帖子進行排序... <div id="#container">中有一個子菜單...我的意圖是讓子菜單鏈接專門更改內容我的<div id="contentbox-news"> ...

即“最新消息”,“近期建設項目”,“新聞發布公告”等......

這是來自“page-news.php”和原始鏈接Cars&Coffee HFX的一些代碼

<div id="news_submenu_container"><!-- begin submenu placement -->
            <ul id="news_submenu">
              <li>VIEW</li>
              <li><a href="#" onClick="get_posts_all();">ALL</a></li>
              <li><a href="#" onClick="get_posts_news();">NEWS</a></li>
              <li><a href="#" onClick="get_posts_builds();">BUILDS</a></li>
              <li><a href="#" onClick="get_posts_pr();">PR</a></li>
            </ul>
        </div><!-- end submenu placement -->

        <script>
            function get_posts_all() {
                var posts_all_var = '<?php echo "Insert Wordpress Loop here identified by Category-ID" ?>';
            document.getElementById("contentbox-news").innerHTML = posts_all_var;
            return false;
            }

            function get_posts_news() {
                var posts_news_var = '<?php echo "Huh?" ?>';
            document.getElementById("contentbox-news").innerHTML = posts_news_var;
            return false;
            }

            function get_posts_builds() {
                var posts_builds_var = '<?php echo "Cant get loop to work" ?>';
            document.getElementById("contentbox-news").innerHTML = posts_builds_var;
            return false;
            }

            function get_posts_pr() {
                var posts_pr_var = '<?php echo "DAMNIT!" ?>';
            document.getElementById("contentbox-news").innerHTML = posts_pr_var;
            return false;
            }
        </script>

我現在理解JavaScript和PHP不能以我想的方式一起工作......顯然我需要通過AJAX使用一種方法...我在PHP AJAX和MySQL上找到了這篇文章但是它對我來說太先進了,我我無法理解它並為自己創造一個有效的例子......

但是現在,從星期六開始,我已經制作了新的代碼,讓我這么遠,我可以用PHP回應......就此而言。

            function get_posts_builds() {
                var posts_builds_var = '<?php query_posts('cat=6'); 
                                              while (have_posts()):
                                              the_post(); 
                                              the_content(); 
                                              endwhile; ?>';
            document.getElementById("contentbox-news").innerHTML = posts_builds_var;
            return false;
            }

一旦我用這個PHP wordpress循環替換PHP回聲,它似乎沒有為我做的技巧和休息。

你確實需要使用AJAX來實現這一目標。 Wordpress有自己的方式處理ajax請求 ,您可以通過以下幾個步驟來執行此操作。 我將嘗試在這個主題上展示一些WP最佳實踐 - 因為可能有更快/更容易/更臟的方式來實現這一點(可能甚至通過插件),這將為您提供Wordpress主題/插件開發的良好介紹。 請隨意關注文檔鏈接,以更好地了解其工作原理。


1.構建類別菜單

在您的代碼示例中,菜單是靜態的,但您最好使用動態菜單。 一種解決方案可能是使用get_the_category_list ,但它不允許您完全控制類別鏈接。 我建議像這樣定義一個新的導航菜單 (以下代碼進入你的主題functions.php ):

add_action('after_setup_theme', 'add_categories_menu');
function add_categories_menu() {
  register_nav_menu('categories_menu', __('Categories Menu', 'your-theme-slug'));
}

然后在模板中,使用以下內容替換靜態菜單,以顯示全新菜單:

<?php wp_nav_menu(array('theme_location' => 'categories_menu')); ?>

現在要將類別添加到菜單中,登錄到Wordpress管理,進入
外觀 > 菜單 ,創建一個新菜單,為其選擇主題位置“類別菜單”,並為其添加類別。

最后一步,我們將添加一個過濾器 ,以便在菜單鏈接上添加onclick屬性,將類別slug發送到我們稍后定義的名為showPostsFromCategory()的js函數。

這進入你的functions.php

function add_onclick_attr_categories_menu($atts, $item, $args) {
    if($args->theme_location == 'categories_menu' && $item->object == 'category') {
        $category = get_category($item->object_id);
        if($category !== null) {
            $atts['onClick'] = 'showPostsFromCategory("' . $item->slug . '")';
        }
    }
    return $atts;
}
add_filter('nav_menu_link_attributes', 'add_onclick_attr_categories_menu', 10, 3);

您可能想問, 為什么我們要在菜單項上保留類別鏈接? 它適用於SEO和可訪問性目的:對於沒有javascript的瀏覽器(如屏幕閱讀器)或搜索爬蟲,類別頁面仍然可以訪問。


2.為AJAX准備主題

在Wordpress中,需要將所有AJAX請求發送到wp-admin/admin-ajax.php其中包含一個動作參數,該參數將使用wp_ajax_nopriv_my_action (對於未登錄的用戶)識別請求以便在functions.php中捕獲它和wp_ajax_my_action (對於登錄用戶)掛鈎。

因此,在進一步推進之前的一小步是在JavaScript中訪問該路徑( wp-admin/admin-ajax.php )。 首先,創建一個我們將用於主題文件夾中的AJAX進程的js文件,假設他的名字是./js/categories-ajax.js 然后,在functions.php中添加以下內容,以便將此新腳本排入隊列並通過腳本本地化訪問該路徑:

add_action('wp_enqueue_scripts', 'ajax_categories_enqueue_scripts');
function ajax_categories_enqueue_scripts() {
    wp_register_script('categories_ajax', get_stylesheet_directory_uri() . '/js/categories-ajax.js', array('jquery'), '', true);
    wp_localize_script('categories_ajax', 'ls', array(
        'ajax_url'                  => admin_url('admin-ajax.php')
    ));
    wp_enqueue_script('categories_ajax');
}

有了這個,你可以在你的JS中使用ls.ajax_url訪問admin-ajax.php路徑。


3.觸發ajax請求

是時候創建showPostsFromCategory()函數了。 所以讓我們寫一下你的新類別-ajax.js文件。 就個人而言,為了避免在我的插件/主題開發中與jQuery發生任何可能的沖突,我喜歡總是將我的jQuery代碼封裝在JavaScript閉包中,並通過像這樣的全局變量來訪問函數:

(function($){
  showPostsFromCategory = function(category_slug) {
    // code function...
  };
})(jQuery);
var showPostsFromCategory;

所以我現在假設功能代碼在閉包內。
基本上,我們現在需要做的是設置一個$.post請求給admin-ajax.php ,它將發送以下參數:

  • action :正在調用的AJAX操作的標識符,以使Wordpress知道稍后應該調用哪個函數。 我們將這個dynamic_categories命名為。
  • category :在菜單中單擊的類別slug。

所以功能代碼如下所示:

showPostsFromCategory = function(category_slug) {
    $.post(ls.ajax_url, {action: 'dynamic_categories', category: category_slug}, function success(data) {
        $('#your-post-content-wrapper').html(data); // Update the page with the new posts -- change this ID to the correct one
    });
    return false; // this is to cancel the link click, so the page isn't being redirected
}

這是非常基本的,您可能希望稍后添加一些錯誤處理和加載器。 這里我們只用AJAX返回替換實際的帖子,我們假設是HTML。 在JS方面沒有更多的事情要做,所以現在讓我們在PHP方面工作。


4.獲取所請求類別的帖子

首先,在functions.php中添加以下行,以便將函數get_categories_posts()附加到wp_ajax_dynamic_categorieswp_ajax_nopriv_dynamic_categories操作。

add_action('wp_ajax_dynamic_categories', 'get_categories_posts');
add_action('wp_ajax_nopriv_dynamic_categories', 'get_categories_posts');

現在,我們需要在函數中執行以下操作:

  1. 檢查類別slug是否有效且是否有關聯的帖子,否則顯示錯誤。
  2. 獲取與 JS腳本發送的slug標識的類別相關聯的帖子
  3. 循環瀏覽帖子並使用模板部分顯示每個帖子。 為此,在主題文件夾中創建一個模板,該模板僅包含顯示一個帖子所需的HTML / PHP。 您可以在默認的wordpress主題(twentysixteen)中查看此類模板的示例
    template-parts/content.php 在您的主題中執行相同類型的文件 - 可能已經有一個。

    您還需要更新存檔模板以使用模板部件。 這很簡單,刪除用於在循環顯示帖子的代碼並將其替換為:

     <?php get_template_part('template-parts/content'); ?> 

所以整個功能代碼如下所示:

function get_categories_posts() {
    // Check if the category slug provided is ok and if it have posts
    if(!isset($_POST['category'])) {
        die('<p class="error">' . __('No category parameter provided', 'your-theme-slug') . '</p>');
    }
    $category_slug = sanitize_text_field($_POST['category']);
    $category = get_category_by_slug($category_slug);
    if(!$category) {
        die('<p class="error">' . sprintf(__('Category %s not found', 'your-theme-slug'), $category_slug) . '</p>');
    }
    $posts = get_posts(array(
        'category' => $category->term_id,
        'posts_per_page' => -1 // get all posts
    ));
    if(empty($posts)) {
        die('<p class="error">' . sprintf(__('The category %s is empty', 'your-theme-slug'), $category->name) . '</p>');
    }

    // Loop through the posts and display them
    foreach ($posts as $post) {
        setup_postdata($post);
        get_template_part('template-parts/content');
    }
    die('');
}

就這樣! 有了這個,您現在可以為您的帖子類別進行動態導航。

供參考: sanitize_text_fieldget_category_by_slugget_postssetup_postdataget_template_part


請注意,這不支持分頁。 如果您需要,請查看我對此事所做的回答


進一步閱讀

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM