需求

平时在开发过程中,一般都是把标题、描述等标签直接写在模板中,如

# articles/show.blade.php

@section('title', "{$article->title} - {$article->category->name} - {$sitename}") `

在模板少的情况下问题还不大,一旦项目中有多套模板共用相同的标题和描述(比如pcmobile模板,多套不同风格主题的模板),管理起来就很繁琐了,每次修改都要先找到对应的模板,再一个一个地改。

如果能将这些标签内容抽取出来放在配置文件供复用,那就再方便不过了。

优点

  1. 再也不用人工一个一个去找对应的模板了。
  2. 用配置而不是硬编码的方式,达到一处修改,处处修改的目的。
  3. 模板中的meta标签更简洁了,再也不用字符串和变量混合在一起了。

配置文件

config目录下面新建meta.php文件

# config/meta.php
# 我喜欢用路由命名作为 key

return [
    'title' => [
        'home' => '首页标题',
        'articles.show' => '{title} - {category}',
    ],

    'description' => [
        'home' => '{sitename}为您提供...',
        'articles.show' => '{description}',
    ],
];

帮助函数

# app/helpers.php

if (! function_exists('meta')) {
    /**
     * Get meta tag from configuration.
     *
     * @param  string  $name
     * @return string
     */
    function meta($tag, $name, array $parameters = [])
    {
        $tag = config("meta.{$tag}")[$name];
       
        $search = array_map(function ($key) {
            return '{'.$key.'}';
        }, array_keys($parameters));

        $replace = array_values($parameters);

        return str_replace($search, $replace, $tag);
    }
}


if (! function_exists('meta_title')) {
    /**
     * Get meta title from configuration.
     *
     * @param  string  $name
     * @return string
     */
    function meta_title($name, array $parameters = [])
    {
        return meta('title', $name, $parameters);
    }
}

if (! function_exists('meta_description')) {
    /**
     * Get meta description from configuration.
     *
     * @param  string  $name
     * @return string
     */
    function meta_description($name, array $parameters = [])
    {
        return meta('description', $name, $parameters);
    }
}

用法

用法比较像route函数,由于是基于字符串替换,所以不能直接传对象。

# layouts/app.blade.php

<title>@yield('title') - {{ config('app.name') }}</title>


# articles/show.blade.php

@section('title', meta_title('articles.show', [
    'title' => $article->title,
    'category' => $article->category->name
]))


OR

// 命名的好处
@section('title', meta_title(Route::currentRouteName(), [
    'title' => $article->title,
    'category' => $article->category->name
]))

说明:当然了,除了标题描述标签之外,其他的标签也可以采用这种方式来统一管理。