函数文档

wp_staticize_emoji()

💡 云策文档标注

概述

wp_staticize_emoji() 函数用于将内容中的 emoji 转换为静态图片元素,以增强兼容性和显示效果。它通过检测文本中的 emoji 字符,将其替换为对应的 PNG 图片链接,并支持过滤器和忽略特定标签的处理。

关键要点

  • 函数接受一个字符串参数 $text,返回编码后的字符串。
  • 内部使用 wp_encode_emoji() 和 _wp_emoji_list() 辅助函数来处理 emoji 检测和转换。
  • 支持通过 apply_filters() 钩子 emoji_url 和 emoji_ext 自定义图片 CDN 地址和文件扩展名。
  • 在转换过程中会忽略 code、pre、style、script、textarea 等标签内的内容,避免破坏代码结构。
  • 函数从 WordPress 4.2.0 版本引入,主要用于前端显示和电子邮件中的 emoji 静态化。

代码示例

function wp_staticize_emoji( $text ) {
    // 检查文本是否包含 emoji 实体
    if ( ! str_contains( $text, '&#x' ) ) {
        // 如果文本为 ASCII 编码或无 emoji,直接返回
        if ( ( function_exists( 'mb_check_encoding' ) && mb_check_encoding( $text, 'ASCII' ) ) || ! preg_match( '/[^x00-x7F]/', $text ) ) {
            return $text;
        } else {
            $encoded_text = wp_encode_emoji( $text );
            if ( $encoded_text === $text ) {
                return $encoded_text;
            }
            $text = $encoded_text;
        }
    }
    // 获取 emoji 实体列表并替换为图片
    $emoji = _wp_emoji_list( 'entities' );
    $possible_emoji = array();
    foreach ( $emoji as $emojum ) {
        if ( str_contains( $text, $emojum ) ) {
            $possible_emoji[$emojum] = html_entity_decode( $emojum );
        }
    }
    if ( ! $possible_emoji ) {
        return $text;
    }
    $cdn_url = apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/17.0.2/72x72/' );
    $ext = apply_filters( 'emoji_ext', '.png' );
    // 处理文本,忽略特定标签
    $textarr = preg_split( '/()/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE );
    $output = '';
    $tags_to_ignore = 'code|pre|style|script|textarea';
    $ignore_block_element = '';
    for ( $i = 0; $i < count( $textarr ); $i++ ) {
        $content = $textarr[$i];
        // 检查是否进入忽略块
        if ( '' === $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')[s>]/', $content, $matches ) ) {
            $ignore_block_element = $matches[1];
        }
        // 如果不在忽略块中,替换 emoji
        if ( '' === $ignore_block_element && strlen( $content ) > 0 && '<' !== $content[0] ) {
            foreach ( $possible_emoji as $emojum => $emoji_char ) {
                if ( ! str_contains( $content, $emojum ) ) {
                    continue;
                }
                $file = str_replace( ';&#x', '-', $emojum );
                $file = str_replace( array( '&#x', ';' ), '', $file );
                $entity = sprintf( '', $cdn_url . $file . $ext, $emoji_char );
                $content = str_replace( $emojum, $entity, $content );
            }
        }
        // 检查是否退出忽略块
        if ( '' !== $ignore_block_element && '' === $content ) {
            $ignore_block_element = '';
        }
        $output .= $content;
    }
    // 移除多余的 U+FE0F 字符
    $output = str_replace( '️', '', $output );
    return $output;
}

注意事项

  • 函数依赖于 WordPress 核心的 emoji 处理函数,如 wp_encode_emoji() 和 _wp_emoji_list(),确保这些函数可用。
  • 使用过滤器 emoji_url 和 emoji_ext 可以自定义 emoji 图片的源地址和文件类型,适用于 CDN 或自定义部署场景。
  • 在转换时自动忽略 code、pre 等标签内的内容,防止破坏代码或样式,开发者应注意此行为以避免意外影响。
  • 函数从 4.2.0 版本开始提供,主要用于提升 emoji 在旧浏览器或邮件客户端中的兼容性。

📄 原文内容

Converts emoji to a static img element.

Parameters

$textstringrequired
The content to encode.

Return

string The encoded content.

Source

function wp_staticize_emoji( $text ) {
	if ( ! str_contains( $text, '&#x' ) ) {
		if ( ( function_exists( 'mb_check_encoding' ) && mb_check_encoding( $text, 'ASCII' ) ) || ! preg_match( '/[^x00-x7F]/', $text ) ) {
			// The text doesn't contain anything that might be emoji, so we can return early.
			return $text;
		} else {
			$encoded_text = wp_encode_emoji( $text );
			if ( $encoded_text === $text ) {
				return $encoded_text;
			}

			$text = $encoded_text;
		}
	}

	$emoji = _wp_emoji_list( 'entities' );

	// Quickly narrow down the list of emoji that might be in the text and need replacing.
	$possible_emoji = array();
	foreach ( $emoji as $emojum ) {
		if ( str_contains( $text, $emojum ) ) {
			$possible_emoji[ $emojum ] = html_entity_decode( $emojum );
		}
	}

	if ( ! $possible_emoji ) {
		return $text;
	}

	/** This filter is documented in wp-includes/formatting.php */
	$cdn_url = apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/17.0.2/72x72/' );

	/** This filter is documented in wp-includes/formatting.php */
	$ext = apply_filters( 'emoji_ext', '.png' );

	$output = '';
	/*
	 * HTML loop taken from smiley function, which was taken from texturize function.
	 * It'll never be consolidated.
	 *
	 * First, capture the tags as well as in between.
	 */
	$textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE );
	$stop    = count( $textarr );

	// Ignore processing of specific tags.
	$tags_to_ignore       = 'code|pre|style|script|textarea';
	$ignore_block_element = '';

	for ( $i = 0; $i < $stop; $i++ ) {
		$content = $textarr[ $i ];

		// If we're in an ignore block, wait until we find its closing tag.
		if ( '' === $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')>/', $content, $matches ) ) {
			$ignore_block_element = $matches[1];
		}

		// If it's not a tag and not in ignore block.
		if ( '' === $ignore_block_element && strlen( $content ) > 0 && '<' !== $content[0] && str_contains( $content, '&#x' ) ) {
			foreach ( $possible_emoji as $emojum => $emoji_char ) {
				if ( ! str_contains( $content, $emojum ) ) {
					continue;
				}

				$file = str_replace( ';&#x', '-', $emojum );
				$file = str_replace( array( '&#x', ';' ), '', $file );

				$entity = sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />', $cdn_url . $file . $ext, $emoji_char );

				$content = str_replace( $emojum, $entity, $content );
			}
		}

		// Did we exit ignore block?
		if ( '' !== $ignore_block_element && '</' . $ignore_block_element . '>' === $content ) {
			$ignore_block_element = '';
		}

		$output .= $content;
	}

	// Finally, remove any stray U+FE0F characters.
	$output = str_replace( '️', '', $output );

	return $output;
}

Hooks

apply_filters( ’emoji_ext’, string $extension )

Filters the extension of the emoji png files.

apply_filters( ’emoji_url’, string $url )

Filters the URL where emoji png images are hosted.

Changelog

VersionDescription
4.2.0Introduced.

User Contributed Notes

You must log in before being able to contribute a note or feedback.

{“prefetch”:[{“source”:”document”,”where”:{“and”:[{“href_matches”:”/*”},{“not”:{“href_matches”:[“/wp-*.php”,”/wp-admin/*”,”/files/*”,”/wp-content/*”,”/wp-content/plugins/*”,”/wp-content/themes/wporg-developer-2023/*”,”/wp-content/themes/wporg-parent-2021/*”,”/*\?(.+)”]}},{“not”:{“selector_matches”:”a[rel~=”nofollow”]”}},{“not”:{“selector_matches”:”.no-prefetch, .no-prefetch a”}}]},”eagerness”:”conservative”}]} var prism_settings = {“pluginUrl”:”https://developer.wordpress.org/wp-content/plugins/code-syntax-block/”}; //# sourceURL=mkaz-code-syntax-prism-js-js-extra var autocomplete = {“ajaxurl”:”https://developer.wordpress.org/wp-admin/admin-ajax.php”,”nonce”:”dc6f8fe9ee”,”post_type”:”wp-parser-function”}; //# sourceURL=autocomplete-js-extra wp.i18n.setLocaleData( { ‘text directionu0004ltr’: [ ‘ltr’ ] } ); //# sourceURL=wp-i18n-js-after var wporgFunctionReferenceI18n = {“copy”:”Copy”,”copied”:”Code copied”,”expand”:”Expand code”,”collapse”:”Collapse code”,”sourceFile”:”wp-includes/formatting.php”}; //# sourceURL=wporg-developer-function-reference-js-extra var quicktagsL10n = {“closeAllOpenTags”:”Close all open tags”,”closeTags”:”close tags”,”enterURL”:”Enter the URL”,”enterImageURL”:”Enter the URL of the image”,”enterImageDescription”:”Enter a description of the image”,”textdirection”:”text direction”,”toggleTextdirection”:”Toggle Editor Text Direction”,”dfw”:”Distraction-free writing mode”,”strong”:”Bold”,”strongClose”:”Close bold tag”,”em”:”Italic”,”emClose”:”Close italic tag”,”link”:”Insert link”,”blockquote”:”Blockquote”,”blockquoteClose”:”Close blockquote tag”,”del”:”Deleted text (strikethrough)”,”delClose”:”Close deleted text tag”,”ins”:”Inserted text”,”insClose”:”Close inserted text tag”,”image”:”Insert image”,”ul”:”Bulleted list”,”ulClose”:”Close bulleted list tag”,”ol”:”Numbered list”,”olClose”:”Close numbered list tag”,”li”:”List item”,”liClose”:”Close list item tag”,”code”:”Code”,”codeClose”:”Close code tag”,”more”:”Insert Read More tag”}; //# sourceURL=quicktags-js-extra var wporg_note_feedback = {“show”:”Show feedback”,”hide”:”Hide feedback”,”hide_feedback”:”Hide feedback form”,”add_feedback”:”Add feedback”}; //# sourceURL=wporg-developer-user-notes-feedback-js-extra var wporg_note_preview = {“ajaxurl”:”https://developer.wordpress.org/wp-admin/admin-ajax.php”,”nonce”:”119215fa41″,”preview”:”preview note”,”preview_empty”:”Nothing to preview”,”is_admin”:””}; //# sourceURL=wporg-developer-preview-js-extra _stq = window._stq || []; _stq.push([ “view”, {“v”:”ext”,”blog”:”209306761″,”post”:”16296″,”tz”:”0″,”srv”:”developer.wordpress.org”,”j”:”1:15.5″} ]); _stq.push([ “clickTrackerInit”, “209306761”, “16296” ]); //# sourceURL=jetpack-stats-js-before var wporgGlobalHeaderI18n = {“openSearchLabel”:”Open Search”,”closeSearchLabel”:”Close Search”,”overflowMenuLabel”:”More menu”}; //# sourceURL=wporg-global-header-script-js-extra {“baseUrl”:”https://s.w.org/images/core/emoji/17.0.2/72×72/”,”ext”:”.png”,”svgUrl”:”https://s.w.org/images/core/emoji/17.0.2/svg/”,”svgExt”:”.svg”,”source”:{“concatemoji”:”https://developer.wordpress.org/wp-includes/js/wp-emoji-release.min.js?ver=7.1-alpha-62239″}} /*! This file is auto-generated */ const a=JSON.parse(document.getElementById(“wp-emoji-settings”).textContent),o=(window._wpemojiSettings=a,”wpEmojiSettingsSupports”),s=[“flag”,”emoji”];function i(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(o,JSON.stringify(t))}catch(e){}}function c(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0);const a=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);return t.every((e,t)=>e===a[t])}function p(e,t){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var n=e.getImageData(16,16,1,1);for(let e=0;e{s[e]=t(o,e,n,a)}),s}function r(e){var t=document.createElement(“script”);t.src=e,t.defer=!0,document.head.appendChild(t)}a.supports={everything:!0,everythingExceptFlag:!0},new Promise(t=>{let n=function(){try{var e=JSON.parse(sessionStorage.getItem(o));if(“object”==typeof e&&”number”==typeof e.timestamp&&(new Date).valueOf(){i(n=e.data),r.terminate(),t(n)})}catch(e){}i(n=f(s,u,c,p))}t(n)}).then(e=>{for(const n in e)a.supports[n]=e[n],a.supports.everything=a.supports.everything&&a.supports[n],”flag”!==n&&(a.supports.everythingExceptFlag=a.supports.everythingExceptFlag&&a.supports[n]);var t;a.supports.everythingExceptFlag=a.supports.everythingExceptFlag&&!a.supports.flag,a.supports.everything||((t=a.source||{}).concatemoji?r(t.concatemoji):t.wpemoji&&t.twemoji&&(r(t.twemoji),r(t.wpemoji)))}); //# sourceURL=https://developer.wordpress.org/wp-includes/js/wp-emoji-loader.min.js