javascript - 在没有页面加载的情况下从 "sort posts by category"菜单更改 <div> 内的内容

标签 javascript php jquery wordpress

我在这个网站上的第一篇文章,我正在为我的第一个自定义 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 and MySQL 上找到了这篇文章但是它对我来说太高级了,我无法理解它并为自己创建一个工作示例......

但是现在,从昨天开始,我已经编写了可以让我走到这一步的新代码,我可以用 PHP echo ……仅此而已。
            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 have its own way to handle ajax request您可以通过下面详述的几个步骤来使用它。我将尝试在这个主题上展示一些 WP 最佳实践 - 因为可能有更快/更容易/更脏的方法来实现这一点(甚至可能通过插件),这将为您很好地介绍 Wordpress 主题/插件开发。请随时关注文档链接以更好地了解其工作原理。

1. 建立你的类别菜单
在您的代码示例中,菜单是静态的,但您最好使用动态菜单。一种解决方案是使用 get_the_category_list ,但它不允许您完全控制类别链接。我建议定义一个新的 navigation menu像这样(以下代码进入您的主题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 管理,进入外观 > 菜单,创建一个新菜单,为其选择主题位置“类别菜单”,然后向其中添加类别。
最后一步,我们将添加 a filter为了添加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使用一个 Action 参数来识别请求,以便使用 wp_ajax_nopriv_my_action 在 functions.php 中捕获它(对于非登录用户)和 wp_ajax_my_action (对于登录用户)钩子(Hook)。
因此,在更进一步之前的一小步是使该路径 ( wp-admin/admin-ajax.php ) 在您的 JavaScript 中可访问。首先,在您的主题文件夹中创建一个我们将用于 AJAX 进程的 js 文件,假设他的名字是 ./js/categories-ajax.js .然后,在您的functions.php 中添加以下内容以enqueue这个新脚本并使路径可以通过 script localization 访问:
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');
}
有了这个,admin-ajax.php 路径将可以在你的 JS 中使用 ls.ajax_url 访问。 .

3.触发ajax请求
是时候创建 showPostsFromCategory()功能。所以让我们写入新的 category-ajax.js 文件。就我个人而言,为了避免在我的插件/主题开发中与 jQuery 发生任何可能的冲突,我喜欢总是将我的 jQuery 代码封装在 JavaScript closure 中。并通过全局变量访问函数,如下所示:
(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');
    
    现在,我们需要在函数中执行以下操作:
  • 检查类别 slug 是否有效并且是否有关联的帖子,否则显示错误。
  • Get the posts与由 JS 脚本发送的 slug 标识的类别相关联。
  • 循环浏览帖子并使用 template part 显示每个帖子.为此,在您的主题文件夹中创建一个模板,该模板将仅包含显示 所需的 HTML/PHP。一 邮政。您可以在 template-parts/content.php 中的默认 wordpress 主题 (twentysixteen) 中看到此类模板的示例。 .在您的主题中执行相同类型的文件 - 也许已经有一个。您也需要更新您的存档模板以使用模板部分。这个很简单,去掉用于显示帖子的代码循环并将其替换为:
     <?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_field , get_category_by_slug , get_posts , setup_postdata get_template_part .

    请注意,这不支持分页。如果您需要这个,请查看 this answer我提出了这件事。

    进一步阅读
  • How to use AJAX in Wordpress
  • Understanding get_template_part
  • 关于javascript - 在没有页面加载的情况下从 "sort posts by category"菜单更改 <div> 内的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36379500/

    相关文章:

    javascript - 在 Javascript 中使用变量作为对象成员名称

    javascript - AngularJS 类型错误 : "track" is not a function

    javascript - 检查值是否是 JavaScript 中的对象

    php - 从部分英国邮政编码返回的结果不正确

    php - 使用 PHP PDO 将同一 mysql 列中的值打印到多个列中

    c# - 如何在 MVC 3 中通过 jQuery 加载传递对象数组?

    javascript - SortableJS 保持不可拖动项目固定

    javascript - 将 JSON 文件传递​​到 php 服务器,然后将其中的数据保存到 Mysql DB

    javascript - 从 nginclude 调用父作用域上的函数

    php - Symfony 2 根据用户代理属性加载不同的模板