mirror of
https://github.com/mashirozx/sakura.git
synced 2024-11-22 23:08:14 +08:00
Add tags and categories page
wip tags & categories
This commit is contained in:
parent
e9d5c98b6d
commit
6f396c25ba
@ -13,6 +13,7 @@ new \Sakura\Helpers\WhoopsHelper();
|
|||||||
new \Sakura\Helpers\ViteRequireHelper();
|
new \Sakura\Helpers\ViteRequireHelper();
|
||||||
new \Sakura\Helpers\CustomMenuMetaFieldsHelper();
|
new \Sakura\Helpers\CustomMenuMetaFieldsHelper();
|
||||||
new \Sakura\Helpers\CommentHelper();
|
new \Sakura\Helpers\CommentHelper();
|
||||||
|
new \Sakura\Helpers\PostQueryHelper('post');
|
||||||
|
|
||||||
new \Sakura\Routers\ApiRouter();
|
new \Sakura\Routers\ApiRouter();
|
||||||
new \Sakura\Routers\PagesRouter();
|
new \Sakura\Routers\PagesRouter();
|
||||||
|
51
app/helpers/post-query-helper.php
Normal file
51
app/helpers/post-query-helper.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Sakura\Helpers;
|
||||||
|
|
||||||
|
class PostQueryHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Post type.
|
||||||
|
*
|
||||||
|
* @since 5.0.0
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $post_type;
|
||||||
|
|
||||||
|
public function __construct(string $post_type)
|
||||||
|
{
|
||||||
|
$this->post_type = $post_type;
|
||||||
|
add_filter("rest_{$post_type}_query", [$this, 'filter_rest_post_query'], 10, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter rest posts by category slug
|
||||||
|
*
|
||||||
|
* @param array $args
|
||||||
|
* @param WP_Rest_Rquest $request
|
||||||
|
* @return array $args
|
||||||
|
*/
|
||||||
|
public function filter_rest_post_query($args, $request)
|
||||||
|
{
|
||||||
|
$args['tax_query'] = [];
|
||||||
|
|
||||||
|
$taxonomies = wp_list_filter(get_object_taxonomies($this->post_type, 'objects'), array('show_in_rest' => true));
|
||||||
|
|
||||||
|
foreach ($taxonomies as $taxonomy) {
|
||||||
|
$base = !empty($taxonomy->rest_base) ? $taxonomy->rest_base : $taxonomy->name;
|
||||||
|
|
||||||
|
if (!isset($request["{$base}_slug"])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($args['tax_query'], [
|
||||||
|
'taxonomy' => $taxonomy->name,
|
||||||
|
'field' => 'slug',
|
||||||
|
'terms' => explode(',', $request["{$base}_slug"]),
|
||||||
|
'include_children' => true,
|
||||||
|
'operator' => 'IN',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return $args;
|
||||||
|
}
|
||||||
|
}
|
58
app/helpers/rest-api-filter-helper.php
Normal file
58
app/helpers/rest-api-filter-helper.php
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Sakura\Helpers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use apply_filters( "rest_{$this->post_type}_query", array $args, WP_REST_Request $request ) or filter instead
|
||||||
|
*/
|
||||||
|
class RestApiFilterHelper
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
add_action('rest_api_init', [$this, 'rest_api_filter_add_filters']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the necessary filter to each post type
|
||||||
|
**/
|
||||||
|
public function rest_api_filter_add_filters()
|
||||||
|
{
|
||||||
|
foreach (get_post_types(array('show_in_rest' => true), 'objects') as $post_type) {
|
||||||
|
add_filter('rest_' . $post_type->name . '_query', [$this, 'rest_api_filter_add_filter_param'], 10, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the filter parameter
|
||||||
|
*
|
||||||
|
* @param array $args The query arguments.
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return array $args.
|
||||||
|
**/
|
||||||
|
public function rest_api_filter_add_filter_param($args, $request)
|
||||||
|
{
|
||||||
|
// Bail out if no filter parameter is set.
|
||||||
|
if (empty($request['filter']) || !is_array($request['filter'])) {
|
||||||
|
return $args;
|
||||||
|
}
|
||||||
|
|
||||||
|
$filter = $request['filter'];
|
||||||
|
|
||||||
|
if (isset($filter['posts_per_page']) && ((int) $filter['posts_per_page'] >= 1 && (int) $filter['posts_per_page'] <= 100)) {
|
||||||
|
$args['posts_per_page'] = $filter['posts_per_page'];
|
||||||
|
}
|
||||||
|
|
||||||
|
global $wp;
|
||||||
|
$vars = apply_filters('rest_query_vars', $wp->public_query_vars);
|
||||||
|
|
||||||
|
// Allow valid meta query vars.
|
||||||
|
$vars = array_unique(array_merge($vars, array('meta_query', 'meta_key', 'meta_value', 'meta_compare')));
|
||||||
|
|
||||||
|
foreach ($vars as $var) {
|
||||||
|
if (isset($filter[$var])) {
|
||||||
|
$args[$var] = $filter[$var];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $args;
|
||||||
|
}
|
||||||
|
}
|
357
app/lib/class-wp-rest-posts-controller.php
Normal file
357
app/lib/class-wp-rest-posts-controller.php
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Sakura\Lib;
|
||||||
|
|
||||||
|
use WP_REST_Posts_Controller;
|
||||||
|
use WP_REST_Request;
|
||||||
|
use WP_Error;
|
||||||
|
use WP_Query;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use apply_filters( "rest_{$this->post_type}_query", array $args, WP_REST_Request $request ) instead
|
||||||
|
*/
|
||||||
|
class ClassWpRestPostsController extends WP_REST_Posts_Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Retrieves a collection of posts.
|
||||||
|
* Source: https://github.com/WordPress/wordpress-develop/blob/master/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
|
||||||
|
* Memo: only change $registered = $this->get_collection_params_mod();
|
||||||
|
* Based on commit 5383af8
|
||||||
|
*
|
||||||
|
* @since 4.7.0
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
|
||||||
|
*/
|
||||||
|
public function get_items($request)
|
||||||
|
{
|
||||||
|
// Ensure a search string is set in case the orderby is set to 'relevance'.
|
||||||
|
if (!empty($request['orderby']) && 'relevance' === $request['orderby'] && empty($request['search'])) {
|
||||||
|
return new WP_Error(
|
||||||
|
'rest_no_search_term_defined',
|
||||||
|
__('You need to define a search term to order by relevance.'),
|
||||||
|
array('status' => 400)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure an include parameter is set in case the orderby is set to 'include'.
|
||||||
|
if (!empty($request['orderby']) && 'include' === $request['orderby'] && empty($request['include'])) {
|
||||||
|
return new WP_Error(
|
||||||
|
'rest_orderby_include_missing_include',
|
||||||
|
__('You need to define an include parameter to order by include.'),
|
||||||
|
array('status' => 400)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the list of registered collection query parameters.
|
||||||
|
$registered = $this->get_collection_params_mod();
|
||||||
|
$args = array();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This array defines mappings between public API query parameters whose
|
||||||
|
* values are accepted as-passed, and their internal WP_Query parameter
|
||||||
|
* name equivalents (some are the same). Only values which are also
|
||||||
|
* present in $registered will be set.
|
||||||
|
*/
|
||||||
|
$parameter_mappings = array(
|
||||||
|
'author' => 'author__in',
|
||||||
|
'author_exclude' => 'author__not_in',
|
||||||
|
'exclude' => 'post__not_in',
|
||||||
|
'include' => 'post__in',
|
||||||
|
'menu_order' => 'menu_order',
|
||||||
|
'offset' => 'offset',
|
||||||
|
'order' => 'order',
|
||||||
|
'orderby' => 'orderby',
|
||||||
|
'page' => 'paged',
|
||||||
|
'parent' => 'post_parent__in',
|
||||||
|
'parent_exclude' => 'post_parent__not_in',
|
||||||
|
'search' => 's',
|
||||||
|
'slug' => 'post_name__in',
|
||||||
|
'status' => 'post_status',
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For each known parameter which is both registered and present in the request,
|
||||||
|
* set the parameter's value on the query $args.
|
||||||
|
*/
|
||||||
|
foreach ($parameter_mappings as $api_param => $wp_param) {
|
||||||
|
if (isset($registered[$api_param], $request[$api_param])) {
|
||||||
|
$args[$wp_param] = $request[$api_param];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for & assign any parameters which require special handling or setting.
|
||||||
|
$args['date_query'] = array();
|
||||||
|
|
||||||
|
if (isset($registered['before'], $request['before'])) {
|
||||||
|
$args['date_query'][] = array(
|
||||||
|
'before' => $request['before'],
|
||||||
|
'column' => 'post_date',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($registered['modified_before'], $request['modified_before'])) {
|
||||||
|
$args['date_query'][] = array(
|
||||||
|
'before' => $request['modified_before'],
|
||||||
|
'column' => 'post_modified',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($registered['after'], $request['after'])) {
|
||||||
|
$args['date_query'][] = array(
|
||||||
|
'after' => $request['after'],
|
||||||
|
'column' => 'post_date',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($registered['modified_after'], $request['modified_after'])) {
|
||||||
|
$args['date_query'][] = array(
|
||||||
|
'after' => $request['modified_after'],
|
||||||
|
'column' => 'post_modified',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure our per_page parameter overrides any provided posts_per_page filter.
|
||||||
|
if (isset($registered['per_page'])) {
|
||||||
|
$args['posts_per_page'] = $request['per_page'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($registered['sticky'], $request['sticky'])) {
|
||||||
|
$sticky_posts = get_option('sticky_posts', array());
|
||||||
|
if (!is_array($sticky_posts)) {
|
||||||
|
$sticky_posts = array();
|
||||||
|
}
|
||||||
|
if ($request['sticky']) {
|
||||||
|
/*
|
||||||
|
* As post__in will be used to only get sticky posts,
|
||||||
|
* we have to support the case where post__in was already
|
||||||
|
* specified.
|
||||||
|
*/
|
||||||
|
$args['post__in'] = $args['post__in'] ? array_intersect($sticky_posts, $args['post__in']) : $sticky_posts;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we intersected, but there are no post IDs in common,
|
||||||
|
* WP_Query won't return "no posts" for post__in = array()
|
||||||
|
* so we have to fake it a bit.
|
||||||
|
*/
|
||||||
|
if (!$args['post__in']) {
|
||||||
|
$args['post__in'] = array(0);
|
||||||
|
}
|
||||||
|
} elseif ($sticky_posts) {
|
||||||
|
/*
|
||||||
|
* As post___not_in will be used to only get posts that
|
||||||
|
* are not sticky, we have to support the case where post__not_in
|
||||||
|
* was already specified.
|
||||||
|
*/
|
||||||
|
$args['post__not_in'] = array_merge($args['post__not_in'], $sticky_posts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$args = $this->prepare_tax_query($args, $request);
|
||||||
|
|
||||||
|
// Force the post_type argument, since it's not a user input variable.
|
||||||
|
$args['post_type'] = $this->post_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters WP_Query arguments when querying posts via the REST API.
|
||||||
|
*
|
||||||
|
* The dynamic portion of the hook name, `$this->post_type`, refers to the post type slug.
|
||||||
|
*
|
||||||
|
* Possible hook names include:
|
||||||
|
*
|
||||||
|
* - `rest_post_query`
|
||||||
|
* - `rest_page_query`
|
||||||
|
* - `rest_attachment_query`
|
||||||
|
*
|
||||||
|
* Enables adding extra arguments or setting defaults for a post collection request.
|
||||||
|
*
|
||||||
|
* @since 4.7.0
|
||||||
|
* @since 5.7.0 Moved after the `tax_query` query arg is generated.
|
||||||
|
*
|
||||||
|
* @link https://developer.wordpress.org/reference/classes/wp_query/
|
||||||
|
*
|
||||||
|
* @param array $args Array of arguments for WP_Query.
|
||||||
|
* @param WP_REST_Request $request The REST API request.
|
||||||
|
*/
|
||||||
|
$args = apply_filters("rest_{$this->post_type}_query", $args, $request);
|
||||||
|
$query_args = $this->prepare_items_query($args, $request);
|
||||||
|
$posts_query = new WP_Query();
|
||||||
|
$query_result = $posts_query->query($query_args);
|
||||||
|
|
||||||
|
// Allow access to all password protected posts if the context is edit.
|
||||||
|
if ('edit' === $request['context']) {
|
||||||
|
add_filter('post_password_required', array($this, 'check_password_required'), 10, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
$posts = array();
|
||||||
|
|
||||||
|
foreach ($query_result as $post) {
|
||||||
|
if (!$this->check_read_permission($post)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->prepare_item_for_response($post, $request);
|
||||||
|
$posts[] = $this->prepare_response_for_collection($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset filter.
|
||||||
|
if ('edit' === $request['context']) {
|
||||||
|
remove_filter('post_password_required', array($this, 'check_password_required'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$page = (int) $query_args['paged'];
|
||||||
|
$total_posts = $posts_query->found_posts;
|
||||||
|
|
||||||
|
if ($total_posts < 1) {
|
||||||
|
// Out-of-bounds, run the query again without LIMIT for total count.
|
||||||
|
unset($query_args['paged']);
|
||||||
|
|
||||||
|
$count_query = new WP_Query();
|
||||||
|
$count_query->query($query_args);
|
||||||
|
$total_posts = $count_query->found_posts;
|
||||||
|
}
|
||||||
|
|
||||||
|
$max_pages = ceil($total_posts / (int) $posts_query->query_vars['posts_per_page']);
|
||||||
|
|
||||||
|
if ($page > $max_pages && $total_posts > 0) {
|
||||||
|
return new WP_Error(
|
||||||
|
'rest_post_invalid_page_number',
|
||||||
|
__('The page number requested is larger than the number of pages available.'),
|
||||||
|
array('status' => 400)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = rest_ensure_response($posts);
|
||||||
|
|
||||||
|
$response->header('X-WP-Total', (int) $total_posts);
|
||||||
|
$response->header('X-WP-TotalPages', (int) $max_pages);
|
||||||
|
|
||||||
|
$request_params = $request->get_query_params();
|
||||||
|
$base = add_query_arg(urlencode_deep($request_params), rest_url(sprintf('%s/%s', $this->namespace, $this->rest_base)));
|
||||||
|
|
||||||
|
if ($page > 1) {
|
||||||
|
$prev_page = $page - 1;
|
||||||
|
|
||||||
|
if ($prev_page > $max_pages) {
|
||||||
|
$prev_page = $max_pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
$prev_link = add_query_arg('page', $prev_page, $base);
|
||||||
|
$response->link_header('prev', $prev_link);
|
||||||
|
}
|
||||||
|
if ($max_pages > $page) {
|
||||||
|
$next_page = $page + 1;
|
||||||
|
$next_link = add_query_arg('page', $next_page, $base);
|
||||||
|
|
||||||
|
$response->link_header('next', $next_link);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepares the 'tax_query' for a collection of posts.
|
||||||
|
*
|
||||||
|
* @since 5.7.0
|
||||||
|
*
|
||||||
|
* @param array $args WP_Query arguments.
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return array Updated query arguments.
|
||||||
|
*/
|
||||||
|
private function prepare_tax_query(array $args, WP_REST_Request $request)
|
||||||
|
{
|
||||||
|
$relation = $request['tax_relation'];
|
||||||
|
|
||||||
|
if ($relation) {
|
||||||
|
$args['tax_query'] = array('relation' => $relation);
|
||||||
|
}
|
||||||
|
|
||||||
|
$taxonomies = wp_list_filter(
|
||||||
|
get_object_taxonomies($this->post_type, 'objects'),
|
||||||
|
array('show_in_rest' => true)
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($taxonomies as $taxonomy) {
|
||||||
|
$base = !empty($taxonomy->rest_base) ? $taxonomy->rest_base : $taxonomy->name;
|
||||||
|
|
||||||
|
$tax_include = $request[$base];
|
||||||
|
$tax_exclude = $request[$base . '_exclude'];
|
||||||
|
|
||||||
|
if ($tax_include) {
|
||||||
|
$terms = array();
|
||||||
|
$include_children = false;
|
||||||
|
$operator = 'IN';
|
||||||
|
|
||||||
|
if (rest_is_array($tax_include)) {
|
||||||
|
$terms = $tax_include;
|
||||||
|
} elseif (rest_is_object($tax_include)) {
|
||||||
|
$terms = empty($tax_include['terms']) ? array() : $tax_include['terms'];
|
||||||
|
$include_children = !empty($tax_include['include_children']);
|
||||||
|
|
||||||
|
if (isset($tax_include['operator']) && 'AND' === $tax_include['operator']) {
|
||||||
|
$operator = 'AND';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($terms) {
|
||||||
|
$args['tax_query'][] = array(
|
||||||
|
'taxonomy' => $taxonomy->name,
|
||||||
|
'field' => 'slug', // 'term_id',
|
||||||
|
'terms' => $terms,
|
||||||
|
'include_children' => $include_children,
|
||||||
|
'operator' => $operator,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($tax_exclude) {
|
||||||
|
$terms = array();
|
||||||
|
$include_children = false;
|
||||||
|
|
||||||
|
if (rest_is_array($tax_exclude)) {
|
||||||
|
$terms = $tax_exclude;
|
||||||
|
} elseif (rest_is_object($tax_exclude)) {
|
||||||
|
$terms = empty($tax_exclude['terms']) ? array() : $tax_exclude['terms'];
|
||||||
|
$include_children = !empty($tax_exclude['include_children']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($terms) {
|
||||||
|
$args['tax_query'][] = array(
|
||||||
|
'taxonomy' => $taxonomy->name,
|
||||||
|
'field' => 'term_id',
|
||||||
|
'terms' => $terms,
|
||||||
|
'include_children' => $include_children,
|
||||||
|
'operator' => 'NOT IN',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_public_item_schema_mod()
|
||||||
|
{
|
||||||
|
$schema = $this->get_public_item_schema();
|
||||||
|
$schema['properties']['categories']['items']['type'] = [
|
||||||
|
"string",
|
||||||
|
"integer"
|
||||||
|
];
|
||||||
|
return $schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_collection_params_mod()
|
||||||
|
{
|
||||||
|
$params = $this->get_collection_params();
|
||||||
|
$new = [
|
||||||
|
"title" => "Term Slug",
|
||||||
|
"description" => "Match terms with the listed Slug.",
|
||||||
|
"type" => "array",
|
||||||
|
"items" => [
|
||||||
|
"type" => "string"
|
||||||
|
]
|
||||||
|
];
|
||||||
|
$params['categories']['oneOf'][0] = $new;
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,7 @@ use Sakura\Controllers\CategoryController;
|
|||||||
use Sakura\Controllers\TagController;
|
use Sakura\Controllers\TagController;
|
||||||
use Sakura\Controllers\CommentController;
|
use Sakura\Controllers\CommentController;
|
||||||
use Sakura\Lib\ClassWpRestCommentsController;
|
use Sakura\Lib\ClassWpRestCommentsController;
|
||||||
|
use Sakura\Lib\ClassWpRestPostsController;
|
||||||
|
|
||||||
class ApiRouter extends WP_REST_Controller
|
class ApiRouter extends WP_REST_Controller
|
||||||
{
|
{
|
||||||
@ -135,6 +136,29 @@ class ApiRouter extends WP_REST_Controller
|
|||||||
'schema' => array($this, 'get_public_item_schema'),
|
'schema' => array($this, 'get_public_item_schema'),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// @deprecated using PostQueryHelper instaed
|
||||||
|
// $rest_posts_controller = new ClassWpRestPostsController('post');
|
||||||
|
// custom get posts by category slugs
|
||||||
|
// register_rest_route(
|
||||||
|
// $this->namespace,
|
||||||
|
// '/posts',
|
||||||
|
// array(
|
||||||
|
// array(
|
||||||
|
// 'methods' => WP_REST_Server::READABLE,
|
||||||
|
// 'callback' => array($rest_posts_controller, 'get_items'),
|
||||||
|
// 'permission_callback' => array($rest_posts_controller, 'get_items_permissions_check'),
|
||||||
|
// 'args' => $rest_posts_controller->get_collection_params_mod(),
|
||||||
|
// ),
|
||||||
|
// array(
|
||||||
|
// 'methods' => WP_REST_Server::CREATABLE,
|
||||||
|
// 'callback' => array($rest_posts_controller, 'create_item'),
|
||||||
|
// 'permission_callback' => array($rest_posts_controller, 'create_item_permissions_check'),
|
||||||
|
// 'args' => $rest_posts_controller->get_endpoint_args_for_item_schema(WP_REST_Server::CREATABLE),
|
||||||
|
// ),
|
||||||
|
// 'schema' => array($rest_posts_controller, 'get_public_item_schema_mod'),
|
||||||
|
// )
|
||||||
|
// );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import request, { AxiosPromise } from '@/utils/http'
|
import request, { AxiosPromise } from '@/utils/http'
|
||||||
import snakecaseKeys from 'snakecase-keys'
|
import snakecaseKeys from 'snakecase-keys'
|
||||||
|
|
||||||
type WpPostObjectFilter = number | string | number[] | string[]
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /wp/v2/posts
|
* GET /wp/v2/posts
|
||||||
* https://developer.wordpress.org/rest-api/reference/posts/#arguments
|
* https://developer.wordpress.org/rest-api/reference/posts/#arguments
|
||||||
@ -16,8 +14,8 @@ export interface GetPostParams {
|
|||||||
author?: string | number
|
author?: string | number
|
||||||
authorExclude?: string | number
|
authorExclude?: string | number
|
||||||
before?: string // ISO8601
|
before?: string // ISO8601
|
||||||
exclude?: WpPostObjectFilter // TODO: check this
|
exclude?: number | number[]
|
||||||
include?: WpPostObjectFilter // TODO: check this
|
include?: number | number[]
|
||||||
offset?: number
|
offset?: number
|
||||||
order?: 'asc' | 'desc' // default: desc
|
order?: 'asc' | 'desc' // default: desc
|
||||||
orderby?:
|
orderby?:
|
||||||
@ -31,13 +29,15 @@ export interface GetPostParams {
|
|||||||
| 'slug'
|
| 'slug'
|
||||||
| 'include_slugs'
|
| 'include_slugs'
|
||||||
| 'title' // default: date
|
| 'title' // default: date
|
||||||
slug?: WpPostObjectFilter // TODO: check this
|
slug?: string
|
||||||
status?: string // default: 'publish'
|
status?: string // default: 'publish'
|
||||||
taxRelation?: 'AND' | 'OR'
|
taxRelation?: 'AND' | 'OR'
|
||||||
categories?: WpPostObjectFilter // TODO: check this
|
categories?: number | number[]
|
||||||
categoriesExclude?: WpPostObjectFilter // TODO: check this
|
categoriesExclude?: number | number[]
|
||||||
tags?: WpPostObjectFilter // TODO: check this
|
categoriesSlug?: string
|
||||||
tagsExclude?: WpPostObjectFilter // TODO: check this
|
tags?: number | number[]
|
||||||
|
tagsExclude?: number | number[]
|
||||||
|
tagsSlug?: string
|
||||||
sticky?: boolean // TODO: check this
|
sticky?: boolean // TODO: check this
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,8 +48,10 @@ export interface GetPageParams
|
|||||||
| 'taxRelation'
|
| 'taxRelation'
|
||||||
| 'categories'
|
| 'categories'
|
||||||
| 'categoriesExclude'
|
| 'categoriesExclude'
|
||||||
|
| 'categoriesSlug'
|
||||||
| 'tags'
|
| 'tags'
|
||||||
| 'tagsExclude'
|
| 'tagsExclude'
|
||||||
|
| 'tagsSlug'
|
||||||
| 'sticky'
|
| 'sticky'
|
||||||
> {
|
> {
|
||||||
menuOrder: any // TODO: check this
|
menuOrder: any // TODO: check this
|
||||||
@ -79,8 +81,8 @@ export interface GetCommentParams {
|
|||||||
authorExclude?: string | number
|
authorExclude?: string | number
|
||||||
author_email?: string
|
author_email?: string
|
||||||
before?: string // ISO8601
|
before?: string // ISO8601
|
||||||
exclude?: WpPostObjectFilter // TODO: check this
|
exclude?: number | number[] // TODO: check this
|
||||||
include?: WpPostObjectFilter // TODO: check this
|
include?: number | number[] // TODO: check this
|
||||||
offset?: number
|
offset?: number
|
||||||
order?: 'asc' | 'desc' // default: desc
|
order?: 'asc' | 'desc' // default: desc
|
||||||
orderby?: 'date' | 'date_gmt' | 'id' | 'include' | 'post' | 'parent' | 'type' // default: date
|
orderby?: 'date' | 'date_gmt' | 'id' | 'include' | 'post' | 'parent' | 'type' // default: date
|
||||||
|
@ -8,7 +8,13 @@
|
|||||||
@error="handleError"
|
@error="handleError"
|
||||||
@load="handleLoad"
|
@load="handleLoad"
|
||||||
/>
|
/>
|
||||||
<img v-if="placeholderImage" class="default" :src="placeholderImage" :alt="$props.alt" />
|
<img
|
||||||
|
v-if="placeholderImage"
|
||||||
|
class="default"
|
||||||
|
:src="placeholderImage"
|
||||||
|
:alt="$props.alt"
|
||||||
|
:draggable="$props.draggable"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -29,6 +29,12 @@ export default defineComponent({
|
|||||||
page: { type: Number, default: 1 },
|
page: { type: Number, default: 1 },
|
||||||
perPage: { type: Number, default: 10 },
|
perPage: { type: Number, default: 10 },
|
||||||
autoLoad: { type: Boolean, default: true },
|
autoLoad: { type: Boolean, default: true },
|
||||||
|
fetchParameters: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const [listContainerRef, setListContainerRef] = useElementRef()
|
const [listContainerRef, setListContainerRef] = useElementRef()
|
||||||
@ -64,7 +70,12 @@ export default defineComponent({
|
|||||||
fetchPost({
|
fetchPost({
|
||||||
state: postsStore,
|
state: postsStore,
|
||||||
namespace: props.namespace,
|
namespace: props.namespace,
|
||||||
opts: { page: currentPage.value, perPage: props.perPage, context: 'embed' },
|
opts: {
|
||||||
|
page: currentPage.value,
|
||||||
|
perPage: props.perPage,
|
||||||
|
context: 'embed',
|
||||||
|
...props.fetchParameters,
|
||||||
|
},
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
get()
|
get()
|
||||||
setFetchStatus('done')
|
setFetchStatus('done')
|
@ -1,11 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<h1>Category</h1>
|
<Base class="base">
|
||||||
|
<div class="main__content">
|
||||||
|
<div class="content__wrapper">
|
||||||
|
<PostThumbList :namespace="namespace" :fetchParameters="fetchParameters"></PostThumbList>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Base>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
|
import { useRoute } from '@/hooks'
|
||||||
|
import Base from '@/layouts/Base.vue'
|
||||||
|
import PostThumbList from '@/components/lists/postThumbList/PostThumbList.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {},
|
components: { Base, PostThumbList },
|
||||||
|
setup() {
|
||||||
|
const route = useRoute()
|
||||||
|
const { cat1, cat2, cat3 } = route.params
|
||||||
|
const categories = [cat1, cat2, cat3].filter((cat) => cat)
|
||||||
|
const namespace = ['categories', ...categories].join('-')
|
||||||
|
const fetchParameters = { categoriesSlug: categories.join(',') }
|
||||||
|
return {
|
||||||
|
namespace,
|
||||||
|
fetchParameters,
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<div class="main__content">
|
<div class="main__content">
|
||||||
<div class="cover__wrapper"> </div>
|
<div class="cover__wrapper"> </div>
|
||||||
<div class="content__wrapper">
|
<div class="content__wrapper">
|
||||||
<PostThumbList></PostThumbList>
|
<PostThumbList namespace="homepage"></PostThumbList>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Base>
|
</Base>
|
||||||
@ -11,21 +11,11 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
import { useInjector, useRoute } from '@/hooks'
|
|
||||||
import { posts } from '@/store'
|
|
||||||
import Base from '@/layouts/Base.vue'
|
import Base from '@/layouts/Base.vue'
|
||||||
import PostThumbList from '@/components/lists/postThembList/PostThumbList.vue'
|
import PostThumbList from '@/components/lists/postThumbList/PostThumbList.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { Base, PostThumbList },
|
components: { Base, PostThumbList },
|
||||||
setup() {
|
|
||||||
// const route = useRoute()
|
|
||||||
// console.log(route.params)
|
|
||||||
// const { postsStore, fetchPost } = useInjector(posts)
|
|
||||||
// fetchPost(postsStore, { perPage: 1, page: 10 }).then(async () => {
|
|
||||||
// console.log(postsStore.value)
|
|
||||||
// })
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,11 +1,32 @@
|
|||||||
<template>
|
<template>
|
||||||
<h1>Tag</h1>
|
<Base class="base">
|
||||||
|
<div class="main__content">
|
||||||
|
<div class="content__wrapper">
|
||||||
|
<PostThumbList :namespace="namespace" :fetchParameters="fetchParameters"></PostThumbList>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Base>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
|
import { useRoute } from '@/hooks'
|
||||||
|
import Base from '@/layouts/Base.vue'
|
||||||
|
import PostThumbList from '@/components/lists/postThumbList/PostThumbList.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {},
|
components: { Base, PostThumbList },
|
||||||
|
setup() {
|
||||||
|
const route = useRoute()
|
||||||
|
console.log(route.params)
|
||||||
|
|
||||||
|
const { tag } = route.params
|
||||||
|
const namespace = ['tags', tag].join('-')
|
||||||
|
const fetchParameters = { tagsSlug: tag }
|
||||||
|
return {
|
||||||
|
namespace,
|
||||||
|
fetchParameters,
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user