由Typecho驱动 - 主题WordBook

typecho短代码解析功能实现

更新:2022-06-28 访问:69

typecho短代码的实现

首先在functions.php底部加上


<?php


class Content{

    public static function analysis($content)
    {
        
        /** 
         * 编号01
         * 注册一个文章按钮
         * 
        **/
        if (strpos($content, '[scode') !== false) {//提高效率,避免每篇文章都要解析
            $pattern = self::get_shortcode_regex(array('scode'));
            $content = preg_replace_callback("/$pattern/", array('Content', 'scodeParseCallback'),
                $content);
        }
        

        
        return $content;
        
    }

    
    /**
     * 编号01
     * 短代码解析正则替换回调函数
     * @param $matches
     * @return bool|string
     * 
     * 使用:[scode type="share"]这是灰色的短代码框,常用来引用资料什么的[/scode]
     */
    public static function scodeParseCallback($matches)
    {
        // 不解析类似 [[player]] 双重括号的代码
        if ($matches[1] == '[' && $matches[6] == ']') {
            return substr($matches[0], 1, -1);
        }
        //[scode type="share"]这是灰色的短代码框,常用来引用资料什么的[/scode]
        $attr = htmlspecialchars_decode($matches[3]);//还原转义前的参数列表
        $attrs = self::shortcode_parse_atts($attr);//获取短代码的参数
        $type = "info";
        switch ($attrs['type']) {
            case 'yellow':
                $type = "warning";
                break;
            case 'red':
                $type = "error";
                break;
            case 'lblue':
                $type = "info";
                break;
            case 'green':
                $type = "success";
                break;
            case 'share':
                $type = "share";
                break;
        }
        return '<div class="tip inlineBlock ' . $type . '">' . $matches[5] . '</div>';
    }

























/**************解析功能区域搬WordPress的,这里不需要改动***************************/

/**
 * 获取匹配短代码的正则表达式
 * @param null $tagnames
 * @return string
 * @link https://github.com/WordPress/WordPress/blob/master/wp-includes/shortcodes.php#L254
 */
public static function get_shortcode_regex($tagnames = null)
{
    global $shortcode_tags;
    if (empty($tagnames)) {
        $tagnames = array_keys($shortcode_tags);
    }
    $tagregexp = join('|', array_map('preg_quote', $tagnames));
    // WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcode_tag()
    // Also, see shortcode_unautop() and shortcode.js.
    // phpcs:disable Squiz.Strings.ConcatenationSpacing.PaddingFound -- don't remove regex indentation
    return
        '\\['                                // Opening bracket
        . '(\\[?)'                           // 1: Optional second opening bracket for escaping shortcodes: [[tag]]
        . "($tagregexp)"                     // 2: Shortcode name
        . '(?![\\w-])'                       // Not followed by word character or hyphen
        . '('                                // 3: Unroll the loop: Inside the opening shortcode tag
        . '[^\\]\\/]*'                   // Not a closing bracket or forward slash
        . '(?:'
        . '\\/(?!\\])'               // A forward slash not followed by a closing bracket
        . '[^\\]\\/]*'               // Not a closing bracket or forward slash
        . ')*?'
        . ')'
        . '(?:'
        . '(\\/)'                        // 4: Self closing tag ...
        . '\\]'                          // ... and closing bracket
        . '|'
        . '\\]'                          // Closing bracket
        . '(?:'
        . '('                        // 5: Unroll the loop: Optionally, anything between the opening and closing shortcode tags
        . '[^\\[]*+'             // Not an opening bracket
        . '(?:'
        . '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag
        . '[^\\[]*+'         // Not an opening bracket
        . ')*+'
        . ')'
        . '\\[\\/\\2\\]'             // Closing shortcode tag
        . ')?'
        . ')'
        . '(\\]?)';                          // 6: Optional second closing brocket for escaping shortcodes: [[tag]]
    // phpcs:enable
}

/**
 * 获取短代码属性数组
 * @param $text
 * @return array|string
 * @link https://github.com/WordPress/WordPress/blob/master/wp-includes/shortcodes.php#L508
 */
public static function shortcode_parse_atts($text)
{
    $atts = array();
    $pattern = self::get_shortcode_atts_regex();
    $text = preg_replace("/[\x{00a0}\x{200b}]+/u", ' ', $text);
    if (preg_match_all($pattern, $text, $match, PREG_SET_ORDER)) {
        foreach ($match as $m) {
            if (!empty($m[1])) {
                $atts[strtolower($m[1])] = stripcslashes($m[2]);
            } elseif (!empty($m[3])) {
                $atts[strtolower($m[3])] = stripcslashes($m[4]);
            } elseif (!empty($m[5])) {
                $atts[strtolower($m[5])] = stripcslashes($m[6]);
            } elseif (isset($m[7]) && strlen($m[7])) {
                $atts[] = stripcslashes($m[7]);
            } elseif (isset($m[8]) && strlen($m[8])) {
                $atts[] = stripcslashes($m[8]);
            } elseif (isset($m[9])) {
                $atts[] = stripcslashes($m[9]);
            }
        }
        // Reject any unclosed HTML elements
        foreach ($atts as &$value) {
            if (false !== strpos($value, '<')) {
                if (1 !== preg_match('/^[^<]*+(?:<[^>]*+>[^<]*+)*+$/', $value)) {
                    $value = '';
                }
            }
        }
    } else {
        $atts = ltrim($text);
    }
    return $atts;
}

/**
 * Retrieve the shortcode attributes regex.
 *
 * @return string The shortcode attribute regular expression
 * @since 4.4.0
 *
 */
public static function get_shortcode_atts_regex()
{
    return '/([\w-]+)\s*=\s*"([^"]*)"(?:\s|$)|([\w-]+)\s*=\s*\'([^\']*)\'(?:\s|$)|([\w-]+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|\'([^\']*)\'(?:\s|$)|(\S+)(?:\s|$)/';
}

/**************解析功能区域搬WordPress的,这里不需要改动***************************/


}

然后再滑动到底部加上

//短代码解析


function shortCode($content){
    //解析短代码功能
    $cons = new Content();
    
    $content = $cons->analysis($content);
    
    return  $content;
}

在post.php或者你要解析的地方加上shortCode(内容);

至于怎么在编辑器中插入,这里不做教程了,看另一篇文章或者寻找