繁体   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