函数文档

meta_form()

💡 云策文档标注

概述

meta_form() 函数用于在自定义字段元框中输出表单,主要用于编辑文章时管理自定义字段。它通过查询数据库获取已有的 meta_key 列表,并生成下拉选择框和输入字段。

关键要点

  • 函数接受一个可选的 $post 参数,默认为 null,用于指定正在编辑的文章。
  • 使用 postmeta_form_keys 过滤器可以预定义 meta_key 列表,避免执行昂贵的数据库查询。
  • 使用 postmeta_form_limit 过滤器可以控制从数据库中检索的自定义字段数量,默认值为 30。
  • 函数内部会排除以 '_' 开头的受保护 meta_key,并使用 is_protected_meta() 进行验证。
  • 输出包括一个 meta_key 下拉选择框、一个 meta_value 输入框和一个添加按钮,使用 wp_nonce_field() 提供安全性。
  • 如果存在大量自定义字段,默认查询可能导致性能问题,建议通过过滤器或移除元框来优化。

代码示例

function admin_speedup_remove_post_meta_box() {
    global $post_type;
    if ( is_admin() && post_type_supports( $post_type, 'custom-fields' ) ) {
        remove_meta_box( 'postcustom', 'post', 'normal' );
    }
}
add_action( 'add_meta_boxes', 'admin_speedup_remove_post_meta_box' );

注意事项

当网站有大量自定义字段时,meta_form() 的默认查询可能影响后台编辑页面的加载速度,开发者应考虑使用 postmeta_form_keys 过滤器提供预定义列表或移除默认元框以提高性能。


📄 原文内容

Prints the form in the Custom Fields meta box.

Parameters

$postWP_Postoptional
The post being edited.

Default:null

Source

function meta_form( $post = null ) {
	global $wpdb;
	$post = get_post( $post );

	/**
	 * Filters values for the meta key dropdown in the Custom Fields meta box.
	 *
	 * Returning a non-null value will effectively short-circuit and avoid a
	 * potentially expensive query against postmeta.
	 *
	 * @since 4.4.0
	 *
	 * @param array|null $keys Pre-defined meta keys to be used in place of a postmeta query. Default null.
	 * @param WP_Post    $post The current post object.
	 */
	$keys = apply_filters( 'postmeta_form_keys', null, $post );

	if ( null === $keys ) {
		/**
		 * Filters the number of custom fields to retrieve for the drop-down
		 * in the Custom Fields meta box.
		 *
		 * @since 2.1.0
		 *
		 * @param int $limit Number of custom fields to retrieve. Default 30.
		 */
		$limit = apply_filters( 'postmeta_form_limit', 30 );

		$keys = $wpdb->get_col(
			$wpdb->prepare(
				"SELECT DISTINCT meta_key
				FROM $wpdb->postmeta
				WHERE meta_key NOT BETWEEN '_' AND '_z'
				HAVING meta_key NOT LIKE %s
				ORDER BY meta_key
				LIMIT %d",
				$wpdb->esc_like( '_' ) . '%',
				$limit
			)
		);
	}

	if ( $keys ) {
		natcasesort( $keys );
	}
	?>
<p><strong></strong></p>
<table id="newmeta">
<thead>
<tr>
<th class="left"><label for="metakeyselect"></label></th>
<th><label for="metavalue"></label></th>
</tr>
</thead>

<tbody>
<tr>
<td id="newmetaleft" class="left">
	
<select id="metakeyselect" name="metakeyselect">
<option value="#NONE#"></option>
		ID, $key ) ) {
				continue;
			}
			echo "n<option value='" . esc_attr( $key ) . "'>" . esc_html( $key ) . '</option>';
		}
		?>
</select>
<input class="hidden" type="text" id="metakeyinput" name="metakeyinput" value="" aria-label="<?php _e( 'New custom field name' ); ?>" />
<button type="button" id="newmeta-button" class="button button-small hide-if-no-js" onclick="jQuery('#metakeyinput, #metakeyselect, #enternew, #cancelnew').toggleClass('hidden');jQuery('#metakeyinput, #metakeyselect').filter(':visible').trigger('focus');">
<span id="enternew"></span>
<span id="cancelnew" class="hidden"></span></button>

<input type="text" id="metakeyinput" name="metakeyinput" value="" />

</td>
<td><textarea id="metavalue" name="metavalue" rows="2" cols="25"></textarea>
	
</td>
</tr>
</tbody>
</table>
<div class="submit add-custom-field">
	 'newmeta-submit',
			'data-wp-lists' => 'add:the-list:newmeta',
		)
	);
	?>
</div>
	</pre><p class="wporg-dot-link-list"><a href="https://developer.wordpress.org/reference/files/wp-admin/includes/template.php/">View all references</a> <a href="https://core.trac.wordpress.org/browser/tags/6.9.4/src/wp-admin/includes/template.php#L692">View on Trac</a> <a href="https://github.com/WordPress/wordpress-develop/blob/6.9.4/src/wp-admin/includes/template.php#L692-L791">View on GitHub</a></p></section>
		<section class="wp-block-wporg-code-reference-hooks"><h2 id="hooks" class="is-toc-heading wp-block-heading has-heading-5-font-size" tabindex="-1" ><a href="#hooks">Hooks</a></h2> <dl><dt class="wp-block-wporg-code-reference-title has-normal-font-size"><a href="https://developer.wordpress.org/reference/hooks/postmeta_form_keys/"><span class="hook-func">apply_filters</span>( ‘postmeta_form_keys’,  <nobr><span class="arg-type">array|null</span> <span class="arg-name">$keys</span></nobr>,  <nobr><span class="arg-type">WP_Post</span> <span class="arg-name">$post</span></nobr> )</a></dt><dd><p>Filters values for the meta key dropdown in the Custom Fields meta box.</p>
</dd><dt class="wp-block-wporg-code-reference-title has-normal-font-size"><a href="https://developer.wordpress.org/reference/hooks/postmeta_form_limit/"><span class="hook-func">apply_filters</span>( ‘postmeta_form_limit’,  <nobr><span class="arg-type">int</span> <span class="arg-name">$limit</span></nobr> )</a></dt><dd><p>Filters the number of custom fields to retrieve for the drop-down in the Custom Fields meta box.</p>
</dd></dl></section>
		<section class="wp-block-wporg-code-reference-related" data-nosnippet="true"><h2 id="related" class="is-toc-heading wp-block-heading has-heading-5-font-size" tabindex="-1" ><a href="#related">Related</a></h2> <section style="margin-top:var(--wp--preset--spacing--20)" class="wp-block-wporg-code-table" id="uses"><figure class="wp-block-table "><table><thead><tr><th scope="col">Uses</th><th scope="col">Description</th></tr></thead><tbody><tr class=""><td><a href="https://developer.wordpress.org/reference/classes/wpdb/esc_like/">wpdb::esc_like()</a><code>wp-includes/class-wpdb.php</code></td><td><p>First half of escaping for <code>LIKE</code> special characters <code>%</code> and <code>_</code> before preparing for SQL.</p>
</td></tr><tr class=""><td><a href="https://developer.wordpress.org/reference/functions/submit_button/">submit_button()</a><code>wp-admin/includes/template.php</code></td><td><p>Echoes a submit button, with provided text and appropriate class(es).</p>
</td></tr><tr class=""><td><a href="https://developer.wordpress.org/reference/functions/_ex/">_ex()</a><code>wp-includes/l10n.php</code></td><td><p>Displays translated string with gettext context.</p>
</td></tr><tr class=""><td><a href="https://developer.wordpress.org/reference/functions/wp_nonce_field/">wp_nonce_field()</a><code>wp-includes/functions.php</code></td><td><p>Retrieves or display nonce hidden field for forms.</p>
</td></tr><tr class=""><td><a href="https://developer.wordpress.org/reference/classes/wpdb/get_col/">wpdb::get_col()</a><code>wp-includes/class-wpdb.php</code></td><td><p>Retrieves one column from the database.</p>
</td></tr><tr class="wporg-hidden"><td><a href="https://developer.wordpress.org/reference/functions/is_protected_meta/">is_protected_meta()</a><code>wp-includes/meta.php</code></td><td><p>Determines whether a meta key is considered protected.</p>
</td></tr><tr class="wporg-hidden"><td><a href="https://developer.wordpress.org/reference/functions/current_user_can/">current_user_can()</a><code>wp-includes/capabilities.php</code></td><td><p>Returns whether the current user has the specified capability.</p>
</td></tr><tr class="wporg-hidden"><td><a href="https://developer.wordpress.org/reference/functions/_e/">_e()</a><code>wp-includes/l10n.php</code></td><td><p>Displays translated text.</p>
</td></tr><tr class="wporg-hidden"><td><a href="https://developer.wordpress.org/reference/functions/__/">__()</a><code>wp-includes/l10n.php</code></td><td><p>Retrieves the translation of $text.</p>
</td></tr><tr class="wporg-hidden"><td><a href="https://developer.wordpress.org/reference/functions/esc_attr/">esc_attr()</a><code>wp-includes/formatting.php</code></td><td><p>Escaping for HTML attributes.</p>
</td></tr><tr class="wporg-hidden"><td><a href="https://developer.wordpress.org/reference/functions/esc_html/">esc_html()</a><code>wp-includes/formatting.php</code></td><td><p>Escaping for HTML blocks.</p>
</td></tr><tr class="wporg-hidden"><td><a href="https://developer.wordpress.org/reference/functions/apply_filters/">apply_filters()</a><code>wp-includes/plugin.php</code></td><td><p>Calls the callback functions that have been added to a filter hook.</p>
</td></tr><tr class="wporg-hidden"><td><a href="https://developer.wordpress.org/reference/functions/get_post/">get_post()</a><code>wp-includes/post.php</code></td><td><p>Retrieves post data given a post ID or post object.</p>
</td></tr><tr class="wporg-hidden"><td><a href="https://developer.wordpress.org/reference/classes/wpdb/prepare/">wpdb::prepare()</a><code>wp-includes/class-wpdb.php</code></td><td><p>Prepares a SQL query for safe execution.</p>
</td></tr></tbody></table></figure><a class="wp-block-wporg-code-table-show-more" href="#">Show 9 more</a><a class="wp-block-wporg-code-table-show-less" href="#">Show less</a></section>  <section style="margin-top:var(--wp--preset--spacing--20)" class="wp-block-wporg-code-table" id="used-by"><figure class="wp-block-table "><table><thead><tr><th scope="col">Used by</th><th scope="col">Description</th></tr></thead><tbody><tr class=""><td><a href="https://developer.wordpress.org/reference/functions/post_custom_meta_box/">post_custom_meta_box()</a><code>wp-admin/includes/meta-boxes.php</code></td><td><p>Displays custom fields form fields.</p>
</td></tr></tbody></table></figure></section> </section>
		<section class="wp-block-wporg-code-reference-changelog"><h2 id="changelog" class="is-toc-heading wp-block-heading has-heading-5-font-size" tabindex="-1" ><a href="#changelog">Changelog</a></h2> <section style="margin-top:var(--wp--preset--spacing--20)" class="wp-block-wporg-code-table"><figure class="wp-block-table "><table><thead><tr><th scope="col">Version</th><th scope="col">Description</th></tr></thead><tbody><tr class=""><td><a href="https://developer.wordpress.org/reference/since/1.2.0/">1.2.0</a></td><td>Introduced.</td></tr></tbody></table></figure></section> </section>
		<section class="wp-block-wporg-code-reference-comments" data-nosnippet="true"><h2 id="user-contributed-notes" class="is-toc-heading wp-block-heading" tabindex="-1" ><a href="#user-contributed-notes">User Contributed Notes</a></h2> <ol class="comment-list">			<li id="comment-2219" data-comment-id="2219" class="comment byuser comment-author-pixeline even thread-odd thread-alt depth-1">
			<article id="div-comment-2219" class="comment-body">

							<a href="#comment-content-2219" class="screen-reader-text">Skip to note 2 content</a>
				<header class="comment-meta">
					<div class="comment-author vcard">
						<span class="comment-author-attribution">
						<a href="https://profiles.wordpress.org/pixeline/" rel="external nofollow" class="url">pixeline</a>						</span>
						<a class="comment-date" href="https://developer.wordpress.org/reference/functions/meta_form/#comment-2219">
							<time datetime="2017-05-10T06:58:28+00:00">
							9 years ago							</time>
						</a>

																													</div>
					<div class="user-note-voting" data-nonce="95015c8fec" data-can-vote="false"><a class="user-note-voting-up" title="You must log in to vote on the helpfulness of this note" data-id="2219" data-vote="up" href="https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fmeta_form%2F%23comment-2219"><span class="screen-reader-text">You must log in to vote on the helpfulness of this note</span></a><span class="user-note-voting-count " title="50% like this"><span class="screen-reader-text">Vote results for this note: </span>0</span><a class="user-note-voting-down" title="You must log in to vote on the helpfulness of this note" data-id="2219" data-vote="down" href="https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fmeta_form%2F%23comment-2219"><span class="screen-reader-text">You must log in to vote on the helpfulness of this note</span></a></div>				</header>
				<!-- .comment-metadata -->
			
				<div class="wporg-has-embedded-code comment-content" id="comment-content-2219">
				<p>Note that if your setup uses a lot of metafields, the custom field metabox provided by default by WordPress triggers a very slow mysql query that can slow down the Edit Post page load time (info: <a href="https://core.trac.wordpress.org/ticket/33885" rel="nofollow ugc">https://core.trac.wordpress.org/ticket/33885</a>). Here is an easy fix (add it to your Theme’s functions.php file):</p>
<pre class="wp-block-code"><code lang="php" class="language-php line-numbers">function admin_speedup_remove_post_meta_box() {
global $post_type;

if ( is_admin() && post_type_supports( $post_type, 'custom-fields' ) ) {
remove_meta_box( 'postcustom', 'post', 'normal' );
}
}
add_action( 'add_meta_boxes', 'admin_speedup_remove_post_meta_box' );