' . esc_html($subtitle) . ''; } endif; if (!function_exists('aksrt_get_single_title_html')) : /** * Title + optional subtitle for single headers. */ function aksrt_get_single_title_html($post_id = null): string { $post_id = $post_id ? (int) $post_id : (int) get_the_ID(); $title = get_the_title($post_id); $sub = function_exists('aksrt_get_the_subtitle') ? aksrt_get_the_subtitle(true, '', $post_id) : ''; return esc_html($title) . $sub; } endif; if (!function_exists('aksrt_get_posts_meta_items_html')) : /** * Zibll-like post meta pills: comment + views + likes. * * @param int|null $post_id Post ID. */ function aksrt_get_posts_meta_items_html($post_id = null): string { $post = get_post($post_id); if (!($post instanceof WP_Post)) { return ''; } $post_id = (int) $post->ID; $html = ''; $comments_closed = function_exists('aksrt_are_comments_closed') ? aksrt_are_comments_closed() : (!comments_open($post_id)); if (comments_open($post_id) && !$comments_closed) { $href = is_single($post_id) ? 'javascript:(typeof scrollTopTo===\'function\'?scrollTopTo(\'#comments\'):void(0));' : get_comments_link($post_id); $count = (int) get_comments_number($post_id); $html .= ''; } $views = function_exists('aksrt_get_post_views') ? (int) aksrt_get_post_views($post_id) : 0; $views_label = function_exists('aksrt_format_number') ? aksrt_format_number($views) : number_format_i18n($views); $html .= ''; $like_on = true; if (class_exists('\AKSRT\Settings\Settings')) { $page = \AKSRT\Settings\Settings::get_post_page_settings(); $like_on = !isset($page['like_enabled']) || !empty($page['like_enabled']); } if ($like_on && $post->post_type === 'post') { $likes = function_exists('aksrt_get_post_likes') ? (int) aksrt_get_post_likes($post_id) : 0; $html .= ''; } return $html; } endif; if (!function_exists('aksrt_get_single_meta_box')) : /** * Zibll zib_get_single_meta_box equivalent. * * @param string $class Extra class on wrapper. * @param string $direction Unused (kept for API parity). * @param int|null $post_id Post ID. */ function aksrt_get_single_meta_box(string $class = 'abs-right', string $direction = 'down', $post_id = null): string { if (!is_single() && !is_singular()) { return ''; } $post_id = $post_id ? (int) $post_id : (int) get_the_ID(); $meta = function_exists('aksrt_get_posts_meta_items_html') ? aksrt_get_posts_meta_items_html($post_id) : ''; $more = ''; $edit_link = get_edit_post_link($post_id); $permalink = get_permalink($post_id); $login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url($permalink ?: home_url('/')); $more .= '
'; return ''; } endif; if (!function_exists('aksrt_get_post_status_badge')) : /** * Non-publish status badge (text badge, Zibll-compatible classes). */ function aksrt_get_post_status_badge($post = null): string { $post = get_post($post); if (!($post instanceof WP_Post)) { return ''; } $map = [ 'draft' => ['label' => __('草稿', 'aksrt'), 'class' => 'jb-yellow'], 'pending' => ['label' => __('待审核', 'aksrt'), 'class' => 'jb-red'], 'private' => ['label' => __('私密', 'aksrt'), 'class' => 'b-black opacity8'], 'future' => ['label' => __('定时发布', 'aksrt'), 'class' => 'c-blue'], 'trash' => ['label' => __('回收站', 'aksrt'), 'class' => 'jb-red'], ]; $status = $post->post_status; if (!isset($map[$status])) { return ''; } return '' . esc_html($map[$status]['label']) . ''; } endif; if (!function_exists('aksrt_get_colored_term_tags')) : /** * Colored but-links for terms (Zibll cat/topics palette). * * @param WP_Term[] $terms Terms. * @param string $class Base class. * @param string $before Prefix HTML inside link. * @param string[] $palette Color classes. */ function aksrt_get_colored_term_tags(array $terms, string $class = 'but ml6 radius', string $before = '', array $palette = []): string { if ($palette === []) { $palette = ['c-blue', 'c-yellow', 'c-green', 'c-purple', 'c-red']; } $html = ''; $i = 0; foreach ($terms as $term) { if (!($term instanceof WP_Term)) { continue; } $color = $palette[$i % count($palette)]; $i++; $url = get_term_link($term); if (is_wp_error($url)) { continue; } $html .= '' . $before . esc_html($term->name) . ''; } return $html; } endif; if (!function_exists('aksrt_get_single_article_tags_html')) : /** * topics → categories → tags (Zibll footer order). */ function aksrt_get_single_article_tags_html(int $post_id): string { $topics_html = ''; if (taxonomy_exists('topics')) { $topics = wp_get_post_terms($post_id, 'topics'); if (!is_wp_error($topics) && !empty($topics)) { $topics_html = aksrt_get_colored_term_tags( array_slice($topics, 0, 6), 'but ml6 radius', ' ', ['c-yellow', 'c-green', 'c-purple', 'c-red', 'c-blue'] ); } } $cats = get_the_category($post_id) ?: []; $cat_html = aksrt_get_colored_term_tags( $cats, 'but ml6 radius', ' ', ['c-blue', 'c-yellow', 'c-green', 'c-purple', 'c-red'] ); $tags_html = ''; $tags = get_the_tags($post_id) ?: []; if (!empty($tags) && is_array($tags)) { // Sort by count desc like Zibll. usort($tags, static function ($a, $b) { return (int) $b->count <=> (int) $a->count; }); foreach ($tags as $tag) { if (!($tag instanceof WP_Term)) { continue; } $tags_html .= '# ' . esc_html($tag->name) . ''; } } $top = $topics_html . $cat_html; if ($top === '' && $tags_html === '') { return ''; } return ''; } endif; if (!function_exists('aksrt_get_post_allow_view_data')) : /** * Category/post reading permission gate (Zibll zib_get_post_allow_view_data subset). * * Supported term meta keys (first match wins, walks parents): * - term meta `post_cat_config` array with `allow_view` = signin|login|roles * - term meta `aksrt_allow_view` string * - post meta `_aksrt_allow_view` string (public|login|signin|roles) * * @return array{allow:bool,type:string,not_html:string,allow_reason:string,html:string} */ function aksrt_get_post_allow_view_data($post = null): array { static $cache = []; $data = [ 'allow' => true, 'type' => '', 'not_html' => '', 'allow_reason' => '', 'html' => '', ]; $post = get_post($post); if (!($post instanceof WP_Post) || $post->post_type !== 'post') { return $data; } if (isset($cache[$post->ID])) { return $cache[$post->ID]; } if (current_user_can('manage_options')) { $data['allow_reason'] = __('您是管理员,可查看所有内容', 'aksrt'); $cache[$post->ID] = $data; return $data; } // Post-level override. $post_allow = sanitize_key((string) get_post_meta($post->ID, '_aksrt_allow_view', true)); if ($post_allow !== '' && $post_allow !== 'public') { $resolved = aksrt_resolve_allow_view_rule($post_allow, [], $post); $cache[$post->ID] = $resolved; return $resolved; } $cats = get_the_category($post->ID); if (empty($cats)) { $cache[$post->ID] = $data; return $data; } foreach ($cats as $cat) { if (!($cat instanceof WP_Term)) { continue; } $rule = aksrt_get_term_allow_view_rule((int) $cat->term_id); if ($rule['type'] === '' || $rule['type'] === 'public') { continue; } $resolved = aksrt_resolve_allow_view_rule($rule['type'], $rule['roles'], $post); if (!$resolved['allow']) { $cache[$post->ID] = $resolved; return $resolved; } } $cache[$post->ID] = $data; return $data; } endif; if (!function_exists('aksrt_get_term_allow_view_rule')) : /** * Walk category ancestors for allow_view config. * * @return array{type:string,roles:array' . esc_html__('登录后可查看', 'aksrt') . '
'; if ($user_id <= 0) { $data['allow'] = false; $data['not_html'] = aksrt_get_allow_view_deny_shell( __('内容已隐藏,请登录后查看', 'aksrt'), '' . esc_html__('登录后继续查看', 'aksrt') . '
' . '' . esc_html__('以下用户组可查看', 'aksrt') . '
' . $badges . '