lukaswhite / meta-tags

一个用于管理元标签的PHP类

0.0.2 2020-07-08 06:52 UTC

This package is auto-updated.

Last update: 2024-08-29 05:06:15 UTC


README

Run Tests codecov

这个库可以帮助您管理网站或Web应用的元标签(包括Open Graph)。

很可能,您的大部分元标签都是程序生成的,例如从数据库中生成。最明显的是页面标题,但也许还有描述和关键词。

也许您将这些数据作为数据提供给视图,然后在那里构建标签。这个库所做的就是在您的应用内部(例如在控制器中)构建它们,然后轻松地在视图中输出它们。

所以,例如,不是这样的(这里我使用Blade语法)

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<title>{{ $title }}</title>
		<meta name="og:title" content="{{ $title }}" />
		<meta name="description" content="{{ $description }}" />
		<meta name="og:description" content="{{ $description }}" />
		<meta name="keywords" content="{{ implode( ', ', $keywords ) }}" />
		<meta name="robots" content="index,nofollow" />
		<link rel="canonical" content="{{ $url }}" />
	</head>

这个库允许您这样做

$meta = new MetaTags( );
$meta
	->charSet( 'utf-8' )
	->title( $title )
	->description( $description )
	->keywords( $keywords )
	->robotsShouldIndexButNotFollow( )
	->canonical( $url );

实际上,如果您使用UTF-8,那么它默认就是这样的,所以->charSet( )调用是多余的。

然后在您的视图中

<!DOCTYPE html>
<html lang="en">
	<head>
		{!! $meta !!}
	</head>

如果您使用Laravel,可以这样做

{!! app( )->make( MetaTags::class )->render( ) !!}

在上面的示例中,我们将MetaTags类注册为单例与服务容器。关于这一点,稍后会详细介绍。

那么,它有什么好处呢?

  • 传递给视图的变量最多一个
  • 无需手动编写标签本身
  • 不会混淆何时使用name属性与property属性
  • 它使得忘记设置字符集等事情更难
  • 设置标题和描述,相应的Open Graph元标签将为您设置
  • 它(希望!)有助于提醒重要但经常被忽视的事情,如规范化
  • 它揭示了某些不太为人所知的元标签,如直接针对Googlebots的标签
  • 它使您的布局整洁有序

安装

composer require lukaswhite/meta-tags

第一步

创建实例如下

use Lukaswhite\MetaTags\MetaTags;

$meta = new MetaTags( );

我建议将其创建为单例,然后将其放入服务容器或类似容器中。

例如,如果您使用Laravel

$this->app->singleton( MetaTags::class, function( $app ) {
	return new MetaTags( );
} );

然后,无论何时您想要设置元标签,例如在控制器中,您都可以像这样获取实例

$meta = app( )->make( MetaTags::class );

标准元数据

设置标题

$meta->title( 'My Website' );

默认情况下,这将添加以下内容

<title>My Website</title>
<meta property="og:title" content="My Website" />

您会注意到默认情况下添加了一个带有标题的Open Graph标签;如果您不希望这种行为

$meta->includeOpenGraph( false )
	->title( 'My Website' );

结果

<title>My Website</title>

设置描述

$meta->description( 'A description of the website' );

默认情况下,这将添加以下内容

<meta name="description" content="A description of the website" />
<meta property="og:description" content="A description of the website" />

您会注意到默认情况下添加了一个带有描述的Open Graph标签;如果您不希望这种行为

$meta->includeOpenGraph( false )
	->description( 'A description of the website' );

结果

<meta name="description" content="A description of the website" />

设置关键词

$meta->keywords( 'PHP', 'meta tags', 'SEO' );

结果

<meta name="keywords" content="PHP, meta tags, SEO" />

设置URL

设置URL如下

$meta->url( 'http://example.com' );

这将输出以下内容

<meta name="url" content="http://example.com" />

设置字符集

库将自动将字符集添加到元标签中,默认为UTF-8。所以这是自动添加的

<meta charset="utf-8" />

要设置不同的字符集

$meta->charSet( 'ISO-8859-1' );

结果

<meta charset="ISO-8859-1" />

如果您出于任何原因不希望添加它,则可以将其设置为null

$meta->charSet( null );

规范URL

要设置规范链接元标签

$meta->canonical( 'http://example.com' );

这将导致以下结果

<link rel="canonical" content="http://example.com" />

分页

如果您正在渲染一个列出内容的页面,并使用分页,那么添加到下一页和/或上一页的链接可能会有所帮助。也就是说,一个带有rel=prevrel=nextlink标签。

假设我们目前在第4页

$meta->previousPage( 'http://example.com/articles/page/3' )
	->nextPage( 'http://example.com/articles/page/5' );

您也可以设置第一页和最后一页

$meta
	->firstPage( 'http://example.com/articles/page/1' )
	->lastPage( 'http://example.com/articles/page/10' );

订阅源

RSS

如果您有一个与网站或分类关联的RSS源,创建一个链接到它是个好主意。

没有标题

$meta->addRssFeed( 'http://example.com/feed.rss' );

或者带有

$meta->addRssFeed( 'http://example.com/feed.rss', 'My Website RSS Feed' );

Atom

如果您有一个与网站或分类关联的Atom源,创建一个链接到它是个好主意。

没有标题

$meta->addAtomFeed( 'http://example.com/feed.xml' );

或者带有

$meta->addAtomFeed( 'http://example.com/feed.xml', 'My Website Atom Feed' );

机器人

默认情况下,机器人会索引和跟随;如果您想告诉它们不要做其中之一或两者,可以使用以下方法之一

$meta->robotsShouldIndexButNotFollow( );
// or
$meta->robotsShouldFollowButNotIndex( );
// or
$meta->robotsShouldNotIndexNorFollow( );

Googlebot

您可以从Googlebot那里提出一些额外请求,除了noindexnofollow子句。

防止文本片段或视频预览在搜索结果中显示

$meta->googleShouldNotIncludeSnippets( );

防止Google显示页面的缓存链接

$meta->googleShouldNotIncludeSnippets( );

指定您不希望您的页面出现在Google搜索结果中出现的图片的引用页面上

$meta->googleShouldNotShowPageAsReferringPageForImageSearchResults( );

抱歉方法名太长,欢迎提出更好的建议!

请求Google在指定日期后停止爬取页面

$meta->googleShouldStopCrawlingAfter( new \DateTime( '2019-10-23' ) );

性能相关的元标签

有许多与性能相关的元标签;特别是像预加载和预渲染这样的东西。

预加载

您可以在元标签中添加链接,告诉浏览器预加载资源

$meta->addPrefetchLink( '/scripts.js' );

您还可以添加有关资源类型的提示

$meta->addPrefetchLink( '/scripts.js', 'script' );

预加载

您可以在元标签中添加链接,告诉浏览器预加载资源

$meta->addPreloadLink( '/scripts.js' );

您还可以添加有关资源类型的提示

$meta->addPreloadLink( '/scripts.js', 'script' );

DNS预加载

DNS预加载是在浏览器请求资源之前,对我们托管资源的每个域启动DNS解析的过程,目的是在请求资源时节省DNS解析时间。(来源

要这样做

$meta->addPreconnect( '//cdn.example.com' );

预渲染

请求浏览器预渲染内容

$meta->addPrerender( '//example.com/landing-page.html' );

http-equiv元标签

有一类元标签看起来像这样

<meta http-equiv="Pragma" content="no-cache">

它们基本上是HTTP头部的HTML等价物。

添加一个

$meta->httpEquiv( 'Pragma', 'no-cache' );

要告诉浏览器您不想缓存页面,您可以手动设置相关标签,或者这样做

$meta->tellBrowsersNotToCache( );

此页上的建议所示,由于不是所有客户端浏览器和缓存设备(例如代理服务器)都已知成功实现所有无缓存选项,此方法包括多个无缓存选项;具体来说,它添加以下元标签

<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="cache-control" content="no-store" />

自定义元标签

自定义元标签可以用于向页面注入数据,您可以稍后通过JavaScript访问这些数据。例如,Laravel用于CSRF令牌,或者您可能希望使用这种方法注入应用程序ID或公钥。

以下是一些示例

$meta->custom( 'google-maps', 'your-google-maps-key' );
$meta->custom( 'mixpanel', getenv( 'MIXPANEL_APP_ID' ) );
$meta->custom( 'csrf-token', csrf_token( ), 'name' );

注意最后一个;Laravel输出的CSRF元标签如下

<meta name="csrf-token" content="the-token" />

而上面的Google Maps示例将使用更常见的property属性,即

<meta property="google-maps" content="your-google-maps-key" />

开放图形标签

库使得添加开放图形元标签变得简单。

启用或禁用

默认情况下启用开放图形标签;这包括一些自动添加的标签。如果您希望禁用此功能

$meta->includeOpenGraph( false );

基本标签

有一些基本且非常重要的开放图形标签有“标准”等效项。值得注意的是标题、描述和URL。当您使用相应的方法指定它们时,这些标签会自动作为开放图形标签添加,除了“标准”标签。

换句话说,如果您这样做

$meta
	->title( 'My Website' )
	->description( 'A description of the website' )
	->url( 'http://example.com' );

您将得到以下内容

<title>My Website</title>
<meta property="og:title" content="My Website" />
<meta name="description" content="A description of the website" />
<meta property="og:description" content="A description of the website" />
<meta name="url" content="http://example.com" />

定义类型

默认情况下,会添加必需的og:type元标签,其默认值为网站。即

<meta property="og:type" content="website" />

您可以用type( )方法重写此值,例如

$meta->type( 'article' );

您还可以使用提供的常量之一

$meta->type( MetaTags::OG_TYPE_ARTICLE );

您还可以同时设置任何属性,例如

$meta->type(
	MetaTags::OG_TYPE_BOOK,
	[
		'isbn'  =>  'ISBN-123-1234',
	]
);

// or
$meta->type(
	MetaTags::OG_TYPE_PROFILE,
	[
		'first_name'  =>  'Joe',
		'last_name' => 'Bloggs',
		'username' => 'joebloggs',
	]
);

以这种方式传递属性数组并不是推荐的做法;我们稍后会探讨其他方法。

或者,调用以下方法之一

$meta->isArticle( );
$meta->isBook( );
$meta->isProfile( );
$meta->isBusiness( );

设置地区

要设置地区,例如为 Facebook 进行本地化 设置

$meta->locale( 'en_GB' );

设置URL

要设置 Open Graph URL——也就是说,og:url——只需这样做

$meta->ogUrl( 'https://example.com' );

其他 Open Graph 标签

您可以使用 openGraph( ) 方法设置任何 Open Graph 标签

$meta->openGraph( 'determiner', 'an' );
$meta->openGraph( 'updated_time', new \DateTime( '2018-10-12' ) );
$meta->openGraph( 'restrictions:age', 18 );

如果您需要设置可以多次出现的 Open Graph 标签,将第三个参数传递为 true。这实际上允许您“覆盖”Open Graph 标签;如果需要覆盖应用程序中的某些信息,这可能很有用。

图片

图片对社交网络很重要,例如当您的网站通过 Facebook 分享或用作 Twitter Card 的基础时(稍后会有更多关于这些的内容)。

添加图片

$meta->addImage(
	( new \Lukaswhite\MetaTags\Entities\Image( ) )
		->setUrl( 'http://example.com/image.jpeg' )
		->setSecureUrl( 'https://example.com/image.jpeg' )
		->setType( 'image/jpeg' )
		->setWidth( 500 )
		->setHeight( 300 )
		->setAlt( 'Example image' )
);

如果您想使用自己的图片类,只需实现本包中包含的 Image 合约。

它命名为 addImage( ) 而不是 setImage( ),因为 Open Graph 协议允许您添加多个图片。

视频

添加视频

$meta->addVideo(
	( new \Lukaswhite\MetaTags\Entities\Video( ) )
		->setUrl( 'http://example.com/movie.swf' )
		->setSecureUrl( 'https://example.com/movie.swf' )
		->setType( 'application/x-shockwave-flash' )
		->setWidth( 500 )
		->setHeight( 300 )
		->setImage( 'http://example.com/movie-image.jpg' )
);

如果您想使用自己的视频类,只需实现本包中包含的 Video 合约。

它命名为 addVideo( ) 而不是 setVideo( ),因为 Open Graph 协议允许您添加多个视频。

音频

添加音频

$meta->addAudio(
	( new \Lukaswhite\MetaTags\Entities\Audio( ) )
		->setUrl( 'http://example.com/audio.mp3' )
		->setSecureUrl( 'https://example.com/audio.mp3' )
		->setType( 'audio/mp3' )
);

如果您想使用自己的视频类,只需实现本包中包含的 Video 合约。

个人资料

如果网页代表用户个人资料,例如在社交网络中,则可以这样做

$meta->profile( 
	( new \Lukaswhite\MetaTags\Entities\Profile( ) )
		->setFirstName( 'Joe' )
		->setLastName( 'Bloggs' )
		->setUsername( 'joebloggs' )
		->setGender( \Lukaswhite\MetaTags\Contracts\Profile::MALE ) );

如果您想使用自己的个人资料类,只需实现本包中包含的 Profile 合约。

书籍

如果网页代表书籍

$meta->book(
	( new \Lukaswhite\MetaTags\Entities\Book( ) )
		->setReleaseDate( new \DateTime( '2018-04-03 15:20' ) )
		->setAuthor( 'Joe Bloggs' )
		->setIsbn( 'ISBN-123-1234' )
		->setTag( [ 'PHP' ] )
);

如果您想使用自己的书籍类,只需实现本包中包含的 Book 合约。

请注意,由于书籍可能有多个作者,这也是允许的

$book->setAuthor( [ 'Joe Bloggs', 'Harry Black' ] );

联系信息

您可以将地址、电子邮件地址或电话号码等联系信息添加到 Open Graph 元标签中;例如,这可能适用于企业列表网站。

这里有做这件事的一种方法

$meta->contactData(
	( new \Lukaswhite\MetaTags\Entities\ContactData( ) )
		->setStreetAddress( '1601 S California Ave' )
		->setLocality( 'Palo Alto' )
		->setRegion( 'CA' )
		->setPostalCode( '94304' )
		->setCountryName( 'USA' )
		->setEmail( 'me@example.com' )
		->setPhone('650-123-4567')
		->setFaxNumber('+1-415-123-4567')
		->setWebsite( 'http://example.com' )
);

这将添加以下元标签

<meta name="og:street-address" content="1601 S California Ave" />
<meta name="og:locality" content="Palo Alto" />
<meta name="og:region" content="CA" />
<meta name="og:postal-code" content="94304" />
<meta name="og:country-name" content="USA" />
<meta name="og:email" content="me@example.com" />
<meta name="og:phone_number" content="650-123-4567" />
<meta name="og:fax_number" content="http://example.com" />

或者,您可以通过实现 ContactData 接口使用自己的类

class Business implements ContactData {
	// getStreetAddress( ), getPostalCode( ) etc
}

$meta->contactData( $business );

最后,还有单独的方法

$meta->streetAddress( '1601 S California Ave' )
	->locality( 'Palo Alto' )
	->region( 'CA' )
	->postalCode( '94304' )
	->countryName( 'USA' )
	->email( 'me@example.com' )
	->phone('650-123-4567')
	->faxNumber('+1-415-123-4567')
	->website( 'http://example.com' )
);

地理信息

除了通过联系数据提供地址信息外,Open Graph 还允许您通过设置纬度和经度以及可选的高度来指定页面代表的特定地理位置。

$meta->addGeopoint( 
	new Geopoint( 37.416343, -122.153013 ) 
);

结果

<meta name="og:latitude" content="37.416343" />
<meta name="og:longitude" content="-122.153013" />

而不是传递提供的 Geopoint 类的实例,您还可以传递实现同名接口的任何类。这实际上包括提供 getLatitude( )getLongitude( )getAltitude( ) 方法。

营业时间

指定企业的营业时间

$meta->businessHours(
	new BusinessDay( 'Monday', '09:00', '17:00' ),
	new BusinessDay( 'Tuesday', '09:00', '17:00' ),
	new BusinessDay( 'Wednesday', '09:00', '17:00' ),
	new BusinessDay( 'Thursday', '09:00', '17:00' ),
	new BusinessDay( 'Friday', '09:00', '17:00' ),
	new BusinessDay( 'Saturday', '08:00', '18:00' )
);

Facebook

Facebook 有一些特定于社交网络的 Open Graph 标签。

应用 ID

设置网站的应用的 App ID

$meta->facebookAppId( '12345678910' );

个人资料 ID

设置 Facebook 个人资料 ID;也就是说,可以关注的用户的 Facebook ID

$meta->facebookProfileId( '78676576576' );

管理员

设置管理员

$meta->facebookAdmins(
	'12345',
	'678910'
);

// or
$meta->facebookAdmins(
	'12345'
);

页面

设置一个或多个与 URL 关联的 Facebook 页面 ID,以便启用链接编辑和即时文章发布

$meta->facebookPages(
	'76236783',
	'67873687'
);

// or
$meta->facebookPages(
	'76236783'
);

Twitter 卡片

对于 Twitter 卡片,Open Graph 标签通常足够(之前 Twitter 使用了如 twitter:title 这样的专有标签,但现在这些标签大多已过时),尽管您还需要调用这个

$meta->twitterCard( );

这将添加以下内容

<meta name="twitter:card" content="summary" />

对于不同类型,只需将其作为参数传递

$meta->twitterCard( MetaTags::TWITTER_CARD_SUMMARY_LARGE_IMAGE );
$meta->twitterCard( MetaTags::TWITTER_CARD_APP );
$meta->twitterCard( MetaTags::TWITTER_CARD_PLAYER );

您还可以设置网站和/或创建者

$meta
	->twitterSite( '@lukaswhite' )
	->twitterCreator( '@lukaswhite' );

元数据——例如,名称和描述——以及任何媒体(如图片)将从Open Graph标签中获取。

然而,您可以覆盖这些;如果出于任何原因,您想为Twitter设置不同的元数据

$meta
	->twitterTitle( 'My Twitter' )
	->twitterDescription( 'A Twitter description' );

这将分别设置twitter:titletwitter:description元标签。

这里有一个完整的示例

$meta
	->title( 'My Website' )
	->description( 'A website' )
	->twitterCard( )
	->twitterSite( '@lukaswhite' )
	->twitterCreator( '@lukaswhite' );
	->addImage(
	( new \Lukaswhite\MetaTags\Entities\Image( ) )
		->setUrl( 'http://example.com/image.jpeg' )
		->setSecureUrl( 'https://example.com/image.jpeg' )
		->setType( 'image/jpeg' )
		->setWidth( 500 )
		->setHeight( 300 )
		->setAlt( 'Example image' )
);

示例(Laravel风格)

这些简化示例使用Laravel,但您可以使用任何框架——或者实际上不使用任何框架。

注册为单例

如果您使用Laravel,可以采取的一种方法是注册元标签作为单例;这样您也可以在引导阶段开始设置元标签

$this->app->singleton( MetaTags::class, function( $app ) {
	$meta = new MetaTags( );
	$meta->siteName( array_get( $app[ 'config' ], 'app.name' ) );
	return $meta;
} );

当然,您也可以在不使用Laravel的情况下使用类似的方法,尽管语法显然会有所不同。

然后,无论何时您想要设置元标签,例如在控制器中,您都可以像这样获取实例

$meta = app( )->make( MetaTags::class );

因为它是单例,您可以从应用程序的多个部分构建元标签。

内容管理系统

这是一个非常基本的示例;它从数据库中获取页面,并从数据库中设置页面标题和页面描述。

class PagesController {

	public function show( Page $page )
	{
		app( )->make( MetaTags::class )
			->title( $page->title )
			->description( $page->description );
			
		// The rest of the method	
	}

}

餐厅列表网站

在这个示例中,控制器从数据库中获取餐厅记录以显示它。它使用元标签库将标题和描述与餐厅匹配。

此外,它还设置了餐厅地址的Open Graph标签,并指向地理位置。

class RestaurantController {

	public function show( Restaurant $restaurant )
	{
		app( )->make( MetaTags::class )
			->isBusiness( )
			->title( $restaurant->name )
			->description( $restaurant->description )
			->addGeopoint( 
				new Geopoint(
					$restaurant->lat, $restaurant->lng
				)
			)
			->streetAddress( $restaurant->street_address )
			->locality( $restaurant->locality )
			->region( $restaurant->locality )
			->postalCode( $restaurant->postal_code )
			->country( $restaurant->country )
			->phone( $restaurant->phone );
			
		// The rest of the method	
	}

}

或者,如果Restaurant类实现了ContactDataGeopoint接口,可以显著简化上面的代码

class RestaurantController {

	public function show( Restaurant $restaurant )
	{
		app( )->make( MetaTags::class )
			->isBusiness( )
			->title( $restaurant->name )
			->description( $restaurant->description )
			->addGeopoint( $restaurant )
			->contactData( $restaurant );
			
		// The rest of the method	
	}

}

社交网络

这个示例演示了一个简单示例,其中特定的控制器在一个社交网络上显示用户的个人资料,并设置适当的Open Graph标签。

class User extends Model implements Profile {
	
	public class getFirstName( )
	{
		return $this->attributes[ 'first_name' ];
	}

	public class getLastName( )
	{
		return $this->attributes[ 'last_name' ];
	}

	public class getUsername( )
	{
		return $this->attributes[ 'username' ];
	}

	public class getGender( )
	{
		return $this->attributes[ 'gender' ];
	}

}

class ProfileController {

	public function show( User $user )
	{
		app( )->make( MetaTags::class )
			->profile( $user );
			
		// The rest of the method	
	}

}

输出标签

要渲染标签,只需调用render( )方法,例如

<html>
	<head>
		<?php print $meta->render( ); ?>
	</head>

或使用Blade

<html>
	<head>
		{!! $meta->render( ) !!}
	</head>

该类还实现了__toString( )方法,因此您甚至可以直接print它。它只是调用render( )方法。

自定义输出

默认情况下,元标签输出包括换行符。您可以使用verbose( )方法将其关闭。

如果您想对生成的字符串有更多的控制,可以设置标签前缀和标签后缀。例如,也许您想以美观的格式打印HTML

$meta->tagPrefix( "\t\t" )
	->tagSuffix( "\n" );

结果将如下所示

<html>
	<head>
		<meta charset="utf-8" />
		<title>My Website</title>
		<meta name="description" content="A description here" />
	</head>

如果您想对输出有更多的控制,或者想要进行任何修改,则可以调用build( )方法,该方法将返回一个HtmlElement实例的数组。有关该方法的文档在这里

地理标签

您还可以添加地理标签

$meta->geoPosition( new Geopoint( 37.416343, -122.153013 ) )
	->geoPlaceName( 'London' )
	->geoRegion( 'GB' );

结果

<meta name="geo.position" content="37.416343, -122.153013" />
<meta name="ICBM" content="37.416343, -122.153013" />
<meta name="geo.placename" content="London" />
<meta name="geo.region" content="GB" />	

添加额外的元标签

值得注意的是,您不需要使用此库将所有元标签添加到您的网站;实际上,可能有些标签您根本不应该添加。

例如

<!DOCTYPE html>
<html lang="en">
	<head>
		{!! $meta !!}
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<link rel="stylesheet" href="/assets/styles.min.css">
	</head>

元标签和链接标签非常特定于主题,因此如果以这种方式将它们添加到布局中可能会使事情更清晰。

但这并不意味着您不能以编程方式执行此操作

$meta->viewport( 'width=device-width, initial-scale=1' )
	->addLink( '/assets/styles.min.css', 'stylesheet' );