はてなブログに動的にschema.orgのWebSiteを埋め込む
はてなブログに動的にschema.orgのWebSiteを埋め込む
はてなブログにJavaScriptで動的にschema.orgのWebSiteを埋め込むメモ.
以下の記事で,一般的なwebサイトにschema.orgのWebSite
を埋め込むスクリプトを書いたので,今回ははてなブログ用のものを書く.
はてなブログトップページにデフォで設定されている構造化データ
実は,Googleの構造化データテストツールをしてみるとわかるが,構造化データが設定してある.(JSON-LDでなくmicrodataを使用している)
- Blog
- Photogragh
- ViewAction
- hatom
注意
すでに shcma.orgのタイプBlog
が設定してあるので,
今回のスクリプトを埋め込むとmicrodataでデフォで設定されたBlog
と
JSON-LDのWebSite
が混在するので注意.
schma.orgのWebSite
について
以下の記事で解説している.
JavaScriptで生成した構造化データをGoogleが認識するのか
以下の記事で解説
はてなブログトップのメタ情報
動的にJSON-LDを生成するために, はてなブログトップページのhtmlからメタ情報を取得する.
- ブログ名:
<html .. data-blog-name="はしくれエンジニアもどきのメモ" ...>
- ブログ名
<html .. data-blog-name="はしくれエンジニアもどきのメモ" ...>
- ブログのURL
<html ... data-blog-uri="http://cartman0.hatenablog.com/" ...
- ブログの画像
<meta itemprop="image" content="https://cdn.blog.st-hatena.com/images/theme/og-image-1500.png"/>
- ブログの説明
<meta name="description" content="情報・IT・Web系技術・Englishについてのメモ・備忘録です。">
- ブログのキーワード
<meta name="keywords" content="エンジニア, engineer, 技術, Technology, ...">
- charset
<meta charset="utf-8"/>
- ブログの最終更新日
<div class="profile-activities"> 最終更新: <time datetime="2017-11-08T15:46:53Z" data-relative data-epoch="1510156013000" pubdate class="updated">2017-11-09 00:46</time> ... </div>
- 利用している言語
<html ... data-avail-langs="ja en" ... >
- はてなブログの所属しているサークル
<ul class="hatena-urllist circle-urllist"> <li title="プログラミング" data-circle-id="11696248318754550880" data-circle-mtime="1510159726"> <a href="http://hatenablog.com/g/11696248318754550880"><img class="circle-image" src="/images/circle/official-circle-icon/computers.gif" alt="プログラミング" title="プログラミング"></a> <a href="http://hatenablog.com/g/11696248318754550880">プログラミング</a> </li> <li title="インターネット" data-circle-id="11696248318754550876" data-circle-mtime="1510162357"> <a href="http://hatenablog.com/g/11696248318754550876"><img class="circle-image" src="/images/circle/official-circle-icon/computers.gif" alt="インターネット" title="インターネット"></a> <a href="http://hatenablog.com/g/11696248318754550876">インターネット</a> </li> <li title="知識" data-circle-id="11696248318754550903" data-circle-mtime="1510207530"> <a href="http://hatenablog.com/g/11696248318754550903"><img class="circle-image" src="/images/circle/official-circle-icon/learning-and-culture.gif" alt="知識" title="知識"></a> <a href="http://hatenablog.com/g/11696248318754550903">知識</a> </li> </ul>
-
ブログ投稿者のニックネーム
(JavaScript実行後)
<span data-load-nickname="1" data-user-name="cartman0"><span class="user-name-nickname">Cartman</span> <span class="user-name-paren">(</span><span class="user-name-hatena-id">id:cartman0</span><span class="user-name-paren">)</span></span>
-
ブログ投稿者のアイコン(プロフィールアイコン)
<a href="http://cartman0.hatenablog.com/about" class="profile-icon-link"> <img src="https://cdn1.www.st-hatena.com/users/ca/cartman0/profile.gif?1428245168" alt="id:cartman0" class="profile-icon" /> </a>
JavaScriptコード
今回,WebSite
に設定するプロパティは,以下.
name
: ブログ名url
: ブログのURLmainEntityOfPage
:WebSite
は,ブログトップページのメインコンテンツより,ブログのURLを指定description
: ブログの説明image
:ブログの画像thumbnailUrl
: ブログ用のサムネイル画像(今回はimage
と同じ)keyword
:ブログのキーワードcharset
: htmlのcharset(つまりutf-8)- "fileFormat": htmlページなので"text/html"
datePublished
: はてなブログ開始日dateModified
: 更新日inLanguage
:利用言語genre
: ジャンル(今回は手入力+はてなブログに所属しているサークル名 ex.知識)author
: ブログの著者(ブログ発信者の名前とプロフィールアイコン,メールアドレス,アドレス)publisher
: ブログ発行者(今回はauthor
と同じ)isAccessibleForFree
: 無料でアクセスできるのでtruecopyrightHolder
: ブログの著作権者(今回はauthor
と同じ.)copyrightYear
: 著作権の年(今回はdatePublished
の年を指定)sponsor
: ブログのスポンサー(今回は試しにGoogleAdsenseを指定)potentialAction
:SearchAction
を設定
<!-- website json-ld fetch だと動かない関数がある? --> <script type="text/javascript"> (function(){ function create_schemaorg_website(){ function try_return(f){ try{return f.call();}catch(e){} } /* setting */ var name = undefined || try_return(function(){return document.querySelector("[data-blog-name]").getAttribute("data-blog-name");}); var uri = undefined || try_return(function(){return document.querySelector("[data-blog-uri]").getAttribute("data-blog-uri");}); var search_uri = undefined || (uri ? uri + "search" : undefined); var image = undefined || try_return(function(){return document.querySelector('[itemprop="image"]').getAttribute("content");}); var description = undefined || try_return(function(){return document.querySelector('[name="description"]').getAttribute("content");}); var keywords = undefined || try_return(function(){return document.querySelector('[name="keywords"]').getAttribute("content");}); var charset = undefined || try_return(function(){return document.querySelector('[charset]').getAttribute("charset");}); var datePublished = "2014-04-30"; var dateModified = undefined || try_return(function(){return document.querySelector('.profile-activities [datetime]').getAttribute("datetime");}); var copyrightYear = undefined || try_return(function(){return datePublished.match(/^(\d{4})-/)[1];}); var inLanguage = undefined || try_return(function(){return document.querySelector('[data-avail-langs]').getAttribute("data-avail-langs").split(" ");}); var genre = ["Web", "Technology"]; var hatena_genre = undefined || try_return(function(){ var arr = []; for(var e of document.querySelectorAll('[data-circle-id]')){ arr.push(e.getAttribute("title")); } return arr; }); if(hatena_genre && hatena_genre.length > 0) genre = genre.concat(hatena_genre); var person_name = "nabana" || try_return(function(){return document.querySelector('.user-name-nickname').innerText;}); var person_image = undefined || try_return(function(){return document.querySelector('.profile-icon').getAttribute("src");}); var person = { "@type": "Person", "address": "Japan", "email": "nabana.work@gmail.com" }; if(person_name) person["name"] = person_name; if(person_image) person["image"] = person_image; var sponsor_organization = { "@type": "Organization", "name": "GoogleAdsense" }; var search_action= !search_uri ? undefined : { "@type": "SearchAction", "target": search_uri + "?q={search_term_string}", "query-input": "required name=search_term_string" //google特有のプロパティ }; var script = document.createElement("script"); script.setAttribute("type", "application/ld+json"); // create website_json var website_obj = { "@context": "http://schema.org", "@type": "WebSite", "fileFormat": "text/html", "isAccessibleForFree": true }; if(name) website_obj["name"] = name; if(uri) website_obj["url"] = uri; if(uri) website_obj["mainEntityOfPage"] = {"@type": "WebPage","@id": uri}; if(image) website_obj["image"] = image; if(image) website_obj["thumbnailUrl"] = image; if(description) website_obj["description"] = description; if(keywords) website_obj["keywords"] = keywords; if(charset) website_obj["encoding"] = {"@type": "MediaObject","encodingFormat": charset}; if(datePublished) website_obj["datePublished"] = datePublished; if(dateModified) website_obj["dateModified"] = dateModified; if(person) website_obj["author"] = person; if(person) website_obj["publisher"] = person; if(person) website_obj["copyrightHolder"] = person; if(copyrightYear) website_obj["copyrightYear"] = copyrightYear; if(inLanguage) website_obj["inLanguage"] = inLanguage; if(genre) website_obj["genre"] = genre; if(sponsor_organization) website_obj["sponsor"] = sponsor_organization; if(search_action) website_obj["potentialAction"] = search_action; script.innerText = JSON.stringify(website_obj); document.head.appendChild(script); } window.addEventListener("load", create_schemaorg_website, false); }()); </script>
上のスクリプトを埋め込んで,ブログトップページを「Googleの構造化データテストツール」と以下のように認識される.