优化加入我们页面的样式

优化加入我们页面的样式的同时,还更新了新闻日期的显示,使其精确到时分
同时在文章详情页,将文章的时间显示格式改成YYYY-MM-DD hh:mm
This commit is contained in:
2026-03-07 14:28:29 +08:00
parent 965c62fb20
commit 97e19e990a
7 changed files with 723 additions and 206 deletions
+2 -2
View File
@@ -118,7 +118,7 @@ $featured_ids = array_slice(array_values(array_unique($featured_ids)), 0, 4);
<span class="news-story-meta-dot" aria-hidden="true">/</span> <span class="news-story-meta-dot" aria-hidden="true">/</span>
<time class="news-story-meta-item" datetime="<?php echo esc_attr(get_the_date('c')); ?>"> <time class="news-story-meta-item" datetime="<?php echo esc_attr(get_the_date('c')); ?>">
<span data-cn="发表于" data-en="Published">Published</span> <span data-cn="发表于" data-en="Published">Published</span>
<?php echo esc_html(get_the_date('Y-m-d')); ?> <?php echo esc_html(get_the_date('Y-m-d H:i')); ?>
</time> </time>
<span class="news-story-meta-dot" aria-hidden="true">/</span> <span class="news-story-meta-dot" aria-hidden="true">/</span>
<span class="news-story-meta-item"> <span class="news-story-meta-item">
@@ -215,7 +215,7 @@ $featured_ids = array_slice(array_values(array_unique($featured_ids)), 0, 4);
<a href="<?php echo esc_url($featured_link); ?>"><?php echo esc_html($featured_title); ?></a> <a href="<?php echo esc_url($featured_link); ?>"><?php echo esc_html($featured_title); ?></a>
</h3> </h3>
<div class="news-side-meta"> <div class="news-side-meta">
<time datetime="<?php echo esc_attr(get_the_date('c', $featured_id)); ?>"><?php echo esc_html(get_the_date('Y-m-d', $featured_id)); ?></time> <time datetime="<?php echo esc_attr(get_the_date('c', $featured_id)); ?>"><?php echo esc_html(get_the_date('Y-m-d H:i', $featured_id)); ?></time>
<span class="news-side-meta-dot" aria-hidden="true">/</span> <span class="news-side-meta-dot" aria-hidden="true">/</span>
<span> <span>
<span data-cn="浏览" data-en="Views">Views</span> <span data-cn="浏览" data-en="Views">Views</span>
+189 -64
View File
@@ -25,28 +25,45 @@
line-height: 1.5; line-height: 1.5;
} }
.join-info-layout {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 22px;
align-items: start;
}
.join-info-main,
.join-info-side {
min-width: 0;
}
.join-panel-title {
margin: 0 0 12px;
font-size: clamp(1.35rem, 0.9vw + 1.1rem, 2.05rem);
line-height: 1.1;
color: var(--color-primary);
font-weight: 800;
letter-spacing: 0.01em;
}
.join-news-strip { .join-news-strip {
margin-bottom: 20px; margin: 0;
padding: 0 0 10px; padding: 0;
} }
.join-news-strip-track { .join-news-strip-track {
display: flex; display: grid;
gap: 14px; gap: 0;
} }
.join-news-item { .join-news-item {
--join-news-cols: 5; padding: 12px 0;
flex: 0 0 calc((100% - (var(--join-news-cols) - 1) * 14px) / var(--join-news-cols)); border-bottom: 1px solid color-mix(in srgb, var(--border-default) 84%, transparent);
width: calc((100% - (var(--join-news-cols) - 1) * 14px) / var(--join-news-cols));
min-width: 0;
padding-right: 12px;
border-right: 1px solid color-mix(in srgb, var(--border-default) 82%, transparent);
} }
.join-news-item:last-child { .join-news-item:last-child {
border-right: 0; border-bottom: 0;
padding-right: 0; padding-bottom: 0;
} }
.join-news-item-title { .join-news-item-title {
@@ -66,17 +83,36 @@
color: var(--color-primary); color: var(--color-primary);
} }
.join-news-item-meta {
margin: 6px 0 0;
display: flex;
flex-wrap: wrap;
gap: 10px;
font-size: 0.76rem;
line-height: 1.45;
color: color-mix(in srgb, var(--text-secondary) 86%, var(--text-primary) 14%);
}
.join-news-item-meta-author,
.join-news-item-meta-time {
display: inline-flex;
align-items: center;
gap: 5px;
white-space: nowrap;
}
.join-news-item-excerpt { .join-news-item-excerpt {
margin: 7px 0 0; margin: 8px 0 0;
color: var(--text-secondary); color: var(--text-secondary);
font-size: 0.82rem; font-size: 0.88rem;
line-height: 1.5; line-height: 1.58;
} }
.join-news-strip-empty { .join-news-strip-empty {
margin: 0; margin: 0;
color: var(--text-secondary); color: var(--text-secondary);
font-size: 0.9rem; font-size: 0.9rem;
line-height: 1.55;
} }
.join-hero { .join-hero {
@@ -88,7 +124,7 @@
.join-canvas-shell { .join-canvas-shell {
position: relative; position: relative;
height: clamp(280px, 31vw, 440px); height: clamp(380px, 35vw, 600px);
border-radius: 18px; border-radius: 18px;
overflow: hidden; overflow: hidden;
background: color-mix(in srgb, var(--bg-card) 94%, transparent); background: color-mix(in srgb, var(--bg-card) 94%, transparent);
@@ -623,16 +659,6 @@
overflow-wrap: anywhere; overflow-wrap: anywhere;
} }
.join-forms-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 16px;
}
.join-forms-grid.is-single {
grid-template-columns: 1fr;
}
.join-form-card { .join-form-card {
border: 1px solid color-mix(in srgb, var(--border-default) 86%, transparent); border: 1px solid color-mix(in srgb, var(--border-default) 86%, transparent);
border-radius: 14px; border-radius: 14px;
@@ -645,21 +671,14 @@
box-shadow: 0 16px 30px -24px color-mix(in srgb, #000000 65%, transparent); box-shadow: 0 16px 30px -24px color-mix(in srgb, #000000 65%, transparent);
} }
.join-form-card-full { .join-form-card + .join-panel-title {
grid-column: 1 / -1; margin-top: 16px;
} }
.join-form-head h2 { .join-form-card-placeholder {
margin: 0; min-height: 132px;
color: var(--text-primary); display: flex;
font-size: 1.22rem; align-items: center;
}
.join-form-head p {
margin: 6px 0 0;
color: color-mix(in srgb, var(--text-primary) 72%, var(--text-secondary) 28%);
font-size: 0.94rem;
line-height: 1.55;
} }
.join-form-content { .join-form-content {
@@ -677,7 +696,7 @@
.join-progress-query-grid { .join-progress-query-grid {
display: grid; display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: minmax(0, 1fr);
gap: 10px; gap: 10px;
} }
@@ -748,6 +767,11 @@
background: color-mix(in srgb, #d89a1b 14%, var(--bg-card) 86%); background: color-mix(in srgb, #d89a1b 14%, var(--bg-card) 86%);
} }
.join-progress-query-feedback.is-info {
border-color: color-mix(in srgb, var(--color-primary) 52%, var(--border-default) 48%);
background: color-mix(in srgb, var(--color-primary) 14%, var(--bg-card) 86%);
}
.join-progress-query-feedback.is-error { .join-progress-query-feedback.is-error {
border-color: color-mix(in srgb, #c34646 58%, var(--border-default) 42%); border-color: color-mix(in srgb, #c34646 58%, var(--border-default) 42%);
background: color-mix(in srgb, #c34646 14%, var(--bg-card) 86%); background: color-mix(in srgb, #c34646 14%, var(--bg-card) 86%);
@@ -853,6 +877,126 @@
outline: none !important; outline: none !important;
} }
.join-form-content .frm_style_formidable-style.with_frm_style .iti {
width: 100% !important;
}
.join-form-content .frm_style_formidable-style.with_frm_style .iti input[type="tel"] {
padding-right: 12px !important;
padding-left: calc(var(--iti-selected-country-arrow-padding, 64px) + 4px) !important;
}
.join-form-content .frm_style_formidable-style.with_frm_style .iti__selected-country {
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
}
.join-form-content .frm_style_formidable-style.with_frm_style input:-webkit-autofill,
.join-form-content .frm_style_formidable-style.with_frm_style input:-webkit-autofill:hover,
.join-form-content .frm_style_formidable-style.with_frm_style input:-webkit-autofill:focus,
.join-form-content .frm_style_formidable-style.with_frm_style textarea:-webkit-autofill,
.join-form-content .frm_style_formidable-style.with_frm_style textarea:-webkit-autofill:hover,
.join-form-content .frm_style_formidable-style.with_frm_style textarea:-webkit-autofill:focus,
.join-form-content .frm_style_formidable-style.with_frm_style select:-webkit-autofill,
.join-form-content .frm_style_formidable-style.with_frm_style select:-webkit-autofill:hover,
.join-form-content .frm_style_formidable-style.with_frm_style select:-webkit-autofill:focus {
-webkit-text-fill-color: color-mix(in srgb, var(--text-primary) 96%, #ffffff 4%) !important;
-webkit-box-shadow: 0 0 0 1000px color-mix(in srgb, var(--bg-body) 84%, #ffffff 16%) inset !important;
box-shadow: 0 0 0 1000px color-mix(in srgb, var(--bg-body) 84%, #ffffff 16%) inset !important;
caret-color: color-mix(in srgb, var(--text-primary) 96%, #ffffff 4%) !important;
transition: background-color 9999s ease-out 0s !important;
}
.join-form-content .frm_style_formidable-style.with_frm_style .iti__dropdown-content {
background: color-mix(in srgb, var(--bg-card) 94%, var(--bg-body) 6%) !important;
border: 1px solid color-mix(in srgb, var(--border-default) 46%, var(--color-primary) 54%) !important;
color: color-mix(in srgb, var(--text-primary) 92%, #ffffff 8%) !important;
box-shadow: 0 18px 36px -22px color-mix(in srgb, #000000 68%, transparent);
}
.join-form-content .frm_style_formidable-style.with_frm_style .iti__search-input-wrapper {
margin: 6px 8px !important;
}
.join-form-content .frm_style_formidable-style.with_frm_style .iti__search-input {
border: 1px solid color-mix(in srgb, var(--border-default) 38%, var(--color-primary) 62%) !important;
background: color-mix(in srgb, var(--bg-body) 84%, #ffffff 16%) !important;
color: color-mix(in srgb, var(--text-primary) 94%, #ffffff 6%) !important;
min-height: 40px !important;
}
.join-form-content .frm_style_formidable-style.with_frm_style .iti__search-input::placeholder {
color: color-mix(in srgb, var(--text-secondary) 76%, var(--text-primary) 24%) !important;
opacity: 1;
}
.join-form-content .frm_style_formidable-style.with_frm_style .iti__country-list {
background: transparent !important;
}
.join-form-content .frm_style_formidable-style.with_frm_style .iti__country {
color: color-mix(in srgb, var(--text-primary) 90%, #ffffff 10%) !important;
}
.join-form-content .frm_style_formidable-style.with_frm_style .iti__dial-code,
.join-form-content .frm_style_formidable-style.with_frm_style .iti__country-name {
color: color-mix(in srgb, var(--text-primary) 88%, var(--text-secondary) 12%) !important;
}
.join-form-content .frm_style_formidable-style.with_frm_style .iti__country.iti__highlight,
.join-form-content .frm_style_formidable-style.with_frm_style .iti__country:hover {
background: color-mix(in srgb, var(--color-primary) 16%, var(--bg-card) 84%) !important;
}
.join-form-content .frm_style_formidable-style.with_frm_style .iti__divider {
border-bottom-color: color-mix(in srgb, var(--border-default) 70%, transparent) !important;
}
.frm_forms.with_frm_style .iti__dropdown-content {
background: color-mix(in srgb, var(--bg-card) 94%, var(--bg-body) 6%) !important;
border: 1px solid color-mix(in srgb, var(--border-default) 46%, var(--color-primary) 54%) !important;
color: color-mix(in srgb, var(--text-primary) 92%, #ffffff 8%) !important;
box-shadow: 0 18px 36px -22px color-mix(in srgb, #000000 68%, transparent);
}
.frm_forms.with_frm_style .iti__search-input-wrapper {
margin: 6px 8px !important;
}
.frm_forms.with_frm_style .iti__search-input {
border: 1px solid color-mix(in srgb, var(--border-default) 38%, var(--color-primary) 62%) !important;
background: color-mix(in srgb, var(--bg-body) 84%, #ffffff 16%) !important;
color: color-mix(in srgb, var(--text-primary) 94%, #ffffff 6%) !important;
min-height: 40px !important;
}
.frm_forms.with_frm_style .iti__search-input::placeholder {
color: color-mix(in srgb, var(--text-secondary) 76%, var(--text-primary) 24%) !important;
opacity: 1;
}
.frm_forms.with_frm_style .iti__country-list {
background: transparent !important;
}
.frm_forms.with_frm_style .iti__country {
color: color-mix(in srgb, var(--text-primary) 90%, #ffffff 10%) !important;
}
.frm_forms.with_frm_style .iti__dial-code,
.frm_forms.with_frm_style .iti__country-name {
color: color-mix(in srgb, var(--text-primary) 88%, var(--text-secondary) 12%) !important;
}
.frm_forms.with_frm_style .iti__country.iti__highlight,
.frm_forms.with_frm_style .iti__country:hover {
background: color-mix(in srgb, var(--color-primary) 16%, var(--bg-card) 84%) !important;
}
.frm_forms.with_frm_style .iti__divider {
border-bottom-color: color-mix(in srgb, var(--border-default) 70%, transparent) !important;
}
.join-form-content .frm_style_formidable-style.with_frm_style input[type="checkbox"], .join-form-content .frm_style_formidable-style.with_frm_style input[type="checkbox"],
.join-form-content .frm_style_formidable-style.with_frm_style input[type="radio"] { .join-form-content .frm_style_formidable-style.with_frm_style input[type="radio"] {
accent-color: var(--color-primary); accent-color: var(--color-primary);
@@ -963,37 +1107,18 @@
padding: 30px 0 60px; padding: 30px 0 60px;
} }
.join-news-strip { .join-info-layout {
margin-bottom: 16px; grid-template-columns: 1fr;
} gap: 20px;
.join-news-strip-track {
display: flex;
gap: 12px;
overflow-x: auto;
padding-bottom: 6px;
scrollbar-width: thin;
} }
.join-news-item { .join-news-item {
flex: 0 0 220px; padding: 10px 0;
padding-right: 0;
border-right: 0;
border-bottom: 1px solid color-mix(in srgb, var(--border-default) 82%, transparent);
padding-bottom: 8px;
} }
.join-stage-list { .join-stage-list {
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
} }
.join-forms-grid {
grid-template-columns: 1fr;
}
.join-form-card-full {
grid-column: auto;
}
} }
@media (max-width: 640px) { @media (max-width: 640px) {
@@ -1014,7 +1139,7 @@
} }
.join-canvas-shell { .join-canvas-shell {
height: 240px; height: 272px;
} }
.join-current-stage { .join-current-stage {
+230
View File
@@ -625,9 +625,239 @@
stopBoatAnimations(); stopBoatAnimations();
}); });
function resolveLanguage() {
const bootLang = typeof window.__ITSTUDIO_LANG__ === 'string' ? window.__ITSTUDIO_LANG__ : '';
const htmlLang = document.documentElement.getAttribute('lang') || '';
const lang = (bootLang || htmlLang || 'zh').toLowerCase();
return lang.indexOf('en') === 0 ? 'en' : 'zh';
}
function pickLocaleText(cnText, enText) {
return resolveLanguage() === 'en'
? (enText || cnText || '')
: (cnText || enText || '');
}
function getProgressLookupConfig() {
const config = joinData && typeof joinData.progressLookup === 'object' ? joinData.progressLookup : null;
if (!config) {
return null;
}
if (!config.ajaxUrl || !config.action || !config.nonce) {
return null;
}
return config;
}
function ensureProgressFeedbackNode(formElement) {
const host = formElement.closest('.join-form-content') || formElement.parentElement;
if (!host) {
return null;
}
let feedback = host.querySelector('.join-progress-query-feedback');
if (!feedback) {
feedback = document.createElement('p');
feedback.className = 'join-progress-query-feedback';
feedback.hidden = true;
feedback.setAttribute('aria-live', 'polite');
host.appendChild(feedback);
}
return feedback;
}
function setProgressFeedback(feedback, tone, messageCn, messageEn) {
if (!feedback) {
return;
}
const normalizedTone = ['success', 'warning', 'error', 'info'].indexOf(tone) >= 0 ? tone : 'info';
feedback.classList.remove('is-success', 'is-warning', 'is-error', 'is-info');
feedback.classList.add(`is-${normalizedTone}`);
feedback.dataset.cn = messageCn || '';
feedback.dataset.en = messageEn || '';
feedback.textContent = pickLocaleText(messageCn, messageEn);
feedback.hidden = !(feedback.textContent && feedback.textContent.trim() !== '');
}
function setupProgressLookupAjax() {
const formElement = document.querySelector('.join-progress-query-form');
if (!formElement || typeof window.fetch !== 'function') {
return;
}
const config = getProgressLookupConfig();
if (!config) {
return;
}
const identityInput = formElement.querySelector('input[name="join_query_identity"]');
const submitButton = formElement.querySelector('button[type="submit"], input[type="submit"]');
const feedback = ensureProgressFeedbackNode(formElement);
formElement.addEventListener('submit', async (event) => {
event.preventDefault();
const identity = identityInput ? identityInput.value.trim() : '';
const payload = new URLSearchParams();
payload.set('action', config.action);
payload.set('nonce', config.nonce);
payload.set('join_progress_lookup', '1');
payload.set('join_query_identity', identity);
if (submitButton) {
submitButton.disabled = true;
submitButton.setAttribute('aria-busy', 'true');
}
setProgressFeedback(feedback, 'info', '查询中,请稍候…', 'Checking, please wait...');
try {
const response = await window.fetch(config.ajaxUrl, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
body: payload.toString(),
});
const result = await response.json();
if (!result || !result.success || !result.data) {
throw new Error('invalid_response');
}
const data = result.data;
setProgressFeedback(
feedback,
data.tone || 'info',
data.message_cn || '',
data.message_en || ''
);
} catch (error) {
setProgressFeedback(
feedback,
'error',
'查询失败,请稍后重试。',
'Lookup failed. Please try again later.'
);
} finally {
if (submitButton) {
submitButton.disabled = false;
submitButton.removeAttribute('aria-busy');
}
}
});
}
function detectJoinSubmitIntentFromElement(element) {
if (!element) {
return '';
}
const name = (element.getAttribute('name') || '').toLowerCase();
const value = String(element.value || element.textContent || '').toLowerCase();
if (name.indexOf('draft') !== -1 || value.indexOf('draft') !== -1 || value.indexOf('草稿') !== -1) {
return 'draft';
}
return 'submitted';
}
function ensureJoinSubmitNoticeNode() {
let notice = document.getElementById('joinSubmitNotice');
if (notice) {
return notice;
}
notice = document.querySelector('.join-submit-notice');
if (notice) {
notice.id = 'joinSubmitNotice';
return notice;
}
const head = document.querySelector('.join-head');
if (!head || !head.parentNode) {
return null;
}
notice = document.createElement('p');
notice.id = 'joinSubmitNotice';
notice.className = 'join-submit-notice';
notice.hidden = true;
head.parentNode.insertBefore(notice, head.nextSibling);
return notice;
}
function showJoinSubmitNotice(intent) {
const notice = ensureJoinSubmitNoticeNode();
if (!notice) {
return;
}
const isDraft = intent === 'draft';
const messageCn = isDraft ? '草稿已保存' : '你的报名表单已提交,感谢报名';
const messageEn = isDraft ? 'Draft saved.' : 'Your registration form has been submitted. Thank you for applying.';
notice.dataset.cn = messageCn;
notice.dataset.en = messageEn;
notice.textContent = pickLocaleText(messageCn, messageEn);
notice.hidden = false;
}
function setupRegistrationSubmitNoticeBridge() {
const formElement = document.querySelector('.join-form-content .frm_forms form');
if (!formElement) {
return;
}
let submitIntent = 'submitted';
formElement.addEventListener('click', (event) => {
const control = event.target.closest('button, input[type="submit"]');
const nextIntent = detectJoinSubmitIntentFromElement(control);
if (nextIntent) {
submitIntent = nextIntent;
}
});
formElement.addEventListener('submit', (event) => {
const submitter = event.submitter || null;
const nextIntent = detectJoinSubmitIntentFromElement(submitter);
if (nextIntent) {
submitIntent = nextIntent;
}
});
const formHost = formElement.closest('.join-form-content') || formElement.parentElement;
if (!formHost) {
return;
}
const updateSuccessMessage = () => {
const successNode = formHost.querySelector('.frm_message, .frm_success_style, .frm_success');
if (!successNode) {
return;
}
const lowerText = (successNode.textContent || '').toLowerCase();
const resolvedIntent = (lowerText.indexOf('draft') !== -1 || lowerText.indexOf('草稿') !== -1)
? 'draft'
: submitIntent;
const messageCn = resolvedIntent === 'draft' ? '草稿已保存' : '你的报名表单已提交,感谢报名';
const messageEn = resolvedIntent === 'draft' ? 'Draft saved.' : 'Your registration form has been submitted. Thank you for applying.';
successNode.dataset.cn = messageCn;
successNode.dataset.en = messageEn;
successNode.textContent = pickLocaleText(messageCn, messageEn);
showJoinSubmitNotice(resolvedIntent);
};
const observer = new MutationObserver(updateSuccessMessage);
observer.observe(formHost, { childList: true, subtree: true });
}
targetProgress = computeTargetProgress(); targetProgress = computeTargetProgress();
setupOverlayEntryAnimation(); setupOverlayEntryAnimation();
renderStageMarks(); renderStageMarks();
startWaves(); startWaves();
animateBoatToTarget(); animateBoatToTarget();
setupProgressLookupAjax();
setupRegistrationSubmitNoticeBridge();
})(); })();
+190 -17
View File
@@ -152,6 +152,43 @@ function itstudio_enqueue_scripts() {
} }
add_action('wp_enqueue_scripts', 'itstudio_enqueue_scripts'); add_action('wp_enqueue_scripts', 'itstudio_enqueue_scripts');
function itstudio_expand_news_notice_date_precision($the_date, $format, $post) {
$post_obj = $post instanceof WP_Post ? $post : get_post($post);
if (!($post_obj instanceof WP_Post)) {
return $the_date;
}
if (!in_array((string) $post_obj->post_type, array('announcement', 'news'), true)) {
return $the_date;
}
$format = (string) $format;
if ($format === '') {
$format = (string) get_option('date_format');
}
$lower = strtolower($format);
if (in_array($lower, array('c', 'r', 'u'), true)) {
return $the_date;
}
// Already has time precision.
if (preg_match('/[HhGgis]/', $format)) {
return $the_date;
}
$timestamp = function_exists('get_post_timestamp')
? get_post_timestamp($post_obj, 'date')
: false;
if (!$timestamp) {
return $the_date;
}
$format_with_time = rtrim($format) . ' H:i';
return wp_date($format_with_time, (int) $timestamp, wp_timezone());
}
add_filter('get_the_date', 'itstudio_expand_news_notice_date_precision', 10, 3);
function itstudio_register_sidebars() { function itstudio_register_sidebars() {
register_sidebar(array( register_sidebar(array(
'name' => __('Footer - Column 1', 'itstudio'), 'name' => __('Footer - Column 1', 'itstudio'),
@@ -572,12 +609,20 @@ function itstudio_join_get_recruitment_feed_items($join_runtime = array(), $limi
$excerpt = '...'; $excerpt = '...';
} }
$author_id = (int) get_post_field('post_author', $post_id);
$author = trim((string) get_the_author_meta('display_name', $author_id));
if ($author === '') {
$author = 'Unknown';
}
$items[] = array( $items[] = array(
'id' => $post_id, 'id' => $post_id,
'title' => $title, 'title' => $title,
'excerpt' => $excerpt, 'excerpt' => $excerpt,
'url' => $url, 'url' => $url,
'date' => get_the_date('Y-m-d', $post_id), 'date' => get_the_date('Y-m-d H:i', $post_id),
'date_iso' => get_the_date('c', $post_id),
'author' => $author,
'type' => get_post_type($post_id), 'type' => get_post_type($post_id),
); );
} }
@@ -2293,6 +2338,55 @@ function itstudio_join_normalize_lookup_value($field, $value) {
return strtolower($value); return strtolower($value);
} }
function itstudio_join_detect_progress_query_identity($raw_identity) {
$raw_identity = trim((string) $raw_identity);
$compacted = preg_replace('/\s+/u', '', $raw_identity);
$detected = array(
'raw' => $raw_identity,
'field' => '',
'value' => '',
);
if ($compacted === '') {
return $detected;
}
$email = sanitize_email($compacted);
if ($email !== '' && is_email($email)) {
$detected['field'] = 'email';
$detected['value'] = itstudio_join_normalize_lookup_value('email', $email);
return $detected;
}
if (preg_match('/^\d+$/', $compacted)) {
$digits = $compacted;
$len = strlen($digits);
if ($len >= 10 && $len <= 12) {
$detected['field'] = 'student_id';
$detected['value'] = itstudio_join_normalize_lookup_value('student_id', $digits);
return $detected;
}
if ($len >= 5 && $len <= 12) {
$detected['field'] = 'qq';
$detected['value'] = itstudio_join_normalize_lookup_value('qq', $digits);
return $detected;
}
return $detected;
}
if (preg_match('/^[\x{4e00}-\x{9fff}·]{2,20}$/u', $compacted)) {
$detected['field'] = 'name';
$detected['value'] = itstudio_join_normalize_lookup_value('name', $compacted);
return $detected;
}
return $detected;
}
function itstudio_join_parse_result_records($raw) { function itstudio_join_parse_result_records($raw) {
$raw = str_replace(array("\r\n", "\r"), "\n", (string) $raw); $raw = str_replace(array("\r\n", "\r"), "\n", (string) $raw);
if ($raw === '') { if ($raw === '') {
@@ -2462,30 +2556,43 @@ function itstudio_join_resolve_progress_lookup($runtime = array(), $request_sour
$settings = isset($runtime['settings']) && is_array($runtime['settings']) ? $runtime['settings'] : itstudio_join_get_settings(); $settings = isset($runtime['settings']) && is_array($runtime['settings']) ? $runtime['settings'] : itstudio_join_get_settings();
$request_source = is_array($request_source) ? $request_source : $_GET; $request_source = is_array($request_source) ? $request_source : $_GET;
$raw_identity = isset($request_source['join_query_identity']) ? sanitize_text_field(wp_unslash((string) $request_source['join_query_identity'])) : '';
$raw_name = isset($request_source['join_query_name']) ? sanitize_text_field(wp_unslash((string) $request_source['join_query_name'])) : ''; $raw_name = isset($request_source['join_query_name']) ? sanitize_text_field(wp_unslash((string) $request_source['join_query_name'])) : '';
$raw_qq = isset($request_source['join_query_qq']) ? sanitize_text_field(wp_unslash((string) $request_source['join_query_qq'])) : ''; $raw_qq = isset($request_source['join_query_qq']) ? sanitize_text_field(wp_unslash((string) $request_source['join_query_qq'])) : '';
$raw_email = isset($request_source['join_query_email']) ? sanitize_text_field(wp_unslash((string) $request_source['join_query_email'])) : ''; $raw_email = isset($request_source['join_query_email']) ? sanitize_text_field(wp_unslash((string) $request_source['join_query_email'])) : '';
$raw_student_id = isset($request_source['join_query_student_id']) ? sanitize_text_field(wp_unslash((string) $request_source['join_query_student_id'])) : ''; $raw_student_id = isset($request_source['join_query_student_id']) ? sanitize_text_field(wp_unslash((string) $request_source['join_query_student_id'])) : '';
$query = array( if (trim($raw_identity) === '') {
'name' => itstudio_join_normalize_lookup_value('name', $raw_name), foreach (array($raw_name, $raw_qq, $raw_email, $raw_student_id) as $legacy_value) {
'qq' => itstudio_join_normalize_lookup_value('qq', $raw_qq), $legacy_value = trim((string) $legacy_value);
'email' => itstudio_join_normalize_lookup_value('email', $raw_email), if ($legacy_value !== '') {
'student_id' => itstudio_join_normalize_lookup_value('student_id', $raw_student_id), $raw_identity = $legacy_value;
);
$has_query_value = false;
foreach ($query as $value) {
if ($value !== '') {
$has_query_value = true;
break; break;
} }
} }
}
$submitted = isset($request_source['join_progress_lookup']) || $has_query_value; $detected_identity = itstudio_join_detect_progress_query_identity($raw_identity);
$query = array(
'name' => '',
'qq' => '',
'email' => '',
'student_id' => '',
);
if ($detected_identity['field'] !== '') {
$query[$detected_identity['field']] = (string) $detected_identity['value'];
}
$has_input_value = trim((string) $raw_identity) !== '';
$has_query_value = $detected_identity['field'] !== '';
$submitted = isset($request_source['join_progress_lookup']) || $has_input_value;
$response = array( $response = array(
'submitted' => $submitted, 'submitted' => $submitted,
'has_query' => $has_query_value, 'has_query' => $has_query_value,
'identity' => $raw_identity,
'identity_field' => (string) ($detected_identity['field'] ?? ''),
'name' => $raw_name, 'name' => $raw_name,
'qq' => $raw_qq, 'qq' => $raw_qq,
'email' => $raw_email, 'email' => $raw_email,
@@ -2499,9 +2606,16 @@ function itstudio_join_resolve_progress_lookup($runtime = array(), $request_sour
return $response; return $response;
} }
if (!$has_input_value) {
$response['message_cn'] = '请输入姓名(中文)/ QQ / 邮箱 / 学号(10~12位数字)。';
$response['message_en'] = 'Please enter Name (Chinese) / QQ / Email / Student ID (10-12 digits).';
$response['tone'] = 'warning';
return $response;
}
if (!$has_query_value) { if (!$has_query_value) {
$response['message_cn'] = '请至少填写姓名、QQ、邮箱、学号中的一项。'; $response['message_cn'] = '无法识别输入内容,请输入姓名(中文)/ QQ / 邮箱 / 学号(10~12位数字)。';
$response['message_en'] = 'Please fill at least one item: name, QQ, email or student ID.'; $response['message_en'] = 'Input cannot be recognized. Please enter Name (Chinese) / QQ / Email / Student ID (10-12 digits).';
$response['tone'] = 'warning'; $response['tone'] = 'warning';
return $response; return $response;
} }
@@ -3102,9 +3216,68 @@ function itstudio_join_get_frontend_payload() {
'endTs' => isset($stage['end_ts']) ? $stage['end_ts'] : null, 'endTs' => isset($stage['end_ts']) ? $stage['end_ts'] : null,
); );
}, (array) ($runtime['stages'] ?? array()))), }, (array) ($runtime['stages'] ?? array()))),
'progressLookup' => array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'action' => 'itstudio_join_progress_lookup',
'nonce' => wp_create_nonce('itstudio_join_progress_lookup'),
),
); );
} }
function itstudio_join_ajax_progress_lookup() {
if (!check_ajax_referer('itstudio_join_progress_lookup', 'nonce', false)) {
wp_send_json_error(
array(
'tone' => 'error',
'message_cn' => '请求已过期,请刷新页面后重试。',
'message_en' => 'Request expired. Please refresh the page and try again.',
),
403
);
}
$runtime = itstudio_join_get_runtime_data();
$request_source = $_POST;
if (!isset($request_source['join_progress_lookup'])) {
$request_source['join_progress_lookup'] = '1';
}
$lookup = itstudio_join_resolve_progress_lookup($runtime, $request_source);
$tone = trim((string) ($lookup['tone'] ?? 'info'));
if (!in_array($tone, array('success', 'warning', 'error', 'info'), true)) {
$tone = 'info';
}
wp_send_json_success(
array(
'submitted' => !empty($lookup['submitted']),
'has_query' => !empty($lookup['has_query']),
'identity' => (string) ($lookup['identity'] ?? ''),
'identity_field' => (string) ($lookup['identity_field'] ?? ''),
'tone' => $tone,
'message_cn' => (string) ($lookup['message_cn'] ?? ''),
'message_en' => (string) ($lookup['message_en'] ?? ''),
)
);
}
add_action('wp_ajax_itstudio_join_progress_lookup', 'itstudio_join_ajax_progress_lookup');
add_action('wp_ajax_nopriv_itstudio_join_progress_lookup', 'itstudio_join_ajax_progress_lookup');
function itstudio_join_force_formidable_ajax_submit($form) {
if (!itstudio_is_join_page_context() || !is_object($form)) {
return $form;
}
if (!isset($form->options) || !is_array($form->options)) {
$form->options = array();
}
$form->options['ajax_submit'] = 1;
return $form;
}
add_filter('frm_pre_display_form', 'itstudio_join_force_formidable_ajax_submit', 20);
function itstudio_join_enqueue_assets() { function itstudio_join_enqueue_assets() {
if (!itstudio_is_join_page_context()) { if (!itstudio_is_join_page_context()) {
return; return;
@@ -3114,7 +3287,7 @@ function itstudio_join_enqueue_assets() {
'itstudio-join-page', 'itstudio-join-page',
get_template_directory_uri() . '/assets/css/join-page.css', get_template_directory_uri() . '/assets/css/join-page.css',
array('itstudio-content'), array('itstudio-content'),
'1.1.0' '1.1.1'
); );
wp_enqueue_script( wp_enqueue_script(
@@ -3129,7 +3302,7 @@ function itstudio_join_enqueue_assets() {
'itstudio-join-canvas', 'itstudio-join-canvas',
get_template_directory_uri() . '/assets/js/join-canvas.js', get_template_directory_uri() . '/assets/js/join-canvas.js',
array('itstudio-animejs'), array('itstudio-animejs'),
'1.1.0', '1.1.1',
true true
); );
+2 -2
View File
@@ -175,7 +175,7 @@
</h3> </h3>
<div class="landing-feed-meta"> <div class="landing-feed-meta">
<span class="landing-feed-author"><?php echo esc_html(get_the_author()); ?></span> <span class="landing-feed-author"><?php echo esc_html(get_the_author()); ?></span>
<time datetime="<?php echo get_the_date('c'); ?>"><?php echo get_the_date('Y-m-d'); ?></time> <time datetime="<?php echo esc_attr(get_the_date('c')); ?>"><?php echo esc_html(get_the_date('Y-m-d H:i')); ?></time>
</div> </div>
<p class="landing-feed-excerpt"><?php echo esc_html($announcement_excerpt); ?></p> <p class="landing-feed-excerpt"><?php echo esc_html($announcement_excerpt); ?></p>
</li> </li>
@@ -218,7 +218,7 @@
</h3> </h3>
<div class="landing-feed-meta"> <div class="landing-feed-meta">
<span class="landing-feed-author"><?php echo esc_html(get_the_author()); ?></span> <span class="landing-feed-author"><?php echo esc_html(get_the_author()); ?></span>
<time datetime="<?php echo get_the_date('c'); ?>"><?php echo get_the_date('Y-m-d'); ?></time> <time datetime="<?php echo esc_attr(get_the_date('c')); ?>"><?php echo esc_html(get_the_date('Y-m-d H:i')); ?></time>
</div> </div>
<p class="landing-feed-excerpt"><?php echo esc_html($blog_excerpt); ?></p> <p class="landing-feed-excerpt"><?php echo esc_html($blog_excerpt); ?></p>
</li> </li>
+63 -74
View File
@@ -117,28 +117,6 @@ if ($is_post_request && function_exists('itstudio_join_detect_form_submission_st
</script> </script>
<?php endif; ?> <?php endif; ?>
<section class="join-news-strip" aria-label="Recruitment News">
<?php if (!empty($join_feed_items)) : ?>
<div class="join-news-strip-track">
<?php foreach ($join_feed_items as $feed_item) : ?>
<?php
$feed_title = isset($feed_item['title']) ? (string) $feed_item['title'] : '';
$feed_excerpt = isset($feed_item['excerpt']) ? (string) $feed_item['excerpt'] : '';
$feed_url = isset($feed_item['url']) ? (string) $feed_item['url'] : '';
?>
<article class="join-news-item">
<h3 class="join-news-item-title">
<a href="<?php echo esc_url($feed_url); ?>"><?php echo esc_html($feed_title); ?></a>
</h3>
<p class="join-news-item-excerpt"><?php echo esc_html($feed_excerpt); ?></p>
</article>
<?php endforeach; ?>
</div>
<?php else : ?>
<p class="join-news-strip-empty" data-cn="暂无可展示的招新新闻通告" data-en="No recruitment updates available yet.">暂无可展示的招新新闻通告</p>
<?php endif; ?>
</section>
<section class="join-hero"> <section class="join-hero">
<div class="join-canvas-shell"> <div class="join-canvas-shell">
<div class="join-stage-photo-frame"> <div class="join-stage-photo-frame">
@@ -305,22 +283,19 @@ if ($is_post_request && function_exists('itstudio_join_detect_form_submission_st
</ol> </ol>
</section> </section>
<?php <?php
$show_registration_form = $is_registration_open; $show_registration_form = $is_registration_open;
$show_progress_query_form = $is_progress_query_open; $show_progress_query_form = $is_progress_query_open;
$visible_form_count = ($show_registration_form ? 1 : 0) + ($show_progress_query_form ? 1 : 0); $visible_form_count = ($show_registration_form ? 1 : 0) + ($show_progress_query_form ? 1 : 0);
?> ?>
<?php if ($visible_form_count > 0) : ?> <section class="join-info-layout">
<section class="join-forms-grid<?php echo $visible_form_count === 1 ? ' is-single' : ''; ?>"> <div class="join-info-main<?php echo $visible_form_count === 0 ? ' is-empty' : ''; ?>">
<?php if ($show_registration_form) : ?> <?php if ($show_registration_form) : ?>
<h2 class="join-panel-title" data-cn="报名表单" data-en="Registration Form">报名表单</h2>
<article class="join-form-card"> <article class="join-form-card">
<header class="join-form-head">
<h2 data-cn="报名表单" data-en="Registration Form">报名表单</h2>
<p data-cn="仅在报名阶段开放" data-en="Available during registration stage only.">仅在报名阶段开放</p>
</header>
<div class="join-form-content"> <div class="join-form-content">
<?php if (!$has_formidable) : ?> <?php if (!$has_formidable) : ?>
<p class="join-form-tip" data-cn="未检测到 Formidable Forms 插件 请先启用插件" data-en="Formidable Forms is not active.">未检测到 Formidable Forms 插件 请先启用插件</p> <p class="join-form-tip" data-cn="未检测到 Formidable Forms 插件请先启用插件" data-en="Formidable Forms is not active.">未检测到 Formidable Forms 插件请先启用插件</p>
<?php elseif ($signup_shortcode === '') : ?> <?php elseif ($signup_shortcode === '') : ?>
<p class="join-form-tip" data-cn="请在 设置 > 招新设置 中填写报名表单 Shortcode" data-en="Please configure the registration form shortcode in Settings > Recruitment Settings.">请在 设置 > 招新设置 中填写报名表单 Shortcode</p> <p class="join-form-tip" data-cn="请在 设置 > 招新设置 中填写报名表单 Shortcode" data-en="Please configure the registration form shortcode in Settings > Recruitment Settings.">请在 设置 > 招新设置 中填写报名表单 Shortcode</p>
<?php else : ?> <?php else : ?>
@@ -331,56 +306,20 @@ if ($is_post_request && function_exists('itstudio_join_detect_form_submission_st
<?php endif; ?> <?php endif; ?>
<?php if ($show_progress_query_form) : ?> <?php if ($show_progress_query_form) : ?>
<h2 class="join-panel-title" data-cn="录取进度查询" data-en="Admission Progress Lookup">录取进度查询</h2>
<article class="join-form-card"> <article class="join-form-card">
<header class="join-form-head">
<h2 data-cn="录取进度查询" data-en="Admission Progress Lookup">录取进度查询</h2>
<p data-cn="报名结束后至录取结果公布阶段可查询" data-en="Available after registration ends until the final result release stage.">报名结束后至录取结果公布阶段可查询</p>
</header>
<div class="join-form-content"> <div class="join-form-content">
<form method="get" class="join-progress-query-form"> <form method="get" class="join-progress-query-form">
<div class="join-progress-query-grid"> <div class="join-progress-query-grid">
<label class="join-progress-query-field"> <label class="join-progress-query-field">
<span data-cn="姓名" data-en="Name">姓名</span> <span data-cn="姓名 / QQ / 邮箱 / 学号" data-en="Name / QQ / Email / Student ID">姓名 / QQ / 邮箱 / 学号</span>
<input <input
type="text" type="text"
name="join_query_name" name="join_query_identity"
value="<?php echo esc_attr((string) ($progress_lookup['name'] ?? '')); ?>" value="<?php echo esc_attr((string) ($progress_lookup['identity'] ?? '')); ?>"
data-cn-placeholder="请输入姓名" data-cn-placeholder="请输入中文姓名 / QQ / 邮箱 / 10~12位学号"
data-en-placeholder="Enter name" data-en-placeholder="Enter Name / QQ / Email / Student ID (10-12 digits)"
placeholder="请输入姓名" placeholder="请输入中文姓名 / QQ / 邮箱 / 10~12位学号"
>
</label>
<label class="join-progress-query-field">
<span data-cn="QQ" data-en="QQ">QQ</span>
<input
type="text"
name="join_query_qq"
value="<?php echo esc_attr((string) ($progress_lookup['qq'] ?? '')); ?>"
data-cn-placeholder="请输入QQ"
data-en-placeholder="Enter QQ"
placeholder="请输入QQ"
>
</label>
<label class="join-progress-query-field">
<span data-cn="邮箱" data-en="Email">邮箱</span>
<input
type="text"
name="join_query_email"
value="<?php echo esc_attr((string) ($progress_lookup['email'] ?? '')); ?>"
data-cn-placeholder="请输入邮箱"
data-en-placeholder="Enter email"
placeholder="请输入邮箱"
>
</label>
<label class="join-progress-query-field">
<span data-cn="学号" data-en="Student ID">学号</span>
<input
type="text"
name="join_query_student_id"
value="<?php echo esc_attr((string) ($progress_lookup['student_id'] ?? '')); ?>"
data-cn-placeholder="请输入学号"
data-en-placeholder="Enter student ID"
placeholder="请输入学号"
> >
</label> </label>
</div> </div>
@@ -406,8 +345,58 @@ if ($is_post_request && function_exists('itstudio_join_detect_form_submission_st
</div> </div>
</article> </article>
<?php endif; ?> <?php endif; ?>
</section>
<?php if ($visible_form_count === 0) : ?>
<article class="join-form-card join-form-card-placeholder">
<div class="join-form-content">
<p class="join-form-tip" data-cn="当前阶段暂无可操作表单" data-en="No available form in the current stage.">当前阶段暂无可操作表单</p>
</div>
</article>
<?php endif; ?> <?php endif; ?>
</div>
<aside class="join-info-side">
<h2 class="join-panel-title" data-cn="招新资讯" data-en="Related News">招新资讯</h2>
<section class="join-news-strip" aria-label="Related News">
<?php if (!empty($join_feed_items)) : ?>
<div class="join-news-strip-track">
<?php foreach ($join_feed_items as $feed_item) : ?>
<?php
$feed_title = isset($feed_item['title']) ? (string) $feed_item['title'] : '';
$feed_excerpt = isset($feed_item['excerpt']) ? (string) $feed_item['excerpt'] : '';
$feed_url = isset($feed_item['url']) ? (string) $feed_item['url'] : '';
$feed_author = isset($feed_item['author']) ? (string) $feed_item['author'] : '';
$feed_date = isset($feed_item['date']) ? (string) $feed_item['date'] : '';
$feed_date_iso = isset($feed_item['date_iso']) ? (string) $feed_item['date_iso'] : '';
?>
<article class="join-news-item">
<h3 class="join-news-item-title">
<a href="<?php echo esc_url($feed_url); ?>"><?php echo esc_html($feed_title); ?></a>
</h3>
<div class="join-news-item-meta">
<?php if ($feed_author !== '') : ?>
<span class="join-news-item-meta-author">
<span data-cn="发布者" data-en="Author">发布者</span>
<?php echo esc_html($feed_author); ?>
</span>
<?php endif; ?>
<?php if ($feed_date !== '') : ?>
<time class="join-news-item-meta-time" datetime="<?php echo esc_attr($feed_date_iso !== '' ? $feed_date_iso : $feed_date); ?>">
<span data-cn="时间" data-en="Time">时间</span>
<?php echo esc_html($feed_date); ?>
</time>
<?php endif; ?>
</div>
<p class="join-news-item-excerpt"><?php echo esc_html($feed_excerpt); ?></p>
</article>
<?php endforeach; ?>
</div>
<?php else : ?>
<p class="join-news-strip-empty" data-cn="暂无可展示的招新新闻通告" data-en="No recruitment updates available yet.">暂无可展示的招新新闻通告</p>
<?php endif; ?>
</section>
</aside>
</section>
<?php if ($is_post_request) : ?> <?php if ($is_post_request) : ?>
<script> <script>
+1 -1
View File
@@ -37,7 +37,7 @@
<div class="single-article-meta"> <div class="single-article-meta">
<span class="single-article-meta-item"> <span class="single-article-meta-item">
<span class="single-article-meta-label" data-cn="发布日期:" data-en="Published: ">Published: </span> <span class="single-article-meta-label" data-cn="发布日期:" data-en="Published: ">Published: </span>
<time class="single-article-meta-value" datetime="<?php echo esc_attr(get_the_date('c')); ?>"><?php echo esc_html(get_the_date('Y年m月d日')); ?></time> <time class="single-article-meta-value" datetime="<?php echo esc_attr(get_the_date('c')); ?>"><?php echo esc_html(get_the_date('Y-m-d H:i')); ?></time>
</span> </span>
<span class="single-article-meta-item"> <span class="single-article-meta-item">
<span class="single-article-meta-label" data-cn="作者:" data-en="Author: ">Author: </span> <span class="single-article-meta-label" data-cn="作者:" data-en="Author: ">Author: </span>