WordPress 提供了一個非常簡單方便的函數來顯示當前文章的標題,那就是:the_title() 。
這個函數經常被開發者在 header,post,page,loop,footer 裏使用,這幾乎是開發主題裏最常用的 WordPress 函數之一,然而許多開發者並沒有意識到這裏有個地方並不應該使用此函數,那就是在 attributes 裏,如:
<a href="<?php%20the_permalink();%20?>" title="<?php the_title(); ?>"> 繼續閲讀 <?php the_title(); ?></a>
很多開發者在 loop,page,post 裏使用這樣的寫法設置一個超鏈接到指定的文章,看起來似乎並沒有什麼問題,但其實正確安全的寫法應該把 title=」<?php the_title(); ?>」 改寫成 title=」<?php the_title_attribute(); ?>」
為什麼要這樣寫,大家看看 WordPress 源文件中的相關函數核心文件便知了:
the_title() 源代碼:
/**
* Display or retrieve the current post title with optional content.
*
* @since 0.71
*
* @param string $before Optional. Content to prepend to the title.
* @param string $after Optional. Content to append to the title.
* @param bool $echo Optional, default to true.Whether to display or return.
* @return null|string Null on no title. String if $echo parameter is false.
*/
function the_title($before = '', $after = '', $echo = true) {
$title = get_the_title();
if ( strlen($title) == 0 )
return;
$title = $before . $title . $after;
if ( $echo )
echo $title;
else
return $title;
}
這個函數並沒有提供給我們有效的信息, 只是執行了 get_the_title() 函數,我們再看下這個函數的相關文件.
/**
* Retrieve post title.
*
* If the post is protected and the visitor is not an admin, then "Protected"
* will be displayed before the post title. If the post is private, then
* "Private" will be located before the post title.
*
* @since 0.71
*
* @param mixed $post Optional. Post ID or object.
* @return string
*/
function get_the_title( $post = 0 ) {
$post = get_post( $post );
$title = isset( $post->post_title ) ? $post->post_title : '';
$id = isset( $post->ID ) ? $post->ID : 0;
if ( ! is_admin() ) {
if ( ! empty( $post->post_password ) ) {
$protected_title_format = apply_filters( 'protected_title_format', __( 'Protected: %s' ) );
$title = sprintf( $protected_title_format, $title );
} else if ( isset( $post->post_status ) && 'private' == $post->post_status ) {
$private_title_format = apply_filters( 'private_title_format', __( 'Private: %s' ) );
$title = sprintf( $private_title_format, $title );
}
}
return apply_filters( 'the_title', $title, $id );
}
這個函數非常簡單,它用 get_post() 取回了 post object,然後把它傳遞給一個叫做 the_title 的 filter,返回 $post->post_title
這個函數最重要的地方就是 apply_filters( 『the_title』, $title, $id );
這個 filter 可以提供給開發者自定義標題的輸出形式,比如添加額外的 html 標籤。
the_title_attribute() 源代碼:
/**
* Sanitize the current title when retrieving or displaying.
*
* Works like {@link the_title()}, except the parameters can be in a string or
* an array. See the function for what can be override in the $args parameter.
*
* The title before it is displayed will have the tags stripped and {@link
* esc_attr()} before it is passed to the user or displayed. The default
* as with {@link the_title()}, is to display the title.
*
* @since 2.3.0
*
* @param string|array $args Optional. Override the defaults.
* @return string|null Null on failure or display. String when echo is false.
*/
function the_title_attribute( $args = '' ) {
$title = get_the_title();
if ( strlen($title) == 0 )
return;
$defaults = array('before' => '', 'after' => '', 'echo' => true);
$r = wp_parse_args($args, $defaults);
extract( $r, EXTR_SKIP );
$title = $before . $title . $after;
$title = esc_attr(strip_tags($title));
if ( $echo )
echo $title;
else
return $title;
}
這個函數也使用了 get_the_title() 函數來取回文章的標題,但是最後返回的數據卻與 the_title() 函數不同。這裏過濾掉了許多轉義字符與 html 標籤,能夠更加安全的在元素屬性裏進行使用。
詳細例子:
假設你的 $post->post_title 是這樣的
<span > 這是有 span 標籤的標題</span>
當你使用 the_title() 函數,輸出將保持不變,還是如下
<span > 這是有 span 標籤的標題</span>
但是當你使用 the_title_attribute(),你的輸出是如下的
這是有 span 標籤的標題
注意這裏的 span 標籤已經被移除掉了.
又假如如果你的標題裏有雙引號, 如下
這是一個帶 "雙引號" 的標題
當你使用 the_title() 函數,輸出如下
這是一個帶 "雙引號" 的標題
但是當你使用 the_title_attrubute() 函數,輸出卻如下
這是一個帶 "雙引號" 的標題
注意到這裏自動把雙引號替換成轉義字符了,這樣就保證了 html 標籤屬性的安全使用。
如果我們在 html 標籤屬性裏使用 the_title() 函數, 則會破壞掉屬性原有的形式
<span title="<?php the_title(); ?>"><?php the_title(); ?></span>
輸出將會如下:
<span title="這是一個帶 "雙引號" 的標題"> 這是一個帶」 雙引號」 的標題</span>
注意到了這裏的 title 屬性的引號,html 標籤對引號的使用是非常嚴格的,禁止這樣的形式出現,一旦出現將導致頁面嚴重的顯示問題.
經過以上的分析,希望開發者們在以後的開發過程中能注意到這些小細節,在 html 標籤屬性裏一定要使用 the_title_attribute() 函數而不是 the_title() 函數!
所以正確的用法應該是:
<a href="<?php%20the_permalink();%20?>" title="<?php the_title_attribute(); ?>"> 繼續閲讀 <?php the_title(); ?></a>