【问题标题】:preg_replace, clickable tags Laravelpreg_replace,可点击标签 Laravel
【发布时间】:2018-02-05 19:47:01
【问题描述】:

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

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);
}

所以我把数据交给视图:

$postall = $user->posts()->with('comments', 'tags')->where('status', 1)->latest()->get();

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

【问题讨论】:

    标签: php laravel function tags preg-replace


    【解决方案1】:

    检查每个标签的内容

    我假设你有 $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);
    }
    

    【讨论】:

    • 很抱歉,您的代码不起作用。文本中的主题标签不会替换为 href 链接。
    【解决方案2】:

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

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

    搜索$tag-&gt;name

    替换为&lt;a href&gt; and your route

    在:$post-&gt;content

    编辑 1:

    您可以在内容中的标签被拉入时替换它们: 在您的模型中:

    Post.php
    

    创建一个函数,通过拉入标签来装饰 body 属性的内容,并用您的模式替换每个出现的内容。 在您返回时,您视图上显示的 $content 将是重新装饰的值。

    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->body !!}

    编辑2:

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

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

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

    您需要字符的一致性(始终保存为小写字母或大写字母),因此,在您的 Tag 模型上添加:

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

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

    这些解决了你直接调用&lt;a href="/tags/du"&gt; #du &lt;/a&gt;的第二个问题。

    请注意,您不需要更改上面的替换代码。我忘了加#,这样就够了:

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

    【讨论】:

    • 感谢您的帮助。 post-> body 不知道什么是标签,所以不幸的是代码不起作用。
    • 已编辑..现在检查。
    • 谢谢,它还不能完美运行。您的代码已将数据库中的所有单词更改为没有功能的 href 元素。我稍微改了一下代码:public function getBodyAttribute ($ value) { $ replacement = '&lt;a href="/tags/$1"&gt; # $ 1 &lt;/a&gt;'; $ pattern = '/ # (\ w +) /'; return $ content = preg_replace ($ pattern, $ replacement, $ value); }
    • 问题是,a href元素在文本中显示,没有任何作用。在文本中它看起来像这样:&lt;a href="/tags/du"&gt; #du &lt;/a&gt; 第二个问题是,我需要 URL 中的 ID 而不是标签。不幸的是,我不知道如何解决这个问题。
    • 第一个问题实际上是它应该工作的方式。它将标记名称的出现更改为 href 标记...是的。但是,正如我在上面消息的最后陈述中提到的那样,我写道,在您的视图中使用 {!!$post->body!!} ......而不是 {{$post->body}} 这就是变化并将 href 标签转换为普通的、可点击的标签。第二个问题很容易解决……如果每个标签都是一个单词,只需将它们变成键。我将在下面发布代码。
    猜你喜欢
    • 2018-07-13
    • 2015-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多