preg_replace,可点击标签Laravel

时间:2018-02-05 19:47:02

标签: php laravel function tags preg-replace

如果用户撰写帖子,他可以在文本中使用主题标签。 文本在post表中保存为正文。主题标签是以#开头的单词。主题标签存储在标签表中,与帖子有多对多的关系。

app.post('/todos2',(req,res)=>
{
    var todo=new app1({
        text:req.body.text
    });
    todo.save().then((docs)=>
    {
        res.send(docs);
    },(err)=>
    {
        res.status(404).send(err);
    });
});

所以我将数据提供给视图:

if($post)
{
    preg_match_all('/#(\w+)/', $request->get('body'),$tagNames);
    // $tagnames contains an array of results. $tagnames[0] is all matches
    $tagIds = [];
    foreach($tagNames[0] as $tagName)
    {
        //$post->tags()->create(['name'=>$tagName]);
        //Or to take care of avoiding duplication of Tag
        //you could substitute the above line as
        $tag = Tag::firstOrCreate(['name'=>$tagName]);
        if($tag)
        {
            $tagIds[] = $tag->id;
        }

    }
    $post->tags()->sync($tagIds);
}

每个主题标签都有自己的视图,可以在/ tags / id下找到。现在我想用一个指向相应视图的href元素替换文本中的主题标签。我已经读过preg_replace是可能的,但我该如何以及在哪里使用它?

2 个答案:

答案 0 :(得分:0)

检查每个标记

的内容

我认为您有$post->content 您的代码显示路线的名称为tags.show

foreach($post->tags as $tag){

   $link = '<a href="'.route('tags.show',$tag->title).'">'.$tag->title.'</a>';

   str_replace($tag->title,$link,$post->content);
}

答案 1 :(得分:0)

在您看来......在内容的最新内容中,您可以:

{!!str_replace($tag->name,"<a href='your-tag-route/$tag->id'>$tag->name</a>",$tag->name)!!}

搜索$tag->name

替换为<a href> and your route

内:$post->content

编辑1:

您可以在内容中插入标签,一旦它们被拉入: 在你的模型中:

Post.php

创建一个函数,通过拉入标签来装饰body属性的内容,并用模式替换每个匹配项的内容。 在您返回时,您的观看次数中显示的$内容将重新评估。

public function getBodyAttribute ($value){
        $tags = Tag::pluck('name', 'id')->toArray();
        $replacement =  '<a alt="$1" href="/tags/$1">$1</a>';
        $pattern = '/\b('.implode('|', $tags).')/i';
        return $content = preg_replace($pattern, $replacement, $value);
    }

最后在你看来,使用{!! $ post-&gt; body !!}

EDIT2:

要更改标签名称并将其用作表格的键,请将其添加到标签型号页面:

public function getRouteKeyName(){
     return 'name';
}

从现在开始,只要您Tag::find(),就可以使用id而不是name。 例如,Tag::find(php)

你需要字符的一致性(要么总是保存为小写字母或大字母),所以,在你的标签模型上添加:

public function setNameAttribute ($name){
    $this->attributes['name'] = strtolower($name);
}

在保存到数据库之前,为了保持一致性,它会将所有标记转换为小写字母。

这解决了您直接调用<a href="/tags/du"> #du </a>的第二个问题。

请注意,您无需更改上面的替换代码。我忘了添加#,所以这就足够了:

$replacement =  '<a alt="$1" href="/tags/$1">#$1</a>';