如何获取家长和孩子类别的所有帖子?

时间:2019-11-25 作者:Gvidas Pranauskas

我正在尝试从类别中获取所有帖子products. 我的模板如下所示:/products/PARENT_CATEGORY/CHILD_CATEGORY. 我需要的是来自每个CHILD\\u类别的所有帖子。

我尝试通过/posts?categories=28, 但它不返回帖子,因为ID为28的类别本身没有任何帖子。但它的子级,例如ID为40的类别,有一些帖子。我应该像这样访问它们吗/posts?categories=40,41,42...? 还是有其他方法?

2 个回复
SO网友:Álvaro Reneses

我有与您相同的用例—从React调用WP-API—并遇到了相同的问题。

不幸的是,WP-API不支持按父类别过滤。为了支持它,您可以扩展API的功能,添加一个新的过滤器,该过滤器将运行tax_query 幕后,类似于Faye\'s answer.

假设您有权访问Wordpress应用程序,请修改functions.php 在当前主题中添加:

// Add parent_category filter to REST API
function rest_filter_by_parent_category($args, $request) 
{
  if (isset($request[\'parent_category\'])) {
    $parent_category = sanitize_text_field($request[\'parent_category\']);
    $args[\'tax_query\'] = [
      [
        \'taxonomy\'         => \'category\', 
        \'field\'            => \'term_id\', 
        \'include_children\' => true,
        \'operator\'         => \'IN\',
        \'terms\'            => $parent_category, 
      ]
    ];
  }
  return $args;
}

add_filter(\'rest_post_query\', \'rest_filter_by_parent_category\', 10, 3);
然后,只需使用新过滤器查询API:/posts?parent_category=28

Alternative

如果无法修改functions.php 文件(例如,您正在查询外部博客),然后您可以:

获取所有类别(您可能已经在应用程序中完成)[parentId: number] => number[]categories=C1,C2... 使用反向索引

const axios = require("axios");

// Query all the categories from Wordpress
const fetchCategories = async () => {
  const params = [
    "_fields[]=id",
    "_fields[]=parent",
    // Ideally you would use a better pagination strategy
    "page=1",
    "per_page=100",
  ];

  // Using axios, but you could use native fetch or any other library
  return axios
    .get(`WORDPRESS_SITE/wp-json/wp/v2/categories?${params.join("&")}`)
    .then((result) => result.data);
};

// Build reverse index
const buildParentIndex = (categories) => {
  return categories.reduce((acc, category) => {
    const hasParent = !!category.parent; // Root categories have ID 0

    const parentId = hasParent ? category.parent : category.id;
    if (!acc[parentId]) {
      acc[parentId] = [];
    }

    if (hasParent) {
      acc[parentId].push(category.id);
    }

    return acc;
  }, {});
};

(async () => {
  // You should pre-compute & cache these, as fetching the categories
  // and building the index on every request will heavily affect
  // the latency of your request
  const categories = await fetchCategories();
  const parentIndex = buildParentIndex(categories);

  const fetchPostsByParentId = (categoryId) =>
    axios
      .get(
        `WORDPRESS_SITE/wp-json/wp/v2/posts?categories${parentIndex[
          categoryId
        ].join("&")}`
      )
      .then((result) => result.data);
})();
如果可能,我建议使用第一种方法-修改functions.php — 因为它更简单、更一致。JS替代方案可能需要缓存,以避免延迟受到影响,这会带来许多潜在问题(例如陈旧的缓存)。

Source

SO网友:Faye

我认为你不能通过这样的url查询你的帖子。

理想情况下,您应该有一个模板文件taxonomy-{taxonomyname}.php 所以在这种情况下,taxonomy-products.php

从这里开始,有几种不同的方法可以做到这一点,尽管我将使用的方法是建立这样的循环。

<?php

    $args = [
        \'post_type\'      => \'post\',
        \'posts_per_page\' => 8, // or however many you want
        \'post_status\'    => \'publish\',
        \'order\'          => \'DESC\',
        \'orderby\'        => \'date\',
        \'tax_query\'      => [ // this part will get the category and its childs
            [
                \'taxonomy\' => \'category\',
                \'terms\'    => [ \'28\' ], // parent category id
                \'field\'    => \'term_id\',
            ],
        ],
    ];

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


    // The Loop.
    if ( $the_query->have_posts() ) {
        ?>

            <?php
            while ( $the_query->have_posts() ) {

                $the_query->the_post();

                // your code for the post here like the_title and the_excerpt

            }
            ?>


        <?php
        wp_reset_postdata();
    }
    ?>