工学1号馆

home

auto convert @username to clickable links

Wu Yudong    December 27, 2019     PHP   1,120   

今天实现这个如题所示的功能,通俗点讲就是在点击“回复”的时候,textarea里面出现@username,并且带链接。

这里要解决的问题是,直接在textarea中@**的时候,当数据库存在此用户的时候,也可以实现添加链接。这里的@username后面留有空格,如果没有空格则不添加链接。

v2ex的开源代码中实现了一个版本

https://github.com/livid/v2ex-gae/blob/master/v2ex/templatetags/filters.py#L151

其中的:def mentions(value):

# auto convert @username to clickable links
def mentions(value):
    ms = re.findall('(@[a-zA-Z0-9\_]+\.?)\s?', value)
    if (len(ms) > 0):
        for m in ms:
            m_id = re.findall('@([a-zA-Z0-9\_]+\.?)', m)
            if (len(m_id) > 0):
                if (m_id[0].endswith('.') != True):
                    value = value.replace('@' + m_id[0], '@<a href="/member/' + m_id[0] + '">' + m_id[0] + '</a>')
        return value
    else:
        return value
register.filter(mentions)

基本思路是:用户名为数字和字母的组合,通过正则表达式取得后直接添加链接样式

这种比较简单,问题也比较明显:

1、不能匹配中文用户名

2、@username没有判断是否存在数据库,如果不存在添加链接则没有意义

我这里也是简化一下设计,实现的功能如下:

规定用户名username只能是字母数字和下划线,用户昵称nickname则可以是中文,在textarea中@username 显示的是username,当提交以后显示在评论栏目的时候显示的是用户的nickname。

实现的代码如下:

function mentions($value){
    $pattern = '~@\w+\s~';
    $match_array = [];
    preg_match_all($pattern, $value, $match_array);
    $count = count($match_array[0]);
    for($i = 0; $i < $count; $i++){
       $username = trim($match_array[0][$i], '@ ');
       $res = Db::name('users')->where('username', $username)->find();
       if($res){
           $url = "/ebook/user/".$username;
           $href = '<a target="_blank" href='.$url.'>'.$res['nickname'].'</a>';
           $value = str_replace($username, $href, $value);
       }
    }
    return $value;
}

这里使用了正则匹配与字符串替换的相关函数

如果文章对您有帮助,欢迎点击下方按钮打赏作者

Comments

No comments yet.
To verify that you are human, please fill in "七"(required)