The 搜索框 and 一言 sidebar widgets fell into the generic renderer branch, so they rendered a .jio-panel card wrapping a second bespoke card (.jio-widget-search / .jio-widget-quote). In-article 一言 also used divergent modifier classes and an extra hover rule. - search: render through the shared jio_get_search_box() (legacy keyword, history and category pickers) inside one reference card, mirroring the reference widget's markup and title default 「搜索」 - quote: render the reference .yiyan-box card itself as the click root; the shell now emits only the reference widget-container/title wrapper - article 一言: adopt the reference class lists for header, footer and the standalone after-article box; drop the invented yiyan--* modifiers and the duplicate hover/opacity rules - client: fill .cn/.en in the reference order (first line .cn, second .en) and drop the stale window.JioYiyan bridge plus the dead qv-yiyan.php AJAX path in runtime main.js - schema: replace the ad-hoc search_style radio with the reference switches (keywords, history, input category, more_cats) and default title - assets: enqueue assets/js/yiyan.js through the quote widget's asset list Tests: widget-system suite 820/821 (the one failure is the pre-existing frontend-lifecycle theme-init stub); new search/quote card contracts pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
77 lines
2.6 KiB
PHP
77 lines
2.6 KiB
PHP
<?php
|
|
/**
|
|
* 一言 (Hitokoto) markup helper.
|
|
*
|
|
* Shared shell for single-post placements and the yiyan widget.
|
|
*
|
|
* @package Jio
|
|
*/
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
add_action('wp_ajax_jio_yiyan', 'jio_ajax_yiyan');
|
|
add_action('wp_ajax_nopriv_jio_yiyan', 'jio_ajax_yiyan');
|
|
|
|
if (!function_exists('jio_ajax_yiyan')) :
|
|
/** Return one random Chinese/English pair from the theme quote file. */
|
|
function jio_ajax_yiyan(): void {
|
|
$custom_file = WP_CONTENT_DIR . '/yiyan.txt';
|
|
$theme_file = get_template_directory() . '/yiyan/qv-yiyan.txt';
|
|
$file = is_readable($custom_file) ? $custom_file : $theme_file;
|
|
$lines = is_readable($file) ? file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) : false;
|
|
$pairs = [];
|
|
|
|
if (is_array($lines)) {
|
|
// The first line is the reference file's title; the rest alternate EN/CN.
|
|
array_shift($lines);
|
|
$lines = array_values(array_map('trim', $lines));
|
|
for ($i = 0, $length = count($lines); $i + 1 < $length; $i += 2) {
|
|
if ($lines[$i] !== '' && $lines[$i + 1] !== '') {
|
|
$pairs[] = ['en' => $lines[$i], 'cn' => $lines[$i + 1]];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$pairs) {
|
|
wp_send_json_error(['message' => __('一言内容暂不可用', 'jio')], 503);
|
|
}
|
|
|
|
wp_send_json_success($pairs[array_rand($pairs)]);
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('jio_render_yiyan_block')) :
|
|
/**
|
|
* Shared 一言 shell for single-post placements (and reusable markup).
|
|
*
|
|
* Reads bilingual pairs from the bundled reference file and supports the
|
|
* same optional wp-content/yiyan.txt override used by the reference theme.
|
|
*
|
|
* @param array<string,mixed> $args {
|
|
* @type string $class Extra CSS classes on the root.
|
|
* }
|
|
*/
|
|
function jio_render_yiyan_block(array $args = []): void {
|
|
echo jio_get_yiyan_markup($args); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped by the markup helper.
|
|
}
|
|
function jio_get_yiyan_markup(array $args = []): string {
|
|
$class = trim((string) ($args['class'] ?? 'jio-yiyan'));
|
|
|
|
if (strpos($class, 'jio-yiyan') === false) {
|
|
$class = trim($class . ' jio-yiyan');
|
|
}
|
|
// 与参考结构一致:.yiyan 初始为空,由脚本写入 .cn(首行)与 .en(次行)。
|
|
$html = '<div class="' . esc_attr($class) . '"'
|
|
. ' data-jio-yiyan'
|
|
. ' data-endpoint="' . esc_url(admin_url('admin-ajax.php')) . '"'
|
|
. ' data-toggle="tooltip"'
|
|
. ' title="' . esc_attr__('点击切换一言', 'jio') . '"'
|
|
. ' role="button" tabindex="0"'
|
|
. ' aria-label="' . esc_attr__('点击切换一言', 'jio') . '"'
|
|
. ' aria-live="polite">'
|
|
. '<div class="yiyan"></div>'
|
|
. '</div>';
|
|
return $html;
|
|
}
|
|
endif;
|