<?php
/**
* Plugin Name: Custom Content Manager
* Description: A plugin to manage custom posts, categories, and tags with custom tables.
* Version: 1.0
* Author: Your Name
* License: GPL2
*/
// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Create custom table structure
function custom_content_manager_create_tables() {
global $wpdb;
$table_name_posts = $wpdb->prefix . 'custom_posts';
$table_name_categories = $wpdb->prefix . 'custom_categories';
$table_name_tags = $wpdb->prefix . 'custom_tags';
$table_name_post_category = $wpdb->prefix . 'custom_post_category';
$table_name_post_tag = $wpdb->prefix . 'custom_post_tag';
$charset_collate = $wpdb->get_charset_collate();
// Create custom_posts table
$sql = "CREATE TABLE $table_name_posts (
id BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
post_status ENUM('publish', 'draft') DEFAULT 'draft',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) $charset_collate;";
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );
// Create custom_categories table
$sql = "CREATE TABLE $table_name_categories (
id BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
parent_id BIGINT(20) UNSIGNED DEFAULT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) $charset_collate;";
dbDelta( $sql );
// Create custom_tags table
$sql = "CREATE TABLE $table_name_tags (
id BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) $charset_collate;";
dbDelta( $sql );
// Create custom_post_category relationship table
$sql = "CREATE TABLE $table_name_post_category (
post_id BIGINT(20) UNSIGNED NOT NULL,
category_id BIGINT(20) UNSIGNED NOT NULL,
PRIMARY KEY (post_id, category_id)
) $charset_collate;";
dbDelta( $sql );
// Create custom_post_tag relationship table
$sql = "CREATE TABLE $table_name_post_tag (
post_id BIGINT(20) UNSIGNED NOT NULL,
tag_id BIGINT(20) UNSIGNED NOT NULL,
PRIMARY KEY (post_id, tag_id)
) $charset_collate;";
dbDelta( $sql );
}
register_activation_hook( __FILE__, 'custom_content_manager_create_tables' );
// Admin menu: Post, Category, and Tag page menu
function custom_content_manager_menu() {
add_menu_page( 'Custom Content Manager', 'Content Manager', 'manage_options', 'custom-content-manager', 'custom_content_manager_dashboard', 'dashicons-admin-post', 6 );
add_submenu_page( 'custom-content-manager', 'Manage Posts', 'Manage Posts', 'manage_options', 'manage-posts', 'custom_content_manager_manage_posts' );
add_submenu_page( 'custom-content-manager', 'Manage Categories', 'Manage Categories', 'manage_options', 'manage-categories', 'custom_content_manager_manage_categories' );
add_submenu_page( 'custom-content-manager', 'Manage Tags', 'Manage Tags', 'manage_options', 'manage-tags', 'custom_content_manager_manage_tags' );
}
add_action( 'admin_menu', 'custom_content_manager_menu' );
// Admin dashboard: Display console
function custom_content_manager_dashboard() {
?>
<div class="wrap">
<h1>Welcome to Custom Content Manager</h1>
<p>Use the submenu to manage your posts, categories, and tags.</p>
</div>
<?php
}
// Admin interface: Display Posts list (using wp_list_table)
function custom_content_manager_manage_posts() {
$post_list_table = new Custom_Post_List_Table();
$post_list_table->prepare_items();
?>
<div class="wrap">
<h1>Manage Posts</h1>
<form method="post">
<?php $post_list_table->display(); ?>
</form>
<h2>Add New Post</h2>
<form method="post" action="">
<table class="form-table">
<tr>
<th><label for="post_title">Title</label></th>
<td><input type="text" id="post_title" name="post_title" class="regular-text" required /></td>
</tr>
<tr>
<th><label for="post_content">Content</label></th>
<td><textarea id="post_content" name="post_content" rows="5" class="large-text" required></textarea></td>
</tr>
<tr>
<th><label for="post_status">Status</label></th>
<td>
<select name="post_status" id="post_status">
<option value="publish">Publish</option>
<option value="draft">Draft</option>
</select>
</td>
</tr>
<tr>
<th><label for="post_categories">Categories</label></th>
<td>
<select name="post_categories[]" multiple="multiple" id="post_categories" style="width: 100%;">
<?php
global $wpdb;
$categories = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}custom_categories" );
foreach ( $categories as $category ) {
echo '<option value="' . esc_attr( $category->id ) . '">' . esc_html( $category->name ) . '</option>';
}
?>
</select>
</td>
</tr>
<tr>
<th><label for="post_tags">Tags</label></th>
<td>
<select name="post_tags[]" multiple="multiple" id="post_tags" style="width: 100%;">
<?php
$tags = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}custom_tags" );
foreach ( $tags as $tag ) {
echo '<option value="' . esc_attr( $tag->id ) . '">' . esc_html( $tag->name ) . '</option>';
}
?>
</select>
</td>
</tr>
</table>
<p><input type="submit" name="submit_post" value="Add Post" class="button-primary" /></p>
</form>
</div>
<?php
// Handle form submission
if ( isset( $_POST['submit_post'] ) ) {
$title = sanitize_text_field( $_POST['post_title'] );
$content = sanitize_textarea_field( $_POST['post_content'] );
$status = sanitize_text_field( $_POST['post_status'] );
$categories = isset( $_POST['post_categories'] ) ? $_POST['post_categories'] : array();
$tags = isset( $_POST['post_tags'] ) ? $_POST['post_tags'] : array();
// Insert into custom_posts table
$wpdb->insert(
$wpdb->prefix . 'custom_posts',
array(
'title' => $title,
'content' => $content,
'post_status'=> $status,
),
array( '%s', '%s', '%s' )
);
$post_id = $wpdb->insert_id;
// Associate Categories
foreach ( $categories as $category_id ) {
$wpdb->insert(
$wpdb->prefix . 'custom_post_category',
array( 'post_id' => $post_id, 'category_id' => $category_id ),
array( '%d', '%d' )
);
}
// Associate Tags
foreach ( $tags as $tag_id ) {
$wpdb->insert(
$wpdb->prefix . 'custom_post_tag',
array( 'post_id' => $post_id, 'tag_id' => $tag_id ),
array( '%d', '%d' )
);
}
echo '<div class="updated"><p>Post added successfully!</p></div>';
}
}
// Admin interface: Display Categories list (using wp_list_table)
function custom_content_manager_manage_categories() {
$category_list_table = new Custom_Category_List_Table();
$category_list_table->prepare_items();
?>
<div class="wrap">
<h1>Manage Categories</h1>
<form method="post">
<?php $category_list_table->display(); ?>
</form>
<h2>Add New Category</h2>
<form method="post" action="">
<table class="form-table">
<tr>
<th><label for="category_name">Name</label></th>
<td><input type="text" id="category_name" name="category_name" class="regular-text" required /></td>
</tr>
<tr>
<th><label for="category_parent">Parent Category</label></th>
<td>
<select name="category_parent" id="category_parent">
<option value="">None</option>
<?php
global $wpdb;
$categories = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}custom_categories" );
foreach ( $categories as $category ) {
echo '<option value="' . esc_attr( $category->id ) . '">' . esc_html( $category->name ) . '</option>';
}
?>
</select>
</td>
</tr>
</table>
<p><input type="submit" name="submit_category" value="Add Category" class="button-primary" /></p>
</form>
</div>
<?php
// Handle form submission
if ( isset( $_POST['submit_category'] ) ) {
$name = sanitize_text_field( $_POST['category_name'] );
$parent = isset( $_POST['category_parent'] ) ? intval( $_POST['category_parent'] ) : null;
// Insert into custom_categories table
$wpdb->insert(
$wpdb->prefix . 'custom_categories',
array(
'name' => $name,
'parent_id' => $parent,
),
array( '%s', '%d' )
);
echo '<div class="updated"><p>Category added successfully!</p></div>';
}
}
// Admin interface: Display Tags list (using wp_list_table)
function custom_content_manager_manage_tags() {
$tag_list_table = new Custom_Tag_List_Table();
$tag_list_table->prepare_items();
?>
<div class="wrap">
<h1>Manage Tags</h1>
<form method="post">
<?php $tag_list_table->display(); ?>
</form>
<h2>Add New Tag</h2>
<form method="post" action="">
<table class="form-table">
<tr>
<th><label for="tag_name">Name</label></th>
<td><input type="text" id="tag_name" name="tag_name" class="regular-text" required /></td>
</tr>
</table>
<p><input type="submit" name="submit_tag" value="Add Tag" class="button-primary" /></p>
</form>
</div>
<?php
// Handle form submission
if ( isset( $_POST['submit_tag'] ) ) {
$name = sanitize_text_field( $_POST['tag_name'] );
// Insert into custom_tags table
$wpdb->insert(
$wpdb->prefix . 'custom_tags',
array(
'name' => $name,
),
array( '%s' )
);
echo '<div class="updated"><p>Tag added successfully!</p></div>';
}
}
// WP_List_Table implementation class: Custom Post List Table
if( !class_exists( 'Custom_Post_List_Table' ) ) {
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
class Custom_Post_List_Table extends WP_List_Table {
function __construct() {
parent::__construct( array(
'singular' => 'post',
'plural' => 'posts',
'ajax' => false
) );
}
function get_columns() {
return array(
'cb' => '<input type="checkbox" />',
'title' => 'Title',
'created_at'=> 'Created At'
);
}
function prepare_items() {
global $wpdb;
$per_page = $this->get_items_per_page( 'posts_per_page', 10 );
$start = ( $this->get_pagenum() - 1 ) * $per_page;
$query = "SELECT * FROM {$wpdb->prefix}custom_posts ORDER BY created_at DESC LIMIT %d, %d";
$items = $wpdb->get_results( $wpdb->prepare( $query, $start, $per_page ) );
$this->items = $items;
$total_items = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}custom_posts" );
$this->set_pagination_args( array(
'total_items' => $total_items,
'per_page' => $per_page,
'total_pages' => ceil( $total_items / $per_page ),
) );
}
function column_default( $item, $column_name ) {
switch ( $column_name ) {
case 'title':
return esc_html( $item->title );
case 'created_at':
return esc_html( $item->created_at );
default:
return print_r( $item, true );
}
}
function column_cb( $item ) {
return sprintf(
'<input type="checkbox" name="post_ids[]" value="%d" />',
$item->id
);
}
}
}
// WP_List_Table implementation class: Custom Category List Table
if( !class_exists( 'Custom_Category_List_Table' ) ) {
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
class Custom_Category_List_Table extends WP_List_Table {
function __construct() {
parent::__construct( array(
'singular' => 'category',
'plural' => 'categories',
'ajax' => false
) );
}
function get_columns() {
return array(
'cb' => '<input type="checkbox" />',
'name' => 'Name',
'created_at'=> 'Created At'
);
}
function prepare_items() {
global $wpdb;
$per_page = $this->get_items_per_page( 'categories_per_page', 10 );
$start = ( $this->get_pagenum() - 1 ) * $per_page;
$query = "SELECT * FROM {$wpdb->prefix}custom_categories ORDER BY created_at DESC LIMIT %d, %d";
$items = $wpdb->get_results( $wpdb->prepare( $query, $start, $per_page ) );
$this->items = $items;
$total_items = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}custom_categories" );
$this->set_pagination_args( array(
'total_items' => $total_items,
'per_page' => $per_page,
'total_pages' => ceil( $total_items / $per_page ),
) );
}
function column_default( $item, $column_name ) {
switch ( $column_name ) {
case 'name':
return esc_html( $item->name );
case 'created_at':
return esc_html( $item->created_at );
default:
return print_r( $item, true );
}
}
function column_cb( $item ) {
return sprintf(
'<input type="checkbox" name="category_ids[]" value="%d" />',
$item->id
);
}
}
}
// WP_List_Table implementation class: Custom Tag List Table
if( !class_exists( 'Custom_Tag_List_Table' ) ) {
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
class Custom_Tag_List_Table extends WP_List_Table {
function __construct() {
parent::__construct( array(
'singular' => 'tag',
'plural' => 'tags',
'ajax' => false
) );
}
function get_columns() {
return array(
'cb' => '<input type="checkbox" />',
'name' => 'Name',
'created_at'=> 'Created At'
);
}
function prepare_items() {
global $wpdb;
$per_page = $this->get_items_per_page( 'tags_per_page', 10 );
$start = ( $this->get_pagenum() - 1 ) * $per_page;
$query = "SELECT * FROM {$wpdb->prefix}custom_tags ORDER BY created_at DESC LIMIT %d, %d";
$items = $wpdb->get_results( $wpdb->prepare( $query, $start, $per_page ) );
$this->items = $items;
$total_items = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}custom_tags" );
$this->set_pagination_args( array(
'total_items' => $total_items,
'per_page' => $per_page,
'total_pages' => ceil( $total_items / $per_page ),
) );
}
function column_default( $item, $column_name ) {
switch ( $column_name ) {
case 'name':
return esc_html( $item->name );
case 'created_at':
return esc_html( $item->created_at );
default:
return print_r( $item, true );
}
}
function column_cb( $item ) {
return sprintf(
'<input type="checkbox" name="tag_ids[]" value="%d" />',
$item->id
);
}
}
}
// Frontend page: Display Posts
function custom_content_manager_display_posts( $atts ) {
global $wpdb;
// Pagination
$paged = isset( $_GET['paged'] ) ? (int) $_GET['paged'] : 1;
$per_page = 10;
$offset = ( $paged - 1 ) * $per_page;
$posts = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}custom_posts ORDER BY created_at DESC LIMIT %d, %d", $offset, $per_page ) );
$total_posts = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}custom_posts" );
$total_pages = ceil( $total_posts / $per_page );
ob_start();
if ( $posts ) {
foreach ( $posts as $post ) {
?>
<div class="custom-post">
<h2><?php echo esc_html( $post->title ); ?></h2>
<p><?php echo esc_textarea( $post->content ); ?></p>
<p>Published on: <?php echo esc_html( $post->created_at ); ?></p>
</div>
<?php
}
} else {
echo '<p>No posts found.</p>';
}
// Pagination links
echo '<div class="pagination">';
for ( $i = 1; $i <= $total_pages; $i++ ) {
echo '<a href="?paged=' . $i . '">' . $i . '</a>';
}
echo '</div>';
return ob_get_clean();
}
add_shortcode( 'custom_content_manager_posts', 'custom_content_manager_display_posts' );
// Register Custom Page Template
function custom_content_manager_page_template( $template ) {
if ( is_page() && has_shortcode( get_post()->post_content, 'custom_content_manager_posts' ) ) {
$template = plugin_dir_path( __FILE__ ) . 'templates/custom-content-manager-template.php';
}
return $template;
}
add_filter( 'template_include', 'custom_content_manager_page_template' );
?>
修改前端页面
// Frontend page: Display Posts with Categories and Tags using JOIN and Tailwind CSS
function custom_content_manager_display_posts( $atts ) {
global $wpdb;
// Pagination
$paged = isset( $_GET['paged'] ) ? (int) $_GET['paged'] : 1;
$per_page = 10;
$offset = ( $paged - 1 ) * $per_page;
// Query to retrieve posts with associated categories and tags
$query = $wpdb->prepare(
"SELECT p.*,
GROUP_CONCAT(DISTINCT c.name ORDER BY c.name ASC SEPARATOR '||') AS categories,
GROUP_CONCAT(DISTINCT t.name ORDER BY t.name ASC SEPARATOR '||') AS tags
FROM {$wpdb->prefix}custom_posts p
LEFT JOIN {$wpdb->prefix}custom_post_category pc ON p.id = pc.post_id
LEFT JOIN {$wpdb->prefix}custom_categories c ON pc.category_id = c.id
LEFT JOIN {$wpdb->prefix}custom_post_tag pt ON p.id = pt.post_id
LEFT JOIN {$wpdb->prefix}custom_tags t ON pt.tag_id = t.id
GROUP BY p.id
ORDER BY p.created_at DESC
LIMIT %d, %d",
$offset, $per_page
);
$posts = $wpdb->get_results( $query );
$total_posts = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}custom_posts" );
$total_pages = ceil( $total_posts / $per_page );
ob_start();
if ( $posts ) {
foreach ( $posts as $post ) {
// Split categories and tags into arrays
$categories = $post->categories ? explode('||', $post->categories) : [];
$tags = $post->tags ? explode('||', $post->tags) : [];
?>
<div class="custom-post p-4 mb-6 border rounded-lg shadow-md">
<h2 class="text-2xl font-bold mb-2"><?php echo esc_html( $post->title ); ?></h2>
<p class="mb-4"><?php echo esc_textarea( $post->content ); ?></p>
<p class="text-gray-600 mb-2">Published on: <?php echo esc_html( $post->created_at ); ?></p>
<?php if ( !empty( $categories ) ) : ?>
<div class="flex flex-wrap gap-2 mb-4">
<?php foreach ( $categories as $category ) : ?>
<span class="inline-block px-3 py-1 text-sm font-semibold text-gray-700 bg-gray-200 rounded-full">
<?php echo esc_html( $category ); ?>
</span>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if ( !empty( $tags ) ) : ?>
<div class="flex flex-wrap gap-2">
<?php foreach ( $tags as $tag ) : ?>
<span class="inline-block px-3 py-1 text-sm font-semibold text-blue-700 bg-blue-200 rounded-full">
<?php echo esc_html( $tag ); ?>
</span>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<?php
}
} else {
echo '<p class="text-center text-gray-600">No posts found.</p>';
}
// Pagination links
echo '<div class="pagination flex justify-center gap-2 mt-6">';
for ( $i = 1; $i <= $total_pages; $i++ ) {
echo '<a href="?paged=' . $i . '" class="px-3 py-1 text-sm font-semibold text-gray-700 bg-gray-200 rounded-full">' . $i . '</a>';
}
echo '</div>';
return ob_get_clean();
}
add_shortcode( 'custom_content_manager_posts', 'custom_content_manager_display_posts' );
<?php
/*
Plugin Name: Custom Content Manager
Description: A plugin to manage custom posts with custom categories and tags, and display them using custom page templates.
Version: 1.0
Author: Your Name
*/
// 激活时刷新重写规则
function custom_post_flush_rewrite_rules() {
custom_post_rewrite_rule();
flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'custom_post_flush_rewrite_rules' );
// 注册自定义 URL 路由规则
function custom_post_rewrite_rule() {
// 匹配自定义文章列表的分页 URL 格式:/custom/page/1
add_rewrite_rule(
'^custom/page/([0-9]{1,})/?$', // 匹配 /custom/page/1 或 /custom/page/2
'index.php?pagename=custom-post-list&paged=$matches[1]', // 路由到自定义页面
'top'
);
// 匹配单篇文章的 URL 格式:/custom/slug
add_rewrite_rule(
'^custom/([^/]+)/?$', // 匹配 /custom/slug
'index.php?post_type=custom_post&slug=$matches[1]', // 查询自定义文章
'top'
);
}
add_action( 'init', 'custom_post_rewrite_rule' );
// 获取指定 slug 的文章内容
function get_custom_post_by_slug($slug) {
global $wpdb;
$post = $wpdb->get_row($wpdb->prepare(
"SELECT p.*,
GROUP_CONCAT(DISTINCT c.name ORDER BY c.name ASC SEPARATOR ', ') AS categories,
GROUP_CONCAT(DISTINCT t.name ORDER BY t.name ASC SEPARATOR ', ') AS tags
FROM {$wpdb->prefix}custom_posts p
LEFT JOIN {$wpdb->prefix}custom_post_category pc ON p.id = pc.post_id
LEFT JOIN {$wpdb->prefix}custom_categories c ON pc.category_id = c.id
LEFT JOIN {$wpdb->prefix}custom_post_tag pt ON p.id = pt.post_id
LEFT JOIN {$wpdb->prefix}custom_tags t ON pt.tag_id = t.id
WHERE p.slug = %s
GROUP BY p.id",
$slug
));
return $post;
}
// 生成分页链接
function custom_content_manager_display_posts($atts) {
global $wpdb;
// 获取当前页码,默认为 1
$paged = isset($_GET['paged']) ? (int) $_GET['paged'] : 1;
$per_page = 10; // 每页显示文章数量
$offset = ($paged - 1) * $per_page;
// 获取文章数据,带有分页和类别标签信息
$query = $wpdb->prepare(
"SELECT p.*,
GROUP_CONCAT(DISTINCT c.name ORDER BY c.name ASC SEPARATOR ', ') AS categories,
GROUP_CONCAT(DISTINCT t.name ORDER BY t.name ASC SEPARATOR ', ') AS tags
FROM {$wpdb->prefix}custom_posts p
LEFT JOIN {$wpdb->prefix}custom_post_category pc ON p.id = pc.post_id
LEFT JOIN {$wpdb->prefix}custom_categories c ON pc.category_id = c.id
LEFT JOIN {$wpdb->prefix}custom_post_tag pt ON p.id = pt.post_id
LEFT JOIN {$wpdb->prefix}custom_tags t ON pt.tag_id = t.id
GROUP BY p.id
ORDER BY p.created_at DESC
LIMIT %d, %d",
$offset, $per_page
);
$posts = $wpdb->get_results($query);
$total_posts = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}custom_posts");
$total_pages = ceil($total_posts / $per_page);
ob_start(); // 开始输出缓冲
if ($posts) {
foreach ($posts as $post) {
?>
<div class="custom-post">
<h2><?php echo esc_html($post->title); ?></h2>
<p><?php echo esc_textarea($post->content); ?></p>
<p>Published on: <?php echo esc_html($post->created_at); ?></p>
<?php if ($post->categories) : ?>
<p><strong>Categories:</strong> <?php echo esc_html($post->categories); ?></p>
<?php endif; ?>
<?php if ($post->tags) : ?>
<p><strong>Tags:</strong> <?php echo esc_html($post->tags); ?></p>
<?php endif; ?>
</div>
<?php
}
} else {
echo '<p>No posts found.</p>';
}
// 输出分页链接
echo '<div class="pagination">';
for ($i = 1; $i <= $total_pages; $i++) {
echo '<a href="' . home_url('/custom/page/' . $i) . '">' . $i . '</a>';
}
echo '</div>';
return ob_get_clean(); // 返回输出内容
}
add_shortcode('custom_content_manager_posts', 'custom_content_manager_display_posts');
// 创建自定义页面模板:页面将显示文章内容
function custom_page_template($template) {
if (is_page('custom-post-list')) {
$template = plugin_dir_path(__FILE__) . 'page-custom-post-list.php'; // 页面模板路径
}
return $template;
}
add_filter('template_include', 'custom_page_template');
// 页面模板:列出所有文章,带分页
?>
<!-- page-custom-post-list.php -->
<?php
/* Template Name: Custom Post List */
get_header();
// 显示文章列表(带分页)
echo custom_content_manager_display_posts();
get_footer();
?>
// 文章详情页模板:根据 slug 显示单篇文章
?>
<!-- single-custom_post.php -->
<?php
get_header();
// 获取 URL 中的 slug
$post_slug = get_query_var('slug');
// 根据 slug 获取文章内容
$post = get_custom_post_by_slug($post_slug);
if ($post) {
?>
<div class="single-post">
<h1><?php echo esc_html($post->title); ?></h1>
<p><?php echo esc_textarea($post->content); ?></p>
<p><strong>Published on:</strong> <?php echo esc_html($post->created_at); ?></p>
<?php if ($post->categories) : ?>
<p><strong>Categories:</strong> <?php echo esc_html($post->categories); ?></p>
<?php endif; ?>
<?php if ($post->tags) : ?>
<p><strong>Tags:</strong> <?php echo esc_html($post->tags); ?></p>
<?php endif; ?>
</div>
<?php
} else {
echo '<p>Post not found.</p>';
}
get_footer();
?>