Skip to content

Instantly share code, notes, and snippets.

@terrylinooo
Created October 13, 2023 06:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save terrylinooo/44ee18c0fa205f06a7bc6873fbe0faae to your computer and use it in GitHub Desktop.
Save terrylinooo/44ee18c0fa205f06a7bc6873fbe0faae to your computer and use it in GitHub Desktop.
Day 28
<?php
/**
* 鐵人賽示範:產生 Meta Box 區塊
*/
function airoseo_add_meta_box() {
add_meta_box(
'airyseo_post_metabox',
'Airy SEO',
'airyseo_post_metabox_callback',
'post',
'normal',
'default'
);
}
add_action( 'add_meta_boxes', 'airoseo_add_meta_box' );
/**
* 鐵人賽示範:產生 Meta Box 的內容
*
* @param WP_Post $post 當前文章物件.
*/
function airyseo_post_metabox_callback( $post ) {
wp_nonce_field( 'airyseo_create_nonce', 'airyseo_metabox_nonce' );
$title = get_post_meta( $post->ID, '_airyseo_title', true );
$description = get_post_meta( $post->ID, '_airyseo_description', true );
?>
<div id="airyseo-metabox">
<div class="airyseo-metabox__item">
<div class="airyseo-metabox__item-row">
<label for="airyseo-title">標題</label>
<div class="airyseo-metabox__seo-status">
<span class="seo-status__count">
<span class="seo-status__title--current">0</span>
<span class="airyseo-metabox__row--right__count__max">/ 60</span>
</span>
</div>
</div>
<div class="airyseo-metabox__item-row">
<input type="text" id="airyseo-title"
name="airyseo_title" value="<?php echo esc_attr( $title ); ?>" />
</div>
</div>
<div class="airyseo-metabox__item">
<div class="airyseo-metabox__item-row">
<label for="airyseo-description">描述</label>
<div class="airyseo-metabox__seo-status">
<span class="seo-status__count">
<span class="seo-status__description--current">0</span>
<span class="airyseo-metabox__row--right__count__max">/ 160</span>
</span>
</div>
</div>
<div class="airyseo-metabox__item-row">
<textarea id="airyseo-description" name="airyseo_description">
<?php echo esc_attr( $description ); ?>
</textarea>
</div>
</div>
</div>
<?php
}
/**
* 鐵人賽示範:儲存 Meta Box 資料
*
* @param int $post_id 當前文章 ID.
*/
function airyseo_save_metabox( $post_id ) {
if (
! isset( $_POST['airyseo_metabox_nonce'] ) ||
! current_user_can( 'edit_post', $post_id )
) {
return;
}
$nonce = sanitize_text_field( wp_unslash( $_POST['airyseo_metabox_nonce'] ) );
if ( ! wp_verify_nonce( $nonce, 'airyseo_create_nonce' ) ) {
return;
}
if ( isset( $_POST['airyseo_title'] ) ) {
$title = trim( sanitize_text_field( wp_unslash( $_POST['airyseo_title'] ) ) );
update_post_meta( $post_id, '_airyseo_title', $title );
}
if ( isset( $_POST['airyseo_description'] ) ) {
$description = trim( sanitize_text_field( wp_unslash( $_POST['airyseo_description'] ) ) );
update_post_meta( $post_id, '_airyseo_description', $description );
}
}
add_action( 'save_post', 'airyseo_save_metabox' );
/**
* 鐵人賽示範:載入 CSS 及 JS 檔案
*
* @param string $hook 當前頁面的 Hook 後綴.
*/
function airyseo_admin_scripts( $hook ) {
if ( 'post.php' !== $hook && 'post-new.php' === $hook ) {
return;
}
$css_file = plugin_dir_url( __FILE__ ) . 'assets/css/style.css';
$js_file = plugin_dir_url( __FILE__ ) . 'assets/js/metabox.js';
wp_register_style( 'airyseo_admin_css', $css_file, false, '1.0.0' );
wp_enqueue_style( 'airyseo_admin_css' );
wp_register_script( 'airyseo_admin_js', $js_file, array(), '1.0.0', true );
wp_enqueue_script( 'airyseo_admin_js' );
}
add_action( 'admin_enqueue_scripts', 'airyseo_admin_scripts' );
const initAirySeoMetabox = () => {
if (!document.querySelector('#airyseo-metabox')) {
return;
}
const titleChars = 60;
const titlePixels = 600;
const descriptionChars = 160;
const descriptionPixels = 920;
const getTextWidth = (text, font) => {
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
context.font = font;
let metrics = context.measureText(text);
return metrics.width;
}
const title = document.querySelector('#airyseo-title');
const description = document.querySelector('#airyseo-description');
const titleCharCounter = document.querySelector('.seo-status__title--current');
const titleDescriptionCounter = document.querySelector('.seo-status__description--current');
title.addEventListener('keyup', () => {
const pixels = getTextWidth(title.value, '20px Arial');
titleCharCounter.innerHTML = title.value.length;
if (title.value.length > titleChars || pixels > titlePixels) {
titleCharCounter.setAttribute('style', 'color: red');
} else if (titleCharCounter.hasAttribute('style')) {
titleCharCounter.removeAttribute('style');
}
});
description.addEventListener('keyup', () => {
const pixels = getTextWidth(description.value, '16px Arial');
titleDescriptionCounter.innerHTML = description.value.length;
if (description.value.length > descriptionChars || pixels > descriptionPixels) {
titleDescriptionCounter.setAttribute('style', 'color: red');
} else if (titleDescriptionCounter.hasAttribute('style')) {
titleDescriptionCounter.removeAttribute('style');
}
});
};
initAirySeoMetabox();
.airyseo-metabox__item {
width: 100%;
max-width: 500px;
}
.airyseo-metabox__item textarea {
resize: none;
width: 100%;
height: 100px;
}
.airyseo-metabox__item input {
width: 100%;
}
.airyseo-metabox__item-row {
padding: 0.25rem 0;
}
.airyseo-metabox__seo-status {
float: right;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment