不乱于心,不困于情。
不畏将来,不念过往。如此,安好。

wordpress如何增加文章别名的长度?

wordpress中对别名长度的限制通过多个方面来进行限制,首先是数据库,在wordpress数据库表$wpdb->posts中,post_name字段的类型是varchar(200),也就是说文章别名只能在数据库中容纳200个字符,但我们知道,中文别名在数据库中使用了urlencode加密,一个中文标题经过加密后就会变的很长很长,据我观察,这200个字符位置最多容纳下22个左右的中文字,而如果我们的文章需要更长的位置怎么办呢?

修改$wpdb->posts字段的长度限制,使用phpmyadmin进入post_name字段的编辑界面,修改200为500,甚至更长。这样,在数据库中你就可以让别名容纳更多的字数了。

然而,这只是第一步,你要知道,虽然数据库中你已经修改了,但wordpress系统本身还不让你这么做,在提交文章的时候,它还会先检查一下,如果你的标题字符超过了200,它还得把你的标题给截断,非常残忍。我们通过一个HOOK来调整wordpress的这个行为。一切得从/wp-includes/formatting.php开始。

/wp-includes/formatting.php是wordpress系统的字符格式化函数库,里面可以对wordpress系统中的字符进行检查、转换、处理等。我们找到sanitize_title函数,它将完成很多和标题相关的字符串处理动作。可是跟别名相关的还跟它没什么关系,我们找到sanitize_title_with_dashes函数,它才是别名处理的罪魁祸首,在执行sanitize_title函数时sanitize_title_with_dashes将发生动作,我们来看下它的源码:

function sanitize_title_with_dashes( $title, $raw_title = '', $context = 'display' ) {
    $title = strip_tags($title);
    // Preserve escaped octets.
    $title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title);
    // Remove percent signs that are not part of an octet.
    $title = str_replace('%', '', $title);
    // Restore octets.
    $title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title);

    if (seems_utf8($title)) {
        if (function_exists('mb_strtolower')) {
            $title = mb_strtolower($title, 'UTF-8');
        }
        $title = utf8_uri_encode($title, 200);
    }

    $title = strtolower($title);
    $title = preg_replace('/&.+ ;/', '', $title); // kill entities
    $title = str_replace('.', '-', $title);

    if ( 'save' == $context ) {
        // Convert nbsp, ndash and mdash to hyphens
        $title = str_replace( array( '%c2%a0', '%e2%80%93', '%e2%80%94' ), '-', $title );

        // Strip these characters entirely
        $title = str_replace( array(
            // iexcl and iquest
            '%c2%a1', '%c2%bf',
            // angle quotes
            '%c2%ab', '%c2%bb', '%e2%80%b9', '%e2%80%ba',
            // curly quotes
            '%e2%80%98', '%e2%80%99', '%e2%80%9c', '%e2%80%9d',
            '%e2%80%9a', '%e2%80%9b', '%e2%80%9e', '%e2%80%9f',
            // copy, reg, deg, hellip and trade
            '%c2%a9', '%c2%ae', '%c2%b0', '%e2%80%a6', '%e2%84%a2',
            // acute accents
            '%c2%b4', '%cb%8a', '%cc%81', '%cd%81',
            // grave accent, macron, caron
            '%cc%80', '%cc%84', '%cc%8c',
        ), '', $title );

        // Convert times to x
        $title = str_replace( '%c3%97', 'x', $title );
    }

    $title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
    $title = preg_replace('/s+/', '-', $title);
    $title = preg_replace('|-+|', '-', $title);
    $title = trim($title, '-');

    return $title;
}

你就会发现,最后得以保存在数据库中的post_name是靠它来格式化完成的,我们必须修改它才能实现我们的目的。那怎么办?你看到我上面用红色标记的地方了吧,把200改为500,覆盖掉原来的formatting.php文件,好了,到后台发布一篇文章(中文标题,很长很长)试试。

这个原理也很简单,原本处理时会用到utf8_uri_encode函数,它对字符串进行识别,判断其所花费的字节位,并做参数中给定数值的截断,我们把它改大不就增加了文章别名的长度了吗(中文的情况下,英文没有测试)?

当然,你会说使用修改wordpress系统文件的方法不可靠,一旦升级系统就会失效。我们也提供一个HOOK的方法,原理很简单,把sanitize_title_with_dashes从事件流中去除,使用新的同样的经过修改的函数(把下面的代码放到functions.php中):

remove_filter( 'sanitize_title', 'sanitize_title_with_dashes' );
add_filter( 'sanitize_title', 'sanitize_title_with_dashes_longer_post_name' );
function sanitize_title_with_dashes_longer_post_name( $title, $raw_title = '', $context = 'display' ) {
    $title = strip_tags($title);
    // Preserve escaped octets.
    $title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title);
    // Remove percent signs that are not part of an octet.
    $title = str_replace('%', '', $title);
    // Restore octets.
    $title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title);

    if (seems_utf8($title)) {
        if (function_exists('mb_strtolower')) {
            $title = mb_strtolower($title, 'UTF-8');
        }
        $title = utf8_uri_encode($title, 500);
    }

    $title = strtolower($title);
    $title = preg_replace('/&.+ ;/', '', $title); // kill entities
    $title = str_replace('.', '-', $title);

    if ( 'save' == $context ) {
        // Convert nbsp, ndash and mdash to hyphens
        $title = str_replace( array( '%c2%a0', '%e2%80%93', '%e2%80%94' ), '-', $title );

        // Strip these characters entirely
        $title = str_replace( array(
            // iexcl and iquest
            '%c2%a1', '%c2%bf',
            // angle quotes
            '%c2%ab', '%c2%bb', '%e2%80%b9', '%e2%80%ba',
            // curly quotes
            '%e2%80%98', '%e2%80%99', '%e2%80%9c', '%e2%80%9d',
            '%e2%80%9a', '%e2%80%9b', '%e2%80%9e', '%e2%80%9f',
            // copy, reg, deg, hellip and trade
            '%c2%a9', '%c2%ae', '%c2%b0', '%e2%80%a6', '%e2%84%a2',
            // acute accents
            '%c2%b4', '%cb%8a', '%cc%81', '%cd%81',
            // grave accent, macron, caron
            '%cc%80', '%cc%84', '%cc%8c',
        ), '', $title );

        // Convert times to x
        $title = str_replace( '%c3%97', 'x', $title );
    }

    $title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
    $title = preg_replace('/s+/', '-', $title);
    $title = preg_replace('|-+|', '-', $title);
    $title = trim($title, '-');

    return $title;
}

其实对于整个标题处理过程而言,就换了一个数字,却需要写这么多代码。记住:要让它生效,你的整个wordpress中,包括你的主题插件中,没有再对此做规定,否则一旦某一处小于500,那么会以小的一处作为标准。

看到这里你或许以为已经完事OK,可以洗洗睡了。然而,你不得不听我把故事讲完,在/wp-includes/post.php中有这么一段代码:

function _truncate_post_slug( $slug, $length = 200 ) {
    if ( strlen( $slug ) > $length ) {
        $decoded_slug = urldecode( $slug );
        if ( $decoded_slug === $slug )
           $slug = substr( $slug, 0, $length );
        else
           $slug = utf8_uri_encode( $decoded_slug, $length );
    }

    return rtrim( $slug, '-' );
}

它好像也要做点什么事,我也没有必要再深究了,把200果断改为500。到这里,我们可以关灯睡觉了。

赞(0) 打赏
未经允许不得转载:seo优化_前端开发_渗透技术 » wordpress如何增加文章别名的长度?

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏