WordPress函数force_balance_tags()确保文本打开HTML标签正确关闭

WordPress函数force_balance_tags()确保文本打开HTML标签正确关闭

WordPress函数force_balance_tags()确保文本打开HTML标签正确关闭

  在 WordPress CMS内容管理系统中,balanceTags()一个内置函数,balanceTags()是WordPress中用于平衡HTML标签的一个函数。该函数的主要作用是:平衡HTML标签,使得标签正确闭合。处理的HTML内容字符串。返回值平衡后的HTML字符串.

  推荐:[最新版]Filter Everything插件下载WordPress通用过滤器插件

force_balance_tags函数基本语法

描述

  使用修改后的堆栈平衡字符串的标签

用法

$text = "<b>Some text";
$balanced_text = force_balance_tags($text);
  • $text (string) – HTML 标签要平衡的文本。

  推荐:WordPress函数block_template_part()打印特定的块模板

force_balance_tags函数

  force_balance_tags() 可以无条件闭合HTML标签,但可能会导致内容格式问题,需要谨慎使用(源文件可参考这里

function force_balance_tags( $text ) {
	$tagstack  = array();
	$stacksize = 0;
	$tagqueue  = '';
	$newtext   = '';
	// Known single-entity/self-closing tags.
	$single_tags = array( 'area', 'base', 'basefont', 'br', 'col', 'command', 'embed', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param', 'source', 'track', 'wbr' );
	// Tags that can be immediately nested within themselves.
	$nestable_tags = array( 'article', 'aside', 'blockquote', 'details', 'div', 'figure', 'object', 'q', 'section', 'span' );

	// WP bug fix for comments - in case you REALLY meant to type '< !--'.
	$text = str_replace( '< !--', '<    !--', $text );
	// WP bug fix for LOVE <3 (and other situations with '<' before a number).
	$text = preg_replace( '#<([0-9]{1})#', '&lt;$1', $text );

	/**
	 * Matches supported tags.
	 *
	 * To get the pattern as a string without the comments paste into a PHP
	 * REPL like `php -a`.
	 *
	 * @see https://html.spec.whatwg.org/#elements-2
	 * @see https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
	 *
	 * @example
	 * ~# php -a
	 * php > $s = [paste copied contents of expression below including parentheses];
	 * php > echo $s;
	 */
	$tag_pattern = (
		'#<' . // Start with an opening bracket.
		'(/?)' . // Group 1 - If it's a closing tag it'll have a leading slash.
		'(' . // Group 2 - Tag name.
			// Custom element tags have more lenient rules than HTML tag names.
			'(?:[a-z](?:[a-z0-9._]*)-(?:[a-z0-9._-]+)+)' .
				'|' .
			// Traditional tag rules approximate HTML tag names.
			'(?:[\w:]+)' .
		')' .
		'(?:' .
			// We either immediately close the tag with its '>' and have nothing here.
			'\s*' .
			'(/?)' . // Group 3 - "attributes" for empty tag.
				'|' .
			// Or we must start with space characters to separate the tag name from the attributes (or whitespace).
			'(\s+)' . // Group 4 - Pre-attribute whitespace.
			'([^>]*)' . // Group 5 - Attributes.
		')' .
		'>#' // End with a closing bracket.
	);

	while ( preg_match( $tag_pattern, $text, $regex ) ) {
		$full_match        = $regex[0];
		$has_leading_slash = ! empty( $regex[1] );
		$tag_name          = $regex[2];
		$tag               = strtolower( $tag_name );
		$is_single_tag     = in_array( $tag, $single_tags, true );
		$pre_attribute_ws  = isset( $regex[4] ) ? $regex[4] : '';
		$attributes        = trim( isset( $regex[5] ) ? $regex[5] : $regex[3] );
		$has_self_closer   = str_ends_with( $attributes, '/' );

		$newtext .= $tagqueue;

		$i = strpos( $text, $full_match );
		$l = strlen( $full_match );

		// Clear the shifter.
		$tagqueue = '';
		if ( $has_leading_slash ) { // End tag.
			// If too many closing tags.
			if ( $stacksize <= 0 ) {
				$tag = '';
				// Or close to be safe $tag = '/' . $tag.

				// If stacktop value = tag close value, then pop.
			} elseif ( $tagstack[ $stacksize - 1 ] === $tag ) { // Found closing tag.
				$tag = '</' . $tag . '>'; // Close tag.
				array_pop( $tagstack );
				--$stacksize;
			} else { // Closing tag not at top, search for it.
				for ( $j = $stacksize - 1; $j >= 0; $j-- ) {
					if ( $tagstack[ $j ] === $tag ) {
						// Add tag to tagqueue.
						for ( $k = $stacksize - 1; $k >= $j; $k-- ) {
							$tagqueue .= '</' . array_pop( $tagstack ) . '>';
							--$stacksize;
						}
						break;
					}
				}
				$tag = '';
			}
		} else { // Begin tag.
			if ( $has_self_closer ) {
				/*
				 * If it presents itself as a self-closing tag, but it isn't a known single-entity self-closing tag,
				 * then don't let it be treated as such and immediately close it with a closing tag.
				 * The tag will encapsulate no text as a result.
				 */
				if ( ! $is_single_tag ) {
					$attributes = trim( substr( $attributes, 0, -1 ) ) . "></$tag";
				}
			} elseif ( $is_single_tag ) {
				// Else if it's a known single-entity tag but it doesn't close itself, do so.
				$pre_attribute_ws = ' ';
				$attributes      .= '/';
			} else {
				/*
				 * It's not a single-entity tag.
				 * If the top of the stack is the same as the tag we want to push, close previous tag.
				 */
				if ( $stacksize > 0 && ! in_array( $tag, $nestable_tags, true ) && $tagstack[ $stacksize - 1 ] === $tag ) {
					$tagqueue = '</' . array_pop( $tagstack ) . '>';
					--$stacksize;
				}
				$stacksize = array_push( $tagstack, $tag );
			}

			// Attributes.
			if ( $has_self_closer && $is_single_tag ) {
				// We need some space - avoid <br/> and prefer <br />.
				$pre_attribute_ws = ' ';
			}

			$tag = '<' . $tag . $pre_attribute_ws . $attributes . '>';
			// If already queuing a close tag, then put this tag on too.
			if ( ! empty( $tagqueue ) ) {
				$tagqueue .= $tag;
				$tag       = '';
			}
		}
		$newtext .= substr( $text, 0, $i ) . $tag;
		$text     = substr( $text, $i + $l );
	}

	// Clear tag queue.
	$newtext .= $tagqueue;

	// Add remaining text.
	$newtext .= $text;

	while ( $x = array_pop( $tagstack ) ) {
		$newtext .= '</' . $x . '>'; // Add remaining tags to close.
	}

	// WP fix for the bug with HTML comments.
	$newtext = str_replace( '< !--', '<!--', $newtext );
	$newtext = str_replace( '<    !--', '< !--', $newtext );

	return $newtext;
}

  推荐:WordPress函数email_exists()确定给定的电子邮件是否存在

如何使用force_balance_tags

  平衡简单文本,在此示例中,我们有一个文本字符串,其中粗体元素(<b>)缺少结束标记。

$text = "<b>Some bold text";
$balanced_text = force_balance_tags($text);
// The output will be "<b>Some bold text</b>"

  嵌套标签,当存在嵌套标签时,force_balance_tags()也可以平衡这些标签。

$text = "<div><p>Some text";
$balanced_text = force_balance_tags($text);
// The output will be "<div><p>Some text</p></div>"

  多个不平衡标签,当存在多个不平衡标签时,force_balance_tags()可以全部处理。

$text = "<div><p>Some text<b>Bold text";
$balanced_text = force_balance_tags($text);
// The output will be "<div><p>Some text<b>Bold text</b></p></div>"

  自动关闭标签,force_balance_tags()不会影响自闭合标签。

$text = "<div><img src='image.jpg'>";
$balanced_text = force_balance_tags($text);
// The output will be "<div><img src='image.jpg'></div>"

  没有标签,如果字符串中没有标签,force_balance_tags()不会更改字符串。

$text = "Just some text";
$balanced_text = force_balance_tags($text);
// The output will be "Just some text"

  推荐:WordPress函数capital_P_dangit()自动将WordPress中的P大写

  推荐:WordPress函数使用手册


滚动至顶部