睡前下载闲鱼打算翻订单找购买商品的参数,见一条11月7日的未读消息,正是今春购买兰花宋梅的卖家大哥发我的,一位扬州的养花大佬,问我宋梅养的怎么样,原来他那盆分苗惠让我的宋梅今夏因天气原因意外死亡。对此颇感惋惜,那花引自杭州,去年上花5杆,竟有4杆双花。

同时,大哥表示希望来年春天能从我这引回宋梅,我也希望促成好事,成人之美。受惠于近几年兰花价格的大幅下降,传统兰花名品得以广泛传播,我这种普通人也能不较锱铢轻易拥有这些经典品种,跟同好分享何乐不为。

宋梅,又名宋锦旋梅,于清乾隆年间由绍兴宋氏选出,自发现至今的200多年里春兰梅瓣者无出其右。

用了一段时间 iOS 的 dark mode 感觉良好,特别是夜间看手机不会很刺眼。周末给网站加了暗黑模式功能,检测用户设备对用户切换到暗黑模式,不需要插件,只要一小段 js 和 css 代码即可。

提醒:这里有更好的方法

实现原理

  1. 通过 js 获取当前访问设备的主题色设置模式做判断给 html 页面增加样式;
  2. 利用增加的样式和 css 的自定义属性切换 css 属性值。

利用 js 代码获取当前访问设备的主题色设置模式,并在页面 html 的 body 标签上增加 css 类 dark

if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches{
document.querySelector("body").classList.add("dark")
};

其中,prefers-color-scheme CSS 媒体特性用于检测用户是否有将系统的主题色设置为亮色或者暗色,详情请见 prefers-color-scheme

处理 css 样式:第一步,定义暗黑模式和正常模式下的 css 样式

/* 这里定义暗黑模式下的样式 */
.dark{
--dark-background:#333;
--dark-color:#333;
}
/* root 伪类定义正常模式下的样式 */
:root{
--light-background:1px solid #e5e5e5;
--light-color:1px solid #555;
}

处理 css 样式:第二步,修改暗黑模式下需要调整的 css 样式

这里需要用到 var() 函数的备用值功能来处理正常模式下的样式,否则在正常模式下获取不到样式。

.wrapper{
background:var(--dark-background,var(--light-background));
color:var(--dark-color,#666);
color:#666; /* 此处属性的目的是兼容不支持 css 自定义属性的浏览器 */
}

什么是 css 自定义属性

自定义属性(有时候也被称作 CSS 变量或者级联变量)是由 CSS 作者定义的,它包含的值可以在整个文档中重复使用。

使用 css 自定义属性

css 自定义属性使用起来非常简单和方便,如下:
由自定义属性标记设定值,如: --dark-color: #000;
由 var() 函数来获取值,如: color: var(--dark-color);
以上效果等同于 color:#000;
var() 函数可以定义多个备用值 (fallback value),当给定值未定义时将会用备用值替换,语法为:

var( <custom-property-name> [, <declaration-value> ]? )

例如:

.dark {--dark-color: #333}
.light {-—light-color: #eee}
body {
color: var(--dark-color, —light-color)
}

当 --dark-color 未定义或是无效值时,取 —light-color 。

为了实现暗黑模式的切换,我们可以这样处理:

.dark {—-background-color: #333}
.light {—-background-color: #eee}
body {
background: var(--background-color)
}

如此,就可以在系统切换到深色模式时给 body 加上 dark 类:<body class=“dark”>;当切回浅色模式时用 light 替换掉 dark:<body class=“dark”>

灵活使用 css 自定义属性会来带意想不到的效果。
更多请见:使用 CSS 自定义属性(变量)

浏览器兼容性

本文用到的 CSS 自定义属性和 prefers-color-scheme 可能需要考虑浏览器的兼容性问题,关于浏览器兼容性详情请见各自的文档说明:

  1. prefers-color-scheme
  2. 使用 CSS 自定义属性(变量)

单独制作了一个日记本来记录关于孩子的一些事情,为方便浏览需要将 post 发布日期改成类似 QQ 亲子相册那样,根据孩子出生日期和照片拍摄日期计算出来年龄,形如:生出、7天、1个月、 3岁5个月、12岁生日。如:5岁3个月

这个功能实现起来需要指定出生日期、获取Post的发布日期,剩下的就是日期判断,代码大概如下,放置于主题的 function.php 文件中:

// get_brave_year_of_age
function get_brave_year_of_age($birth_date) {
    $post_date = date_create(get_the_time('Y-m-d'));
    $interval = date_diff($birth_date, $post_date);
    $prefix = '';
    if ($interval->format('%R') === '-') {
        $prefix = '出生前';
    }
    $result = '';
    if ($interval->format('%y') === '0') {
        if ($interval->format('%m') === '0') {
            if ($interval->format('%d') === '0') {
                $result = '出生';
            } else if ($interval->format('%d') > 0) {
                $result = $interval->format('%d天');
            }
        } else if ($interval->format('%m') > 0) {
            $result = $interval->format('%m个月');
        }
        } else if ($interval->format('%y') > 0) {
            if ($interval->format('%m') === '0') {
                if ($interval->format('%d') === '0') {
                    $result = $interval->format('%y岁生日');
                } else if ($interval->format('%d') > 0) {
                    $result = $interval->format('%y岁');
                }
        } else if ($interval->format('%m') > 0) {
            $result = $interval->format('%y岁%m个月');
        }
    }
    echo $prefix . $result;
}

在需要显示的地方加上下面这段输出即可:

<?php get_brave_year_of_age(); ?>

极个别情况会发一下私密的东西,有时疏忽会忘记设置私密,以下代码可以实现在特定形式在发布时自动设置私密的功能,这段代码在浏览器上是生效的,在 WordPress APP 上却无法正常工作,不知何故,已支持 WordPress APP,之前的问题在于使用get_post_format()获取日志格式未加参数$post_id,加上参数即可,更新后的代码如下:

// aside 形式发布时自动置为私密
function set_post_to_private( $data, $postarr ) {
$brave_post_format = get_post_format($postarr['ID']);
if ( $brave_post_format === 'aside' && $data['post_status'] === 'publish' ) {
$data['post_status'] = 'private'; // 发布时状态设置为私密
}
return $data;
}
add_filter( 'wp_insert_post_data', 'set_post_to_private', 10, 2 );

参考:wp_insert_post_data

Android 平台的 WordPress app 有这样一个功能:预置一段自定义的话,发布时会自动附加在文末,如“发自 WordPress for Android”,见下图,iOS平台始终没有这个功能。最近给网站添加了类似功能,实现在发布时后台自动获取当前终端信息,获取到的终端信息被添加到自定义字段中,在页面上想要展示的位置展示之。加到自定义字段的好处是可以自由控制,实现更多个性化的功能。

实现的关键是 Mobile_Detect 插件和 save_post 钩子,步骤如下:

获取 Mobile_Detect 插件

第一步,需要用到插件 Mobile_Detect
以获取发布终端的设备信息,这个插件就一个文件,名为 Mobile_Detect.php,点此下载最新的 Mobile_Detect.php 文件,解压找到 Mobile_Detect.php 文件放至 WordPress 主题目录(示例代码放在主题文件夹下的p目文件夹里)。

save_post 处理

第二步,将以下两段代码放到在用主题的 functions.php 文件中,保存。第一段代码的作用是发布时获取终端设备信息并存入当前日志的自定义字段;第二段代码的作用是定义存放于自定义代码中的设备信息在前端界面的展示逻辑。

// Auto_save post device meta data
function brave_post_device_meta( $post_id ) {

//自动保存时不处理
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}

$current_post_device_name = get_post_meta($post->ID, 'post_device_name', true);
$current_post_device_ver = get_post_meta($post->ID, 'post_device_ver', true);
//已存在记录的、已发布的、私密的不做更新
if ( current_user_can( 'edit_post', $post_id ) && ! in_array( get_post_status ( $post_id ) , array( 'private', 'publish') )) {
//加载插件
include_once( get_template_directory() . '/p/Mobile_Detect.php' );
$detect = new Mobile_Detect;
if ( $detect->isMobile() && !$detect->isTablet()) {
//手机
if ( $detect->isiPhone() ){
$device_name = 'iPhone';
$device_ver = $detect->version('iOS');
} else if ( $detect->isAndroidOS() ){
$device_name = 'Android';
$device_ver = $detect->version('Android');
}
} else if ( $detect->isMobile() && $detect->isTablet() ) {
//平板
if ( $detect->isiPad() ){
$device_name = 'iPad';
$device_ver = $detect->version('iOS');
} else if ( $detect->isKindle() ){
$device_name = 'Kindle';
} else if ( $detect->isAndroidOS() ){
$device_name = 'Android Tablet';
$device_ver = $detect->version('Android');
}
} else {
//桌面
if ( $detect->version('Chrome') ){
$device_name = 'Chrome';
$device_ver = $detect->version('Chrome');
} else if ( $detect->version('Firefox') ){
$device_name = 'Firefox';
$device_ver = $detect->version('Firefox');
} else if ( $detect->version('Safari') ){
$device_name = 'Safari';
$device_ver = $detect->version('Safari');
}
}
$current_post_device_name = $device_name;
$current_post_device_ver = $device_ver;
update_post_meta( $post_id, 'post_device_name', $current_post_device_name );
update_post_meta( $post_id, 'post_device_ver', $current_post_device_ver );
} else {
return;
}
}
add_action( 'save_post', 'brave_post_device_meta');

//前端展示,自由调整样式

//brave_post_device
function brave_post_device() {
global $post;
$post_device_name = get_post_meta($post->ID, 'post_device_name', true);
$post_device_ver = get_post_meta($post->ID, 'post_device_ver', true);
$post_device_ver = str_replace(array('_', ' ', '/'), '.', $post_device_ver);//版本号替换:将间以_空格/的间隔符替换为.
$post_device_ver = ' '.substr($post_device_ver,0,strpos($post_device_ver,'.'));//移除第一个小数点后的数字
$post_device_pfx = 'via '; //前缀
$post_device = $post_device_pfx . $post_device_name;

if ( $post_device_name == "iPhone" ) {
echo "<span class='ml'>$post_device</span>";
} else if ( $post_device_name == "Android" ) {
echo "<span class='ml'>$post_device</span>";
} else if ( $post_device_name == "iPad" ) {
echo "<span class='ml'>$post_device</span>";
} else if ( $post_device_name == "Android Tablet" ) {
echo "<span class='ml'>Android平板</span>";
} else if ( $post_device_name == "Kindle" ) {
echo "<span class='ml'>$post_device</span>";
} else if ( $post_device_name == "Firefox" ) {
echo "<span class='ml'>$post_device</span>";
} else if ( $post_device_name == "Chrome" ) {
echo "<span class='ml'>$post_device</span>";
} else if ( $post_device_name == "Safari" ) {
echo "<span class='ml'>$post_device</span>";
}
}

第三步,在你希望展示的地方加上下面代码,行了,最终效果见下图。

<?php echo brave_pub_device(); ?>

这里仅粗略检测设备平台,mobiledetect 插件功能非常强大,颗粒度能够做的更细,如输出形如这样的平台和版本号信息:iOS/Android、iPhone OS 13.6、Firefox/Chrome。

参考:
mobiledetect:http://mobiledetect.net
save_post:https://developer.wordpress.org/reference/hooks/save_post/